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

version» Context lines:

pike.git/lib/modules/Protocols.pmod/HTTP.pmod/Session.pike:1:   #pike __REAL_VERSION__    - // $Id: Session.pike,v 1.7 2003/03/13 07:52:20 mirar Exp $ + // $Id: Session.pike,v 1.8 2003/03/13 22:47:02 nilsson Exp $      import Protocols.HTTP;      typedef string|Standards.URI|SessionURL URL;      //! The number of redirects to follow, if any.   //! This is the default to the created Request objects.   //!   //! A redirect automatically turns into a GET request,   //! and all header, query, post or put information is dropped.
pike.git/lib/modules/Protocols.pmod/HTTP.pmod/Session.pike:15:   //! Default is 20 redirects. A negative number will mean infinity.   //! @bugs   //! Loops will currently not be detected, only the limit   //! works to stop loops.   //! @seealso   //! @[Request.follow_redirects]      int follow_redirects=20;      //! Default HTTP headers. -  +    mapping default_headers = ([    "user-agent":"Mozilla/5.0 (compatible; MSIE 6.0; Pike HTTP client)"    " Pike/"+__REAL_MAJOR__+"."+__REAL_MINOR__+"."+__REAL_BUILD__,   ]);    -  + //! Request   class Request   { -  +    //! Raw connection object    Query con;      //! URL requested (set by prepare_method).   //! This will update according to followed redirects.    Standards.URI url_requested;      //! Number of redirects to follow;   //! the request will perform another request if the   //! HTTP answer is a 3xx redirect.   //! Default from the parent @[Session.follow_redirects].   //!   //! A redirect automatically turns into a GET request,   //! and all header, query, post or put information is dropped.   //! @bugs   //! Loops will currently not be detected, only the limit   //! works to stop loops. -  +     int follow_redirects= // from parent, will count down    function_object(object_program(this_object()))->follow_redirects;      //! Cookie callback. When a request is performed,   //! the result is checked for cookie changes and   //! additions. If a cookie is encountered, this   //! function is called. Default is to call   //! @[set_http_cookie] in the @[Session] object. -  +     function(string,Standards.URI:mixed) cookie_encountered=set_http_cookie;      // ----------------       int(0..1) con_https; // internal flag      //! Prepares the HTTP Query object for the connection,   //! and returns the parameters to use with @[do_sync],   //! @[do_async] or @[do_thread].   //!   //! This method will also use cookie information from the   //! parent @[Session], and may reuse connections (keep-alive). -  +     array(string|int|mapping) prepare_method(    string method,    URL url,    void|mapping query_variables,    void|mapping extra_headers,    void|string data)    {    if(stringp(url))    url=Standards.URI(url);    url_requested=url;
pike.git/lib/modules/Protocols.pmod/HTTP.pmod/Session.pike:143:    }      // ---------------- sync      //! Perform a request synchronously.   //! Get arguments from @[prepare_method].   //! @returns   //! 0 upon failure, this object upon success   //! @seealso   //! @[prepare_method], @[do_async], @[do_thread] -  +     Request do_sync(array(string|int|mapping) args)    {    for (;;)    {    if(!con) con=give_me_connection(url_requested);    con->sync_request(@args);    if (con->ok)    {    check_for_cookies();    if (con->status>=300 && con->status<400 &&
pike.git/lib/modules/Protocols.pmod/HTTP.pmod/Session.pike:184:      //! Start a request in the background, using a thread.   //! Call @[wait] to wait for the thread to finish.   //! Get arguments from @[prepare_method].   //! @returns   //! The called object.   //! @seealso   //! @[prepare_method], @[do_sync], @[do_async], @[wait]   //! @note   //! @[do_thread] does not rerun redirections automatically -  +     Request do_thread(array(string|int|mapping) args)    {    if(!con) con=give_me_connection(url_requested);    con->thread_request(@args);    return this_object();    }      //! Wait for the request thread to finish.   //! @returns   //! 0 upon failure, or the called object upon success.   //! @seealso   //! @[do_thread] -  +     Request wait()    {    if (con->`()())    {    check_for_cookies();    return this_object();    }    return 0;    }   
pike.git/lib/modules/Protocols.pmod/HTTP.pmod/Session.pike:223:    static array(mixed) extra_callback_arguments;      //! Setup callbacks for async mode,   //! @[headers] will be called when the request got connected,   //! and got data headers; @[data] will be called when the request   //! got the amount of data it's supposed to get and @[fail] is   //! called whenever the request failed.   //!   //! Note here that an error message from the server isn't   //! considered a failure, only a failed TCP connection. -  +     void set_callbacks(function(mixed...:mixed) headers,    function(mixed...:mixed) data,    function(mixed...:mixed) fail,    mixed ...callback_arguments)    {    headers_callback=headers;    data_callback=data;    fail_callback=fail;    extra_callback_arguments=callback_arguments;    }      //! Start a request asyncroneously. It will perform in   //! the background using callbacks (make sure the backend   //! thread is free).   //! Call @[set_callbacks] to setup the callbacks.   //! Get arguments from @[prepare_method].   //! @returns   //! The called object.   //! @seealso   //! @[set_callbacks], @[prepare_method], @[do_sync], @[do_thread] -  +     Request do_async(array(string|int|mapping) args)    {    if(!con)    {    if (connections_host_n[connection_lookup(url_requested)]>=    maximum_connections_per_server ||    (!connections_kept_n &&    connections_inuse_n>=maximum_total_connections))    {    wait_for_connection(do_async,args);
pike.git/lib/modules/Protocols.pmod/HTTP.pmod/Session.pike:369:       foreach (con->headers["set-cookie"]||({});;string cookie)    cookie_encountered(cookie,url_requested);    }      // ----------------      //! @[destroy] is called when an object is destructed.   //! But since this clears the HTTP connection from the Request object,   //! it can also be used to reuse a @[Request] object. -  +     void destroy()    {    if (con) return_connection(url_requested,con);    con=0;    }      // ----------------       string _sprintf(int t)    {
pike.git/lib/modules/Protocols.pmod/HTTP.pmod/Session.pike:472:    !stringp(path) ||    !intp(expires))    error("Cookie.decode: parse error\n");    return this_object();    }   }         //! Parse and set a cookie received in the HTTP protocol.   //! The cookie will be checked against current security levels et al. -  +    void set_http_cookie(string cookie,Standards.URI at)   {    object c=Cookie();    c->from_http(cookie,at);    set_cookie(c,at);   }      //! Set a cookie.   //! The cookie will be checked against current security levels et al,   //! using the parameter @[who].   //! If @[who] is zero, no security checks will be performed. -  +    void set_cookie(Cookie cookie,Standards.URI who)   {   // fixme: insert security checks here       mapping sc=([]);    if ( (sc=cookie_lookup[cookie->site]) )    {    Cookie old=sc[cookie->key];    if (old) all_cookies[old]=0;    }
pike.git/lib/modules/Protocols.pmod/HTTP.pmod/Session.pike:534:    if (!no_clear) all_cookies=(<>);    map(cookies,set_cookie,0);   }      //! Get the cookies that we should send to this server,   //! for this url. They are presented in the form suitable   //! for HTTP headers (as an array).   //! This will also take in count expiration of cookies,   //! and delete expired cookies from the @[Session] unless   //! @[no_delete] is true. -  +    array(string) get_cookies(Standards.URI|SessionURL for_url,    void|int(0..1) no_delete)   {    mapping(string:Cookie) sc=    cookie_lookup[for_url->host+":"+for_url->port]||([]);       array(string) res=({});    int now=time();       foreach (sc;string key;Cookie c)
pike.git/lib/modules/Protocols.pmod/HTTP.pmod/Session.pike:653:   }      static inline string connection_lookup(Standards.URI url)   {    return url->scheme+"://"+url->host+":"+url->port;   }      //! Request a @[Query] object suitable to use for the   //! given URL. This may be a reused object from a keep-alive   //! connection. -  +    Query give_me_connection(Standards.URI url)   {    Query q;       if (array(KeptConnection) v =    connection_cache[connection_lookup(url)])    {    q=v[0]->use(); // removes itself    // clean up    q->buf="";
pike.git/lib/modules/Protocols.pmod/HTTP.pmod/Session.pike:715:    freed_connection_callbacks-=({v});    callback(@args);    return;    }    }   }      //! Return a previously used Query object to the keep-alive   //! storage. This function will determine if the given object   //! is suitable to keep or not by checking status and headers. -  +    void return_connection(Standards.URI url,Query query)   {    connections_inuse_n--;    string lookup=connection_lookup(url);    if (query->con)    {    if (query->headers->connection &&    lower_case(query->headers->connection)=="keep-alive" &&    connections_kept_n+connections_inuse_n    < maximum_total_connections &&
pike.git/lib/modules/Protocols.pmod/HTTP.pmod/Session.pike:773:   //! @decl Request post_url(URL url, @   //! mapping query_variables)   //! @decl Request put_url(URL url,string file, @   //! void|mapping query_variables)   //! @decl Request delete_url(URL url, @   //! void|mapping query_variables)   //! Sends a HTTP GET, POST, PUT or DELETE request to the server in the URL   //! and returns the created and initialized @[Request] object.   //! 0 is returned upon failure.   //! +    Request get_url(URL url,    void|mapping query_variables)   {    return do_method_url("GET", url, query_variables);   }      Request put_url(URL url,    void|string file,    void|mapping query_variables)   {
pike.git/lib/modules/Protocols.pmod/HTTP.pmod/Session.pike:880:    extra_headers=    (extra_headers||([]))|    (["content-type":"application/x-www-form-urlencoded"]);       p->do_async(p->prepare_method(method,url,query_variables,    extra_headers,data));    return p;   }       - //! @decl Request async_get_url(URL url, - //! void|mapping query_variables, - //! function callback_headers_ok, - //! function callback_data_ok, - //! function callback_fail, - //! mixed... callback_arguments); - //! @decl Request async_put_url(URL url, - //! void|string file, - //! void|mapping query_variables, - //! function callback_headers_ok, - //! function callback_data_ok, - //! function callback_fail, - //! mixed... callback_arguments); - //! @decl Request async_delete_url(URL url, - //! void|mapping query_variables, - //! function callback_headers_ok, - //! function callback_data_ok, - //! function callback_fail, - //! mixed... callback_arguments); - //! @decl Request async_post_url(URL url, - //! mapping query_variables, - //! function callback_headers_ok, - //! function callback_data_ok, - //! function callback_fail, - //! mixed... callback_arguments); + //! @decl Request async_get_url(URL url,@ + //! void|mapping query_variables,@ + //! function callback_headers_ok,@ + //! function callback_data_ok,@ + //! function callback_fail,@ + //! mixed... callback_arguments) + //! @decl Request async_put_url(URL url,@ + //! void|string file,@ + //! void|mapping query_variables,@ + //! function callback_headers_ok,@ + //! function callback_data_ok,@ + //! function callback_fail,@ + //! mixed... callback_arguments) + //! @decl Request async_delete_url(URL url,@ + //! void|mapping query_variables,@ + //! function callback_headers_ok,@ + //! function callback_data_ok,@ + //! function callback_fail,@ + //! mixed... callback_arguments) + //! @decl Request async_post_url(URL url,@ + //! mapping query_variables,@ + //! function callback_headers_ok,@ + //! function callback_data_ok,@ + //! function callback_fail,@ + //! mixed... callback_arguments)   //!   //! Sends a HTTP GET, POST, PUT or DELETE request to the server in   //! the URL asynchroneously, and call the corresponding callbacks   //! when result arrives (or not). The callbacks will receive   //! the created Request object as first argument, then   //! the given @[callback_arguments], if any.   //!   //! @[callback_headers_ok] is called when the HTTP request has received   //! headers.   //!
pike.git/lib/modules/Protocols.pmod/HTTP.pmod/Session.pike:975:    mixed ...callback_arguments)   {    return async_do_method_url("POST", url, 0,    http_encode_query(query_variables),0,    callback_headers_ok,callback_data_ok,    callback_fail,callback_arguments);   }      // ----------------------------------------------------------------   // - //! Class to store URL+referer +     -  + //! Class to store URL+referer   class SessionURL   {    inherit Standards.URI;      //! the referer to this URL    URL referer;      //! instantiate a SessionURL object;   //! when fed to Protocols.HTTP.Session calls, will add   //! referer to the HTTP handshaking variables    void create(URL uri,    URL base_uri,    URL _referer)    {    ::create(uri,base_uri);    referer=_referer;    }   }