File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / sapi / webjames / webjames.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 20:04:02 2014 UTC (10 years, 3 months ago) by misho
Branches: php, MAIN
CVS tags: v5_4_29, HEAD
php 5.4.29

    1: /*
    2:    +----------------------------------------------------------------------+
    3:    | PHP Version 5                                                        |
    4:    +----------------------------------------------------------------------+
    5:    | Copyright (c) 1997-2014 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: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>