pike.git / lib / modules / Protocols.pmod / HTTP.pmod / module.pmod

version» Context lines:

pike.git/lib/modules/Protocols.pmod/HTTP.pmod/module.pmod:39:   constant HTTP_CONFLICT = 409; // RFC 2616 10.4.10: Conflict   constant HTTP_GONE = 410; // RFC 2616 10.4.11: Gone   constant HTTP_LENGTH_REQ = 411; // RFC 2616 10.4.12: Length Required   constant HTTP_PRECOND_FAILED = 412; // RFC 2616 10.4.13: Precondition Failed   constant HTTP_REQ_TOO_LARGE = 413; // RFC 2616 10.4.14: Request Entity Too Large   constant HTTP_URI_TOO_LONG = 414; // RFC 2616 10.4.15: Request-URI Too Long   constant HTTP_UNSUPP_MEDIA = 415; // RFC 2616 10.4.16: Unsupported Media Type   constant HTTP_BAD_RANGE = 416; // RFC 2616 10.4.17: Requested Range Not Satisfiable   constant HTTP_EXPECT_FAILED = 417; // RFC 2616 10.4.18: Expectation Failed   constant HTCPCP_TEAPOT = 418; // RFC 2324 2.3.2: I'm a teapot + constant HTTP_MISDIRECTED_REQ = 421; // RFC 7540 9.1.2: Misdirected Request   constant DAV_UNPROCESSABLE = 422; // RFC 2518 10.3: Unprocessable Entry   constant DAV_LOCKED = 423; // RFC 2518 10.4: Locked   constant DAV_FAILED_DEP = 424; // RFC 2518 10.5: Failed Dependency      constant HTTP_LEGALLY_RESTRICTED= 451; // Draft: Unavailable for Legal Reasons      // Server errors   constant HTTP_INTERNAL_ERR = 500; // RFC 2616 10.5.1: Internal Server Error   constant HTTP_NOT_IMPL = 501; // RFC 2616 10.5.2: Not Implemented   constant HTTP_BAD_GW = 502; // RFC 2616 10.5.3: Bad Gateway
pike.git/lib/modules/Protocols.pmod/HTTP.pmod/module.pmod:106:    409:"409 Conflict",    410:"410 Gone",    411:"411 Length Required",    412:"412 Precondition Failed",    413:"413 Request Entity Too Large",    414:"414 Request-URI Too Large",    415:"415 Unsupported Media Type",    416:"416 Requested range not statisfiable",    417:"417 Expectation Failed",    418:"418 I'm a teapot", // Ha ha +  421:"421 Misdirected Request",    422:"422 Unprocessable Entity", // WebDAV    423:"423 Locked", // WebDAV    424:"424 Failed Dependency", // WebDAV    425:"425 Unordered Collection", // RFC3648    426:"426 Upgrade Required", // RFC2817    451:"451 Unavailable for Legal Reasons", // draft-tbray-http-legally-restricted-status       // Internal Server Errors    500:"500 Internal Server Error.",    501:"501 Not Implemented",
pike.git/lib/modules/Protocols.pmod/HTTP.pmod/module.pmod:174:    mapping(string:string|array(string)) proxy_headers;       if( user || password )    {    if( !request_headers )    proxy_headers = ([]);    else    proxy_headers = request_headers + ([]);       proxy_headers["Proxy-Authorization"] = "Basic " -  + MIME.encode_base64((user || "") + ":" + (password || "")); +  + MIME.encode_base64((user || "") + ":" + (password || ""), 1);    }       if (url->scheme == "http") {    if( query_variables )    url->set_query_variables( url->get_query_variables() +    query_variables );    string web_url = (string)url;       // Note: url object is wrecked here -  +  url->scheme = proxy->scheme;    url->host = proxy->host;    url->port = proxy->port;    query_variables = url->query = 0;    url->path = web_url; - #if constant(SSL.sslfile) +     } else if (url->scheme == "https") {   #ifdef HTTP_QUERY_DEBUG    werror("Proxied SSL request.\n");   #endif    if (!con || (con->host != url->host) || (con->port != url->port)) {    // Make a CONNECT request to the proxy,    // and use keep-alive to stack the real request on top.    proxy->path = url->host + ":" + url->port;    if (!proxy_headers) proxy_headers = ([]);    proxy_headers->connection = "keep-alive";
pike.git/lib/modules/Protocols.pmod/HTTP.pmod/module.pmod:213: Inside #if constant(SSL.sslfile)
   return con;    }    con->headers["connection"] = "keep-alive";    con->headers["content-length"] = "0";    con->host = url->host;    con->port = url->port;    con->https = 1;    con->start_tls(1);    }    proxy_headers = request_headers; - #endif +     } else {    error("Can't handle proxying of %O.\n", url->scheme);    }       return do_method(method, url, query_variables, proxy_headers, con, data);   }      //! Low level HTTP call method.   //!   //! @param method
pike.git/lib/modules/Protocols.pmod/HTTP.pmod/module.pmod:260:    url=Standards.URI(url);       if( (< "httpu", "httpmu" >)[url->scheme] ) {    return do_udp_method(method, url, query_variables, request_headers,    con, data);    }       if(!con)    con = .Query();    - #if constant(SSL.sslfile) +     if(url->scheme!="http" && url->scheme!="https")    error("Can't handle %O or any other protocols than HTTP or HTTPS.\n",    url->scheme);       con->https = (url->scheme=="https")? 1 : 0; - #else -  if(url->scheme!="http") -  error("Can't handle %O or any other protocol than HTTP " -  "(HTTPS requires Nettle support).\n", -  url->scheme); - #endif +        mapping default_headers = ([    "user-agent" : "Mozilla/5.0 (compatible; MSIE 6.0; Pike HTTP client)"    " Pike/" + __REAL_MAJOR__ + "." + __REAL_MINOR__ + "." + __REAL_BUILD__,    "host" : url->host +    (url->port!=(url->scheme=="https"?443:80)?":"+url->port:"")]);       if(url->user || url->password)    default_headers->authorization = "Basic "    + MIME.encode_base64(url->user + ":" + -  (url->password || "")); +  (url->password || ""), +  1);       if(!request_headers)    request_headers = default_headers;    else    request_headers = default_headers |    mkmapping(lower_case(indices(request_headers)[*]),    values(request_headers));       string query=url->query;    if(query_variables && sizeof(query_variables))
pike.git/lib/modules/Protocols.pmod/HTTP.pmod/module.pmod:309:       string path=url->path;    if(path=="") path="/";       con->sync_request(url->host,url->port,    method+" "+path+(query?("?"+query):"")+" HTTP/1.0",    request_headers, data);       if (!con->ok) {    if (con->errno) -  error ("I/O error: %s\n", strerror (con->errno)); +  error ("I/O error: %s.\n", strerror (con->errno));    return 0;    }    return con;   }      protected .Query do_udp_method(string method, Standards.URI url,    void|mapping(string:int|string|array(string)) query_variables,    void|mapping(string:string|array(string))    request_headers, void|Protocols.HTTP.Query con,    void|string data)
pike.git/lib/modules/Protocols.pmod/HTTP.pmod/module.pmod:396:    void|mapping(string:string|array(string)) request_headers,    Protocols.HTTP.Query con, void|string data)   {    if(stringp(url))    url=Standards.URI(url);       if( (< "httpu", "httpmu" >)[url->scheme] ) {    error("Asynchronous httpu or httpmu not yet supported.\n");    }    - #if constant(SSL.sslfile) +     if(url->scheme!="http" && url->scheme!="https")    error("Can't handle %O or any other protocols than HTTP or HTTPS.\n",    url->scheme);       con->https = (url->scheme=="https")? 1 : 0; - #else -  if(url->scheme!="http") -  error("Can't handle %O or any other protocol than HTTP.\n", -  url->scheme); - #endif +        if(!request_headers)    request_headers = ([]);    mapping default_headers = ([    "user-agent" : "Mozilla/5.0 (compatible; MSIE 6.0; Pike HTTP client)"    " Pike/" + __REAL_MAJOR__ + "." + __REAL_MINOR__ + "." + __REAL_BUILD__,    "host" : url->host +    (url->port!=(url->scheme=="https"?443:80)?":"+url->port:"")]);    -  if(url->user || url->passwd) +  if(url->user || url->password)    default_headers->authorization = "Basic "    + MIME.encode_base64(url->user + ":" + -  (url->password || "")); +  (url->password || ""), +  1);    request_headers = default_headers | request_headers;       string query=url->query;    if(query_variables && sizeof(query_variables))    {    if(query)    query+="&"+http_encode_query(query_variables);    else    query=http_encode_query(query_variables);    }       string path=url->path;    if(path=="") path="/";    -  if (!con->headers || -  lower_case(con->headers["connection"]||"close") == "close") { -  // Reset the state of con. -  con->data_timeout = 120; -  con->timeout = 120; -  con->con = 0; -  // con->conthread = 0; -  } -  +     con->async_request(url->host, url->port,    method+" "+path+(query?("?"+query):"")+" HTTP/1.0",    request_headers, data);   }      protected void https_proxy_connect_fail(Protocols.HTTP.Query con,    array(mixed) orig_cb_info,    Standards.URI url, string method,    mapping(string:string) query_variables,    mapping(string:string) request_headers,
pike.git/lib/modules/Protocols.pmod/HTTP.pmod/module.pmod:468:      protected void https_proxy_connect_ok(Protocols.HTTP.Query con,    array(mixed) orig_cb_info,    Standards.URI url, string method,    mapping(string:string) query_variables,    mapping(string:string) request_headers,    string data)   {    con->set_callbacks(@orig_cb_info);    +  // Install the timeout handler for the interval until +  // the TLS connection is up. +  con->init_async_timeout();    con->con->set_nonblocking(0,    lambda() { -  +  // Remove the timeout handler; it will be +  // reinstated by do_async_method() below. +  con->remove_async_timeout();    do_async_method(method, url, query_variables,    request_headers, con, data);    }, con->async_failed);       con->headers["connection"] = "keep-alive";    con->headers["content-length"] = "0";    con->host = url->host;    con->port = url->port;    con->https = 1;    con->start_tls(0);
pike.git/lib/modules/Protocols.pmod/HTTP.pmod/module.pmod:546:    mapping(string:string|array(string)) proxy_headers;       if( user || password )    {    if( !request_headers )    proxy_headers = ([]);    else    proxy_headers = request_headers + ([]);       proxy_headers["Proxy-Authorization"] = "Basic " -  + MIME.encode_base64((user || "") + ":" + (password || "")); +  + MIME.encode_base64((user || "") + ":" + (password || ""), 1);    }       if (url->scheme == "http") {    if( query_variables )    url->set_query_variables( url->get_query_variables() +    query_variables );    string web_url = (string)url;       // Note: url object is wrecked here -  +  url->scheme = proxy->scheme;    url->host = proxy->host;    url->port = proxy->port;    query_variables = url->query = 0;    url->path = web_url; - #if constant(SSL.sslfile) +     } else if(url->scheme == "https") {   #ifdef HTTP_QUERY_DEBUG    werror("Proxied SSL request.\n");   #endif    if (!con || (con->host != url->host) || (con->port != url->port)) {    // Make a CONNECT request to the proxy,    // and use keep-alive to stack the real request on top.    proxy->path = url->host + ":" + url->port;    if (!proxy_headers) proxy_headers = ([]);    proxy_headers->connection = "keep-alive";
pike.git/lib/modules/Protocols.pmod/HTTP.pmod/module.pmod:591: Inside #if constant(SSL.sslfile)
   url, method,    query_variables,    request_headers && request_headers + ([]),    data);    method = "CONNECT";    url = proxy;    data = 0;    } else {    proxy_headers = request_headers;    } - #endif +     } else {    error("Can't handle proxying of %O.\n", url->scheme);    }       do_async_method(method, url, query_variables, proxy_headers, con, data);   }      //! Sends a HTTP GET request to the server in the URL and returns the   //! created and initialized @[Query] object. @expr{0@} is returned   //! upon failure. If a query object having
pike.git/lib/modules/Protocols.pmod/HTTP.pmod/module.pmod:731:      //! Encodes a query mapping to a string;   //! this protects odd - in http perspective - characters   //! like '&' and '#' and control characters,   //! and packs the result together in a HTTP query string.   //!   //! Example:   //! @pre{   //! > Protocols.HTTP.http_encode_query( (["anna":"eva","lilith":"blue"]) );   //! Result: "lilith=blue&anna=eva" - //! > Protocols.HTTP.http_encode_query( (["&amp;":"&","'=\"":"\0\0\0"]) ); - //! Result: "%26amp%3b=%26&%27%3d%22=%00%00%00" + //! > Protocols.HTTP.http_encode_query( (["&amp;":"&","'=\"":"\0\0\0\u0434"]) ); + //! Result: "%27%3D%22=%00%00%00%D0%B4&%26amp%3B=%26"   //! @}   string http_encode_query(mapping(string:int|string|array(string)) variables)   { -  return Array.map((array)variables, +  return map((array)variables,    lambda(array(string|int|array(string)) v)    {    if (intp(v[1]))    return uri_encode(v[0]);    if (arrayp(v[1]))    return map(v[1], lambda (string val) {    return    uri_encode(v[0])+"="+    uri_encode(val);    })*"&";
pike.git/lib/modules/Protocols.pmod/HTTP.pmod/module.pmod:769:   protected local constant other_chars =    (string) enumerate (0x20) + "\x7f" // Control chars    " \"<>\\^`{|}";      protected local constant eight_bit_chars = (string) enumerate (0x80, 1, 0x80);      string percent_encode (string s)   //! Encodes the given string using @tt{%XX@} encoding, except that URI   //! unreserved chars are not encoded. The unreserved chars are   //! @tt{A-Z@}, @tt{a-z@}, @tt{0-9@}, @tt{-@}, @tt{.@}, @tt{_@}, and - //! @tt{~@} (see RFC 2396 section 2.3). + //! @tt{~@} (see @rfc{2396:2.3@}).   //!   //! 8-bit chars are encoded straight, and wider chars are not allowed.   //! That means this encoding is applicable if @[s] is a binary octet   //! string. If it is a character string then @[uri_encode] should be   //! used instead.   //!   //! It is also slightly faster than @[uri_encode] if @[s] is known to   //! contain only US-ASCII.   {    constant replace_chars = (gen_delims + sub_delims +
pike.git/lib/modules/Protocols.pmod/HTTP.pmod/module.pmod:809:   //! is necessary to work as the reverse of @[iri_encode].   {    return _Roxen.http_decode_string (s);   }      string uri_encode (string s)   //! Encodes the given string using @tt{%XX@} encoding to be used as a   //! component part in a URI. This means that all URI reserved and   //! excluded characters are encoded, i.e. everything except @tt{A-Z@},   //! @tt{a-z@}, @tt{0-9@}, @tt{-@}, @tt{.@}, @tt{_@}, and @tt{~@} (see - //! RFC 2396 section 2.3). + //! @rfc{2396:2.3@}).   //!   //! 8-bit chars and wider are encoded using UTF-8 followed by - //! percent-encoding. This follows RFC 3986 section 2.5, the - //! IRI-to-URI conversion method in the IRI standard (RFC 3987) and - //! appendix B.2 in the HTML 4.01 standard. It should work regardless - //! of the charset used in the XML document the URI might be inserted - //! into. + //! percent-encoding. This follows @rfc{3986:2.5@}, the IRI-to-URI + //! conversion method in the IRI standard (@rfc{3987@}) and appendix + //! B.2 in the HTML 4.01 standard. It should work regardless of the + //! charset used in the XML document the URI might be inserted into.   //!   //! @seealso   //! @[uri_decode], @[uri_encode_invalids], @[iri_encode]   {    return percent_encode (string_to_utf8 (s));   }      string uri_encode_invalids (string s)   //! Encodes all "dangerous" chars in the given string using @tt{%XX@}   //! encoding, so that it can be included as a URI in an HTTP message   //! or header field. This includes control chars, space and various - //! delimiter chars except those in the URI @tt{reserved@} set (RFC - //! 2396 section 2.2). + //! delimiter chars except those in the URI @tt{reserved@} set + //! (@rfc{2396:2.2@}).   //!   //! Since this function doesn't touch the URI @tt{reserved@} chars nor   //! the escape char @tt{%@}, it can be used on a complete formatted   //! URI or IRI.   //!   //! 8-bit chars and wider are encoded using UTF-8 followed by - //! percent-encoding. This follows RFC 3986 section 2.5, the IRI - //! standard (RFC 3987) and appendix B.2 in the HTML 4.01 standard. + //! percent-encoding. This follows @rfc{3986:2.5@}, the IRI standard + //! (@rfc{3987@}) and appendix B.2 in the HTML 4.01 standard.   //!   //! @note   //! The characters in the URI @tt{reserved@} set are: @tt{:@},   //! @tt{/@}, @tt{?@}, @tt{#@}, @tt{[@}, @tt{]@}, @tt{@@@}, @tt{!@},   //! @tt{$@}, @tt{&@}, @tt{'@}, @tt{(@}, @tt{)@}, @tt{*@}, @tt{+@},   //! @tt{,@}, @tt{;@}, @tt{=@}. In addition, this function doesn't   //! touch the escape char @tt{%@}.   //!   //! @seealso   //! @[uri_decode], @[uri_encode]
pike.git/lib/modules/Protocols.pmod/HTTP.pmod/module.pmod:873:    // Note: This currently does not quite work for URI-to-IRI    // conversion according to RFC 3987 section 3.2. Most importantly    // any invalid utf8-sequences should be left percent-encoded in the    // result.    return utf8_to_string (_Roxen.http_decode_string (s));   }      string iri_encode (string s)   //! Encodes the given string using @tt{%XX@} encoding to be used as a   //! component part in an IRI (Internationalized Resource Identifier, - //! see RFC 3987). This means that all chars outside the IRI + //! see @rfc{3987@}). This means that all chars outside the IRI   //! @tt{iunreserved@} set are encoded, i.e. this function encodes   //! equivalently to @[uri_encode] except that all 8-bit and wider   //! characters are left as-is.   //!   //! @bugs   //! This function currently does not encode chars in the Unicode   //! private ranges, although that is strictly speaking required in   //! some but not all IRI components. That could change if it turns out   //! to be a problem.   //!   //! @seealso   //! @[percent_decode], @[uri_encode]   {    constant replace_chars = gen_delims + sub_delims + other_chars;    return replace (s,    sprintf ("%c", ((array(int)) replace_chars)[*]),    sprintf ("%%%02X", ((array(int)) replace_chars)[*]));   }    - #if 0 - // These functions are disabled since I haven't found a way to - // implement them even remotely efficiently using pike only. /mast -  - string uri_normalize (string s) - //! Normalizes the URI-style @tt{%XX@} encoded string @[s] by decoding - //! all URI @tt{unreserved@} chars, i.e. US-ASCII digits, letters, - //! @tt{-@}, @tt{.@}, @tt{_@}, and @tt{~@}. - //! - //! Since only unreserved chars are decoded, the result is always - //! semantically equivalent to the input. It's therefore safe to use - //! this on a complete formatted URI. - //! - //! @seealso - //! @[uri_decode], @[uri_encode], @[iri_normalize] - { -  // FIXME - } -  - string iri_normalize (string s) - //! Normalizes the IRI-style UTF-8 and @tt{%XX@} encoded string @[s] - //! by decoding all IRI @tt{unreserved@} chars, i.e. everything except - //! the URI @tt{reserved@} chars and control chars. - //! - //! Since only unreserved chars are decoded, the result is always - //! semantically equivalent to the input. It's therefore safe to use - //! this on a complete formatted IRI. - //! - //! @seealso - //! @[iri_decode], @[uri_normalize] - { -  // FIXME - } -  - #endif -  +    string quoted_string_encode (string s)   //! Encodes the given string quoted to be used as content inside a - //! @tt{quoted-string@} according to RFC 2616 section 2.2. The - //! returned string does not include the surrounding @tt{"@} chars. + //! @tt{quoted-string@} according to @rfc{2616:2.2@}. The returned + //! string does not include the surrounding @tt{"@} chars.   //!   //! @note - //! The @tt{quoted-string@} quoting rules in RFC 2616 have several + //! The @tt{quoted-string@} quoting rules in @rfc{2616@} have several   //! problems:   //!   //! @ul   //! @item   //! Quoting is inconsistent since @tt{"@} is quoted as @tt{\"@}, but   //! @tt{\@} does not need to be quoted. This is resolved in the HTTP   //! bis update to mandate quoting of @tt{\@} too, which this   //! function performs.   //!   //! @item
pike.git/lib/modules/Protocols.pmod/HTTP.pmod/module.pmod:959:   //! @endul   //!   //! @seealso   //! @[quoted_string_decode]   {    return replace (s, (["\"": "\\\"", "\\": "\\\\"]));   }      string quoted_string_decode (string s)   //! Decodes the given string which has been encoded as a - //! @tt{quoted-string@} according to RFC 2616 section 2.2. @[s] is - //! assumed to not include the surrounding @tt{"@} chars. + //! @tt{quoted-string@} according to @rfc{2616:2.2@}. @[s] is assumed + //! to not include the surrounding @tt{"@} chars.   //!   //! @seealso   //! @[quoted_string_encode]   {    return map (s / "\\\\", replace, "\\", "") * "\\";   } -  - // --- Compatibility code -  - __deprecated__ string http_encode_string(string in) - //! This is a deprecated alias for @[uri_encode], for compatibility - //! with Pike 7.6 and earlier. - //! - //! In 7.6 this function didn't handle 8-bit and wider chars - //! correctly. It encoded 8-bit chars directly to @tt{%XX@} escapes, - //! and it used nonstandard @tt{%uXXXX@} escapes for 16-bit chars. - //! - //! That is considered a bug, and hence the function is changed. If - //! you need the old buggy encoding then use the 7.6 compatibility - //! version (@expr{#pike 7.6@}). - //! - //! @deprecated uri_encode - { -  return uri_encode (in); - } -  - //! This function used to claim that it encodes the specified string - //! according to the HTTP cookie standard. If fact it does not - it - //! applies URI-style (i.e. @expr{%XX@}) encoding on some of the - //! characters that cannot occur literally in cookie values. There - //! exist some web servers (read Roxen and forks) that usually perform - //! a corresponding nonstandard decoding of %-style escapes in cookie - //! values in received requests. - //! - //! This function is deprecated. The function @[quoted_string_encode] - //! performs encoding according to the standard, but it is not safe to - //! use with arbitrary chars. Thus URI-style encoding using - //! @[uri_encode] or @[percent_encode] is normally a good choice, if - //! you can use @[uri_decode]/@[percent_decode] at the decoding end. - //! - //! @deprecated - __deprecated__ string http_encode_cookie(string f) - { -  return replace( -  f, -  ({ "\000", "\001", "\002", "\003", "\004", "\005", "\006", "\007", -  "\010", "\011", "\012", "\013", "\014", "\015", "\016", "\017", -  "\020", "\021", "\022", "\023", "\024", "\025", "\026", "\027", -  "\030", "\031", "\032", "\033", "\034", "\035", "\036", "\037", -  "\177", -  "\200", "\201", "\202", "\203", "\204", "\205", "\206", "\207", -  "\210", "\211", "\212", "\213", "\214", "\215", "\216", "\217", -  "\220", "\221", "\222", "\223", "\224", "\225", "\226", "\227", -  "\230", "\231", "\232", "\233", "\234", "\235", "\236", "\237", -  " ", "%", "'", "\"", ",", ";", "=", ":" }), -  ({ -  "%00", "%01", "%02", "%03", "%04", "%05", "%06", "%07", -  "%08", "%09", "%0a", "%0b", "%0c", "%0d", "%0e", "%0f", -  "%10", "%11", "%12", "%13", "%14", "%15", "%16", "%17", -  "%18", "%19", "%1a", "%1b", "%1c", "%1d", "%1e", "%1f", -  "%7f", -  "%80", "%81", "%82", "%83", "%84", "%85", "%86", "%87", -  "%88", "%89", "%8a", "%8b", "%8c", "%8d", "%8e", "%8f", -  "%90", "%91", "%92", "%93", "%94", "%95", "%96", "%97", -  "%98", "%99", "%9a", "%9b", "%9c", "%9d", "%9e", "%9f", -  "%20", "%25", "%27", "%22", "%2c", "%3b", "%3d", "%3a" })); - } -  - //! Helper function for replacing HTML entities with the corresponding - //! unicode characters. - //! @deprecated Parser.parse_html_entities - __deprecated__ string unentity(string s) - { -  return master()->resolv("Parser.parse_html_entities")(s,1); - } +