2a2a5b | 1996-12-01 | Per Hedbor | |
|
86729e | 1997-09-06 | Per Hedbor | | constant cvs_version = "$Id: http.pike,v 1.41 1997/09/05 22:34:14 per Exp $";
|
2a2a5b | 1996-12-01 | Per Hedbor | |
|
b1fca0 | 1996-11-12 | Per Hedbor | | #include <config.h>
|
fc2fcf | 1997-04-13 | Per Hedbor | | private inherit "roxenlib";
|
b1fca0 | 1996-11-12 | Per Hedbor | | int first;
|
d7b087 | 1997-08-31 | Per Hedbor | |
|
14179b | 1997-01-29 | Per Hedbor | | constant decode=roxen->decode;
constant find_supports=roxen->find_supports;
constant version=roxen->version;
constant handle=roxen->handle;
constant _query=roxen->query;
|
0829d5 | 1997-03-03 | Henrik Grubbström (Grubba) | | import Simulate;
|
b1fca0 | 1996-11-12 | Per Hedbor | |
function _time=time;
|
7ee565 | 1996-12-10 | Per Hedbor | | private static array(string) cache;
private static int wanted_data, have_data;
|
b1fca0 | 1996-11-12 | Per Hedbor | | object conf;
#ifdef REQUEST_DEBUG
int kept_alive;
#endif
#include <roxen.h>
#include <module.h>
|
ceb927 | 1997-05-15 | David Hedbor | | #undef SPEED_MAX
|
b1fca0 | 1996-11-12 | Per Hedbor | |
#undef QUERY
|
14179b | 1997-01-29 | Per Hedbor | | #define QUERY(X) _query("X")
|
b1fca0 | 1996-11-12 | Per Hedbor | |
int time;
string raw_url;
|
d7b087 | 1997-08-31 | Per Hedbor | | int do_not_disconnect;
|
b1fca0 | 1996-11-12 | Per Hedbor | |
mapping (string:string) variables = ([ ]);
|
d7b087 | 1997-08-31 | Per Hedbor | |
|
b1fca0 | 1996-11-12 | Per Hedbor | | mapping (string:mixed) misc = ([ ]);
multiset (string) prestate = (< >);
multiset (string) config = (< >);
multiset (string) supports = (< >);
string remoteaddr, host;
|
d7b087 | 1997-08-31 | Per Hedbor | | array (string) client = ({ });
|
b1fca0 | 1996-11-12 | Per Hedbor | | array (string) referer = ({ });
|
d7b087 | 1997-08-31 | Per Hedbor | | multiset (string) pragma = (< >);
|
b1fca0 | 1996-11-12 | Per Hedbor | |
mapping (string:string) cookies = ([ ]);
mixed file;
object my_fd;
object pipe;
string prot;
|
1afe37 | 1997-06-12 | Henrik Grubbström (Grubba) | | string clientprot;
|
b1fca0 | 1996-11-12 | Per Hedbor | | string method;
string realfile, virtfile;
string rest_query="";
string raw;
string query;
string not_query;
string extra_extension = "";
string data;
array (int|string) auth;
string rawauth, realauth;
string since;
|
ceb927 | 1997-05-15 | David Hedbor | | #if _DEBUG_HTTP_OBJECTS
int my_id;
int my_state;
#endif
|
b1fca0 | 1996-11-12 | Per Hedbor | |
void end(string|void);
private void setup_pipe(int noend)
{
|
ceb927 | 1997-05-15 | David Hedbor | | #if _DEBUG_HTTP_OBJECTS
my_state = 6;
#endif
|
184261 | 1997-05-30 | Henrik Grubbström (Grubba) | | if(!my_fd) {
end();
return;
}
|
5e8921 | 1997-02-13 | Per Hedbor | | if(!pipe) pipe=Pipe.pipe();
|
48fa36 | 1997-04-05 | Per Hedbor | |
|
b1fca0 | 1996-11-12 | Per Hedbor | | #ifdef REQUEST_DEBUG
perror("REQUEST: Pipe setup.\n");
#endif
}
void send(string|object what, int|void noend)
{
|
ceb927 | 1997-05-15 | David Hedbor | | #if _DEBUG_HTTP_OBJECTS
my_state = 7;
#endif
|
b1fca0 | 1996-11-12 | Per Hedbor | | if(!what) return;
if(!pipe) setup_pipe(noend);
#ifdef REQUEST_DEBUG
perror("REQUEST: Sending some data\n");
#endif
if(stringp(what)) pipe->write(what);
else pipe->input(what);
}
string scan_for_query( string f )
{
|
ceb927 | 1997-05-15 | David Hedbor | | #if _DEBUG_HTTP_OBJECTS
my_state = 8;
#endif
|
b1fca0 | 1996-11-12 | Per Hedbor | | if(sscanf(f,"%s?%s", f, query) == 2)
{
string v, a, b;
foreach(query / "&", v)
if(sscanf(v, "%s=%s", a, b) == 2)
{
a = http_decode_string(replace(a, "+", " "));
b = http_decode_string(replace(b, "+", " "));
if(variables[ a ])
variables[ a ] += "\0" + b;
else
variables[ a ] = b;
} else
if(strlen( rest_query ))
rest_query += "&" + http_decode_string( v );
else
rest_query = http_decode_string( v );
}
rest_query=replace(rest_query, "+", "\000");
return f;
}
private int really_set_config(array mod_config)
{
string url, m;
string base;
|
14179b | 1997-01-29 | Per Hedbor | | base = conf->query("MyWorldLocation")||"/";
|
ceb927 | 1997-05-15 | David Hedbor | | #if _DEBUG_HTTP_OBJECTS
my_state = 8;
#endif
|
b1fca0 | 1996-11-12 | Per Hedbor | | if(supports->cookies)
{
#ifdef REQUEST_DEBUG
perror("Setting cookie..\n");
#endif
if(mod_config)
foreach(mod_config, m)
if(m[-1]=='-')
config[m[1..]]=0;
else
config[m]=1;
if(sscanf(replace(raw_url,({"%3c","%3e","%3C","%3E" }),
({"<",">","<",">"})),"/<%*s>/%s",url)!=2)
url = "/";
|
0ddff6 | 1997-07-20 | Henrik Grubbström (Grubba) | | if ((base[-1] == '/') && (url[0] == '/')) {
url = base + url[1..];
} else {
url = base + url;
}
my_fd->write(prot + " 302 Config in cookie!\r\n"
|
b1fca0 | 1996-11-12 | Per Hedbor | | "Set-Cookie: "
|
0ddff6 | 1997-07-20 | Henrik Grubbström (Grubba) | | + http_roxen_config_cookie(indices(config) * ",") + "\r\n"
"Location: " + url + "\r\n"
|
b1fca0 | 1996-11-12 | Per Hedbor | | "Content-Type: text/html\r\n"
"Content-Length: 0\r\n\r\n");
} else {
#ifdef REQUEST_DEBUG
perror("Setting {config} for user without Cookie support..\n");
#endif
if(mod_config)
foreach(mod_config, m)
if(m[-1]=='-')
prestate[m[1..]]=0;
else
prestate[m]=1;
|
0ddff6 | 1997-07-20 | Henrik Grubbström (Grubba) | | if (sscanf(replace(raw_url, ({ "%3c", "%3e", "%3C", "%3E" }),
({ "<", ">", "<", ">" })), "/<%*s>/%s", url) == 2) {
url = "/" + url;
}
if (sscanf(replace(url, ({ "%28", "%29" }), ({ "(", ")" })),
"/(%*s)/%s", url) == 2) {
url = "/" + url;
}
url = add_pre_state(url, prestate);
if (base[-1] == '/') {
url = base + url[1..];
} else {
url = base + url;
}
my_fd->write(prot + " 302 Config In Prestate!\r\n"
"\r\nLocation: " + url + "\r\n"
"Content-Type: text/html\r\n"
"Content-Length: 0\r\n\r\n");
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
return -2;
}
private int parse_got(string s)
{
|
ceb927 | 1997-05-15 | David Hedbor | | #if _DEBUG_HTTP_OBJECTS
|
2154ca | 1997-08-31 | Per Hedbor | | if(my_fd) catch{mark_fd(my_fd->query_fd(), "HTTP: Parsing");};
|
ceb927 | 1997-05-15 | David Hedbor | | my_state = 9;
#endif
|
b1fca0 | 1996-11-12 | Per Hedbor | | multiset (string) sup;
array mod_config;
mixed f, line;
string a, b, linename, contents, real_raw;
int config_in_url;
|
ceb927 | 1997-05-15 | David Hedbor | |
|
b1fca0 | 1996-11-12 | Per Hedbor | | real_raw = s;
s -= "\r";
|
1afe37 | 1997-06-12 | Henrik Grubbström (Grubba) | |
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
1afe37 | 1997-06-12 | Henrik Grubbström (Grubba) | | if((s[-1] != '\n') || (search(s, "HTTP/") >= 0))
|
b1fca0 | 1996-11-12 | Per Hedbor | | if(search(s, "\n\n") == -1)
return 0;
raw = s;
s = replace(s, "\t", " ");
|
1afe37 | 1997-06-12 | Henrik Grubbström (Grubba) | | #if 0
|
b1fca0 | 1996-11-12 | Per Hedbor | | if(sscanf(s,"%s %s %s\n%s", method, f, prot, s) < 4)
{
if(sscanf(s,"%s %s\n", method, f) < 2)
f="";
s="";
prot = "HTTP/0.9";
}
if(!method)
method = "GET";
|
1afe37 | 1997-06-12 | Henrik Grubbström (Grubba) | | #else
{
array arr = s/"\n";
prot = clientprot = "HTTP/0.9";
s="";
f="/";
method = "GET";
if (sizeof(arr[0])) {
array arr2 = arr[0]/" ";
switch(sizeof(arr2)) {
default:
case 3:
if ((clientprot = arr2[-1]) != "HTTP/0.9") {
prot = "HTTP/1.0";
if (sizeof(arr)>1) {
s = arr[1..]*"\n";
}
}
f = arr2[1..sizeof(arr2)-2]*" ";
method = arr2[0];
break;
case 2:
f = arr2[1];
case 1:
method = arr2[0];
break;
}
}
}
#endif /* 0 */
|
b1fca0 | 1996-11-12 | Per Hedbor | | method = upper_case(method);
if(method == "PING")
{
my_fd->write("PONG\n");
return -2;
}
raw_url = f;
time = _time(1);
|
b04f07 | 1997-01-29 | Per Hedbor | |
|
7ec660 | 1997-01-29 | Per Hedbor | |
|
b1fca0 | 1996-11-12 | Per Hedbor | | if(!remoteaddr)
{
|
2154ca | 1997-08-31 | Per Hedbor | | if(my_fd) catch(remoteaddr = ((my_fd->query_address()||"")/" ")[0]);
|
b1fca0 | 1996-11-12 | Per Hedbor | | if(!remoteaddr) this_object()->end();
}
|
7ec660 | 1997-01-29 | Per Hedbor | |
|
b1fca0 | 1996-11-12 | Per Hedbor | | #if 0
sscanf(f,"%s;%s", f, range);
#endif
f = scan_for_query( f );
|
06583f | 1997-09-03 | Per Hedbor | |
|
b1fca0 | 1996-11-12 | Per Hedbor | |
if (sscanf(f, "/<%s>%s", a, f))
{
config_in_url = 1;
mod_config = (a/",");
}
if (sscanf(f, "/(%s)%s", a, f) && strlen(a))
prestate = aggregate_multiset(@(a/","-({""})));
|
86729e | 1997-09-06 | Per Hedbor | | not_query = simplify_path(http_decode_string(f));
|
b1fca0 | 1996-11-12 | Per Hedbor | |
if(strlen(s))
{
sscanf(real_raw, "%s\r\n\r\n%s", s, data);
sscanf(s, "%*s\n%s", s);
s = replace(s, "\n\t", ", ") - "\r";
foreach(s/"\n" - ({ "" }), line)
{
linename=contents=0;
sscanf(line, "%s:%s", linename, contents);
if(linename&&contents)
{
linename=lower_case(linename);
sscanf(contents, "%*[\t ]%s", contents);
if(strlen(contents))
{
|
48633b | 1997-08-04 | Henrik Grubbström (Grubba) | | switch (linename) {
case "content-length":
|
b1fca0 | 1996-11-12 | Per Hedbor | | misc->len = (int)(contents-" ");
if(method == "POST")
{
|
dcc435 | 1997-05-20 | Per Hedbor | | if(!data) data="";
|
b1fca0 | 1996-11-12 | Per Hedbor | | int l = (int)(contents-" ")-1;
|
7ee565 | 1996-12-10 | Per Hedbor | | wanted_data=l;
have_data=strlen(data);
|
ceb927 | 1997-05-15 | David Hedbor | |
if(strlen(data) <= l)
{
#if _DEBUG_HTTP_OBJECTS
roxen->httpobjects[my_id] = "Parsed data - short post...";
#endif
|
7ee565 | 1996-12-10 | Per Hedbor | | return 0;
|
ceb927 | 1997-05-15 | David Hedbor | | }
|
7ee565 | 1996-12-10 | Per Hedbor | | data = data[..l];
switch(lower_case(((misc["content-type"]||"")/";")[0]-" "))
|
ceb927 | 1997-05-15 | David Hedbor | | { default:
|
7ee565 | 1996-12-10 | Per Hedbor | | string v;
if(l < 200000)
{
foreach(replace(data-"\n", "+", " ")/"&", v)
if(sscanf(v, "%s=%s", a, b) == 2)
{
a = http_decode_string( a );
b = http_decode_string( b );
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
7ee565 | 1996-12-10 | Per Hedbor | | if(variables[ a ])
variables[ a ] += "\0" + b;
else
variables[ a ] = b;
}
}
break;
|
48633b | 1997-08-04 | Henrik Grubbström (Grubba) | | case "multipart/form-data":
|
7ee565 | 1996-12-10 | Per Hedbor | |
|
57d41d | 1997-08-14 | Marcus Comstedt | | object messg = MIME.Message(data, misc);
foreach(messg->body_parts, object part) {
if(part->disp_params->filename) {
variables[part->disp_params->name]=part->getdata();
variables[part->disp_params->name+".filename"]=
part->disp_params->filename;
if(!misc->files)
misc->files = ({ part->disp_params->name });
else
misc->files += ({ part->disp_params->name });
} else {
variables[part->disp_params->name]=part->getdata();
|
7ee565 | 1996-12-10 | Per Hedbor | | }
}
break;
}
}
break;
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
48633b | 1997-08-04 | Henrik Grubbström (Grubba) | | case "authorization":
|
b1fca0 | 1996-11-12 | Per Hedbor | | string *y;
rawauth = contents;
y = contents /= " ";
if(sizeof(y) < 2)
break;
y[1] = decode(y[1]);
realauth=y[1];
if(conf && conf->auth_module)
y = conf->auth_module->auth( y, this_object() );
auth=y;
break;
|
48633b | 1997-08-04 | Henrik Grubbström (Grubba) | | case "proxy-authorization":
|
b1fca0 | 1996-11-12 | Per Hedbor | | string *y;
y = contents /= " ";
if(sizeof(y) < 2)
break;
y[1] = decode(y[1]);
if(conf && conf->auth_module)
y = conf->auth_module->auth( y, this_object() );
misc->proxyauth=y;
break;
|
48633b | 1997-08-04 | Henrik Grubbström (Grubba) | | case "pragma":
|
5e8921 | 1997-02-13 | Per Hedbor | | pragma|=aggregate_multiset(@replace(contents, " ", "")/ ",");
|
b1fca0 | 1996-11-12 | Per Hedbor | | break;
|
48633b | 1997-08-04 | Henrik Grubbström (Grubba) | | case "user-agent":
|
b1fca0 | 1996-11-12 | Per Hedbor | | sscanf(contents, "%s via", contents);
|
5e8921 | 1997-02-13 | Per Hedbor | | client = contents/" " - ({ "" });
|
b1fca0 | 1996-11-12 | Per Hedbor | | break;
|
695bba | 1997-03-22 | Henrik Grubbström (Grubba) | |
|
48633b | 1997-08-04 | Henrik Grubbström (Grubba) | | case "ua-pixels":
case "ua-color":
case "ua-os":
case "ua-cpu":
|
695bba | 1997-03-22 | Henrik Grubbström (Grubba) | | break;
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
48633b | 1997-08-04 | Henrik Grubbström (Grubba) | | case "referer":
|
f6d62d | 1997-03-26 | Per Hedbor | | referer = contents/" ";
break;
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
48633b | 1997-08-04 | Henrik Grubbström (Grubba) | | case "extension":
|
b1fca0 | 1996-11-12 | Per Hedbor | | #ifdef DEBUG
perror("Client extension: "+contents+"\n");
#endif
linename="extension";
|
48633b | 1997-08-04 | Henrik Grubbström (Grubba) | | case "connection":
|
b1fca0 | 1996-11-12 | Per Hedbor | | contents = lower_case(contents);
|
48633b | 1997-08-04 | Henrik Grubbström (Grubba) | | case "content-type":
misc[linename] = lower_case(contents);
|
b1fca0 | 1996-11-12 | Per Hedbor | | break;
|
48633b | 1997-08-04 | Henrik Grubbström (Grubba) | | case "accept":
case "accept-encoding":
case "accept-charset":
case "accept-language":
case "session-id":
case "message-id":
case "from":
|
b1fca0 | 1996-11-12 | Per Hedbor | | if(misc[linename])
|
5e8921 | 1997-02-13 | Per Hedbor | | misc[linename] += (contents-" ") / ",";
|
b1fca0 | 1996-11-12 | Per Hedbor | | else
|
5e8921 | 1997-02-13 | Per Hedbor | | misc[linename] = (contents-" ") / ",";
|
b1fca0 | 1996-11-12 | Per Hedbor | | break;
case "cookie":
string c;
misc->cookies = contents;
foreach(contents/";", c)
{
string name, value;
while(c[0]==' ') c=c[1..];
if(sscanf(c, "%s=%s", name, value) == 2)
{
value=http_decode_string(value);
name=http_decode_string(name);
cookies[ name ]=value;
if(name == "RoxenConfig" && strlen(value))
{
array tmpconfig = value/"," + ({ });
string m;
if(mod_config && sizeof(mod_config))
foreach(mod_config, m)
if(!strlen(m))
{ continue; }
else if(m[0]=='-')
tmpconfig -= ({ m[1..] });
else
tmpconfig |= ({ m });
mod_config = 0;
config = aggregate_multiset(@tmpconfig);
}
}
}
break;
|
48633b | 1997-08-04 | Henrik Grubbström (Grubba) | | case "host":
case "proxy-connection":
case "security-scheme":
|
b1fca0 | 1996-11-12 | Per Hedbor | | misc[linename] = contents;
break;
|
48633b | 1997-08-04 | Henrik Grubbström (Grubba) | | case "proxy-by":
case "proxy-maintainer":
case "proxy-software":
|
b1fca0 | 1996-11-12 | Per Hedbor | | #ifdef MORE_HEADERS
if(misc[linename])
misc[linename] += explode(contents-" ", ",");
else
misc[linename] = explode(contents-" ", ",");
#endif
|
48633b | 1997-08-04 | Henrik Grubbström (Grubba) | | case "mime-version":
|
b1fca0 | 1996-11-12 | Per Hedbor | | break;
|
48633b | 1997-08-04 | Henrik Grubbström (Grubba) | | case "if-modified-since":
|
14179b | 1997-01-29 | Per Hedbor | |
|
b1fca0 | 1996-11-12 | Per Hedbor | | since=contents;
break;
|
48633b | 1997-08-04 | Henrik Grubbström (Grubba) | |
case "negotiate":
misc["negotiate"]=contents;
break;
case "via":
misc["via"]=contents;
break;
case "cache-control":
misc["cache-control"]=contents;
break;
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
48633b | 1997-08-04 | Henrik Grubbström (Grubba) | | case "forwarded":
misc["forwarded"]=contents;
|
b1fca0 | 1996-11-12 | Per Hedbor | | break;
#ifdef DEBUG
|
48633b | 1997-08-04 | Henrik Grubbström (Grubba) | | default:
|
b1fca0 | 1996-11-12 | Per Hedbor | |
if(linename[0] != 'x')
perror("Unknown header: `"+linename+"' -> `"+contents+"'\n");
#endif
}
}
}
}
}
|
14179b | 1997-01-29 | Per Hedbor | | supports = find_supports(lower_case(client*" "));
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
dde965 | 1996-12-08 | David Hedbor | | if(misc->proxyauth) {
mixed tmp1,tmp2;
foreach(tmp2 = (raw / "\n"), tmp1) {
if(!search(lower_case(tmp1), "proxy-authorization:"))
tmp2 -= ({tmp1});
}
raw = tmp2 * "\n";
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
ceb927 | 1997-05-15 | David Hedbor | | #if _DEBUG_HTTP_OBJECTS
my_state = 10;
roxen->httpobjects[my_id] = sprintf("%O - %O", raw_url, remoteaddr);
#endif
if(config_in_url) {
#if _DEBUG_HTTP_OBJECTS
roxen->httpobjects[my_id] = "Configuration request?...";
#endif
return really_set_config( mod_config );
}
|
b1fca0 | 1996-11-12 | Per Hedbor | | if(!supports->cookies)
config = prestate;
else
if(conf
|
27b0e1 | 1996-11-26 | Per Hedbor | | && !cookies->RoxenUserID && strlen(not_query)
&& not_query[0]=='/' && method!="PUT"
&& QUERY(set_cookie))
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
#ifdef DEBUG
perror("Setting unique ID.\n");
#endif
|
a773c6 | 1997-07-06 | Henrik Grubbström (Grubba) | | if (!(QUERY(set_cookie_only_once) &&
cache_lookup("hosts_for_cookie",remoteaddr))) {
misc->moreheads = ([ "Set-Cookie":http_roxen_id_cookie(), ]);
}
if (QUERY(set_cookie_only_once))
cache_set("hosts_for_cookie",remoteaddr,1);
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
#ifdef DEBUG
#if DEBUG_LEVEL > 30
else
perror("Unique ID: "+cookies->RoxenUserID+"\n");
#endif
#endif
return 1;
}
void disconnect()
{
|
ceb927 | 1997-05-15 | David Hedbor | | #if _DEBUG_HTTP_OBJECTS
my_state = 2;
#endif
if(do_not_disconnect)
{
|
b1fca0 | 1996-11-12 | Per Hedbor | | #ifdef REQUEST_DEBUG
|
ceb927 | 1997-05-15 | David Hedbor | | perror("REQUEST: Not disconnecting...\n");
|
b1fca0 | 1996-11-12 | Per Hedbor | | #endif
|
ceb927 | 1997-05-15 | David Hedbor | | return;
}
|
b1fca0 | 1996-11-12 | Per Hedbor | | #ifdef REQUEST_DEBUG
|
ceb927 | 1997-05-15 | David Hedbor | | perror("REQUEST: Disconnecting...\n");
#endif
|
a773c6 | 1997-07-06 | Henrik Grubbström (Grubba) | | if(mappingp(file) && objectp(file->file)) {
|
d8138a | 1997-08-04 | Henrik Grubbström (Grubba) | | if (file->file->no_destruct) {
|
a773c6 | 1997-07-06 | Henrik Grubbström (Grubba) | | file->file = 0;
} else {
destruct(file->file);
}
}
|
ceb927 | 1997-05-15 | David Hedbor | | #if _DEBUG_HTTP_OBJECTS
roxen->httpobjects[my_id] += " - disconnect";
|
b1fca0 | 1996-11-12 | Per Hedbor | | #endif
|
ceb927 | 1997-05-15 | David Hedbor | | my_fd = 0;
|
2154ca | 1997-08-31 | Per Hedbor | |
|
14179b | 1997-01-29 | Per Hedbor | | destruct();
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
14179b | 1997-01-29 | Per Hedbor | | #ifdef KEEP_CONNECTION_ALIVE
|
b1fca0 | 1996-11-12 | Per Hedbor | | void no_more_keep_connection_alive(mapping foo)
{
if(!pipe || !objectp(my_fd)) end();
}
|
14179b | 1997-01-29 | Per Hedbor | | #endif
|
b1fca0 | 1996-11-12 | Per Hedbor | |
void end(string|void s)
{
|
ceb927 | 1997-05-15 | David Hedbor | | #if _DEBUG_HTTP_OBJECTS
|
2154ca | 1997-08-31 | Per Hedbor | | if(my_fd) catch{mark_fd(my_fd->query_fd(), "");};
|
ceb927 | 1997-05-15 | David Hedbor | | my_state = 1;
#endif
|
2154ca | 1997-08-31 | Per Hedbor | |
|
b1fca0 | 1996-11-12 | Per Hedbor | | #ifdef REQUEST_DEBUG
|
ceb927 | 1997-05-15 | David Hedbor | | perror("REQUEST: End...\n");
|
b1fca0 | 1996-11-12 | Per Hedbor | | #endif
|
14179b | 1997-01-29 | Per Hedbor | | #ifdef KEEP_CONNECTION_ALIVE
|
ceb927 | 1997-05-15 | David Hedbor | | remove_call_out(no_more_keep_connection_alive);
|
14179b | 1997-01-29 | Per Hedbor | | #endif
|
ceb927 | 1997-05-15 | David Hedbor | | #if _DEBUG_HTTP_OBJECTS
roxen->httpobjects[my_id] += " - end";
#endif
if(objectp(my_fd))
{
if(s) my_fd->write(s);
|
d8138a | 1997-08-04 | Henrik Grubbström (Grubba) | | if (!my_fd->no_destruct) {
destruct(my_fd);
}
my_fd = 0;
|
ceb927 | 1997-05-15 | David Hedbor | | }
|
2154ca | 1997-08-31 | Per Hedbor | |
|
ceb927 | 1997-05-15 | David Hedbor | | disconnect();
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
ceb927 | 1997-05-15 | David Hedbor | | static void do_timeout(mapping foo)
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
|
ceb927 | 1997-05-15 | David Hedbor | | #if _DEBUG_HTTP_OBJECTS
my_state = 10;
#endif
#if _DEBUG_HTTP_OBJECTS
roxen->httpobjects[my_id] += " - timed out";
#endif
end((prot||"HTTP/1.0")+" 408 Timeout\n");
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
14179b | 1997-01-29 | Per Hedbor | | #ifdef KEEP_CONNECTION_ALIVE
|
b1fca0 | 1996-11-12 | Per Hedbor | | void got_data(mixed fooid, string s);
void keep_connection_alive()
{
pipe=0;
|
e118b8 | 1997-01-29 | Per Hedbor | | my_fd->set_read_callback(got_data);
my_fd->set_close_callback(end);
|
b1fca0 | 1996-11-12 | Per Hedbor | | if(cache && strlen(cache))
got_data(1, "");
else
call_out(no_more_keep_connection_alive, 100);
}
|
14179b | 1997-01-29 | Per Hedbor | | #endif
|
b1fca0 | 1996-11-12 | Per Hedbor | |
mapping internal_error(array err)
{
if(QUERY(show_internals))
file = http_low_answer(500, "<h1>Error: Internal server error.</h1>"
+ "<font size=+1><pre>"+ describe_backtrace(err)
+ "</pre></font>");
else
file = http_low_answer(500, "<h1>Error: The server failed to "
"fulfill your query.</h1>");
report_error("Internal server error: " +
describe_backtrace(err) + "\n");
}
|
23a789 | 1996-12-15 | Per Hedbor | | int wants_more()
{
return !!cache;
}
|
fc2fcf | 1997-04-13 | Per Hedbor | | constant errors =
([
200:"200 OK",
201:"201 URI follows",
202:"202 Accepted",
203:"203 Provisional Information",
204:"204 No Content",
300:"300 Moved",
301:"301 Permanent Relocation",
302:"302 Temporary Relocation",
303:"303 Temporary Relocation method and URI",
304:"304 Not Modified",
400:"400 Bad Request",
401:"401 Access denied",
402:"402 Payment Required",
403:"403 Forbidden",
404:"404 No such file or directory.",
405:"405 Method not allowed",
407:"407 Proxy authorization needed",
408:"408 Request timeout",
409:"409 Conflict",
410:"410 This document is no more. It has gone to meet it's creator. It is gone. It will not be coming back. Give up. I promise. There is no such file or directory.",
500:"500 Internal Server Error.",
501:"501 Not Implemented",
502:"502 Gateway Timeout",
503:"503 Service unavailable",
]);
|
d7b087 | 1997-08-31 | Per Hedbor | |
void do_log(array id)
{
if(conf)
{
int len;
pipe = id[0];
file = id[1];
if(len = pipe->bytes_sent()) file->len = len;
if(conf)
{
conf->log(file, this_object());
if(file->len > 0) conf->sent+=file->len;
}
}
my_fd=0;
pipe=file=0;
|
2154ca | 1997-08-31 | Per Hedbor | | destruct();
|
d7b087 | 1997-08-31 | Per Hedbor | | }
|
9f46de | 1997-04-08 | Per Hedbor | | void handle_request( )
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
|
ceb927 | 1997-05-15 | David Hedbor | | #if _DEBUG_HTTP_OBJECTS
|
2154ca | 1997-08-31 | Per Hedbor | | mark_fd(my_fd->query_fd(), "HTTP: Handling");
|
ceb927 | 1997-05-15 | David Hedbor | | my_state = 15;
#endif
|
b1fca0 | 1996-11-12 | Per Hedbor | | mixed *err;
|
5bc199 | 1997-01-29 | Per Hedbor | | int tmp;
#ifdef KEEP_CONNECTION_ALIVE
int keep_alive;
#endif
|
b1fca0 | 1996-11-12 | Per Hedbor | | function funp;
mapping heads;
|
5bc199 | 1997-01-29 | Per Hedbor | | string head_string;
|
14179b | 1997-01-29 | Per Hedbor | | object thiso=this_object();
|
5bc199 | 1997-01-29 | Per Hedbor | |
|
b1fca0 | 1996-11-12 | Per Hedbor | | #ifndef SPEED_MAX
|
ceb927 | 1997-05-15 | David Hedbor | |
#if _DEBUG_HTTP_OBJECTS
roxen->httpobjects[my_id] += " - handled";
#endif
remove_call_out(do_timeout);
remove_call_out(do_timeout);
|
b1fca0 | 1996-11-12 | Per Hedbor | | #endif
|
82f519 | 1997-03-02 | Per Hedbor | |
|
b1fca0 | 1996-11-12 | Per Hedbor | | if(conf)
{
|
14179b | 1997-01-29 | Per Hedbor | |
|
68e030 | 1997-08-19 | Per Hedbor | | object oc = conf;
foreach(conf->first_modules(), funp) {
if(file = funp( thiso)) break;
if(conf != oc) {handle_request();return;}
}
|
14179b | 1997-01-29 | Per Hedbor | | if(!file) err=catch(file = conf->get_file(thiso));
|
b1fca0 | 1996-11-12 | Per Hedbor | |
if(err) internal_error(err);
if(!mappingp(file))
|
14179b | 1997-01-29 | Per Hedbor | | foreach(conf->last_modules(), funp) if(file = funp(thiso)) break;
} else if(err=catch(file = roxen->configuration_parse( thiso ))) {
if(err==-1) return;
internal_error(err);
}
|
82f519 | 1997-03-02 | Per Hedbor | |
|
b1fca0 | 1996-11-12 | Per Hedbor | | if(!mappingp(file))
{
|
f6d62d | 1997-03-26 | Per Hedbor | | if(misc->error_code)
file = http_low_answer(misc->error_code, errors[misc->error]);
else if(method != "GET" && method != "HEAD" && method != "POST")
|
b1fca0 | 1996-11-12 | Per Hedbor | | file = http_low_answer(501, "Not implemented.");
else
|
14179b | 1997-01-29 | Per Hedbor | | file=http_low_answer(404,
replace(parse_rxml(conf->query("ZNoSuchFile"),
thiso),
({"$File", "$Me"}),
({not_query,
conf->query("MyWorldLocation")})));
} else {
if((file->file == -1) || file->leave_me)
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
|
fc2fcf | 1997-04-13 | Per Hedbor | | if(do_not_disconnect) return;
|
0ee085 | 1997-02-08 | Per Hedbor | |
my_fd = file = 0;
|
14179b | 1997-01-29 | Per Hedbor | | return;
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
14179b | 1997-01-29 | Per Hedbor | | if(file->type == "raw")
file->raw = 1;
else if(!file->type)
file->type="text/plain";
}
|
b1fca0 | 1996-11-12 | Per Hedbor | |
if(!file->raw && prot != "HTTP/0.9")
{
string h;
heads=
([
"Content-type":file["type"],
|
6d309c | 1997-08-13 | Henrik Grubbström (Grubba) | | "Server":replace(version(), " ", "·"),
|
e118b8 | 1997-01-29 | Per Hedbor | | "Date":http_date(time)
]);
|
b1fca0 | 1996-11-12 | Per Hedbor | |
if(file->encoding)
heads["Content-Encoding"] = file->encoding;
if(!file->error)
file->error=200;
if(file->expires)
heads->Expires = http_date(file->expires);
if(!file->len)
{
if(objectp(file->file))
|
14179b | 1997-01-29 | Per Hedbor | | if(!file->stat && !(file->stat=misc->stat))
|
b1fca0 | 1996-11-12 | Per Hedbor | | file->stat = (int *)file->file->stat();
array fstat;
if(arrayp(fstat = file->stat))
{
if(file->file && !file->len)
file->len = fstat[1];
heads["Last-Modified"] = http_date(fstat[3]);
if(since)
{
if(is_modified(since, fstat[3], fstat[1]))
{
file->error = 304;
method="HEAD";
}
}
}
if(stringp(file->data))
file->len += strlen(file->data);
}
#ifdef KEEP_CONNECTION_ALIVE
#ifdef REQUEST_DEBUG
if(kept_alive)
perror(sprintf("Connection: Kept alive %d times.\n", kept_alive));
#endif
if(misc->connection && search(misc->connection, "keep-alive") != -1)
{
if(file->len > 0)
{
heads->Connection = "keep-alive; timeout=100, maxreq=666";
keep_alive=1;
#ifdef REQUEST_DEBUG
kept_alive++;
#endif
}
}
#endif
if(mappingp(file->extra_heads))
heads |= file->extra_heads;
if(mappingp(misc->moreheads))
heads |= misc->moreheads;
|
14179b | 1997-01-29 | Per Hedbor | | array myheads = ({prot+" "+(file->rettext||errors[file->error])});
|
b1fca0 | 1996-11-12 | Per Hedbor | | foreach(indices(heads), h)
if(arrayp(heads[h]))
foreach(heads[h], tmp)
|
5e8921 | 1997-02-13 | Per Hedbor | | myheads += ({ `+(h,": ", tmp)});
|
b1fca0 | 1996-11-12 | Per Hedbor | | else
|
5e8921 | 1997-02-13 | Per Hedbor | | myheads += ({ `+(h, ": ", heads[h])});
|
b1fca0 | 1996-11-12 | Per Hedbor | |
if(file->len > -1)
|
14179b | 1997-01-29 | Per Hedbor | | myheads += ({"Content-length: " + file->len });
head_string = (myheads+({"",""}))*"\r\n";
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
d7b087 | 1997-08-31 | Per Hedbor | | if(conf) conf->hsent+=strlen(head_string||"");
|
5bc199 | 1997-01-29 | Per Hedbor | |
|
b1fca0 | 1996-11-12 | Per Hedbor | | if(method=="HEAD")
{
|
14179b | 1997-01-29 | Per Hedbor | | if(conf)conf->log(file, thiso);
|
5bc199 | 1997-01-29 | Per Hedbor | | #ifdef KEEP_CONNECTION_ALIVE
|
b1fca0 | 1996-11-12 | Per Hedbor | | if(keep_alive)
{
my_fd->write(head_string);
misc->connection = 0;
keep_connection_alive();
|
5bc199 | 1997-01-29 | Per Hedbor | | } else
|
14179b | 1997-01-29 | Per Hedbor | | #endif
|
b1fca0 | 1996-11-12 | Per Hedbor | | end(head_string);
return;
}
|
2154ca | 1997-08-31 | Per Hedbor | | #ifdef USE_SHUFFLE
|
5bc199 | 1997-01-29 | Per Hedbor | | if(!file->data &&
(file->len<=0 || (file->len > 30000))
#ifdef KEEP_CONNECTION_ALIVE
&& !keep_alive
#endif
&& objectp(file->file))
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
|
5bc199 | 1997-01-29 | Per Hedbor | | if(head_string) my_fd->write(head_string);
|
14179b | 1997-01-29 | Per Hedbor | | shuffle( file->file, my_fd );
if(conf)conf->log(file, thiso);
my_fd=file->file=file=pipe=0;
|
5bc199 | 1997-01-29 | Per Hedbor | | return;
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
d7b087 | 1997-08-31 | Per Hedbor | | #endif
|
5bc199 | 1997-01-29 | Per Hedbor | | if(file->len < 3000 &&
#ifdef KEEP_CONNECTION_ALIVE
!keep_alive &&
#endif
file->len >= 0)
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
|
d7b087 | 1997-08-31 | Per Hedbor | | if(file->data) head_string += file->data;
|
e118b8 | 1997-01-29 | Per Hedbor | | if(file->file)
{
head_string += file->file->read(file->len);
destruct(file->file);
}
|
d7b087 | 1997-08-31 | Per Hedbor | |
if(conf)
{
file->len = strlen( head_string );
conf->log(file, thiso);
}
|
e118b8 | 1997-01-29 | Per Hedbor | | end(head_string);
return;
}
|
14179b | 1997-01-29 | Per Hedbor | | }
|
e118b8 | 1997-01-29 | Per Hedbor | |
|
b1fca0 | 1996-11-12 | Per Hedbor | | if(head_string) send(head_string);
if(file->data) send(file->data);
if(file->file) send(file->file);
pipe->output(my_fd);
|
d7b087 | 1997-08-31 | Per Hedbor | |
pipe->set_done_callback( do_log, ({ pipe, file }) );
|
b1fca0 | 1996-11-12 | Per Hedbor | |
#ifdef KEEP_CONNECTION_ALIVE
if(keep_alive)
{
if(my_fd)
{
|
14179b | 1997-01-29 | Per Hedbor | | misc->connection=0;
|
b1fca0 | 1996-11-12 | Per Hedbor | | pipe->set_done_callback(keep_connection_alive);
}
|
d7b087 | 1997-08-31 | Per Hedbor | | }
|
14179b | 1997-01-29 | Per Hedbor | | #endif
}
void got_data(mixed fooid, string s)
{
int tmp;
|
ceb927 | 1997-05-15 | David Hedbor | | #if _DEBUG_HTTP_OBJECTS
my_state = 3;
#endif
|
14179b | 1997-01-29 | Per Hedbor | |
#ifndef SPEED_MAX
|
ceb927 | 1997-05-15 | David Hedbor | |
#if _DEBUG_HTTP_OBJECTS
roxen->httpobjects[my_id] = ("Got data - "+remoteaddr +" - "+ctime(_time())) - "\n";
#endif
remove_call_out(do_timeout);
|
2154ca | 1997-08-31 | Per Hedbor | | call_out(do_timeout, 30);
|
ceb927 | 1997-05-15 | David Hedbor | |
|
14179b | 1997-01-29 | Per Hedbor | | #endif
if(wanted_data)
{
if(strlen(s)+have_data < wanted_data)
{
cache += ({ s });
have_data += strlen(s);
return;
}
}
if(cache)
{
cache += ({ s });
s = cache*"";
cache = 0;
}
#ifdef KEEP_CONNECTION_ALIVE
remove_call_out(no_more_keep_connection_alive);
#endif
tmp = parse_got(s);
switch(-tmp)
{
case 0:
cache = ({ s });
return;
case 1:
end(prot+" 500 Stupid Client Error\r\nContent-Length: 0\r\n\r\n");
return;
case 2:
end();
return;
}
|
ceb927 | 1997-05-15 | David Hedbor | | #if _DEBUG_HTTP_OBJECTS
roxen->httpobjects[my_id] += " - finished getting data.";
#endif
|
14179b | 1997-01-29 | Per Hedbor | | if(conf)
{
conf->received += strlen(s);
conf->requests++;
}
|
2154ca | 1997-08-31 | Per Hedbor | |
my_fd->set_close_callback(0);
my_fd->set_read_callback(0);
my_fd->set_blocking();
|
14179b | 1997-01-29 | Per Hedbor | | #ifdef THREADS
|
48633b | 1997-08-04 | Henrik Grubbström (Grubba) | | roxen->handle(this_object()->handle_request);
|
14179b | 1997-01-29 | Per Hedbor | | #else
|
9f46de | 1997-04-08 | Per Hedbor | | this_object()->handle_request();
|
b1fca0 | 1996-11-12 | Per Hedbor | | #endif
}
object clone_me()
{
|
14179b | 1997-01-29 | Per Hedbor | | object c,t;
|
ceb927 | 1997-05-15 | David Hedbor | | #if _DEBUG_HTTP_OBJECTS
my_state = 4;
#endif
|
14179b | 1997-01-29 | Per Hedbor | | c=object_program(t=this_object())();
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
f6d62d | 1997-03-26 | Per Hedbor | | c->first = first;
|
b1fca0 | 1996-11-12 | Per Hedbor | | c->conf = conf;
c->time = time;
|
f6d62d | 1997-03-26 | Per Hedbor | | c->raw_url = raw_url;
c->variables = copy_value(variables);
|
48fa36 | 1997-04-05 | Per Hedbor | | c->misc = copy_value(misc);
c->misc->orig = t;
|
f6d62d | 1997-03-26 | Per Hedbor | |
|
b1fca0 | 1996-11-12 | Per Hedbor | | c->prestate = prestate;
c->supports = supports;
|
f6d62d | 1997-03-26 | Per Hedbor | | c->config = config;
|
b1fca0 | 1996-11-12 | Per Hedbor | | c->remoteaddr = remoteaddr;
|
f6d62d | 1997-03-26 | Per Hedbor | | c->host = host;
|
b1fca0 | 1996-11-12 | Per Hedbor | | c->client = client;
|
f6d62d | 1997-03-26 | Per Hedbor | | c->referer = referer;
c->pragma = pragma;
c->cookies = cookies;
c->my_fd = 0;
c->prot = prot;
|
1afe37 | 1997-06-12 | Henrik Grubbström (Grubba) | | c->clientprot = clientprot;
|
f6d62d | 1997-03-26 | Per Hedbor | | c->method = method;
c->rest_query = rest_query;
c->raw = raw;
c->query = query;
c->not_query = not_query;
c->extra_extension = extra_extension;
c->data = data;
|
b1fca0 | 1996-11-12 | Per Hedbor | | c->auth = auth;
c->realauth = realauth;
|
f6d62d | 1997-03-26 | Per Hedbor | | c->rawauth = rawauth;
c->since = since;
|
ceb927 | 1997-05-15 | David Hedbor | | #if _DEBUG_HTTP_OBJECTS
if(!c->my_id)
c->my_id = roxen->new_id();
roxen->httpobjects[c->my_id] = roxen->httpobjects[my_id] + " - clone";
roxen->httpobjects[my_id] += " - CLONED";
#endif
|
b1fca0 | 1996-11-12 | Per Hedbor | | return c;
}
void clean()
{
|
ceb927 | 1997-05-15 | David Hedbor | | #if _DEBUG_HTTP_OBJECTS
my_state = 4;
#endif
|
b1fca0 | 1996-11-12 | Per Hedbor | | if(!(my_fd && objectp(my_fd))) end();
else if((_time(1) - time) > 4800) end();
}
|
ceb927 | 1997-05-15 | David Hedbor | | #if _DEBUG_HTTP_OBJECTS
void destroy()
{
|
2154ca | 1997-08-31 | Per Hedbor | | if(my_fd) catch{mark_fd(my_fd->query_fd(), "");};
|
ceb927 | 1997-05-15 | David Hedbor | | roxen->httpobjects->num--;
m_delete(roxen->httpobjects, my_id);
}
#endif
|
14179b | 1997-01-29 | Per Hedbor | | void create(object f, object c)
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
|
ceb927 | 1997-05-15 | David Hedbor | |
#if _DEBUG_HTTP_OBJECTS
my_state = 5;
roxen->httpobjects->num++;
#endif
|
14179b | 1997-01-29 | Per Hedbor | | if(f)
{
|
ceb927 | 1997-05-15 | David Hedbor | | #if _DEBUG_HTTP_OBJECTS
if(!my_id)
my_id = roxen->new_id();
#endif
|
14179b | 1997-01-29 | Per Hedbor | | my_fd = f;
|
e118b8 | 1997-01-29 | Per Hedbor | | my_fd->set_read_callback(got_data);
my_fd->set_close_callback(end);
|
ceb927 | 1997-05-15 | David Hedbor | | #if _DEBUG_HTTP_OBJECTS
|
2154ca | 1997-08-31 | Per Hedbor | | if(my_fd) catch(remoteaddr = ((my_fd->query_address()||"")/" ")[0]);
|
ceb927 | 1997-05-15 | David Hedbor | | roxen->httpobjects[my_id] = ("Created - "+
remoteaddr +" - "+ctime(_time())) - "\n" ;
#endif
|
14179b | 1997-01-29 | Per Hedbor | | conf = c;
mark_fd(my_fd->query_fd(), "HTTP connection");
|
b1fca0 | 1996-11-12 | Per Hedbor | | #ifndef SPEED_MAX
|
ceb927 | 1997-05-15 | David Hedbor | |
call_out(do_timeout, 60);
call_out(do_timeout, 70);
|
b1fca0 | 1996-11-12 | Per Hedbor | | #endif
|
14179b | 1997-01-29 | Per Hedbor | | }
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
ceb927 | 1997-05-15 | David Hedbor | |
|