Annotation of parser3/src/types/pa_vrequest.C, revision 1.77
1.2 paf 1: /** @file
1.5 paf 2: Parser: @b request class.
1.2 paf 3:
1.75 moko 4: Copyright (c) 2001-2026 Art. Lebedev Studio (https://www.artlebedev.com)
1.70 moko 5: Authors: Konstantin Morshnev <moko@design.ru>, Alexandr Petrosian <paf@design.ru>
1.18 paf 6: */
1.2 paf 7:
1.1 paf 8: #include "pa_vrequest.h"
1.28 paf 9: #include "pa_request_info.h"
10: #include "pa_request_charsets.h"
1.13 paf 11: #include "pa_charsets.h"
1.28 paf 12: #include "pa_vstring.h"
1.38 misha 13: #include "pa_vhash.h"
1.40 misha 14: #include "pa_vform.h"
15: #include "pa_vvoid.h"
1.50 misha 16: #include "pa_vfile.h"
1.1 paf 17:
1.77 ! moko 18: volatile const char * IDENT_PA_VREQUEST_C="$Id: pa_vrequest.C,v 1.76 2026/09/30 16:44:20 moko Exp $" IDENT_PA_VREQUEST_H;
1.52 moko 19:
1.30 paf 20: // defines
21:
22: #define DOCUMENT_ROOT_NAME "document-root"
1.58 moko 23: #define REQUEST_HEADERS_ELEMENT_NAME "headers"
1.30 paf 24:
1.64 moko 25: VRequest::VRequest(Request_info& ainfo, Request_charsets& acharsets, VForm& aform, SAPI_Info& asapi_info):
26: finfo(ainfo),
27: fsapi_info(asapi_info),
28: fcharsets(acharsets),
29: fform(aform)
30: {
1.46 misha 31: if(ainfo.argv)
1.66 moko 32: for(size_t i=0; ainfo.argv[i]; i++) {
1.38 misha 33: fargv.put_dont_replace(
1.66 moko 34: String(i, "%d"),
1.74 moko 35: new VString(pa_strdup(ainfo.argv[i]))
1.38 misha 36: );
37: }
38: }
1.30 paf 39:
1.49 misha 40: Value* VRequest::get_element(const String& aname) {
1.77 ! moko 41: MAYBE_GET_SPECIAL(VStateless_class::get_element(aname));
1.58 moko 42:
1.40 misha 43: // $request:charset
1.24 paf 44: if(aname==CHARSET_NAME)
1.74 moko 45: return new VString(fcharsets.source().NAME());
1.39 misha 46:
1.58 moko 47: // $request:body-charset
48: if(aname==REQUEST_BODY_CHARSET_NAME || aname==POST_CHARSET_NAME /*backward*/){
49: if(Charset* body_charset=fform.get_body_charset())
1.74 moko 50: return new VString(body_charset->NAME());
1.40 misha 51: else
1.42 misha 52: return VVoid::get();
1.40 misha 53: }
1.50 misha 54:
1.58 moko 55: // $resuest:body-file
56: if(aname==REQUEST_BODY_BODY_NAME || aname==POST_BODY_NAME /*backward*/){
1.50 misha 57: VFile& result=*new VFile;
1.55 moko 58: result.set_binary(true/*tainted*/, (finfo.post_data)?finfo.post_data:"" /*to distinguish from stat-ed file*/, finfo.post_size);
1.50 misha 59: return &result;
60: }
61:
1.40 misha 62: // $request:argv
1.39 misha 63: if(aname==REQUEST_ARGV_ELEMENT_NAME)
1.38 misha 64: return new VHash(fargv);
1.30 paf 65:
1.58 moko 66: //$request:headers
67: if(aname==REQUEST_HEADERS_ELEMENT_NAME){
68: if(!ffields.count())
69: fill();
70: return new VHash(ffields);
71: }
72:
73: // $request:query $request:uri $request:document-root $request:body $request:method
1.30 paf 74: const char* buf;
75: if(aname=="query")
76: buf=finfo.query_string;
77: else if(aname=="uri")
78: buf=finfo.uri;
1.72 moko 79: else if(aname=="path")
80: buf=path_from_uri(pa_strdup(finfo.uri));
1.30 paf 81: else if(aname==DOCUMENT_ROOT_NAME)
82: buf=finfo.document_root;
1.43 misha 83: else if(aname=="body")
1.30 paf 84: buf=finfo.post_data;
1.58 moko 85: else if(aname=="method")
86: buf=finfo.method;
1.43 misha 87: else
1.30 paf 88: return bark("%s field not found", &aname);
1.12 paf 89:
1.74 moko 90: return new VString(buf);
1.1 paf 91: }
92:
1.56 moko 93: const VJunction* VRequest::put_element(const String& aname, Value* avalue) {
1.30 paf 94: // $charset
1.20 paf 95: if(aname==CHARSET_NAME) {
1.63 moko 96: fcharsets.set_source(pa_charsets.get(avalue->as_string()));
1.67 moko 97: return 0;
1.30 paf 98: }
99:
100: // $document-root
101: if(aname==DOCUMENT_ROOT_NAME) {
1.76 moko 102: finfo.set_document_root(avalue->as_string().taint_cstr(String::L_FILE_SPEC));
1.67 moko 103: return 0;
1.30 paf 104: }
105:
1.56 moko 106: return Value::put_element(aname, avalue);
1.12 paf 107: }
1.58 moko 108:
109: void VRequest::fill(){
110: for(SAPI::Env::Iterator i(fsapi_info); i; i.next() ){
111: char* key=i.key();
112:
113: if(pa_strncasecmp(key, "HTTP_")==0) {
114: for(char* c=key+5; *c; c++)
115: *c=(char)toupper((unsigned char)*c);
116:
117: ffields.put(
118: key+5 /*skip "HTTP_" */,
1.74 moko 119: new VString(i.value())
1.58 moko 120: );
121: }
122: }
123: }
1.72 moko 124:
125: const char* VRequest::path_from_uri(char* uri){
126: const char *result=uri;
127: lsplit(uri,'?');
128: if(result && *result)
129: result=unescape_chars(result, strlen(result), &pa_UTF8_charset, false /* uri */);
130: if(result && *result)
131: result=Charset::transcode(result, pa_UTF8_charset, fcharsets.source()).cstr();
132: if(result && *result)
133: return result;
1.73 moko 134: return ""; // to match an empty URI in console mode
1.72 moko 135: }
E-mail: