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.394 2004/04/04 00:13:11 mani Exp $"; + constant cvs_version = "$Id: http.pike,v 1.395 2004/04/04 00:37:11 mani Exp $";   // #define REQUEST_DEBUG   #define MAGIC_ERROR      // HTTP protocol module.   #include <config.h>   #define TIMER_PREFIX "http:"   #include <timers.h>      inherit RequestID;   
Roxen.git/server/plugins/protocols/http.pike:597:   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 )    {    array res; -  if( catch( res = hpf( new_data ) ) ) +  if( mixed err = catch( res = hpf( new_data ) ) ) { + #ifdef DEBUG +  report_debug("Got bad request, HeaderParser error: " + +  describe_error(err)); + #endif    return 1; -  +  }    if( !res )    {    TIMER_END(parse_got);    return 0; // Not enough data    }    data = res[0];    line = res[1];    request_headers = res[2];    }    return parse_got_2();
Roxen.git/server/plugins/protocols/http.pike:891:    o->chain(fd,port_obj,leftovers);    pipe = 0;    disconnect();    return;    }       pipe = 0;    if(objectp(my_fd))    {    MARK_FD("HTTP closed"); -  catch +  mixed err = catch    {    // Don't set to blocking mode if SSL.    if (!my_fd->CipherSpec) {    my_fd->set_blocking();    }    my_fd->close();    destruct(my_fd);    }; -  catch { + #ifdef DEBUG +  if (err) report_debug ("Close failure (1): %s", describe_backtrace (err)); + #endif +  err = catch {    my_fd = 0;    }; -  + #ifdef DEBUG +  if (err) report_debug ("Close failure (2): %s", describe_backtrace (err)); + #endif    }    disconnect();   }      static void do_timeout()   {    int elapsed = predef::time(1)-time;    if(time && elapsed >= 30)    {    REQUEST_WERR("HTTP: Connection timed out. Closing.");
Roxen.git/server/plugins/protocols/http.pike:1135:    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. - #define INTERNAL_ERROR(err) \ -  if (mixed __eRr = catch (internal_error (err))) \ -  report_error("Internal server error: " + describe_backtrace(err) + \ -  "internal_error() also failed: " + describe_backtrace(__eRr)) + #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;   }      void do_log( Shuffler.Shuffle r, int reason )   {    MARK_FD("HTTP logging"); // fd can be closed here    int fsent = r->sent_data();
Roxen.git/server/plugins/protocols/http.pike:1164:    file->len += misc->_log_cheat_addition;    conf->log(file, this_object());    }       if( !port_obj )    {    TIMER_END(do_log);    MERGE_TIMERS(conf);    if( conf )    conf->connection_drop( this_object() ); -  catch // paranoia +  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;    }    TIMER_END(do_log);    end(1);    return;   }      #ifdef FD_DEBUG   void timer(int start)   {
Roxen.git/server/plugins/protocols/http.pike:1493:       if ( fstat[ST_MTIME] > misc->last_modified )    misc->last_modified = fstat[ST_MTIME];    }       if( !zero_type(misc->cacheable) &&    misc->cacheable < INITIAL_CACHEABLE ) {    if (misc->cacheable == 0) {    heads["Expires"] = Roxen.http_date( 0 );    -  if (!misc->last_modified) { -  // Data with immediate expiry is assumed to have been generated -  // at the same instant. +  if (misc->cacheable < INITIAL_CACHEABLE) { +  // Data with expiry is assumed to have been generated at +  // the same instant.    misc->last_modified = predef::time(1);    }    }    else    heads["Expires"] = Roxen.http_date( predef::time(1)+misc->cacheable );    }       if (misc->last_modified)    heads["Last-Modified"] = Roxen.http_date(misc->last_modified);   
Roxen.git/server/plugins/protocols/http.pike:1617:    heads["Content-Length"] = (string)file->len;       // Some browsers, e.g. Netscape 4.7, doesn't trust a zero    // content length when using keep-alive. So let's force a    // close in that case.    if( file->error/100 == 2 && file->len <= 0 )    {    heads->Connection = "close";    misc->connection = "close";    } -  if( catch( head_string += Roxen.make_http_headers( heads ) ) ) +  if( mixed err = catch( head_string += Roxen.make_http_headers( heads ) ) )    { -  + #ifdef DEBUG +  report_debug("Roxen.make_http_headers failed: " + +  describe_error(err)); + #endif    foreach( heads; string x; mixed head )    if( stringp( head ) )    head_string += x+": "+head+"\r\n";    else if( arrayp( head ) )    foreach( head, string xx )    head_string += x+": "+xx+"\r\n";    else if( catch {    head_string += x+": "+(string)head;    } )    error("Illegal value in headers array! "
Roxen.git/server/plugins/protocols/http.pike:1734: Inside #if defined(MAGIC_ERROR)
   return;    }    }    }    }   #endif /* MAGIC_ERROR */       MARK_FD("HTTP handling request");       array e; -  if(e= catch(file = conf->handle_request( this_object() ))) +  mapping result; +  if(e= catch(result = conf->handle_request( this_object() )))    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; +  } +     if( file )    if( file->try_again_later )    {    if( objectp( file->try_again_later ) )    ;    else    call_out( core.handle, file->try_again_later, handle_request );    return;    } -  else if( file->pipe ) -  return; +     TIMER_END(handle_request);    send_result();   }      string url_base()   // See the RequestID class for doc.   {    // Note: Code duplication in server_core/prototypes.pike.       if (!cached_url_base) {
Roxen.git/server/plugins/protocols/http.pike:1844:    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() ); -  catch // paranoia +  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    return;    }       switch( parse_got( s ) )    {    case 0:    REQUEST_WERR("HTTP: Request needs more data.");    return;       case 1:
Roxen.git/server/plugins/protocols/http.pike:1961:    }    }    if( conf )    {    conf->connection_add( this_object(), ([]) );    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    TIMER_START(cache_lookup);    array cv;    if( prot != "HTTP/0.9" &&    misc->cacheable && -  +  !misc->no_proto_cache &&    !since &&    (cv = conf->datacache->get( raw_url )) )    {    MY_TRACE_ENTER (sprintf ("Found %O in ram cache - checking entry", raw_url), 0);    if( !cv[1]->key ) {    MY_TRACE_LEAVE ("Entry invalid due to zero key");    conf->datacache->expire_entry( raw_url );    }    else    {
Roxen.git/server/plugins/protocols/http.pike:2141:    if(!(my_fd && objectp(my_fd)))    end();    else if((predef::time(1) - time) > 4800)    end();   }      static void create(object f, object c, object cc)   {    if(f)    { -  f->set_read_callback(got_data); -  f->set_close_callback(end); +  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();   }      void chain( object f, object c, string le )   {    my_fd = f; -  f->set_read_callback(0); -  f->set_close_callback(end); +  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"); -  time = predef::time(1); +  time = predef::time();       if ( strlen( le ) )    got_data( 0,le );    else    {    // If no pipelined data is available, call out...    remove_call_out(do_timeout);    call_out(do_timeout, 90);    }   
Roxen.git/server/plugins/protocols/http.pike:2186:    {    do_not_disconnect=0;    disconnect();    }    }    else    {    if(do_not_disconnect == -1)    do_not_disconnect = 0;    if(!processed) -  { -  my_fd->set_read_callback(got_data); -  my_fd->set_close_callback(end); +  f->set_nonblocking(got_data, f->query_write_callback(), end);    }   } - } +       string _sprintf(int t)   {    if(t!='O') return 0;    return "RequestID(" + (raw_url||"") + ")"   #ifdef ID_OBJ_DEBUG    + (__marker ? "[" + __marker->count + "]" : "")   #endif    ;   }      Stdio.File connection( )   {    return my_fd;   }      Configuration configuration()   {    return conf;   }