Roxen.git / server / modules / tags / insert_cached_href.pike

version» Context lines:

Roxen.git/server/modules/tags/insert_cached_href.pike:1:   // This is a roxen module. Copyright © 2000 - 2004, Roxen IS.   //      #include <module.h>   inherit "module";      //<locale-token project="mod_insert_cached_href">LOCALE</locale-token>   #define LOCALE(X,Y) _DEF_LOCALE("mod_insert_cached_href",X,Y)    - constant cvs_version = "$Id: insert_cached_href.pike,v 1.20 2008/02/27 08:55:44 liin Exp $"; + constant cvs_version = "$Id: insert_cached_href.pike,v 1.21 2008/03/31 14:29:22 liin Exp $";      constant thread_safe = 1;   constant module_type = MODULE_TAG;   LocaleString module_name = LOCALE(1, "Tags: Insert cached href");   LocaleString module_doc = LOCALE(2, "This module contains the RXML tag \"insert "    "cached-href\". Useful when implementing e.g."    " RSS syndication.");      #if DEBUG_INSERT_CACHED_HREF   #define DWRITE(x) report_debug("INSERT_CACHED_HREF: " + x + "\n")
Roxen.git/server/modules/tags/insert_cached_href.pike:62:    "be updated. In seconds, minutes, hours or days."));       defvar("recursion_limit", 2, LOCALE(13, "Maximum recursion depth"),    TYPE_INT|VAR_MORE,    LOCALE(14,"Maximum number of nested <tt>&lt;insert cached-href&gt;</tt>'s "    "allowed. May be set to zero to disable the limit."));   }         void start(int occasion, Configuration conf) { -  DWRITE("start(), occasion: " + occasion); -  +     if (occasion == 0) {    href_database = HrefDatabase();   #ifdef THREADS    initiated = ({});    mutex = Thread.Mutex();   #endif    }      #ifdef THREADS    if (occasion == 2)
Roxen.git/server/modules/tags/insert_cached_href.pike:97:   #endif   }      mapping(string:function) query_action_buttons()   {    return ([LOCALE(15, "Clear database") : href_database->empty_db]);   }         void stop() { -  DWRITE("stop()"); -  +    #ifdef THREADS    bg_process && bg_process->stop();    bg_process = 0;    mutex_key = mutex->lock();       /* Removing registered callbacks for unfinished data fetches to avoid having the    back-end thread call them after the module has been destructed: */    foreach(initiated, HTTPClient client) {    client->con->request_ok = 0;    client->con->request_fail = 0;
Roxen.git/server/modules/tags/insert_cached_href.pike:195:    int counter;    string location = client->con->headers->location;       if (!location || !sizeof(location))    return decode_data(client->data(), client->con->headers);       DWRITE("Following redirect from " + (string)client->url +    " to " + location);       args["cached-href"] = location; -  HTTPClient new_client = HTTPClient("GET", args, header); +  HTTPClient new_client = HTTPClient(args, header);       new_client->orig_url = (string)client->url;    new_client->run();    counter++;       while (is_redirect(new_client->status) && counter < MAX_REDIRECTS) {    location = new_client->con->headers->location;       if (!location || !sizeof(location))    return decode_data(new_client->data(), new_client->con->headers);       DWRITE("Following redirect from " + (string)new_client->url +    " to " + location);       args["cached-href"] = location; -  new_client = HTTPClient("GET", args, header); +  new_client = HTTPClient(args, header);    new_client->orig_url = (string)client->url;    new_client->run();    counter++;    }       return decode_data(new_client->data(), new_client->con->headers);   }      /*    Takes action based on HTTP status codes in reply.
Roxen.git/server/modules/tags/insert_cached_href.pike:240:       if (redirects > MAX_REDIRECTS ||    !location ||    !sizeof(location))    return;       DWRITE("Following redirect from " + (string)client->url +    " to " + location);       args["cached-href"] = location; -  HTTPClient new_client = HTTPClient("GET", args, header); +  HTTPClient new_client = HTTPClient(args, header);       new_client->orig_url = client->orig_url;    new_client->redirects = redirects;    new_client->run();   }      public void|string fetch_url(mapping(string:mixed) to_fetch, void|mapping header) {    DWRITE(sprintf("fetch_url(): To fetch: %s, with timeout: %d", to_fetch["url"],    to_fetch["timeout"]));   
Roxen.git/server/modules/tags/insert_cached_href.pike:265:    object client;      #ifdef THREADS    mutex_key = mutex->lock();       if (!to_fetch["sync"] && already_initiated(to_fetch["url"])) {    mutex_key = 0;    return;    }    -  client = HTTPClient("GET", args, header); +  client = HTTPClient(args, header);    initiated += ({client});    mutex_key = 0;    client->orig_url = (string)client->url;    client->run();       if (to_fetch["sync"])    return get_result_sync(client, args, header);   #else    client = Protocols.HTTP.get_url(to_fetch["url"], 0);   
Roxen.git/server/modules/tags/insert_cached_href.pike:675:    }   }      #ifdef THREADS      /* This class represents the retrieval of data from an URL */   class HTTPClient {    int status, timeout, start_time, redirects;    object con;    Standards.URI url; -  string path, query, req_data,method, orig_url; +  string path, query, orig_url;    mapping request_headers;    Thread.Queue queue = Thread.Queue();    int(0..1) sync;    -  void do_method(string _method, -  string|Standards.URI _url, -  void|mapping query_variables, -  void|mapping _request_headers, -  void|Protocols.HTTP.Query _con, void|string _data) -  { -  if(!_con) { +  void create(mapping args, void|mapping _request_headers) { +  timeout = args["timeout"]; +  sync = args["sync"];    con = Protocols.HTTP.Query(); -  } -  else -  con = _con; +     -  method = _method; -  +     if(!_request_headers)    request_headers = ([]);    else    request_headers = _request_headers;    -  req_data = _data; -  -  if(stringp(_url)) { -  if (mixed err = catch (url=Standards.URI(_url))) +  if (mixed err = catch (url=Standards.URI(args["cached-href"])))    RXML.parse_error ("Invalid URL: %s\n", describe_error (err)); -  } -  else -  url = _url; +       #if constant(SSL.sslfile)    if(url->scheme!="http" && url->scheme!="https")    error("Protocols.HTTP 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("Protocols.HTTP can't handle %O or any other protocol than HTTP\n",
Roxen.git/server/modules/tags/insert_cached_href.pike:731:    if(!request_headers)    request_headers = ([]);    mapping default_headers = ([    "user-agent" : "Mozilla/4.0 compatible (Pike HTTP client)",    "host" : sprintf("%s:%d", url->host, url->port) ]);       if(url->user || url->passwd)    default_headers->authorization = "Basic "    + MIME.encode_base64(url->user + ":" +    (url->password || "")); -  request_headers = default_headers | request_headers; +     -  +  request_headers = default_headers | request_headers;    query=url->query; -  if(query_variables && sizeof(query_variables)) -  { -  if(query) -  query+="&"+Protocols.HTTP.http_encode_query(query_variables); -  else -  query=Protocols.HTTP.http_encode_query(query_variables); -  } -  +     path=url->path; -  +     if(path=="") path="/";    }       string data() {    if(!con->ok)    return "";       if(status > 0 && status < 300)    return con->data();   
Roxen.git/server/modules/tags/insert_cached_href.pike:846:    mutex_key = mutex->lock();    initiated -= ({this_object()});    mutex_key = 0;    }       void run() {    con->set_callbacks(req_ok, req_fail);    con->timeout = timeout;    start_time = time();    con->async_request(url->host,url->port, -  method+" "+path+(query?("?"+query):"")+" HTTP/1.0", -  request_headers, req_data); +  "GET "+path+(query?("?"+query):"")+" HTTP/1.0", +  request_headers);    status = con->status;       if (sync) {    DWRITE("Initiating synchronous fetch for " + (string)url);    queue->read();    DWRITE("Synchronous fetch for " + (string)url + " completed.");    }    } -  -  void create(string method, mapping args, mapping|void headers) { -  if(method == "POST") { -  mapping vars = ([ ]); - #if constant(roxen) -  foreach( (args["post-variables"] || "") / ",", string var) { -  array a = var / "="; -  if(sizeof(a) == 2) -  vars[String.trim_whites(a[0])] = RXML.user_get_var(String.trim_whites(a[1])); +    }   #endif -  do_method("POST", args["cached-href"], vars, headers); -  } -  else -  do_method("GET", args["cached-href"], 0, headers); +     -  timeout = args["timeout"]; -  sync = args["sync"]; -  } -  - } - #endif -  +    /*    Decodes data based on 1) HTTP headers or 2) fallbacks on    data content, meta http-equiv for html and BOM + encoding=''    for xml   */   string decode_data(string data, mapping headers) { -  +  if (data == "" || !headers) +  return data; +     function get_ct_cs =    lambda(string ct) {    string cs;    foreach((ct/";")[1..], string s) {    string s2 = String.trim_all_whites(s);    string _cs;    if(sscanf(s2, "charset=%s", _cs) == 1)    cs = String.trim_all_whites(_cs);    }    return cs;