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: 398 533 74.7 %
Date: 2014-11-22 Functions: 33 43 76.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Sat, 22 Nov 2014 23:01:30 +0000 (3 days ago)

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