hproxy: simple http proxy server
This commit is contained in:
parent
51915912e9
commit
fdfce9d864
2 changed files with 104 additions and 1 deletions
|
@ -1,6 +1,6 @@
|
|||
.TH IPSERV 8
|
||||
.SH NAME
|
||||
telnetd, rlogind, rexexec, ftpd, socksd \- Internet remote access daemons
|
||||
telnetd, rlogind, rexexec, ftpd, socksd, hproxy \- Internet remote access daemons
|
||||
.SH SYNOPSIS
|
||||
.B ip/telnetd
|
||||
.RB [ -adnptN ]
|
||||
|
@ -24,6 +24,8 @@ telnetd, rlogind, rexexec, ftpd, socksd \- Internet remote access daemons
|
|||
.B -o
|
||||
.I outside
|
||||
]
|
||||
.PP
|
||||
.B ip/hproxy
|
||||
.SH DESCRIPTION
|
||||
These programs support remote access across the Internet. All expect the
|
||||
network connection to be standard input, output, and error. They are normally
|
||||
|
@ -200,6 +202,9 @@ and
|
|||
.I outside
|
||||
will default to
|
||||
.BR /net .
|
||||
.PP
|
||||
.I Hproxy
|
||||
is a simple HTTP proxy server.
|
||||
.SH FILES
|
||||
.B /lib/namepace
|
||||
.br
|
||||
|
@ -218,6 +223,8 @@ will default to
|
|||
.B /sys/src/cmd/ip/ftpd.c
|
||||
.br
|
||||
.B /sys/src/cmd/ip/socksd.c
|
||||
.br
|
||||
.B /sys/src/cmd/ip/hproxy.c
|
||||
.SH "SEE ALSO"
|
||||
.IR ftpfs (4),
|
||||
.IR pop3 (8)
|
||||
|
|
96
sys/src/cmd/ip/hproxy.c
Normal file
96
sys/src/cmd/ip/hproxy.c
Normal file
|
@ -0,0 +1,96 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
enum { bufsize = 8*1024 };
|
||||
char buf[bufsize+1], addr[128], *proto, *host, *port, *path;
|
||||
|
||||
void
|
||||
main(void)
|
||||
{
|
||||
char *f[3], *p, *e;
|
||||
int con, fd, n, r;
|
||||
|
||||
/* read all the headers */
|
||||
n = 0;
|
||||
do {
|
||||
if(n >= bufsize)
|
||||
return;
|
||||
if((r = read(0, buf+n, bufsize-n)) <= 0)
|
||||
return;
|
||||
n += r;
|
||||
buf[n] = 0;
|
||||
} while(strstr(buf, "\r\n\r\n") == nil);
|
||||
|
||||
/* remove keep alive headers */
|
||||
if(p = cistrstr(buf, "\nConnection:"))
|
||||
if(e = strchr(p+1, '\n'))
|
||||
strcpy(p, e);
|
||||
if(p = cistrstr(buf, "\nProxy-Connection:"))
|
||||
if(e = strchr(p+1, '\n'))
|
||||
strcpy(p, e);
|
||||
|
||||
/* crack first line of http request */
|
||||
if(e = strchr(buf, '\n'))
|
||||
*e++ = 0;
|
||||
r = tokenize(buf, f, 3);
|
||||
if(r < 2)
|
||||
return;
|
||||
if(r == 2)
|
||||
f[2] = "HTTP/1.0";
|
||||
proto = f[1];
|
||||
if(p = strstr(proto, "://")){
|
||||
*p = 0;
|
||||
host = p + 3;
|
||||
} else {
|
||||
host = proto;
|
||||
proto = "http";
|
||||
}
|
||||
port = proto;
|
||||
path = "";
|
||||
if(p = strchr(host, '/')){
|
||||
*p++ = 0;
|
||||
path = p;
|
||||
}
|
||||
if(*host == '[')
|
||||
host++;
|
||||
if(p = strrchr(host, ':')){
|
||||
*p++ = 0;
|
||||
port = p;
|
||||
}
|
||||
if(p = strrchr(host, ']'))
|
||||
*p = 0;
|
||||
|
||||
snprint(addr, sizeof(addr), "tcp!%s!%s", host, port);
|
||||
|
||||
alarm(30000);
|
||||
fd = dial(addr, 0, 0, 0);
|
||||
alarm(0);
|
||||
|
||||
con = cistrcmp(f[0], "CONNECT") == 0;
|
||||
if(con){
|
||||
if(fd < 0)
|
||||
print("%s 500 Connection Failed\r\n\r\n%r\n", f[2]);
|
||||
else
|
||||
print("%s 200 Connection Established\r\n\r\n", f[2]);
|
||||
}
|
||||
if(fd < 0)
|
||||
return;
|
||||
|
||||
switch(rfork(RFPROC|RFFDG|RFNOWAIT)){
|
||||
case -1:
|
||||
return;
|
||||
case 0:
|
||||
dup(fd, 0);
|
||||
break;
|
||||
default:
|
||||
dup(fd, 1);
|
||||
if(!con)
|
||||
print("%s /%s %s\r\n%s", f[0], path, f[2], e);
|
||||
}
|
||||
|
||||
while((r = read(0, buf, sizeof(buf))) > 0)
|
||||
if(write(1, buf, r) != r)
|
||||
break;
|
||||
|
||||
postnote(PNGROUP, getpid(), "kill");
|
||||
}
|
Loading…
Reference in a new issue