Return to webjames.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / sapi / webjames |
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: | Author: Alex Waugh <alex@alexwaugh.com> | ! 16: +----------------------------------------------------------------------+ ! 17: */ ! 18: ! 19: ! 20: #include "php.h" ! 21: #include "SAPI.h" ! 22: #include "php_main.h" ! 23: #include "php_variables.h" ! 24: ! 25: #define WEBJAMES_PHP_ONLY ! 26: #include "php_webjames.h" ! 27: ! 28: #include <unixlib/local.h> ! 29: ! 30: #define WEBJAMES_SAPI_VERSION "1.0.2" ! 31: ! 32: typedef struct { ! 33: struct connection *conn; /*structure holding all the details of the current request*/ ! 34: int bodyread; /*amount of POST body read*/ ! 35: closefn oldclose; /*function to call to close the connection*/ ! 36: } php_webjames_globals; ! 37: ! 38: static php_webjames_globals webjames_globals; ! 39: ! 40: #define WG(v) (webjames_globals.v) ! 41: ! 42: static int sapi_webjames_ub_write(const char *str, uint str_length TSRMLS_DC) ! 43: /*unbuffered write - send data straight out to socket*/ ! 44: { ! 45: int totalbytes = 0; ! 46: ! 47: do { ! 48: int bytes; ! 49: bytes = webjames_writebuffer(WG(conn),str,str_length); ! 50: if (bytes<0) { ! 51: PG(connection_status) = PHP_CONNECTION_ABORTED; ! 52: if (!PG(ignore_user_abort)) { ! 53: zend_bailout(); ! 54: } ! 55: return bytes; ! 56: } ! 57: str += bytes; ! 58: str_length -= bytes; ! 59: totalbytes += bytes; ! 60: } while (str_length); ! 61: return totalbytes; ! 62: } ! 63: ! 64: static void sapi_webjames_send_header(sapi_header_struct *sapi_header, void *server_context TSRMLS_DC) ! 65: /*send an HTTP header*/ ! 66: { ! 67: char *header = sapi_header->header; ! 68: int len = sapi_header->header_len; ! 69: if (WG(conn)->flags.outputheaders) { ! 70: while (sapi_header && len > 0) { ! 71: int bytes; ! 72: bytes = webjames_writebuffer(WG(conn), header, len); ! 73: if (bytes<0) { ! 74: PG(connection_status) = PHP_CONNECTION_ABORTED; ! 75: if (!PG(ignore_user_abort)) { ! 76: zend_bailout(); ! 77: } ! 78: return; ! 79: } ! 80: header += bytes; ! 81: len -= bytes; ! 82: } ! 83: webjames_writestring(WG(conn), "\r\n"); ! 84: } ! 85: } ! 86: ! 87: static int sapi_webjames_read_post(char *buffer, uint count_bytes TSRMLS_DC) ! 88: /*read some of the post data*/ ! 89: { ! 90: if (WG(conn)->body==NULL) return 0; ! 91: if (count_bytes+WG(bodyread)>WG(conn)->bodysize) count_bytes=WG(conn)->bodysize-WG(bodyread); ! 92: memcpy(buffer, WG(conn)->body+WG(bodyread), count_bytes); ! 93: WG(bodyread)+=count_bytes; ! 94: return count_bytes; ! 95: } ! 96: ! 97: static char *sapi_webjames_read_cookies(TSRMLS_D) ! 98: { ! 99: return WG(conn)->cookie; ! 100: } ! 101: ! 102: #define BUF_SIZE 512 ! 103: #define ADD_STRING(name,string)\ ! 104: php_register_variable(name, string, track_vars_array TSRMLS_CC) ! 105: ! 106: #define ADD_NUM(name,field) {\ ! 107: snprintf(buf, BUF_SIZE, "%d", WG(conn)->field);\ ! 108: php_register_variable(name, buf, track_vars_array TSRMLS_CC);\ ! 109: } ! 110: ! 111: #define ADD_FIELD(name, field) \ ! 112: if (WG(conn)->field) { \ ! 113: php_register_variable(name, WG(conn)->field, track_vars_array TSRMLS_CC); \ ! 114: } ! 115: ! 116: static void sapi_webjames_register_variables(zval *track_vars_array TSRMLS_DC) ! 117: { ! 118: char buf[BUF_SIZE + 1]; ! 119: char *docroot; ! 120: ! 121: buf[BUF_SIZE] = '\0'; ! 122: ! 123: ADD_STRING("SERVER_SOFTWARE", configuration.server); ! 124: ADD_STRING("SERVER_NAME", configuration.serverip); ! 125: ADD_FIELD("SERVER_PROTOCOL", protocol); ! 126: ADD_NUM("SERVER_PORT", port); ! 127: ADD_STRING("SERVER_ADMIN",configuration.webmaster); ! 128: ADD_STRING("GATEWAY_INTERFACE", "CGI/1.1"); ! 129: ! 130: docroot = __unixify(WG(conn)->homedir,0,NULL,1024,0); ! 131: if (docroot) ADD_STRING("DOCUMENT_ROOT", docroot); ! 132: ! 133: ADD_FIELD("REQUEST_METHOD", methodstr); ! 134: ADD_FIELD("REQUEST_URI", requesturi); ! 135: ADD_STRING("PATH_TRANSLATED", SG(request_info).path_translated); ! 136: ADD_FIELD("SCRIPT_NAME", uri); ! 137: ADD_FIELD("PHP_SELF", uri); ! 138: ADD_FIELD("QUERY_STRING", args); ! 139: ! 140: ! 141: snprintf(buf, BUF_SIZE, "%d.%d.%d.%d", WG(conn)->ipaddr[0], WG(conn)->ipaddr[1], WG(conn)->ipaddr[2], WG(conn)->ipaddr[3]); ! 142: ADD_STRING("REMOTE_ADDR", buf); ! 143: if (WG(conn)->dnsstatus == DNS_OK) ADD_FIELD("REMOTE_HOST", host); ! 144: ! 145: if ((WG(conn)->method == METHOD_POST) || (WG(conn)->method == METHOD_PUT)) { ! 146: ADD_NUM("CONTENT_LENGTH", bodysize); ! 147: ADD_FIELD("CONTENT_TYPE", type); ! 148: } ! 149: ! 150: if ((WG(conn)->method == METHOD_PUT) || (WG(conn)->method == METHOD_DELETE)) ADD_FIELD("ENTITY_PATH", requesturi); ! 151: ! 152: if (WG(conn)->pwd) { ! 153: ADD_STRING("AUTH_TYPE", "basic"); ! 154: ADD_FIELD("REMOTE_USER", authorization); ! 155: } ! 156: ! 157: ADD_FIELD("HTTP_COOKIE", cookie); ! 158: ADD_FIELD("HTTP_USER_AGENT", useragent); ! 159: ADD_FIELD("HTTP_REFERER", referer); ! 160: ADD_FIELD("HTTP_ACCEPT", accept); ! 161: ADD_FIELD("HTTP_ACCEPT_LANGUAGE", acceptlanguage); ! 162: ADD_FIELD("HTTP_ACCEPT_CHARSET", acceptcharset); ! 163: ADD_FIELD("HTTP_ACCEPT_ENCODING", acceptencoding); ! 164: } ! 165: ! 166: static void webjames_module_main(TSRMLS_D) ! 167: { ! 168: zend_file_handle file_handle; ! 169: FILE *fp=NULL; ! 170: char *path; ! 171: ! 172: /* Convert filename to Unix format*/ ! 173: __riscosify_control|=__RISCOSIFY_STRICT_UNIX_SPECS; ! 174: path = __unixify(WG(conn)->filename,0,NULL,1024,0); ! 175: if (path) SG(request_info).path_translated = estrdup(path); ! 176: ! 177: SG(request_info).query_string = WG(conn)->args; ! 178: SG(request_info).request_uri = WG(conn)->requesturi; ! 179: SG(request_info).request_method = WG(conn)->methodstr; ! 180: if (WG(conn)->method==METHOD_HEAD) { ! 181: SG(request_info).headers_only = 1; ! 182: } else { ! 183: SG(request_info).headers_only = 0; ! 184: } ! 185: SG(sapi_headers).http_response_code = 200; ! 186: SG(request_info).content_type = WG(conn)->type; ! 187: SG(request_info).content_length = WG(conn)->bodysize; ! 188: ! 189: SG(request_info).auth_user = NULL; ! 190: SG(request_info).auth_password = NULL; ! 191: if (WG(conn)->authorization) { ! 192: char *colon=strchr(WG(conn)->authorization,':'); ! 193: if (colon) { ! 194: SG(request_info).auth_user = emalloc(colon-WG(conn)->authorization+1); ! 195: if (SG(request_info).auth_user) { ! 196: memcpy(SG(request_info).auth_user,WG(conn)->authorization,colon-WG(conn)->authorization); ! 197: SG(request_info).auth_user[colon-WG(conn)->authorization]='\0'; ! 198: SG(request_info).auth_password = estrdup(colon+1); ! 199: } ! 200: } ! 201: } ! 202: ! 203: /*ensure that syslog calls get logged separately from WebJames' main log */ ! 204: openlog("PHP",0,0); ! 205: ! 206: file_handle.type = ZEND_HANDLE_FILENAME; ! 207: file_handle.filename = SG(request_info).path_translated; ! 208: file_handle.free_filename = 0; ! 209: file_handle.opened_path = NULL; ! 210: ! 211: if (php_request_startup(TSRMLS_C) == FAILURE) { ! 212: return; ! 213: } ! 214: ! 215: php_execute_script(&file_handle TSRMLS_CC); ! 216: php_request_shutdown(NULL); ! 217: } ! 218: ! 219: static void webjames_php_close(struct connection *conn, int force) ! 220: /*called by webjames if it wants to close the connection*/ ! 221: { ! 222: TSRMLS_FETCH(); ! 223: ! 224: php_request_shutdown(NULL); ! 225: WG(oldclose)(conn,force); ! 226: } ! 227: ! 228: void webjames_php_request(struct connection *conn) ! 229: /*called by WebJames to start handler*/ ! 230: { ! 231: TSRMLS_FETCH(); ! 232: ! 233: WG(conn) = conn; ! 234: WG(bodyread) = 0; ! 235: WG(oldclose) = conn->close; ! 236: conn->close=webjames_php_close; ! 237: ! 238: webjames_module_main(TSRMLS_C); ! 239: ! 240: WG(oldclose)(WG(conn), 0); ! 241: } ! 242: ! 243: static void php_info_webjames(ZEND_MODULE_INFO_FUNC_ARGS) ! 244: { ! 245: php_info_print_table_start(); ! 246: php_info_print_table_row(2, "SAPI module version", WEBJAMES_SAPI_VERSION); ! 247: php_info_print_table_row(2, "WebJames version", WEBJAMES_VERSION " (" WEBJAMES_DATE ")"); ! 248: php_info_print_table_end(); ! 249: } ! 250: ! 251: static zend_module_entry php_webjames_module = { ! 252: #if ZEND_MODULE_API_NO >= 20010901 ! 253: STANDARD_MODULE_HEADER, ! 254: #endif ! 255: "WebJames", ! 256: NULL, ! 257: NULL, ! 258: NULL, ! 259: NULL, ! 260: NULL, ! 261: php_info_webjames, ! 262: #if ZEND_MODULE_API_NO >= 20010901 ! 263: WEBJAMES_SAPI_VERSION, ! 264: #endif ! 265: STANDARD_MODULE_PROPERTIES ! 266: }; ! 267: ! 268: ! 269: static int php_webjames_startup(sapi_module_struct *sapi_module) ! 270: { ! 271: if(php_module_startup(sapi_module, &php_webjames_module, 1) == FAILURE) { ! 272: return FAILURE; ! 273: } else { ! 274: return SUCCESS; ! 275: } ! 276: } ! 277: ! 278: static sapi_module_struct sapi_module = { ! 279: "webjames", /* name */ ! 280: "WebJames", /* pretty name */ ! 281: ! 282: php_webjames_startup, /* startup */ ! 283: php_module_shutdown_wrapper, /* shutdown */ ! 284: ! 285: NULL, /* activate */ ! 286: NULL, /* deactivate */ ! 287: ! 288: sapi_webjames_ub_write, /* unbuffered write */ ! 289: NULL, /* flush */ ! 290: NULL, /* get uid */ ! 291: NULL, /* getenv */ ! 292: ! 293: php_error, /* error handler */ ! 294: ! 295: NULL, /* header handler */ ! 296: NULL, /* send headers handler */ ! 297: sapi_webjames_send_header, /* send header handler */ ! 298: sapi_webjames_read_post, /* read POST data */ ! 299: sapi_webjames_read_cookies, /* read Cookies */ ! 300: ! 301: sapi_webjames_register_variables, /* register server variables */ ! 302: NULL, /* Log message */ ! 303: NULL, /* Get request time */ ! 304: NULL, /* Child terminate */ ! 305: ! 306: STANDARD_SAPI_MODULE_PROPERTIES ! 307: }; ! 308: ! 309: int webjames_php_init(void) ! 310: /*called when WebJames initialises*/ ! 311: { ! 312: TSRMLS_FETCH(); ! 313: if (strcmp(configuration.webjames_h_revision,WEBJAMES_H_REVISION)!=0) { ! 314: /*This file was compiled against a different revision of ! 315: webjames.h than webjames was, which could be bad news*/ ! 316: webjames_writelog(0,"PHP module is compiled for WebJames (%s) and was linked with a different version (%s)",WEBJAMES_H_REVISION,configuration.webjames_h_revision); ! 317: return 0; /*failed to initialise*/ ! 318: } ! 319: sapi_startup(&sapi_module); ! 320: sapi_module.startup(&sapi_module); ! 321: SG(server_context) = (void *) 1; ! 322: return 1; /*initialised correctly*/ ! 323: } ! 324: ! 325: void webjames_php_shutdown(void) ! 326: /*called when WebJames is about to quit*/ ! 327: { ! 328: sapi_module.shutdown(&sapi_module); ! 329: sapi_shutdown(); ! 330: }