Branch: Tag:

2004-04-13

2004-04-13 18:59:03 by Martin Stjernholm <mast@lysator.liu.se>

Don't try to get the file twice to cope with PATH_INFO in
try_get_file. Added try_get_headers and restructured try_get_file a
bit to share code with it.

Rev: server/base_server/configuration.pike:1.552

5:   // @appears Configuration   //! A site's main configuration    - constant cvs_version = "$Id: configuration.pike,v 1.551 2004/03/16 10:52:40 grubba Exp $"; + constant cvs_version = "$Id: configuration.pike,v 1.552 2004/04/13 18:59:03 mast Exp $";   #include <module.h>   #include <module_constants.h>   #include <roxen.h>
2337:    return res;   }    - int|string try_get_file(string s, RequestID id, -  int|void status, int|void nocache, -  int|void not_internal, -  mapping|void result_mapping) - //! Convenience function used in quite a lot of modules. Tries to read - //! a file into memory, and then returns the resulting string. - //! - //! NOTE: A 'file' can be a cgi script, which will be executed, - //! resulting in a horrible delay. - //! - //! Unless the not_internal flag is set, this tries to get an external - //! or internal file. Here "internal" means a file that never should be - //! sent directly as a request response. E.g. an internal redirect to a - //! different file is still considered "external" since its contents is - //! sent directly to the client. Internal requests are recognized by - //! the id->misc->internal_get flag being non-zero. + static RequestID make_fake_id (string s, RequestID id)   { -  string res, q, cache_key; +     RequestID fake_id; -  mapping m; +     -  if(!objectp(id)) -  error("No ID passed to 'try_get_file'\n"); -  +     // id->misc->common is here for compatibility; it's better to use    // id->root_id->misc.    if ( !id->misc )
2371:    fake_id = id->clone_me();       fake_id->misc->common = id->misc->common; -  fake_id->misc->internal_get = !not_internal; +     fake_id->conf = this_object();       if (fake_id->scan_for_query)
2385:       fake_id->raw_url=s;    fake_id->not_query=s; -  fake_id->method = "GET"; +     -  if(!(m = get_file(fake_id,0,!not_internal))) { -  // Might be a PATH_INFO type URL. +  // FIXME: How much other info is there that really shouldn't be +  // propagated? It actually looks fairly bogus to clone the current +  // request. /mast    m_delete (fake_id->misc, "path_info"); -  +  +  return fake_id; + } +  + int|string try_get_file(string s, RequestID id, +  int|void stat_only, int|void nocache, +  int|void not_internal, +  mapping|void result_mapping) + //! Convenience function used in quite a lot of modules. Tries to read + //! a file into memory, and then returns the resulting string. + //! + //! NOTE: A 'file' can be a cgi script, which will be executed, + //! resulting in a horrible delay. + //! + //! Unless the not_internal flag is set, this tries to get an external + //! or internal file. Here "internal" means a file that never should be + //! sent directly as a request response. E.g. an internal redirect to a + //! different file is still considered "external" since its contents is + //! sent directly to the client. Internal requests are recognized by + //! the id->misc->internal_get flag being non-zero. + { +  string res; +  RequestID fake_id = make_fake_id (s, id); +  mapping m; +  +  fake_id->misc->internal_get = !not_internal; +  fake_id->method = "GET"; +     array a = open_file( s, "r", fake_id, !not_internal );    if(a && a[0]) {    m = a[1];
2399:    destruct (fake_id);    return 0;    } -  } +        CACHE( fake_id->misc->cacheable );    destruct (fake_id);    -  if (!mappingp(m) && !objectp(m)) { -  report_error("try_get_file(%O, %O, %O, %O): m = %O is not a mapping.\n", -  s, id, status, nocache, m); -  return 0; -  } -  +     if (result_mapping)    foreach(indices(m), string i)    result_mapping[i] = m[i];
2417:    // Allow 2* and 3* error codes, not only a few specific ones.    if (!(< 0,2,3 >)[m->error/100]) return 0;    -  if(status) return 1; +  if(stat_only) return 1;       if(m->data)    res = m->data;
2444:    return res;   }    + mapping(string:string) try_get_headers(string s, RequestID id, +  int|void not_internal) + //! Like @[try_get_file] but performs a HEAD request and only returns + //! the response headers. Note that the returned headers are as they + //! would be in a formatted response by the http protocol module, + //! which is completely different from a response mapping. + { +  RequestID fake_id = make_fake_id (s, id); +  mapping m; +  +  fake_id->misc->internal_get = !not_internal; +  fake_id->method = "HEAD"; +  +  array a = open_file( s, "r", fake_id, !not_internal ); +  if(a && a[1]) { +  if (a[0]) a[0]->close(); +  m = a[1]; +  } +  else { +  destruct (fake_id); +  return 0; +  } +  +  CACHE( fake_id->misc->cacheable ); +  +  if (!m->raw) +  m = fake_id->make_response_headers (m); +  +  else { +  Roxen.HeaderParser hp = Roxen.HeaderParser(); +  array res; +  +  if(m->data) +  res = hp->feed (m->data); +  +  if (!res && objectp(m->file)) +  { +  hp->feed (m->file->read()); +  if (m->file) { +  // Some wrappers may destruct themselves in read()... +  destruct(m->file); +  } +  } +  +  m = res && res[2]; +  } +  +  destruct (fake_id); +  return m; + } +    mapping(string:mixed) try_put_file(string path, string data, RequestID id)   {    TIMER_START(try_put_file);