remove traces of benchmarks from test/.
[minix.git] / commands / httpd / proxy.c
blobd93acee9e19d8e3bb7a9a8cd6892b7b44c22057c
1 /* proxy.c Copyright 2000 by Michael Temari All Rights Reserved */
3 #include <sys/types.h>
4 #include <sys/ioctl.h>
5 #include <sys/wait.h>
6 #include <stdio.h>
7 #include <ctype.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <errno.h>
11 #include <fcntl.h>
12 #include <signal.h>
13 #include <unistd.h>
14 #include <time.h>
15 #include <net/netlib.h>
16 #include <net/hton.h>
17 #include <net/gen/in.h>
18 #include <net/gen/inet.h>
19 #include <net/gen/tcp.h>
20 #include <net/gen/tcp_io.h>
21 #include <net/gen/socket.h>
22 #include <net/gen/netdb.h>
24 #include "config.h"
25 #include "http.h"
26 #include "utility.h"
27 #include "net.h"
29 _PROTOTYPE(static int connect, (char *host));
30 #if 0
31 _PROTOTYPE(static int readline, (char *p, int len));
32 #endif
33 _PROTOTYPE(static int sendout, (int fd, char *data));
35 static int connect(host)
36 char *host;
38 nwio_tcpconf_t tcpconf;
39 nwio_tcpcl_t tcpcopt;
40 char *tcp_device;
41 int netfd;
42 ipaddr_t nethost;
43 tcpport_t netport = 0;
44 struct hostent *hp;
45 struct servent *sp;
46 char *p;
47 int s;
48 int tries;
50 p = host;
51 while(*p && *p != ':') p++;
52 if(*p == ':') {
53 *p++ = '\0';
54 netport = htons(atoi(p));
57 if((hp = gethostbyname(host)) == (struct hostent *)NULL) {
58 fprintf(stderr, "Unknown host %s!\n", host);
59 return(-1);
60 } else
61 memcpy((char *) &nethost, (char *) hp->h_addr, hp->h_length);
63 /* Now, to which port must we connect? */
64 if(netport == 0)
65 if((sp = getservbyname("http", "tcp")) == (struct servent *)NULL) {
66 fprintf(stderr, "HTTP port is unknown????\n");
67 return(-1);
68 } else
69 netport = sp->s_port;
71 /* Connect to the host */
72 if((tcp_device = getenv("TCP_DEVICE")) == NULL)
73 tcp_device = TCP_DEVICE;
75 if((netfd = open(tcp_device, O_RDWR)) < 0) {
76 perror("httpget: opening tcp");
77 return(-1);
80 tcpconf.nwtc_flags = NWTC_LP_SEL | NWTC_SET_RA | NWTC_SET_RP;
81 tcpconf.nwtc_remaddr = nethost;
82 tcpconf.nwtc_remport = netport;
84 s = ioctl(netfd, NWIOSTCPCONF, &tcpconf);
85 if(s < 0) {
86 perror("httpget: NWIOSTCPCONF");
87 close(netfd);
88 return(-1);
91 s = ioctl(netfd, NWIOGTCPCONF, &tcpconf);
92 if(s < 0) {
93 perror("httpget: NWIOGTCPCONF");
94 close(netfd);
95 return(-1);
98 tcpcopt.nwtcl_flags = 0;
100 tries = 0;
101 do {
102 s = ioctl(netfd, NWIOTCPCONN, &tcpcopt);
103 if(s == -1 && errno == EAGAIN) {
104 if(tries++ >= 10)
105 break;
106 sleep(10);
107 } else
108 break;
109 } while(1);
111 if(s < 0) {
112 perror("httpget: NWIOTCPCONN");
113 close(netfd);
114 return(-1);
117 return(netfd);
120 char buffer[8192];
122 #if 0
123 static int readline(p, len)
124 char *p;
125 int len;
127 int c;
128 int cr = 0;
129 int n = 0;
131 len--;
132 if(len < 0) return(-1);
133 while(len > 0 && (c = getchar()) != EOF) {
134 if(c == '\n' && cr) {
135 *p = '\0';
136 return(n);
138 if(c == '\r') {
139 cr = 1;
140 continue;
142 n++;
143 *p++ = c;
145 *p = '\0';
146 return(n);
148 #endif
150 static int sendout(fd, data)
151 int fd;
152 char *data;
154 if(strlen(data) > 0)
155 write(fd, data, strlen(data));
156 write(fd, "\r\n", 2);
157 if(dbglog != (FILE *)NULL) {
158 fprintf(dbglog, "REPLY: %s\n", data);
159 fflush(dbglog);
162 return(0);
165 void proxy(rq, rp)
166 struct http_request *rq;
167 struct http_reply *rp;
169 int s;
170 char *p;
171 char *ps;
172 char *b;
173 char *host;
174 static char user[256];
175 static char pass[256];
176 char *url;
177 char *at;
178 int fd;
179 int bad;
181 while(1) {
182 bad = 0;
183 p = rq->uri;
184 if(tolower(*p++) != 'h') bad++;
185 if(tolower(*p++) != 't') bad++;
186 if(tolower(*p++) != 't') bad++;
187 if(tolower(*p++) != 'p') bad++;
188 if(tolower(*p++) != ':') bad++;
189 if(tolower(*p++) != '/') bad++;
190 if(tolower(*p++) != '/') bad++;
191 if(bad) {
192 sprintf(buffer, "HTTP/%d.%d 400 Bad Request",
193 rq->vmajor, rq->vminor);
194 sendout(1, buffer);
195 sendout(1, "");
196 sendout(1, "Proxy Request was not http:");
197 return;
199 host = p;
200 while(*p && *p != '/') p++;
201 url = p;
202 *url = '\0';
203 at = strchr(host, '@');
204 if(at != (char *)NULL) {
205 *at = '\0';
206 p = host;
207 while(*p && *p != ':') p++;
208 if(*p)
209 *p++ = '\0';
210 strcpy(user, host);
211 strcpy(pass, p);
212 host = at + 1;
213 } else {
214 user[0] = '\0';
215 pass[0] = '\0';
218 fd = connect(host);
219 if(fd < 0) {
220 sprintf(buffer, "HTTP/%d.%d 400 Bad Request",
221 rq->vmajor, rq->vminor);
222 sendout(1, buffer);
223 sendout(1, "");
224 sendout(1, "Could not connect to host");
225 return;
227 if(rq->method == HTTP_METHOD_GET)
228 write(fd, "GET ", 4); else
229 if(rq->method == HTTP_METHOD_POST)
230 write(fd, "POST ", 5);
231 *url = '/';
232 if(strlen(url) > 0)
233 write(fd, url, strlen(url));
234 write(fd, " ", 1);
235 sprintf(buffer, "HTTP/%d.%d", rq->vmajor, rq->vminor);
236 sendout(fd, buffer);
237 if(rq->ifmodsince != -1) {
238 write(fd, "If-Mod-Since: ", 14);
239 sendout(fd, httpdate(&rq->ifmodsince));
241 if(rq->size != 0) {
242 sendout(fd, "Content-Type: application/x-www-form-urlencoded");
243 sprintf(buffer, "Content-Length: %lu", rq->size);
244 sendout(fd, buffer);
246 if(*rq->cookie) {
247 sprintf(buffer, "Cookie: %s", rq->cookie);
248 sendout(fd, buffer);
250 if(*rq->useragent) {
251 sprintf(buffer, "User-Agent: %s", rq->useragent);
252 sendout(fd, buffer);
254 if(*rq->host) {
255 sprintf(buffer, "Host: %s", rq->host);
256 sendout(fd, buffer);
258 if(*rq->wwwauth) {
259 sprintf(buffer, "Authorization: %s", rq->wwwauth);
260 sendout(fd, buffer);
262 sprintf(buffer, "X-Forwarded-From: %s", rmthostaddr);
263 sendout(fd, buffer);
264 sendout(fd, "");
265 if(rq->size != 0) {
266 if(stdlog != (FILE *)NULL) {
267 fprintf(stdlog, "%s %s %d %d ",
268 logdate((time_t *)NULL), rmthostname,
269 rq->method, rp->status);
270 fprintf(stdlog, "proxy %s?", rq->uri);
272 while((s = read(0, buffer, rq->size >
273 sizeof(buffer) ? sizeof(buffer) : rq->size)) > 0) {
274 write(fd, buffer, s);
275 rq->size -= s;
276 b = buffer;
277 if(stdlog != (FILE *)NULL)
278 while(s--) fputc(*b++, stdlog);
279 if(rq->size == 0) break;
281 if(stdlog != (FILE *)NULL) {
282 fprintf(stdlog, "\n");
283 fflush(stdlog);
286 while((s = read(fd, buffer, sizeof(buffer))) > 0) {
287 write(1, buffer, s);
289 close(fd);
290 return;