about summary refs log tree commit diff stats
path: root/adapter/protocol/spartan
blob: ac0f590ebe4f8bfd04b08d9abb812d85b1bb59fe (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#!/bin/sh
# Adapter for the spartan protocol. See: spartan://mozz.us
# Requires netcat (nc).
#
# Usage: add the following line to your urimethodmap:
#
# spartan: /cgi-bin/spartan.cgi

if ! type nc >/dev/null 2>/dev/null
then	printf 'Cha-Control: ConnectionError 1 nc not found\n'
	exit 1
fi
MAPPED_URI_PORT=${MAPPED_URI_PORT:=300} # default port is 300
MAPPED_URI_PATH=${MAPPED_URI_PATH:=/} # needs / for root
if test "$REQUEST_METHOD" != POST && test "$MAPPED_URI_QUERY" = "input"
then	printf "Content-Type: text/html

<!DOCTYPE html>
<form method=POST action=\"$MAPPED_URI_PATH\">
Input text to upload:
<p>
<textarea name=q></textarea>
<p>
<input type=submit>
</form>"
	exit 0
fi
CONTENT_LENGTH=${CONTENT_LENGTH:+$(($CONTENT_LENGTH - 2))} # skip q=
CONTENT_LENGTH=${CONTENT_LENGTH:=0} # if missing, set to 0
{
	printf '%s %d\n' "$MAPPED_URI_HOST $MAPPED_URI_PATH" "$CONTENT_LENGTH"
	tail -c+3 # skip q=
} | nc "$MAPPED_URI_HOST" "$MAPPED_URI_PORT" 2>/dev/null | {
	IFS= read -r line
	case $line in
	'2 '*)	ctype=${line#2 }
		printf "Content-Type: %s\n\n" "$ctype"
		# Spartan does something very rude by extending text/gemini
		# for the spartan protocol only. Horrible hack to make it work:
		test "${ctype%
}" = "text/gemini" &&
			sed 's/^=: \([^ ]*\)/=> \1?input/' || cat ;;
	'3 '*)	printf "Status: 301\nLocation: %s\n" "${line#3 }" ;;
	'4 '*)	printf "Status: 403\n\n%s" "${line#4 }" ;;
	'5 '*)	printf "Status: 500\n\n%s" "${line#5 }" ;;
	*)	printf "Cha-Control: ConnectionError 1 malformed response\n"
	esac
}
="s">'pager.reshape()' g = 'pager.cursorFirstLine()' G = 'pager.cursorLastLine()' z = 'pager.centerLine()' C-g = 'pager.lineInfo()' v = 'pager.toggleSource()' D = 'pager.discardBuffer()' ',' = 'pager.prevBuffer()' '.' = 'pager.nextBuffer()' M-C = 'pager.command()' C = 'pager.commandMode();console.show()' '/' = 'pager.isearchForward()' '?' = 'pager.isearchBackward()' n = 'pager.searchNext()' N = 'pager.searchPrev()' [line] C-m = 'line.submit()' C-j = 'line.submit()' C-h = 'line.backspace()' 'C-?' = 'line.backspace()' C-d = 'line.delete()' C-c = 'line.cancel()' M-b = 'line.prevWord()' M-f = 'line.nextWord()' C-b = 'line.backward()' C-f = 'line.forward()' C-u = 'line.clear()' C-_ = 'line.clear()' M-k = 'line.clear()' C-k = 'line.kill()' C-w = 'line.clearWord()' M-C-h = 'line.clearWord()' 'M-C-?' = 'line.clearWord()' M-d = 'line.killWord()' C-a = 'line.begin()' C-e = 'line.end()' C-v = 'line.escape()'