Node.js, but | sed 's/Node/HTTP/;s/js/sh/'
.
HTTP.sh is (by far) the most extensible attempt at creating a web framework in Bash, and (AFAIK) the only one that's actively maintained. Although I strive for code quality, this is still rather experimental and may contain bugs.
Originally made for Junction Stupidhack 2020; Created by sdomi, ptrcnull and selfisekai.
If you want to build a new webapp from scratch:
./http.sh init
./http.sh
If you're setting up HTTP.sh for an existing application:
git clone https://git.sakamoto.pl/laudom/ocw/ app # example repo :P
./http.sh
We also support Docker! Both a Dockerfile and an example docker-compose.yml are included for your convenience. Containerizing your webapp is as easy as docker-compose up -d
- Bash (4.x should work, but we'll need 5.0 soon)
- Ncat, not openbsd-nc, not netcat, not nc
- socat (because the above is slightly broken)
- pkill
- mktemp
- jq (probably not needed just yet, but it will be in 1.0)
- dd (for accounts, multipart/form-data and websockets)
- sha1sum, sha256sum, base64 (for accounts and simple auth)
- curl (for some demos)
- can't change the HTTP status code from Shell Server scripts. This could theoretically be done with custom vhost configs and some
if
statements, but this would be a rather nasty solution to that problem. $post_multipart
doesn't keep original names - could be fixed by parsing individual headers from the multipart request instead of skipping them all- it won't ever throw a 500, thus it fails silently
- ${cfg[namespace]} (
app
by default)- ${cfg[root]} (
webroot
by default) - public application root - workers/ - scripts that execute periodically live there (see examples)
- views/ - for use with HTTP.sh router
- config.sh - application-level config file
- ${cfg[root]} (
- config
- master.sh - main server config file - loaded on boot and with every request
- host:port - if a file matching the Host header is found, HTTP.sh will load it request-wide
- src
- server source files and modules
- response
- files corresponding to specific HTTP status codes
- listing.sh (code 210) is actually HTTP 200, but triggered in a directory with autoindex turned on and without a valid
index.shs
file
- templates - section templates go here
- secret - users, passwords and other Seecret data should be stored here
- storage - random data storage for your webapp
- get_data - holds data from GET parameters
- /?test=asdf ->
${get_data[test]}
=="asdf"
- /?test=asdf ->
- params - holds parsed data from URL router
- /profile/test (assuming profile/:name) ->
${params[name]}
=="test"
- /profile/test (assuming profile/:name) ->
- post_data - same as above, but for urlencoded POST params
- test=asdf ->
${post_data[test]}
=="asdf"
- test=asdf ->
- post_multipart - contains paths to uploaded files from multipart/form-data POST requests. WARNING: it doesn't hold field names yet, it relies on upload order for identification
- first file (in upload order) ->
cat ${post_multipart[0]}
- second file ->
cat ${post_multipart[1]}
- first file (in upload order) ->
- r - misc request data
- authorization
- content_boundary
- content_boundary
- content_length
- content_type
- headers
- host
- host_portless
- ip
- post
- proto
- status
- uri
- url
- user_agent
- view
- websocket_key
- cfg - server and app config - see
config/master.sh
for more details
- To prevent running malicious scripts, by default only scripts with extension
.shs
can be run by the server, but this can be changed in the config. - ${cfg[index]} ignores the above - see config/master.sh
- Trans rights!
- SHS stands for Shell Server.