32#elif defined(PHP_WIN32)
47static void _type_dtor(
zval *
zv)
74 ts_allocate_fast_id(&sapi_globals_id, &sapi_globals_offset,
sizeof(
sapi_globals_struct), (ts_allocate_ctor) sapi_globals_ctor, (ts_allocate_dtor) sapi_globals_dtor);
76 _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
92 ts_free_id(sapi_globals_id);
100 tsrm_win32_shutdown();
139 char *callback_error =
NULL;
147 goto callback_failed;
156 if (callback_error) {
157 efree(callback_error);
163 if (
SG(request_info).post_entry &&
SG(request_info).content_type_dup) {
164 SG(request_info).post_entry->post_handler(
SG(request_info).content_type_dup,
arg);
165 efree(
SG(request_info).content_type_dup);
166 SG(request_info).content_type_dup =
NULL;
173 uint32_t content_type_length = (uint32_t)
strlen(
SG(request_info).content_type);
174 char *content_type =
estrndup(
SG(request_info).content_type, content_type_length);
184 for (
p = content_type;
p < content_type + content_type_length;
p++) {
189 content_type_length =
p-content_type;
200 if ((post_entry = zend_hash_str_find_ptr(&
SG(known_post_content_types), content_type,
201 content_type_length)) !=
NULL) {
203 SG(request_info).post_entry = post_entry;
207 SG(request_info).post_entry =
NULL;
210 SG(request_info).content_type_dup =
NULL;
221 SG(request_info).content_type_dup = content_type;
223 if(post_reader_func) {
242 if (read_bytes > 0) {
244 SG(read_post_bytes) += read_bytes;
246 if (read_bytes < buflen) {
258 if (post_max_size > 0 &&
SG(request_info).content_length > post_max_size) {
260 SG(request_info).content_length, post_max_size);
275 if (read_bytes > 0) {
284 if (post_max_size > 0 &&
SG(read_post_bytes) > post_max_size) {
299static inline char *get_default_content_type(uint32_t prefix_len, uint32_t *
len)
301 char *mimetype, *
charset, *content_type;
302 uint32_t mimetype_len, charset_len;
304 if (
SG(default_mimetype)) {
305 mimetype =
SG(default_mimetype);
306 mimetype_len = (uint32_t)
strlen(
SG(default_mimetype));
311 if (
SG(default_charset)) {
313 charset_len = (uint32_t)
strlen(
SG(default_charset));
322 *
len = prefix_len + mimetype_len +
sizeof(
"; charset=") - 1 + charset_len;
324 p = content_type + prefix_len;
325 p = zend_mempcpy(
p, mimetype, mimetype_len);
326 p = zend_mempcpy(
p,
"; charset=",
sizeof(
"; charset=") - 1);
329 *
len = prefix_len + mimetype_len;
331 memcpy(content_type + prefix_len, mimetype, mimetype_len + 1);
341 return get_default_content_type(0, &
len);
349 default_header->
header = get_default_content_type(
sizeof(
"Content-type: ")-1, &
len);
351 memcpy(default_header->
header,
"Content-type: ",
sizeof(
"Content-type: ") - 1);
371 if (*mimetype !=
NULL) {
376 strlcat(newtype,
";charset=", newlen + 1);
388 if (
SG(request_info).headers_read == 1)
390 SG(request_info).headers_read = 1;
393 SG(sapi_headers).send_default_content_type = 1;
396 SG(sapi_headers).http_status_line =
NULL;
397 SG(sapi_headers).mimetype =
NULL;
398 SG(read_post_bytes) = 0;
399 SG(request_info).request_body =
NULL;
400 SG(request_info).current_user =
NULL;
401 SG(request_info).current_user_length = 0;
402 SG(request_info).no_headers = 0;
403 SG(request_info).post_entry =
NULL;
404 SG(global_request_time) = 0;
410 if (
SG(request_info).request_method && !
strcmp(
SG(request_info).request_method,
"HEAD")) {
411 SG(request_info).headers_only = 1;
413 SG(request_info).headers_only = 0;
415 if (
SG(server_context)) {
433 SG(sapi_headers).send_default_content_type = 1;
438 SG(sapi_headers).http_status_line =
NULL;
439 SG(sapi_headers).mimetype =
NULL;
442 SG(read_post_bytes) = 0;
443 SG(request_info).request_body =
NULL;
444 SG(request_info).current_user =
NULL;
445 SG(request_info).current_user_length = 0;
446 SG(request_info).no_headers = 0;
447 SG(request_info).post_entry =
NULL;
448 SG(request_info).proto_num = 1000;
449 SG(global_request_time) = 0;
452 if (
SG(request_info).request_method && !
strcmp(
SG(request_info).request_method,
"HEAD")) {
453 SG(request_info).headers_only = 1;
455 SG(request_info).headers_only = 0;
457 SG(rfc1867_uploaded_files) =
NULL;
458 SG(request_parse_body_context).throw_exceptions =
false;
459 memset(&
SG(request_parse_body_context).options_cache, 0,
sizeof(
SG(request_parse_body_context).options_cache));
462 if (
SG(server_context)) {
463 if (
PG(enable_post_data_reading)
464 &&
SG(request_info).content_type
465 &&
SG(request_info).request_method
466 && !
strcmp(
SG(request_info).request_method,
"POST")) {
471 SG(request_info).content_type_dup =
NULL;
486static void sapi_send_headers_free(
void)
488 if (
SG(sapi_headers).http_status_line) {
489 efree(
SG(sapi_headers).http_status_line);
490 SG(sapi_headers).http_status_line =
NULL;
497 if (
SG(request_info).request_body) {
498 SG(request_info).request_body =
NULL;
499 }
else if (
SG(server_context)) {
500 if (!
SG(post_read)) {
510 if (
SG(request_info).auth_user) {
511 efree(
SG(request_info).auth_user);
512 SG(request_info).auth_user =
NULL;
514 if (
SG(request_info).auth_password) {
515 efree(
SG(request_info).auth_password);
516 SG(request_info).auth_password =
NULL;
518 if (
SG(request_info).auth_digest) {
519 efree(
SG(request_info).auth_digest);
520 SG(request_info).auth_digest =
NULL;
522 if (
SG(request_info).content_type_dup) {
523 efree(
SG(request_info).content_type_dup);
525 if (
SG(request_info).current_user) {
526 efree(
SG(request_info).current_user);
535 if (
SG(rfc1867_uploaded_files)) {
538 if (
SG(sapi_headers).mimetype) {
539 efree(
SG(sapi_headers).mimetype);
540 SG(sapi_headers).mimetype =
NULL;
542 sapi_send_headers_free();
543 SG(sapi_started) = 0;
545 SG(request_info).headers_read = 0;
546 SG(global_request_time) = 0;
558 SG(server_context) =
NULL;
559 SG(request_info).request_method =
NULL;
560 SG(request_info).auth_digest =
SG(request_info).auth_user =
SG(request_info).auth_password =
NULL;
561 SG(request_info).content_type_dup =
NULL;
565static int sapi_extract_response_code(
const char *header_line)
571 if (*
ptr ==
' ' && *(
ptr + 1) !=
' ') {
572 code = atoi(
ptr + 1);
581static void sapi_update_response_code(
int ncode)
589 if (
SG(sapi_headers).http_status_line) {
590 efree(
SG(sapi_headers).http_status_line);
591 SG(sapi_headers).http_status_line =
NULL;
593 SG(sapi_headers).http_response_code = ncode;
633 ctr.
line = header_line;
640 efree((
void *) header_line);
653 char sav = *colon_offset;
656 sapi_remove_header(&
SG(sapi_headers).headers, sapi_header->
header,
strlen(sapi_header->
header));
671 size_t header_line_len;
679 sapi_module.sapi_error(
E_WARNING,
"Cannot modify header information - headers already sent by (output started at %s:%d)",
689 sapi_update_response_code((
int)(intptr_t)
arg);
697 if (!
p->line || !
p->line_len) {
701 header_line_len =
p->line_len;
708 sapi_module.header_handler(&sapi_header, op, &
SG(sapi_headers));
718 if (header_line_len && isspace(header_line[header_line_len-1])) {
721 }
while(header_line_len && isspace(header_line[header_line_len-1]));
722 header_line[header_line_len]=
'\0';
726 if (
strchr(header_line,
':')) {
732 sapi_header.
header = header_line;
734 sapi_module.header_handler(&sapi_header, op, &
SG(sapi_headers));
736 sapi_remove_header(&
SG(sapi_headers).headers, header_line, header_line_len);
742 for (i = 0; i < header_line_len; i++) {
744 if (header_line[i] ==
'\n' || header_line[i] ==
'\r') {
747 "more than a single header, new line detected");
750 if (header_line[i] ==
'\0') {
758 sapi_header.
header = header_line;
762 if (header_line_len>=5
765 sapi_update_response_code(sapi_extract_response_code(header_line));
767 if (
SG(sapi_headers).http_status_line) {
768 efree(
SG(sapi_headers).http_status_line);
770 SG(sapi_headers).http_status_line = header_line;
773 colon_offset =
strchr(header_line,
':');
776 if (!
strcasecmp(header_line,
"Content-Type")) {
777 char *
ptr = colon_offset+1, *mimetype =
NULL, *newheader;
778 size_t len = header_line_len - (
ptr - header_line), newlen;
779 while (*
ptr ==
' ') {
786 if (!
SG(sapi_headers).mimetype){
787 SG(sapi_headers).mimetype =
estrdup(mimetype);
791 newlen +=
sizeof(
"Content-type: ");
793 PHP_STRLCPY(newheader,
"Content-type: ", newlen,
sizeof(
"Content-type: ")-1);
794 strlcat(newheader, mimetype, newlen);
795 sapi_header.
header = newheader;
796 sapi_header.
header_len = (uint32_t)(newlen - 1);
800 SG(sapi_headers).send_default_content_type = 0;
801 }
else if (!
strcasecmp(header_line,
"Content-Length")) {
811 }
else if (!
strcasecmp(header_line,
"Location")) {
818 }
else if (
SG(request_info).proto_num > 1000 &&
819 SG(request_info).request_method &&
820 strcmp(
SG(request_info).request_method,
"HEAD") &&
821 strcmp(
SG(request_info).request_method,
"GET")) {
822 sapi_update_response_code(303);
824 sapi_update_response_code(302);
827 }
else if (!
strcasecmp(header_line,
"WWW-Authenticate")) {
828 sapi_update_response_code(401);
830 if (sapi_header.
header==header_line) {
838 sapi_header_add_op(op, &sapi_header);
855 if (
SG(sapi_headers).send_default_content_type &&
sapi_module.send_headers) {
857 char *default_mimetype = get_default_content_type(0, &
len);
859 if (default_mimetype &&
len) {
862 SG(sapi_headers).mimetype = default_mimetype;
864 default_header.
header_len =
sizeof(
"Content-type: ") - 1 +
len;
867 memcpy(default_header.
header,
"Content-type: ",
sizeof(
"Content-type: ") - 1);
868 memcpy(default_header.
header +
sizeof(
"Content-type: ") - 1,
SG(sapi_headers).mimetype,
len + 1);
872 efree(default_mimetype);
874 SG(sapi_headers).send_default_content_type = 0;
881 sapi_run_header_callback(&
cb);
901 if (
SG(sapi_headers).http_status_line) {
902 http_status_line.
header =
SG(sapi_headers).http_status_line;
908 sapi_module.send_header(&http_status_line,
SG(server_context));
911 if(
SG(sapi_headers).send_default_content_type) {
915 sapi_module.send_header(&default_header,
SG(server_context));
927 sapi_send_headers_free();
937 while (
p->content_type) {
951 if (
SG(sapi_started) &&
EG(current_execute_data)) {
956 ret = zend_hash_add_mem(&
SG(known_post_content_types),
key,
964 if (
SG(sapi_started) &&
EG(current_execute_data)) {
974 if (
SG(sapi_started) &&
EG(current_execute_data)) {
977 sapi_module.default_post_reader = default_post_reader;
984 if (
SG(sapi_started) &&
EG(current_execute_data)) {
993 if (
SG(sapi_started) &&
EG(current_execute_data)) {
1016 if (!
SG(request_info).path_translated || (
VCWD_STAT(
SG(request_info).path_translated, &
SG(global_stat)) == -1)) {
1019 return &
SG(global_stat);
1090 if(
SG(global_request_time))
return SG(global_request_time);
1094 struct timeval tp = {0};
1096 SG(global_request_time) = (double)(tp.tv_sec + tp.tv_usec / 1000000.00);
1098 SG(global_request_time) = (double)
time(0);
1101 return SG(global_request_time);
1138 }
else if (*
p >=
'A' && *
p <=
'Z') {
1139 *str++ = (*
p++ -
'A' +
'a');
1145 }
else if (var_len ==
sizeof(
"CONTENT_TYPE")-1 &&
1146 memcmp(var,
"CONTENT_TYPE",
sizeof(
"CONTENT_TYPE")-1) == 0) {
1147 var =
"Content-Type";
1148 }
else if (var_len ==
sizeof(
"CONTENT_LENGTH")-1 &&
1149 memcmp(var,
"CONTENT_LENGTH",
sizeof(
"CONTENT_LENGTH")-1) == 0) {
1150 var =
"Content-Length";
SAPI_API int sapi_register_default_post_reader(void(*default_post_reader)(void))
SAPI_API zend_stat_t * sapi_get_stat(void)
SAPI_API double sapi_get_request_time(void)
SAPI_API int sapi_register_treat_data(void(*treat_data)(int arg, char *str, zval *destArray))
SAPI_API char * sapi_get_default_content_type(void)
SAPI_API void sapi_terminate_process(void)
SAPI_API sapi_module_struct sapi_module
SAPI_API int sapi_send_headers(void)
SAPI_API void sapi_initialize_empty_request(void)
SAPI_API void sapi_add_request_header(const char *var, unsigned int var_len, char *val, unsigned int val_len, void *arg)
SAPI_API void sapi_activate_headers_only(void)
SAPI_API int sapi_register_input_filter(unsigned int(*input_filter)(int arg, const char *var, char **val, size_t val_len, size_t *new_val_len), unsigned int(*input_filter_init)(void))
SAPI_API int sapi_flush(void)
SAPI_API void sapi_free_header(sapi_header_struct *sapi_header)
SAPI_API int sapi_add_header_ex(const char *header_line, size_t header_line_len, bool duplicate, bool replace)
SAPI_API char * sapi_getenv(const char *name, size_t name_len)
SAPI_API void sapi_unregister_post_entry(const sapi_post_entry *post_entry)
SAPI_API void sapi_read_post_data(void)
SAPI_API void sapi_get_default_content_type_header(sapi_header_struct *default_header)
SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg)
SAPI_API void sapi_activate(void)
SAPI_API int sapi_register_post_entries(const sapi_post_entry *post_entries)
SAPI_API void sapi_deactivate_destroy(void)
SAPI_API int sapi_get_fd(int *fd)
SAPI_API size_t sapi_apply_default_charset(char **mimetype, size_t len)
SAPI_API size_t sapi_read_post_block(char *buffer, size_t buflen)
sapi_globals_struct sapi_globals
SAPI_API void sapi_deactivate(void)
SAPI_API int sapi_register_post_entry(const sapi_post_entry *post_entry)
SAPI_API int sapi_get_target_uid(uid_t *obj)
SAPI_API void sapi_handle_post(void *arg)
SAPI_API void sapi_deactivate_module(void)
SAPI_API void sapi_startup(sapi_module_struct *sf)
SAPI_API int sapi_force_http_10(void)
SAPI_API int sapi_get_target_gid(gid_t *obj)
SAPI_API void sapi_shutdown(void)
#define REQUEST_PARSE_BODY_OPTION_GET(name, fallback)
#define SAPI_POST_READER_FUNC(post_reader)
#define SAPI_HEADER_SEND_FAILED
#define SAPI_DEFAULT_MIMETYPE
#define SAPI_HEADER_DO_SEND
#define SAPI_DEFAULT_CHARSET
struct _sapi_globals_struct sapi_globals_struct
#define SAPI_HEADER_SENT_SUCCESSFULLY
struct _sapi_module_struct sapi_module_struct
struct _sapi_post_entry sapi_post_entry
#define SAPI_POST_BLOCK_SIZE
header_register_callback(callable $callback)
http_response_code(int $response_code=0)
gettimeofday(bool $as_float=false)
header(string $header, bool $replace=true, int $response_code=0)
strstr(string $haystack, string $needle, bool $before_needle=false)
strchr(string $haystack, string $needle, bool $before_needle=false)
headers_sent(&$filename=null, &$line=null)
memset(ptr, 0, type->size)
zend_ffi_ctype_name_buf buf
enum entity_charset charset
PHPAPI ZEND_COLD void php_error_docref(const char *docref, int type, const char *format,...)
PHPAPI const char * php_output_get_start_filename(void)
PHPAPI int php_output_get_start_lineno(void)
#define PHP_STRLCPY(dst, src, size, src_size)
int php_setup_sapi_content_types(void)
#define PHP_INI_STAGE_RUNTIME
#define TEMP_STREAM_DEFAULT
#define php_stream_temp_create_ex(mode, max_memory_usage, tmpdir)
zend_string * output_start_filename
#define reentrancy_shutdown()
#define reentrancy_startup()
unsigned char key[REFLECTION_KEY_LEN]
#define php_stream_rewind(stream)
#define php_stream_truncate_set_size(stream, size)
#define php_stream_write(stream, buf, count)
PHPAPI void destroy_uploaded_files_hash(void)
void(* post_reader)(void)
uint32_t content_type_len
zend_llist_element * head
zend_llist_element * tail
ZEND_API zend_result zend_fcall_info_init(zval *callable, uint32_t check_flags, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_string **callable_name, char **error)
ZEND_API zend_result zend_parse_parameters(uint32_t num_args, const char *type_spec,...)
ZEND_API void add_assoc_stringl_ex(zval *arg, const char *key, size_t key_len, const char *str, size_t length)
ZEND_API const zend_fcall_info_cache empty_fcall_info_cache
struct _zend_fcall_info_cache zend_fcall_info_cache
struct _zend_fcall_info zend_fcall_info
ZEND_API zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache)
#define estrndup(s, length)
strncmp(string $string1, string $string2, int $length)
strcmp(string $string1, string $string2)
zend_string_release_ex(func->internal_function.function_name, 0)
#define strncasecmp(s1, s2, n)
#define strcasecmp(s1, s2)
ZEND_API void(ZEND_FASTCALL *zend_touch_vm_stack_data)(void *vm_stack_data)
ZEND_API void ZEND_FASTCALL zend_hash_destroy(HashTable *ht)
ZEND_API zend_result ZEND_FASTCALL zend_hash_str_del(HashTable *ht, const char *str, size_t len)
#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent)
ZEND_API zend_result zend_alter_ini_entry_chars(zend_string *name, const char *value, size_t value_length, int modify_type, int stage)
ZEND_API void zend_llist_destroy(zend_llist *l)
ZEND_API void zend_llist_add_element(zend_llist *l, const void *element)
ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent)
ZEND_API void zend_llist_clean(zend_llist *l)
ZEND_API void zend_llist_apply_with_argument(zend_llist *l, llist_apply_with_arg_func_t func, void *arg)
struct _zend_llist_element zend_llist_element
void(* llist_apply_with_arg_func_t)(void *data, void *arg)
struct _zend_llist zend_llist
struct _zend_string zend_string
#define ALLOCA_FLAG(name)
#define do_alloca(p, use_heap)
#define free_alloca(p, use_heap)
#define UNEXPECTED(condition)
#define ZSTR_INIT_LITERAL(s, persistent)
#define GC_MAKE_PERSISTENT_LOCAL(p)
#define ZVAL_COPY_VALUE(z, v)
ZEND_API void zval_ptr_dtor(zval *zval_ptr)
#define VCWD_STAT(path, buff)