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

Generated by: LCOV version 1.10

Generated at Mon, 26 Jan 2015 14:46:59 +0000 (34 hours ago)

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