Back to index

php5  5.3.10
phttpd.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1997-2012 The PHP Group                                |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 3.01 of the PHP license,      |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.php.net/license/3_01.txt                                  |
00011    | If you did not receive a copy of the PHP license and are unable to   |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@php.net so we can mail you a copy immediately.               |
00014    +----------------------------------------------------------------------+
00015    | Author: Thies C. Arntzen <thies@thieso.net>                                      |
00016    | Based on aolserver SAPI by Sascha Schumann <sascha@schumann.cx>      |
00017    +----------------------------------------------------------------------+
00018 */
00019 
00020 #include "php.h"
00021 #include "SAPI.h"
00022 #include "php_main.h"
00023 
00024 #ifdef HAVE_PHTTPD
00025 
00026 #include "ext/standard/info.h"
00027  
00028 #ifndef ZTS
00029 #error PHTTPD module is only useable in thread-safe mode
00030 #endif
00031 
00032 #include "php_phttpd.h"
00033 
00034 typedef struct {
00035     struct connectioninfo *cip;
00036        struct stat sb;
00037 } phttpd_globals_struct; 
00038 
00039 static int ph_globals_id;
00040 
00041 #define PHG(v) TSRMG(ph_globals_id, phttpd_globals_struct *, v)
00042 
00043 static int
00044 php_phttpd_startup(sapi_module_struct *sapi_module)
00045 {
00046        fprintf(stderr,"***php_phttpd_startup\n");
00047 
00048     if (php_module_startup(sapi_module, NULL, 0)) {
00049         return FAILURE;
00050     } else {
00051         return SUCCESS;
00052     }
00053 }
00054 
00055 static int
00056 php_phttpd_sapi_ub_write(const char *str, uint str_length TSRMLS_DC)
00057 {
00058     int sent_bytes;
00059 
00060        sent_bytes = fd_write(PHG(cip)->fd, str, str_length);
00061 
00062        if (sent_bytes == -1) {
00063               php_handle_aborted_connection();
00064        }
00065 
00066     return sent_bytes;
00067 }
00068 
00069 static int
00070 php_phttpd_sapi_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC)
00071 {
00072     char *header_name, *header_content;
00073     char *p;
00074     TSRMLS_FETCH();
00075  
00076        http_sendheaders(PHG(cip)->fd, PHG(cip), SG(sapi_headers).http_response_code, NULL);
00077 
00078     header_name = sapi_header->header;
00079     header_content = p = strchr(header_name, ':');
00080  
00081     if (p) {
00082         *p = '\0';
00083         do {
00084             header_content++;
00085         } while (*header_content == ' ');
00086 
00087               fd_printf(PHG(cip)->fd,"%s: %s\n", header_name, header_content);
00088  
00089         *p = ':';
00090     }
00091 
00092     sapi_free_header(sapi_header);
00093 
00094     return 0;
00095 }
00096 
00097 static int
00098 php_phttpd_sapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
00099 {
00100     TSRMLS_FETCH();
00101  
00102     if (SG(sapi_headers).send_default_content_type) {
00103               fd_printf(PHG(cip)->fd,"Content-Type: text/html\n");
00104     }
00105  
00106        fd_putc('\n', PHG(cip)->fd);
00107  
00108     return SAPI_HEADER_SENT_SUCCESSFULLY;
00109 }
00110 
00111 static char *
00112 php_phttpd_sapi_read_cookies(TSRMLS_D)
00113 {
00114 
00115 /*
00116     int i;
00117     char *http_cookie = NULL;
00118     NTSRMLS_FETCH();
00119  
00120     i = Ns_SetIFind(NSG(conn->headers), "cookie");
00121     if(i != -1) {
00122         http_cookie = Ns_SetValue(NSG(conn->headers), i);
00123     }
00124  
00125     return http_cookie;
00126 */
00127        fprintf(stderr,"***php_phttpd_sapi_read_cookies\n");
00128  
00129        return 0;
00130 }
00131 
00132 static int
00133 php_phttpd_sapi_read_post(char *buf, uint count_bytes TSRMLS_DC)
00134 {
00135 /*
00136     uint max_read;
00137     uint total_read = 0;
00138     NTSRMLS_FETCH();
00139  
00140     max_read = MIN(NSG(data_avail), count_bytes);
00141  
00142     total_read = Ns_ConnRead(NSG(conn), buf, max_read);
00143  
00144     if(total_read == NS_ERROR) {
00145         total_read = -1;
00146     } else {
00147         NSG(data_avail) -= total_read;
00148     }
00149  
00150     return total_read;
00151 */
00152        fprintf(stderr,"***php_phttpd_sapi_read_post\n");
00153        return 0;
00154 }
00155 
00156 static sapi_module_struct phttpd_sapi_module = {
00157     "phttpd",
00158     "PHTTPD",
00159  
00160     php_phttpd_startup,                     /* startup */
00161     php_module_shutdown_wrapper,            /* shutdown */
00162  
00163        NULL,                                                          /* activate */
00164        NULL,                                                          /* deactivate */
00165 
00166     php_phttpd_sapi_ub_write,               /* unbuffered write */
00167        NULL,                                                          /* flush */
00168        NULL,                                                          /* get uid */
00169        NULL,                                                          /* getenv */
00170 
00171     php_error,                              /* error handler */
00172  
00173     php_phttpd_sapi_header_handler,         /* header handler */
00174     php_phttpd_sapi_send_headers,           /* send headers handler */
00175     NULL,                                   /* send header handler */
00176  
00177     php_phttpd_sapi_read_post,              /* read POST data */
00178     php_phttpd_sapi_read_cookies,           /* read Cookies */
00179  
00180        NULL,                                                          /* register server variables */
00181        NULL,                                                          /* Log message */
00182        NULL,                                                          /* Get request time */
00183        NULL,                                                          /* Child terminate */
00184 
00185     STANDARD_SAPI_MODULE_PROPERTIES
00186 };
00187 
00188 static void
00189 php_phttpd_request_ctor(TSRMLS_D TSRMLS_DC)
00190 {
00191        memset(&SG(request_info), 0, sizeof(sapi_globals_struct)); /* pfusch! */
00192 
00193     SG(request_info).query_string = PHG(cip)->hip->request;
00194     SG(request_info).request_method = PHG(cip)->hip->method;
00195        SG(request_info).path_translated = malloc(MAXPATHLEN);
00196     SG(sapi_headers).http_response_code = 200;
00197        if (url_expand(PHG(cip)->hip->url, SG(request_info).path_translated, MAXPATHLEN, &PHG(sb), NULL, NULL) == NULL) {
00198               /* handle error */
00199        }
00200 
00201 #if 0
00202     char *server;
00203     Ns_DString ds;
00204     char *root;
00205     int index;
00206     char *tmp;
00207  
00208     server = Ns_ConnServer(NSG(conn));
00209  
00210     Ns_DStringInit(&ds);
00211     Ns_UrlToFile(&ds, server, NSG(conn->request->url));
00212  
00213     /* path_translated is the absolute path to the file */
00214     SG(request_info).path_translated = strdup(Ns_DStringValue(&ds));
00215     Ns_DStringFree(&ds);
00216     root = Ns_PageRoot(server);
00217     SG(request_info).request_uri = SG(request_info).path_translated + strlen(root);
00218     SG(request_info).content_length = Ns_ConnContentLength(NSG(conn));
00219     index = Ns_SetIFind(NSG(conn)->headers, "content-type");
00220     SG(request_info).content_type = index == -1 ? NULL :
00221         Ns_SetValue(NSG(conn)->headers, index);
00222  
00223     tmp = Ns_ConnAuthUser(NSG(conn));
00224     if(tmp) {
00225         tmp = estrdup(tmp);
00226     }
00227     SG(request_info).auth_user = tmp;
00228  
00229     tmp = Ns_ConnAuthPasswd(NSG(conn));
00230     if(tmp) {
00231         tmp = estrdup(tmp);
00232     }
00233     SG(request_info).auth_password = tmp;
00234  
00235     NSG(data_avail) = SG(request_info).content_length;
00236 #endif
00237 }
00238 
00239 static void
00240 php_phttpd_request_dtor(TSRMLS_D TSRMLS_DC)
00241 {
00242     free(SG(request_info).path_translated);
00243 }
00244 
00245 
00246 int php_doit(TSRMLS_D TSRMLS_DC)
00247 {
00248        struct stat sb;
00249        zend_file_handle file_handle;
00250        struct httpinfo *hip = PHG(cip)->hip;
00251        TSRMLS_FETCH();
00252 
00253        if (php_request_startup(TSRMLS_C) == FAILURE) {
00254         return -1;
00255     }
00256 
00257     file_handle.type = ZEND_HANDLE_FILENAME;
00258     file_handle.filename = SG(request_info).path_translated;
00259     file_handle.free_filename = 0;
00260 
00261 /*
00262        php_phttpd_hash_environment(TSRMLS_C);
00263 */
00264        php_execute_script(&file_handle TSRMLS_CC);
00265        php_request_shutdown(NULL);
00266 
00267        return SG(sapi_headers).http_response_code;
00268 }
00269 
00270 int pm_init(const char **argv)
00271 {
00272        tsrm_startup(1, 1, 0, NULL);
00273        sapi_startup(&phttpd_sapi_module);
00274     phttpd_sapi_module.startup(&phttpd_sapi_module);
00275 
00276        ts_allocate_id(&ph_globals_id, sizeof(phttpd_globals_struct), NULL, NULL);
00277 
00278        return 0;
00279 }
00280 
00281 void pm_exit(void)
00282 {
00283        fprintf(stderr,"***pm_exit\n");
00284 }
00285 
00286 int pm_request(struct connectioninfo *cip)
00287 {
00288        struct httpinfo *hip = cip->hip;
00289        int status;
00290        TSRMLS_FETCH();
00291 
00292        if (strcasecmp(hip->method, "GET") == 0 || 
00293            strcasecmp(hip->method, "HEAD") == 0 ||
00294            strcasecmp(hip->method, "POST") == 0) {
00295               PHG(cip) = cip;
00296               
00297               php_phttpd_request_ctor(TSRMLS_C);
00298               status = php_doit(TSRMLS_C);
00299               php_phttpd_request_dtor(TSRMLS_C);
00300 
00301               return status;       
00302        } else {
00303               return -2;
00304        }
00305 }
00306 
00307 #endif