mirror of
https://git.sakamoto.pl/laudom/http.sh.git
synced 2026-01-12 04:01:15 +01:00
Compare commits
No commits in common. "master" and "v0.97.3.1" have entirely different histories.
7 changed files with 25 additions and 150 deletions
|
|
@ -15,7 +15,6 @@ We have some guides and general documentation in the [docs](docs/) directory. Am
|
||||||
- [HTTP Router](docs/router.md)
|
- [HTTP Router](docs/router.md)
|
||||||
- [Template engine](docs/template.md)
|
- [Template engine](docs/template.md)
|
||||||
- [Script integrations](docs/util.md)
|
- [Script integrations](docs/util.md)
|
||||||
- [HTTP request API](docs/http.md)
|
|
||||||
- [List of security fixes](docs/sec-fixes/)
|
- [List of security fixes](docs/sec-fixes/)
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
|
||||||
43
docs/http.md
43
docs/http.md
|
|
@ -1,43 +0,0 @@
|
||||||
# HTTP - the proto, the API
|
|
||||||
|
|
||||||
very work in progress file.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## GET/POST parameters
|
|
||||||
|
|
||||||
- `${get_data["param"]}`
|
|
||||||
- `${post_data["param"]}`
|
|
||||||
|
|
||||||
Case-insensitive. If K/V pairs aren't used (but a string is provided, just without `=`) then
|
|
||||||
it can be accessed through `${get_data}` / `${post_data}` (array element 0).
|
|
||||||
|
|
||||||
### Arrays
|
|
||||||
|
|
||||||
HTTP does arrays through concatenating multiple parameters with the same name. In our case, values
|
|
||||||
are passed to a secondary array, and a reference to it is left for application use.
|
|
||||||
|
|
||||||
```
|
|
||||||
GET asdf/?a=1&a=2&a=3&b=1
|
|
||||||
```
|
|
||||||
|
|
||||||
will result in:
|
|
||||||
|
|
||||||
```
|
|
||||||
declare -A get_data=([b]="1" [a]="[array]" )
|
|
||||||
```
|
|
||||||
|
|
||||||
To get the value set out of an array, call `http_array <param_name> <output_name>`. For instance:
|
|
||||||
|
|
||||||
```
|
|
||||||
#!/bin/bash
|
|
||||||
if ! http_array a array; then
|
|
||||||
echo "Not an array"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
for (( i=0; i<${#array[@]}; i++ )) {
|
|
||||||
echo "a[$i]=${array[i]}"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
23
docs/util.md
23
docs/util.md
|
|
@ -4,8 +4,6 @@ HTTP.sh provides a number of useful APIs designed to make interfacing with HTTP
|
||||||
Some of those (especially notORM) are also useful in a CLI environment, to help with migrations and
|
Some of those (especially notORM) are also useful in a CLI environment, to help with migrations and
|
||||||
other administrative tasks.
|
other administrative tasks.
|
||||||
|
|
||||||
## Invocation
|
|
||||||
|
|
||||||
Utils integrate into HTTP.sh through calling the main script, with the utility name as the first
|
Utils integrate into HTTP.sh through calling the main script, with the utility name as the first
|
||||||
parameter. So, for `meow.sh` the invocation would be `./http.sh meow`, or `./http.sh meow [params]`
|
parameter. So, for `meow.sh` the invocation would be `./http.sh meow`, or `./http.sh meow [params]`
|
||||||
if the util takes any parameters.
|
if the util takes any parameters.
|
||||||
|
|
@ -21,27 +19,6 @@ Of note:
|
||||||
|
|
||||||
A list of utilities can be obtained by calling `./http.sh utils`.
|
A list of utilities can be obtained by calling `./http.sh utils`.
|
||||||
|
|
||||||
## Creating your own
|
|
||||||
|
|
||||||
Simply create a shell script in your namespace's util directory (that's usually `app/util/`), and
|
|
||||||
mark it as executable. It has to have `.sh` as an extension, but shebang currently doesn't matter.
|
|
||||||
|
|
||||||
It's recommended that if your util takes any positional parameters, it should check for $1 being
|
|
||||||
set, and display a help message. An example of such script is listed below.
|
|
||||||
|
|
||||||
```
|
|
||||||
if [[ ! "$1" || "$1" == "help" ]]; then
|
|
||||||
echo "usage: $0 $HTTPSH_SCRIPTNAME <action>
|
|
||||||
|
|
||||||
Action can be one of:
|
|
||||||
meow - Mrrrrrrrp!
|
|
||||||
help - This message."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# script continues here...
|
|
||||||
```
|
|
||||||
|
|
||||||
## Built-in utils
|
## Built-in utils
|
||||||
|
|
||||||
The following scripts are generic helpers shipped with HTTP.sh. We hope they'll come in handy.
|
The following scripts are generic helpers shipped with HTTP.sh. We hope they'll come in handy.
|
||||||
|
|
|
||||||
2
http.sh
2
http.sh
|
|
@ -37,7 +37,7 @@ if [[ "$1" == "init" ]]; then # will get replaced with proper parameter parsing
|
||||||
fi
|
fi
|
||||||
source config/master.sh
|
source config/master.sh
|
||||||
|
|
||||||
mkdir -p "${cfg[namespace]}/${cfg[root]}" "${cfg[namespace]}/workers/example" "${cfg[namespace]}/views" "${cfg[namespace]}/templates" "${cfg[namespace]}/util/"
|
mkdir -p "${cfg[namespace]}/${cfg[root]}" "${cfg[namespace]}/workers/example" "${cfg[namespace]}/views" "${cfg[namespace]}/templates"
|
||||||
touch "${cfg[namespace]}/config.sh" "${cfg[namespace]}/workers/example/control"
|
touch "${cfg[namespace]}/config.sh" "${cfg[namespace]}/workers/example/control"
|
||||||
cp ".resources/config.sh" "${cfg[namespace]}/config.sh"
|
cp ".resources/config.sh" "${cfg[namespace]}/config.sh"
|
||||||
cp ".resources/routes.sh" "${cfg[namespace]}/routes.sh"
|
cp ".resources/routes.sh" "${cfg[namespace]}/routes.sh"
|
||||||
|
|
|
||||||
55
src/misc.sh
55
src/misc.sh
|
|
@ -71,58 +71,3 @@ function url_decode() {
|
||||||
function worker_add() {
|
function worker_add() {
|
||||||
:
|
:
|
||||||
}
|
}
|
||||||
|
|
||||||
# internal function
|
|
||||||
# common GET/POST application/x-www-form-urlencoded parser
|
|
||||||
#
|
|
||||||
# _param_parse(input, destination_ref)
|
|
||||||
_param_parse() {
|
|
||||||
[[ ! "$1" || ! "$2" ]] && return 1
|
|
||||||
local -n ref="$2"
|
|
||||||
|
|
||||||
local i name value
|
|
||||||
|
|
||||||
while read -d'&' i; do
|
|
||||||
name="${i%%=*}"
|
|
||||||
if [[ "$name" ]]; then
|
|
||||||
value="${i#*=}"
|
|
||||||
if [[ "${ref["$name"]}" ]]; then # array mode
|
|
||||||
if [[ ! "${http_array_refs["$name"]}" ]]; then
|
|
||||||
http_array_refs["$name"]=_param_$RANDOM
|
|
||||||
local -n arr="${http_array_refs["$name"]}"
|
|
||||||
|
|
||||||
arr=("${ref["$name"]}")
|
|
||||||
ref["$name"]="[array]"
|
|
||||||
else
|
|
||||||
local -n arr="${http_array_refs["$name"]}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
arr+=("$(url_decode "$value")")
|
|
||||||
else
|
|
||||||
ref["$name"]="$(url_decode "$value")"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done <<< "$1"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Safely receive a reference to a HTTP urlencoded array
|
|
||||||
#
|
|
||||||
# http_array(name, out_ref)
|
|
||||||
http_array() {
|
|
||||||
[[ ! "$1" || ! "$2" ]] && return 1
|
|
||||||
if [[ ! "${http_array_refs[$1]}" ]]; then
|
|
||||||
declare -ga $2
|
|
||||||
local -n ref=$2
|
|
||||||
|
|
||||||
if [[ "${post_data[$1]}" ]]; then
|
|
||||||
ref=("${post_data[$1]}")
|
|
||||||
elif [[ "${get_data[$1]}" ]]; then
|
|
||||||
ref=("${get_data[$1]}")
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
declare -gn $2=${http_array_refs[$1]}
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ declare -A cookies # cookies!
|
||||||
declare -A get_data # all GET params
|
declare -A get_data # all GET params
|
||||||
declare -A post_data # all POST params
|
declare -A post_data # all POST params
|
||||||
declare -A params # parsed router data
|
declare -A params # parsed router data
|
||||||
declare -A http_array_refs # references to GET/POST arrays
|
|
||||||
|
|
||||||
r[status]=210 # Mommy always said that I was special
|
r[status]=210 # Mommy always said that I was special
|
||||||
r[req_headers]=''
|
r[req_headers]=''
|
||||||
|
|
@ -45,7 +44,16 @@ if [[ "${param,,}" =~ ^(get|post|patch|put|delete|meow) ]]; then # TODO: OPTIONS
|
||||||
r[url]="$(sed -E 's/^ *//;s/HTTP\/[0-9]+\.[0-9]+//;s/ //g;s/\/*\r//g;s/\/\/*/\//g' <<< "$param")"
|
r[url]="$(sed -E 's/^ *//;s/HTTP\/[0-9]+\.[0-9]+//;s/ //g;s/\/*\r//g;s/\/\/*/\//g' <<< "$param")"
|
||||||
unset IFS
|
unset IFS
|
||||||
|
|
||||||
_param_parse "${r[url]#*\?}&" get_data
|
if [[ "${r[url]}" == *'?'* ]]; then
|
||||||
|
while read -d'&' i; do
|
||||||
|
name="${i%%=*}"
|
||||||
|
if [[ "$name" ]]; then
|
||||||
|
value="${i#*=}"
|
||||||
|
get_data[$name]="$(url_decode "$value")"
|
||||||
|
fi
|
||||||
|
done <<< "${r[url]#*\?}&"
|
||||||
|
fi
|
||||||
|
|
||||||
else
|
else
|
||||||
exit 1 # TODO: throw 400 here
|
exit 1 # TODO: throw 400 here
|
||||||
fi
|
fi
|
||||||
|
|
@ -104,17 +112,11 @@ if [[ -n "${headers["host"]}" ]]; then
|
||||||
r[host]="${headers["host"]}"
|
r[host]="${headers["host"]}"
|
||||||
r[host_portless]="${headers["host"]%%:*}"
|
r[host_portless]="${headers["host"]%%:*}"
|
||||||
|
|
||||||
cfg_temp="config/$(basename -- ${r[host]})"
|
if [[ -f "config/$(basename -- ${r[host]})" ]]; then
|
||||||
|
source "config/$(basename -- ${r[host]})"
|
||||||
if [[ -f "$cfg_temp" ]]; then
|
elif [[ -f "config/$(basename -- ${r[host_portless]})" ]]; then
|
||||||
source "$cfg_temp"
|
source "config/$(basename -- ${r[host_portless]})"
|
||||||
elif [[ "${r[host]}" != "${r[host_portless]}" ]]; then
|
|
||||||
cfg_temp_portless="config/$(basename -- ${r[host_portless]})"
|
|
||||||
[[ -f "$cfg_temp_portless" ]] && source "$cfg_temp_portless"
|
|
||||||
unset cfg_temp_portless
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
unset cfg_temp
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "${headers["connection"]}" == *"upgrade"* && "${headers["upgrade"]}" == "websocket" ]]; then
|
if [[ "${headers["connection"]}" == *"upgrade"* && "${headers["upgrade"]}" == "websocket" ]]; then
|
||||||
|
|
@ -264,7 +266,12 @@ if [[ "${r[post]}" == true ]] && [[ "${r[status]}" == 200 || "${r[status]}" ==
|
||||||
|
|
||||||
if [[ "${r[payload_type]}" == "urlencoded" ]]; then
|
if [[ "${r[payload_type]}" == "urlencoded" ]]; then
|
||||||
unset IFS
|
unset IFS
|
||||||
_param_parse "${data}&" post_data
|
while read -r -d'&' i; do
|
||||||
|
name="${i%%=*}"
|
||||||
|
value="${i#*=}"
|
||||||
|
post_data[$name]="$(url_decode "$value")"
|
||||||
|
echo post_data[$name]="$value" >/dev/stderr
|
||||||
|
done <<< "${data}&"
|
||||||
else
|
else
|
||||||
# this is fine?
|
# this is fine?
|
||||||
post_data[0]="${data%\&}"
|
post_data[0]="${data%\&}"
|
||||||
|
|
|
||||||
|
|
@ -30,26 +30,19 @@ EOF
|
||||||
match="nyaa"
|
match="nyaa"
|
||||||
}
|
}
|
||||||
|
|
||||||
server_get_array() {
|
server_get_random() {
|
||||||
prepare() {
|
prepare() {
|
||||||
cat <<"EOF" > app/webroot/meow.shs
|
cat <<"EOF" > app/webroot/meow.shs
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
http_array meow ref
|
echo "${get_data[meow]}"
|
||||||
echo "${ref[1]}"
|
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
tst() {
|
tst() {
|
||||||
curl -s "localhost:1337/meow.shs?meow=nyaa&meow=second+element&meow=meow"
|
curl -s "localhost:1337/meow.shs?meow=nyaa"
|
||||||
}
|
}
|
||||||
|
|
||||||
match="second element"
|
match="nyaa"
|
||||||
}
|
|
||||||
|
|
||||||
server_post_array() {
|
|
||||||
tst() {
|
|
||||||
curl -s "localhost:1337/meow.shs" -d 'meow=nyaa&meow=second+element&meow=meow'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
server_post_param() {
|
server_post_param() {
|
||||||
|
|
@ -209,9 +202,6 @@ subtest_list=(
|
||||||
server_get_param
|
server_get_param
|
||||||
server_post_param
|
server_post_param
|
||||||
|
|
||||||
server_get_array
|
|
||||||
server_post_array
|
|
||||||
|
|
||||||
# currently functionally equivalent
|
# currently functionally equivalent
|
||||||
server_patch_dummy
|
server_patch_dummy
|
||||||
server_put_dummy
|
server_put_dummy
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue