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: