root/sapi/webjames/webjames.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sapi_webjames_ub_write
  2. sapi_webjames_send_header
  3. sapi_webjames_read_post
  4. sapi_webjames_read_cookies
  5. sapi_webjames_register_variables
  6. webjames_module_main
  7. webjames_php_close
  8. webjames_php_request
  9. php_info_webjames
  10. php_webjames_startup
  11. webjames_php_init
  12. webjames_php_shutdown

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

/* [<][>][^][v][top][bottom][index][help] */