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

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.15    ! paf        12: static const char * const IDENT="$Date: 2003/12/01 14:20:50 $";
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);
1.14      paf        31:                memcpy(a_buffer, m_buf+m_position, to_read);
1.8       paf        32:                m_position+=to_read;
                     33:                return to_read;
                     34:        }
                     35: 
                     36: };
                     37: #endif
                     38: 
1.15    ! paf        39: static void *
        !            40: xmlFileOpen_ReadIntoStream (const char* filename, bool adjust_path_to_root_from_document_root=false) {
        !            41:        Request& r=pa_thread_request();
        !            42:        char adjust_buf[MAX_STRING];    
        !            43:        if(adjust_path_to_root_from_document_root) {
        !            44:                const char* document_root=r.request_info.document_root;
        !            45:                if(!document_root)
        !            46:                        document_root=".";
        !            47: 
        !            48:                adjust_buf[0]=0;
        !            49:                strcat(adjust_buf, document_root);
        !            50:                strcat(adjust_buf, &filename[16]);
        !            51:                filename=adjust_buf;
        !            52:        } else
        !            53:                if(strstr(filename, "file://"))
        !            54:                        filename+=7/*strlen("file://")*/; 
        !            55:                else if(strstr(filename, "://")) 
        !            56:                        return 0; // plug out [do not handle other prefixes]
        !            57: 
        !            58:        const char *buf;
        !            59:        try {
        !            60:                buf=file_read_text(r.charsets, *new String(filename));
        !            61:        } catch(const Exception& e) {
        !            62:                buf=e.comment();
        !            63:        } catch(...) {
        !            64:                buf="xmlFileOpenLocalhost: unknown error";
        !            65:        }
        !            66:        MemoryStream* stream=new(UseGC) MemoryStream;
        !            67:        stream->m_buf=buf;
        !            68:        stream->m_size=strlen(buf);
        !            69:        return (void *)stream;
        !            70: }
1.9       paf        71: 
                     72: #ifdef PA_SAFE_MODE
                     73: static int
                     74: xmlFileMatchSafeMode(const char* file_spec_cstr) {
1.15    ! paf        75:        return 1; // always intercept, causing xmlFileOpenSafeMode to be called
        !            76: }
        !            77: static void *
        !            78: xmlFileOpenSafeMode(const char* filename) {
        !            79:        return xmlFileOpen_ReadIntoStream(filename); // handles localfile case, else returns 0
1.9       paf        80: }
                     81: #endif
                     82: 
                     83: 
1.1       paf        84: /**
                     85:  * xmlFileMatchWithLocalhostEqDocumentRoot:
                     86:  * filename:  the URI for matching
                     87:  *
                     88:  * check if the URI matches an HTTP one
                     89:  *
                     90:  * Returns 1 if matches, 0 otherwise
                     91:  */
                     92: static int
                     93: xmlFileMatchLocalhost(const char* filename) {
                     94:        if (!strncmp(filename, "http://localhost", 16))
                     95:                return(1);
                     96:        return(0);
                     97: }
                     98: 
                     99: /**
1.15    ! paf       100:  * xmlFileOpenLocalhost:
1.1       paf       101:  * filename:  the URI for matching
                    102:  *
                    103:  * http://localhost/abc -> $ENV{DOCUMENT_ROOT}/abc | ./abc
                    104:  *
                    105:  * Returns an I/O context or NULL in case of error
                    106:  */
                    107: static void *
                    108: xmlFileOpenLocalhost (const char* filename) {
1.15    ! paf       109:        return xmlFileOpen_ReadIntoStream(filename, true/*adjust path to root from document_root*/);
1.1       paf       110: }
                    111: 
1.2       paf       112: static int
                    113: xmlFileMatchMethod(const char* filename) {
1.3       paf       114:        if (!strncmp(filename, "parser://", 9 /*strlen("parser://"), and check xmlFileOpenMethod*/))
1.2       paf       115:                return(1);
                    116:        return(0);
                    117: }
                    118: 
1.5       paf       119: /// parser://method/param/here -> ^MAIN:method[/params/here]
1.2       paf       120: static void *
                    121: xmlFileOpenMethod (const char* afilename) {
1.15    ! paf       122:        const char* buf;
        !           123:        try {
        !           124:                Request& r=pa_thread_request();
        !           125: 
        !           126:                char* s=pa_strdup(afilename+9 /*strlen("parser://")*/);
        !           127:                const char* method_cstr=lsplit(&s, '/');
        !           128:                const String* method=new String(method_cstr);
        !           129:                String::Body param_body("/");  
        !           130:                if(s)
        !           131:                        param_body.append_know_length(s, strlen(s));
        !           132: 
        !           133:                VString* vparam=new VString(*new String(param_body, String::L_TAINTED));
        !           134:                {
        !           135:                        Temp_lang temp_lang(r, String::L_XML); // default language: XML
        !           136:                        Request::Execute_nonvirtual_method_result body=
        !           137:                                r.execute_nonvirtual_method(r.main_class, *method, vparam, true);
        !           138:                        if(body.string) {
        !           139:                                buf=body.string->cstr(String::L_UNSPECIFIED);
        !           140:                        } else
        !           141:                                throw Exception(0,
        !           142:                                        new String(afilename),
        !           143:                                        "'%s' method not found in %s class", 
        !           144:                                                        method_cstr, MAIN_CLASS_NAME);
1.2       paf       145:                }
1.15    ! paf       146:        } catch(const Exception& e) {
        !           147:                buf=e.comment();
        !           148:        } catch(...) {
        !           149:                buf="xmlFileOpenLocalhost: unknown error";
1.2       paf       150:        }
1.15    ! paf       151:        MemoryStream* stream=new(UseGC) MemoryStream;
        !           152:        stream->m_buf=buf;
        !           153:        stream->m_size=strlen(buf);
        !           154:        return (void *)stream;
1.2       paf       155: }
                    156: 
1.15    ! paf       157: /**
        !           158:  * pa_xmlFileReadMethod:
        !           159:  * @context:  the I/O context
        !           160:  * @buffer:  where to drop data
        !           161:  * @len:  number of bytes to write
        !           162:  *
        !           163:  * Read @len bytes to @buffer from the I/O channel.
        !           164:  *
        !           165:  * Returns the number of bytes written
        !           166:  */
1.2       paf       167: static int
                    168: pa_xmlFileReadMethod (void * context, //< MemoryStream actually
                    169:                                          char * buffer, int len) 
                    170: {
                    171:        MemoryStream& stream=*static_cast<MemoryStream*>(context);
                    172: 
                    173:        return stream.read(buffer, len);
                    174: }
                    175: 
                    176: static int
                    177: pa_xmlFileCloseMethod (void * /*context*/) {
                    178:        return 0;
                    179: }
                    180: 
                    181: 
1.1       paf       182: 
                    183: void pa_xml_io_init() {
1.9       paf       184: #ifdef PA_SAFE_MODE
                    185:        // safe mode checker, always fail match, but checks non-"://" there
                    186:        xmlRegisterInputCallbacks(
1.15    ! paf       187:                xmlFileMatchSafeMode, xmlFileOpenSafeMode,
        !           188:                pa_xmlFileReadMethod, pa_xmlFileCloseMethod);
1.9       paf       189: #endif
1.1       paf       190:        // http://localhost/abc -> $ENV{DOCUMENT_ROOT}/abc | ./abc
                    191:        xmlRegisterInputCallbacks(
                    192:                xmlFileMatchLocalhost, xmlFileOpenLocalhost,
1.8       paf       193:                pa_xmlFileReadMethod, pa_xmlFileCloseMethod);
1.2       paf       194: 
1.5       paf       195:        // parser://method/param/here -> ^MAIN:method[/params/here]
1.2       paf       196:        xmlRegisterInputCallbacks(
                    197:                xmlFileMatchMethod, xmlFileOpenMethod,
                    198:                pa_xmlFileReadMethod, pa_xmlFileCloseMethod);
1.1       paf       199: }
                    200: 
                    201: #endif

E-mail: