-
Notifications
You must be signed in to change notification settings - Fork 0
/
proxy.sh
executable file
·165 lines (143 loc) · 3.97 KB
/
proxy.sh
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#!/bin/bash
#
# Run this on a port and configure
# apt-cacher-ng
# to use it for example in file
# /etc/apt-cacher-ng/proxy.conf
# add:
# AllowUserPorts: 80 443
# Proxy: http://127.0.0.1:8080
# NoSSLChecks: 0
TIMEOUT=10
DOWNGRADE=/tmp/APT-CACHER-NG-PROXY.https.tmp
UNKNOWN=/tmp/APT-CACHER-NG-PROXY.host.unknown.tmp
STDOUT() { local a b; printf -va '[%s] %q' "$SOCKLINGER_NR" "$1"; [ 1 -ge $# ] || printf -vb ' %q' "${@:2}"; printf '%s%s\n' "$a" "$b"; }
STDERR() { local e=$?; STDOUT "$@" >&2; return $e; }
FAIL()
{
printf -v fail ' %q' "$@"
printf 'HTTP/1.1 %03d FAIL\r\n' "$1"
printf 'Connection: close\r\n'
printf 'Content-Length: %d\r\n' $[8 + ${#fail}]
printf 'Content-Type: text/plain\r\n'
printf '\r\n'
printf 'FAIL:%s\r\n' "$fail"
}
OOPS() { STDERR OOPS: "$@"; FAIL 500 "$@"; exit 23; }
x() { "$@"; }
o() { x "$@" || OOPS fail $?: "$@"; }
get-headers()
{
HEADS=()
CURLHEADS=()
while read -rt$TIMEOUT h && h="${h%$'\r'}" && [ -n "$h" ]
do
ht="${h%%: *}"
hd="${h#*: }"
o test ".$h" = ".$ht: $hd"
ht="${ht,,}"
case "$ht:$hd" in
(proxy-connection:*) continue;;
(connection:*) continue;;
(cache-control:*) continue;;
(content-length:*) ContentLength="$hd";;
(content-type:*) ContentType="$hd";;
(accept:*) Accept="$hd";;
(host:*) Host="$hd";;
(user-agent:*) UserAgent="$hd";;
(accept-encoding:*) ;;
(range:*) ;;
(if-range:*) ;;
(referer:*) ;;
(accept-language:*) ;;
(*) STDERR head "$ht:" "$hd";;
esac
CURLHEADS+=(-H "$h")
HEADS+=("$h")
done
}
GET()
{
local STDPORT SOCATMODE
printf -vh '%s\r\n' "${HEADS[@]}"
case "$MODE" in
(http) STDPORT=80; SOCATMODE=tcp;;
(https) STDPORT=443; SOCATMODE=openssl;;
esac
MODE="$MODE" Host="$Host" PORT="${PORT:-$STDPORT}" URL="$URL" HEADS="$h" PARENT="$SOCKLINGER_NR" TIMEOUT="$TIMEOUT" o socat "$SOCATMODE:$Host:${PORT:-$STDPORT}" "exec:${0%/*}/GET.sh" 3>&1 >&2
}
getter()
{
case "$URL" in
(http://$Host/*) URL="${URL#http://$Host}";;
(*) OOPS Host "$Host" does not match "$URL";;
esac
MODE=http
case "$Host" in
# list of known hostnames to not log
# Debian
(deb.debian.org) ;;
(cdn-fastly.deb.debian.org) ;;
# Ubuntu
(ppa.launchpadcontent.net) ;;
(ppa.launchpad.net) ;;
(security.ubuntu.com) ;;
(ftp.tu-ilmenau.de) ;;
(ftp.hosteurope.de) ;;
(ddebs.ubuntu.com) ;;
# Raspbian
(archive.raspberrypi.org) ;;
# Microsoft et al
(packages.microsoft.com) ;;
(dl.google.com) ;;
# list of hostnames to treat special
(apache.jfrog.io) MODE=https;;
(developer.download.nvidia.com) MODE=https;;
(*) fgrep -qsx "$Host" "$DOWNGRADE" && MODE=https || # Hack: Upgrade downgraded Location requests, see GET.sh
STDERR Host "$Host" see "$UNKNOWN" || # Report unknown hosts
fgrep -svf "$UNKNOWN" >> "$UNKNOWN" <<< "$Host" # Record unknwon hosts
;;
esac
PORT=
# Following heuristic probably fails for IPv6 IP based hosts:
case "$Host" in
(*:*) PORT="${Host##*:}"; Host="${Host%:*}";;
esac
GET
}
# Use
# DEBUG GET
# above to catch evidence.
# But you probably never need it:
DEBUG()
{
local ret FILE=/tmp/PROXY-DEBUG.$$
{
printf '================\n'
printf ' %q\n' "$MODE" "$Host" "$PORT" "$URL"
printf ' %s\n' "${HEADS[@]}"
printf '================\n'
} >> "$FILE"
set -o pipefail
"$@" | tee -a "$FILE"
ret=$?
printf '==== %q ====\n' "$ret" >> "$FILE"
return $ret;
}
# This shitty Apt-Cacher-NG does not work properly with
# connection:close
have=false
while read -rt$TIMEOUT GET URL HTTP
do
HTTP="${HTTP%$'\r'}"
STDERR "$GET" "$URL" "$HTTP"
get-headers
have=:
# We do not support CONNECT for a good reason:
# At my side apt-cacher-ng fails to connect to SSL based hosts (IDKW)
case "$GET" in
(GET) getter "$URL";;
(*) OOPS 503 wrong or unknown method: "$GET";;
esac
done
$have || OOPS no input or timeout