Roxen.git / server / base_server / roxen.pike

version» Context lines:

Roxen.git/server/base_server/roxen.pike:1:   // This file is part of Roxen WebServer.   // Copyright © 1996 - 2009, Roxen IS.   //   // The Roxen WebServer main program.   //   // Per Hedbor, Henrik Grubbström, Pontus Hagland, David Hedbor and others.   // ABS and suicide systems contributed freely by Francesco Chemolli    - constant cvs_version="$Id: roxen.pike,v 1.1035 2009/06/24 11:38:00 mast Exp $"; + constant cvs_version="$Id: roxen.pike,v 1.1036 2009/06/29 13:15:24 mast Exp $";      //! @appears roxen   //!   //! The Roxen WebServer main program.      // The argument cache. Used by the image cache.   ArgCache argcache;      // Some headerfiles   #define IN_ROXEN
Roxen.git/server/base_server/roxen.pike:1280: Inside #if defined(THREADS)
   if (call_out) monitor->remove_call_out (call_out);   #endif    bg_process_running = 0;    handle (bg_process_queue);    throw (err);    }    bg_process_running = 0;   }   #endif    - protected function get_enqueue_func (function func, array args) - { -  return lambda() -  { -  bg_queue->write (({func, args})); -  if (!bg_process_running) -  handle (bg_process_queue); -  }; - } -  +    mixed background_run (int|float delay, function func, mixed... args)   //! Enqueue a task to run in the background in a way that makes as   //! little impact as possible on the incoming requests. No matter how   //! many tasks are queued to run in the background, only one is run at   //! a time. The tasks won't be starved regardless of server load,   //! though.   //!   //! The function @[func] will be enqueued after approximately @[delay]   //! seconds, to be called with the rest of the arguments as its   //! arguments.
Roxen.git/server/base_server/roxen.pike:1338: Inside #if defined(DEBUG_BACKGROUND_RUN)
   map (args, lambda (mixed arg)    {return sprintf ("%O", arg);}) * ", ",    bg_queue->size());   #endif      #ifdef THREADS    if (!hold_wakeup_cond)    // stop_handler_threads is running; ignore more work.    return 0;    -  mixed res; -  if (delay) -  res = call_out (get_enqueue_func (func, args), delay); -  else -  get_enqueue_func (func, args)(); +  function enqueue = lambda() +  { +  bg_queue->write (({func, args})); +  if (!bg_process_running) +  handle (bg_process_queue); +  };    -  return res; +  // Be careful to zero enqueue below to avoid trampoline garbage. +  +  if (delay) +  // A trick to zero enqueue without putting the call_out return +  // value into a local variable. +  return call_out (enqueue, (enqueue = 0, delay)); +  else { +  enqueue(); +  enqueue = 0; +  return 0; +  }   #else    // Can't do much better when we haven't got threads..    return call_out (func, delay, @args);   #endif   }      class BackgroundProcess   //! A class to do a task repeatedly in the background, in a way that   //! makes as little impact as possible on the incoming requests (using   //! @[background_run]).
Roxen.git/server/base_server/roxen.pike:2613:    string a, b;    foreach( (ui->fragment||"")/";", string x )    {    sscanf( x, "%s=%s", a, b );    opts[a]=b;    }       if( (int)opts->nobind )    {    report_warning( -  LOC_M(61,"Not binding the port %O, disabled in configuration")+"\n", +  LOC_M(61,"Not binding the port %O - disabled in configuration.")+"\n",    (string) ui );    return 0;    }    -  +  string display_url = normalize_url (url, 0);    url = normalize_url (url, 1);    ui = Standards.URI (url);       string protocol = ui->scheme;    string host = ui->host;    if (host == "" || !protocols[protocol]) { -  report_error(LOC_M(19,"Bad URL %O for server `%s'")+"\n", +  report_error(LOC_M(19,"Bad URL %O for server %O.")+"\n",    ourl, conf->query_name());    }       int port = ui->port || protocols[protocol]->default_port;       string path = ui->path;    if (has_suffix(path, "/"))    path = path[..<1];    if (path == "") path = 0;       if( urls[ url ] )    {    if( !urls[ url ]->port )    m_delete( urls, url );    else if( urls[ url ]->conf )    {    if( urls[ url ]->conf != conf )    {    report_error(LOC_M(20, -  "Cannot register URL %s, " -  "already registered by %s!")+"\n", -  url, urls[ url ]->conf->name); +  "Cannot register URL %s - " +  "already registered by %s.")+"\n", +  display_url, urls[ url ]->conf->name);    return 0;    }    urls[ url ]->port->ref(url, urls[url]);    return 1;    }    else    urls[ url ]->port->unref( url );    }       program prot;       if( !( prot = protocols[ protocol ] ) )    { -  report_error(LOC_M(21, "Cannot register URL %s, " -  "cannot find the protocol %s!")+"\n", -  url, protocol); +  report_error(LOC_M(21, "Cannot register URL %s - " +  "cannot find the protocol %s.")+"\n", +  display_url, protocol);    return 0;    }       urls[ url ] = ([ "conf":conf, "path":path, "hostname": host ]);    urls[ ourl ] = urls[url] + ([]);    sorted_urls += ({ url });       array(string)|int(-1..0) required_hosts;       if (is_ip(host))    required_hosts = ({ host });    else if(!sizeof(required_hosts = -  filter(replace(opts->ip||"", " ","")/",", is_ip)) ) +  filter(replace(opts->ip||"", " ","")/",", is_ip)) ) {    required_hosts = find_ips_for( host ); -  +     if (!required_hosts) {    // FIXME: Used to fallback to ANY.    // Will this work with glob URLs? -  report_error(LOC_M(23, "Cannot register URL %s!")+"\n", url); +     return 0;    } -  +  }       mapping(string:mapping(int:Protocol)) m;    if( !( m = open_ports[ protocol ] ) )    // always add 'ANY' (0) and 'IPv6_ANY' (::) here, as empty mappings,    // for speed reasons.    // There is now no need to check for both open_ports[prot][0] and    // open_ports[prot][0][port], we can go directly to the latter    // test.    m = open_ports[ protocol ] = ([ 0:([]), "::":([]) ]);   
Roxen.git/server/base_server/roxen.pike:2715: Inside #if constant(__ROXEN_SUPPORTS_IPV6__)
   }   #if constant(__ROXEN_SUPPORTS_IPV6__)    if (m["::"][port] && sizeof(ipv6 - ({ "::" }))) {    // We have a non-ANY IPv6 IP number.    ipv6 = ({ "::" });    }    required_hosts = ipv4 + ipv6;   #else    if (sizeof(ipv6)) {    foreach(ipv6, string p) { -  report_warning(LOC_M(65, "IPv6 port for URL %s disabled: %s\n"), -  url, p); +  report_warning(LOC_M(65, "Cannot open port %s for URL %s - " +  "IPv6 support disabled.\n"), +  p, display_url);    }    }    required_hosts = ipv4;   #endif /* __ROXEN_SUPPORTS_IPV6__ */    }       int failures;    int opened_ipv4_any_port;       foreach(required_hosts, string required_host)
Roxen.git/server/base_server/roxen.pike:2747:    urls[ourl]->ports += ({ m[required_host][port] });    } else {    urls[ourl]->ports = ({ m[required_host][port] });    }    continue; /* No need to open a new port */    }       if( !m[ required_host ] )    m[ required_host ] = ([ ]);    +  +  Protocol prot_obj;    if (mixed err = catch { -  m[ required_host ][ port ] = +  prot_obj = m[ required_host ][ port ] =    prot( port, required_host,    // Don't complain if binding IPv6 ANY fails with    // EADDRINUSE after we've bound IPv4 ANY. At least on    // Linux, it seems that IPv4 and IPv6 can share the    // same interface, and in that case we're already done    // if we've bound the IPv4 ANY.    required_host == "::" && opened_ipv4_any_port);    }) {    failures++; -  + #if 0    if (has_prefix(describe_error(err), "Invalid address") &&    required_host && has_value(required_host, ":")) {    report_error(sprintf("Failed to initialize IPv6 port for URL %s" -  " (ip %s). Not supported?\n", -  url, required_host)); -  } else { -  report_error(sprintf("Initializing the port handler for URL %s" -  " failed! (ip %s)\n" -  "%s\n", -  url, +  " (ip %s).\n", +  display_url, required_host)); +  } else + #endif +  report_error(sprintf("Initializing the port handler for " +  "URL %s (ip %s) failed: %s\n", +  display_url,    required_host||"ANY", -  describe_backtrace(err))); -  } + #ifdef DEBUG +  describe_backtrace(err) + #else +  describe_error (err) + #endif +  ));    continue;    }       if (!required_host) opened_ipv4_any_port = 1;    -  Protocol prot_obj = m[required_host][port]; -  -  if( !prot_obj ) -  { -  m_delete( m[ required_host ], port ); -  failures++; -  if (required_host) { -  report_warning(LOC_M(22, "Binding the port on IP %s failed\n" -  " for URL %s!\n"), -  required_host, url); -  } -  continue; -  } -  +     if (prot_obj->bound == -1) {    // Got EADDRINUSE for the IPv6 case - see above. Just forget    // about this one.    m_delete (m[required_host], port);    continue;    }       urls[ url ]->port = prot_obj;    urls[ ourl ]->port = prot_obj;    if (urls[ourl]->ports) {
Roxen.git/server/base_server/roxen.pike:2811:    } else {    urls[ourl]->ports = ({ prot_obj });    }    prot_obj->ref(url, urls[url]);       if( !prot_obj->bound )    failures++;    }    if (failures == sizeof(required_hosts))    { -  report_error(LOC_M(23, "Cannot register URL %s!")+"\n", url); +  report_error(LOC_M(23, "Failed to register URL %s for %O.")+"\n", +  display_url, conf->query_name());    return 0;    }    sort_urls();       // The following will show the punycoded version for IDN hostnames.    // That is intentional, to make it clear what actually happens. -  report_notice(" "+LOC_S(3, "Registered %s for %s")+"\n", -  url, conf->query_name() ); +  report_notice(" "+LOC_S(3, "Registered URL %s for %O.")+"\n", +  display_url, conf->query_name() );    return 1;   }         Configuration find_configuration( string name )   //! Searches for a configuration with a name or fullname like the   //! given string. See also get_configuration().   {    // Optimization, in case the exact name is given...    if( Configuration o = get_configuration( name ) )