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