pike.git / lib / modules / Tools.pmod / Standalone.pmod / httpserver.pike

version» Context lines:

pike.git/lib/modules/Tools.pmod/Standalone.pmod/httpserver.pike:12:       constant help_pre = #"Usage: httpserver [flags] [path]   Starts a simple HTTP server on port 8080 unless another port is specified. The   server will present the contents of the current directory and it's children to   the world without any authentication.   ";       constant port_help = "Port to use. Defaults to 8080.";    constant version_help = "Displays version information.";    constant headers_help = "Set additional header and value, e.g. --header X-Content-Type-Options:nosniff"; +  constant allow_help = "Limit access to a specific IP, IP-range or CIDR net.";    constant log_help = "Logs request in 'commonlog', 'raw' or 'string' format.";       Opt port = Int(HasOpt("--port")|Default(8080));    Opt version = NoOpt("--version");    Opt headers = Multiple(HasOpt("--header")); -  +  Opt allow = Multiple(HasOpt("--allow"));    Opt log = HasOpt("--log");   }      Options opt;   mapping headers = ([]); -  + NetUtils.IpRangeLookup ip_whitelist;      int main(int argc, array(string) argv)   {    opt = Options(argv);       if(opt->version)    exit(0, version); -  +  if(opt->help) +  exit(0);       int port = opt->port;    if(sizeof(argv=opt[Arg.REST]))    {    string home = combine_path(getcwd(), argv[-1]);    if( Stdio.is_dir(home) )    cd(home);    else if(port==8080 && (int)argv[-1])    port=(int)argv[-1];    }
pike.git/lib/modules/Tools.pmod/Standalone.pmod/httpserver.pike:50:    if( opt->headers )    {    foreach(opt->headers, string hdr)    {    array h = hdr/":";    if(sizeof(h)<2) error("Illegal header format %O.\n", hdr);    headers[h[0]] = h[1..]*":";    }    }    +  if( opt->allow ) +  { +  ip_whitelist = NetUtils.IpRangeLookup( ([ 1 : opt->allow ]) ); +  } +     Protocols.HTTP.Server.Port(handle_request, port, NetUtils.ANY);    write("%s is now accessible on port %d through http, "    "without password.\n", getcwd(), port);    return -1;   }      string dirlist( string dir )   {    string res =    "<html><head>\n"
pike.git/lib/modules/Tools.pmod/Standalone.pmod/httpserver.pike:106:    "<html><body><h1>File not found</h1>\n"    "<tt>" + Parser.encode_html_entities(fname) + "</tt><br />\n"    "</body></html>\n";   }      void handle_request(Protocols.HTTP.Server.Request request)   {    string file = "."+combine_path("/",request->not_query);    file = Protocols.HTTP.uri_decode(file);    Stdio.Stat s = file_stat( file ); +  int ipblock = ip_whitelist && +  !ip_whitelist->lookup_range(request->my_fd->query_address());       switch(opt->log)    {    case 1:    case "commonlog":    {    object now = Calendar.now(); -  +  int code = 404; +  if( s ) code = 200; +  if( ipblock ) code = 401;    write("%s - - [%d/%s/%d:%02d:%02d:%02d %s] %O %d %d\n",    (request->my_fd->query_address()/" ")[0],    now->month_day(), now->month_name()[..2], now->year_no(),    now->hour_no(), now->minute_no(), now->second_no(),    now->tzname_utc_offset(), -  request->request_raw, -  s ? 200 : 404, +  request->request_raw, code,    s && s->isreg && s->size); // Not showing generated data.    }    break;    case "raw":    write("%s\n\n", request->raw);    break;    case "string":    write("%O\n\n", request->raw);    break;    default:    break;    }    -  if( !s ) +  if( ipblock ) +  request->response_and_finish( (["data": "Permission denied for "+ +  (request->my_fd->query_address()/" ")[0], +  "type":"text/plain", +  "extra_heads" : headers, +  "error":401]) ); +  else if( !s )    request->response_and_finish( (["data":    file_not_found(request->not_query),    "type":"text/html",    "extra_heads" : headers,    "error":404]) );    else if( s->isdir )    request->response_and_finish( ([ "data":dirlist(file),    "extra_heads" : headers,    "type":"text/html" ]) );    else    request->response_and_finish( ([ "file":Stdio.File(file),    "extra_heads" : headers,    ]) );   }