-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathutil.go
171 lines (140 loc) · 3.39 KB
/
util.go
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
165
166
167
168
169
170
171
package main
import (
"bytes"
"compress/flate"
"compress/gzip"
"encoding/json"
"io"
"net/http"
"strconv"
"github.com/bobesa/go-domain-util/domainutil"
"github.com/dsnet/compress/brotli"
)
// https://stackoverflow.com/questions/41670155/get-public-ip-in-golang
type IP struct {
Query string
}
func getPublicIP() string {
req, err := http.Get("http://ip-api.com/json/")
if err != nil {
return err.Error()
}
defer req.Body.Close()
body, err := io.ReadAll(req.Body)
if err != nil {
return err.Error()
}
var ip IP
json.Unmarshal(body, &ip)
return ip.Query
}
func compareBase(name1, name2 string) bool {
return domainutil.Domain(name1) == domainutil.Domain(name2)
}
func getHostOptions(host string) *HostOptions {
for _, entry := range config.Hosts {
//Only compare domain + tld. Ignore subdomains
if compareBase(entry.Name, host) {
//log.Println("match", entry)
return &entry
}
}
return nil
}
//Stolen from: https://github.com/drk1wi/Modlishka/blob/00a2385a0952c48202ed0e314b0be016e0613ba7/core/proxy.go#L375
func decompress(httpResponse *http.Response) (buffer []byte, err error) {
body := httpResponse.Body
compression := httpResponse.Header.Get("Content-Encoding")
var reader io.ReadCloser
switch compression {
case "x-gzip":
fallthrough
case "gzip":
// A format using the Lempel-Ziv coding (LZ77), with a 32-bit CRC.
reader, err = gzip.NewReader(body)
if err != io.EOF {
buffer, _ = io.ReadAll(reader)
defer reader.Close()
} else {
// Unset error
err = nil
}
case "deflate":
// Using the zlib structure (defined in RFC 1950) with the deflate compression algorithm (defined in RFC 1951).
reader = flate.NewReader(body)
buffer, _ = io.ReadAll(reader)
defer reader.Close()
case "br":
// A format using the Brotli algorithm.
c := brotli.ReaderConfig{}
reader, err = brotli.NewReader(body, &c)
buffer, _ = io.ReadAll(reader)
defer reader.Close()
case "compress":
// Unhandled: Fallback to default
fallthrough
default:
reader = body
buffer, err = io.ReadAll(reader)
if err != nil {
return nil, err
}
defer reader.Close()
}
return
}
// GZIP content
func gzipBuffer(input []byte) []byte {
var b bytes.Buffer
gz := gzip.NewWriter(&b)
if _, err := gz.Write(input); err != nil {
panic(err)
}
if err := gz.Flush(); err != nil {
panic(err)
}
if err := gz.Close(); err != nil {
panic(err)
}
return b.Bytes()
}
// Deflate content
func deflateBuffer(input []byte) []byte {
var b bytes.Buffer
zz, err := flate.NewWriter(&b, 0)
if err != nil {
panic(err)
}
if _, err = zz.Write(input); err != nil {
panic(err)
}
if err := zz.Flush(); err != nil {
panic(err)
}
if err := zz.Close(); err != nil {
panic(err)
}
return b.Bytes()
}
func compress(httpResponse *http.Response, buffer []byte) {
compression := httpResponse.Header.Get("Content-Encoding")
switch compression {
case "x-gzip":
fallthrough
case "gzip":
buffer = gzipBuffer(buffer)
case "deflate":
buffer = deflateBuffer(buffer)
case "br":
// Brotli writer is not available just compress with something else
httpResponse.Header.Set("Content-Encoding", "deflate")
buffer = deflateBuffer(buffer)
default:
// Whatif?
}
body := io.NopCloser(bytes.NewReader(buffer))
httpResponse.Body = body
httpResponse.ContentLength = int64(len(buffer))
httpResponse.Header.Set("Content-Length", strconv.Itoa(len(buffer)))
httpResponse.Body.Close()
}