this one burned up on re-entry, but philly was great!
[k_transpose.git] / httpd.go
1 package main
2
3 import(
4 "fmt"
5 "os"
6
7 "io"
8 "io/ioutil"
9 "bufio"
10
11 "strings"
12 "strconv"
13
14 "net/http"
15 "net/url"
16
17 "github.com/wsxiaoys/terminal/color"
18 )
19
20 /* holds our palette, or 16 ANSI colors (8 normal colors + bright complements)
21 and two foreground/background colors. colors are 3 byte arrays (RGB) */
22 type ktPalette struct {
23
24 black [3]byte
25 bblack [3]byte
26
27 red [3]byte
28 bred [3]byte
29
30 green [3]byte
31 bgreen [3]byte
32
33 yellow [3]byte
34 byellow [3]byte
35
36 blue [3]byte
37 bblue [3]byte
38
39 purple [3]byte
40 bpurple [3]byte
41
42 cyan [3]byte
43 bcyan [3]byte
44
45 white [3]byte
46 bwhite [3]byte
47
48 fg [3]byte
49 bg [3]byte
50 }
51
52 /* the default "control" ANSI color set (boring) */
53 var ansiColors = ktPalette {
54
55 black : [3]byte {0,0,0},
56 bblack : [3]byte {128,128,128},
57
58 red : [3]byte {128,0,0},
59 bred : [3]byte {255,0,0},
60
61 green : [3]byte {0,128,0},
62 bgreen : [3]byte {0,255,0},
63
64 yellow : [3]byte {128,128,0},
65 byellow : [3]byte {255,255,0},
66
67 blue : [3]byte {0,0,128},
68 bblue : [3]byte {0,0,255},
69
70 purple : [3]byte {128,0,128},
71 bpurple : [3]byte {255,0,255},
72
73 cyan : [3]byte {0,128,128},
74 bcyan : [3]byte {0,255,255},
75
76 white : [3]byte {128,128,128},
77 bwhite : [3]byte {255,255,255},
78
79 fg : [3]byte {0,0,0},
80 bg : [3]byte {255,255,255},
81 }
82
83 /* lets get our money's worth out of this utf-8 crap */
84 var checkM = "✓"
85 var xM = "✗"
86
87 /* parses a colorfile, returns palette struct. given a nil file pointer,
88 returns standard ANSI color set (our "control") */
89 func parseColors(colorfile *os.File) (pal ktPalette, err error) {
90
91 if colorfile == nil { return ansiColors, nil }
92
93 ret := ktPalette {}
94 var e errConsumer
95
96 scanner := bufio.NewScanner(colorfile)
97 for scanner.Scan() {
98
99 if strings.Contains(scanner.Text(), "color") &&
100 !strings.Contains(scanner.Text(), "!") {
101
102 /* i am so sorry */
103 cur := strings.Replace(scanner.Text(), " ", "", -1)
104 split := strings.Split(cur, ":")
105 hexColor := strings.Replace(split[1], "#", "", -1)
106 coNumStr := strings.Replace(split[0], "URxvt*color", "", -1)
107
108 r, err := strconv.ParseUint(hexColor[0:2], 16, 8); e.Consume(err)
109 g, err := strconv.ParseUint(hexColor[2:4], 16, 8); e.Consume(err)
110 b, err := strconv.ParseUint(hexColor[4:], 16, 8); e.Consume(err)
111
112 colorNo, err := strconv.Atoi(coNumStr); e.Consume(err)
113
114 if e.err != nil {
115 return ktPalette{}, e.err
116 }
117
118 switch(colorNo) {
119 case 0: ret.black[0] = byte(r); ret.black[1] = byte(g); ret.black[2] = byte(b)
120 case 1: ret.red[0] = byte(r); ret.red[1] = byte(g); ret.red[2] = byte(b)
121 case 2: ret.green[0] = byte(r); ret.green[1] = byte(g); ret.green[2] = byte(b)
122 case 3: ret.yellow[0] = byte(r); ret.yellow[1] = byte(g); ret.yellow[2] = byte(b)
123 case 4: ret.blue[0] = byte(r); ret.blue[1] = byte(g); ret.blue[2] = byte(b)
124 case 5: ret.purple[0] = byte(r); ret.purple[1] = byte(g); ret.purple[2] = byte(b)
125 case 6: ret.cyan[0] = byte(r); ret.cyan[1] = byte(g); ret.cyan[2] = byte(b)
126 case 7: ret.white[0] = byte(r); ret.white[1] = byte(g); ret.white[2] = byte(b)
127 case 8: ret.bblack[0] = byte(r); ret.bblack[1] = byte(g); ret.bblack[2] = byte(b)
128 case 9: ret.bred[0] = byte(r); ret.bred[1] = byte(g); ret.bred[2] = byte(b)
129 case 10: ret.bgreen[0] = byte(r); ret.bgreen[1] = byte(g); ret.bgreen[2] = byte(b)
130 case 11: ret.byellow[0] = byte(r); ret.byellow[1] = byte(g); ret.byellow[2] = byte(b)
131 case 12: ret.bblue[0] = byte(r); ret.bblue[1] = byte(g); ret.bblue[2] = byte(b)
132 case 13: ret.bpurple[0] = byte(r); ret.bpurple[1] = byte(g); ret.bpurple[2] = byte(b)
133 case 14: ret.bcyan[0] = byte(r); ret.bcyan[1] = byte(g); ret.bcyan[2] = byte(b)
134 case 15: ret.bwhite[0] = byte(r); ret.bwhite[1] = byte(g); ret.bwhite[2] = byte(b)
135 }
136
137 } else if strings.Contains(scanner.Text(), "background") {
138
139 hex := strings.Split(scanner.Text(), "#")
140 het := hex[1]
141
142 r, err := strconv.ParseUint(het[0:2], 16, 8); e.Consume(err)
143 g, err := strconv.ParseUint(het[2:4], 16, 8); e.Consume(err)
144 b, err := strconv.ParseUint(het[4:], 16, 8); e.Consume(err)
145
146 if e.err != nil {
147 return ktPalette{}, e.err
148 }
149
150 ret.bg[0] = byte(r)
151 ret.bg[1] = byte(g)
152 ret.bg[2] = byte(b)
153
154 } else if strings.Contains(scanner.Text(), "foreground") {
155
156 hex := strings.Split(scanner.Text(), "#")
157 het := hex[1]
158
159 r, err := strconv.ParseUint(het[0:2], 16, 8); e.Consume(err)
160 g, err := strconv.ParseUint(het[2:4], 16, 8); e.Consume(err)
161 b, err := strconv.ParseUint(het[4:], 16, 8); e.Consume(err)
162
163 if e.err != nil {
164 return ktPalette{}, e.err
165 }
166
167 ret.fg[0] = byte(r)
168 ret.fg[1] = byte(g)
169 ret.fg[2] = byte(b)
170 }
171 }
172
173 return ret, e.err
174 }
175
176 var httpdStatus bool
177
178 func ktInit(dirPrepend string, port int, colorfilePath string) error {
179
180 httpdStatus = false
181
182 color.Print("@yparsing colorfile :: @{|}")
183 file, err := os.Open(colorfilePath)
184 if err != nil {
185 color.Printf("@r[%s]@{|} - bad colorfile path\n", xM)
186 return fmt.Errorf("%s\n", "bad colorfile path")
187 }
188
189 pal, err := parseColors(file)
190
191 if err != nil {
192 color.Printf("@r[%s]@{|} - malformed colorfile [%s]\n", xM, err)
193 return fmt.Errorf("%s\n", "malformed colorfile")
194 }
195
196 color.Printf("@g[%s]@{|}\n", checkM)
197
198 if pal == ansiColors {}
199
200 color.Printf("@yverifying & preprocessing colorsets@{|} :: @y[SKIP]\n")
201 color.Printf("@ygenerating transpositional colorspace@{|} :: @y[SKIP]\n")
202
203 color.Printf("@ystarting httpd on port @b%d@{|} :: ", port)
204 http.HandleFunc("/kt/", transposePage)
205
206 var portString string
207 fmt.Sprintf(portString, ":%d", port)
208 err = http.ListenAndServe(portString, nil)
209 if err != nil {
210
211 color.Printf("@r[%s]@{-} - run me as root!\n", xM)
212 return fmt.Errorf("%s\n", "failed to start httpd")
213 }
214
215 color.Printf("@g[%s]@{-}\n", checkM)
216
217 return nil
218 }
219
220 func transposePage(writer http.ResponseWriter, req *http.Request) {
221
222 if !httpdStatus {
223
224 httpdStatus = true
225 color.Printf("@g[%s]@{|}\n", checkM)
226 }
227
228 if req.URL.Path == "/kt/" {
229 writer.Write([]byte("wtf"))
230 return
231 }
232
233 fqdn := req.URL.Path[4:]
234 targetURL := fmt.Sprintf("http://%s", fqdn)
235
236 resp, err := http.Get(targetURL)
237
238 if err != nil || resp.StatusCode != 200 {
239
240 io.WriteString(writer, "failed to get that page! -kt\n")
241 io.WriteString(writer, targetURL + "\n")
242
243 io.WriteString(writer, resp.Status)
244 return
245 }
246
247 conType := resp.Header.Get("Content-Type")
248
249 switch conType[0:strings.Index(conType, ";")] {
250
251 case "text/html":
252 writer.Write(transposeHTML(bufio.NewScanner(resp.Body), fqdn))
253
254 case "text/css":
255 writer.Write(transposeCSS(bufio.NewScanner(resp.Body), fqdn))
256
257 default:
258 page, _ := ioutil.ReadAll(resp.Body)
259 writer.Write(page)
260 }
261
262 resp.Body.Close()
263 }
264
265 /* swap href="" & src="" */
266 func transposeHTML(scan *bufio.Scanner, fqdn string) []byte {
267
268 var ret []byte
269 var i int
270
271 scan.Split(bufio.ScanWords)
272 for scan.Scan() {
273
274 i++
275 cur := scan.Text()
276
277 //fmt.Printf("%s\n", cur)
278
279 if len(cur) < 7 {
280
281
282 } else if(cur[0:6] == "href=\\") {
283
284 urlStr := cur[7:strings.Index(cur[7:], "\\") + 7]
285
286 u, err := url.Parse(urlStr)
287 if err != nil {
288 fmt.Printf("malformed URL: %s\n", urlStr)
289 }
290
291 if u.Host == "" {
292
293 u.Host = fmt.Sprintf("localhost/kt/%s", fqdn)
294 // cur = append(cur[0:6],
295 }
296
297 fmt.Printf("[F] URL: %s // PATH: %s\n", u.Host, u.Path)
298 if u == u {}
299
300
301 } else if(cur[0:5] == "href=") {
302
303 urlStr := cur[6:strings.Index(cur[6:], "\"") + 6]
304
305 u, err := url.Parse(urlStr)
306 if err != nil {
307 fmt.Printf("malformed URL: %s\n", urlStr)
308 }
309
310 if u == u {}
311 fmt.Printf("URL: %s // PATH: %s\n", u.Host, u.Path)
312
313 } else if(cur[0:5] == "src=\"") {
314
315 //fmt.Printf("%s\n", cur)
316 urlStr := cur[5:strings.Index(cur[5:], "\"") + 5]
317
318 u, err := url.Parse(urlStr)
319 if err != nil {
320 fmt.Printf("malformed URL: %s\n", urlStr)
321 }
322
323 if u.Host == "" {
324
325 u.Host = fmt.Sprintf("localhost/kt/%s", fqdn)
326 // cur = append(cur[0:6],
327
328 fmt.Printf("[S] URL: %s // PATH: %s\n", u.Host, u.Path)
329 if u == u {}
330 }
331
332 }
333
334 ret = append(ret, byte(' '))
335 ret = append(ret, cur...)
336 }
337
338 fmt.Printf("%d\n", i)
339
340 return ret
341 }
342
343 func transposeCSS(scan *bufio.Scanner, fqdn string) []byte {
344
345 var ret []byte
346
347 return ret
348 }
349
350 func main() {
351
352 err := ktInit("kolors", 999, "/home/kremlin/.Xresources")
353
354 if err != nil {}
355 }
356
357 type errConsumer struct {
358 err error
359 }
360
361 func (e *errConsumer) Consume(err error) {
362 if e.err == nil && err != nil {
363 e.err = err
364 }
365 }
366