mirror of
https://git.sakamoto.pl/laudom/http.sh.git
synced 2026-01-02 07:21:15 +01:00
Compare commits
4 commits
7e40fd14e0
...
b5320a169d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b5320a169d | ||
|
|
3bacddd8a4 | ||
|
|
37770a1735 | ||
|
|
dadfebb128 |
5 changed files with 116 additions and 20 deletions
|
|
@ -15,6 +15,7 @@ We have some guides and general documentation in the [docs](docs/) directory. Am
|
|||
- [HTTP Router](docs/router.md)
|
||||
- [Template engine](docs/template.md)
|
||||
- [Script integrations](docs/util.md)
|
||||
- [HTTP request API](docs/http.md)
|
||||
- [List of security fixes](docs/sec-fixes/)
|
||||
|
||||
## Dependencies
|
||||
|
|
|
|||
43
docs/http.md
Normal file
43
docs/http.md
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
# 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]}"
|
||||
}
|
||||
```
|
||||
|
||||
55
src/misc.sh
55
src/misc.sh
|
|
@ -71,3 +71,58 @@ function url_decode() {
|
|||
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,6 +23,7 @@ declare -A cookies # cookies!
|
|||
declare -A get_data # all GET params
|
||||
declare -A post_data # all POST params
|
||||
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[req_headers]=''
|
||||
|
|
@ -44,16 +45,7 @@ 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")"
|
||||
unset IFS
|
||||
|
||||
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
|
||||
|
||||
_param_parse "${r[url]#*\?}&" get_data
|
||||
else
|
||||
exit 1 # TODO: throw 400 here
|
||||
fi
|
||||
|
|
@ -272,12 +264,7 @@ if [[ "${r[post]}" == true ]] && [[ "${r[status]}" == 200 || "${r[status]}" ==
|
|||
|
||||
if [[ "${r[payload_type]}" == "urlencoded" ]]; then
|
||||
unset IFS
|
||||
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}&"
|
||||
_param_parse "${data}&" post_data
|
||||
else
|
||||
# this is fine?
|
||||
post_data[0]="${data%\&}"
|
||||
|
|
|
|||
|
|
@ -30,19 +30,26 @@ EOF
|
|||
match="nyaa"
|
||||
}
|
||||
|
||||
server_get_random() {
|
||||
server_get_array() {
|
||||
prepare() {
|
||||
cat <<"EOF" > app/webroot/meow.shs
|
||||
#!/bin/bash
|
||||
echo "${get_data[meow]}"
|
||||
http_array meow ref
|
||||
echo "${ref[1]}"
|
||||
EOF
|
||||
}
|
||||
|
||||
tst() {
|
||||
curl -s "localhost:1337/meow.shs?meow=nyaa"
|
||||
curl -s "localhost:1337/meow.shs?meow=nyaa&meow=second+element&meow=meow"
|
||||
}
|
||||
|
||||
match="nyaa"
|
||||
match="second element"
|
||||
}
|
||||
|
||||
server_post_array() {
|
||||
tst() {
|
||||
curl -s "localhost:1337/meow.shs" -d 'meow=nyaa&meow=second+element&meow=meow'
|
||||
}
|
||||
}
|
||||
|
||||
server_post_param() {
|
||||
|
|
@ -202,6 +209,9 @@ subtest_list=(
|
|||
server_get_param
|
||||
server_post_param
|
||||
|
||||
server_get_array
|
||||
server_post_array
|
||||
|
||||
# currently functionally equivalent
|
||||
server_patch_dummy
|
||||
server_put_dummy
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue