Annotation of parser3/src/main/pa_xml_io.C, revision 1.9
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.9 ! paf 12: static const char * const IDENT="$Date: 2003/11/28 10:34:39 $";
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) {
! 43: if(strstr(filename, "://")) {
! 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();
1.1 paf 89: FILE *fd;
1.8 paf 90: const char* document_root=r.request_info.document_root;
1.1 paf 91: if(!document_root)
92: document_root=".";
93:
94: char path[MAX_STRING];
95: path[0]=0;
96: strcat(path, document_root);
97: strcat(path, &filename[16]);
98:
1.8 paf 99: MemoryStream *stream=new(UseGC) MemoryStream;
100: stream->m_buf=file_read_text(r.charsets, *new String(filename), true);
101: stream->m_size=strlen(stream->m_buf);
1.1 paf 102:
1.8 paf 103: return (void *)stream;
1.1 paf 104: }
105:
1.2 paf 106: static int
107: xmlFileMatchMethod(const char* filename) {
1.3 paf 108: if (!strncmp(filename, "parser://", 9 /*strlen("parser://"), and check xmlFileOpenMethod*/))
1.2 paf 109: return(1);
110: return(0);
111: }
112:
1.5 paf 113: /// parser://method/param/here -> ^MAIN:method[/params/here]
1.2 paf 114: static void *
115: xmlFileOpenMethod (const char* afilename) {
116: Request& r=pa_thread_request();
117:
1.3 paf 118: char* s=pa_strdup(afilename+9 /*strlen("parser://")*/);
1.2 paf 119: const char* method_cstr=lsplit(&s, '/');
120: const String* method=new String(method_cstr);
1.4 paf 121: String::Body param_body("/");
122: if(s)
123: param_body.append_know_length(s, strlen(s));
124:
125: VString* vparam=new VString(*new String(param_body, String::L_TAINTED));
1.2 paf 126: {
127: Temp_lang temp_lang(r, String::L_XML); // default language: XML
1.3 paf 128: Request::Execute_nonvirtual_method_result body=
1.4 paf 129: r.execute_nonvirtual_method(r.main_class, *method, vparam, true);
1.3 paf 130: if(body.string) {
1.2 paf 131: MemoryStream *stream=new(UseGC) MemoryStream;
1.3 paf 132: stream->m_buf=body.string->cstr(String::L_UNSPECIFIED);
1.2 paf 133: stream->m_size=strlen(stream->m_buf);
134: return (void*)stream;
135: }
136: }
137:
138: throw Exception(0,
1.3 paf 139: new String(afilename),
140: "'%s' method not found in %s class",
141: method_cstr, MAIN_CLASS_NAME);
1.2 paf 142: }
143:
144: static int
145: pa_xmlFileReadMethod (void * context, //< MemoryStream actually
146: char * buffer, int len)
147: {
148: MemoryStream& stream=*static_cast<MemoryStream*>(context);
149:
150: return stream.read(buffer, len);
151: }
152:
153: static int
154: pa_xmlFileCloseMethod (void * /*context*/) {
155: return 0;
156: }
157:
158:
1.1 paf 159:
160: void pa_xml_io_init() {
1.9 ! paf 161: #ifdef PA_SAFE_MODE
! 162: // safe mode checker, always fail match, but checks non-"://" there
! 163: xmlRegisterInputCallbacks(
! 164: xmlFileMatchSafeMode, 0,
! 165: 0, 0);
! 166: #endif
1.1 paf 167: // http://localhost/abc -> $ENV{DOCUMENT_ROOT}/abc | ./abc
168: xmlRegisterInputCallbacks(
169: xmlFileMatchLocalhost, xmlFileOpenLocalhost,
1.8 paf 170: pa_xmlFileReadMethod, pa_xmlFileCloseMethod);
1.2 paf 171:
1.5 paf 172: // parser://method/param/here -> ^MAIN:method[/params/here]
1.2 paf 173: xmlRegisterInputCallbacks(
174: xmlFileMatchMethod, xmlFileOpenMethod,
175: pa_xmlFileReadMethod, pa_xmlFileCloseMethod);
1.1 paf 176: }
177:
178: #endif
E-mail: