https://github.com/cablehead/http-sh
Attach Bash scripts to a HTTP interface
https://github.com/cablehead/http-sh
cli http-server rust
Last synced: about 2 months ago
JSON representation
Attach Bash scripts to a HTTP interface
- Host: GitHub
- URL: https://github.com/cablehead/http-sh
- Owner: cablehead
- License: mit
- Created: 2022-08-24T00:25:03.000Z (almost 3 years ago)
- Default Branch: main
- Last Pushed: 2025-01-31T08:07:13.000Z (4 months ago)
- Last Synced: 2025-04-02T22:54:20.611Z (2 months ago)
- Topics: cli, http-server, rust
- Language: Rust
- Homepage: https://ndyg.cross.stream/projects/chat-app
- Size: 88.9 KB
- Stars: 6
- Watchers: 2
- Forks: 0
- Open Issues: 15
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# http-sh [](https://github.com/cablehead/http-sh/actions/workflows/ci.yml)
`http-sh` lets you attach a Bash scripts to an HTTP interface. If you prefer
[Nushell](https://www.nushell.sh) to POSIX, this project has a cousin called
[http-nu](https://github.com/cablehead/http-nu).## Install
```bash
cargo install http-sh --locked
```## Live examples
- [`chat-app`](https://ndyg.cross.stream/projects/chat-app)
## Overview
### GET: Hello world
```bash
$ http-sh :3001 -- echo Hello world
$ curl -s localhost:3001
Hello world
```You can listen to UNIX domain sockets as well
```bash
$ http-sh ./sock -- echo Hello world
$ curl -s --unix-socket ./sock localhost
Hello world
```### POST: echo
```bash
$ http-sh :3001 -- cat
$ curl -s -d Hai localhost:3001
Hai
```### Request metadata
The Request metadata is available as JSON on file descriptor 3.
Pairs well with [`jq`](https://github.com/stedolan/jq)
```bash
$ http-sh :3001 -- bash -c 'jq <&3'
$ curl -s localhost:3001
{
"headers": {
"accept": "*/*",
"host": "localhost:3001",
"user-agent": "curl/7.79.1"
},
"method": "GET",
"path": "/",
"proto": "HTTP/1.1",
"query": {},
"remote_ip": "127.0.0.1",
"remote_port": 51435,
"request_id": "0391ND23LWW4KVCZ00G30BZAG",
"uri": "/"
}$ http-sh :3001 -- bash -c 'echo hello: $(jq -r .path <&3)'
$ curl -s localhost:3001/yello
hello: /yello
```### Response metadata
You can set the Response metadata by writing JSON on file descriptor 4.
Currently you can set the Response `status` and `headers`.Pairs well with [`jo`](https://github.com/jpmens/jo)
```
$ http-sh :3001 -- bash -c 'jo status=404 >&4; echo sorry, eh'
$ curl -si localhost:3001
HTTP/1.1 404 Not Found
content-type: text/plain
transfer-encoding: chunked
date: Sat, 25 Feb 2023 05:20:48 GMTsorry, eh
```Note, for streaming responses, you'll want to close fd 4, so the Response is
initiated.```
$ http-sh :3001 -- bash -c 'exec 4>&-; while true ; do date; sleep 1; done'
$ curl -s localhost:3001
Sat Feb 25 00:31:41 EST 2023
Sat Feb 25 00:31:43 EST 2023
Sat Feb 25 00:31:44 EST 2023
Sat Feb 25 00:31:45 EST 2023
Sat Feb 25 00:31:46 EST 2023
...
```### [server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events)
Pairs well with [`xcat`](https://github.com/cablehead/xcat)
```bash
$ http-sh :3001 -- bash -c '
jo headers="$(jo "content-type"="text/event-stream")" >&4
exec 4>&-
tail -F source.json | xcat -- bash -c "sed '\''s/^/data: /g'\''; echo;"
'# simulate generating events in a seperate process
$ while true; do jo date="$(date)" ; sleep 1 ; done >> source.json$ curl -si localhost:3001/
HTTP/1.1 200 OK
content-type: text/event-stream
transfer-encoding: chunked
date: Sat, 25 Feb 2023 18:13:37 GMTdata: {"date":"Sat Feb 25 13:13:35 EST 2023"}
data: {"date":"Sat Feb 25 13:13:36 EST 2023"}
data: {"date":"Sat Feb 25 13:13:37 EST 2023"}
data: {"date":"Sat Feb 25 13:13:38 EST 2023"}
data: {"date":"Sat Feb 25 13:13:39 EST 2023"}
...
```## Direct Testing of Script
While `http-sh` provides a convenient way to serve HTTP requests and interact with the associated metadata, there might be times when you wish to directly test the script you intend to use with `http-sh` without the HTTP layer.
To simulate the environment in which `http-sh` invokes your script, you can use the following command:
```bash
echo "Hai" | ./root.sh 3&1
```Here's a breakdown of what's happening:
1. `echo "Hai"`: Simulates sending the request body.
2. `./root.sh`: Your script that processes the input.
3. `3&1`: Redirects output from file descriptor 4 to stdout, so you can see the response metadata and main response together in the terminal.This method allows you to bypass `http-sh` during development and testing phases, ensuring that your script behaves as expected before integrating it with the HTTP server.