Roxen.git / server / plugins / protocols / http.pike

version» Context lines:

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");