Roxen.git/server/plugins/protocols/http.pike:1:
// This is a ChiliMoon protocol module.
// Modified by Francesco Chemolli to add throttling capabilities.
// Copyright © 1996 - 2001, Roxen IS.
- constant cvs_version = "$Id: http.pike,v 1.395 2004/04/04 00:37:11 mani Exp $";
+ constant cvs_version = "$Id: http.pike,v 1.396 2004/04/04 14:24:53 mani Exp $";
// #define REQUEST_DEBUG
#define MAGIC_ERROR
// HTTP protocol module.
#include <config.h>
#define TIMER_PREFIX "http:"
#include <timers.h>
inherit RequestID;
#ifdef PROFILE
#define HRTIME() gethrtime()
#define HRSEC(X) ((int)((X)*1000000))
#define SECHR(X) ((X)/(float)1000000)
int req_time = HRTIME();
#endif
#ifdef ID_OBJ_DEBUG
- RoxenDebug.ObjectMarker __marker = RoxenDebug.ObjectMarker (this_object());
+ RoxenDebug.ObjectMarker __marker = RoxenDebug.ObjectMarker(this);
#endif
#ifdef REQUEST_DEBUG
int footime, bartime;
#define REQUEST_WERR(X) bartime = gethrtime()-footime; werror("%s (%d)\n", (X), bartime);footime=gethrtime()
#else
#define REQUEST_WERR(X)
#endif
#ifdef FD_DEBUG
Roxen.git/server/plugins/protocols/http.pike:56:
private static array(string) cache;
private static int wanted_data, have_data;
private static String.Buffer data_buffer;
#include <roxen.h>
#include <module.h>
#include <variables.h>
#include <request_trace.h>
#define MY_TRACE_ENTER(A, B) \
- do {RequestID id = this_object(); TRACE_ENTER (A, B);} while (0)
+ do {RequestID id = this; TRACE_ENTER (A, B);} while (0)
#define MY_TRACE_LEAVE(A) \
- do {RequestID id = this_object(); TRACE_LEAVE (A);} while (0)
+ do {RequestID id = this; TRACE_LEAVE (A);} while (0)
mapping(string:array) real_variables = ([]);
mapping(string:mixed)|FakedVariables variables = FakedVariables( real_variables );
mapping (string:mixed) misc =
([
#ifdef REQUEST_DEBUG
"trace_enter":lambda(mixed ...args) {
REQUEST_WERR(sprintf("TRACE_ENTER(%{%O,%})", args));
},
Roxen.git/server/plugins/protocols/http.pike:97:
class AuthEmulator
// Emulate the old (rather cumbersome) authentication API
{
mixed `[]( int i )
{
User u;
switch( i )
{
case 0:
- return conf->authenticate( this_object() );
+ return conf->authenticate( this );
case 1:
- if( u = conf->authenticate( this_object() ) )
+ if( u = conf->authenticate( this ) )
return u->name();
if( realauth )
return (realauth/":")[0];
case 2:
- if( u = conf->authenticate( this_object() ) )
+ if( u = conf->authenticate( this ) )
return 0;
if( realauth )
return ((realauth/":")[1..])*":";
}
}
int `!( )
{
return !realauth;
}
}
Roxen.git/server/plugins/protocols/http.pike:301:
private void setup_pipe()
{
if(!my_fd)
{
end();
return;
}
pipe = core.get_shuffler( my_fd );
if( conf )
- conf->connection_add( this_object(), pipe );
+ conf->connection_add( this, pipe );
}
void send(string|object what, int|void len, int|void start)
{
if(!what) return;
if(!pipe) setup_pipe();
if( len>0 && port_obj && port_obj->minimum_byterate )
call_out( end, len / port_obj->minimum_byterate );
pipe->add_source(what,start,len||strlen(what));
Roxen.git/server/plugins/protocols/http.pike:584:
&& not_query[0]=='/' && method!="PUT")
{
if (!(port_obj->set_cookie_only_once &&
cache_lookup("hosts_for_cookie",remoteaddr)))
misc->moreheads = ([ "Set-Cookie":Roxen.http_roxen_id_cookie(), ]);
if (port_obj->set_cookie_only_once)
cache_set("hosts_for_cookie",remoteaddr,1);
}
if( mixed q = real_variables->magic_roxen_automatic_charset_variable )
- decode_charset_encoding(Roxen.get_client_charset_decoder(q[0],this_object()));
+ decode_charset_encoding(Roxen.get_client_charset_decoder(q[0], this));
}
static Roxen.HeaderParser hp = Roxen.HeaderParser();
static function(string:array(string|mapping)) hpf = hp->feed;
int last;
private int parse_got( string new_data )
{
TIMER_START(parse_got);
if( !method )
Roxen.git/server/plugins/protocols/http.pike:853:
int set_max_cache( int t )
{
int ot = misc->cacheable;
misc->cacheable = t;
return ot;
}
void disconnect()
{
file = 0;
- conf && conf->connection_drop( this_object() );
+ conf && conf->connection_drop( this );
#ifdef REQUEST_DEBUG
if (my_fd)
MARK_FD("HTTP my_fd in HTTP disconnected?");
#endif
MERGE_TIMERS(conf);
if(do_not_disconnect) return;
destruct();
}
void end(int|void keepit)
{
if( conf )
- conf->connection_drop( this_object() );
+ conf->connection_drop( this );
if(keepit
&& !file->raw
&& (misc->connection == "keep-alive" ||
(prot == "HTTP/1.1" && misc->connection != "close"))
&& my_fd
&& !catch(my_fd->query_address()) )
{
// Now.. Transfer control to a new http-object. Reset all variables etc..
- object o = object_program(this_object())(0, 0, 0);
+ this_program o = this_program(0, 0, 0);
o->remoteaddr = remoteaddr;
o->client = client;
o->supports = supports;
o->client_var = client_var;
o->host = host;
o->conf = conf;
o->pipe = pipe;
MARK_FD("HTTP kept alive");
object fd = my_fd;
my_fd=0;
Roxen.git/server/plugins/protocols/http.pike:1144:
"fulfill your query, due to an internal error.</h1>");
}
report_error("Internal server error: " +
describe_backtrace(err) + "\n");
#ifdef INTERNAL_ERROR_DEBUG
report_error("Raw backtrace:%O\n", err);
#endif /* INTERNAL_ERROR_DEBUG */
}
// This macro ensures that something gets reported even when the very
- // call to internal_error() fails. That happens eg when this_object()
- // has been destructed.
+ // call to internal_error() fails. That happens eg when this has been
+ // destructed.
#define INTERNAL_ERROR(err) do { \
if (mixed __eRr = catch (internal_error (err))) \
report_error("Internal server error: " + describe_backtrace(err) + \
"internal_error() also failed: "+describe_backtrace(__eRr));\
} while(0)
int wants_more()
{
return !!cache;
}
Roxen.git/server/plugins/protocols/http.pike:1167:
void do_log( Shuffler.Shuffle r, int reason )
{
MARK_FD("HTTP logging"); // fd can be closed here
int fsent = r->sent_data();
TIMER_START(do_log);
if(conf)
{
conf->sent+=fsent;
file->len += misc->_log_cheat_addition;
- conf->log(file, this_object());
+ conf->log(file, this);
}
if( !port_obj )
{
TIMER_END(do_log);
MERGE_TIMERS(conf);
if( conf )
- conf->connection_drop( this_object() );
+ conf->connection_drop( this );
mixed err = catch // paranoia
{
my_fd->close();
destruct( my_fd );
destruct( );
};
#ifdef DEBUG
if (err) report_debug ("Close failure (3): %s", describe_backtrace (err));
#endif
return;
Roxen.git/server/plugins/protocols/http.pike:1460:
if(!leftovers)
leftovers = data||"";
if(!mappingp(file))
{
misc->no_proto_cache = 1;
if(misc->error_code)
file = Roxen.http_low_answer(misc->error_code, errors[misc->error]);
else if(err = catch {
- file = conf->error_file( this_object() );
+ file = conf->error_file( this );
})
INTERNAL_ERROR(err);
}
else
{
if((file->file == -1) || file->leave_me)
{
TIMER_END(send_result);
file = 0;
pipe = 0;
Roxen.git/server/plugins/protocols/http.pike:1602:
if(sizeof(ranges) == 1)
{
heads["Content-Range"] = sprintf("bytes %d-%d/%d",
@ranges[0], file->len);
file->start = ranges[0][0];
file->len = ranges[0][1] - ranges[0][0]+1;
} else {
// Multiple ranges. Multipart reply and stuff needed.
// We do this by replacing the file object with a wrapper.
// Nice and handy.
- file->file = MultiRangeWrapper(file, heads, ranges, this_object());
+ file->file = MultiRangeWrapper(file, heads, ranges, this);
}
} else {
// Got the header, but the specified ranges was out of bounds.
// Reply with a 416 Requested Range not satisfiable.
file->error = 416;
heads["Content-Range"] = "*/"+file->len;
if(method == "GET") {
file->data = "The requested byte range is out-of-bounds. Sorry.";
file->len = strlen(file->data);
file->file = 0;
Roxen.git/server/plugins/protocols/http.pike:1734: Inside #if defined(MAGIC_ERROR)
file = ([
"type":"text/plain",
"data":generate_bugreport( @err ),
]);
TIMER_END(handle_request);
send_result();
return;
} else {
if(prestate->find_file)
{
- if (!core.configuration_authenticate(this_object(), "View Settings"))
+ if (!core.configuration_authenticate(this, "View Settings"))
file = Roxen.http_auth_required("admin");
else
file = ([
"type":"text/html",
"data":handle_error_file_request( @err ),
]);
TIMER_END(handle_request);
send_result();
return;
}
}
}
}
#endif /* MAGIC_ERROR */
MARK_FD("HTTP handling request");
array e;
mapping result;
- if(e= catch(result = conf->handle_request( this_object() )))
+ if(e= catch(result = conf->handle_request( this )))
INTERNAL_ERROR( e );
else {
if (result && result->pipe)
// Could be destructed here already since handle_request might
// have handed over us to another thread that finished quickly.
return;
file = result;
}
Roxen.git/server/plugins/protocols/http.pike:1870:
if (mixed err = catch {
MARK_FD("HTTP got data");
raw += s;
// The port has been closed, but old (probably keep-alive)
// connections remain. Close those connections.
if( !port_obj )
{
if( conf )
- conf->connection_drop( this_object() );
+ conf->connection_drop( this );
mixed err = catch // paranoia
{
my_fd->set_blocking();
my_fd->close();
destruct( my_fd );
destruct( );
};
#ifdef DEBUG
if (err) report_debug ("Close failure (4): %s", describe_backtrace (err));
#endif
Roxen.git/server/plugins/protocols/http.pike:1926:
// consider caching them?
// RFC 2068 5.1.2:
//
// To allow for transition to absoluteURIs in all requests in future
// versions of HTTP, all HTTP/1.1 servers MUST accept the absoluteURI
// form in requests, even though HTTP/1.1 clients will only generate
// them in requests to proxies.
#ifdef RFC2068
if (has_prefix(raw_url, port_obj->name+"://") &&
- (conf = port_obj->find_configuration_for_url(raw_url,
- this_object(), 1))) {
+ (conf = port_obj->find_configuration_for_url(raw_url, this, 1))) {
sscanf(raw_url[sizeof(port_obj->name+"://")..],
"%[^/]%s", misc->host, raw_url);
}
else
#endif
{
if (misc->host) {
conf =
port_obj->find_configuration_for_url(port_obj->name + "://" +
misc->host +
(has_value(misc->host, ":")<0?
"":(":"+port_obj->port)) +
- raw_url,
- this_object());
+ raw_url, this);
} else {
conf =
port_obj->find_configuration_for_url(port_obj->name +
"://*:" + port_obj->port +
- raw_url,
- this_object());
+ raw_url, this);
}
}
}
else if( strlen(path) )
adjust_for_config_path( path );
TIMER_END(find_conf);
if (rawauth)
{
Roxen.git/server/plugins/protocols/http.pike:1980:
if( misc->proxyauth )
{
/* Need to authenticate with the configuration */
misc->no_proto_cache = 1;
if (sizeof(misc->proxyauth) >= 2)
{
// misc->proxyauth[1] = MIME.decode_base64(misc->proxyauth[1]);
if (conf->auth_module)
misc->proxyauth
- = conf->auth_module->auth(misc->proxyauth,this_object() );
+ = conf->auth_module->auth(misc->proxyauth, this);
}
}
if( conf )
{
- conf->connection_add( this_object(), ([]) );
+ conf->connection_add( this, ([]) );
conf->received += strlen(raw);
conf->requests++;
}
my_fd->set_close_callback(0);
my_fd->set_read_callback(0);
if (my_fd->set_accept_callback) my_fd->set_accept_callback(0);
processed=1;
remove_call_out(do_timeout);
#ifdef RAM_CACHE
Roxen.git/server/plugins/protocols/http.pike:2025: Inside #if defined(RAM_CACHE)
string d = cv[ 0 ];
file = cv[1];
if( sizeof(file->callbacks) )
{
if( mixed e = catch
{
foreach( file->callbacks, function f ) {
MY_TRACE_ENTER (sprintf ("Checking with %s",
master()->describe_function (f)), 0);
- if( !f(this_object(), cv[1]->key ) )
+ if( !f(this, cv[1]->key ) )
{
MY_TRACE_LEAVE ("Entry invalid according to callback");
MY_TRACE_LEAVE ("");
can_cache = 0;
break;
}
MY_TRACE_LEAVE ("");
}
} )
{
Roxen.git/server/plugins/protocols/http.pike:2108:
report_error("Internal server error: " + describe_backtrace(err));
my_fd->set_blocking();
my_fd->close();
disconnect();
}
}
/* Get a somewhat identical copy of this object, used when doing
* 'simulated' requests. */
- object clone_me()
+ this_program clone_me()
{
- object c,t;
- c=object_program(t=this_object())(0, port_obj, conf);
+ this_program c=this_program(0, port_obj, conf);
#ifdef ID_OBJ_DEBUG
- werror ("clone %O -> %O\n", t, c);
+ werror ("clone %O -> %O\n", this, c);
#endif
c->port_obj = port_obj;
c->conf = conf;
c->root_id = root_id;
c->time = time;
c->raw_url = raw_url;
c->real_variables = copy_value( real_variables );
c->variables = FakedVariables( c->real_variables );
c->misc = copy_value( misc );
- c->misc->orig = t;
+ c->misc->orig = this;
c->prestate = prestate;
c->supports = supports;
c->config = config;
c->client_var = client_var;
c->remoteaddr = remoteaddr;
c->host = host;
c->client = client;
Roxen.git/server/plugins/protocols/http.pike:2181:
if(f)
{
f->set_nonblocking(got_data, f->query_write_callback(), end);
my_fd = f;
MARK_FD("HTTP connection");
if( c ) port_obj = c;
if( cc ) conf = cc;
time = predef::time(1);
call_out(do_timeout, 90);
}
- root_id = this_object();
+ root_id = this;
}
void chain( object f, object c, string le )
{
my_fd = f;
f->set_nonblocking(0, f->query_write_callback(), end);
port_obj = c;
processed = 0;
do_not_disconnect=-1; // Block destruction until we return.
MARK_FD("HTTP kept alive");