summaryrefslogtreecommitdiff
path: root/sapi/webjames/webjames.c
diff options
context:
space:
mode:
Diffstat (limited to 'sapi/webjames/webjames.c')
-rw-r--r--sapi/webjames/webjames.c330
1 files changed, 330 insertions, 0 deletions
diff --git a/sapi/webjames/webjames.c b/sapi/webjames/webjames.c
new file mode 100644
index 0000000..9237ac7
--- /dev/null
+++ b/sapi/webjames/webjames.c
@@ -0,0 +1,330 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Alex Waugh <alex@alexwaugh.com> |
+ +----------------------------------------------------------------------+
+*/
+
+
+#include "php.h"
+#include "SAPI.h"
+#include "php_main.h"
+#include "php_variables.h"
+
+#define WEBJAMES_PHP_ONLY
+#include "php_webjames.h"
+
+#include <unixlib/local.h>
+
+#define WEBJAMES_SAPI_VERSION "1.0.2"
+
+typedef struct {
+ struct connection *conn; /*structure holding all the details of the current request*/
+ int bodyread; /*amount of POST body read*/
+ closefn oldclose; /*function to call to close the connection*/
+} php_webjames_globals;
+
+static php_webjames_globals webjames_globals;
+
+#define WG(v) (webjames_globals.v)
+
+static int sapi_webjames_ub_write(const char *str, uint str_length TSRMLS_DC)
+/*unbuffered write - send data straight out to socket*/
+{
+ int totalbytes = 0;
+
+ do {
+ int bytes;
+ bytes = webjames_writebuffer(WG(conn),str,str_length);
+ if (bytes<0) {
+ PG(connection_status) = PHP_CONNECTION_ABORTED;
+ if (!PG(ignore_user_abort)) {
+ zend_bailout();
+ }
+ return bytes;
+ }
+ str += bytes;
+ str_length -= bytes;
+ totalbytes += bytes;
+ } while (str_length);
+ return totalbytes;
+}
+
+static void sapi_webjames_send_header(sapi_header_struct *sapi_header, void *server_context TSRMLS_DC)
+/*send an HTTP header*/
+{
+ char *header = sapi_header->header;
+ int len = sapi_header->header_len;
+ if (WG(conn)->flags.outputheaders) {
+ while (sapi_header && len > 0) {
+ int bytes;
+ bytes = webjames_writebuffer(WG(conn), header, len);
+ if (bytes<0) {
+ PG(connection_status) = PHP_CONNECTION_ABORTED;
+ if (!PG(ignore_user_abort)) {
+ zend_bailout();
+ }
+ return;
+ }
+ header += bytes;
+ len -= bytes;
+ }
+ webjames_writestring(WG(conn), "\r\n");
+ }
+}
+
+static int sapi_webjames_read_post(char *buffer, uint count_bytes TSRMLS_DC)
+/*read some of the post data*/
+{
+ if (WG(conn)->body==NULL) return 0;
+ if (count_bytes+WG(bodyread)>WG(conn)->bodysize) count_bytes=WG(conn)->bodysize-WG(bodyread);
+ memcpy(buffer, WG(conn)->body+WG(bodyread), count_bytes);
+ WG(bodyread)+=count_bytes;
+ return count_bytes;
+}
+
+static char *sapi_webjames_read_cookies(TSRMLS_D)
+{
+ return WG(conn)->cookie;
+}
+
+#define BUF_SIZE 512
+#define ADD_STRING(name,string)\
+ php_register_variable(name, string, track_vars_array TSRMLS_CC)
+
+#define ADD_NUM(name,field) {\
+ snprintf(buf, BUF_SIZE, "%d", WG(conn)->field);\
+ php_register_variable(name, buf, track_vars_array TSRMLS_CC);\
+}
+
+#define ADD_FIELD(name, field) \
+ if (WG(conn)->field) { \
+ php_register_variable(name, WG(conn)->field, track_vars_array TSRMLS_CC); \
+ }
+
+static void sapi_webjames_register_variables(zval *track_vars_array TSRMLS_DC)
+{
+ char buf[BUF_SIZE + 1];
+ char *docroot;
+
+ buf[BUF_SIZE] = '\0';
+
+ ADD_STRING("SERVER_SOFTWARE", configuration.server);
+ ADD_STRING("SERVER_NAME", configuration.serverip);
+ ADD_FIELD("SERVER_PROTOCOL", protocol);
+ ADD_NUM("SERVER_PORT", port);
+ ADD_STRING("SERVER_ADMIN",configuration.webmaster);
+ ADD_STRING("GATEWAY_INTERFACE", "CGI/1.1");
+
+ docroot = __unixify(WG(conn)->homedir,0,NULL,1024,0);
+ if (docroot) ADD_STRING("DOCUMENT_ROOT", docroot);
+
+ ADD_FIELD("REQUEST_METHOD", methodstr);
+ ADD_FIELD("REQUEST_URI", requesturi);
+ ADD_STRING("PATH_TRANSLATED", SG(request_info).path_translated);
+ ADD_FIELD("SCRIPT_NAME", uri);
+ ADD_FIELD("PHP_SELF", uri);
+ ADD_FIELD("QUERY_STRING", args);
+
+
+ snprintf(buf, BUF_SIZE, "%d.%d.%d.%d", WG(conn)->ipaddr[0], WG(conn)->ipaddr[1], WG(conn)->ipaddr[2], WG(conn)->ipaddr[3]);
+ ADD_STRING("REMOTE_ADDR", buf);
+ if (WG(conn)->dnsstatus == DNS_OK) ADD_FIELD("REMOTE_HOST", host);
+
+ if ((WG(conn)->method == METHOD_POST) || (WG(conn)->method == METHOD_PUT)) {
+ ADD_NUM("CONTENT_LENGTH", bodysize);
+ ADD_FIELD("CONTENT_TYPE", type);
+ }
+
+ if ((WG(conn)->method == METHOD_PUT) || (WG(conn)->method == METHOD_DELETE)) ADD_FIELD("ENTITY_PATH", requesturi);
+
+ if (WG(conn)->pwd) {
+ ADD_STRING("AUTH_TYPE", "basic");
+ ADD_FIELD("REMOTE_USER", authorization);
+ }
+
+ ADD_FIELD("HTTP_COOKIE", cookie);
+ ADD_FIELD("HTTP_USER_AGENT", useragent);
+ ADD_FIELD("HTTP_REFERER", referer);
+ ADD_FIELD("HTTP_ACCEPT", accept);
+ ADD_FIELD("HTTP_ACCEPT_LANGUAGE", acceptlanguage);
+ ADD_FIELD("HTTP_ACCEPT_CHARSET", acceptcharset);
+ ADD_FIELD("HTTP_ACCEPT_ENCODING", acceptencoding);
+}
+
+static void webjames_module_main(TSRMLS_D)
+{
+ zend_file_handle file_handle;
+ FILE *fp=NULL;
+ char *path;
+
+ /* Convert filename to Unix format*/
+ __riscosify_control|=__RISCOSIFY_STRICT_UNIX_SPECS;
+ path = __unixify(WG(conn)->filename,0,NULL,1024,0);
+ if (path) SG(request_info).path_translated = estrdup(path);
+
+ SG(request_info).query_string = WG(conn)->args;
+ SG(request_info).request_uri = WG(conn)->requesturi;
+ SG(request_info).request_method = WG(conn)->methodstr;
+ if (WG(conn)->method==METHOD_HEAD) {
+ SG(request_info).headers_only = 1;
+ } else {
+ SG(request_info).headers_only = 0;
+ }
+ SG(sapi_headers).http_response_code = 200;
+ SG(request_info).content_type = WG(conn)->type;
+ SG(request_info).content_length = WG(conn)->bodysize;
+
+ SG(request_info).auth_user = NULL;
+ SG(request_info).auth_password = NULL;
+ if (WG(conn)->authorization) {
+ char *colon=strchr(WG(conn)->authorization,':');
+ if (colon) {
+ SG(request_info).auth_user = emalloc(colon-WG(conn)->authorization+1);
+ if (SG(request_info).auth_user) {
+ memcpy(SG(request_info).auth_user,WG(conn)->authorization,colon-WG(conn)->authorization);
+ SG(request_info).auth_user[colon-WG(conn)->authorization]='\0';
+ SG(request_info).auth_password = estrdup(colon+1);
+ }
+ }
+ }
+
+ /*ensure that syslog calls get logged separately from WebJames' main log */
+ openlog("PHP",0,0);
+
+ file_handle.type = ZEND_HANDLE_FILENAME;
+ file_handle.filename = SG(request_info).path_translated;
+ file_handle.free_filename = 0;
+ file_handle.opened_path = NULL;
+
+ if (php_request_startup(TSRMLS_C) == FAILURE) {
+ return;
+ }
+
+ php_execute_script(&file_handle TSRMLS_CC);
+ php_request_shutdown(NULL);
+}
+
+static void webjames_php_close(struct connection *conn, int force)
+/*called by webjames if it wants to close the connection*/
+{
+ TSRMLS_FETCH();
+
+ php_request_shutdown(NULL);
+ WG(oldclose)(conn,force);
+}
+
+void webjames_php_request(struct connection *conn)
+/*called by WebJames to start handler*/
+{
+ TSRMLS_FETCH();
+
+ WG(conn) = conn;
+ WG(bodyread) = 0;
+ WG(oldclose) = conn->close;
+ conn->close=webjames_php_close;
+
+ webjames_module_main(TSRMLS_C);
+
+ WG(oldclose)(WG(conn), 0);
+}
+
+static void php_info_webjames(ZEND_MODULE_INFO_FUNC_ARGS)
+{
+ php_info_print_table_start();
+ php_info_print_table_row(2, "SAPI module version", WEBJAMES_SAPI_VERSION);
+ php_info_print_table_row(2, "WebJames version", WEBJAMES_VERSION " (" WEBJAMES_DATE ")");
+ php_info_print_table_end();
+}
+
+static zend_module_entry php_webjames_module = {
+#if ZEND_MODULE_API_NO >= 20010901
+ STANDARD_MODULE_HEADER,
+#endif
+ "WebJames",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ php_info_webjames,
+#if ZEND_MODULE_API_NO >= 20010901
+ WEBJAMES_SAPI_VERSION,
+#endif
+ STANDARD_MODULE_PROPERTIES
+};
+
+
+static int php_webjames_startup(sapi_module_struct *sapi_module)
+{
+ if(php_module_startup(sapi_module, &php_webjames_module, 1) == FAILURE) {
+ return FAILURE;
+ } else {
+ return SUCCESS;
+ }
+}
+
+static sapi_module_struct sapi_module = {
+ "webjames", /* name */
+ "WebJames", /* pretty name */
+
+ php_webjames_startup, /* startup */
+ php_module_shutdown_wrapper, /* shutdown */
+
+ NULL, /* activate */
+ NULL, /* deactivate */
+
+ sapi_webjames_ub_write, /* unbuffered write */
+ NULL, /* flush */
+ NULL, /* get uid */
+ NULL, /* getenv */
+
+ php_error, /* error handler */
+
+ NULL, /* header handler */
+ NULL, /* send headers handler */
+ sapi_webjames_send_header, /* send header handler */
+ sapi_webjames_read_post, /* read POST data */
+ sapi_webjames_read_cookies, /* read Cookies */
+
+ sapi_webjames_register_variables, /* register server variables */
+ NULL, /* Log message */
+ NULL, /* Get request time */
+ NULL, /* Child terminate */
+
+ STANDARD_SAPI_MODULE_PROPERTIES
+};
+
+int webjames_php_init(void)
+/*called when WebJames initialises*/
+{
+ TSRMLS_FETCH();
+ if (strcmp(configuration.webjames_h_revision,WEBJAMES_H_REVISION)!=0) {
+ /*This file was compiled against a different revision of
+ webjames.h than webjames was, which could be bad news*/
+ 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);
+ return 0; /*failed to initialise*/
+ }
+ sapi_startup(&sapi_module);
+ sapi_module.startup(&sapi_module);
+ SG(server_context) = (void *) 1;
+ return 1; /*initialised correctly*/
+}
+
+void webjames_php_shutdown(void)
+/*called when WebJames is about to quit*/
+{
+ sapi_module.shutdown(&sapi_module);
+ sapi_shutdown();
+}