|
|
| version 1.91, 2002/08/01 11:26:43 | version 1.96, 2002/08/20 14:20:36 |
|---|---|
| Line 5 | Line 5 |
| Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru) | Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru) |
| */ | */ |
| static const char* IDENT_FILE_C="$Id$"; | static const char* IDENT_FILE_C="$Date$"; |
| #include "pa_config_includes.h" | #include "pa_config_includes.h" |
| Line 119 static void _move(Request& r, const Stri | Line 119 static void _move(Request& r, const Stri |
| static void _load(Request& r, const String& method_name, MethodParams *params) { | static void _load(Request& r, const String& method_name, MethodParams *params) { |
| Pool& pool=r.pool(); | Pool& pool=r.pool(); |
| Value& vmode_name=params-> as_no_junction(0, "mode must not be code"); | Value& vmode_name=params-> as_no_junction(0, "mode must not be code"); |
| Value& vfile_name=params->as_no_junction(1, "file name must not be code"); | const String& lfile_name=r.absolute(params->as_no_junction(1, "file name must not be code").as_string()); |
| const String& lfile_name=vfile_name.as_string(); | |
| void *data; size_t size; | void *data; size_t size; |
| file_read(pool, r.absolute(lfile_name), data, size, | file_read(pool, lfile_name, data, size, |
| vmode_name.as_string()==TEXT_MODE_NAME); | vmode_name.as_string()==TEXT_MODE_NAME); |
| char *user_file_name=params->size()>2? | char *user_file_name=params->size()>2? |
| Line 153 static void _stat(Request& r, const Stri | Line 151 static void _stat(Request& r, const Stri |
| ff.put(*new(pool) String(pool, "adate"), new(pool) VDate(pool, atime)); | ff.put(*new(pool) String(pool, "adate"), new(pool) VDate(pool, atime)); |
| ff.put(*new(pool) String(pool, "mdate"), new(pool) VDate(pool, mtime)); | ff.put(*new(pool) String(pool, "mdate"), new(pool) VDate(pool, mtime)); |
| ff.put(*new(pool) String(pool, "cdate"), new(pool) VDate(pool, ctime)); | ff.put(*new(pool) String(pool, "cdate"), new(pool) VDate(pool, ctime)); |
| ff.put(*content_type_name, new(pool) VString(r.mime_type_of(lfile_name.cstr(String::UL_FILE_SPEC)))); | |
| } | } |
| static bool is_safe_env_key(const char *key) { | static bool is_safe_env_key(const char *key) { |
| Line 186 static void append_env_pair(const Hash:: | Line 185 static void append_env_pair(const Hash:: |
| pi.hash->put(key, &svalue); | pi.hash->put(key, &svalue); |
| } | } |
| } | } |
| static void pass_cgi_header_attribute(Array::Item *value, void *info) { | #ifndef DOXYGEN |
| struct Pass_cgi_header_attribute_info { | |
| Hash *hash; | |
| Value *content_type; | |
| }; | |
| #endif | |
| static void pass_cgi_header_attribute(Array::Item *value, void *ainfo) { | |
| String& string=*static_cast<String *>(value); | String& string=*static_cast<String *>(value); |
| Hash& hash=*static_cast<Hash *>(info); | Pool& pool=string.pool(); |
| Pass_cgi_header_attribute_info& info=*static_cast<Pass_cgi_header_attribute_info *>(ainfo); | |
| int colon_pos=string.pos(":", 1); | int colon_pos=string.pos(":", 1); |
| if(colon_pos>0) | if(colon_pos>0) { |
| hash.put(string.mid(0, colon_pos), | const String& key=string.mid(0, colon_pos).change_case(pool, String::CC_UPPER); |
| new(string.pool()) VString(string.mid(colon_pos+1, string.size()))); | Value *value=new(pool) VString(string.mid(colon_pos+1, string.size())); |
| info.hash->put(key, value); | |
| if(key=="CONTENT-TYPE") | |
| info.content_type=value; | |
| } | |
| } | } |
| /// @todo fix `` in perl - they produced flipping consoles and no output to perl | /// @todo fix `` in perl - they produced flipping consoles and no output to perl |
| static void _exec_cgi(Request& r, const String& method_name, MethodParams *params, | static void _exec_cgi(Request& r, const String& method_name, MethodParams *params, |
| Line 270 static void _exec_cgi(Request& r, const | Line 280 static void _exec_cgi(Request& r, const |
| VFile& self=*static_cast<VFile *>(r.self); | VFile& self=*static_cast<VFile *>(r.self); |
| const String *body=&out; // ^file:exec | const String *body=&out; // ^file:exec |
| Value *content_type=0; | |
| const char *eol_marker="\r\n"; size_t eol_marker_size=2; | |
| const String *header=0; | |
| if(cgi) { // ^file:cgi | if(cgi) { // ^file:cgi |
| // construct with 'out' body and header | // construct with 'out' body and header |
| int delim_size; | int delim_size; |
| const char *eol_marker="\r\n"; size_t eol_marker_size=2; | |
| int pos=out.pos("\r\n\r\n", delim_size=4); | int pos=out.pos("\r\n\r\n", delim_size=4); |
| if(pos<0) { | if(pos<0) { |
| eol_marker="\n"; eol_marker_size=1; | eol_marker="\n"; eol_marker_size=1; |
| Line 290 static void _exec_cgi(Request& r, const | Line 302 static void _exec_cgi(Request& r, const |
| (uint)err.size(), err.cstr()); | (uint)err.size(), err.cstr()); |
| } | } |
| const String& header=out.mid(0, pos); | header=&out.mid(0, pos); |
| body=&out.mid(pos+delim_size, out.size()); | body=&out.mid(pos+delim_size, out.size()); |
| // header to $fields | |
| { | |
| Array rows(pool); | |
| header.split(rows, 0, eol_marker, eol_marker_size, String::UL_CLEAN); | |
| rows.for_each(pass_cgi_header_attribute, &self.fields()); | |
| } | |
| } | } |
| // body | // body |
| self.set(false/*not tainted*/, body->cstr(), body->size()); | self.set(false/*not tainted*/, body->cstr(), body->size()); |
| // $fields << header | |
| if(header) { | |
| Array rows(pool); | |
| header->split(rows, 0, eol_marker, eol_marker_size); | |
| Pass_cgi_header_attribute_info info={&self.fields()}; | |
| rows.for_each(pass_cgi_header_attribute, &info); | |
| if(info.content_type) | |
| self.fields().put(*content_type_name, info.content_type); | |
| } | |
| // $status | // $status |
| self.fields().put( | self.fields().put( |
| *new(pool) String(pool, "status"), | *new(pool) String(pool, "status"), |
| Line 444 static void _find(Request& r, const Stri | Line 459 static void _find(Request& r, const Stri |
| // easy way | // easy way |
| if(file_readable(r.absolute(*file_spec))) { | if(file_readable(r.absolute(*file_spec))) { |
| r.write_no_lang(*file_spec); | r.write_assign_lang(*file_spec); |
| return; | return; |
| } | } |
| Line 459 static void _find(Request& r, const Stri | Line 474 static void _find(Request& r, const Stri |
| local_test_name<<*(dirname=&dirname->mid(0, after_monkey_slash)); | local_test_name<<*(dirname=&dirname->mid(0, after_monkey_slash)); |
| local_test_name<<basename; | local_test_name<<basename; |
| if(file_readable(r.absolute(local_test_name))) { | if(file_readable(r.absolute(local_test_name))) { |
| r.write_no_lang(*new(pool) String(local_test_name)); | r.write_assign_lang(*new(pool) String(local_test_name)); |
| return; | return; |
| } | } |
| } | } |