PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - main - SAPI.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 395 541 73.0 %
Date: 2014-09-13 Functions: 31 41 75.6 %
Legend: Lines: hit not hit

          Line data    Source code
       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             :    | Original design:  Shane Caraveo <shane@caraveo.com>                  |
      16             :    | Authors: Andi Gutmans <andi@zend.com>                                |
      17             :    |          Zeev Suraski <zeev@zend.com>                                |
      18             :    +----------------------------------------------------------------------+
      19             : */
      20             : 
      21             : /* $Id$ */
      22             : 
      23             : #include <ctype.h>
      24             : #include <sys/stat.h>
      25             : 
      26             : #include "php.h"
      27             : #include "SAPI.h"
      28             : #include "php_variables.h"
      29             : #include "php_ini.h"
      30             : #include "ext/standard/php_string.h"
      31             : #include "ext/standard/pageinfo.h"
      32             : #if (HAVE_PCRE || HAVE_BUNDLED_PCRE) && !defined(COMPILE_DL_PCRE)
      33             : #include "ext/pcre/php_pcre.h"
      34             : #endif
      35             : #ifdef ZTS
      36             : #include "TSRM.h"
      37             : #endif
      38             : #ifdef HAVE_SYS_TIME_H
      39             : #include <sys/time.h>
      40             : #elif defined(PHP_WIN32)
      41             : #include "win32/time.h"
      42             : #endif
      43             : 
      44             : #include "rfc1867.h"
      45             : 
      46             : #ifdef PHP_WIN32
      47             : #define STRCASECMP stricmp
      48             : #else
      49             : #define STRCASECMP strcasecmp
      50             : #endif
      51             : 
      52             : #include "php_content_types.h"
      53             : 
      54             : #ifdef ZTS
      55             : SAPI_API int sapi_globals_id;
      56             : #else
      57             : sapi_globals_struct sapi_globals;
      58             : #endif
      59             : 
      60       20225 : static void sapi_globals_ctor(sapi_globals_struct *sapi_globals TSRMLS_DC)
      61             : {
      62       20225 :         memset(sapi_globals, 0, sizeof(*sapi_globals));
      63       20225 :         zend_hash_init_ex(&sapi_globals->known_post_content_types, 5, NULL, NULL, 1, 0);
      64       20225 :         php_setup_sapi_content_types(TSRMLS_C);
      65       20225 : }
      66             : 
      67       20263 : static void sapi_globals_dtor(sapi_globals_struct *sapi_globals TSRMLS_DC)
      68             : {
      69       20263 :         zend_hash_destroy(&sapi_globals->known_post_content_types);
      70       20263 : }
      71             : 
      72             : /* True globals (no need for thread safety) */
      73             : SAPI_API sapi_module_struct sapi_module;
      74             : 
      75             : 
      76       20225 : SAPI_API void sapi_startup(sapi_module_struct *sf)
      77             : {
      78             : #ifdef ZEND_SIGNALS
      79             :         zend_signal_startup();
      80             : #endif
      81             : 
      82       20225 :         sf->ini_entries = NULL;
      83       20225 :         sapi_module = *sf;
      84             : 
      85             : #ifdef ZTS
      86             :         ts_allocate_id(&sapi_globals_id, sizeof(sapi_globals_struct), (ts_allocate_ctor) sapi_globals_ctor, (ts_allocate_dtor) sapi_globals_dtor);
      87             : # ifdef PHP_WIN32
      88             :         _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
      89             : # endif
      90             : #else
      91       20225 :         sapi_globals_ctor(&sapi_globals);
      92             : #endif
      93             : 
      94       20225 :         virtual_cwd_startup(); /* Could use shutdown to free the main cwd but it would just slow it down for CGI */
      95             : 
      96             : #ifdef PHP_WIN32
      97             :         tsrm_win32_startup();
      98             : #endif
      99             : 
     100             :         reentrancy_startup();
     101       20225 : }
     102             : 
     103       20263 : SAPI_API void sapi_shutdown(void)
     104             : {
     105             : #ifdef ZTS
     106             :         ts_free_id(sapi_globals_id);
     107             : #else
     108       20263 :         sapi_globals_dtor(&sapi_globals);
     109             : #endif
     110             : 
     111             :         reentrancy_shutdown();
     112             : 
     113       20263 :         virtual_cwd_shutdown();
     114             : 
     115             : #ifdef PHP_WIN32
     116             :         tsrm_win32_shutdown();
     117             : #endif
     118       20263 : }
     119             : 
     120             : 
     121       41563 : SAPI_API void sapi_free_header(sapi_header_struct *sapi_header)
     122             : {
     123       41563 :         efree(sapi_header->header);
     124       41563 : }
     125             : 
     126             : /* {{{ proto bool header_register_callback(mixed callback)
     127             :    call a header function */
     128           0 : PHP_FUNCTION(header_register_callback)
     129             : {
     130             :         zval *callback_func;
     131             :         char *callback_name;
     132           0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &callback_func) == FAILURE) {
     133           0 :                 return;
     134             :         }
     135             :         
     136           0 :         if (!zend_is_callable(callback_func, 0, &callback_name TSRMLS_CC)) {
     137           0 :                 efree(callback_name);
     138           0 :                 RETURN_FALSE;
     139             :         }
     140             : 
     141           0 :         efree(callback_name);
     142             : 
     143           0 :         if (SG(callback_func)) {
     144           0 :                 zval_ptr_dtor(&SG(callback_func));
     145           0 :                 SG(fci_cache) = empty_fcall_info_cache;
     146             :         }
     147             : 
     148           0 :         SG(callback_func) = callback_func;
     149             : 
     150           0 :         Z_ADDREF_P(SG(callback_func));
     151             : 
     152           0 :         RETURN_TRUE;
     153             : }
     154             : /* }}} */
     155             : 
     156           0 : static void sapi_run_header_callback(TSRMLS_D)
     157             : {
     158             :         int   error;
     159             :         zend_fcall_info fci;
     160           0 :         char *callback_name = NULL;
     161           0 :         char *callback_error = NULL;
     162           0 :         zval *retval_ptr = NULL;
     163             :         
     164           0 :         if (zend_fcall_info_init(SG(callback_func), 0, &fci, &SG(fci_cache), &callback_name, &callback_error TSRMLS_CC) == SUCCESS) {
     165           0 :                 fci.retval_ptr_ptr = &retval_ptr;
     166             :                 
     167           0 :                 error = zend_call_function(&fci, &SG(fci_cache) TSRMLS_CC);
     168           0 :                 if (error == FAILURE) {
     169           0 :                         goto callback_failed;
     170           0 :                 } else if (retval_ptr) {
     171           0 :                         zval_ptr_dtor(&retval_ptr);
     172             :                 }
     173             :         } else {
     174             : callback_failed:
     175           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not call the sapi_header_callback");
     176             :         }
     177             :         
     178           0 :         if (callback_name) {
     179           0 :                 efree(callback_name);
     180             :         }
     181           0 :         if (callback_error) {
     182           0 :                 efree(callback_error);
     183             :         }       
     184           0 : }
     185             : 
     186          78 : SAPI_API void sapi_handle_post(void *arg TSRMLS_DC)
     187             : {
     188          78 :         if (SG(request_info).post_entry && SG(request_info).content_type_dup) {
     189          73 :                 SG(request_info).post_entry->post_handler(SG(request_info).content_type_dup, arg TSRMLS_CC);
     190          73 :                 if (SG(request_info).post_data) {
     191          36 :                         efree(SG(request_info).post_data);
     192          36 :                         SG(request_info).post_data = NULL;
     193             :                 }
     194          73 :                 efree(SG(request_info).content_type_dup);
     195          73 :                 SG(request_info).content_type_dup = NULL;
     196             :         }
     197          78 : }
     198             : 
     199          75 : static void sapi_read_post_data(TSRMLS_D)
     200             : {
     201             :         sapi_post_entry *post_entry;
     202          75 :         uint content_type_length = strlen(SG(request_info).content_type);
     203          75 :         char *content_type = estrndup(SG(request_info).content_type, content_type_length);
     204             :         char *p;
     205          75 :         char oldchar=0;
     206          75 :         void (*post_reader_func)(TSRMLS_D) = NULL;
     207             : 
     208             : 
     209             :         /* dedicated implementation for increased performance:
     210             :          * - Make the content type lowercase
     211             :          * - Trim descriptive data, stay with the content-type only
     212             :          */
     213        2047 :         for (p=content_type; p<content_type+content_type_length; p++) {
     214        1972 :                 switch (*p) {
     215             :                         case ';':
     216             :                         case ',':
     217             :                         case ' ':
     218          36 :                                 content_type_length = p-content_type;
     219          36 :                                 oldchar = *p;
     220          36 :                                 *p = 0;
     221          36 :                                 break;
     222             :                         default:
     223        1936 :                                 *p = tolower(*p);
     224             :                                 break;
     225             :                 }
     226             :         }
     227             : 
     228             :         /* now try to find an appropriate POST content handler */
     229          75 :         if (zend_hash_find(&SG(known_post_content_types), content_type,
     230             :                         content_type_length+1, (void **) &post_entry) == SUCCESS) {
     231             :                 /* found one, register it for use */
     232          74 :                 SG(request_info).post_entry = post_entry;
     233          74 :                 post_reader_func = post_entry->post_reader;
     234             :         } else {
     235             :                 /* fallback */
     236           1 :                 SG(request_info).post_entry = NULL;
     237           1 :                 if (!sapi_module.default_post_reader) {
     238             :                         /* no default reader ? */
     239           0 :                         SG(request_info).content_type_dup = NULL;
     240           0 :                         sapi_module.sapi_error(E_WARNING, "Unsupported content type:  '%s'", content_type);
     241           0 :                         return;
     242             :                 }
     243             :         }
     244          75 :         if (oldchar) {
     245          36 :                 *(p-1) = oldchar;
     246             :         }
     247             : 
     248          75 :         SG(request_info).content_type_dup = content_type;
     249             : 
     250          75 :         if(post_reader_func) {
     251          37 :                 post_reader_func(TSRMLS_C);
     252             :         }
     253             : 
     254          75 :         if(sapi_module.default_post_reader) {
     255          75 :                 sapi_module.default_post_reader(TSRMLS_C);
     256             :         }
     257             : }
     258             : 
     259             : 
     260          38 : SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data)
     261             : {
     262             :         int read_bytes;
     263          38 :         int allocated_bytes=SAPI_POST_BLOCK_SIZE+1;
     264             : 
     265          38 :         if ((SG(post_max_size) > 0) && (SG(request_info).content_length > SG(post_max_size))) {
     266           1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "POST Content-Length of %ld bytes exceeds the limit of %ld bytes",
     267             :                                         SG(request_info).content_length, SG(post_max_size));
     268           1 :                 return;
     269             :         }
     270          37 :         SG(request_info).post_data = emalloc(allocated_bytes);
     271             : 
     272             :         for (;;) {
     273          37 :                 read_bytes = sapi_module.read_post(SG(request_info).post_data+SG(read_post_bytes), SAPI_POST_BLOCK_SIZE TSRMLS_CC);
     274          37 :                 if (read_bytes<=0) {
     275           0 :                         break;
     276             :                 }
     277          37 :                 SG(read_post_bytes) += read_bytes;
     278          37 :                 if ((SG(post_max_size) > 0) && (SG(read_post_bytes) > SG(post_max_size))) {
     279           0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Actual POST length does not match Content-Length, and exceeds %ld bytes", SG(post_max_size));
     280           0 :                         break;
     281             :                 }
     282          37 :                 if (read_bytes < SAPI_POST_BLOCK_SIZE) {
     283          37 :                         break;
     284             :                 }
     285           0 :                 if (SG(read_post_bytes)+SAPI_POST_BLOCK_SIZE >= allocated_bytes) {
     286           0 :                         allocated_bytes = SG(read_post_bytes)+SAPI_POST_BLOCK_SIZE+1;
     287           0 :                         SG(request_info).post_data = erealloc(SG(request_info).post_data, allocated_bytes);
     288             :                 }
     289           0 :         }
     290          37 :         SG(request_info).post_data[SG(read_post_bytes)] = 0;  /* terminating NULL */
     291          37 :         SG(request_info).post_data_length = SG(read_post_bytes);
     292             : }
     293             : 
     294             : 
     295       19870 : static inline char *get_default_content_type(uint prefix_len, uint *len TSRMLS_DC)
     296             : {
     297             :         char *mimetype, *charset, *content_type;
     298             :         uint mimetype_len, charset_len;
     299             : 
     300       19870 :         if (SG(default_mimetype)) {
     301       19870 :                 mimetype = SG(default_mimetype);
     302       19870 :                 mimetype_len = strlen(SG(default_mimetype));
     303             :         } else {
     304           0 :                 mimetype = SAPI_DEFAULT_MIMETYPE;
     305           0 :                 mimetype_len = sizeof(SAPI_DEFAULT_MIMETYPE) - 1;
     306             :         }
     307       19870 :         if (SG(default_charset)) {
     308       19870 :                 charset = SG(default_charset);
     309       19870 :                 charset_len = strlen(SG(default_charset));
     310             :         } else {
     311           0 :                 charset = SAPI_DEFAULT_CHARSET;
     312           0 :                 charset_len = sizeof(SAPI_DEFAULT_CHARSET) - 1;
     313             :         }
     314             : 
     315       19992 :         if (*charset && strncasecmp(mimetype, "text/", 5) == 0) {
     316             :                 char *p;
     317             : 
     318         122 :                 *len = prefix_len + mimetype_len + sizeof("; charset=") - 1 + charset_len;
     319         122 :                 content_type = (char*)emalloc(*len + 1);
     320         122 :                 p = content_type + prefix_len;
     321         122 :                 memcpy(p, mimetype, mimetype_len);
     322         122 :                 p += mimetype_len;
     323         122 :                 memcpy(p, "; charset=", sizeof("; charset=") - 1);
     324         122 :                 p += sizeof("; charset=") - 1;
     325         122 :                 memcpy(p, charset, charset_len + 1);
     326             :         } else {
     327       19748 :                 *len = prefix_len + mimetype_len;
     328       19748 :                 content_type = (char*)emalloc(*len + 1);
     329       19748 :                 memcpy(content_type + prefix_len, mimetype, mimetype_len + 1);
     330             :         }
     331       19870 :         return content_type;
     332             : }
     333             : 
     334             : 
     335           0 : SAPI_API char *sapi_get_default_content_type(TSRMLS_D)
     336             : {
     337             :         uint len;
     338             : 
     339           0 :         return get_default_content_type(0, &len TSRMLS_CC);
     340             : }
     341             : 
     342             : 
     343           0 : SAPI_API void sapi_get_default_content_type_header(sapi_header_struct *default_header TSRMLS_DC)
     344             : {
     345             :     uint len;
     346             : 
     347           0 :         default_header->header = get_default_content_type(sizeof("Content-type: ")-1, &len TSRMLS_CC);
     348           0 :         default_header->header_len = len;
     349           0 :         memcpy(default_header->header, "Content-type: ", sizeof("Content-type: ") - 1);
     350           0 : }
     351             : 
     352             : /*
     353             :  * Add charset on content-type header if the MIME type starts with
     354             :  * "text/", the default_charset directive is not empty and
     355             :  * there is not already a charset option in there.
     356             :  *
     357             :  * If "mimetype" is non-NULL, it should point to a pointer allocated
     358             :  * with emalloc().  If a charset is added, the string will be
     359             :  * re-allocated and the new length is returned.  If mimetype is
     360             :  * unchanged, 0 is returned.
     361             :  *
     362             :  */
     363         192 : SAPI_API size_t sapi_apply_default_charset(char **mimetype, size_t len TSRMLS_DC)
     364             : {
     365             :         char *charset, *newtype;
     366             :         size_t newlen;
     367         192 :         charset = SG(default_charset) ? SG(default_charset) : SAPI_DEFAULT_CHARSET;
     368             : 
     369         192 :         if (*mimetype != NULL) {
     370         192 :                 if (*charset && strncmp(*mimetype, "text/", 5) == 0 && strstr(*mimetype, "charset=") == NULL) {
     371           4 :                         newlen = len + (sizeof(";charset=")-1) + strlen(charset);
     372           4 :                         newtype = emalloc(newlen + 1);
     373           4 :                         PHP_STRLCPY(newtype, *mimetype, newlen + 1, len);
     374           4 :                         strlcat(newtype, ";charset=", newlen + 1);
     375           4 :                         strlcat(newtype, charset, newlen + 1);
     376           4 :                         efree(*mimetype);
     377           4 :                         *mimetype = newtype;
     378           4 :                         return newlen;
     379             :                 }
     380             :         }
     381         188 :         return 0;
     382             : }
     383             : 
     384           0 : SAPI_API void sapi_activate_headers_only(TSRMLS_D)
     385             : {
     386           0 :         if (SG(request_info).headers_read == 1)
     387           0 :                 return;
     388           0 :         SG(request_info).headers_read = 1;
     389           0 :         zend_llist_init(&SG(sapi_headers).headers, sizeof(sapi_header_struct), 
     390             :                         (void (*)(void *)) sapi_free_header, 0);
     391           0 :         SG(sapi_headers).send_default_content_type = 1;
     392             : 
     393             :         /* SG(sapi_headers).http_response_code = 200; */ 
     394           0 :         SG(sapi_headers).http_status_line = NULL;
     395           0 :         SG(sapi_headers).mimetype = NULL;
     396           0 :         SG(read_post_bytes) = 0;
     397           0 :         SG(request_info).post_data = NULL;
     398           0 :         SG(request_info).raw_post_data = NULL;
     399           0 :         SG(request_info).current_user = NULL;
     400           0 :         SG(request_info).current_user_length = 0;
     401           0 :         SG(request_info).no_headers = 0;
     402           0 :         SG(request_info).post_entry = NULL;
     403           0 :         SG(global_request_time) = 0;
     404             : 
     405             :         /*
     406             :          * It's possible to override this general case in the activate() callback, 
     407             :          * if necessary.
     408             :          */
     409           0 :         if (SG(request_info).request_method && !strcmp(SG(request_info).request_method, "HEAD")) {
     410           0 :                 SG(request_info).headers_only = 1;
     411             :         } else {
     412           0 :                 SG(request_info).headers_only = 0;
     413             :         }
     414           0 :         if (SG(server_context)) {
     415           0 :                 SG(request_info).cookie_data = sapi_module.read_cookies(TSRMLS_C);
     416           0 :                 if (sapi_module.activate) {
     417           0 :                         sapi_module.activate(TSRMLS_C);
     418             :                 }
     419             :         }
     420           0 :         if (sapi_module.input_filter_init ) {
     421           0 :                 sapi_module.input_filter_init(TSRMLS_C);
     422             :         }
     423             : }
     424             : 
     425             : /*
     426             :  * Called from php_request_startup() for every request.
     427             :  */
     428             : 
     429       40407 : SAPI_API void sapi_activate(TSRMLS_D)
     430             : {
     431       40407 :         zend_llist_init(&SG(sapi_headers).headers, sizeof(sapi_header_struct), (void (*)(void *)) sapi_free_header, 0);
     432       40407 :         SG(sapi_headers).send_default_content_type = 1;
     433             : 
     434             :         /*
     435             :         SG(sapi_headers).http_response_code = 200;
     436             :         */
     437       40407 :         SG(sapi_headers).http_status_line = NULL;
     438       40407 :         SG(sapi_headers).mimetype = NULL;
     439       40407 :         SG(headers_sent) = 0;
     440       40407 :         SG(callback_run) = 0;
     441       40407 :         SG(callback_func) = NULL;
     442       40407 :         SG(read_post_bytes) = 0;
     443       40407 :         SG(request_info).post_data = NULL;
     444       40407 :         SG(request_info).raw_post_data = NULL;
     445       40407 :         SG(request_info).current_user = NULL;
     446       40407 :         SG(request_info).current_user_length = 0;
     447       40407 :         SG(request_info).no_headers = 0;
     448       40407 :         SG(request_info).post_entry = NULL;
     449       40407 :         SG(request_info).proto_num = 1000; /* Default to HTTP 1.0 */
     450       40407 :         SG(global_request_time) = 0;
     451             : 
     452             :         /* It's possible to override this general case in the activate() callback, if necessary. */
     453       40407 :         if (SG(request_info).request_method && !strcmp(SG(request_info).request_method, "HEAD")) {
     454           0 :                 SG(request_info).headers_only = 1;
     455             :         } else {
     456       40407 :                 SG(request_info).headers_only = 0;
     457             :         }
     458       40407 :         SG(rfc1867_uploaded_files) = NULL;
     459             : 
     460             :         /* Handle request method */
     461       40407 :         if (SG(server_context)) {
     462         611 :                 if (PG(enable_post_data_reading) && SG(request_info).request_method) {
     463         283 :                         if (SG(request_info).content_type && !strcmp(SG(request_info).request_method, "POST")) {
     464             :                                 /* HTTP POST may contain form data to be processed into variables
     465             :                                  * depending on given content type */
     466          75 :                                 sapi_read_post_data(TSRMLS_C);
     467             :                         } else {
     468             :                                 /* Any other method with content payload will fill $HTTP_RAW_POST_DATA 
     469             :                                  * if it is enabled by always_populate_raw_post_data. 
     470             :                                  * It's up to the webserver to decide whether to allow a method or not. */
     471         133 :                                 SG(request_info).content_type_dup = NULL;
     472         133 :                                 if (sapi_module.default_post_reader) {
     473         133 :                                         sapi_module.default_post_reader(TSRMLS_C);
     474             :                                 }
     475             :                         }
     476             :                 } else {
     477         195 :                         SG(request_info).content_type_dup = NULL;
     478             :                 }
     479             : 
     480             :                 /* Cookies */
     481         403 :                 SG(request_info).cookie_data = sapi_module.read_cookies(TSRMLS_C);
     482             : 
     483         403 :                 if (sapi_module.activate) {
     484         403 :                         sapi_module.activate(TSRMLS_C);
     485             :                 }
     486             :         }
     487       40407 :         if (sapi_module.input_filter_init) {
     488       20182 :                 sapi_module.input_filter_init(TSRMLS_C);
     489             :         }
     490       40407 : }
     491             : 
     492             : 
     493       60537 : static void sapi_send_headers_free(TSRMLS_D)
     494             : {
     495       60537 :         if (SG(sapi_headers).http_status_line) {
     496         156 :                 efree(SG(sapi_headers).http_status_line);
     497         156 :                 SG(sapi_headers).http_status_line = NULL;
     498             :         }
     499       60537 : }
     500             :         
     501       40486 : SAPI_API void sapi_deactivate(TSRMLS_D)
     502             : {
     503       40486 :         zend_llist_destroy(&SG(sapi_headers).headers);
     504       40486 :         if (SG(request_info).post_data) {
     505           1 :                 efree(SG(request_info).post_data);
     506       40485 :         }  else         if (SG(server_context)) {
     507         399 :                 if(sapi_module.read_post) { 
     508             :                         /* make sure we've consumed all request input data */
     509             :                         char dummy[SAPI_POST_BLOCK_SIZE];
     510             :                         int read_bytes;
     511             : 
     512         802 :                         while((read_bytes = sapi_module.read_post(dummy, sizeof(dummy)-1 TSRMLS_CC)) > 0) {
     513           4 :                                 SG(read_post_bytes) += read_bytes;
     514             :                         }
     515             :                 }
     516             :         }
     517       40486 :         if (SG(request_info).raw_post_data) {
     518          37 :                 efree(SG(request_info).raw_post_data);
     519             :         } 
     520       40486 :         if (SG(request_info).auth_user) {
     521           0 :                 efree(SG(request_info).auth_user);
     522             :         }
     523       40486 :         if (SG(request_info).auth_password) {
     524           0 :                 efree(SG(request_info).auth_password);
     525             :         }
     526       40486 :         if (SG(request_info).auth_digest) {
     527           0 :                 efree(SG(request_info).auth_digest);
     528             :         }
     529       40486 :         if (SG(request_info).content_type_dup) {
     530           2 :                 efree(SG(request_info).content_type_dup);
     531             :         }
     532       40486 :         if (SG(request_info).current_user) {
     533           9 :                 efree(SG(request_info).current_user);
     534             :         }
     535       40486 :         if (sapi_module.deactivate) {
     536       40486 :                 sapi_module.deactivate(TSRMLS_C);
     537             :         }
     538       40486 :         if (SG(rfc1867_uploaded_files)) {
     539          34 :                 destroy_uploaded_files_hash(TSRMLS_C);
     540             :         }
     541       40486 :         if (SG(sapi_headers).mimetype) {
     542       20054 :                 efree(SG(sapi_headers).mimetype);
     543       20054 :                 SG(sapi_headers).mimetype = NULL;
     544             :         }
     545       40486 :         sapi_send_headers_free(TSRMLS_C);
     546       40486 :         SG(sapi_started) = 0;
     547       40486 :         SG(headers_sent) = 0;
     548       40486 :         SG(callback_run) = 0;
     549       40486 :         if (SG(callback_func)) {
     550           0 :                 zval_ptr_dtor(&SG(callback_func));
     551             :         }
     552       40486 :         SG(request_info).headers_read = 0;
     553       40486 :         SG(global_request_time) = 0;
     554       40486 : }
     555             : 
     556             : 
     557       20225 : SAPI_API void sapi_initialize_empty_request(TSRMLS_D)
     558             : {
     559       20225 :         SG(server_context) = NULL;
     560       20225 :         SG(request_info).request_method = NULL;
     561       20225 :         SG(request_info).auth_digest = SG(request_info).auth_user = SG(request_info).auth_password = NULL;
     562       20225 :         SG(request_info).content_type_dup = NULL;
     563       20225 : }
     564             : 
     565             : 
     566         157 : static int sapi_extract_response_code(const char *header_line)
     567             : {
     568         157 :         int code = 200;
     569             :         const char *ptr;
     570             : 
     571        1413 :         for (ptr = header_line; *ptr; ptr++) {
     572        1413 :                 if (*ptr == ' ' && *(ptr + 1) != ' ') {
     573         157 :                         code = atoi(ptr + 1);
     574         157 :                         break;
     575             :                 }
     576             :         }
     577             :         
     578         157 :         return code;
     579             : }
     580             : 
     581             : 
     582         164 : static void sapi_update_response_code(int ncode TSRMLS_DC)
     583             : {
     584             :         /* if the status code did not change, we do not want
     585             :            to change the status line, and no need to change the code */
     586         164 :         if (SG(sapi_headers).http_response_code == ncode) {
     587           2 :                 return;
     588             :         }
     589             : 
     590         162 :         if (SG(sapi_headers).http_status_line) {
     591           1 :                 efree(SG(sapi_headers).http_status_line);
     592           1 :                 SG(sapi_headers).http_status_line = NULL;
     593             :         }
     594         162 :         SG(sapi_headers).http_response_code = ncode;
     595             : }
     596             : 
     597             : /* 
     598             :  * since zend_llist_del_element only remove one matched item once,
     599             :  * we should remove them by ourself
     600             :  */
     601         535 : static void sapi_remove_header(zend_llist *l, char *name, uint len) {
     602             :         sapi_header_struct *header;
     603             :         zend_llist_element *next;
     604         535 :         zend_llist_element *current=l->head;
     605             : 
     606        1276 :         while (current) {
     607         206 :                 header = (sapi_header_struct *)(current->data);
     608         206 :                 next = current->next;
     609         240 :                 if (header->header_len > len && header->header[len] == ':'
     610          34 :                                 && !strncasecmp(header->header, name, len)) {
     611           4 :                         if (current->prev) {
     612           4 :                                 current->prev->next = next;
     613             :                         } else {
     614           0 :                                 l->head = next;
     615             :                         }
     616           4 :                         if (next) {
     617           2 :                                 next->prev = current->prev;
     618             :                         } else {
     619           2 :                                 l->tail = current->prev;
     620             :                         }
     621           4 :                         sapi_free_header(header);
     622           4 :                         efree(current);
     623           4 :                         --l->count;
     624             :                 }
     625         206 :                 current = next;
     626             :         }
     627         535 : }
     628             : 
     629       22270 : SAPI_API int sapi_add_header_ex(char *header_line, uint header_line_len, zend_bool duplicate, zend_bool replace TSRMLS_DC)
     630             : {
     631       22270 :         sapi_header_line ctr = {0};
     632             :         int r;
     633             :         
     634       22270 :         ctr.line = header_line;
     635       22270 :         ctr.line_len = header_line_len;
     636             : 
     637       22270 :         r = sapi_header_op(replace ? SAPI_HEADER_REPLACE : SAPI_HEADER_ADD,
     638             :                         &ctr TSRMLS_CC);
     639             : 
     640       22270 :         if (!duplicate)
     641         265 :                 efree(header_line);
     642             : 
     643       22270 :         return r;
     644             : }
     645             : 
     646       41569 : static void sapi_header_add_op(sapi_header_op_enum op, sapi_header_struct *sapi_header TSRMLS_DC)
     647             : {
     648       83138 :         if (!sapi_module.header_handler ||
     649       40814 :                 (SAPI_HEADER_ADD & sapi_module.header_handler(sapi_header, op, &SG(sapi_headers) TSRMLS_CC))) {
     650         755 :                 if (op == SAPI_HEADER_REPLACE) {
     651         532 :                         char *colon_offset = strchr(sapi_header->header, ':');
     652             : 
     653         532 :                         if (colon_offset) {
     654         532 :                                 char sav = *colon_offset;
     655             : 
     656         532 :                                 *colon_offset = 0;
     657         532 :                         sapi_remove_header(&SG(sapi_headers).headers, sapi_header->header, strlen(sapi_header->header));
     658         532 :                                 *colon_offset = sav;
     659             :                         }
     660             :                 }
     661         755 :                 zend_llist_add_element(&SG(sapi_headers).headers, (void *) sapi_header);
     662             :         } else {
     663       40814 :                 sapi_free_header(sapi_header);
     664             :         }
     665       41569 : }
     666             : 
     667       22423 : SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC)
     668             : {
     669             :         sapi_header_struct sapi_header;
     670             :         char *colon_offset;
     671             :         char *header_line;
     672             :         uint header_line_len;
     673             :         int http_response_code;
     674             : 
     675       22423 :         if (SG(headers_sent) && !SG(request_info).no_headers) {
     676         554 :                 const char *output_start_filename = php_output_get_start_filename(TSRMLS_C);
     677         554 :                 int output_start_lineno = php_output_get_start_lineno(TSRMLS_C);
     678             : 
     679         554 :                 if (output_start_filename) {
     680         553 :                         sapi_module.sapi_error(E_WARNING, "Cannot modify header information - headers already sent by (output started at %s:%d)",
     681             :                                 output_start_filename, output_start_lineno);
     682             :                 } else {
     683           1 :                         sapi_module.sapi_error(E_WARNING, "Cannot modify header information - headers already sent");
     684             :                 }
     685         554 :                 return FAILURE;
     686             :         }
     687             : 
     688       21869 :         switch (op) {
     689             :                 case SAPI_HEADER_SET_STATUS:
     690           0 :                         sapi_update_response_code((int)(zend_intptr_t) arg TSRMLS_CC);
     691           0 :                         return SUCCESS;
     692             : 
     693             :                 case SAPI_HEADER_ADD:
     694             :                 case SAPI_HEADER_REPLACE:
     695             :                 case SAPI_HEADER_DELETE: {
     696       21867 :                                 sapi_header_line *p = arg;
     697             : 
     698       21867 :                                 if (!p->line || !p->line_len) {
     699           1 :                                         return FAILURE;
     700             :                                 }
     701       21866 :                                 header_line = p->line;
     702       21866 :                                 header_line_len = p->line_len;
     703       21866 :                                 http_response_code = p->response_code;
     704       21866 :                                 break;
     705             :                         }
     706             : 
     707             :                 case SAPI_HEADER_DELETE_ALL:
     708           2 :                         if (sapi_module.header_handler) {
     709           0 :                                 sapi_module.header_handler(&sapi_header, op, &SG(sapi_headers) TSRMLS_CC);
     710             :                         }
     711           2 :                         zend_llist_clean(&SG(sapi_headers).headers);
     712           2 :                         return SUCCESS;
     713             : 
     714             :                 default:
     715           0 :                         return FAILURE;
     716             :         }
     717             : 
     718       21866 :         header_line = estrndup(header_line, header_line_len);
     719             : 
     720             :         /* cut off trailing spaces, linefeeds and carriage-returns */
     721       21866 :         if (header_line_len && isspace(header_line[header_line_len-1])) {
     722             :                 do {
     723           7 :                         header_line_len--;
     724           7 :                 } while(header_line_len && isspace(header_line[header_line_len-1]));
     725           3 :                 header_line[header_line_len]='\0';
     726             :         }
     727             :         
     728       21866 :         if (op == SAPI_HEADER_DELETE) {
     729           6 :                 if (strchr(header_line, ':')) {
     730           3 :                         efree(header_line);
     731           3 :                         sapi_module.sapi_error(E_WARNING, "Header to delete may not contain colon.");
     732           3 :                         return FAILURE;
     733             :                 }
     734           3 :                 if (sapi_module.header_handler) {
     735           0 :                         sapi_header.header = header_line;
     736           0 :                         sapi_header.header_len = header_line_len;
     737           0 :                         sapi_module.header_handler(&sapi_header, op, &SG(sapi_headers) TSRMLS_CC);
     738             :                 }
     739           3 :                 sapi_remove_header(&SG(sapi_headers).headers, header_line, header_line_len);
     740           3 :                 efree(header_line);
     741           3 :                 return SUCCESS;
     742             :         } else {
     743             :                 /* new line/NUL character safety check */
     744             :                 int i;
     745      653655 :                 for (i = 0; i < header_line_len; i++) {
     746             :                         /* RFC 2616 allows new lines if followed by SP or HT */
     747             :                         int illegal_break =
     748     1845658 :                                         (header_line[i+1] != ' ' && header_line[i+1] != '\t')
     749             :                                         && (
     750      606928 :                                                 header_line[i] == '\n'
     751     1238730 :                                                 || (header_line[i] == '\r' && header_line[i+1] != '\n'));
     752      631799 :                         if (illegal_break) {
     753           3 :                                 efree(header_line);
     754           3 :                                 sapi_module.sapi_error(E_WARNING, "Header may not contain "
     755             :                                                 "more than a single header, new line detected");
     756           3 :                                 return FAILURE;
     757             :                         }
     758      631796 :                         if (header_line[i] == '\0') {
     759           1 :                                 efree(header_line);
     760           1 :                                 sapi_module.sapi_error(E_WARNING, "Header may not contain NUL bytes");
     761           1 :                                 return FAILURE;
     762             :                         }
     763             :                 }
     764             :         }
     765             : 
     766       21856 :         sapi_header.header = header_line;
     767       21856 :         sapi_header.header_len = header_line_len;
     768             : 
     769             :         /* Check the header for a few cases that we have special support for in SAPI */
     770       43712 :         if (header_line_len>=5 
     771       21856 :                 && !strncasecmp(header_line, "HTTP/", 5)) {
     772             :                 /* filter out the response code */
     773         157 :                 sapi_update_response_code(sapi_extract_response_code(header_line) TSRMLS_CC);
     774             :                 /* sapi_update_response_code doesn't free the status line if the code didn't change */
     775         157 :                 if (SG(sapi_headers).http_status_line) {
     776           0 :                         efree(SG(sapi_headers).http_status_line);
     777             :                 }
     778         157 :                 SG(sapi_headers).http_status_line = header_line;
     779         157 :                 return SUCCESS;
     780             :         } else {
     781       21699 :                 colon_offset = strchr(header_line, ':');
     782       21699 :                 if (colon_offset) {
     783       21698 :                         *colon_offset = 0;
     784       21698 :                         if (!STRCASECMP(header_line, "Content-Type")) {
     785         192 :                                 char *ptr = colon_offset+1, *mimetype = NULL, *newheader;
     786         192 :                                 size_t len = header_line_len - (ptr - header_line), newlen;
     787         574 :                                 while (*ptr == ' ') {
     788         190 :                                         ptr++;
     789         190 :                                         len--;
     790             :                                 }
     791             : 
     792             :                                 /* Disable possible output compression for images */
     793         192 :                                 if (!strncmp(ptr, "image/", sizeof("image/")-1)) {
     794           4 :                                         zend_alter_ini_entry("zlib.output_compression", sizeof("zlib.output_compression"), "0", sizeof("0") - 1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
     795             :                                 }
     796             : 
     797         192 :                                 mimetype = estrdup(ptr);
     798         192 :                                 newlen = sapi_apply_default_charset(&mimetype, len TSRMLS_CC);
     799         192 :                                 if (!SG(sapi_headers).mimetype){
     800         181 :                                         SG(sapi_headers).mimetype = estrdup(mimetype);
     801             :                                 }
     802             : 
     803         192 :                                 if (newlen != 0) {
     804           4 :                                         newlen += sizeof("Content-type: ");
     805           4 :                                         newheader = emalloc(newlen);
     806           4 :                                         PHP_STRLCPY(newheader, "Content-type: ", newlen, sizeof("Content-type: ")-1);
     807           4 :                                         strlcat(newheader, mimetype, newlen);
     808           4 :                                         sapi_header.header = newheader;
     809           4 :                                         sapi_header.header_len = newlen - 1;
     810           4 :                                         efree(header_line);
     811             :                                 }
     812         192 :                                 efree(mimetype);
     813         192 :                                 SG(sapi_headers).send_default_content_type = 0;
     814       21506 :                         } else if (!STRCASECMP(header_line, "Content-Length")) {
     815             :                                 /* Script is setting Content-length. The script cannot reasonably
     816             :                                  * know the size of the message body after compression, so it's best
     817             :                                  * do disable compression altogether. This contributes to making scripts
     818             :                                  * portable between setups that have and don't have zlib compression
     819             :                                  * enabled globally. See req #44164 */
     820         244 :                                 zend_alter_ini_entry("zlib.output_compression", sizeof("zlib.output_compression"),
     821             :                                         "0", sizeof("0") - 1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
     822       21262 :                         } else if (!STRCASECMP(header_line, "Location")) {
     823          53 :                                 if ((SG(sapi_headers).http_response_code < 300 ||
     824          22 :                                         SG(sapi_headers).http_response_code > 399) &&
     825           5 :                                         SG(sapi_headers).http_response_code != 201) {
     826             :                                         /* Return a Found Redirect if one is not already specified */
     827           4 :                                         if (http_response_code) { /* user specified redirect code */
     828           2 :                                                 sapi_update_response_code(http_response_code TSRMLS_CC);
     829           2 :                                         } else if (SG(request_info).proto_num > 1000 && 
     830           0 :                                            SG(request_info).request_method && 
     831           0 :                                            strcmp(SG(request_info).request_method, "HEAD") &&
     832           0 :                                            strcmp(SG(request_info).request_method, "GET")) {
     833           0 :                                                 sapi_update_response_code(303 TSRMLS_CC);
     834             :                                         } else {
     835           2 :                                                 sapi_update_response_code(302 TSRMLS_CC);
     836             :                                         }
     837             :                                 }
     838       21236 :                         } else if (!STRCASECMP(header_line, "WWW-Authenticate")) { /* HTTP Authentication */
     839           0 :                                 sapi_update_response_code(401 TSRMLS_CC); /* authentication-required */
     840             :                         }
     841       21698 :                         if (sapi_header.header==header_line) {
     842       21694 :                                 *colon_offset = ':';
     843             :                         }
     844             :                 }
     845             :         }
     846       21699 :         if (http_response_code) {
     847           3 :                 sapi_update_response_code(http_response_code TSRMLS_CC);
     848             :         }
     849       21699 :         sapi_header_add_op(op, &sapi_header TSRMLS_CC);
     850       21699 :         return SUCCESS;
     851             : }
     852             : 
     853             : 
     854       20051 : SAPI_API int sapi_send_headers(TSRMLS_D)
     855             : {
     856             :         int retval;
     857       20051 :         int ret = FAILURE;
     858             : 
     859       20051 :         if (SG(headers_sent) || SG(request_info).no_headers || SG(callback_run)) {
     860           0 :                 return SUCCESS;
     861             :         }
     862             : 
     863             :         /* Success-oriented.  We set headers_sent to 1 here to avoid an infinite loop
     864             :          * in case of an error situation.
     865             :          */
     866       20051 :         if (SG(sapi_headers).send_default_content_type && sapi_module.send_headers) {
     867             :                 sapi_header_struct default_header;
     868             :             uint len;
     869             : 
     870       19870 :                 SG(sapi_headers).mimetype = get_default_content_type(0, &len TSRMLS_CC);
     871       19870 :                 default_header.header_len = sizeof("Content-type: ") - 1 + len;
     872       19870 :                 default_header.header = emalloc(default_header.header_len + 1);
     873       19870 :                 memcpy(default_header.header, "Content-type: ", sizeof("Content-type: ") - 1);
     874       19870 :                 memcpy(default_header.header + sizeof("Content-type: ") - 1, SG(sapi_headers).mimetype, len + 1);
     875       19870 :                 sapi_header_add_op(SAPI_HEADER_ADD, &default_header TSRMLS_CC);
     876       19870 :                 SG(sapi_headers).send_default_content_type = 0;
     877             :         }
     878             : 
     879       20051 :         if (SG(callback_func) && !SG(callback_run)) {
     880           0 :                 SG(callback_run) = 1;
     881           0 :                 sapi_run_header_callback(TSRMLS_C);
     882             :         }
     883             : 
     884       20051 :         SG(headers_sent) = 1;
     885             : 
     886       20051 :         if (sapi_module.send_headers) {
     887       20051 :                 retval = sapi_module.send_headers(&SG(sapi_headers) TSRMLS_CC);
     888             :         } else {
     889           0 :                 retval = SAPI_HEADER_DO_SEND;
     890             :         }
     891             : 
     892       20051 :         switch (retval) {
     893             :                 case SAPI_HEADER_SENT_SUCCESSFULLY:
     894       20051 :                         ret = SUCCESS;
     895       20051 :                         break;
     896             :                 case SAPI_HEADER_DO_SEND: {
     897             :                                 sapi_header_struct http_status_line;
     898             :                                 char buf[255];
     899             : 
     900           0 :                                 if (SG(sapi_headers).http_status_line) {
     901           0 :                                         http_status_line.header = SG(sapi_headers).http_status_line;
     902           0 :                                         http_status_line.header_len = strlen(SG(sapi_headers).http_status_line);
     903             :                                 } else {
     904           0 :                                         http_status_line.header = buf;
     905           0 :                                         http_status_line.header_len = slprintf(buf, sizeof(buf), "HTTP/1.0 %d X", SG(sapi_headers).http_response_code);
     906             :                                 }
     907           0 :                                 sapi_module.send_header(&http_status_line, SG(server_context) TSRMLS_CC);
     908             :                         }
     909           0 :                         zend_llist_apply_with_argument(&SG(sapi_headers).headers, (llist_apply_with_arg_func_t) sapi_module.send_header, SG(server_context) TSRMLS_CC);
     910           0 :                         if(SG(sapi_headers).send_default_content_type) {
     911             :                                 sapi_header_struct default_header;
     912             : 
     913           0 :                                 sapi_get_default_content_type_header(&default_header TSRMLS_CC);
     914           0 :                                 sapi_module.send_header(&default_header, SG(server_context) TSRMLS_CC);
     915           0 :                                 sapi_free_header(&default_header);
     916             :                         }
     917           0 :                         sapi_module.send_header(NULL, SG(server_context) TSRMLS_CC);
     918           0 :                         ret = SUCCESS;
     919           0 :                         break;
     920             :                 case SAPI_HEADER_SEND_FAILED:
     921           0 :                         SG(headers_sent) = 0;
     922           0 :                         ret = FAILURE;
     923             :                         break;
     924             :         }
     925             : 
     926       20051 :         sapi_send_headers_free(TSRMLS_C);
     927             : 
     928       20051 :         return ret;
     929             : }
     930             : 
     931             : 
     932       40464 : SAPI_API int sapi_register_post_entries(sapi_post_entry *post_entries TSRMLS_DC)
     933             : {
     934       40464 :         sapi_post_entry *p=post_entries;
     935             : 
     936      141603 :         while (p->content_type) {
     937       80914 :                 if (sapi_register_post_entry(p TSRMLS_CC) == FAILURE) {
     938       20239 :                         return FAILURE;
     939             :                 }
     940       60675 :                 p++;
     941             :         }
     942       20225 :         return SUCCESS;
     943             : }
     944             : 
     945             : 
     946       80914 : SAPI_API int sapi_register_post_entry(sapi_post_entry *post_entry TSRMLS_DC)
     947             : {
     948       80914 :         if (SG(sapi_started) && EG(in_execution)) {
     949           0 :                 return FAILURE;
     950             :         }
     951       80914 :         return zend_hash_add(&SG(known_post_content_types),
     952             :                         post_entry->content_type, post_entry->content_type_len+1,
     953             :                         (void *) post_entry, sizeof(sapi_post_entry), NULL);
     954             : }
     955             : 
     956       20225 : SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry TSRMLS_DC)
     957             : {
     958       20225 :         if (SG(sapi_started) && EG(in_execution)) {
     959           0 :                 return;
     960             :         }
     961       20225 :         zend_hash_del(&SG(known_post_content_types), post_entry->content_type,
     962             :                         post_entry->content_type_len+1);
     963             : }
     964             : 
     965             : 
     966       20225 : SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D) TSRMLS_DC)
     967             : {
     968       20225 :         if (SG(sapi_started) && EG(in_execution)) {
     969           0 :                 return FAILURE;
     970             :         }
     971       20225 :         sapi_module.default_post_reader = default_post_reader;
     972       20225 :         return SUCCESS;
     973             : }
     974             : 
     975             : 
     976       40450 : SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC) TSRMLS_DC)
     977             : {
     978       40450 :         if (SG(sapi_started) && EG(in_execution)) {
     979           0 :                 return FAILURE;
     980             :         }
     981       40450 :         sapi_module.treat_data = treat_data;
     982       40450 :         return SUCCESS;
     983             : }
     984             : 
     985       40450 : SAPI_API int sapi_register_input_filter(unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC), unsigned int (*input_filter_init)(TSRMLS_D) TSRMLS_DC)
     986             : {
     987       40450 :         if (SG(sapi_started) && EG(in_execution)) {
     988           0 :                 return FAILURE;
     989             :         }
     990       40450 :         sapi_module.input_filter = input_filter;
     991       40450 :         sapi_module.input_filter_init = input_filter_init;
     992       40450 :         return SUCCESS;
     993             : }
     994             : 
     995      957710 : SAPI_API int sapi_flush(TSRMLS_D)
     996             : {
     997      957710 :         if (sapi_module.flush) {
     998      957710 :                 sapi_module.flush(SG(server_context));
     999      957710 :                 return SUCCESS;
    1000             :         } else {
    1001           0 :                 return FAILURE;
    1002             :         }
    1003             : }
    1004             : 
    1005          18 : SAPI_API struct stat *sapi_get_stat(TSRMLS_D)
    1006             : {
    1007          18 :         if (sapi_module.get_stat) {
    1008           0 :                 return sapi_module.get_stat(TSRMLS_C);
    1009             :         } else {
    1010          18 :                 if (!SG(request_info).path_translated || (VCWD_STAT(SG(request_info).path_translated, &SG(global_stat)) == -1)) {
    1011           0 :                         return NULL;
    1012             :                 }
    1013          18 :                 return &SG(global_stat);
    1014             :         }
    1015             : }
    1016             : 
    1017       30107 : SAPI_API char *sapi_getenv(char *name, size_t name_len TSRMLS_DC)
    1018             : {
    1019       30107 :         if (sapi_module.getenv) { 
    1020           8 :                 char *value, *tmp = sapi_module.getenv(name, name_len TSRMLS_CC);
    1021           8 :                 if (tmp) {
    1022           8 :                         value = estrdup(tmp);
    1023             :                 } else {
    1024           0 :                         return NULL;
    1025             :                 }
    1026           8 :                 if (sapi_module.input_filter) {
    1027           8 :                         sapi_module.input_filter(PARSE_STRING, name, &value, strlen(value), NULL TSRMLS_CC);
    1028             :                 }
    1029           8 :                 return value;
    1030             :         }
    1031       30099 :         return NULL;
    1032             : }
    1033             : 
    1034           0 : SAPI_API int sapi_get_fd(int *fd TSRMLS_DC)
    1035             : {
    1036           0 :         if (sapi_module.get_fd) {
    1037           0 :                 return sapi_module.get_fd(fd TSRMLS_CC);
    1038             :         } else {
    1039           0 :                 return FAILURE;
    1040             :         }
    1041             : }
    1042             : 
    1043           0 : SAPI_API int sapi_force_http_10(TSRMLS_D)
    1044             : {
    1045           0 :         if (sapi_module.force_http_10) {
    1046           0 :                 return sapi_module.force_http_10(TSRMLS_C);
    1047             :         } else {
    1048           0 :                 return FAILURE;
    1049             :         }
    1050             : }
    1051             : 
    1052             : 
    1053           0 : SAPI_API int sapi_get_target_uid(uid_t *obj TSRMLS_DC)
    1054             : {
    1055           0 :         if (sapi_module.get_target_uid) {
    1056           0 :                 return sapi_module.get_target_uid(obj TSRMLS_CC);
    1057             :         } else {
    1058           0 :                 return FAILURE;
    1059             :         }
    1060             : }
    1061             : 
    1062           0 : SAPI_API int sapi_get_target_gid(gid_t *obj TSRMLS_DC)
    1063             : {
    1064           0 :         if (sapi_module.get_target_gid) {
    1065           0 :                 return sapi_module.get_target_gid(obj TSRMLS_CC);
    1066             :         } else {
    1067           0 :                 return FAILURE;
    1068             :         }
    1069             : }
    1070             : 
    1071       19897 : SAPI_API double sapi_get_request_time(TSRMLS_D)
    1072             : {
    1073       19897 :         if(SG(global_request_time)) return SG(global_request_time);
    1074             : 
    1075       19897 :         if (sapi_module.get_request_time && SG(server_context)) {
    1076           0 :                 SG(global_request_time) = sapi_module.get_request_time(TSRMLS_C);
    1077             :         } else {
    1078       19897 :                 struct timeval tp = {0};
    1079       19897 :                 if (!gettimeofday(&tp, NULL)) {
    1080       19897 :                         SG(global_request_time) = (double)(tp.tv_sec + tp.tv_usec / 1000000.00);
    1081             :                 } else {
    1082           0 :                         SG(global_request_time) = (double)time(0);
    1083             :                 }
    1084             :         }
    1085       19897 :         return SG(global_request_time);
    1086             : }
    1087             : 
    1088           0 : SAPI_API void sapi_terminate_process(TSRMLS_D) {
    1089           0 :         if (sapi_module.terminate_process) {
    1090           0 :                 sapi_module.terminate_process(TSRMLS_C);
    1091             :         }
    1092           0 : }
    1093             : 
    1094             : /*
    1095             :  * Local variables:
    1096             :  * tab-width: 4
    1097             :  * c-basic-offset: 4
    1098             :  * End:
    1099             :  * vim600: sw=4 ts=4 fdm=marker
    1100             :  * vim<600: sw=4 ts=4
    1101             :  */

Generated by: LCOV version 1.10

Generated at Sat, 13 Sep 2014 16:24:39 +0000 (5 days ago)

Copyright © 2005-2014 The PHP Group
All rights reserved.