source: trunk/minix/commands/httpd/proxy.c@ 15

Last change on this file since 15 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 5.9 KB
Line 
1/* proxy.c Copyright 2000 by Michael Temari All Rights Reserved */
2
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>
23
24#include "config.h"
25#include "http.h"
26#include "utility.h"
27#include "net.h"
28
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));
34
35static int connect(host)
36char *host;
37{
38nwio_tcpconf_t tcpconf;
39nwio_tcpcl_t tcpcopt;
40char *tcp_device;
41int netfd;
42ipaddr_t nethost;
43tcpport_t netport = 0;
44struct hostent *hp;
45struct servent *sp;
46char *p;
47int s;
48int tries;
49
50 p = host;
51 while(*p && *p != ':') p++;
52 if(*p == ':') {
53 *p++ = '\0';
54 netport = htons(atoi(p));
55 }
56
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);
62
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;
70
71 /* Connect to the host */
72 if((tcp_device = getenv("TCP_DEVICE")) == NULL)
73 tcp_device = TCP_DEVICE;
74
75 if((netfd = open(tcp_device, O_RDWR)) < 0) {
76 perror("httpget: opening tcp");
77 return(-1);
78 }
79
80 tcpconf.nwtc_flags = NWTC_LP_SEL | NWTC_SET_RA | NWTC_SET_RP;
81 tcpconf.nwtc_remaddr = nethost;
82 tcpconf.nwtc_remport = netport;
83
84 s = ioctl(netfd, NWIOSTCPCONF, &tcpconf);
85 if(s < 0) {
86 perror("httpget: NWIOSTCPCONF");
87 close(netfd);
88 return(-1);
89 }
90
91 s = ioctl(netfd, NWIOGTCPCONF, &tcpconf);
92 if(s < 0) {
93 perror("httpget: NWIOGTCPCONF");
94 close(netfd);
95 return(-1);
96 }
97
98 tcpcopt.nwtcl_flags = 0;
99
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);
110
111 if(s < 0) {
112 perror("httpget: NWIOTCPCONN");
113 close(netfd);
114 return(-1);
115 }
116
117 return(netfd);
118}
119
120char buffer[8192];
121
122#if 0
123static int readline(p, len)
124char *p;
125int len;
126{
127int c;
128int cr = 0;
129int n = 0;
130
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);
137 }
138 if(c == '\r') {
139 cr = 1;
140 continue;
141 }
142 n++;
143 *p++ = c;
144 }
145 *p = '\0';
146 return(n);
147}
148#endif
149
150static int sendout(fd, data)
151int fd;
152char *data;
153{
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);
160 }
161
162 return(0);
163}
164
165void proxy(rq, rp)
166struct http_request *rq;
167struct http_reply *rp;
168{
169int s;
170char *p;
171char *ps;
172char *b;
173char *host;
174static char user[256];
175static char pass[256];
176char *url;
177char *at;
178int fd;
179int bad;
180
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;
198 }
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';
216 }
217
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;
226 }
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));
240 }
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);
245 }
246 if(*rq->cookie) {
247 sprintf(buffer, "Cookie: %s", rq->cookie);
248 sendout(fd, buffer);
249 }
250 if(*rq->useragent) {
251 sprintf(buffer, "User-Agent: %s", rq->useragent);
252 sendout(fd, buffer);
253 }
254 if(*rq->host) {
255 sprintf(buffer, "Host: %s", rq->host);
256 sendout(fd, buffer);
257 }
258 if(*rq->wwwauth) {
259 sprintf(buffer, "Authorization: %s", rq->wwwauth);
260 sendout(fd, buffer);
261 }
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);
271 }
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;
280 }
281 if(stdlog != (FILE *)NULL) {
282 fprintf(stdlog, "\n");
283 fflush(stdlog);
284 }
285 }
286 while((s = read(fd, buffer, sizeof(buffer))) > 0) {
287 write(1, buffer, s);
288 }
289 close(fd);
290 return;
291 }
292}
Note: See TracBrowser for help on using the repository browser.