curl_bible

Written by Connor Ricotta
6/3/2022

After being inspired by various terminal based applications, ranging from the incredibly useful (Such as wttr.in or cheat.sh), or just fun (parrot.live), I was inspired to make my own.

The only challenge was what to choose as a project. When I was sitting in church one day, it noticed how easily you could translate a bible passage into an endpoint. Whether splitting up a passage such as John 3:15-19 into "/John/3/15-19" or "/John:3:15-19", it seemed like a great option. Once I had settled on a project, two of my goals were to:

  1. Format the text graphically as a book, with terminal colors.
  2. Have a variety of endpoints, to ensure I wrote DRY (Don't Repeat Yourself) code.

Thankfully, someone had already created a repository that had already contained several different versions of the bible with a great version-agnostic database schema. Every single verse was uniquely indentified by the value:

{Book ID}{Chapter ID}{Verse ID}

Each book ID was two characters (or padded with a zero), and the chapter and verses were both three characters (also padded with zeros if to short). This means that chapter 1, verses 1-9 of Leviticus (the third book of the Bible) can be expressed as this mysql query,

SELECT * FROM t_asv WHERE ID BETWEEN 03001001 and 03001009

For my backend server, I choose Flask , because I am familiar with it, and it is quite easy to get a basic server running. The application is hosted a Linode server behind Cloudflare, which proxies the requests to the server while preventing any serious attacks on the web server. Here is a diagram of the server.

Diagram of curl_bible

If you notice on the diagram, you notice that HTTP traffic is supported, even though all .dev domains are on the HSTS pre-load list. This is because Curl defaults to HTTP, and Curling an HTTPS site normally returns a 301.
However, this list is only for browsers, meaning that while a browser cannot (easily) access the HTTP version of your site, Curl can!

So by checking for certain User-Agents (currently the ones for Curl and HTTPie), users without those headers can be re-directed to the HTTPS version of the webpage like normal, while those with the headers continue on to the Flask server. An example of this done in Nginx can be seen here:

  map "$host:$http_user_agent" $validUA {
        default         1;
        "~curl"         0;
        "~HTTPie"       0;
  }
  server {
  server_name me.test;

  # SSL #
  listen 443 ssl;
  include /etc/nginx/snippets/ssl_keys;
  include /etc/nginx/snippets/ssl_oscp;

  # Logging #
  access_log /var/log/nginx/access.log;
  error_log /var/log/nginx/error.log;

  # If they don't have the proper user-agent, redirect to HTTPS
  if ( $validUA ) { 
          return 301 https://$server_name$request_uri;
  }
  # Otherwise, send to the proper location
  location / {
          include /etc/nginx/snippets/proxy_security;
          proxy_pass flask.server.local;
  }
}

This must be done this way because in Nginx 'if is evil', i.e. it can lead to unintentional behavior

If you have something to add (or something to correct), please feel free to contribute to this project!

Thank you!