forked from cyfdecyf/cow
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpac.go
107 lines (93 loc) · 2.06 KB
/
pac.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
package main
import (
"bufio"
"bytes"
"fmt"
"os"
"strings"
"text/template"
)
var pacRawTmpl = `var direct = 'DIRECT';
var httpProxy = 'PROXY {{.ProxyAddr}}; DIRECT';
var directList = [
localhost,
0.1,
"{{.DirectDomains}}"
];
var directAcc = {};
for (var i = 0; i < directList.length; i += 1) {
directAcc[directList[i]] = true;
}
var topLevel = {
"co": true,
"org": true,
"com": true,
"net": true,
"edu": true
};
function host2domain(host) {
var lastDot = host.lastIndexOf(".");
if (lastDot === -1)
return host;
// Find the second last dot
dot2ndLast = host.lastIndexOf(".", lastDot-1);
if (dot2ndLast === -1)
return host;
var part = host.substring(dot2ndLast+1, lastDot)
if (topLevel[part]) {
var dot3rdLast = host.lastIndexOf(".", dot2ndLast-1)
if (dot3rdLast === -1) {
return host
}
return host.substring(dot3rdLast+1)
}
return host.substring(dot2ndLast+1);
};
function FindProxyForURL(url, host) {
return directAcc[host2domain(host)] ? direct : httpProxy;
};
`
var pacTmpl *template.Template
func init() {
var err error
pacTmpl, err = template.New("pac").Parse(pacRawTmpl)
if err != nil {
fmt.Println("Internal error on generating pac file template")
os.Exit(1)
}
}
func genPAC() string {
// domains in PAC file needs double quote
ds1 := strings.Join(alwaysDirectDs.toArray(), "\",\n\"")
ds2 := strings.Join(directDs.toArray(), "\",\n\"")
var ds string
if ds1 == "" {
ds = ds2
} else if ds2 == "" {
ds = ds1
} else {
ds = ds1 + "\",\n\"" + ds2
}
data := struct {
ProxyAddr string
DirectDomains string
}{
config.listenAddr,
ds,
}
// debug.Println("direct:", data.DirectDomains)
buf := new(bytes.Buffer)
if err := pacTmpl.Execute(buf, data); err != nil {
errl.Println("Error generating pac file:", err)
os.Exit(1)
}
pac := buf.String()
pacHeader := "HTTP/1.1 200 Okay\r\nServer: cow-proxy\r\nContent-Type: text/html\r\nConnection: close\r\n" +
fmt.Sprintf("Content-Length: %d\r\n\r\n", len(pac))
pac = pacHeader + pac
return pac
}
func sendPAC(w *bufio.Writer) {
w.WriteString(genPAC())
w.Flush()
}