]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/ip/hproxy.c
merge
[plan9front.git] / sys / src / cmd / ip / hproxy.c
1 #include <u.h>
2 #include <libc.h>
3
4 enum { bufsize = 8*1024 };
5 char buf[bufsize+1], addr[128], *proto, *host, *port, *path;
6
7 void
8 main(void)
9 {
10         char *f[3], *p, *e;
11         int con, fd, n, r;
12
13         /* read all the headers */
14         n = 0;
15         do {
16                 if(n >= bufsize)
17                         return;
18                 if((r = read(0, buf+n, bufsize-n)) <= 0)
19                         return;
20                 n += r;
21                 buf[n] = 0;
22         } while(strstr(buf, "\r\n\r\n") == nil);
23
24         /* remove keep alive headers */
25         if(p = cistrstr(buf, "\nConnection:"))
26                 if(e = strchr(p+1, '\n'))
27                         strcpy(p, e);
28         if(p = cistrstr(buf, "\nProxy-Connection:"))
29                 if(e = strchr(p+1, '\n'))
30                         strcpy(p, e);
31
32         /* crack first line of http request */
33         if(e = strchr(buf, '\n'))
34                 *e++ = 0;
35         r = tokenize(buf, f, 3);
36         if(r < 2)
37                 return;
38         if(r == 2)
39                 f[2] = "HTTP/1.0";
40         proto = f[1];
41         if(p = strstr(proto, "://")){
42                 *p = 0;
43                 host = p + 3;
44         } else {
45                 host = proto;
46                 proto = "http";
47         }
48         port = proto;
49         path = "";
50         if(p = strchr(host, '/')){
51                 *p++ = 0;
52                 path = p;
53         }
54         if(*host == '['){
55                 host++;
56                 if(p = strrchr(host, ']')){
57                         *p++ = 0;
58                         if(p = strrchr(p, ':'))
59                                 port = ++p;
60                 }
61         } else if(p = strrchr(host, ':')){
62                 *p++ = 0;
63                 port = p;
64         }
65
66         snprint(addr, sizeof(addr), "tcp!%s!%s", host, port);
67
68         alarm(30000);
69         fd = dial(addr, 0, 0, 0);
70         alarm(0);
71
72         con = cistrcmp(f[0], "CONNECT") == 0;
73         if(con){
74                 if(fd < 0)
75                         print("%s 500 Connection Failed\r\n\r\n%r\n", f[2]);
76                 else
77                         print("%s 200 Connection Established\r\n\r\n", f[2]);
78         }
79         if(fd < 0)
80                 return;
81
82         switch(rfork(RFPROC|RFFDG|RFNOWAIT)){
83         case -1:
84                 return;
85         case 0:
86                 dup(fd, 0);
87                 break;
88         default:
89                 dup(fd, 1);
90                 if(!con)
91                         print("%s /%s %s\r\nConnection: close\r\n%s", f[0], path, f[2], e);
92         }
93
94         while((r = read(0, buf, sizeof(buf))) > 0)
95                 if(write(1, buf, r) != r)
96                         break;
97
98         postnote(PNGROUP, getpid(), "kill");
99 }