Annotation of embedaddon/php/sapi/pi3web/pi3web_sapi.c, revision 1.1.1.1
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
5: | Copyright (c) 1997-2012 The PHP Group |
6: +----------------------------------------------------------------------+
7: | This source file is subject to version 3.01 of the PHP license, |
8: | that is bundled with this package in the file LICENSE, and is |
9: | available through the world-wide-web at the following url: |
10: | http://www.php.net/license/3_01.txt |
11: | If you did not receive a copy of the PHP license and are unable to |
12: | obtain it through the world-wide-web, please send a note to |
13: | license@php.net so we can mail you a copy immediately. |
14: +----------------------------------------------------------------------+
15: | Pi3Web version 2.0 |
16: +----------------------------------------------------------------------+
17: | This file is committed by the Pi3 development group. |
18: | (pi3web.sourceforge.net) |
19: | |
20: | Author: Holger Zimmermann (zimpel@users.sourceforge.net) |
21: +----------------------------------------------------------------------+
22: */
23:
24: /* $Id: pi3web_sapi.c 321634 2012-01-01 13:15:04Z felipe $ */
25:
26: #define ZEND_INCLUDE_FULL_WINDOWS_HEADERS
27:
28: #include "php.h"
29: #include "php_main.h"
30: #include "php_variables.h"
31: #include "SAPI.h"
32: #include "php_globals.h"
33: #include "ext/standard/info.h"
34: #include "zend_highlight.h"
35: #include "zend_indent.h"
36: #include "zend_alloc.h"
37: #include "ext/standard/basic_functions.h"
38: #include "TSRM/TSRM.h"
39: #include "PiAPI.h"
40: #include "Pi3API.h"
41:
42: #include "pi3web_sapi.h"
43:
44: #define PI3WEB_SERVER_VAR_BUF_SIZE 1024
45:
46: int IWasLoaded=0;
47:
48:
49: static void php_info_pi3web(ZEND_MODULE_INFO_FUNC_ARGS)
50: {
51: char variable_buf[PI3WEB_SERVER_VAR_BUF_SIZE];
52: DWORD variable_len;
53: LPCONTROL_BLOCK lpCB = (LPCONTROL_BLOCK) SG(server_context);
54: PIDB *pDB = (PIDB *)lpCB->GetVariableNames(lpCB->ConnID);
55: PIDBIterator *pIter = PIDB_getIterator( pDB, PIDBTYPE_STRING, 0, 0 );
56:
57: PUTS("<table border=0 cellpadding=3 cellspacing=1 width=600 align=center>\n");
58: PUTS("<tr><th colspan=2 bgcolor=\"" PHP_HEADER_COLOR "\">Pi3Web Server Information</th></tr>\n");
59: php_info_print_table_header(2, "Information Field", "Value");
60: php_info_print_table_row(2, "Pi3Web SAPI module version", "$Id: pi3web_sapi.c 321634 2012-01-01 13:15:04Z felipe $");
61: php_info_print_table_row(2, "Server Name Stamp", HTTPCore_getServerStamp());
62: snprintf(variable_buf, 511, "%d", HTTPCore_debugEnabled());
63: php_info_print_table_row(2, "Debug Enabled", variable_buf);
64: PIPlatform_getCurrentDirectory( variable_buf, PI3WEB_SERVER_VAR_BUF_SIZE);
65: php_info_print_table_row(2, "Current Path", variable_buf);
66: if (lpCB->GetServerVariable(lpCB->ConnID, "SERVER_NAME", variable_buf, &variable_len)
67: && variable_buf[0]) {
68: php_info_print_table_row(2, "Main Virtual Hostname", variable_buf);
69: };
70: snprintf(variable_buf, 511, "%d", PIPlatform_getProcessId());
71: php_info_print_table_row(2, "Server PID", variable_buf);
72: php_info_print_table_row(2, "Server Platform", PIPlatform_getDescription());
73:
74: PUTS("</table><br />");
75:
76: PUTS("<table border=0 cellpadding=3 cellspacing=1 width=600 align=center>\n");
77: PUTS("<tr><th colspan=2 bgcolor=\"" PHP_HEADER_COLOR "\">HTTP Request Information</th></tr>\n");
78: php_info_print_table_row(2, "HTTP Request Line", lpCB->lpszReq);
79: PUTS("<tr><th colspan=2 bgcolor=\"" PHP_HEADER_COLOR "\">HTTP Headers</th></tr>\n");
80: php_info_print_table_header(2, "Server Variable", "Value");
81:
82: /* --- loop over all registered server variables --- */
83: for(; pIter && PIDBIterator_atValidElement( pIter ); PIDBIterator_next( pIter ) )
84: {
85: PCHAR pKey;
86: PIDBIterator_current( pIter, &pKey );
87: if ( !pKey ) { /* sanity */ continue; };
88:
89: variable_len = PI3WEB_SERVER_VAR_BUF_SIZE;
90: if (lpCB->GetServerVariable(lpCB->ConnID, pKey, variable_buf, &variable_len)
91: && variable_buf[0]) {
92: php_info_print_table_row(2, pKey, variable_buf);
93: } else if (PIPlatform_getLastError() == PIAPI_EINVAL) {
94: char *tmp_variable_buf;
95:
96: tmp_variable_buf = (char *) emalloc(variable_len);
97: if (lpCB->GetServerVariable(lpCB->ConnID, pKey, tmp_variable_buf, &variable_len)
98: && variable_buf[0]) {
99: php_info_print_table_row(2, pKey, tmp_variable_buf);
100: }
101: efree(tmp_variable_buf);
102: }
103: }
104:
105: PUTS("</table>");
106: }
107:
108:
109: static zend_module_entry php_pi3web_module = {
110: STANDARD_MODULE_HEADER,
111: "PI3WEB",
112: NULL,
113: NULL,
114: NULL,
115: NULL,
116: NULL,
117: php_info_pi3web,
118: NULL,
119: STANDARD_MODULE_PROPERTIES
120: };
121:
122:
123: static int zend_pi3web_ub_write(const char *str, uint str_length TSRMLS_DC)
124: {
125: DWORD num_bytes = str_length;
126: LPCONTROL_BLOCK cb;
127:
128: cb = (LPCONTROL_BLOCK) SG(server_context);
129:
130: if ( !IWasLoaded ) return 0;
131: cb->WriteClient(cb->ConnID, (char *) str, &num_bytes, 0 );
132:
133: if (num_bytes != str_length)
134: php_handle_aborted_connection();
135: return num_bytes;
136: }
137:
138:
139: static int sapi_pi3web_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC)
140: {
141: return SAPI_HEADER_ADD;
142: }
143:
144:
145: static void accumulate_header_length(sapi_header_struct *sapi_header, uint *total_length TSRMLS_DC)
146: {
147: *total_length += sapi_header->header_len+2;
148: }
149:
150:
151: static void concat_header(sapi_header_struct *sapi_header, char **combined_headers_ptr TSRMLS_DC)
152: {
153: memcpy(*combined_headers_ptr, sapi_header->header, sapi_header->header_len);
154: *combined_headers_ptr += sapi_header->header_len;
155: **combined_headers_ptr = '\r';
156: (*combined_headers_ptr)++;
157: **combined_headers_ptr = '\n';
158: (*combined_headers_ptr)++;
159: }
160:
161:
162: static int sapi_pi3web_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
163: {
164: uint total_length = 2; /* account for the trailing \r\n */
165: char *combined_headers, *combined_headers_ptr;
166: LPCONTROL_BLOCK lpCB = (LPCONTROL_BLOCK) SG(server_context);
167: sapi_header_struct default_content_type;
168:
169: if ( !IWasLoaded ) return SAPI_HEADER_SENT_SUCCESSFULLY;
170:
171:
172: if (SG(sapi_headers).send_default_content_type) {
173: sapi_get_default_content_type_header(&default_content_type TSRMLS_CC);
174: accumulate_header_length(&default_content_type, (void *) &total_length TSRMLS_CC);
175: }
176: zend_llist_apply_with_argument(&SG(sapi_headers).headers, (llist_apply_with_arg_func_t) accumulate_header_length, (void *) &total_length TSRMLS_CC);
177:
178: /* Generate headers */
179: combined_headers = (char *) emalloc(total_length+1);
180: combined_headers_ptr = combined_headers;
181: if (SG(sapi_headers).send_default_content_type) {
182: concat_header(&default_content_type, (void *) &combined_headers_ptr TSRMLS_CC);
183: sapi_free_header(&default_content_type); /* we no longer need it */
184: }
185: zend_llist_apply_with_argument(&SG(sapi_headers).headers, (llist_apply_with_arg_func_t) concat_header, (void *) &combined_headers_ptr TSRMLS_CC);
186: *combined_headers_ptr++ = '\r';
187: *combined_headers_ptr++ = '\n';
188: *combined_headers_ptr = 0;
189:
190: lpCB->dwHttpStatusCode = SG(sapi_headers).http_response_code;
191: lpCB->SendHeaderFunction(lpCB->ConnID, &total_length, (LPDWORD) combined_headers);
192:
193: efree(combined_headers);
194: if (SG(sapi_headers).http_status_line) {
195: efree(SG(sapi_headers).http_status_line);
196: SG(sapi_headers).http_status_line = 0;
197: }
198: return SAPI_HEADER_SENT_SUCCESSFULLY;
199: }
200:
201:
202: static int php_pi3web_startup(sapi_module_struct *sapi_module)
203: {
204: if (php_module_startup(sapi_module, &php_pi3web_module, 1)==FAILURE) {
205: return FAILURE;
206: } else {
207: return SUCCESS;
208: }
209: }
210:
211:
212: static int sapi_pi3web_read_post(char *buffer, uint count_bytes TSRMLS_DC)
213: {
214: LPCONTROL_BLOCK lpCB = (LPCONTROL_BLOCK) SG(server_context);
215: DWORD read_from_buf=0;
216: DWORD read_from_input=0;
217: DWORD total_read=0;
218:
219: if ((DWORD)SG(read_post_bytes) < lpCB->cbAvailable) {
220: read_from_buf = MIN(lpCB->cbAvailable-SG(read_post_bytes), count_bytes);
221: memcpy(buffer, lpCB->lpbData+SG(read_post_bytes), read_from_buf);
222: total_read += read_from_buf;
223: }
224: if (read_from_buf<count_bytes
225: && (SG(read_post_bytes)+read_from_buf) < lpCB->cbTotalBytes) {
226: DWORD cbRead=0, cbSize;
227:
228: read_from_input = MIN(count_bytes-read_from_buf, lpCB->cbTotalBytes-SG(read_post_bytes)-read_from_buf);
229: while (cbRead < read_from_input) {
230: cbSize = read_from_input - cbRead;
231: if (!lpCB->ReadClient(lpCB->ConnID, buffer+read_from_buf+cbRead, &cbSize) || cbSize==0) {
232: break;
233: }
234: cbRead += cbSize;
235: }
236: total_read += cbRead;
237: }
238:
239: /* removed after re-testing POST with Pi3Web 2.0.2 */
240: /* SG(read_post_bytes) += total_read; */
241: return total_read;
242: }
243:
244:
245: static char *sapi_pi3web_read_cookies(TSRMLS_D)
246: {
247: LPCONTROL_BLOCK lpCB = (LPCONTROL_BLOCK) SG(server_context);
248: char variable_buf[PI3WEB_SERVER_VAR_BUF_SIZE];
249: DWORD variable_len = PI3WEB_SERVER_VAR_BUF_SIZE;
250:
251: if (lpCB->GetServerVariable(lpCB->ConnID, "HTTP_COOKIE", variable_buf, &variable_len)) {
252: return estrndup(variable_buf, variable_len);
253: } else if (PIPlatform_getLastError()==PIAPI_EINVAL) {
254: char *tmp_variable_buf = (char *) emalloc(variable_len+1);
255:
256: if (lpCB->GetServerVariable(lpCB->ConnID, "HTTP_COOKIE", tmp_variable_buf, &variable_len)) {
257: tmp_variable_buf[variable_len] = 0;
258: return tmp_variable_buf;
259: } else {
260: efree(tmp_variable_buf);
261: }
262: }
263: return NULL;
264: }
265:
266: static void init_request_info(LPCONTROL_BLOCK lpCB TSRMLS_DC)
267: {
268: SG(server_context) = lpCB;
269: SG(request_info).request_method = lpCB->lpszMethod;
270: SG(request_info).query_string = lpCB->lpszQueryString;
271: SG(request_info).path_translated = lpCB->lpszPathTranslated;
272: SG(request_info).request_uri = lpCB->lpszUri;
273: SG(request_info).content_type = lpCB->lpszContentType;
274: SG(request_info).content_length = lpCB->cbTotalBytes;
275: SG(request_info).auth_user = (lpCB->lpszUser) ? (char *)estrdup((const char *)(lpCB->lpszUser)) : 0;
276: SG(request_info).auth_password = (lpCB->lpszPassword) ? (char *)estrdup((const char *)(lpCB->lpszPassword)) : 0;
277: SG(sapi_headers).http_response_code = 200;
278: }
279:
280: static void sapi_pi3web_register_variables(zval *track_vars_array TSRMLS_DC)
281: {
282: char static_variable_buf[PI3WEB_SERVER_VAR_BUF_SIZE];
283: char *variable_buf;
284: DWORD variable_len = PI3WEB_SERVER_VAR_BUF_SIZE;
285: LPCONTROL_BLOCK lpCB = (LPCONTROL_BLOCK) SG(server_context);
286: PIDB *pDB = (PIDB *)lpCB->GetVariableNames(lpCB->ConnID);
287: PIDBIterator *pIter = PIDB_getIterator( pDB, PIDBTYPE_STRING, 0, 0 );
288:
289: /* --- loop over all registered server variables --- */
290: for(; pIter && PIDBIterator_atValidElement( pIter ); PIDBIterator_next( pIter ) )
291: {
292: PCHAR pKey;
293: PIDBIterator_current( pIter, &pKey );
294: if ( !pKey ) { /* sanity */ continue; };
295:
296: variable_len = PI3WEB_SERVER_VAR_BUF_SIZE;
297: if (lpCB->GetServerVariable(lpCB->ConnID, pKey, static_variable_buf, &variable_len)
298: && (variable_len > 1)) {
299: php_register_variable(pKey, static_variable_buf, track_vars_array TSRMLS_CC);
300: } else if (PIPlatform_getLastError()==PIAPI_EINVAL) {
301: variable_buf = (char *) emalloc(variable_len);
302: if (lpCB->GetServerVariable(lpCB->ConnID, pKey, variable_buf, &variable_len)) {
303: php_register_variable(pKey, variable_buf, track_vars_array TSRMLS_CC);
304: }
305: efree(variable_buf);
306: }
307:
308: }
309:
310:
311: /* PHP_SELF support */
312: variable_len = PI3WEB_SERVER_VAR_BUF_SIZE;
313: if (lpCB->GetServerVariable(lpCB->ConnID, "SCRIPT_NAME", static_variable_buf, &variable_len)
314: && (variable_len > 1)) {
315: php_register_variable("PHP_SELF", static_variable_buf, track_vars_array TSRMLS_CC);
316: }
317: }
318:
319: static sapi_module_struct pi3web_sapi_module = {
320: "pi3web", /* name */
321: "PI3WEB", /* pretty name */
322:
323: php_pi3web_startup, /* startup */
324: php_module_shutdown_wrapper, /* shutdown */
325: NULL, /* activate */
326: NULL, /* deactivate */
327: zend_pi3web_ub_write, /* unbuffered write */
328: NULL, /* flush */
329: NULL, /* get uid */
330: NULL, /* getenv */
331: php_error, /* error handler */
332: sapi_pi3web_header_handler, /* header handler */
333: sapi_pi3web_send_headers, /* send headers handler */
334: NULL, /* send header handler */
335: sapi_pi3web_read_post, /* read POST data */
336: sapi_pi3web_read_cookies, /* read Cookies */
337: sapi_pi3web_register_variables, /* register server variables */
338: NULL, /* Log message */
339: NULL, /* Get request time */
340: NULL, /* Child terminate */
341:
342: STANDARD_SAPI_MODULE_PROPERTIES
343: };
344:
345: MODULE_API DWORD PHP5_wrapper(LPCONTROL_BLOCK lpCB)
346: {
347: zend_file_handle file_handle = {0};
348: int iRet = PIAPI_COMPLETED;
349: TSRMLS_FETCH();
350:
351: zend_first_try {
352: file_handle.filename = lpCB->lpszFileName;
353: file_handle.free_filename = 0;
354: file_handle.type = ZEND_HANDLE_FILENAME;
355: file_handle.opened_path = NULL;
356:
357: init_request_info(lpCB TSRMLS_CC);
358: php_request_startup(TSRMLS_C);
359:
360: switch ( lpCB->dwBehavior ) {
361: case PHP_MODE_STANDARD:
362: iRet = ( php_execute_script( &file_handle TSRMLS_CC ) ) ?
363: PIAPI_COMPLETED : PIAPI_ERROR;
364: break;
365: case PHP_MODE_HIGHLIGHT: {
366: zend_syntax_highlighter_ini syntax_highlighter_ini;
367: if ( open_file_for_scanning( &file_handle TSRMLS_CC ) == SUCCESS )
368: {
369: php_get_highlight_struct( &syntax_highlighter_ini );
370: zend_highlight( &syntax_highlighter_ini TSRMLS_CC );
371: }
372: else
373: {
374: iRet = PIAPI_ERROR;
375: };
376: };
377: break;
378: case PHP_MODE_INDENT: {
379: sapi_header_line ctr = {0};
380:
381: ctr.line = "Content-Type: text/plain";
382: ctr.line_len = strlen(ctr.line);
383:
384: sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC);
385: }
386: if ( open_file_for_scanning( &file_handle TSRMLS_CC ) == SUCCESS )
387: {
388: zend_indent();
389: }
390: else
391: {
392: iRet = PIAPI_ERROR;
393: };
394: break;
395: case PHP_MODE_LINT:
396: iRet = (php_lint_script(&file_handle TSRMLS_CC) == SUCCESS) ?
397: PIAPI_COMPLETED : PIAPI_ERROR;
398: break;
399: default:
400: iRet = PIAPI_ERROR;;
401: }
402:
403: if (SG(request_info).cookie_data) {
404: efree(SG(request_info).cookie_data);
405: };
406:
407: php_request_shutdown(NULL);
408: } zend_catch {
409: iRet = PIAPI_ERROR;
410: } zend_end_try();
411: return iRet;
412: }
413:
414: MODULE_API BOOL PHP5_startup() {
415: tsrm_startup(1, 1, 0, NULL);
416: sapi_startup(&pi3web_sapi_module);
417: if (pi3web_sapi_module.startup) {
418: pi3web_sapi_module.startup(&pi3web_sapi_module);
419: };
420: IWasLoaded = 1;
421: return IWasLoaded;
422: };
423:
424: MODULE_API BOOL PHP5_shutdown() {
425: if (pi3web_sapi_module.shutdown) {
426: pi3web_sapi_module.shutdown(&pi3web_sapi_module);
427: };
428: sapi_shutdown();
429: tsrm_shutdown();
430: IWasLoaded = 0;
431: return !IWasLoaded;
432: };
433:
434: /*
435: * Local variables:
436: * tab-width: 4
437: * c-basic-offset: 4
438: * End:
439: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>