Roxen.git / server / etc / modules / HTTPClient.pmod

version» Context lines:

Roxen.git/server/etc/modules/HTTPClient.pmod:42:   #ifdef HTTP_CLIENT_DEBUG   # define TRACE(X...)werror("%s:%d: %s",basename(__FILE__),__LINE__,sprintf(X))   #else   # define TRACE(X...)0   #endif      protected constant DEFAULT_MAXTIME = 60;         //! Do a HTTP GET request - public Result sync_get(Protocols.HTTP.Session.URL uri, void|Arguments args) + public Result sync_get(Protocols.HTTP.Session.URL uri, +  void|Arguments args, +  void|Session session)   { -  return do_safe_method("GET", uri, args); +  return do_safe_method("GET", uri, args, false, session);   }         //! Do a HTTP POST request - public Result sync_post(Protocols.HTTP.Session.URL uri, void|Arguments args) + public Result sync_post(Protocols.HTTP.Session.URL uri, +  void|Arguments args, +  void|Session session)   { -  return do_safe_method("POST", uri, args); +  return do_safe_method("POST", uri, args, false, session);   }         //! Do a HTTP PUT request - public Result sync_put(Protocols.HTTP.Session.URL uri, void|Arguments args) + public Result sync_put(Protocols.HTTP.Session.URL uri, +  void|Arguments args, +  void|Session session)   { -  return do_safe_method("PUT", uri, args); +  return do_safe_method("PUT", uri, args, false, session);   }         //! Do a HTTP DELETE request - public Result sync_delete(Protocols.HTTP.Session.URL uri, void|Arguments args) + public Result sync_delete(Protocols.HTTP.Session.URL uri, +  void|Arguments args, +  void|Session session)   { -  return do_safe_method("DELETE", uri, args); +  return do_safe_method("DELETE", uri, args, false, session);   }         //! Do an async HTTP GET request - public void async_get(Protocols.HTTP.Session.URL uri, void|Arguments args) + public void async_get(Protocols.HTTP.Session.URL uri, +  void|Arguments args, +  void|Session session)   { -  do_safe_method("GET", uri, args, true); +  do_safe_method("GET", uri, args, true, session);   }         //! Do an async HTTP POST request - public void async_post(Protocols.HTTP.Session.URL uri, void|Arguments args) + public void async_post(Protocols.HTTP.Session.URL uri, +  void|Arguments args, +  void|Session session)   { -  do_safe_method("POST", uri, args, true); +  do_safe_method("POST", uri, args, true, session);   }         //! Do an async HTTP PUT request - public void async_put(Protocols.HTTP.Session.URL uri, void|Arguments args) + public void async_put(Protocols.HTTP.Session.URL uri, +  void|Arguments args, +  void|Session session)   { -  do_safe_method("PUT", uri, args, true); +  do_safe_method("PUT", uri, args, true, session);   }         //! Do an async HTTP DELETE request - public void async_delete(Protocols.HTTP.Session.URL uri, void|Arguments args) + public void async_delete(Protocols.HTTP.Session.URL uri, +  void|Arguments args, +  void|Session session)   { -  do_safe_method("DELETE", uri, args, true); +  do_safe_method("DELETE", uri, args, true, session);   }         //! Fetch an URL with a timeout with the @[http_method] method.   public Result do_safe_method(string http_method,    Protocols.HTTP.Session.URL uri,    void|Arguments args, -  void|bool async) +  void|bool async, +  void|Session session)   {    if (!args) {    args = Arguments();    }       Result res; -  Session s = Session(); +  Session s = session || Session();    if (args && args->follow_redirects > -1) {    s->follow_redirects = args->follow_redirects;    }    object /* Session.Request */ qr;    Thread.Queue q;    mixed co_maxtime;       if (args->maxtime) s->maxtime = args->maxtime;    if (args->timeout) s->timeout = args->timeout;   
Roxen.git/server/etc/modules/HTTPClient.pmod:148:       qr = s->async_do_method_url(http_method, uri,    args->variables,    args->data,    args->headers,    0, // headers received callback    cb, // ok callback    cb, // fail callback    args->extra_args || ({}));    +  if (!async) {    if (!query_has_maxtime()) {    TRACE("No maxtime in Protocols.HTTP.Query. Set external max timeout: %O\n",    s->maxtime || DEFAULT_MAXTIME);    co_maxtime = call_out(lambda () {    TRACE("Timeout callback: %O\n", qr);       res = Failure(([    "status" : 504,    "status_desc" : "Gateway timeout",    "host" : qr->con->host,    "headers" : qr->con->headers,    "url" : qr->url_requested    ]));       qr->set_callbacks(0, 0, 0, 0);    qr->con->set_callbacks(0, 0, 0);    destruct(qr); -  destruct(s); +  s = 0;       q && q->write("@");    -  if (async) { -  if (args->on_failure) { +  if (async && args->on_failure) {    args->on_failure(res);    } -  -  qr = 0; -  s = 0; -  } +     }, s->maxtime || DEFAULT_MAXTIME);    }    -  if (!async) { +     q->read(); -  } +        if (co_maxtime && co_maxtime[0]) {    TRACE("Remove timeout callout\n");    remove_call_out(co_maxtime);    }    -  if (!async) { +     q = 0;    qr = 0;    s = 0;    }       return res;   }         //! If the Protocols.HTTP.Query class doesn't have the maxtime property
Roxen.git/server/etc/modules/HTTPClient.pmod:234:    //! default value being used.    int follow_redirects = -1;       //! Additional request headers    mapping(string:string) headers;       //! Query variables    mapping(string:mixed) variables;       //! POST data -  void|string|mapping data; +  void|string|mapping|Stdio.Stream data;       //! Callback to call on successful async request    function(Result:void) on_success;       //! Callback to call on failed async request    function(Result:void) on_failure;       //! Extra arguments that will end up in the @[Result] object    array(mixed) extra_args;   
Roxen.git/server/etc/modules/HTTPClient.pmod:405:   //! @[Concurrent.Future()->on_failure()] callback registered on the returned   //! @[Concurrent.Future] object from @[get_url()], @[post_url()],   //! @[delete_url()], @[put_url()] or @[do_method()].   class Failure   {    inherit Result;    public bool `ok() { return false; }   }       - //! Internal class for the actual HTTP requests - protected class Session + //! Class for the actual HTTP requests + public class Session   {    inherit Protocols.HTTP.Session : parent;       public int(0..) maxtime, timeout;    public int maximum_connections_per_server = 20;       Request async_do_method_url(string method,    URL url,    void|mapping query_variables, -  void|string|mapping data, +  void|string|mapping|Stdio.Stream data,    void|mapping extra_headers,    function callback_headers_ok,    function callback_data_ok,    function callback_fail,    array callback_arguments)    {    if (stringp(url)) {    url = Standards.URI(url);    }   
Roxen.git/server/etc/modules/HTTPClient.pmod:510:    if (!has_content_type) {    extra_headers["Content-Type"] = "application/x-www-form-urlencoded";    }       query_variables = 0;    }    }       TRACE("Request: %O\n", url);    +  // NB: The argument data might be an instance of Stdio.Stream and +  // Protocols.HTTP.Session->async_do_method_url() does not declare that it +  // supports that. However, we know (and depend on) that +  // Protocols.HTTP.Session does not really care about the type. It just +  // passes the data-argument around. Eventually it ends up in an instance of +  // our class SessionQuery (see later in this file).    return ::async_do_method_url(method, url, query_variables, data,    extra_headers, callback_headers_ok,    callback_data_ok, callback_fail,    callback_arguments);    }          class Request    {    inherit parent::Request;
Roxen.git/server/etc/modules/HTTPClient.pmod:639: Inside #if constant (this::maxtime)
   TRACE("# Query has maxtime\n");    if (Session::maxtime) {    this::maxtime = Session::maxtime;    }    #endif       if (Session::timeout) {    this::timeout = Session::timeout;    }    } +  +  // Support for streaming query (data in form of Stdio.Stream). Implemented +  // here in wait of support in Protocols.HTTP. +  protected Stdio.Stream source_stream; +  protected int source_stream_length; +  +  this_program async_request (string server, +  int port, +  string query, +  void|mapping|string headers, +  void|string|Stdio.Stream data) +  { +  if (objectp(data)) { +  set_source_stream(data); +  data = UNDEFINED;    } -  +  if (source_stream) { +  if (data) +  error ("String data not allowed in streaming mode.\n"); +  if (stringp (headers)) +  error ("String headers not allowed in streaming mode.\n"); +  +  if (!headers) +  headers = ([]); +  headers["Content-Length"] = source_stream_length;    } -  +  +  ::async_request (server, port, query, headers, data); +  } +  +  protected void async_write() +  { +  ::async_write(); +  if (!con->query_write_callback() && source_stream) { +  // Headers sent, continue with data. +  Stdio.sendfile (0, source_stream, 0, source_stream_length, 0, con, +  lambda(int bytes_sent) { +  source_stream->close(); source_stream = 0; +  }); +  } +  } +  +  void set_source_stream (Stdio.Stream s) +  { +  source_stream = s; +  source_stream_length = s->stat()->size; +  } +  +  this_program sync_request(string server, +  int port, +  string query, +  void|mapping|string http_headers, +  void|string|Stdio.Stream data) +  { +  if (objectp(data)) { +  // Did not bother to write a loop in order to be able to read more than +  // 0x7fffffff bytes from the data argument, since sending so much data +  // using sync request is a pretty bad idea anyway... +  string tmp = data->read(0x7fffffff); +  data->close(); +  data = tmp; +  } +  return ::sync_request(server, port, query, http_headers, data); +  } +  // End of code "Support for streaming query". +  +  } + }