Annotation of parser3/src/main/pa_xml_io.C, revision 1.12

1.1       paf         1: /** @file
                      2:        Parser: plugins to xml library, controlling i/o; implementation
                      3: 
                      4:        Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com)
                      5:        Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
                      6: */
                      7: 
                      8: #include "pa_xml_io.h"
                      9: 
                     10: #ifdef XML
                     11: 
1.12    ! paf        12: static const char * const IDENT="$Date: 2003/11/28 10:42:47 $";
1.1       paf        13: 
                     14: #include "libxslt/extensions.h"
                     15: 
                     16: #include "pa_globals.h"
                     17: #include "pa_request.h"
                     18: 
1.8       paf        19: #ifndef DOXYGEN
                     20: struct MemoryStream {
                     21:        const char* m_buf;
                     22:        size_t m_size;
                     23:        size_t m_position;
                     24: 
                     25:        int read(char* a_buffer, size_t a_size) {
                     26:                size_t left=m_size-m_position;
                     27:                if(!left)
                     28:                        return 0;
                     29: 
                     30:                size_t to_read=min(a_size, left);
                     31:                memcpy(a_buffer, m_buf, to_read);
                     32:                m_position+=to_read;
                     33:                return to_read;
                     34:        }
                     35: 
                     36: };
                     37: #endif
                     38: 
1.9       paf        39: 
                     40: #ifdef PA_SAFE_MODE
                     41: static int
                     42: xmlFileMatchSafeMode(const char* file_spec_cstr) {
1.11      paf        43:        if(strstr(file_spec_cstr, "://")) {
1.9       paf        44:                String* file_spec=new String(file_spec_cstr, true);
                     45:                struct stat finfo;
                     46:                if(stat(file_spec_cstr, &finfo)!=0)
                     47:                        throw Exception("file.missing", 
                     48:                                file_spec, 
                     49:                                "stat failed: %s (%d)", 
                     50:                                        strerror(errno), errno);
                     51: 
                     52:                check_safe_mode(finfo, file_spec, file_spec_cstr);
                     53:        }
                     54:        return 0;
                     55: }
                     56: #endif
                     57: 
                     58: 
1.1       paf        59: /**
                     60:  * xmlFileMatchWithLocalhostEqDocumentRoot:
                     61:  * filename:  the URI for matching
                     62:  *
                     63:  * check if the URI matches an HTTP one
                     64:  *
                     65:  * Returns 1 if matches, 0 otherwise
                     66:  */
                     67: static int
                     68: xmlFileMatchLocalhost(const char* filename) {
                     69:        if (!strncmp(filename, "http://localhost", 16))
                     70:                return(1);
                     71:        return(0);
                     72: }
                     73: 
                     74: 
                     75: /**
                     76:  * xmlFileOpenHttpLocalhost :
                     77:  * filename:  the URI for matching
                     78:  *
                     79:  * http://localhost/abc -> $ENV{DOCUMENT_ROOT}/abc | ./abc
                     80:  *
                     81:  * input from FILE *, supports compressed input
                     82:  * if filename is " " then the standard input is used
                     83:  *
                     84:  * Returns an I/O context or NULL in case of error
                     85:  */
                     86: static void *
                     87: xmlFileOpenLocalhost (const char* filename) {
1.8       paf        88:        Request& r=pa_thread_request();
                     89:        const char* document_root=r.request_info.document_root;
1.1       paf        90:        if(!document_root)
                     91:                document_root=".";
                     92: 
                     93:        char path[MAX_STRING];  
                     94:        path[0]=0;
                     95:        strcat(path, document_root);
                     96:        strcat(path, &filename[16]);
                     97: 
1.12    ! paf        98:        if(char *buf=file_read_text(r.charsets, *new String(path), false)) {
        !            99:                MemoryStream *stream=new(UseGC) MemoryStream;
        !           100:                stream->m_buf=buf
        !           101:                stream->m_size=strlen(buf);
        !           102:                return (void *)stream;
        !           103:        } else
        !           104:                return 0;
1.1       paf       105: }
                    106: 
1.2       paf       107: static int
                    108: xmlFileMatchMethod(const char* filename) {
1.3       paf       109:        if (!strncmp(filename, "parser://", 9 /*strlen("parser://"), and check xmlFileOpenMethod*/))
1.2       paf       110:                return(1);
                    111:        return(0);
                    112: }
                    113: 
1.5       paf       114: /// parser://method/param/here -> ^MAIN:method[/params/here]
1.2       paf       115: static void *
                    116: xmlFileOpenMethod (const char* afilename) {
                    117:        Request& r=pa_thread_request();
                    118: 
1.3       paf       119:        char* s=pa_strdup(afilename+9 /*strlen("parser://")*/);
1.2       paf       120:        const char* method_cstr=lsplit(&s, '/');
                    121:        const String* method=new String(method_cstr);
1.4       paf       122:        String::Body param_body("/");  
                    123:        if(s)
                    124:                param_body.append_know_length(s, strlen(s));
                    125: 
                    126:        VString* vparam=new VString(*new String(param_body, String::L_TAINTED));
1.2       paf       127:        {
                    128:                Temp_lang temp_lang(r, String::L_XML); // default language: XML
1.3       paf       129:                Request::Execute_nonvirtual_method_result body=
1.4       paf       130:                        r.execute_nonvirtual_method(r.main_class, *method, vparam, true);
1.3       paf       131:                if(body.string) {
1.2       paf       132:                        MemoryStream *stream=new(UseGC) MemoryStream;
1.3       paf       133:                        stream->m_buf=body.string->cstr(String::L_UNSPECIFIED);
1.2       paf       134:                        stream->m_size=strlen(stream->m_buf);
                    135:                        return (void*)stream;
                    136:                }
                    137:        }
                    138: 
                    139:        throw Exception(0,
1.3       paf       140:                new String(afilename),
                    141:                "'%s' method not found in %s class", 
                    142:                        method_cstr, MAIN_CLASS_NAME);
1.2       paf       143: }
                    144: 
                    145: static int
                    146: pa_xmlFileReadMethod (void * context, //< MemoryStream actually
                    147:                                          char * buffer, int len) 
                    148: {
                    149:        MemoryStream& stream=*static_cast<MemoryStream*>(context);
                    150: 
                    151:        return stream.read(buffer, len);
                    152: }
                    153: 
                    154: static int
                    155: pa_xmlFileCloseMethod (void * /*context*/) {
                    156:        return 0;
                    157: }
                    158: 
                    159: 
1.1       paf       160: 
                    161: void pa_xml_io_init() {
1.9       paf       162: #ifdef PA_SAFE_MODE
                    163:        // safe mode checker, always fail match, but checks non-"://" there
                    164:        xmlRegisterInputCallbacks(
                    165:                xmlFileMatchSafeMode, 0,
                    166:                0, 0);
                    167: #endif
1.1       paf       168:        // http://localhost/abc -> $ENV{DOCUMENT_ROOT}/abc | ./abc
                    169:        xmlRegisterInputCallbacks(
                    170:                xmlFileMatchLocalhost, xmlFileOpenLocalhost,
1.8       paf       171:                pa_xmlFileReadMethod, pa_xmlFileCloseMethod);
1.2       paf       172: 
1.5       paf       173:        // parser://method/param/here -> ^MAIN:method[/params/here]
1.2       paf       174:        xmlRegisterInputCallbacks(
                    175:                xmlFileMatchMethod, xmlFileOpenMethod,
                    176:                pa_xmlFileReadMethod, pa_xmlFileCloseMethod);
1.1       paf       177: }
                    178: 
                    179: #endif

E-mail: