diff options
Diffstat (limited to 'sapi')
30 files changed, 447 insertions, 4775 deletions
diff --git a/sapi/aolserver/aolserver.c b/sapi/aolserver/aolserver.c index 7f727532e1..0cba81bcbc 100644 --- a/sapi/aolserver/aolserver.c +++ b/sapi/aolserver/aolserver.c @@ -241,6 +241,7 @@ static void php_info_aolserver(ZEND_MODULE_INFO_FUNC_ARGS) PHP_FUNCTION(getallheaders); /* {{{ arginfo */ +static ZEND_BEGIN_ARG_INFO(arginfo_aolserver_getallheaders, 0) ZEND_END_ARG_INFO() /* }}} */ diff --git a/sapi/apache/mod_php5.c b/sapi/apache/mod_php5.c index 8fe32faa67..a5afb77be4 100644 --- a/sapi/apache/mod_php5.c +++ b/sapi/apache/mod_php5.c @@ -35,7 +35,7 @@ static void php_save_umask(void); static void php_restore_umask(void); static int sapi_apache_read_post(char *buffer, uint count_bytes TSRMLS_DC); static char *sapi_apache_read_cookies(TSRMLS_D); -static int sapi_apache_header_handler(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers TSRMLS_DC); +static int sapi_apache_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC); static int sapi_apache_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC); static int send_php(request_rec *r, int display_source_mode, char *filename); static int send_parsed_php(request_rec * r); @@ -163,54 +163,41 @@ static char *sapi_apache_read_cookies(TSRMLS_D) /* {{{ sapi_apache_header_handler */ -static int sapi_apache_header_handler(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers TSRMLS_DC) +static int sapi_apache_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) { char *header_name, *header_content, *p; request_rec *r = (request_rec *) SG(server_context); if(!r) { + efree(sapi_header->header); return 0; } - switch(op) { - case SAPI_HEADER_DELETE_ALL: - clear_table(r->headers_out); - return 0; + header_name = sapi_header->header; - case SAPI_HEADER_DELETE: - table_unset(r->headers_out, sapi_header->header); - return 0; - - case SAPI_HEADER_ADD: - case SAPI_HEADER_REPLACE: - header_name = sapi_header->header; - - header_content = p = strchr(header_name, ':'); - if (!p) { - return 0; - } - - *p = 0; - do { - header_content++; - } while (*header_content==' '); - - if (!strcasecmp(header_name, "Content-Type")) { - r->content_type = pstrdup(r->pool, header_content); - } else if (!strcasecmp(header_name, "Set-Cookie")) { - table_add(r->headers_out, header_name, header_content); - } else if (op == SAPI_HEADER_REPLACE) { - table_set(r->headers_out, header_name, header_content); - } else { - table_add(r->headers_out, header_name, header_content); - } + header_content = p = strchr(header_name, ':'); + if (!p) { + efree(sapi_header->header); + return 0; + } - *p = ':'; /* a well behaved header handler shouldn't change its original arguments */ + *p = 0; + do { + header_content++; + } while (*header_content==' '); + + if (!strcasecmp(header_name, "Content-Type")) { + r->content_type = pstrdup(r->pool, header_content); + } else if (!strcasecmp(header_name, "Set-Cookie")) { + table_add(r->headers_out, header_name, header_content); + } else if (sapi_header->replace) { + table_set(r->headers_out, header_name, header_content); + } else { + table_add(r->headers_out, header_name, header_content); + } - return SAPI_HEADER_ADD; + *p = ':'; /* a well behaved header handler shouldn't change its original arguments */ - default: - return 0; - } + return SAPI_HEADER_ADD; } /* }}} */ @@ -613,8 +600,6 @@ static int send_php(request_rec *r, int display_source_mode, char *filename) return OK; } - SG(server_context) = r; - zend_first_try { /* Make sure file exists */ @@ -672,6 +657,8 @@ static int send_php(request_rec *r, int display_source_mode, char *filename) /* Init timeout */ hard_timeout("send", r); + SG(server_context) = r; + php_save_umask(); add_common_vars(r); add_cgi_vars(r); @@ -745,11 +732,11 @@ static zend_bool should_overwrite_per_dir_entry(HashTable *target_ht, php_per_di return 1; /* does not exist in dest, copy from source */ } - if (orig_per_dir_entry->type==PHP_INI_SYSTEM - && new_per_dir_entry->type!=PHP_INI_SYSTEM) { - return 0; - } else { + if (new_per_dir_entry->type==PHP_INI_SYSTEM + && orig_per_dir_entry->type!=PHP_INI_SYSTEM) { return 1; + } else { + return 0; } } /* }}} */ @@ -786,9 +773,9 @@ static void *php_merge_dir(pool *p, void *basev, void *addv) /* need a copy of addv to merge */ new = php_create_dir(p, "php_merge_dir"); - zend_hash_copy(new, (HashTable *) basev, (copy_ctor_func_t) copy_per_dir_entry, NULL, sizeof(php_per_dir_entry)); + zend_hash_copy(new, (HashTable *) addv, (copy_ctor_func_t) copy_per_dir_entry, NULL, sizeof(php_per_dir_entry)); - zend_hash_merge_ex(new, (HashTable *) addv, (copy_ctor_func_t) copy_per_dir_entry, sizeof(php_per_dir_entry), (merge_checker_func_t) should_overwrite_per_dir_entry, NULL); + zend_hash_merge_ex(new, (HashTable *) basev, (copy_ctor_func_t) copy_per_dir_entry, sizeof(php_per_dir_entry), (merge_checker_func_t) should_overwrite_per_dir_entry, NULL); return new; } /* }}} */ diff --git a/sapi/apache/php_apache.c b/sapi/apache/php_apache.c index 18bbffab8e..e0f5d5405d 100644 --- a/sapi/apache/php_apache.c +++ b/sapi/apache/php_apache.c @@ -56,40 +56,50 @@ PHP_FUNCTION(apache_reset_timeout); PHP_MINFO_FUNCTION(apache); +static ZEND_BEGIN_ARG_INFO(arginfo_apache_child_terminate, 0) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_apache_note, 0, 0, 1) ZEND_ARG_INFO(0, note_name) ZEND_ARG_INFO(0, note_value) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_apache_virtual, 0, 0, 1) ZEND_ARG_INFO(0, filename) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO(arginfo_apache_request_headers, 0) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO(arginfo_apache_response_headers, 0) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_apache_setenv, 0, 0, 2) ZEND_ARG_INFO(0, variable) ZEND_ARG_INFO(0, value) ZEND_ARG_INFO(0, walk_to_top) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_apache_lookup_uri, 0, 0, 1) ZEND_ARG_INFO(0, uri) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO(arginfo_apache_get_version, 0) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO(arginfo_apache_get_modules, 0) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO(arginfo_apache_reset_timeout, 0) ZEND_END_ARG_INFO() diff --git a/sapi/apache2filter/php_functions.c b/sapi/apache2filter/php_functions.c index 6cb0b02db6..290e575f24 100644 --- a/sapi/apache2filter/php_functions.c +++ b/sapi/apache2filter/php_functions.c @@ -59,22 +59,23 @@ static request_rec *php_apache_lookup_uri(char *filename TSRMLS_DC) Perform an apache sub-request */ PHP_FUNCTION(virtual) { - char *filename; - int filename_len; + zval **filename; request_rec *rr; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) { - return; + if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &filename) == FAILURE) { + WRONG_PARAM_COUNT; } - if (!(rr = php_apache_lookup_uri(filename TSRMLS_CC))) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include '%s' - URI lookup failed", filename); + convert_to_string_ex(filename); + + if (!(rr = php_apache_lookup_uri(Z_STRVAL_PP(filename) TSRMLS_CC))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include '%s' - URI lookup failed", Z_STRVAL_PP(filename)); RETURN_FALSE; } if (rr->status == HTTP_OK) { if (ap_run_sub_req(rr)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include '%s' - request execution failed", filename); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include '%s' - request execution failed", Z_STRVAL_PP(filename)); ap_destroy_sub_req(rr); RETURN_FALSE; } @@ -82,7 +83,7 @@ PHP_FUNCTION(virtual) RETURN_TRUE; } - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include '%s' - error finding URI", filename); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include '%s' - error finding URI", Z_STRVAL_PP(filename)); ap_destroy_sub_req(rr); RETURN_FALSE; } @@ -98,15 +99,16 @@ PHP_FUNCTION(virtual) PHP_FUNCTION(apache_lookup_uri) { request_rec *rr; - char *filename; - int filename_len; + zval **filename; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) { - return; + if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &filename) == FAILURE) { + WRONG_PARAM_COUNT; } - if (!(rr = php_apache_lookup_uri(filename TSRMLS_CC))) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include '%s' - URI lookup failed", filename); + convert_to_string_ex(filename); + + if (!(rr = php_apache_lookup_uri(Z_STRVAL_PP(filename) TSRMLS_CC))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include '%s' - URI lookup failed", Z_STRVAL_PP(filename)); RETURN_FALSE; } @@ -143,7 +145,7 @@ PHP_FUNCTION(apache_lookup_uri) return; } - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include '%s' - error finding URI", filename); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include '%s' - error finding URI", Z_STRVAL_PP(filename)); ap_destroy_sub_req(rr); RETURN_FALSE; } @@ -193,28 +195,31 @@ PHP_FUNCTION(apache_response_headers) PHP_FUNCTION(apache_note) { php_struct *ctx; - char *note_name, *note_val; - int note_name_len, note_val_len; + zval **note_name, **note_val; char *old_note_val=NULL; int arg_count = ZEND_NUM_ARGS(); - if (zend_parse_parameters(arg_count TSRMLS_CC, "s|s", ¬e_name, ¬e_name_len, ¬e_val, ¬e_val_len) == FAILURE) { - return; + if (arg_count<1 || arg_count>2 || + zend_get_parameters_ex(arg_count, ¬e_name, ¬e_val) == FAILURE) { + WRONG_PARAM_COUNT; } - + ctx = SG(server_context); + + convert_to_string_ex(note_name); - old_note_val = (char *) apr_table_get(ctx->r->notes, note_name); - + old_note_val = (char *) apr_table_get(ctx->r->notes, Z_STRVAL_PP(note_name)); + if (arg_count == 2) { - apr_table_set(ctx->r->notes, note_name, note_val); + convert_to_string_ex(note_val); + apr_table_set(ctx->r->notes, Z_STRVAL_PP(note_name), Z_STRVAL_PP(note_val)); } if (old_note_val) { RETURN_STRING(old_note_val, 1); + } else { + RETURN_FALSE; } - - RETURN_FALSE; } /* }}} */ @@ -224,24 +229,26 @@ PHP_FUNCTION(apache_note) PHP_FUNCTION(apache_setenv) { php_struct *ctx; - char *variable=NULL, *string_val=NULL; - int variable_len, string_val_len; - zend_bool walk_to_top = 0; + zval **variable=NULL, **string_val=NULL, **walk_to_top=NULL; int arg_count = ZEND_NUM_ARGS(); - if (zend_parse_parameters(arg_count TSRMLS_CC, "ss|b", &variable, &variable_len, &string_val, &string_val_len, &walk_to_top) == FAILURE) { - return; + if (arg_count<1 || arg_count>3 || + zend_get_parameters_ex(arg_count, &variable, &string_val, &walk_to_top) == FAILURE) { + WRONG_PARAM_COUNT; } ctx = SG(server_context); - if (arg_count == 3 && walk_to_top) { + if (arg_count == 3 && Z_STRVAL_PP(walk_to_top)) { while(ctx->f->r->prev) { ctx->f->r = ctx->f->r->prev; - } + } } - apr_table_set(ctx->r->subprocess_env, variable, string_val); + convert_to_string_ex(variable); + convert_to_string_ex(string_val); + + apr_table_set(ctx->r->subprocess_env, Z_STRVAL_PP(variable), Z_STRVAL_PP(string_val)); RETURN_TRUE; } @@ -252,30 +259,31 @@ PHP_FUNCTION(apache_setenv) PHP_FUNCTION(apache_getenv) { php_struct *ctx; - char *variable=NULL; - int variable_len; - zend_bool walk_to_top = 0; + zval **variable=NULL, **walk_to_top=NULL; int arg_count = ZEND_NUM_ARGS(); char *env_val=NULL; - if (zend_parse_parameters(arg_count TSRMLS_CC, "s|b", &variable, &variable_len, &walk_to_top) == FAILURE) { - return; + if (arg_count<1 || arg_count>2 || + zend_get_parameters_ex(arg_count, &variable, &walk_to_top) == FAILURE) { + WRONG_PARAM_COUNT; } ctx = SG(server_context); - if (arg_count == 2 && walk_to_top) { + if (arg_count == 2 && Z_STRVAL_PP(walk_to_top)) { while(ctx->f->r->prev) { ctx->f->r = ctx->f->r->prev; - } + } } - env_val = (char*) apr_table_get(ctx->r->subprocess_env, variable); + convert_to_string_ex(variable); + + env_val = (char*) apr_table_get(ctx->r->subprocess_env, Z_STRVAL_PP(variable)); if (env_val != NULL) { RETURN_STRING(env_val, 1); - } - - RETURN_FALSE; + } else { + RETURN_FALSE; + } } /* }}} */ @@ -352,39 +360,48 @@ PHP_MINFO_FUNCTION(apache) } /* {{{ arginfo */ +static ZEND_BEGIN_ARG_INFO_EX(arginfo_apache2filter_lookup_uri, 0, 0, 1) ZEND_ARG_INFO(0, filename) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_apache2filter_virtual, 0, 0, 1) ZEND_ARG_INFO(0, uri) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO(arginfo_apache2filter_getallheaders, 0) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO(arginfo_apache2filter_response_headers, 0) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_apache2filter_note, 0, 0, 1) ZEND_ARG_INFO(0, note_name) ZEND_ARG_INFO(0, note_value) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_apache2filter_setenv, 0, 0, 2) ZEND_ARG_INFO(0, variable) ZEND_ARG_INFO(0, value) ZEND_ARG_INFO(0, walk_to_top) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_apache2filter_getenv, 0, 0, 1) ZEND_ARG_INFO(0, variable) ZEND_ARG_INFO(0, walk_to_top) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO(arginfo_apache2filter_get_version, 0) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO(arginfo_apache2filter_get_modules, 0) ZEND_END_ARG_INFO() /* }}} */ diff --git a/sapi/apache2filter/sapi_apache2.c b/sapi/apache2filter/sapi_apache2.c index ecd1eb624d..1edc0f9ea3 100644 --- a/sapi/apache2filter/sapi_apache2.c +++ b/sapi/apache2filter/sapi_apache2.c @@ -91,7 +91,7 @@ php_apache_sapi_ub_write(const char *str, uint str_length TSRMLS_DC) } static int -php_apache_sapi_header_handler(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers TSRMLS_DC) +php_apache_sapi_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) { php_struct *ctx; ap_filter_t *f; @@ -100,44 +100,29 @@ php_apache_sapi_header_handler(sapi_header_struct *sapi_header, sapi_header_op_e ctx = SG(server_context); f = ctx->r->output_filters; - switch(op) { - case SAPI_HEADER_DELETE: - apr_table_unset(ctx->r->headers_out, sapi_header->header); - return 0; - - case SAPI_HEADER_DELETE_ALL: - apr_table_clear(ctx->r->headers_out); - return 0; - - case SAPI_HEADER_ADD: - case SAPI_HEADER_REPLACE: - val = strchr(sapi_header->header, ':'); - - if (!val) { - sapi_free_header(sapi_header); - return 0; - } - ptr = val; - - *val = '\0'; - - do { - val++; - } while (*val == ' '); - - if (!strcasecmp(sapi_header->header, "content-type")) - ctx->r->content_type = apr_pstrdup(ctx->r->pool, val); - else if (op == SAPI_HEADER_REPLACE) - apr_table_set(ctx->r->headers_out, sapi_header->header, val); - else - apr_table_add(ctx->r->headers_out, sapi_header->header, val); - - *ptr = ':'; - return SAPI_HEADER_ADD; - - default: - return 0; + val = strchr(sapi_header->header, ':'); + + if (!val) { + sapi_free_header(sapi_header); + return 0; } + ptr = val; + + *val = '\0'; + + do { + val++; + } while (*val == ' '); + + if (!strcasecmp(sapi_header->header, "content-type")) + ctx->r->content_type = apr_pstrdup(ctx->r->pool, val); + else if (sapi_header->replace) + apr_table_set(ctx->r->headers_out, sapi_header->header, val); + else + apr_table_add(ctx->r->headers_out, sapi_header->header, val); + + *ptr = ':'; + return SAPI_HEADER_ADD; } static int diff --git a/sapi/apache2handler/apache_config.c b/sapi/apache2handler/apache_config.c index b53a0c984d..c629dbf48e 100644 --- a/sapi/apache2handler/apache_config.c +++ b/sapi/apache2handler/apache_config.c @@ -117,23 +117,6 @@ static const char *php_apache_phpini_set(cmd_parms *cmd, void *mconfig, const ch return NULL; } -static zend_bool should_overwrite_per_dir_entry(HashTable *target_ht, php_dir_entry *new_per_dir_entry, zend_hash_key *hash_key, void *pData) -{ - php_dir_entry *orig_per_dir_entry; - - if (zend_hash_find(target_ht, hash_key->arKey, hash_key->nKeyLength, (void **) &orig_per_dir_entry)==FAILURE) { - return 1; /* does not exist in dest, copy from source */ - } - - if (new_per_dir_entry->status >= orig_per_dir_entry->status) { - /* use new entry */ - phpapdebug((stderr, "ADDING/OVERWRITING %s (%d vs. %d)\n", hash_key->arKey, new_per_dir_entry->status, orig_per_dir_entry->status)); - return 1; - } else { - return 0; - } -} - void *merge_php_config(apr_pool_t *p, void *base_conf, void *new_conf) { @@ -145,12 +128,9 @@ void *merge_php_config(apr_pool_t *p, void *base_conf, void *new_conf) ulong num_index; n = create_php_config(p, "merge_php_config"); - /* copy old config */ - zend_hash_copy(&n->config, &d->config, NULL, NULL, sizeof(php_dir_entry)); - /* merge new config */ + zend_hash_copy(&n->config, &e->config, NULL, NULL, sizeof(php_dir_entry)); + phpapdebug((stderr, "Merge dir (%p)+(%p)=(%p)\n", base_conf, new_conf, n)); - zend_hash_merge_ex(&n->config, &e->config, NULL, sizeof(php_dir_entry), (merge_checker_func_t) should_overwrite_per_dir_entry, NULL); -#if STAS_0 for (zend_hash_internal_pointer_reset(&d->config); zend_hash_get_current_key_ex(&d->config, &str, &str_len, &num_index, 0, NULL) == HASH_KEY_IS_STRING; @@ -160,10 +140,10 @@ void *merge_php_config(apr_pool_t *p, void *base_conf, void *new_conf) if (zend_hash_find(&n->config, str, str_len, (void **) &pe) == SUCCESS) { if (pe->status >= data->status) continue; } - phpapdebug((stderr, "ADDING/OVERWRITING %s (%d vs. %d)\n", str, data->status, pe?pe->status:-1)); zend_hash_update(&n->config, str, str_len, data, sizeof(*data), NULL); + phpapdebug((stderr, "ADDING/OVERWRITING %s (%d vs. %d)\n", str, data->status, pe?pe->status:-1)); } -#endif + return n; } diff --git a/sapi/apache2handler/php_functions.c b/sapi/apache2handler/php_functions.c index 5fe67a2254..809cf0a69a 100644 --- a/sapi/apache2handler/php_functions.c +++ b/sapi/apache2handler/php_functions.c @@ -469,39 +469,48 @@ PHP_MINFO_FUNCTION(apache) } /* {{{ arginfo */ +static ZEND_BEGIN_ARG_INFO_EX(arginfo_apache2handler_lookup_uri, 0, 0, 1) ZEND_ARG_INFO(0, filename) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_apache2handler_virtual, 0, 0, 1) ZEND_ARG_INFO(0, uri) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO(arginfo_apache2handler_response_headers, 0) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO(arginfo_apache2handler_getallheaders, 0) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_apache2handler_note, 0, 0, 1) ZEND_ARG_INFO(0, note_name) ZEND_ARG_INFO(0, note_value) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_apache2handler_setenv, 0, 0, 2) ZEND_ARG_INFO(0, variable) ZEND_ARG_INFO(0, value) ZEND_ARG_INFO(0, walk_to_top) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_apache2handler_getenv, 0, 0, 1) ZEND_ARG_INFO(0, variable) ZEND_ARG_INFO(0, walk_to_top) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO(arginfo_apache2handler_get_version, 0) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO(arginfo_apache2handler_get_modules, 0) ZEND_END_ARG_INFO() /* }}} */ diff --git a/sapi/apache2handler/sapi_apache2.c b/sapi/apache2handler/sapi_apache2.c index cf2e1427be..b8671c59d4 100644 --- a/sapi/apache2handler/sapi_apache2.c +++ b/sapi/apache2handler/sapi_apache2.c @@ -83,55 +83,40 @@ php_apache_sapi_ub_write(const char *str, uint str_length TSRMLS_DC) } static int -php_apache_sapi_header_handler(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers TSRMLS_DC) +php_apache_sapi_header_handler(sapi_header_struct *sapi_header,sapi_headers_struct *sapi_headers TSRMLS_DC) { php_struct *ctx; char *val, *ptr; ctx = SG(server_context); - switch (op) { - case SAPI_HEADER_DELETE: - apr_table_unset(ctx->r->headers_out, sapi_header->header); - return 0; + val = strchr(sapi_header->header, ':'); - case SAPI_HEADER_DELETE_ALL: - apr_table_clear(ctx->r->headers_out); - return 0; - - case SAPI_HEADER_ADD: - case SAPI_HEADER_REPLACE: - val = strchr(sapi_header->header, ':'); - - if (!val) { - return 0; - } - ptr = val; + if (!val) { + sapi_free_header(sapi_header); + return 0; + } + ptr = val; - *val = '\0'; + *val = '\0'; - do { - val++; - } while (*val == ' '); - - if (!strcasecmp(sapi_header->header, "content-type")) { - if (ctx->content_type) { - efree(ctx->content_type); - } - ctx->content_type = estrdup(val); - } else if (op == SAPI_HEADER_REPLACE) { - apr_table_set(ctx->r->headers_out, sapi_header->header, val); - } else { - apr_table_add(ctx->r->headers_out, sapi_header->header, val); - } + do { + val++; + } while (*val == ' '); - *ptr = ':'; - - return SAPI_HEADER_ADD; - - default: - return 0; + if (!strcasecmp(sapi_header->header, "content-type")) { + if (ctx->content_type) { + efree(ctx->content_type); + } + ctx->content_type = estrdup(val); + } else if (sapi_header->replace) { + apr_table_set(ctx->r->headers_out, sapi_header->header, val); + } else { + apr_table_add(ctx->r->headers_out, sapi_header->header, val); } + *ptr = ':'; + + return SAPI_HEADER_ADD; } static int diff --git a/sapi/apache_hooks/mod_php5.c b/sapi/apache_hooks/mod_php5.c index 1e66f44328..83cca78b80 100644 --- a/sapi/apache_hooks/mod_php5.c +++ b/sapi/apache_hooks/mod_php5.c @@ -34,7 +34,7 @@ static void php_save_umask(void); static void php_restore_umask(void); static int sapi_apache_read_post(char *buffer, uint count_bytes TSRMLS_DC); static char *sapi_apache_read_cookies(TSRMLS_D); -static int sapi_apache_header_handler(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers TSRMLS_DC); +static int sapi_apache_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC); static int sapi_apache_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC); static int send_php(request_rec *r, int display_source_mode, char *filename); static int send_parsed_php(request_rec * r); @@ -308,54 +308,35 @@ static char *sapi_apache_read_cookies(TSRMLS_D) /* {{{ sapi_apache_header_handler */ -static int sapi_apache_header_handler(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers TSRMLS_DC) +static int sapi_apache_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) { char *header_name, *header_content, *p; request_rec *r = (request_rec *) SG(server_context); - if(!r) { - return 0; - } - - switch(op) { - case SAPI_HEADER_DELETE_ALL: - clear_table(r->headers_out); - return 0; - case SAPI_HEADER_DELETE: - table_unset(r->headers_out, sapi_header->header); - return 0; + header_name = sapi_header->header; - case SAPI_HEADER_ADD: - case SAPI_HEADER_REPLACE: - header_name = sapi_header->header; - - header_content = p = strchr(header_name, ':'); - if (!p) { - return 0; - } + header_content = p = strchr(header_name, ':'); + if (!p) { + efree(sapi_header->header); + return 0; + } - *p = 0; - do { - header_content++; - } while (*header_content==' '); - - if (!strcasecmp(header_name, "Content-Type")) { - r->content_type = pstrdup(r->pool, header_content); - } else if (!strcasecmp(header_name, "Set-Cookie")) { - table_add(r->headers_out, header_name, header_content); - } else if (op == SAPI_HEADER_REPLACE) { - table_set(r->headers_out, header_name, header_content); - } else { - table_add(r->headers_out, header_name, header_content); - } + *p = 0; + do { + header_content++; + } while (*header_content==' '); - *p = ':'; /* a well behaved header handler shouldn't change its original arguments */ + if (!strcasecmp(header_name, "Content-Type")) { + r->content_type = pstrdup(r->pool, header_content); + } else if (!strcasecmp(header_name, "Set-Cookie")) { + table_add(r->headers_out, header_name, header_content); + } else { + table_set(r->headers_out, header_name, header_content); + } - return SAPI_HEADER_ADD; + *p = ':'; /* a well behaved header handler shouldn't change its original arguments */ - default: - return 0; - } + return SAPI_HEADER_ADD; } /* }}} */ diff --git a/sapi/apache_hooks/php_apache.c b/sapi/apache_hooks/php_apache.c index b0a1bb2a79..e6b867b9a4 100644 --- a/sapi/apache_hooks/php_apache.c +++ b/sapi/apache_hooks/php_apache.c @@ -59,38 +59,48 @@ PHP_FUNCTION(apache_get_modules); PHP_MINFO_FUNCTION(apache); +static ZEND_BEGIN_ARG_INFO_EX(arginfo_apachehooks_virtual, 0, 0, 1) ZEND_ARG_INFO(0, filename) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO(arginfo_apachehooks_request_headers, 0) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO(arginfo_apachehooks_response_headers, 0) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_apachehooks_setenv, 0, 0, 2) ZEND_ARG_INFO(0, variable) ZEND_ARG_INFO(0, value) ZEND_ARG_INFO(0, walk_to_top) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_apachehooks_lookup_uri, 0, 0, 1) ZEND_ARG_INFO(0, uri) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO(arginfo_apachehooks_get_version, 0) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO(arginfo_apachehooks_get_modules, 0) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO(arginfo_apachehooks_request_run, 0) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO(arginfo_apachehooks_child_terminate, 0) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_apachehooks_note, 0, 0, 1) ZEND_ARG_INFO(0, note_name) ZEND_ARG_INFO(0, note_value) @@ -220,16 +230,11 @@ static void apache_request_read_string_slot(int offset, INTERNAL_FUNCTION_PARAME */ static void apache_request_string_slot(int offset, INTERNAL_FUNCTION_PARAMETERS) { - zval *id; + zval *id, **new_value; request_rec *r; - char *old_value, *new_value; - int new_value_len; + char *old_value; char **target; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &new_value, &new_value_len) == FAILURE) { - return; - } - APREQ_GET_REQUEST(id, r); target = (char **)((char*)r + offset); @@ -239,7 +244,11 @@ static void apache_request_string_slot(int offset, INTERNAL_FUNCTION_PARAMETERS) case 0: break; case 1: - *target = ap_pstrdup(r->pool, new_value); + if (zend_get_parameters_ex(1, &new_value) == FAILURE) { + RETURN_FALSE; + } + convert_to_string_ex(new_value); + *target = ap_pstrdup(r->pool, Z_STRVAL_PP(new_value)); break; default: WRONG_PARAM_COUNT; @@ -277,15 +286,11 @@ static void apache_request_read_int_slot(int offset, INTERNAL_FUNCTION_PARAMETER */ static void apache_request_int_slot(int offset, INTERNAL_FUNCTION_PARAMETERS) { - zval *id; + zval *id, **new_value; request_rec *r; - long old_value, new_value; + long old_value; long *target; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &new_value) == FAILURE) { - return; - } - APREQ_GET_REQUEST(id, r); target = (long *)((char*)r + offset); @@ -295,7 +300,11 @@ static void apache_request_int_slot(int offset, INTERNAL_FUNCTION_PARAMETERS) case 0: break; case 1: - *target = new_value; + if (zend_get_parameters_ex(1, &new_value) == FAILURE) { + RETURN_FALSE; + } + convert_to_long_ex(new_value); + *target = Z_LVAL_PP(new_value); break; default: WRONG_PARAM_COUNT; @@ -522,20 +531,24 @@ PHP_FUNCTION(apache_request_mtime) */ PHP_FUNCTION(apache_request_content_length) { - zval *id; - long zlen; + zval *id, **zlen; request_rec *r; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &zlen) == FAILURE) { - return; - } - if (ZEND_NUM_ARGS() == 0) { apache_request_read_int_slot(offsetof(request_rec, clength), INTERNAL_FUNCTION_PARAM_PASSTHRU); - } else { + } + else if (ZEND_NUM_ARGS() > 1) { + WRONG_PARAM_COUNT; + } + else { + if (zend_get_parameters_ex(1, &zlen) == FAILURE) { + RETURN_FALSE; + } + APREQ_GET_REQUEST(id, r); - (void)ap_set_content_length(r, zlen); + convert_to_long_ex(zlen); + (void)ap_set_content_length(r, Z_LVAL_PP(zlen)); RETURN_TRUE; } } @@ -730,21 +743,23 @@ PHP_FUNCTION(apache_request_server_port) */ PHP_FUNCTION(apache_request_remote_host) { - zval *id; - long ztype; + zval *id, **ztype; request_rec *r; char *res; int type = REMOTE_NAME; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &ztype) == FAILURE) { - return; - } - switch (ZEND_NUM_ARGS()) { case 0: break; case 1: - type = ztype; + if (zend_get_parameters_ex(1, &ztype) == FAILURE) { + RETURN_FALSE; + } + convert_to_long_ex(ztype); + type = Z_LVAL_PP(ztype); + break; + default: + WRONG_PARAM_COUNT; break; } @@ -752,7 +767,6 @@ PHP_FUNCTION(apache_request_remote_host) APREQ_GET_REQUEST(id, r); res = (char *)ap_get_remote_host(r->connection, r->per_dir_config, type); - if (res) RETURN_STRING(res, 1); @@ -764,14 +778,26 @@ PHP_FUNCTION(apache_request_remote_host) */ PHP_FUNCTION(apache_request_update_mtime) { - zval *id; + zval *id, **zmtime; request_rec *r; int mtime = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &mtime) == FAILURE) { - return; + switch (ZEND_NUM_ARGS()) { + case 0: + break; + case 1: + if (zend_get_parameters_ex(1, &zmtime) == FAILURE) { + RETURN_FALSE; + } + convert_to_long_ex(zmtime); + mtime = Z_LVAL_PP(zmtime); + break; + default: + WRONG_PARAM_COUNT; + break; } + APREQ_GET_REQUEST(id, r); RETURN_LONG(ap_update_mtime(r, mtime)); @@ -1044,14 +1070,25 @@ PHP_FUNCTION(apache_request_send_http_options) PHP_FUNCTION(apache_request_send_error_response) { + zval **recursive; zval *id; request_rec *r; - int rec = 0; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &rec) == FAILURE) { - return; - } - + int rec; + + switch(ZEND_NUM_ARGS()) { + case 0: + rec = 0; + break; + case 1: + if(zend_get_parameters_ex(1, &recursive) == FAILURE) { + RETURN_FALSE; + } + convert_to_long_ex(recursive); + rec = Z_LVAL_PP(recursive); + break; + default: + WRONG_PARAM_COUNT; + } APREQ_GET_REQUEST(id, r); ap_send_error_response(r, rec); RETURN_TRUE; @@ -1059,17 +1096,17 @@ PHP_FUNCTION(apache_request_send_error_response) PHP_FUNCTION(apache_request_set_content_length) { - int length; + zval **length; zval *id; request_rec *r; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &length) == FAILURE) { - return; - } - + if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &length) == FAILURE) { + WRONG_PARAM_COUNT; + } APREQ_GET_REQUEST(id, r); - ap_set_content_length(r, length); + convert_to_long_ex(length); + ap_set_content_length(r, Z_LVAL_PP(length)); RETURN_TRUE; } @@ -1096,17 +1133,16 @@ PHP_FUNCTION(apache_request_send_fd_length) /* These are for overriding default output behaviour */ PHP_FUNCTION(apache_request_rputs) { - char *buffer; - int buffer_len; + zval **buffer; zval *id; request_rec *r; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buffer, &buffer_len) == FAILURE) { - return; - } - + if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &buffer) == FAILURE) { + WRONG_PARAM_COUNT; + } APREQ_GET_REQUEST(id, r); - ap_rwrite(buffer, buffer_len, (request_rec*)SG(server_context)); + convert_to_string_ex(buffer); + ap_rwrite(Z_STRVAL_PP(buffer), Z_STRLEN_PP(buffer), (request_rec*)SG(server_context)); } /* This stuff would be useful for custom POST handlers, @@ -1140,17 +1176,30 @@ PHP_FUNCTION(apache_request_discard_request_body) PHP_FUNCTION(apache_request_log_error) { zval *id; - char *z_errstr; - int z_errstr_len; - int facility = APLOG_ERR; + zval **z_errstr, **z_facility; request_rec *r; + int facility = APLOG_ERR; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &z_errstr, &z_errstr_len, &facility) == FAILURE) { - return; - } - + switch(ZEND_NUM_ARGS()) { + case 1: + if(zend_get_parameters_ex(1, &z_errstr) == FAILURE) { + RETURN_FALSE; + } + break; + case 2: + if(zend_get_parameters_ex(1, &z_errstr, &z_facility) == FAILURE) { + RETURN_FALSE; + } + convert_to_long_ex(z_facility); + facility = Z_LVAL_PP(z_facility); + break; + default: + WRONG_PARAM_COUNT; + break; + } APREQ_GET_REQUEST(id, r); - ap_log_error(APLOG_MARK, facility, r->server, "%s", z_errstr); + convert_to_string_ex(z_errstr); + ap_log_error(APLOG_MARK, facility, r->server, "%s", Z_STRVAL_PP(z_errstr)); RETURN_TRUE; } /* }}} */ @@ -1163,18 +1212,15 @@ PHP_FUNCTION(apache_request_log_error) PHP_FUNCTION(apache_request_sub_req_lookup_uri) { zval *id; - char *file; - int file_len; + zval **file; request_rec *r, *sub_r; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &file, &file_len) == FAILURE) { - return; - } - + if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &file) == FAILURE) { + WRONG_PARAM_COUNT; + } APREQ_GET_REQUEST(id, r); - sub_r = ap_sub_req_lookup_uri(file, r); - - if (!sub_r) { + convert_to_string_ex(file); + sub_r = ap_sub_req_lookup_uri(Z_STRVAL_PP(file), r); + if(!sub_r) { RETURN_FALSE; } return_value = php_apache_request_new(sub_r); @@ -1188,19 +1234,16 @@ PHP_FUNCTION(apache_request_sub_req_lookup_uri) PHP_FUNCTION(apache_request_sub_req_lookup_file) { zval *id; - char *file; - int file_len; + zval **file; request_rec *r, *sub_r; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &file, &file_len) == FAILURE) { - return; - } - + if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &file) == FAILURE) { + WRONG_PARAM_COUNT; + } APREQ_GET_REQUEST(id, r); - - sub_r = ap_sub_req_lookup_file(file, r); - - if (!sub_r) { + convert_to_string_ex(file); + sub_r = ap_sub_req_lookup_file(Z_STRVAL_PP(file), r); + if(!sub_r) { RETURN_FALSE; } return_value = php_apache_request_new(sub_r); @@ -1214,19 +1257,17 @@ PHP_FUNCTION(apache_request_sub_req_lookup_file) PHP_FUNCTION(apache_request_sub_req_method_uri) { zval *id; - char *file, *method; - int file_len, method_len; + zval **file, **method; request_rec *r, *sub_r; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &method, &method_len, &file, &file_len) == FAILURE) { - return; - } - + if(ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &method, &file) == FAILURE) { + WRONG_PARAM_COUNT; + } APREQ_GET_REQUEST(id, r); - - sub_r = ap_sub_req_method_uri(method, file, r); - - if (!sub_r) { + convert_to_string_ex(method); + convert_to_string_ex(file); + sub_r = ap_sub_req_method_uri(Z_STRVAL_PP(method),Z_STRVAL_PP(file), r); + if(!sub_r) { RETURN_FALSE; } return_value = php_apache_request_new(sub_r); @@ -1255,33 +1296,32 @@ PHP_FUNCTION(apache_request_run) PHP_FUNCTION(apache_request_internal_redirect) { zval *id; - char *new_uri; - int new_uri_len; + zval **new_uri; request_rec *r; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &new_uri, &new_uri_len) == FAILURE) { - return; - } - + if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &new_uri) == FAILURE) { + WRONG_PARAM_COUNT; + } APREQ_GET_REQUEST(id, r); - - ap_internal_redirect(new_uri, r); + convert_to_string_ex(new_uri); + ap_internal_redirect(Z_STRVAL_PP(new_uri), r); } PHP_FUNCTION(apache_request_send_header_field) { - char *fieldname, *fieldval; - int fieldname_len, fieldval_len; + zval **fieldname; + zval **fieldval; zval *id; request_rec *r; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &fieldname, &fieldname_len, &fieldval, &fieldval_len) == FAILURE) { - return; - } - + if(ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &fieldname, &fieldval) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_string_ex(fieldname); + convert_to_string_ex(fieldval); APREQ_GET_REQUEST(id, r); - ap_send_header_field(r, fieldname, fieldval); + ap_send_header_field(r, Z_STRVAL_PP(fieldname), Z_STRVAL_PP(fieldval)); SG(headers_sent) = 1; AP(headers_sent) = 1; } @@ -1551,26 +1591,28 @@ PHP_FUNCTION(apache_child_terminate) Get and set Apache request notes */ PHP_FUNCTION(apache_note) { - char *arg_name, *arg_val; - int arg_name_len, arg_val_len; + zval **arg_name, **arg_val; char *note_val; int arg_count = ZEND_NUM_ARGS(); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &arg_name, &arg_name_len, &arg_val, &arg_val_len) == FAILURE) { - return; + if (arg_count<1 || arg_count>2 || + zend_get_parameters_ex(arg_count, &arg_name, &arg_val) ==FAILURE ) { + WRONG_PARAM_COUNT; } - - note_val = (char *) table_get(((request_rec *)SG(server_context))->notes, arg_name); + + convert_to_string_ex(arg_name); + note_val = (char *) table_get(((request_rec *)SG(server_context))->notes, (*arg_name)->value.str.val); if (arg_count == 2) { - table_set(((request_rec *)SG(server_context))->notes, arg_name, arg_val); + convert_to_string_ex(arg_val); + table_set(((request_rec *)SG(server_context))->notes, (*arg_name)->value.str.val, (*arg_val)->value.str.val); } - if (!note_val) { + if (note_val) { + RETURN_STRING(note_val, 1); + } else { RETURN_FALSE; } - - RETURN_STRING(note_val, 1); } /* }}} */ @@ -1715,25 +1757,23 @@ PHP_MINFO_FUNCTION(apache) */ PHP_FUNCTION(virtual) { - char *filename; - int filename_len; + zval **filename; request_rec *rr = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) { - return; + if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &filename) == FAILURE) { + WRONG_PARAM_COUNT; } - - if (!(rr = sub_req_lookup_uri (filename, ((request_rec *) SG(server_context))))) { - php_error(E_WARNING, "Unable to include '%s' - URI lookup failed", filename); - if (rr) - destroy_sub_req (rr); + convert_to_string_ex(filename); + + if (!(rr = sub_req_lookup_uri ((*filename)->value.str.val, ((request_rec *) SG(server_context))))) { + php_error(E_WARNING, "Unable to include '%s' - URI lookup failed", (*filename)->value.str.val); + if (rr) destroy_sub_req (rr); RETURN_FALSE; } if (rr->status != 200) { - php_error(E_WARNING, "Unable to include '%s' - error finding URI", filename); - if (rr) - destroy_sub_req (rr); + php_error(E_WARNING, "Unable to include '%s' - error finding URI", (*filename)->value.str.val); + if (rr) destroy_sub_req (rr); RETURN_FALSE; } @@ -1741,15 +1781,13 @@ PHP_FUNCTION(virtual) php_header(TSRMLS_C); if (run_sub_req(rr)) { - php_error(E_WARNING, "Unable to include '%s' - request execution failed", filename); - if (rr) - destroy_sub_req (rr); + php_error(E_WARNING, "Unable to include '%s' - request execution failed", (*filename)->value.str.val); + if (rr) destroy_sub_req (rr); RETURN_FALSE; - } - - if (rr) - destroy_sub_req (rr); - RETURN_TRUE; + } else { + if (rr) destroy_sub_req (rr); + RETURN_TRUE; + } } /* }}} */ @@ -1827,23 +1865,20 @@ PHP_FUNCTION(apache_setenv) Perform a partial request of the given URI to obtain information about it */ PHP_FUNCTION(apache_lookup_uri) { - char *filename; - int filename_len; + zval **filename; request_rec *rr=NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) { - return; + if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &filename) == FAILURE) { + WRONG_PARAM_COUNT; } + convert_to_string_ex(filename); - - if(!(rr = sub_req_lookup_uri(filename, ((request_rec *) SG(server_context))))) { - php_error(E_WARNING, "URI lookup failed", filename); + if(!(rr = sub_req_lookup_uri((*filename)->value.str.val, ((request_rec *) SG(server_context))))) { + php_error(E_WARNING, "URI lookup failed", (*filename)->value.str.val); RETURN_FALSE; } - object_init(return_value); add_property_long(return_value,"status", rr->status); - if (rr->the_request) { add_property_string(return_value,"the_request", rr->the_request, 1); } diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c index a39df163e4..87f7998201 100644 --- a/sapi/cgi/cgi_main.c +++ b/sapi/cgi/cgi_main.c @@ -375,8 +375,6 @@ static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC) char buf[SAPI_CGI_MAX_HEADER_LENGTH]; sapi_header_struct *h; zend_llist_position pos; - zend_bool ignore_status = 0; - int response_status = SG(sapi_headers).http_response_code; if (SG(request_info).no_headers == 1) { return SAPI_HEADER_SENT_SUCCESSFULLY; @@ -388,11 +386,7 @@ static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC) zend_bool has_status = 0; if (CGIG(rfc2616_headers) && SG(sapi_headers).http_status_line) { - char *s; len = slprintf(buf, SAPI_CGI_MAX_HEADER_LENGTH, "%s\r\n", SG(sapi_headers).http_status_line); - if ((s = strchr(SG(sapi_headers).http_status_line, ' '))) { - response_status = atoi((s + 1)); - } if (len > SAPI_CGI_MAX_HEADER_LENGTH) { len = SAPI_CGI_MAX_HEADER_LENGTH; @@ -407,7 +401,6 @@ static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC) strncasecmp(SG(sapi_headers).http_status_line, "HTTP/", 5) == 0 ) { len = slprintf(buf, sizeof(buf), "Status:%s\r\n", s); - response_status = atoi((s + 1)); } else { h = (sapi_header_struct*)zend_llist_get_first_ex(&sapi_headers->headers, &pos); while (h) { @@ -437,7 +430,6 @@ static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC) } if (!has_status) { PHPWRITE_H(buf, len); - ignore_status = 1; } } @@ -445,21 +437,8 @@ static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC) while (h) { /* prevent CRLFCRLF */ if (h->header_len) { - if (h->header_len > sizeof("Status:")-1 && - strncasecmp(h->header, "Status:", sizeof("Status:")-1) == 0) { - if (!ignore_status) { - ignore_status = 1; - PHPWRITE_H(h->header, h->header_len); - PHPWRITE_H("\r\n", 2); - } - } else if (response_status == 304 && h->header_len > sizeof("Content-Type:")-1 && - strncasecmp(h->header, "Content-Type:", sizeof("Content-Type:")-1) == 0) { - h = (sapi_header_struct*)zend_llist_get_next_ex(&sapi_headers->headers, &pos); - continue; - } else { - PHPWRITE_H(h->header, h->header_len); - PHPWRITE_H("\r\n", 2); - } + PHPWRITE_H(h->header, h->header_len); + PHPWRITE_H("\r\n", 2); } h = (sapi_header_struct*)zend_llist_get_next_ex(&sapi_headers->headers, &pos); } @@ -1078,9 +1057,6 @@ static void init_request_info(TSRMLS_D) if (script_path_translated && (script_path_translated_len = strlen(script_path_translated)) > 0 && (script_path_translated[script_path_translated_len-1] == '/' || -#ifdef PHP_WIN32 - script_path_translated[script_path_translated_len-1] == '\\' || -#endif (real_path = tsrm_realpath(script_path_translated, NULL TSRMLS_CC)) == NULL) ) { char *pt = estrndup(script_path_translated, script_path_translated_len); @@ -1612,18 +1588,11 @@ consult the installation file that came with this distribution, or visit \n\ #ifndef PHP_WIN32 /* Pre-fork, if required */ if (getenv("PHP_FCGI_CHILDREN")) { - char * children_str = getenv("PHP_FCGI_CHILDREN"); - children = atoi(children_str); + children = atoi(getenv("PHP_FCGI_CHILDREN")); if (children < 0) { fprintf(stderr, "PHP_FCGI_CHILDREN is not valid\n"); return FAILURE; } - fcgi_set_mgmt_var("FCGI_MAX_CONNS", sizeof("FCGI_MAX_CONNS")-1, children_str, strlen(children_str)); - /* This is the number of concurrent requests, equals FCGI_MAX_CONNS */ - fcgi_set_mgmt_var("FCGI_MAX_REQS", sizeof("FCGI_MAX_REQS")-1, children_str, strlen(children_str)); - } else { - fcgi_set_mgmt_var("FCGI_MAX_CONNS", sizeof("FCGI_MAX_CONNS")-1, "1", sizeof("1")-1); - fcgi_set_mgmt_var("FCGI_MAX_REQS", sizeof("FCGI_MAX_REQS")-1, "1", sizeof("1")-1); } if (children) { diff --git a/sapi/cgi/fastcgi.c b/sapi/cgi/fastcgi.c index 03921995f7..8315c0c472 100644 --- a/sapi/cgi/fastcgi.c +++ b/sapi/cgi/fastcgi.c @@ -133,7 +133,18 @@ typedef union _sa_t { struct sockaddr_in sa_inet; } sa_t; -static HashTable fcgi_mgmt_vars; +typedef struct _fcgi_mgmt_rec { + char* name; + char name_len; + char val; +} fcgi_mgmt_rec; + +static const fcgi_mgmt_rec fcgi_mgmt_vars[] = { + {"FCGI_MAX_CONNS", sizeof("FCGI_MAX_CONNS")-1, 1}, + {"FCGI_MAX_REQS", sizeof("FCGI_MAX_REQS")-1, 1}, + {"FCGI_MPXS_CONNS", sizeof("FCGI_MPXS_CONNS")-1, 0} +}; + static int is_initialized = 0; static int is_fastcgi = 0; @@ -183,8 +194,6 @@ int fcgi_in_shutdown(void) int fcgi_init(void) { if (!is_initialized) { - zend_hash_init(&fcgi_mgmt_vars, 0, NULL, fcgi_free_mgmt_var_cb, 1); - fcgi_set_mgmt_var("FCGI_MPXS_CONNS", sizeof("FCGI_MPXS_CONNS")-1, "0", sizeof("0")-1); #ifdef _WIN32 # if 0 /* TODO: Support for TCP sockets */ @@ -251,9 +260,6 @@ int fcgi_is_fastcgi(void) void fcgi_shutdown(void) { - if (is_initialized) { - zend_hash_destroy(&fcgi_mgmt_vars); - } is_fastcgi = 0; } @@ -744,13 +750,8 @@ static int fcgi_read_request(fcgi_request *req) padding = hdr.paddingLength; } } else if (hdr.type == FCGI_GET_VALUES) { + int j; unsigned char *p = buf + sizeof(fcgi_header); - HashPosition pos; - char * str_index; - uint str_length; - ulong num_index; - int key_type; - zval ** value; if (safe_read(req, buf, len+padding) != len+padding) { req->keep = 0; @@ -762,41 +763,11 @@ static int fcgi_read_request(fcgi_request *req) return 0; } - zend_hash_internal_pointer_reset_ex(req->env, &pos); - while ((key_type = zend_hash_get_current_key_ex(req->env, &str_index, &str_length, &num_index, 0, &pos)) != HASH_KEY_NON_EXISTANT) { - int zlen; - zend_hash_move_forward_ex(req->env, &pos); - if (key_type != HASH_KEY_IS_STRING) { - continue; - } - if (zend_hash_find(&fcgi_mgmt_vars, str_index, str_length, (void**) &value) != SUCCESS) { - continue; - } - --str_length; - zlen = Z_STRLEN_PP(value); - if ((p + 4 + 4 + str_length + zlen) >= (buf + sizeof(buf))) { - break; - } - if (str_length < 0x80) { - *p++ = str_length; - } else { - *p++ = ((str_length >> 24) & 0xff) | 0x80; - *p++ = (str_length >> 16) & 0xff; - *p++ = (str_length >> 8) & 0xff; - *p++ = str_length & 0xff; + for (j = 0; j < sizeof(fcgi_mgmt_vars)/sizeof(fcgi_mgmt_vars[0]); j++) { + if (zend_hash_exists(req->env, fcgi_mgmt_vars[j].name, fcgi_mgmt_vars[j].name_len+1) == 0) { + sprintf((char*)p, "%c%c%s%c", fcgi_mgmt_vars[j].name_len, 1, fcgi_mgmt_vars[j].name, fcgi_mgmt_vars[j].val); + p += fcgi_mgmt_vars[j].name_len + 3; } - if (zlen < 0x80) { - *p++ = zlen; - } else { - *p++ = ((zlen >> 24) & 0xff) | 0x80; - *p++ = (zlen >> 16) & 0xff; - *p++ = (zlen >> 8) & 0xff; - *p++ = zlen & 0xff; - } - memcpy(p, str_index, str_length); - p += str_length; - memcpy(p, Z_STRVAL_PP(value), zlen); - p += zlen; } len = p - buf - sizeof(fcgi_header); len += fcgi_make_header((fcgi_header*)buf, FCGI_GET_VALUES_RESULT, 0, len); @@ -1261,23 +1232,6 @@ void fcgi_impersonate(void) } #endif -void fcgi_set_mgmt_var(const char * name, size_t name_len, const char * value, size_t value_len) -{ - zval * zvalue; - zvalue = pemalloc(sizeof(*zvalue), 1); - Z_TYPE_P(zvalue) = IS_STRING; - Z_STRVAL_P(zvalue) = pestrndup(value, value_len, 1); - Z_STRLEN_P(zvalue) = value_len; - zend_hash_add(&fcgi_mgmt_vars, name, name_len + 1, &zvalue, sizeof(zvalue), NULL); -} - -void fcgi_free_mgmt_var_cb(void * ptr) -{ - zval ** var = (zval **)ptr; - pefree(Z_STRVAL_PP(var), 1); - pefree(*var, 1); -} - /* * Local variables: * tab-width: 4 diff --git a/sapi/cgi/fastcgi.h b/sapi/cgi/fastcgi.h index a9662bc0fb..b5c418138a 100644 --- a/sapi/cgi/fastcgi.h +++ b/sapi/cgi/fastcgi.h @@ -132,10 +132,6 @@ int fcgi_flush(fcgi_request *req, int close); #ifdef PHP_WIN32 void fcgi_impersonate(void); #endif - -void fcgi_set_mgmt_var(const char * name, size_t name_len, const char * value, size_t value_len); -void fcgi_free_mgmt_var_cb(void * ptr); - /* * Local variables: * tab-width: 4 diff --git a/sapi/cgi/tests/010.phpt b/sapi/cgi/tests/010.phpt deleted file mode 100644 index e633ad28ba..0000000000 --- a/sapi/cgi/tests/010.phpt +++ /dev/null @@ -1,53 +0,0 @@ ---TEST-- -Bug #45860 (header() function fails to correctly replace all Status lines) ---SKIPIF-- -<?php include "skipif.inc"; ?> ---FILE-- -<?php - -include "include.inc"; - -$php = get_cgi_path(); -reset_env_vars(); - -$f = tempnam(sys_get_temp_dir(), 'cgitest'); - -putenv("TRANSLATED_PATH=".$f."/x"); -putenv("SCRIPT_FILENAME=".$f."/x"); -file_put_contents($f, '<?php -header("HTTP/1.1 403 Forbidden"); -header("Status: 403 Also Forbidden"); -?>'); - -echo (`$php -n $f`); - -file_put_contents($f, '<?php -header("HTTP/1.1 403 Forbidden"); -?>'); - -echo (`$php -n $f`); - -file_put_contents($f, '<?php -header("Status: 403 Also Forbidden"); -?>'); - -echo (`$php -n $f`); - -echo "Done\n"; - -@unlink($f); -?> ---EXPECTF-- -Status: 403 Forbidden -X-Powered-By: PHP/%s -Content-type: text/html - -Status: 403 Forbidden -X-Powered-By: PHP/%s -Content-type: text/html - -X-Powered-By: PHP/%s -Status: 403 Also Forbidden -Content-type: text/html - -Done diff --git a/sapi/cgi/tests/011.phpt b/sapi/cgi/tests/011.phpt deleted file mode 100644 index 177df021a6..0000000000 --- a/sapi/cgi/tests/011.phpt +++ /dev/null @@ -1,165 +0,0 @@ ---TEST-- -header_remove() ---SKIPIF-- -<?php include "skipif.inc"; ?> ---FILE-- -<?php - -include "include.inc"; - -$php = get_cgi_path(); -reset_env_vars(); - -$f = tempnam(sys_get_temp_dir(), 'cgitest'); - -function test($script) { - file_put_contents($GLOBALS['f'], $script); - $cmd = escapeshellcmd($GLOBALS['php']); - $cmd .= ' -n -dreport_zend_debug=0 -dhtml_errors=0 ' . escapeshellarg($GLOBALS['f']); - echo "----------\n"; - echo rtrim($script) . "\n"; - echo "----------\n"; - passthru($cmd); -} - -test('<?php ?>'); -test('<?php header_remove(); ?>'); -test('<?php header_remove("X-Foo"); ?>'); -test('<?php -header("X-Foo: Bar"); -?>'); -test('<?php -header("X-Foo: Bar"); -header("X-Bar: Baz"); -header_remove("X-Foo"); -?>'); -test('<?php -header("X-Foo: Bar"); -header_remove("X-Foo: Bar"); -?>'); -test('<?php -header("X-Foo: Bar"); -header_remove("X-Foo:"); -?>'); -test('<?php -header("X-Foo: Bar"); -header_remove(); -?>'); -test('<?php -header_remove(""); -?>'); -test('<?php -header_remove(":"); -?>'); -test('<?php -header("X-Foo: Bar"); -echo "flush\n"; -flush(); -header_remove("X-Foo"); -?>'); - -@unlink($f); -?> ---EXPECTF-- ----------- -<?php ?> ----------- -X-Powered-By: PHP/%s -Content-type: text/html - ----------- -<?php header_remove(); ?> ----------- -Content-type: text/html - ----------- -<?php header_remove("X-Foo"); ?> ----------- -X-Powered-By: PHP/%s -Content-type: text/html - ----------- -<?php -header("X-Foo: Bar"); -?> ----------- -X-Powered-By: PHP/%s -X-Foo: Bar -Content-type: text/html - ----------- -<?php -header("X-Foo: Bar"); -header("X-Bar: Baz"); -header_remove("X-Foo"); -?> ----------- -X-Powered-By: PHP/%s -X-Bar: Baz -Content-type: text/html - ----------- -<?php -header("X-Foo: Bar"); -header_remove("X-Foo: Bar"); -?> ----------- -X-Powered-By: PHP/%s -X-Foo: Bar -Content-type: text/html - - -Warning: Header to delete may not contain colon. in %s on line 3 ----------- -<?php -header("X-Foo: Bar"); -header_remove("X-Foo:"); -?> ----------- -X-Powered-By: PHP/%s -X-Foo: Bar -Content-type: text/html - - -Warning: Header to delete may not contain colon. in %s on line 3 ----------- -<?php -header("X-Foo: Bar"); -header_remove(); -?> ----------- -Content-type: text/html - ----------- -<?php -header_remove(""); -?> ----------- -X-Powered-By: PHP/%s -Content-type: text/html - ----------- -<?php -header_remove(":"); -?> ----------- -X-Powered-By: PHP/%s -Content-type: text/html - - -Warning: Header to delete may not contain colon. in %s on line 2 ----------- -<?php -header("X-Foo: Bar"); -echo "flush\n"; -flush(); -header_remove("X-Foo"); -?> ----------- -X-Powered-By: PHP/%s -X-Foo: Bar -Content-type: text/html - -flush - -Warning: Cannot modify header information - headers already sent by (output started at %s:3) in %s on line 5 diff --git a/sapi/cli/php_cli.c b/sapi/cli/php_cli.c index e554051d29..66e206df62 100644 --- a/sapi/cli/php_cli.c +++ b/sapi/cli/php_cli.c @@ -260,10 +260,11 @@ static int sapi_cli_ub_write(const char *str, uint str_length TSRMLS_DC) /* {{{ { ret = sapi_cli_single_write(ptr, remaining); if (!ret) { -#ifndef PHP_CLI_WIN32_NO_CONSOLE +#ifdef PHP_CLI_WIN32_NO_CONSOLE + break; +#else php_handle_aborted_connection(); #endif - break; } ptr += ret; remaining -= ret; @@ -346,8 +347,11 @@ static char* sapi_cli_read_cookies(TSRMLS_D) /* {{{ */ } /* }}} */ -static int sapi_cli_header_handler(sapi_header_struct *h, sapi_header_op_enum op, sapi_headers_struct *s TSRMLS_DC) /* {{{ */ +static int sapi_cli_header_handler(sapi_header_struct *h, sapi_headers_struct *s TSRMLS_DC) /* {{{ */ { + /* free allocated header line */ + efree(h->header); + /* avoid pushing headers into SAPI headers list */ return 0; } /* }}} */ diff --git a/sapi/cli/tests/002-win32.phpt b/sapi/cli/tests/002-win32.phpt index 5a00c67f74..ca0e66ddcd 100644 --- a/sapi/cli/tests/002-win32.phpt +++ b/sapi/cli/tests/002-win32.phpt @@ -10,7 +10,7 @@ if (substr(PHP_OS, 0, 3) != 'WIN') { --FILE-- <?php -$php = getenv('TEST_PHP_EXECUTABLE'); +$php = $_ENV['TEST_PHP_EXECUTABLE']; var_dump(`$php -n -r "var_dump('hello');"`); diff --git a/sapi/cli/tests/022.inc b/sapi/cli/tests/022.inc deleted file mode 100644 index b77512fcf3..0000000000 --- a/sapi/cli/tests/022.inc +++ /dev/null @@ -1,14 +0,0 @@ -<?php - -ob_start(); -var_dump(STDIN); - -$fd = fopen("php://stdin","r"); -var_dump($fd); - -$client_socket = stream_socket_accept($fd); - -$data = ob_get_clean(); -fwrite($client_socket, $data); - -?> diff --git a/sapi/cli/tests/022.phpt b/sapi/cli/tests/022.phpt deleted file mode 100644 index eabb8bdf8d..0000000000 --- a/sapi/cli/tests/022.phpt +++ /dev/null @@ -1,47 +0,0 @@ ---TEST-- -STDIN/OUT/ERR stream type ---SKIPIF-- -<?php -if (!getenv("TEST_PHP_EXECUTABLE")) die("skip TEST_PHP_EXECUTABLE not set"); -if (substr(PHP_OS, 0, 3) == "WIN") die("skip non windows test"); -?> ---FILE-- -<?php -$php = getenv("TEST_PHP_EXECUTABLE"); -$socket_file = dirname(__FILE__) . '/' . pathinfo(__FILE__, PATHINFO_FILENAME) . '.sock'; -$test_file = dirname(__FILE__) . '/' . pathinfo(__FILE__, PATHINFO_FILENAME) . '.inc'; -if (file_exists($socket_file)) { - unlink($socket_file); -} -$socket = stream_socket_server('unix://' . $socket_file); -var_dump($socket); -if (!$socket) { - exit(1); -} -$desc = array( - 0 => $socket, - 1 => STDOUT, - 2 => STDERR, -); -$pipes = array(); -$proc = proc_open("$php -n " . escapeshellarg($test_file), $desc, $pipes); -var_dump($proc); -if (!$proc) { - exit(1); -} - -$client_socket = stream_socket_client('unix://' . $socket_file); -var_dump($client_socket); -echo stream_get_contents($client_socket); -fclose($client_socket); - -proc_terminate($proc); -proc_close($proc); -unlink($socket_file); -?> ---EXPECTF-- -resource(%d) of type (stream) -resource(%d) of type (process) -resource(%d) of type (stream) -resource(%d) of type (stream) -resource(%d) of type (stream) diff --git a/sapi/isapi/stresstest/stresstest.cpp b/sapi/isapi/stresstest/stresstest.cpp index 97824e6be8..c7e634c152 100644 --- a/sapi/isapi/stresstest/stresstest.cpp +++ b/sapi/isapi/stresstest/stresstest.cpp @@ -271,7 +271,7 @@ void DoThreads() { for (i=0; i< numThreads; i++) { CloseHandle(threads[i]); } - delete [] threads; + delete threads; } void DoFileList(const char *filelist, const char *environment) diff --git a/sapi/litespeed/CREDITS b/sapi/litespeed/CREDITS deleted file mode 100644 index 2fa192e97d..0000000000 --- a/sapi/litespeed/CREDITS +++ /dev/null @@ -1,2 +0,0 @@ -litespeed -George Wang diff --git a/sapi/litespeed/Makefile.frag b/sapi/litespeed/Makefile.frag deleted file mode 100644 index e1af2b90ca..0000000000 --- a/sapi/litespeed/Makefile.frag +++ /dev/null @@ -1,3 +0,0 @@ -$(SAPI_LITESPEED_PATH): $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) - $(BUILD_LITESPEED) - diff --git a/sapi/litespeed/README b/sapi/litespeed/README deleted file mode 100644 index 3f138c2163..0000000000 --- a/sapi/litespeed/README +++ /dev/null @@ -1,225 +0,0 @@ -Introduction -============ - -LiteSpeed SAPI module is a dedicated interface for PHP integration with -LiteSpeed Web Server. LiteSpeed SAPI has similar architecture to the -FastCGI SAPI with there major enhancements: better performance, dynamic -spawning and PHP configuration modification through web server -configuration and .htaccess files. - -Our simple benchmark test ("hello world") shows that PHP with -LiteSpeed SAPI has 30% better performance over PHP with FastCGI SAPI, -which is nearly twice the performance that Apache mod_php can deliver. - -A major drawback of FastCGI PHP comparing to Apache mod_php is lacking -the flexibilities in PHP configurations. PHP configurations cannot be -changed at runtime via configuration files like .htaccess files or web -server's virtual host configuration. In shared hosting environment, -each hosting account will has its own "open_basedir" overridden in -server configuration to enhance server security when mod_php is used. -usually, FastCGI PHP is not an option in shared hosting environment -due to lacking of this flexibility. LiteSpeed SAPI is carefully designed -to address this issue. PHP configurations can be modified the same way -as that in mod_php with the the same configuration directives. - -PHP with LiteSpeed SAPI is highly recommended over FastCGI PHP for -PHP scripting with LiteSpeed web server. - - -Building PHP with LiteSpeed SAPI -================================ - -You need to add "--with-litespeed" to the configure command to build -PHP with LiteSpeed SAPI, all other SAPI related configure options -should be removed. - -For example: - ./configure --with-litespeed - make - -You should find an executable called 'php' under sapi/litespeed/ -directory after the compilation succeeds. Copy it to -'lsws/fcgi-bin/lsphp' or wherever you prefer, if LiteSpeed web server -has been configured to run PHP with LiteSpeed SAPI already, you just -need to overwrite the old executable with this one and you are all -set. - -Start PHP from command line -=========================== - -Usually, lsphp is managed by LiteSpeed web server in a single server -installation. lsphp can be used in clustered environment with one -LiteSpeed web server at the front, load balancing lsphp processes -running on multiple backend servers. In such environment, lsphp can be -start manually from command with option "-b <socket_address>", socket -address can be IPv4, IPv6 or Unix Domain Socket address. -for example: - - ./lsphp -b [::]:3000 - -have lsphp bind to port 3000 on all IPv4 and IPv6 address, - - ./lsphp -b *:3000 - -have lsphp bind to port 300 on all IPv4 address. - - ./lsphp -b 192.168.0.2:3000 - -have lsphp bind to address 192.168.0.2:3000. - - ./lsphp -b /tmp/lsphp_manual.sock - -have lsphp accept request on Unix domain socket "/tmp/lsphp_manual.sock" - - -Using LiteSpeed PHP with LiteSpeed Web Server -============================================= - -Detailed information about how to configure LiteSpeed web server with -PHP support is available from our website, at: - -http://www.litespeedtech.com/docs/HowTo_QA.html - -Usually, PHP support has been configured out of box, you don't need to -change it unless you want to change PHP interface from FastCGI to -LiteSpeed SAPI or vice versa. - -Brief instructions are as follow: - -1) Login to web administration interface, go to 'Server'->'Ext App' tab, - add an external application of type "LSAPI app", "Command" should be - set to a shell command that executes the PHP binary you just built. - "Instances" should be set to "1". Add "LSAPI_CHILDREN" environment - variable to match the value of "Max Connections". More tunable - environment variable described below can be added. - -2) Go to 'Server'->'Script Handler' tab, add a script handler - configuration: set 'suffix' to 'php', 'Handler Type' to 'LiteSpeed - API', 'Handler Name' should be the name of external application - just defined. - - -3) Click 'Apply Changes' link on the top left of the page, then click - 'graceful restart'. Now PHP is running with LiteSpeed SAPI. - -Tunings -------- - -There are a few environment variables that can be tweaked to control the -behavior of LSAPI application. - -* LSAPI_CHILDREN or PHP_LSAPI_CHILDREN (default: 0) - -There are two ways to let PHP handle multiple requests concurrently, -Server Managed Mode and Self Managed Mode. In Server Managed Mode, -LiteSpeed web server dynamically spawn/stop PHP processes, in this mode -"Instances" should match "Max Connections" configuration for PHP -external application. To start PHP in Self Managed Mode, "Instances" -should be set to "1", while "LSAPI_CHILDREN" environment variable should -be set to match the value of "Max Connections" and >1. Web Server will -start one PHP process, this process will start/stop children PHP processes -dynamically based on on demand. If "LSAPI_CHILDREN" <=1, PHP will be -started in server managed mode. - -Self Managed Mode is preferred because all PHP processes can share one -shared memory block for the opcode cache. - -Usually, there is no need to set value of LSAPI_CHILDREN over 100 in -most server environment. - - -* LSAPI_AVOID_FORK (default: 0) - -LSAPI_AVOID_FORK specifies the policy of the internal process manager in -"Self Managed Mode". When set to 0, the internal process manager will stop -and start children process on demand to save system resource. This is -preferred in a shared hosting environment. When set to 1, the internal -process manager will try to avoid freqently stopping and starting children -process. This might be preferred in a dedicate hosting environment. - - -* LSAPI_EXTRA_CHILDREN (default: 1/3 of LSAPI_CHILDREN or 0) - -LSAPI_EXTRA_CHILDREN controls the maximum number of extra children processes -can be started when some or all existing children processes are in -malfunctioning state. Total number of children processes will be reduced to -LSAPI_CHILDREN level as soon as service is back to normal. -When LSAPI_AVOID_FORK is set to 0, the default value is 1/3 of -LSAPI_CHIDLREN, When LSAPI_AVOID_FORK is set to 1, the default value is 0. - - -* LSAPI_MAX_REQS or PHP_LSAPI_MAX_REQUESTS (default value: 10000) - -This controls how many requests each child process will handle before -it exits automatically. Several PHP functions have been identified -having memory leaks. This parameter can help reducing memory usage -of leaky PHP functions. - - -* LSAPI_MAX_IDLE (default value: 300 seconds) - -In Self Managed Mode, LSAPI_MAX_IDLE controls how long a idle child -process will wait for a new request before it exits. This option help -releasing system resources taken by idle processes. - - -* LSAPI_MAX_IDLE_CHILDREN - (default value: 1/3 of LSAPI_CHILDREN or LSAPI_CHILDREN) - -In Self Managed Mode, LSAI_MAX_IDLE_CHILDREN controls how many idle -children processes are allowed. Excessive idle children processes -will be killed by the parent process immediately. -When LSAPI_AVOID_FORK is set to 0, the default value is 1/3 of -LSAPI_CHIDLREN, When LSAPI_AVOID_FORK is set to 1, the default value -is LSAPI_CHILDREN. - - -* LSAPI_MAX_PROCESS_TIME (default value: 300 seconds) - -In Self Managed Mode, LSAPI_MAX_PROCESS_TIME controls the maximum -processing time allowed when processing a request. If a child process -can not finish processing of a request in the given time period, it -will be killed by the parent process. This option can help getting rid -of dead or runaway child process. - - -* LSAPI_PGRP_MAX_IDLE (default value: FOREVER ) - -In Self Managed Mode, LSAPI_PGRP_MAX_IDLE controls how long the parent -process will wait before exiting when there is no child process. -This option help releasing system resources taken by an idle parent -process. - - -* LSAPI_PPID_NO_CHECK - -By default a LSAPI application check the existence of its parent process -and exits automatically if the parent process died. This is to reduce -orphan process when web server is restarted. However, it is desireable -to disable this feature, such as when a LSAPI process was started -manually from command line. LSAPI_PPID_NO_CHECK should be set when -you want to disable the checking of existence of parent process. -When PHP started by "-b" option, it is disabled automatically. - - -Compatibility with Apache mod_php -================================= - -LSAPI PHP supports PHP configuration overridden via web server configuration -as well as .htaccess. -Since 4.0 release "apache_response_headers" function is supported. - - - -Contact -======= - -For support questions, please post to our free support forum, at: - -http://www.litespeedtech.com/forum/ - -For bug report, please send bug report to bug [at] litespeedtech.com. - - - - diff --git a/sapi/litespeed/config.m4 b/sapi/litespeed/config.m4 deleted file mode 100644 index 5499baf628..0000000000 --- a/sapi/litespeed/config.m4 +++ /dev/null @@ -1,31 +0,0 @@ -dnl -dnl $Id$ -dnl - -AC_MSG_CHECKING(for LiteSpeed support) - -PHP_ARG_WITH(litespeed,, -[ --with-litespeed Build PHP as litespeed module], no) - -if test "$PHP_LITESPEED" != "no"; then - PHP_ADD_MAKEFILE_FRAGMENT($abs_srcdir/sapi/litespeed/Makefile.frag,$abs_srcdir/sapi/litespeed,sapi/litespeed) - SAPI_LITESPEED_PATH=sapi/litespeed/php - PHP_SUBST(SAPI_LITESPEED_PATH) - PHP_SELECT_SAPI(litespeed, program, lsapi_main.c lsapilib.c, "", '$(SAPI_LITESPEED_PATH)') - case $host_alias in - *darwin*) - BUILD_LITESPEED="\$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_SAPI_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_LITESPEED_PATH)" - ;; - *cygwin*) - SAPI_LITESPEED_PATH=sapi/litespeed/php.exe - BUILD_LITESPEED="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_SAPI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_LITESPEED_PATH)" - ;; - *) - BUILD_LITESPEED="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_SAPI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_LITESPEED_PATH)" - ;; - esac - - PHP_SUBST(BUILD_LITESPEED) -fi - -AC_MSG_RESULT($PHP_LITESPEED) diff --git a/sapi/litespeed/lsapi_main.c b/sapi/litespeed/lsapi_main.c deleted file mode 100644 index 967c9acc60..0000000000 --- a/sapi/litespeed/lsapi_main.c +++ /dev/null @@ -1,909 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2007 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available at through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Author: George Wang <gwang@litespeedtech.com> | - +----------------------------------------------------------------------+ -*/ - -/* $Id$ */ - -#include "php.h" -#include "SAPI.h" -#include "php_main.h" -#include "php_ini.h" -#include "php_variables.h" -#include "zend_highlight.h" -#include "zend.h" - -#include "lsapilib.h" - -#include <stdio.h> - -#if HAVE_STDLIB_H -#include <stdlib.h> -#endif - -#if HAVE_UNISTD_H -#include <unistd.h> -#endif - -#ifdef PHP_WIN32 - -#include <io.h> -#include <fcntl.h> -#include "win32/php_registry.h" - -#else - -#include <sys/wait.h> - -#endif - -#include <sys/stat.h> - -#if HAVE_SYS_TYPES_H - -#include <sys/types.h> - -#endif - -#if HAVE_SIGNAL_H - -#include <signal.h> - -#endif - -#include <sys/socket.h> -#include <arpa/inet.h> -#include <netinet/in.h> - - -#define SAPI_LSAPI_MAX_HEADER_LENGTH 2048 - -static int lsapi_mode = 1; -static char *php_self = ""; -static char *script_filename = ""; -static int source_highlight = 0; - -#ifdef ZTS -zend_compiler_globals *compiler_globals; -zend_executor_globals *executor_globals; -php_core_globals *core_globals; -sapi_globals_struct *sapi_globals; -void ***tsrm_ls; -#endif - -zend_module_entry litespeed_module_entry; - -/* {{{ php_lsapi_startup - */ -static int php_lsapi_startup(sapi_module_struct *sapi_module) -{ - if (php_module_startup(sapi_module, NULL, 0)==FAILURE) { - return FAILURE; - } - return SUCCESS; -} -/* }}} */ - - - -/* {{{ sapi_lsapi_ub_write - */ -static int sapi_lsapi_ub_write(const char *str, uint str_length TSRMLS_DC) -{ - int ret; - int remain; - if ( lsapi_mode ) { - ret = LSAPI_Write( str, str_length ); - if ( ret < str_length ) { - php_handle_aborted_connection(); - return str_length - ret; - } - } else { - remain = str_length; - while( remain > 0 ) { - ret = write( 1, str, remain ); - if ( ret <= 0 ) { - php_handle_aborted_connection(); - return str_length - remain; - } - str += ret; - remain -= ret; - } - } - return str_length; -} -/* }}} */ - - -/* {{{ sapi_lsapi_flush - */ -static void sapi_lsapi_flush( void * server_context ) -{ - if ( lsapi_mode ) { - if ( LSAPI_Flush() == -1) { - php_handle_aborted_connection(); - } - } -} -/* }}} */ - - -/* {{{ sapi_lsapi_deactivate - */ -static int sapi_lsapi_deactivate(TSRMLS_D) -{ - LSAPI_Finish(); - return SUCCESS; -} -/* }}} */ - - - - -/* {{{ sapi_lsapi_getenv - */ -static char *sapi_lsapi_getenv( char * name, size_t name_len TSRMLS_DC ) -{ - if ( lsapi_mode ) { - return LSAPI_GetEnv( name ); - } else { - return getenv( name ); - } -} -/* }}} */ - - - -static int add_variable( const char * pKey, int keyLen, const char * pValue, int valLen, - void * arg ) -{ - php_register_variable_safe((char *)pKey, (char *)pValue, valLen, (zval *)arg TSRMLS_CC); - return 1; -} - - - -/* {{{ sapi_lsapi_register_variables - */ -static void sapi_lsapi_register_variables(zval *track_vars_array TSRMLS_DC) -{ - - if ( lsapi_mode ) { - LSAPI_ForeachHeader( add_variable, track_vars_array ); - LSAPI_ForeachEnv( add_variable, track_vars_array ); - php_import_environment_variables(track_vars_array TSRMLS_CC); - - php_register_variable("PHP_SELF", (SG(request_info).request_uri ? SG(request_info).request_uri:""), track_vars_array TSRMLS_CC); - } else { - php_import_environment_variables(track_vars_array TSRMLS_CC); - - php_register_variable("PHP_SELF", php_self, track_vars_array TSRMLS_CC); - php_register_variable("SCRIPT_NAME", php_self, track_vars_array TSRMLS_CC); - php_register_variable("SCRIPT_FILENAME", script_filename, track_vars_array TSRMLS_CC); - php_register_variable("PATH_TRANSLATED", script_filename, track_vars_array TSRMLS_CC); - php_register_variable("DOCUMENT_ROOT", "", track_vars_array TSRMLS_CC); - - } -} -/* }}} */ - - -/* {{{ sapi_lsapi_read_post - */ -static int sapi_lsapi_read_post(char *buffer, uint count_bytes TSRMLS_DC) -{ - if ( lsapi_mode ) { - return LSAPI_ReadReqBody( buffer, count_bytes ); - } else { - return 0; - } -} -/* }}} */ - - - - -/* {{{ sapi_lsapi_read_cookies - */ -static char *sapi_lsapi_read_cookies(TSRMLS_D) -{ - if ( lsapi_mode ) { - return LSAPI_GetHeader( H_COOKIE ); - } else { - return NULL; - } -} -/* }}} */ - - -/* {{{ sapi_lsapi_send_headers - */ -static int sapi_lsapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC) -{ - sapi_header_struct *h; - zend_llist_position pos; - if ( lsapi_mode ) { - LSAPI_SetRespStatus( SG(sapi_headers).http_response_code ); - - h = zend_llist_get_first_ex(&sapi_headers->headers, &pos); - while (h) { - if ( h->header_len > 0 ) { - LSAPI_AppendRespHeader(h->header, h->header_len); - } - h = zend_llist_get_next_ex(&sapi_headers->headers, &pos); - } - if (SG(sapi_headers).send_default_content_type) { - char *hd; - int len; - char headerBuf[SAPI_LSAPI_MAX_HEADER_LENGTH]; - - hd = sapi_get_default_content_type(TSRMLS_C); - len = snprintf( headerBuf, SAPI_LSAPI_MAX_HEADER_LENGTH - 1, - "Content-type: %s", hd ); - efree(hd); - - LSAPI_AppendRespHeader( headerBuf, len ); - } - } - LSAPI_FinalizeRespHeaders(); - return SAPI_HEADER_SENT_SUCCESSFULLY; - - -} -/* }}} */ - - -/* {{{ sapi_lsapi_send_headers - */ -static void sapi_lsapi_log_message(char *message) -{ - int len = strlen( message ); - LSAPI_Write_Stderr( message, len); -} -/* }}} */ - - -/* {{{ sapi_module_struct cgi_sapi_module - */ -static sapi_module_struct lsapi_sapi_module = -{ - "litespeed", - "LiteSpeed", - - php_lsapi_startup, /* startup */ - php_module_shutdown_wrapper, /* shutdown */ - - NULL, /* activate */ - sapi_lsapi_deactivate, /* deactivate */ - - sapi_lsapi_ub_write, /* unbuffered write */ - sapi_lsapi_flush, /* flush */ - NULL, /* get uid */ - sapi_lsapi_getenv, /* getenv */ - - php_error, /* error handler */ - - NULL, /* header handler */ - sapi_lsapi_send_headers, /* send headers handler */ - NULL, /* send header handler */ - - sapi_lsapi_read_post, /* read POST data */ - sapi_lsapi_read_cookies, /* read Cookies */ - - sapi_lsapi_register_variables, /* register server variables */ - sapi_lsapi_log_message, /* Log message */ - - NULL, /* php.ini path override */ - NULL, /* block interruptions */ - NULL, /* unblock interruptions */ - NULL, /* default post reader */ - NULL, /* treat data */ - NULL, /* executable location */ - - 0, /* php.ini ignore */ - - STANDARD_SAPI_MODULE_PROPERTIES - -}; -/* }}} */ - -static int init_request_info( TSRMLS_D ) -{ - char * pContentType = LSAPI_GetHeader( H_CONTENT_TYPE ); - char * pAuth; - - SG(request_info).content_type = pContentType ? pContentType : ""; - SG(request_info).request_method = LSAPI_GetRequestMethod(); - SG(request_info).query_string = LSAPI_GetQueryString(); - SG(request_info).request_uri = LSAPI_GetScriptName(); - SG(request_info).content_length = LSAPI_GetReqBodyLen(); - SG(request_info).path_translated = LSAPI_GetScriptFileName(); - - /* It is not reset by zend engine, set it to 0. */ - SG(sapi_headers).http_response_code = 0; - - pAuth = LSAPI_GetHeader( H_AUTHORIZATION ); - php_handle_auth_data(pAuth TSRMLS_CC); -} - -static int lsapi_module_main(int show_source TSRMLS_DC) -{ - zend_file_handle file_handle = {0}; - - if (php_request_startup(TSRMLS_C) == FAILURE ) { - return -1; - } - if (show_source) { - zend_syntax_highlighter_ini syntax_highlighter_ini; - - php_get_highlight_struct(&syntax_highlighter_ini); - highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini TSRMLS_CC); - } else { - file_handle.type = ZEND_HANDLE_FILENAME; - file_handle.handle.fd = 0; - file_handle.filename = SG(request_info).path_translated; - file_handle.free_filename = 0; - file_handle.opened_path = NULL; - - php_execute_script(&file_handle TSRMLS_CC); - } - zend_try { - php_request_shutdown(NULL); - } zend_end_try(); - return 0; -} - - -static int alter_ini( const char * pKey, int keyLen, const char * pValue, int valLen, - void * arg ) -{ - int type = ZEND_INI_PERDIR; - if ( '\001' == *pKey ) { - ++pKey; - if ( *pKey == 4 ) { - type = ZEND_INI_SYSTEM; - } - ++pKey; - --keyLen; - zend_alter_ini_entry((char *)pKey, keyLen, - (char *)pValue, valLen, - type, PHP_INI_STAGE_ACTIVATE); - } - return 1; -} - - -static void override_ini() -{ - - LSAPI_ForeachSpecialEnv( alter_ini, NULL ); - -} - -static int processReq( TSRMLS_D ) -{ - int ret = 0; - zend_first_try { - /* avoid server_context==NULL checks */ - SG(server_context) = (void *) 1; - - init_request_info( TSRMLS_C ); - - override_ini(); - - if ( lsapi_module_main( source_highlight TSRMLS_CC ) == -1 ) { - ret = -1; - } - } zend_end_try(); - return ret; -} - -static void cli_usage( TSRMLS_D ) -{ - static const char * usage = - "Usage: php\n" - " php -[b|c|h|i|q|s|v|?] [<file>] [args...]\n" - " Run in LSAPI mode, only '-b', '-s' and '-c' are effective\n" - " Run in Command Line Interpreter mode when parameters are specified\n" - "\n" - " -b <address:port>|<port> Bind Path for external LSAPI Server mode\n" - " -c <path>|<file> Look for php.ini file in this directory\n" - " -h This help\n" - " -i PHP information\n" - " -q Quiet-mode. Suppress HTTP Header output.\n" - " -s Display colour syntax highlighted source.\n" - " -v Version number\n" - " -? This help\n" - "\n" - " args... Arguments passed to script.\n"; - php_output_startup(); - php_output_activate(TSRMLS_C); - php_printf( usage ); -#ifdef PHP_OUTPUT_NEWAPI - php_output_end_all(TSRMLS_C); -#else - php_end_ob_buffers(1 TSRMLS_CC); -#endif -} - -static int parse_opt( int argc, char * argv[], int *climode, - char **php_ini_path, char ** php_bind ) -{ - char ** p = &argv[1]; - char ** argend= &argv[argc]; - int c; - while (( p < argend )&&(**p == '-' )) { - c = *((*p)+1); - ++p; - switch( c ) { - case 'b': - if ( p >= argend ) { - fprintf( stderr, "TCP or socket address must be specified following '-b' option.\n"); - return -1; - } - *php_bind = *p++; - break; - - case 'c': - if ( p >= argend ) { - fprintf( stderr, "<path> or <file> must be specified following '-c' option.\n"); - - return -1; - } - *php_ini_path = *p++; - break; - case 's': - source_highlight = 1; - break; - case 'h': - case 'i': - case 'q': - case 'v': - case '?': - default: - *climode = 1; - break; - } - } - if ( p - argv < argc ) { - *climode = 1; - } - return 0; -} - -static int cli_main( int argc, char * argv[] ) -{ - - static const char * ini_defaults[] = { - "report_zend_debug", "0", - "display_errors", "1", - "register_argc_argv", "1", - "html_errors", "0", - "implicit_flush", "1", - "output_buffering", "0", - "max_execution_time", "0", - NULL - }; - - const char ** ini; - char ** p = &argv[1]; - char ** argend= &argv[argc]; - int ret = 0; - int c; - lsapi_mode = 0; /* enter CLI mode */ - -#ifdef PHP_WIN32 - _fmode = _O_BINARY; /*sets default for file streams to binary */ - setmode(_fileno(stdin), O_BINARY); /* make the stdio mode be binary */ - setmode(_fileno(stdout), O_BINARY); /* make the stdio mode be binary */ - setmode(_fileno(stderr), O_BINARY); /* make the stdio mode be binary */ -#endif - - zend_first_try { - SG(server_context) = (void *) 1; - - zend_uv.html_errors = 0; /* tell the engine we're in non-html mode */ - CG(in_compilation) = 0; /* not initialized but needed for several options */ - EG(uninitialized_zval_ptr) = NULL; - - for( ini = ini_defaults; *ini; ini+=2 ) { - zend_alter_ini_entry( (char *)*ini, strlen( *ini )+1, - (char *)*(ini+1), strlen( *(ini+1) ), - PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE); - } - - while (( p < argend )&&(**p == '-' )) { - c = *((*p)+1); - ++p; - switch( c ) { - case 'q': - break; - case 'i': - if (php_request_startup(TSRMLS_C) != FAILURE) { - php_print_info(0xFFFFFFFF TSRMLS_CC); -#ifdef PHP_OUTPUT_NEWAPI - php_output_end_all(TSRMLS_C); -#else - php_end_ob_buffers(1 TSRMLS_CC); -#endif - php_request_shutdown( NULL ); - } - ret = 1; - break; - case 'v': - if (php_request_startup(TSRMLS_C) != FAILURE) { -#if ZEND_DEBUG - php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); -#else - php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); -#endif -#ifdef PHP_OUTPUT_NEWAPI - php_output_end_all(TSRMLS_C); -#else - php_end_ob_buffers(1 TSRMLS_CC); -#endif - php_request_shutdown( NULL ); - } - ret = 1; - break; - case 'c': - ++p; - /* fall through */ - case 's': - break; - - case 'h': - case '?': - default: - cli_usage(TSRMLS_C); - ret = 1; - break; - - } - } - if ( !ret ) { - if ( *p ) { - zend_file_handle file_handle = {0}; - - file_handle.type = ZEND_HANDLE_FP; - file_handle.handle.fp = VCWD_FOPEN(*p, "rb"); - - if ( file_handle.handle.fp ) { - script_filename = *p; - php_self = *p; - - SG(request_info).path_translated = *p; - SG(request_info).argc = argc - (p - argv); - SG(request_info).argv = p; - - if (php_request_startup(TSRMLS_C) == FAILURE ) { - fclose( file_handle.handle.fp ); - ret = 2; - } else { - if (source_highlight) { - zend_syntax_highlighter_ini syntax_highlighter_ini; - - php_get_highlight_struct(&syntax_highlighter_ini); - highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini TSRMLS_CC); - } else { - file_handle.filename = *p; - file_handle.free_filename = 0; - file_handle.opened_path = NULL; - - php_execute_script(&file_handle TSRMLS_CC); - } - - php_request_shutdown( NULL ); - } - } else { - php_printf("Could not open input file: %s.\n", *p); - } - } else { - cli_usage(TSRMLS_C); - } - } - - }zend_end_try(); - - php_module_shutdown(TSRMLS_C); - -#ifdef ZTS - tsrm_shutdown(); -#endif - return ret; -} - -static int s_stop; -void litespeed_cleanup(int signal) -{ - s_stop = signal; -} - - -void start_children( int children ) -{ - struct sigaction act, old_term, old_quit, old_int, old_usr1; - int running = 0; - int status; - pid_t pid; - - /* Create a process group */ - setsid(); - - /* Set up handler to kill children upon exit */ - act.sa_flags = 0; - act.sa_handler = litespeed_cleanup; - if( sigaction( SIGTERM, &act, &old_term ) || - sigaction( SIGINT, &act, &old_int ) || - sigaction( SIGUSR1, &act, &old_usr1 ) || - sigaction( SIGQUIT, &act, &old_quit )) { - perror( "Can't set signals" ); - exit( 1 ); - } - s_stop = 0; - while( 1 ) { - while((!s_stop )&&( running < children )) { - pid = fork(); - switch( pid ) { - case 0: /* children process */ - - /* don't catch our signals */ - sigaction( SIGTERM, &old_term, 0 ); - sigaction( SIGQUIT, &old_quit, 0 ); - sigaction( SIGINT, &old_int, 0 ); - sigaction( SIGUSR1, &old_usr1, 0 ); - return ; - case -1: - perror( "php (pre-forking)" ); - exit( 1 ); - break; - default: /* parent process */ - running++; - break; - } - } - if ( s_stop ) { - break; - } - pid = wait( &status ); - running--; - } - kill( -getpgrp(), SIGUSR1 ); - exit( 0 ); -} - - - -#include <fcntl.h> -int main( int argc, char * argv[] ) -{ - int ret; - int bindFd; - - char * php_ini_path = NULL; - char * php_bind = NULL; - char * p; - int n; - int climode = 0; - -#ifdef HAVE_SIGNAL_H -#if defined(SIGPIPE) && defined(SIG_IGN) - signal(SIGPIPE, SIG_IGN); -#endif -#endif - -#ifdef ZTS - tsrm_startup(1, 1, 0, NULL); -#endif - - if (argc > 1 ) { - if ( parse_opt( argc, argv, &climode, - &php_ini_path, &php_bind ) == -1 ) { - return 1; - } - } - if ( climode ) { - lsapi_sapi_module.phpinfo_as_text = 1; - } - sapi_startup(&lsapi_sapi_module); - -#ifdef ZTS - compiler_globals = ts_resource(compiler_globals_id); - executor_globals = ts_resource(executor_globals_id); - core_globals = ts_resource(core_globals_id); - sapi_globals = ts_resource(sapi_globals_id); - tsrm_ls = ts_resource(0); - - SG(request_info).path_translated = NULL; -#endif - - lsapi_sapi_module.executable_location = argv[0]; - - if ( php_ini_path ) { - lsapi_sapi_module.php_ini_path_override = php_ini_path; - } - - if (php_module_startup(&lsapi_sapi_module, &litespeed_module_entry, 1) == FAILURE) { -#ifdef ZTS - tsrm_shutdown(); -#endif - return FAILURE; - } - - if ( climode ) { - return cli_main(argc, argv); - } - - - if ( php_bind ) { - bindFd = LSAPI_CreateListenSock( php_bind, 10 ); - if ( bindFd == -1 ) { - fprintf( stderr, - "Failed to bind socket [%s]: %s\n", php_bind, strerror( errno ) ); - exit( 2 ); - } - if ( bindFd != 0 ) { - dup2( bindFd, 0 ); - close( bindFd ); - } - } - - LSAPI_Init(); - - LSAPI_Init_Env_Parameters( NULL ); - - if ( php_bind ) { - LSAPI_No_Check_ppid(); - } - - while( LSAPI_Prefork_Accept_r( &g_req ) >= 0 ) { - ret = processReq(TSRMLS_C); - LSAPI_Finish(); - if ( ret ) { - break; - } - } - php_module_shutdown(TSRMLS_C); - -#ifdef ZTS - tsrm_shutdown(); -#endif - return ret; -} - - -/* LiteSpeed PHP module starts here */ - - - -PHP_FUNCTION(litespeed_request_headers); -PHP_FUNCTION(litespeed_response_headers); - -PHP_MINFO_FUNCTION(litespeed); - -zend_function_entry litespeed_functions[] = { - PHP_FE(litespeed_request_headers, NULL) - PHP_FE(litespeed_response_headers, NULL) - PHP_FALIAS(getallheaders, litespeed_request_headers, NULL) - PHP_FALIAS(apache_request_headers, litespeed_request_headers, NULL) - PHP_FALIAS(apache_response_headers, litespeed_response_headers, NULL) - {NULL, NULL, NULL} -}; - -static PHP_MINIT_FUNCTION(litespeed) -{ - /* REGISTER_INI_ENTRIES(); */ - return SUCCESS; -} - - -static PHP_MSHUTDOWN_FUNCTION(litespeed) -{ - /* UNREGISTER_INI_ENTRIES(); */ - return SUCCESS; -} - -zend_module_entry litespeed_module_entry = { - STANDARD_MODULE_HEADER, - "litespeed", - litespeed_functions, - PHP_MINIT(litespeed), - PHP_MSHUTDOWN(litespeed), - NULL, - NULL, - NULL, - NO_VERSION_YET, - STANDARD_MODULE_PROPERTIES -}; - -static int add_associate_array( const char * pKey, int keyLen, const char * pValue, int valLen, - void * arg ) -{ - add_assoc_string_ex( (zval *)arg, (char *)pKey, keyLen+1, (char *)pValue, 1 ); - return 1; -} - - -/* {{{ proto array litespeed_request_headers(void) - Fetch all HTTP request headers */ -PHP_FUNCTION(litespeed_request_headers) -{ - /* TODO: */ - if (ZEND_NUM_ARGS() > 0) { - WRONG_PARAM_COUNT; - } - array_init(return_value); - - LSAPI_ForeachOrgHeader( add_associate_array, return_value ); - -} -/* }}} */ - - - -/* {{{ proto array litespeed_response_headers(void) - Fetch all HTTP response headers */ -PHP_FUNCTION(litespeed_response_headers) -{ - sapi_header_struct *h; - zend_llist_position pos; - char * p; - int len; - char headerBuf[SAPI_LSAPI_MAX_HEADER_LENGTH]; - - if (ZEND_NUM_ARGS() > 0) { - WRONG_PARAM_COUNT; - } - - if (!&SG(sapi_headers).headers) { - RETURN_FALSE; - } - array_init(return_value); - - h = zend_llist_get_first_ex(&SG(sapi_headers).headers, &pos); - while (h) { - if ( h->header_len > 0 ) { - p = strchr( h->header, ':' ); - len = p - h->header; - if (( p )&&( len > 0 )) { - memmove( headerBuf, h->header, len ); - while( len > 0 && (isspace( headerBuf[len-1])) ) { - --len; - } - headerBuf[len] = 0; - if ( len ) { - while( isspace(*++p)); - add_assoc_string_ex(return_value, headerBuf, len+1, p, 1 ); - } - } - } - h = zend_llist_get_next_ex(&SG(sapi_headers).headers, &pos); - } -} - -/* }}} */ - - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: sw=4 ts=4 fdm=marker - * vim<600: sw=4 ts=4 - */ - - diff --git a/sapi/litespeed/lsapidef.h b/sapi/litespeed/lsapidef.h deleted file mode 100644 index 276c579b2c..0000000000 --- a/sapi/litespeed/lsapidef.h +++ /dev/null @@ -1,196 +0,0 @@ - -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2007 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available at through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Author: George Wang <gwang@litespeedtech.com> | - +----------------------------------------------------------------------+ -*/ - - -/* -Copyright (c) 2007, Lite Speed Technologies Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - * Neither the name of the Lite Speed Technologies Inc nor the - names of its contributors may be used to endorse or promote - products derived from this software without specific prior - written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#ifndef _LSAPIDEF_H_ -#define _LSAPIDEF_H_ - -#include <inttypes.h> - -#if defined (c_plusplus) || defined (__cplusplus) -extern "C" { -#endif - -enum -{ - H_ACCEPT = 0, - H_ACC_CHARSET, - H_ACC_ENCODING, - H_ACC_LANG, - H_AUTHORIZATION, - H_CONNECTION, - H_CONTENT_TYPE, - H_CONTENT_LENGTH, - H_COOKIE, - H_COOKIE2, - H_HOST, - H_PRAGMA, - H_REFERER, - H_USERAGENT, - H_CACHE_CTRL, - H_IF_MODIFIED_SINCE, - H_IF_MATCH, - H_IF_NO_MATCH, - H_IF_RANGE, - H_IF_UNMOD_SINCE, - H_KEEP_ALIVE, - H_RANGE, - H_X_FORWARDED_FOR, - H_VIA, - H_TRANSFER_ENCODING - -}; -#define LSAPI_SOCK_FILENO 0 - -#define LSAPI_VERSION_B0 'L' -#define LSAPI_VERSION_B1 'S' - -/* Values for m_flag in lsapi_packet_header */ -#define LSAPI_ENDIAN_LITTLE 0 -#define LSAPI_ENDIAN_BIG 1 -#define LSAPI_ENDIAN_BIT 1 - -#if defined(__i386__)||defined( __x86_64 )||defined( __x86_64__ ) -#define LSAPI_ENDIAN LSAPI_ENDIAN_LITTLE -#else -#define LSAPI_ENDIAN LSAPI_ENDIAN_BIG -#endif - -/* Values for m_type in lsapi_packet_header */ -#define LSAPI_BEGIN_REQUEST 1 -#define LSAPI_ABORT_REQUEST 2 -#define LSAPI_RESP_HEADER 3 -#define LSAPI_RESP_STREAM 4 -#define LSAPI_RESP_END 5 -#define LSAPI_STDERR_STREAM 6 -#define LSAPI_REQ_RECEIVED 7 - - -#define LSAPI_MAX_HEADER_LEN 65535 -#define LSAPI_MAX_DATA_PACKET_LEN 16384 - -#define LSAPI_RESP_HTTP_HEADER_MAX 4096 -#define LSAPI_PACKET_HEADER_LEN 8 - - -struct lsapi_packet_header -{ - char m_versionB0; /* LSAPI protocol version */ - char m_versionB1; - char m_type; - char m_flag; - union - { - int32_t m_iLen; /* include this header */ - char m_bytes[4]; - }m_packetLen; -}; - -/* - LSAPI request header packet - - 1. struct lsapi_req_header - 2. struct lsapi_http_header_index - 3. lsapi_header_offset * unknownHeaders - 4. org http request header - 5. request body if available -*/ - -struct lsapi_req_header -{ - struct lsapi_packet_header m_pktHeader; - - int32_t m_httpHeaderLen; - int32_t m_reqBodyLen; - int32_t m_scriptFileOff; /* path to the script file. */ - int32_t m_scriptNameOff; /* decrypted URI, without pathinfo, */ - int32_t m_queryStringOff; /* Query string inside env */ - int32_t m_requestMethodOff; - int32_t m_cntUnknownHeaders; - int32_t m_cntEnv; - int32_t m_cntSpecialEnv; -} ; - - -struct lsapi_http_header_index -{ - int16_t m_headerLen[H_TRANSFER_ENCODING+1]; - int32_t m_headerOff[H_TRANSFER_ENCODING+1]; -} ; - -struct lsapi_header_offset -{ - int32_t nameOff; - int32_t nameLen; - int32_t valueOff; - int32_t valueLen; -} ; - -struct lsapi_resp_info -{ - int32_t m_cntHeaders; - int32_t m_status; -}; - -struct lsapi_resp_header -{ - struct lsapi_packet_header m_pktHeader; - struct lsapi_resp_info m_respInfo; -}; - -#if defined (c_plusplus) || defined (__cplusplus) -} -#endif - - -#endif - diff --git a/sapi/litespeed/lsapilib.c b/sapi/litespeed/lsapilib.c deleted file mode 100644 index 9084a850b2..0000000000 --- a/sapi/litespeed/lsapilib.c +++ /dev/null @@ -1,2189 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2007 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available at through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Author: George Wang <gwang@litespeedtech.com> | - +----------------------------------------------------------------------+ -*/ - -/* $Id$ */ - -/* -Copyright (c) 2007, Lite Speed Technologies Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - * Neither the name of the Lite Speed Technologies Inc nor the - names of its contributors may be used to endorse or promote - products derived from this software without specific prior - written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include <lsapilib.h> - -#include <ctype.h> -#include <errno.h> -#include <fcntl.h> - -#include <arpa/inet.h> -#include <netdb.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <sys/un.h> -#include <signal.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <sys/mman.h> -#include <sys/resource.h> -#include <sys/socket.h> -#include <sys/time.h> -#include <sys/uio.h> -#include <sys/wait.h> -#include <time.h> -#include <unistd.h> - -#define LSAPI_ST_REQ_HEADER 1 -#define LSAPI_ST_REQ_BODY 2 -#define LSAPI_ST_RESP_HEADER 4 -#define LSAPI_ST_RESP_BODY 8 - -#define LSAPI_RESP_BUF_SIZE 8192 -#define LSAPI_INIT_RESP_HEADER_LEN 4096 - - -static int g_inited = 0; -static int g_running = 1; -static int s_ppid; -LSAPI_Request g_req = { -1, -1 }; - -void Flush_RespBuf_r( LSAPI_Request * pReq ); - -static const char *CGI_HEADERS[H_TRANSFER_ENCODING+1] = -{ - "HTTP_ACCEPT", "HTTP_ACCEPT_CHARSET", - "HTTP_ACCEPT_ENCODING", - "HTTP_ACCEPT_LANGUAGE", "HTTP_AUTHORIZATION", - "HTTP_CONNECTION", "CONTENT_TYPE", - "CONTENT_LENGTH", "HTTP_COOKIE", "HTTP_COOKIE2", - "HTTP_HOST", "HTTP_PRAGMA", - "HTTP_REFERER", "HTTP_USER_AGENT", - "HTTP_CACHE_CONTROL", - "HTTP_IF_MODIFIED_SINCE", "HTTP_IF_MATCH", - "HTTP_IF_NONE_MATCH", - "HTTP_IF_RANGE", - "HTTP_IF_UNMODIFIED_SINCE", - "HTTP_KEEP_ALIVE", - "HTTP_RANGE", - "HTTP_X_FORWARDED_FOR", - "HTTP_VIA", - "HTTP_TRANSFER_ENCODING" -}; - -static int CGI_HEADER_LEN[H_TRANSFER_ENCODING+1] = { - 11, 19, 20, 20, 18, 15, 12, 14, 11, 12, 9, 11, 12, 15, 18, - 22, 13, 18, 13, 24, 15, 10, 20, 8, 22 -}; - - -static const char *HTTP_HEADERS[H_TRANSFER_ENCODING+1] = { - "Accept", "Accept-Charset", - "Accept-Encoding", - "Accept-Language", "Authorization", - "Connection", "Content-Type", - "Content-Length", "Cookie", "Cookie2", - "Host", "Pragma", - "Referer", "User-Agent", - "Cache-Control", - "If-Modified-Since", "If-Match", - "If-None-Match", - "If-Range", - "If-Unmodified-Since", - "Keep-Alive", - "Range", - "X-Forwarded-For", - "Via", - "Transfer-Encoding" -}; - -static int HTTP_HEADER_LEN[H_TRANSFER_ENCODING+1] = { - 6, 14, 15, 15, 13, 10, 12, 14, 6, 7, 4, 6, 7, 10, /* user-agent */ - 13,17, 8, 13, 8, 19, 10, 5, 15, 3, 17 -}; - -static void lsapi_sigpipe( int sig ) -{ -} -static void lsapi_siguser1( int sig ) -{ - g_running = 0; -} - -#ifndef sighandler_t -typedef void (*sighandler_t)(int); -#endif - -static void lsapi_signal(int signo, sighandler_t handler) -{ - struct sigaction sa; - - sigaction(signo, NULL, &sa); - - if (sa.sa_handler == SIG_DFL) { - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sa.sa_handler = handler; - sigaction(signo, &sa, NULL); - } -} - - -static inline void lsapi_buildPacketHeader( struct lsapi_packet_header * pHeader, - char type, int len ) -{ - pHeader->m_versionB0 = LSAPI_VERSION_B0; /* LSAPI protocol version */ - pHeader->m_versionB1 = LSAPI_VERSION_B1; - pHeader->m_type = type; - pHeader->m_flag = LSAPI_ENDIAN; - pHeader->m_packetLen.m_iLen = len; -} - -static int lsapi_set_nblock( int fd, int nonblock ) -{ - int val = fcntl( fd, F_GETFL, 0 ); - if ( nonblock ) - { - if (!( val & O_NONBLOCK )) - { - return fcntl( fd, F_SETFL, val | O_NONBLOCK ); - } - } - else - { - if ( val & O_NONBLOCK ) - { - return fcntl( fd, F_SETFL, val &(~O_NONBLOCK) ); - } - } - return 0; -} - - -static int lsapi_close( int fd ) -{ - int ret; - while( 1 ) { - ret = close( fd ); - if (( ret == -1 )&&( errno == EINTR )&&(g_running)) { - continue; - } - return ret; - } -} - -static inline int lsapi_read( int fd, void * pBuf, int len ) -{ - int ret; - while( 1 ) { - ret = read( fd, (char *)pBuf, len ); - if (( ret == -1 )&&( errno == EINTR )&&(g_running)) { - continue; - } - return ret; - } -} - - -static int lsapi_writev( int fd, struct iovec ** pVec, int count, int totalLen ) -{ - int ret; - int left = totalLen; - int n = count; - while(( left > 0 )&&g_running ) { - ret = writev( fd, *pVec, n ); - if ( ret > 0 ) { - left -= ret; - if (( left <= 0)||( !g_running )) { - return totalLen - left; - } - while( ret > 0 ) { - if ( (*pVec)->iov_len <= ret ) { - ret -= (*pVec)->iov_len; - ++(*pVec); - } else { - (*pVec)->iov_base = (char *)(*pVec)->iov_base + ret; - (*pVec)->iov_len -= ret; - break; - } - } - } else if ( ret == -1 ) { - if ( errno == EAGAIN ) { - if ( totalLen - left > 0 ) { - return totalLen - left; - } else { - return -1; - } - } else { - if ( errno != EINTR ) { - return ret; - } - } - } - } - return totalLen - left; -} - -static inline int allocateBuf( LSAPI_Request * pReq, int size ) -{ - char * pBuf = (char *)realloc( pReq->m_pReqBuf, size ); - if ( pBuf ) { - pReq->m_pReqBuf = pBuf; - pReq->m_reqBufSize = size; - pReq->m_pHeader = (struct lsapi_req_header *)pReq->m_pReqBuf; - return 0; - } - return -1; -} - - -static int allocateIovec( LSAPI_Request * pReq, int n ) -{ - struct iovec * p = (struct iovec *)realloc( - pReq->m_pIovec, sizeof(struct iovec) * n ); - if ( !p ) { - return -1; - } - pReq->m_pIovecToWrite = p + ( pReq->m_pIovecToWrite - pReq->m_pIovec ); - pReq->m_pIovecCur = p + ( pReq->m_pIovecCur - pReq->m_pIovec ); - pReq->m_pIovec = p; - pReq->m_pIovecEnd = p + n; - return 0; -} - -static int allocateRespHeaderBuf( LSAPI_Request * pReq, int size ) -{ - char * p = (char *)realloc( pReq->m_pRespHeaderBuf, size ); - if ( !p ) { - return -1; - } - pReq->m_pRespHeaderBufPos = p + ( pReq->m_pRespHeaderBufPos - pReq->m_pRespHeaderBuf ); - pReq->m_pRespHeaderBuf = p; - pReq->m_pRespHeaderBufEnd = p + size; - return 0; -} - - -static inline int verifyHeader( struct lsapi_packet_header * pHeader, char pktType ) -{ - if (( LSAPI_VERSION_B0 != pHeader->m_versionB0 )|| - ( LSAPI_VERSION_B1 != pHeader->m_versionB1 )|| - ( pktType != pHeader->m_type )) { - return -1; - } - if ( LSAPI_ENDIAN != (pHeader->m_flag & LSAPI_ENDIAN_BIT )) { - register char b; - b = pHeader->m_packetLen.m_bytes[0]; - pHeader->m_packetLen.m_bytes[0] = pHeader->m_packetLen.m_bytes[3]; - pHeader->m_packetLen.m_bytes[3] = b; - b = pHeader->m_packetLen.m_bytes[1]; - pHeader->m_packetLen.m_bytes[1] = pHeader->m_packetLen.m_bytes[2]; - pHeader->m_packetLen.m_bytes[2] = b; - } - return pHeader->m_packetLen.m_iLen; -} - -static int allocateEnvList( struct LSAPI_key_value_pair ** pEnvList, - int *curSize, int newSize ) -{ - struct LSAPI_key_value_pair * pBuf; - if ( *curSize >= newSize ) { - return 0; - } - if ( newSize > 8192 ) { - return -1; - } - pBuf = (struct LSAPI_key_value_pair *)realloc( *pEnvList, newSize * - sizeof(struct LSAPI_key_value_pair) ); - if ( pBuf ) { - *pEnvList = pBuf; - *curSize = newSize; - return 0; - } else { - return -1; - } - -} - -static inline int isPipe( int fd ) -{ - char achPeer[128]; - socklen_t len = 128; - if (( getpeername( fd, (struct sockaddr *)achPeer, &len ) != 0 )&& - ( errno == ENOTCONN )) { - return 0; - } else { - return 1; - } -} - -static int parseEnv( struct LSAPI_key_value_pair * pEnvList, int count, - char **pBegin, char * pEnd ) -{ - struct LSAPI_key_value_pair * pEnvEnd; - int keyLen = 0, valLen = 0; - if ( count > 8192 ) { - return -1; - } - pEnvEnd = pEnvList + count; - while( pEnvList != pEnvEnd ) { - if ( pEnd - *pBegin < 4 ) { - return -1; - } - keyLen = *((unsigned char *)((*pBegin)++)); - keyLen = (keyLen << 8) + *((unsigned char *)((*pBegin)++)); - valLen = *((unsigned char *)((*pBegin)++)); - valLen = (valLen << 8) + *((unsigned char *)((*pBegin)++)); - if ( *pBegin + keyLen + valLen > pEnd ) { - return -1; - } - if (( !keyLen )||( !valLen )) { - return -1; - } - - pEnvList->pKey = *pBegin; - *pBegin += keyLen; - pEnvList->pValue = *pBegin; - *pBegin += valLen; - - pEnvList->keyLen = keyLen - 1; - pEnvList->valLen = valLen - 1; - ++pEnvList; - } - if ( memcmp( *pBegin, "\0\0\0\0", 4 ) != 0 ) { - return -1; - } - *pBegin += 4; - return 0; -} - -static inline void swapIntEndian( int * pInteger ) -{ - char * p = (char *)pInteger; - register char b; - b = p[0]; - p[0] = p[3]; - p[3] = b; - b = p[1]; - p[1] = p[2]; - p[2] = b; - -} - -static inline void fixEndian( LSAPI_Request * pReq ) -{ - struct lsapi_req_header *p= pReq->m_pHeader; - swapIntEndian( &p->m_httpHeaderLen ); - swapIntEndian( &p->m_reqBodyLen ); - swapIntEndian( &p->m_scriptFileOff ); - swapIntEndian( &p->m_scriptNameOff ); - swapIntEndian( &p->m_queryStringOff ); - swapIntEndian( &p->m_requestMethodOff ); - swapIntEndian( &p->m_cntUnknownHeaders ); - swapIntEndian( &p->m_cntEnv ); - swapIntEndian( &p->m_cntSpecialEnv ); -} - -static void fixHeaderIndexEndian( LSAPI_Request * pReq ) -{ - int i; - for( i = 0; i < H_TRANSFER_ENCODING; ++i ) { - if ( pReq->m_pHeaderIndex->m_headerOff[i] ) { - register char b; - char * p = (char *)(&pReq->m_pHeaderIndex->m_headerLen[i]); - b = p[0]; - p[0] = p[1]; - p[1] = b; - swapIntEndian( &pReq->m_pHeaderIndex->m_headerOff[i] ); - } - } - if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 ) { - struct lsapi_header_offset * pCur, *pEnd; - pCur = pReq->m_pUnknownHeader; - pEnd = pCur + pReq->m_pHeader->m_cntUnknownHeaders; - while( pCur < pEnd ) { - swapIntEndian( &pCur->nameOff ); - swapIntEndian( &pCur->nameLen ); - swapIntEndian( &pCur->valueOff ); - swapIntEndian( &pCur->valueLen ); - ++pCur; - } - } -} - -static int parseRequest( LSAPI_Request * pReq, int totalLen ) -{ - int shouldFixEndian; - char * pBegin = pReq->m_pReqBuf + sizeof( struct lsapi_req_header ); - char * pEnd = pReq->m_pReqBuf + totalLen; - shouldFixEndian = ( LSAPI_ENDIAN != ( - pReq->m_pHeader->m_pktHeader.m_flag & LSAPI_ENDIAN_BIT ) ); - if ( shouldFixEndian ) { - fixEndian( pReq ); - } - if ( (pReq->m_specialEnvListSize < pReq->m_pHeader->m_cntSpecialEnv )&& - allocateEnvList( &pReq->m_pSpecialEnvList, - &pReq->m_specialEnvListSize, - pReq->m_pHeader->m_cntSpecialEnv ) == -1 ) { - return -1; - } - if ( (pReq->m_envListSize < pReq->m_pHeader->m_cntEnv )&& - allocateEnvList( &pReq->m_pEnvList, &pReq->m_envListSize, - pReq->m_pHeader->m_cntEnv ) == -1 ) { - return -1; - } - if ( parseEnv( pReq->m_pSpecialEnvList, - pReq->m_pHeader->m_cntSpecialEnv, - &pBegin, pEnd ) == -1 ) { - return -1; - } - if ( parseEnv( pReq->m_pEnvList, pReq->m_pHeader->m_cntEnv, - &pBegin, pEnd ) == -1 ) { - return -1; - } - pReq->m_pScriptFile = pReq->m_pReqBuf + pReq->m_pHeader->m_scriptFileOff; - pReq->m_pScriptName = pReq->m_pReqBuf + pReq->m_pHeader->m_scriptNameOff; - pReq->m_pQueryString = pReq->m_pReqBuf + pReq->m_pHeader->m_queryStringOff; - pReq->m_pRequestMethod = pReq->m_pReqBuf + pReq->m_pHeader->m_requestMethodOff; - - pBegin = pReq->m_pReqBuf + (( pBegin - pReq->m_pReqBuf + 7 ) & (~0x7)); - pReq->m_pHeaderIndex = ( struct lsapi_http_header_index * )pBegin; - pBegin += sizeof( struct lsapi_http_header_index ); - - pReq->m_pUnknownHeader = (struct lsapi_header_offset *)pBegin; - pBegin += sizeof( struct lsapi_header_offset) * - pReq->m_pHeader->m_cntUnknownHeaders; - - pReq->m_pHttpHeader = pBegin; - pBegin += pReq->m_pHeader->m_httpHeaderLen; - if ( pBegin != pEnd ) { - return -1; - } - - if ( shouldFixEndian ) { - fixHeaderIndexEndian( pReq ); - } - - return 0; -} - -static struct lsapi_packet_header ack = {'L', 'S', - LSAPI_REQ_RECEIVED, LSAPI_ENDIAN, {LSAPI_PACKET_HEADER_LEN} }; -static inline int notify_req_received( LSAPI_Request * pReq ) -{ - if ( write( pReq->m_fd, &ack, LSAPI_PACKET_HEADER_LEN ) - < LSAPI_PACKET_HEADER_LEN ) { - return -1; - } - return 0; -} - - -static int readReq( LSAPI_Request * pReq ) -{ - int len; - int packetLen; - if ( !pReq ) { - return -1; - } - if ( pReq->m_reqBufSize < 8192 ) { - if ( allocateBuf( pReq, 8192 ) == -1 ) { - return -1; - } - } - - while ( pReq->m_bufRead < LSAPI_PACKET_HEADER_LEN ) { - len = lsapi_read( pReq->m_fd, pReq->m_pReqBuf, pReq->m_reqBufSize ); - if ( len <= 0 ) { - return -1; - } - pReq->m_bufRead += len; - } - pReq->m_reqState = LSAPI_ST_REQ_HEADER; - - packetLen = verifyHeader( &pReq->m_pHeader->m_pktHeader, LSAPI_BEGIN_REQUEST ); - if ( packetLen < 0 ) { - return -1; - } - if ( packetLen > LSAPI_MAX_HEADER_LEN ) { - return -1; - } - - if ( packetLen + 1024 > pReq->m_reqBufSize ) { - if ( allocateBuf( pReq, packetLen + 1024 ) == -1 ) { - return -1; - } - } - while( packetLen > pReq->m_bufRead ) { - len = lsapi_read( pReq->m_fd, pReq->m_pReqBuf + pReq->m_bufRead, packetLen - pReq->m_bufRead ); - if ( len <= 0 ) { - return -1; - } - pReq->m_bufRead += len; - } - if ( parseRequest( pReq, packetLen ) < 0 ) { - return -1; - } - pReq->m_bufProcessed = packetLen; - pReq->m_reqState = LSAPI_ST_REQ_BODY | LSAPI_ST_RESP_HEADER; - - return notify_req_received( pReq ); -} - - - -int LSAPI_Init(void) -{ - if ( !g_inited ) { - lsapi_signal(SIGPIPE, lsapi_sigpipe); - lsapi_signal(SIGUSR1, lsapi_siguser1); - -#if defined(SIGXFSZ) && defined(SIG_IGN) - signal(SIGXFSZ, SIG_IGN); -#endif - - if ( LSAPI_InitRequest( &g_req, LSAPI_SOCK_FILENO ) == -1 ) { - return -1; - } - g_inited = 1; - s_ppid = getppid(); - } - return 0; -} - -void LSAPI_Stop(void) -{ - g_running = 0; -} - -int LSAPI_IsRunning(void) -{ - return g_running; -} - -int LSAPI_InitRequest( LSAPI_Request * pReq, int fd ) -{ - if ( !pReq ) { - return -1; - } - memset( pReq, 0, sizeof( LSAPI_Request ) ); - if ( allocateIovec( pReq, 16 ) == -1 ) { - return -1; - } - pReq->m_pRespBuf = pReq->m_pRespBufPos = (char *)malloc( LSAPI_RESP_BUF_SIZE ); - if ( !pReq->m_pRespBuf ) { - return -1; - } - pReq->m_pRespBufEnd = pReq->m_pRespBuf + LSAPI_RESP_BUF_SIZE; - pReq->m_pIovecCur = pReq->m_pIovecToWrite = pReq->m_pIovec + 1; - pReq->m_respPktHeaderEnd = &pReq->m_respPktHeader[5]; - if ( allocateRespHeaderBuf( pReq, LSAPI_INIT_RESP_HEADER_LEN ) == -1 ) { - return -1; - } - - if ( isPipe( fd ) ) { - pReq->m_fdListen = -1; - pReq->m_fd = fd; - } else { - pReq->m_fdListen = fd; - pReq->m_fd = -1; - lsapi_set_nblock( fd, 1 ); - } - return 0; -} - -int LSAPI_Is_Listen( void ) -{ - return LSAPI_Is_Listen_r( &g_req ); -} - -int LSAPI_Is_Listen_r( LSAPI_Request * pReq) -{ - return pReq->m_fdListen != -1; -} - - - -int LSAPI_Accept_r( LSAPI_Request * pReq ) -{ - char achPeer[128]; - socklen_t len; - int nodelay = 1; - - if ( !pReq ) { - return -1; - } - if ( LSAPI_Finish_r( pReq ) == -1 ) { - return -1; - } - while( g_running ) { - if ( pReq->m_fd == -1 ) { - if ( pReq->m_fdListen != -1) { - len = sizeof( achPeer ); - pReq->m_fd = accept( pReq->m_fdListen, - (struct sockaddr *)&achPeer, &len ); - if ( pReq->m_fd == -1 ) { - if (( errno == EINTR )||( errno == EAGAIN)) { - continue; - } else { - return -1; - } - } else { - lsapi_set_nblock( pReq->m_fd , 0 ); - if (((struct sockaddr *)&achPeer)->sa_family == AF_INET ) { - setsockopt(pReq->m_fd, IPPROTO_TCP, TCP_NODELAY, - (char *)&nodelay, sizeof(nodelay)); - } - } - } else { - return -1; - } - } - if ( !readReq( pReq ) ) { - break; - } - lsapi_close( pReq->m_fd ); - pReq->m_fd = -1; - LSAPI_Reset_r( pReq ); - } - return 0; -} - -static struct lsapi_packet_header finish = {'L', 'S', - LSAPI_RESP_END, LSAPI_ENDIAN, {LSAPI_PACKET_HEADER_LEN} }; - -int LSAPI_Finish_r( LSAPI_Request * pReq ) -{ - /* finish req body */ - if ( !pReq ) { - return -1; - } - if (pReq->m_reqState) { - if ( pReq->m_fd != -1 ) { - if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) { - LSAPI_FinalizeRespHeaders_r( pReq ); - } - if ( pReq->m_pRespBufPos != pReq->m_pRespBuf ) { - Flush_RespBuf_r( pReq ); - } - - pReq->m_pIovecCur->iov_base = (void *)&finish; - pReq->m_pIovecCur->iov_len = LSAPI_PACKET_HEADER_LEN; - pReq->m_totalLen += LSAPI_PACKET_HEADER_LEN; - ++pReq->m_pIovecCur; - LSAPI_Flush_r( pReq ); - } - LSAPI_Reset_r( pReq ); - } - return 0; -} - - -void LSAPI_Reset_r( LSAPI_Request * pReq ) -{ - pReq->m_pRespBufPos = pReq->m_pRespBuf; - pReq->m_pIovecCur = pReq->m_pIovecToWrite = pReq->m_pIovec + 1; - pReq->m_pRespHeaderBufPos = pReq->m_pRespHeaderBuf; - - memset( &pReq->m_pHeaderIndex, 0, - (char *)(pReq->m_respHeaderLen) - (char *)&pReq->m_pHeaderIndex ); -} - - -int LSAPI_Release_r( LSAPI_Request * pReq ) -{ - if ( pReq->m_pReqBuf ) { - free( pReq->m_pReqBuf ); - } - if ( pReq->m_pSpecialEnvList ) { - free( pReq->m_pSpecialEnvList ); - } - if ( pReq->m_pEnvList ) { - free( pReq->m_pEnvList ); - } - if ( pReq->m_pRespHeaderBuf ) { - free( pReq->m_pRespHeaderBuf ); - } - return 0; -} - - -char * LSAPI_GetHeader_r( LSAPI_Request * pReq, int headerIndex ) -{ - int off; - if ( !pReq || ((unsigned int)headerIndex > H_TRANSFER_ENCODING) ) { - return NULL; - } - off = pReq->m_pHeaderIndex->m_headerOff[ headerIndex ]; - if ( !off ) { - return NULL; - } - if ( *(pReq->m_pHttpHeader + off + - pReq->m_pHeaderIndex->m_headerLen[ headerIndex ]) ) { - *( pReq->m_pHttpHeader + off + - pReq->m_pHeaderIndex->m_headerLen[ headerIndex ]) = 0; - } - return pReq->m_pHttpHeader + off; -} - -static int readBodyToReqBuf( LSAPI_Request * pReq ) -{ - int bodyLeft; - int len = pReq->m_bufRead - pReq->m_bufProcessed; - if ( len > 0 ) { - return len; - } - pReq->m_bufRead = pReq->m_bufProcessed = pReq->m_pHeader->m_pktHeader.m_packetLen.m_iLen; - - bodyLeft = pReq->m_pHeader->m_reqBodyLen - pReq->m_reqBodyRead; - len = pReq->m_reqBufSize - pReq->m_bufRead; - if ( len < 0 ) { - return -1; - } - if ( len > bodyLeft ) { - len = bodyLeft; - } - len = lsapi_read( pReq->m_fd, pReq->m_pReqBuf + pReq->m_bufRead, len ); - if ( len > 0 ) { - pReq->m_bufRead += len; - } - return len; -} - - -int LSAPI_ReqBodyGetChar_r( LSAPI_Request * pReq ) -{ - if (!pReq || (pReq->m_fd ==-1) ) { - return EOF; - } - if ( pReq->m_bufProcessed >= pReq->m_bufRead ) { - if ( readBodyToReqBuf( pReq ) <= 0 ) { - return EOF; - } - } - ++pReq->m_reqBodyRead; - return (unsigned char)*(pReq->m_pReqBuf + pReq->m_bufProcessed++); -} - - - -int LSAPI_ReqBodyGetLine_r( LSAPI_Request * pReq, char * pBuf, int bufLen, int *getLF ) -{ - int len; - int left; - char * pBufEnd = pBuf + bufLen - 1; - char * pBufCur = pBuf; - char * pCur; - char * p; - if (!pReq || (pReq->m_fd ==-1) ||( !pBuf )||(bufLen < 0 )|| !getLF ) { - return -1; - } - *getLF = 0; - while( (left = pBufEnd - pBufCur ) > 0 ) { - - len = pReq->m_bufRead - pReq->m_bufProcessed; - if ( len <= 0 ) { - if ( (len = readBodyToReqBuf( pReq )) <= 0 ) { - *getLF = 1; - break; - } - } - if ( len > left ) { - len = left; - } - pCur = pReq->m_pReqBuf + pReq->m_bufProcessed; - p = memchr( pCur, '\n', len ); - if ( p ) { - len = p - pCur + 1; - } - memmove( pBufCur, pCur, len ); - pBufCur += len; - pReq->m_bufProcessed += len; - - pReq->m_reqBodyRead += len; - - if ( p ) { - *getLF = 1; - break; - } - } - *pBufCur = 0; - - return pBufCur - pBuf; -} - - -int LSAPI_ReadReqBody_r( LSAPI_Request * pReq, char * pBuf, int bufLen ) -{ - int len; - int total; - /* char *pOldBuf = pBuf; */ - if (!pReq || (pReq->m_fd ==-1) || ( !pBuf )||(bufLen < 0 )) { - return -1; - } - total = pReq->m_pHeader->m_reqBodyLen - pReq->m_reqBodyRead; - - if ( total <= 0 ) { - return 0; - } - if ( total < bufLen ) { - bufLen = total; - } - - total = 0; - len = pReq->m_bufRead - pReq->m_bufProcessed; - if ( len > 0 ) { - if ( len > bufLen ) { - len = bufLen; - } - memmove( pBuf, pReq->m_pReqBuf + pReq->m_bufProcessed, len ); - pReq->m_bufProcessed += len; - total += len; - pBuf += len; - bufLen -= len; - } - while( bufLen > 0 ) { - len = lsapi_read( pReq->m_fd, pBuf, bufLen ); - if ( len > 0 ) { - total += len; - pBuf += len; - bufLen -= len; - } else { - if ( len <= 0 ) { - if ( !total) { - return -1; - } - break; - } - } - } - pReq->m_reqBodyRead += total; - return total; - -} - - -int LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, int len ) -{ - struct lsapi_packet_header * pHeader; - const char * pEnd; - const char * p; - int bufLen; - int toWrite; - int packetLen; - - if ( !pReq || !pBuf || (pReq->m_fd == -1) ) { - return -1; - } - if ( len < pReq->m_pRespBufEnd - pReq->m_pRespBufPos ) { - memmove( pReq->m_pRespBufPos, pBuf, len ); - pReq->m_pRespBufPos += len; - return len; - } - - if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) { - LSAPI_FinalizeRespHeaders_r( pReq ); - } - pReq->m_reqState |= LSAPI_ST_RESP_BODY; - - pHeader = pReq->m_respPktHeader; - p = pBuf; - pEnd = pBuf + len; - bufLen = pReq->m_pRespBufPos - pReq->m_pRespBuf; - - while( ( toWrite = pEnd - p ) > 0 ) { - packetLen = toWrite + bufLen; - if ( LSAPI_MAX_DATA_PACKET_LEN < packetLen) { - packetLen = LSAPI_MAX_DATA_PACKET_LEN; - toWrite = packetLen - bufLen; - } - - lsapi_buildPacketHeader( pHeader, LSAPI_RESP_STREAM, - packetLen + LSAPI_PACKET_HEADER_LEN ); - pReq->m_totalLen += packetLen + LSAPI_PACKET_HEADER_LEN; - - pReq->m_pIovecCur->iov_base = (void *)pHeader; - pReq->m_pIovecCur->iov_len = LSAPI_PACKET_HEADER_LEN; - ++pReq->m_pIovecCur; - ++pHeader; - if ( bufLen > 0 ) { - pReq->m_pIovecCur->iov_base = (void *)pReq->m_pRespBuf; - pReq->m_pIovecCur->iov_len = bufLen; - pReq->m_pRespBufPos = pReq->m_pRespBuf; - ++pReq->m_pIovecCur; - bufLen = 0; - } - - pReq->m_pIovecCur->iov_base = (void *)p; - pReq->m_pIovecCur->iov_len = toWrite; - ++pReq->m_pIovecCur; - p += toWrite; - - if ( pHeader >= pReq->m_respPktHeaderEnd - 1) { - if ( LSAPI_Flush_r( pReq ) == -1 ) { - return -1; - } - pHeader = pReq->m_respPktHeader; - } - } - if ( pHeader != pReq->m_respPktHeader ) { - if ( LSAPI_Flush_r( pReq ) == -1 ) { - return -1; - } - } - return p - pBuf; -} - -void Flush_RespBuf_r( LSAPI_Request * pReq ) -{ - struct lsapi_packet_header * pHeader = pReq->m_respPktHeader; - int bufLen = pReq->m_pRespBufPos - pReq->m_pRespBuf; - pReq->m_reqState |= LSAPI_ST_RESP_BODY; - lsapi_buildPacketHeader( pHeader, LSAPI_RESP_STREAM, - bufLen + LSAPI_PACKET_HEADER_LEN ); - pReq->m_totalLen += bufLen + LSAPI_PACKET_HEADER_LEN; - - pReq->m_pIovecCur->iov_base = (void *)pHeader; - pReq->m_pIovecCur->iov_len = LSAPI_PACKET_HEADER_LEN; - ++pReq->m_pIovecCur; - ++pHeader; - if ( bufLen > 0 ) { - pReq->m_pIovecCur->iov_base = (void *)pReq->m_pRespBuf; - pReq->m_pIovecCur->iov_len = bufLen; - pReq->m_pRespBufPos = pReq->m_pRespBuf; - ++pReq->m_pIovecCur; - bufLen = 0; - } -} - - - - -int LSAPI_Flush_r( LSAPI_Request * pReq ) -{ - int ret = 0; - int n; - if ( !pReq ) { - return -1; - } - n = pReq->m_pIovecCur - pReq->m_pIovecToWrite; - if (( 0 == n )&&( pReq->m_pRespBufPos == pReq->m_pRespBuf )) { - return 0; - } - if ( pReq->m_fd == -1 ) { - pReq->m_pRespBufPos = pReq->m_pRespBuf; - pReq->m_totalLen = 0; - pReq->m_pIovecCur = pReq->m_pIovecToWrite = pReq->m_pIovec; - return -1; - } - if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) { - LSAPI_FinalizeRespHeaders_r( pReq ); - } - if ( pReq->m_pRespBufPos != pReq->m_pRespBuf ) { - Flush_RespBuf_r( pReq ); - } - - n = pReq->m_pIovecCur - pReq->m_pIovecToWrite; - if ( n > 0 ) { - - ret = lsapi_writev( pReq->m_fd, &pReq->m_pIovecToWrite, - n, pReq->m_totalLen ); - if ( ret < pReq->m_totalLen ) { - lsapi_close( pReq->m_fd ); - pReq->m_fd = -1; - ret = -1; - } - pReq->m_totalLen = 0; - pReq->m_pIovecCur = pReq->m_pIovecToWrite = pReq->m_pIovec; - } - return ret; -} - - -int LSAPI_Write_Stderr_r( LSAPI_Request * pReq, const char * pBuf, int len ) -{ - struct lsapi_packet_header header; - const char * pEnd; - const char * p; - int packetLen; - int totalLen; - int ret; - struct iovec iov[2]; - struct iovec *pIov; - - if ( !pReq ) { - return -1; - } - if (( pReq->m_fd == -1 )||(pReq->m_fd == pReq->m_fdListen )) { - return write( 2, pBuf, len ); - } - if ( pReq->m_pRespBufPos != pReq->m_pRespBuf ) { - LSAPI_Flush_r( pReq ); - } - - p = pBuf; - pEnd = pBuf + len; - - while( ( packetLen = pEnd - p ) > 0 ) { - if ( LSAPI_MAX_DATA_PACKET_LEN < packetLen) { - packetLen = LSAPI_MAX_DATA_PACKET_LEN; - } - - lsapi_buildPacketHeader( &header, LSAPI_STDERR_STREAM, - packetLen + LSAPI_PACKET_HEADER_LEN ); - totalLen = packetLen + LSAPI_PACKET_HEADER_LEN; - - iov[0].iov_base = (void *)&header; - iov[0].iov_len = LSAPI_PACKET_HEADER_LEN; - - iov[1].iov_base = (void *)p; - iov[1].iov_len = packetLen; - p += packetLen; - pIov = iov; - ret = lsapi_writev( pReq->m_fd, &pIov, - 2, totalLen ); - if ( ret < totalLen ) { - lsapi_close( pReq->m_fd ); - pReq->m_fd = -1; - ret = -1; - } - } - return p - pBuf; -} - -static char * GetHeaderVar( LSAPI_Request * pReq, const char * name ) -{ - int i; - for( i = 0; i < H_TRANSFER_ENCODING; ++i ) { - if ( pReq->m_pHeaderIndex->m_headerOff[i] ) { - if ( strcmp( name, CGI_HEADERS[i] ) == 0 ) { - return pReq->m_pHttpHeader + pReq->m_pHeaderIndex->m_headerOff[i]; - } - } - } - if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 ) { - const char *p; - char *pKey; - char *pKeyEnd; - int keyLen; - struct lsapi_header_offset * pCur, *pEnd; - pCur = pReq->m_pUnknownHeader; - pEnd = pCur + pReq->m_pHeader->m_cntUnknownHeaders; - while( pCur < pEnd ) { - pKey = pReq->m_pHttpHeader + pCur->nameOff; - keyLen = pCur->nameLen; - pKeyEnd = pKey + keyLen; - p = &name[5]; - - while(( pKey < pKeyEnd )&&( *p )) { - char ch = toupper( *pKey ); - if ((ch != *p )||(( *p == '_' )&&( ch != '-'))) { - break; - } - ++p; ++pKey; - } - if (( pKey == pKeyEnd )&& (!*p )) { - return pReq->m_pHttpHeader + pCur->valueOff; - } - ++pCur; - } - } - return NULL; -} - - -char * LSAPI_GetEnv_r( LSAPI_Request * pReq, const char * name ) -{ - struct LSAPI_key_value_pair * pBegin = pReq->m_pEnvList; - struct LSAPI_key_value_pair * pEnd = pBegin + pReq->m_pHeader->m_cntEnv; - if ( !pReq || !name ) { - return NULL; - } - if ( strncmp( name, "HTTP_", 5 ) == 0 ) { - return GetHeaderVar( pReq, name ); - } - while( pBegin < pEnd ) { - if ( strcmp( name, pBegin->pKey ) == 0 ) { - return pBegin->pValue; - } - ++pBegin; - } - return NULL; -} - -int LSAPI_ForeachOrgHeader_r( LSAPI_Request * pReq, - LSAPI_CB_EnvHandler fn, void * arg ) -{ - int i; - int len = 0; - char * pValue; - int ret; - int count = 0; - if ( !pReq || !fn ) { - return -1; - } - for( i = 0; i < H_TRANSFER_ENCODING; ++i ) { - if ( pReq->m_pHeaderIndex->m_headerOff[i] ) { - len = pReq->m_pHeaderIndex->m_headerLen[i]; - pValue = pReq->m_pHttpHeader + pReq->m_pHeaderIndex->m_headerOff[i]; - *(pValue + len ) = 0; - ret = (*fn)( HTTP_HEADERS[i], HTTP_HEADER_LEN[i], - pValue, len, arg ); - ++count; - if ( ret <= 0 ) { - return ret; - } - } - } - if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 ) { - char *pKey; - int keyLen; - struct lsapi_header_offset * pCur, *pEnd; - pCur = pReq->m_pUnknownHeader; - pEnd = pCur + pReq->m_pHeader->m_cntUnknownHeaders; - while( pCur < pEnd ) { - pKey = pReq->m_pHttpHeader + pCur->nameOff; - keyLen = pCur->nameLen; - - pValue = pReq->m_pHttpHeader + pCur->valueOff; - *(pValue + pCur->valueLen ) = 0; - ret = (*fn)( pKey, keyLen, - pValue, pCur->valueLen, arg ); - if ( ret <= 0 ) { - return ret; - } - ++pCur; - } - } - return count + pReq->m_pHeader->m_cntUnknownHeaders; - -} - - -int LSAPI_ForeachHeader_r( LSAPI_Request * pReq, - LSAPI_CB_EnvHandler fn, void * arg ) -{ - int i; - int len = 0; - char * pValue; - int ret; - int count = 0; - if ( !pReq || !fn ) { - return -1; - } - for( i = 0; i < H_TRANSFER_ENCODING; ++i ) { - if ( pReq->m_pHeaderIndex->m_headerOff[i] ) { - len = pReq->m_pHeaderIndex->m_headerLen[i]; - pValue = pReq->m_pHttpHeader + pReq->m_pHeaderIndex->m_headerOff[i]; - *(pValue + len ) = 0; - ret = (*fn)( CGI_HEADERS[i], CGI_HEADER_LEN[i], - pValue, len, arg ); - ++count; - if ( ret <= 0 ) { - return ret; - } - } - } - if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 ) { - char achHeaderName[256]; - char *p; - char *pKey; - char *pKeyEnd ; - int keyLen; - struct lsapi_header_offset * pCur, *pEnd; - pCur = pReq->m_pUnknownHeader; - pEnd = pCur + pReq->m_pHeader->m_cntUnknownHeaders; - while( pCur < pEnd ) { - pKey = pReq->m_pHttpHeader + pCur->nameOff; - keyLen = pCur->nameLen; - pKeyEnd = pKey + keyLen; - memcpy( achHeaderName, "HTTP_", 5 ); - p = &achHeaderName[5]; - if ( keyLen > 250 ) { - keyLen = 250; - } - - while( pKey < pKeyEnd ) { - char ch = *pKey++; - if ( ch == '-' ) { - *p++ = '_'; - } else { - *p++ = toupper( ch ); - } - } - *p = 0; - keyLen += 5; - - pValue = pReq->m_pHttpHeader + pCur->valueOff; - *(pValue + pCur->valueLen ) = 0; - ret = (*fn)( achHeaderName, keyLen, - pValue, pCur->valueLen, arg ); - if ( ret <= 0 ) { - return ret; - } - ++pCur; - } - } - return count + pReq->m_pHeader->m_cntUnknownHeaders; - -} - -static int EnvForeach( struct LSAPI_key_value_pair * pEnv, - int n, LSAPI_CB_EnvHandler fn, void * arg ) -{ - struct LSAPI_key_value_pair * pEnd = pEnv + n; - int ret; - if ( !pEnv || !fn ) { - return -1; - } - while( pEnv < pEnd ) { - ret = (*fn)( pEnv->pKey, pEnv->keyLen, - pEnv->pValue, pEnv->valLen, arg ); - if ( ret <= 0 ) { - return ret; - } - ++pEnv; - } - return n; -} - - - -int LSAPI_ForeachEnv_r( LSAPI_Request * pReq, - LSAPI_CB_EnvHandler fn, void * arg ) -{ - if ( !pReq || !fn ) { - return -1; - } - if ( pReq->m_pHeader->m_cntEnv > 0 ) { - return EnvForeach( pReq->m_pEnvList, pReq->m_pHeader->m_cntEnv, - fn, arg ); - } - return 0; -} - - - -int LSAPI_ForeachSpecialEnv_r( LSAPI_Request * pReq, - LSAPI_CB_EnvHandler fn, void * arg ) -{ - if ( !pReq || !fn ) { - return -1; - } - if ( pReq->m_pHeader->m_cntSpecialEnv > 0 ) { - return EnvForeach( pReq->m_pSpecialEnvList, - pReq->m_pHeader->m_cntSpecialEnv, - fn, arg ); - } - return 0; - -} - - - -int LSAPI_FinalizeRespHeaders_r( LSAPI_Request * pReq ) -{ - if ( !pReq || !pReq->m_pIovec ) { - return -1; - } - if ( !( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) ) { - return 0; - } - pReq->m_reqState &= ~LSAPI_ST_RESP_HEADER; - if ( pReq->m_pRespHeaderBufPos > pReq->m_pRespHeaderBuf ) { - pReq->m_pIovecCur->iov_base = (void *)pReq->m_pRespHeaderBuf; - pReq->m_pIovecCur->iov_len = pReq->m_pRespHeaderBufPos - pReq->m_pRespHeaderBuf; - pReq->m_totalLen += pReq->m_pIovecCur->iov_len; - ++pReq->m_pIovecCur; - } - - pReq->m_pIovec->iov_len = sizeof( struct lsapi_resp_header) - + pReq->m_respHeader.m_respInfo.m_cntHeaders * sizeof( short ); - pReq->m_totalLen += pReq->m_pIovec->iov_len; - - lsapi_buildPacketHeader( &pReq->m_respHeader.m_pktHeader, - LSAPI_RESP_HEADER, pReq->m_totalLen ); - pReq->m_pIovec->iov_base = (void *)&pReq->m_respHeader; - pReq->m_pIovecToWrite = pReq->m_pIovec; - return 0; -} - - - - -int LSAPI_AppendRespHeader_r( LSAPI_Request * pReq, char * pBuf, int len ) -{ - if ( !pReq || !pBuf || len <= 0 || len > LSAPI_RESP_HTTP_HEADER_MAX ) { - return -1; - } - if ( pReq->m_reqState & LSAPI_ST_RESP_BODY ) { - return -1; - } - if ( pReq->m_respHeader.m_respInfo.m_cntHeaders >= LSAPI_MAX_RESP_HEADERS ) { - return -1; - } - if ( pReq->m_pRespHeaderBufPos + len + 1 > pReq->m_pRespHeaderBufEnd ) { - int newlen = pReq->m_pRespHeaderBufPos + len + 4096 - pReq->m_pRespHeaderBuf; - newlen -= newlen % 4096; - if ( allocateRespHeaderBuf( pReq, newlen ) == -1 ) { - return -1; - } - } - memmove( pReq->m_pRespHeaderBufPos, pBuf, len ); - pReq->m_pRespHeaderBufPos += len; - *pReq->m_pRespHeaderBufPos++ = 0; - ++len; /* add one byte padding for \0 */ - pReq->m_respHeaderLen[pReq->m_respHeader.m_respInfo.m_cntHeaders] = len; - ++pReq->m_respHeader.m_respInfo.m_cntHeaders; - return 0; -} - - -int LSAPI_CreateListenSock2( const struct sockaddr * pServerAddr, int backlog ) -{ - int ret; - int fd; - int flag = 1; - int addr_len; - - switch( pServerAddr->sa_family ) { - case AF_INET: - addr_len = 16; - break; - case AF_INET6: - addr_len = sizeof( struct sockaddr_in6 ); - break; - case AF_UNIX: - addr_len = sizeof( struct sockaddr_un ); - unlink( ((struct sockaddr_un *)pServerAddr)->sun_path ); - break; - default: - return -1; - } - - fd = socket( pServerAddr->sa_family, SOCK_STREAM, 0 ); - if ( fd == -1 ) { - return -1; - } - - fcntl( fd, F_SETFD, FD_CLOEXEC ); - - if(setsockopt( fd, SOL_SOCKET, SO_REUSEADDR, - (char *)( &flag ), sizeof(flag)) == 0) { - ret = bind( fd, pServerAddr, addr_len ); - if ( !ret ) { - ret = listen( fd, backlog ); - if ( !ret ) { - return fd; - } - } - } - - ret = errno; - close(fd); - errno = ret; - return -1; - -} - -int LSAPI_ParseSockAddr( const char * pBind, struct sockaddr * pAddr ) -{ - char achAddr[256]; - char * p = achAddr; - char * pEnd; - struct addrinfo *res, hints; - int doAddrInfo = 0; - int port; - - if ( !pBind ) { - return -1; - } - - while( isspace( *p ) ) { - ++pBind; - } - - strncpy( achAddr, pBind, 256 ); - - switch( *p ) { - case '/': - pAddr->sa_family = AF_UNIX; - strncpy( ((struct sockaddr_un *)pAddr)->sun_path, p, - sizeof(((struct sockaddr_un *)pAddr)->sun_path) ); - return 0; - - case '[': - pAddr->sa_family = AF_INET6; - ++p; - pEnd = strchr( p, ']' ); - if ( !pEnd ) - return -1; - *pEnd++ = 0; - - if ( *p == '*' ) { - strcpy( achAddr, "::" ); - p = achAddr; - } - doAddrInfo = 1; - break; - - default: - pAddr->sa_family = AF_INET; - pEnd = strchr( p, ':' ); - if ( !pEnd ) { - return -1; - } - *pEnd++ = 0; - - doAddrInfo = 0; - if ( *p == '*' ) { - ((struct sockaddr_in *)pAddr)->sin_addr.s_addr = htonl(INADDR_ANY); - } else { - if (!strcasecmp( p, "localhost" ) ) { - ((struct sockaddr_in *)pAddr)->sin_addr.s_addr = htonl( INADDR_LOOPBACK ); - } else { - ((struct sockaddr_in *)pAddr)->sin_addr.s_addr = inet_addr( p ); - if ( ((struct sockaddr_in *)pAddr)->sin_addr.s_addr == INADDR_BROADCAST) { - doAddrInfo = 1; - } - } - } - break; - } - if ( *pEnd == ':' ) { - ++pEnd; - } - - port = atoi( pEnd ); - if (( port <= 0 )||( port > 655535 )) { - return -1; - } - if ( doAddrInfo ) { - - memset(&hints, 0, sizeof(hints)); - - hints.ai_family = pAddr->sa_family; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - - if ( getaddrinfo(p, NULL, &hints, &res) ) { - return -1; - } - - memcpy(pAddr, res->ai_addr, res->ai_addrlen); - freeaddrinfo(res); - } - - if ( pAddr->sa_family == AF_INET ) { - ((struct sockaddr_in *)pAddr)->sin_port = htons( port ); - } else { - ((struct sockaddr_in6 *)pAddr)->sin6_port = htons( port ); - } - return 0; - -} - -int LSAPI_CreateListenSock( const char * pBind, int backlog ) -{ - char serverAddr[128]; - int ret; - int fd = -1; - ret = LSAPI_ParseSockAddr( pBind, (struct sockaddr *)serverAddr ); - if ( !ret ) { - fd = LSAPI_CreateListenSock2( (struct sockaddr *)serverAddr, backlog ); - } - return fd; -} - -static fn_select_t g_fnSelect = select; - -typedef struct _lsapi_child_status -{ - int m_pid; - - volatile short m_iKillSent; - volatile short m_inProcess; - - volatile long m_tmWaitBegin; - volatile long m_tmReqBegin; - volatile long m_tmLastCheckPoint; -} -lsapi_child_status; - -static lsapi_child_status * s_pChildStatus = NULL; - -typedef struct _lsapi_prefork_server -{ - int m_fd; - int m_iMaxChildren; - int m_iExtraChildren; - int m_iCurChildren; - int m_iMaxIdleChildren; - int m_iServerMaxIdle; - int m_iChildrenMaxIdleTime; - int m_iMaxReqProcessTime; - int m_iAvoidFork; - - lsapi_child_status * m_pChildrenStatus; - -}lsapi_prefork_server; - -static lsapi_prefork_server * g_prefork_server = NULL; - -int LSAPI_Init_Prefork_Server( int max_children, fn_select_t fp, int avoidFork ) -{ - if ( g_prefork_server ) { - return 0; - } - if ( max_children <= 1 ) { - return -1; - } - if ( max_children >= 10000) { - max_children = 10000; - } - - - g_prefork_server = (lsapi_prefork_server *)malloc( sizeof( lsapi_prefork_server ) ); - if ( !g_prefork_server ) { - return -1; - } - memset( g_prefork_server, 0, sizeof( lsapi_prefork_server ) ); - - if ( fp != NULL ) { - g_fnSelect = fp; - } - - s_ppid = getppid(); - g_prefork_server->m_iAvoidFork = avoidFork; - g_prefork_server->m_iMaxChildren = max_children; - - g_prefork_server->m_iExtraChildren = ( avoidFork ) ? 0 : (max_children / 3) ; - g_prefork_server->m_iMaxIdleChildren = ( avoidFork ) ? (max_children + 1) : (max_children / 3); - g_prefork_server->m_iChildrenMaxIdleTime = 300; - g_prefork_server->m_iMaxReqProcessTime = 300; - return 0; -} - -void LSAPI_Set_Server_fd( int fd ) -{ - if( g_prefork_server ) { - g_prefork_server->m_fd = fd; - } -} - - -static int lsapi_accept( int fdListen ) -{ - int fd; - int nodelay = 1; - socklen_t len; - char achPeer[128]; - - len = sizeof( achPeer ); - fd = accept( fdListen, (struct sockaddr *)&achPeer, &len ); - if ( fd != -1 ) { - if (((struct sockaddr *)&achPeer)->sa_family == AF_INET ) { - setsockopt( fd, IPPROTO_TCP, TCP_NODELAY, - (char *)&nodelay, sizeof(nodelay)); - } - } - return fd; - -} - - - - -static int s_req_processed = 0; -static int s_max_reqs = 10000; -static int s_max_idle_secs = 300; - -static int s_stop; - -static void lsapi_cleanup(int signal) -{ - s_stop = signal; -} - -static lsapi_child_status * find_child_status( int pid ) -{ - lsapi_child_status * pStatus = g_prefork_server->m_pChildrenStatus; - lsapi_child_status * pEnd = g_prefork_server->m_pChildrenStatus + g_prefork_server->m_iMaxChildren * 2; - while( pStatus < pEnd ) { - if ( pStatus->m_pid == pid ) { - return pStatus; - } - ++pStatus; - } - return NULL; -} - - - -static void lsapi_sigchild( int signal ) -{ - int status, pid; - lsapi_child_status * child_status; - while( 1 ) { - pid = waitpid( -1, &status, WNOHANG|WUNTRACED ); - if ( pid <= 0 ) { - break; - } - child_status = find_child_status( pid ); - if ( child_status ) { - child_status->m_pid = 0; - } - --g_prefork_server->m_iCurChildren; - } - -} - -static int lsapi_init_children_status() -{ - int size = 4096; - - char * pBuf; - size = g_prefork_server->m_iMaxChildren * sizeof( lsapi_child_status ) * 2; - size = (size + 4095 ) / 4096 * 4096; - pBuf =( char*) mmap( NULL, size, PROT_READ | PROT_WRITE, - MAP_ANON | MAP_SHARED, -1, 0 ); - if ( pBuf == MAP_FAILED ) { - perror( "Anonymous mmap() failed" ); - return -1; - } - memset( pBuf, 0, size ); - g_prefork_server->m_pChildrenStatus = (lsapi_child_status *)pBuf; - return 0; -} - -static void lsapi_check_child_status( long tmCur ) -{ - int idle = 0; - int tobekilled; - int dying = 0; - lsapi_child_status * pStatus = g_prefork_server->m_pChildrenStatus; - lsapi_child_status * pEnd = g_prefork_server->m_pChildrenStatus + g_prefork_server->m_iMaxChildren * 2; - while( pStatus < pEnd ) { - tobekilled = pStatus->m_iKillSent; - if ( pStatus->m_pid != 0 ) { - if ( !tobekilled ) { - if ( !pStatus->m_inProcess ) { - - if (( g_prefork_server->m_iCurChildren - dying > g_prefork_server->m_iMaxChildren)|| - ( idle >= g_prefork_server->m_iMaxIdleChildren )) { - - tobekilled = 1; - } else { - if (( s_max_idle_secs> 0)&&(tmCur - pStatus->m_tmWaitBegin > s_max_idle_secs + 5 )) { - tobekilled = 1; - } - } - if ( !tobekilled ) { - ++idle; - } - } else { - if ( tmCur - pStatus->m_tmReqBegin > - g_prefork_server->m_iMaxReqProcessTime ) { - tobekilled = 1; - } - } - } else { - if ( pStatus->m_inProcess ) { - tobekilled = pStatus->m_iKillSent = 0; - } - } - if ( tobekilled ) { - tobekilled = 0; - if ( pStatus->m_iKillSent > 5 ) { - tobekilled = SIGKILL; - } else { - if ( pStatus->m_iKillSent == 3 ) { - tobekilled = SIGTERM; - } else { - if ( pStatus->m_iKillSent == 1 ) { - tobekilled = SIGUSR1; - } - } - } - if ( tobekilled ) { - kill( pStatus->m_pid, tobekilled ); - } - ++pStatus->m_iKillSent; - ++dying; - } - - } else { - ++dying; - } - ++pStatus; - } -} - -static int lsapi_all_children_must_die() -{ - int maxWait; - int sec =0; - g_prefork_server->m_iMaxReqProcessTime = 10; - g_prefork_server->m_iMaxIdleChildren = -1; - maxWait = 15; - - while( g_prefork_server->m_iCurChildren && (sec < maxWait) ) { - lsapi_check_child_status(time(NULL)); - sleep( 1 ); - sec++; - } - if ( g_prefork_server->m_iCurChildren != 0 ) { - kill( -getpgrp(), SIGKILL ); - } - return 0; -} - - - -static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Request * pReq ) -{ - struct sigaction act, old_term, old_quit, old_int, - old_usr1, old_child; - lsapi_child_status * child_status; - int wait_secs = 0; - int ret = 0; - int pid; - time_t lastTime = 0; - time_t curTime = 0; - fd_set readfds; - struct timeval timeout; - - lsapi_init_children_status(); - - setsid(); - - act.sa_flags = 0; - act.sa_handler = lsapi_sigchild; - if( sigaction( SIGCHLD, &act, &old_child ) ) { - perror( "Can't set signal handler for SIGCHILD" ); - return -1; - } - - /* Set up handler to kill children upon exit */ - act.sa_flags = 0; - act.sa_handler = lsapi_cleanup; - if( sigaction( SIGTERM, &act, &old_term ) || - sigaction( SIGINT, &act, &old_int ) || - sigaction( SIGUSR1, &act, &old_usr1 ) || - sigaction( SIGQUIT, &act, &old_quit )) { - perror( "Can't set signals" ); - return -1; - } - s_stop = 0; - while( !s_stop ) { - if ( ret ) { - curTime = time( NULL ); - } else { - ++curTime; - } - if (curTime != lastTime ) { - lastTime = curTime; - if (s_ppid && (getppid() != s_ppid )) { - break; - } - lsapi_check_child_status(curTime ); - if (pServer->m_iServerMaxIdle) { - if ( pServer->m_iCurChildren <= 0 ) { - ++wait_secs; - if ( wait_secs > pServer->m_iServerMaxIdle ) { - return -1; - } - } else { - wait_secs = 0; - } - } - } - - if ( pServer->m_iCurChildren >= (pServer->m_iMaxChildren + pServer->m_iExtraChildren ) ) { - usleep( 100000 ); - continue; - } - - FD_ZERO( &readfds ); - FD_SET( pServer->m_fd, &readfds ); - timeout.tv_sec = 1; timeout.tv_usec = 0; - if ((ret = (*g_fnSelect)(pServer->m_fd+1, &readfds, NULL, NULL, &timeout)) == 1 ) { - if ( pServer->m_iCurChildren >= 0 ) { - usleep( 10 ); - FD_ZERO( &readfds ); - FD_SET( pServer->m_fd, &readfds ); - timeout.tv_sec = 0; timeout.tv_usec = 0; - if ( (*g_fnSelect)(pServer->m_fd+1, &readfds, NULL, NULL, &timeout) == 0 ) { - continue; - } - } - } else { - if ( ret == -1 ) { - if ( errno == EINTR ) { - continue; - } - /* perror( "select()" ); */ - break; - } else { - continue; - } - } - - pReq->m_fd = lsapi_accept( pServer->m_fd ); - if ( pReq->m_fd != -1 ) { - child_status = find_child_status( 0 ); - pid = fork(); - if ( !pid ) { - g_prefork_server = NULL; - s_ppid = getppid(); - s_req_processed = 0; - s_pChildStatus = child_status; - child_status->m_iKillSent = 0; - lsapi_set_nblock( pReq->m_fd, 0 ); - - /* don't catch our signals */ - sigaction( SIGCHLD, &old_child, 0 ); - sigaction( SIGTERM, &old_term, 0 ); - sigaction( SIGQUIT, &old_quit, 0 ); - sigaction( SIGINT, &old_int, 0 ); - sigaction( SIGUSR1, &old_usr1, 0 ); - return 0; - } else { - if ( pid == -1 ) { - perror( "fork() failed, please increase process limit" ); - } else { - ++pServer->m_iCurChildren; - if ( child_status ) { - child_status->m_pid = pid; - child_status->m_iKillSent = 0; - child_status->m_tmWaitBegin = time(NULL); - } - } - } - close( pReq->m_fd ); - pReq->m_fd = -1; - - } else { - if (( errno == EINTR )||( errno == EAGAIN)) { - continue; - } - perror( "accept() failed" ); - return -1; - } - } - sigaction( SIGUSR1, &old_usr1, 0 ); - kill( -getpgrp(), SIGUSR1 ); - lsapi_all_children_must_die(); /* Sorry, children ;-) */ - return -1; - -} - -int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq ) -{ - int fd; - int ret; - int wait_secs; - fd_set readfds; - struct timeval timeout; - - LSAPI_Finish_r( pReq ); - - - if ( g_prefork_server ) { - if ( g_prefork_server->m_fd != -1 ) { - if ( lsapi_prefork_server_accept( g_prefork_server, pReq ) == -1 ) { - return -1; - } - } - } - if ( s_req_processed >= s_max_reqs ) { - return -1; - } - - if ( s_pChildStatus ) { - s_pChildStatus->m_tmWaitBegin = time( NULL ); - } - - while( g_running ) { - if ( pReq->m_fd != -1 ) { - fd = pReq->m_fd; - } else { - if ( pReq->m_fdListen != -1 ) { - fd = pReq->m_fdListen; - } else { - return -1; - } - } - wait_secs = 0; - while( 1 ) { - if ( !g_running ) { - return -1; - } - if (( s_pChildStatus )&&( s_pChildStatus->m_iKillSent )) { - return -1; - } - FD_ZERO( &readfds ); - FD_SET( fd, &readfds ); - timeout.tv_sec = 1; - timeout.tv_usec = 0; - ret = (*g_fnSelect)(fd+1, &readfds, NULL, NULL, &timeout); - if ( ret == 0 ) { - if ( s_pChildStatus ) { - s_pChildStatus->m_inProcess = 0; - } - ++wait_secs; - if (( s_max_idle_secs > 0 )&&(wait_secs >= s_max_idle_secs )) { - return -1; - } - if ( s_ppid &&( getppid() != s_ppid)) { - return -1; - } - } else { - if ( ret == -1 ) { - if ( errno == EINTR ) { - continue; - } else { - return -1; - } - } else { - if ( ret >= 1 ) { - if (( s_pChildStatus )&&( s_pChildStatus->m_iKillSent )) { - return -1; - } - if ( fd == pReq->m_fdListen ) { - pReq->m_fd = lsapi_accept( pReq->m_fdListen ); - if ( pReq->m_fd != -1 ) { - fd = pReq->m_fd; - lsapi_set_nblock( fd, 0 ); - } else { - if (( errno == EINTR )||( errno == EAGAIN)) { - continue; - } - return -1; - } - } else { - break; - } - } - } - } - } - if ( !readReq( pReq ) ) { - if ( s_pChildStatus ) { - s_pChildStatus->m_inProcess = 1; - s_pChildStatus->m_tmReqBegin = s_pChildStatus->m_tmLastCheckPoint = time(NULL); - } - ++s_req_processed; - return 0; - } - lsapi_close( pReq->m_fd ); - pReq->m_fd = -1; - LSAPI_Reset_r( pReq ); - } - return -1; - -} - -void LSAPI_Set_Max_Reqs( int reqs ) -{ - s_max_reqs = reqs; -} - -void LSAPI_Set_Max_Idle( int secs ) -{ - s_max_idle_secs = secs; -} - -void LSAPI_Set_Max_Children( int maxChildren ) -{ - if ( g_prefork_server ) { - g_prefork_server->m_iMaxChildren = maxChildren; - } -} - -void LSAPI_Set_Extra_Children( int extraChildren ) -{ - if (( g_prefork_server )&&( extraChildren >= 0 )) { - g_prefork_server->m_iExtraChildren = extraChildren; - } -} - -void LSAPI_Set_Max_Process_Time( int secs ) -{ - if (( g_prefork_server )&&( secs > 0 )) { - g_prefork_server->m_iMaxReqProcessTime = secs; - } -} - - -void LSAPI_Set_Max_Idle_Children( int maxIdleChld ) -{ - if (( g_prefork_server )&&( maxIdleChld > 0 )) { - g_prefork_server->m_iMaxIdleChildren = maxIdleChld; - } -} - -void LSAPI_Set_Server_Max_Idle_Secs( int serverMaxIdle ) -{ - if ( g_prefork_server ) { - g_prefork_server->m_iServerMaxIdle = serverMaxIdle; - } -} - - -void LSAPI_No_Check_ppid() -{ - s_ppid = 0; -} - -#if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) -#include <crt_externs.h> -#else -extern char ** environ; -#endif -static void unset_lsapi_envs() -{ - char **env; -#if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) - env = *_NSGetEnviron(); -#else - env = environ; -#endif - while( env != NULL && *env != NULL ) { - if ( !strncmp(*env, "LSAPI_", 6) || - !strncmp( *env, "PHP_LSAPI_", 10 ) ) { - char ** del = env; - do { - *del = del[1]; - } while( *del++ ); - } else { - ++env; - } - } -} - -void LSAPI_Init_Env_Parameters( fn_select_t fp ) -{ - const char *p; - int n; - int avoidFork = 0; - p = getenv( "PHP_LSAPI_MAX_REQUESTS" ); - if ( !p ) { - p = getenv( "LSAPI_MAX_REQS" ); - } - if ( p ) { - n = atoi( p ); - if ( n > 0 ) { - LSAPI_Set_Max_Reqs( n ); - } - } - - p = getenv( "LSAPI_AVOID_FORK" ); - if ( p ) { - avoidFork = atoi( p ); - } - -#if defined( RLIMIT_CORE ) - p = getenv( "LSAPI_ALLOW_CORE_DUMP" ); - if ( !p ) { - struct rlimit limit = { 0, 0 }; - setrlimit( RLIMIT_CORE, &limit ); - } -#endif - - p = getenv( "LSAPI_MAX_IDLE" ); - if ( p ) { - n = atoi( p ); - LSAPI_Set_Max_Idle( n ); - } - - if ( LSAPI_Is_Listen() ) { - n = 0; - p = getenv( "PHP_LSAPI_CHILDREN" ); - if ( !p ) { - p = getenv( "LSAPI_CHILDREN" ); - } - if ( p ) { - n = atoi( p ); - } - if ( n > 1 ) { - LSAPI_Init_Prefork_Server( n, fp, avoidFork ); - LSAPI_Set_Server_fd( g_req.m_fdListen ); - } - - p = getenv( "LSAPI_EXTRA_CHILDREN" ); - if ( p ) { - LSAPI_Set_Extra_Children( atoi( p ) ); - } - - p = getenv( "LSAPI_MAX_IDLE_CHILDREN" ); - if ( p ) { - LSAPI_Set_Max_Idle_Children( atoi( p ) ); - } - p = getenv( "LSAPI_PGRP_MAX_IDLE" ); - if ( p ) { - LSAPI_Set_Server_Max_Idle_Secs( atoi( p ) ); - } - - p = getenv( "LSAPI_MAX_PROCESS_TIME" ); - if ( p ) { - LSAPI_Set_Max_Process_Time( atoi( p ) ); - } - if ( getenv( "LSAPI_PPID_NO_CHECK" ) ) { - LSAPI_No_Check_ppid(); - } - } - unset_lsapi_envs(); -} - - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: sw=4 ts=4 fdm=marker - * vim<600: sw=4 ts=4 - */ - - diff --git a/sapi/litespeed/lsapilib.h b/sapi/litespeed/lsapilib.h deleted file mode 100644 index b7b82e3594..0000000000 --- a/sapi/litespeed/lsapilib.h +++ /dev/null @@ -1,358 +0,0 @@ - -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2007 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available at through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Author: George Wang <gwang@litespeedtech.com> | - +----------------------------------------------------------------------+ -*/ - -/* -Copyright (c) 2007, Lite Speed Technologies Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - * Neither the name of the Lite Speed Technologies Inc nor the - names of its contributors may be used to endorse or promote - products derived from this software without specific prior - written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - - -#ifndef _LSAPILIB_H_ -#define _LSAPILIB_H_ - -#if defined (c_plusplus) || defined (__cplusplus) -extern "C" { -#endif - -#include <stddef.h> -#include <lsapidef.h> - -#include <sys/time.h> -#include <sys/types.h> - -struct LSAPI_key_value_pair -{ - char * pKey; - char * pValue; - int keyLen; - int valLen; -}; - - -#define LSAPI_MAX_RESP_HEADERS 100 - -typedef struct lsapi_request -{ - int m_fdListen; - int m_fd; - - long m_lLastActive; - long m_lReqBegin; - - char * m_pReqBuf; - int m_reqBufSize; - - char * m_pRespBuf; - char * m_pRespBufEnd; - char * m_pRespBufPos; - - char * m_pRespHeaderBuf; - char * m_pRespHeaderBufEnd; - char * m_pRespHeaderBufPos; - - - struct iovec * m_pIovec; - struct iovec * m_pIovecEnd; - struct iovec * m_pIovecCur; - struct iovec * m_pIovecToWrite; - - struct lsapi_packet_header * m_respPktHeaderEnd; - - struct lsapi_req_header * m_pHeader; - struct LSAPI_key_value_pair * m_pEnvList; - struct LSAPI_key_value_pair * m_pSpecialEnvList; - int m_envListSize; - int m_specialEnvListSize; - - struct lsapi_http_header_index * m_pHeaderIndex; - struct lsapi_header_offset * m_pUnknownHeader; - - char * m_pScriptFile; - char * m_pScriptName; - char * m_pQueryString; - char * m_pHttpHeader; - char * m_pRequestMethod; - int m_totalLen; - int m_reqState; - int m_reqBodyRead; - int m_bufProcessed; - int m_bufRead; - - struct lsapi_packet_header m_respPktHeader[5]; - - struct lsapi_resp_header m_respHeader; - short m_respHeaderLen[LSAPI_MAX_RESP_HEADERS]; - -}LSAPI_Request; - -extern LSAPI_Request g_req; - - -/* return: >0 continue, ==0 stop, -1 failed */ -typedef int (*LSAPI_CB_EnvHandler )( const char * pKey, int keyLen, - const char * pValue, int valLen, void * arg ); - - -int LSAPI_Init(void); - -void LSAPI_Stop(void); - -int LSAPI_Is_Listen_r( LSAPI_Request * pReq); - -int LSAPI_InitRequest( LSAPI_Request * pReq, int fd ); - -int LSAPI_Accept_r( LSAPI_Request * pReq ); - -void LSAPI_Reset_r( LSAPI_Request * pReq ); - -int LSAPI_Finish_r( LSAPI_Request * pReq ); - -int LSAPI_Release_r( LSAPI_Request * pReq ); - -char * LSAPI_GetHeader_r( LSAPI_Request * pReq, int headerIndex ); - -int LSAPI_ForeachHeader_r( LSAPI_Request * pReq, - LSAPI_CB_EnvHandler fn, void * arg ); - -int LSAPI_ForeachOrgHeader_r( LSAPI_Request * pReq, - LSAPI_CB_EnvHandler fn, void * arg ); - -int LSAPI_ForeachEnv_r( LSAPI_Request * pReq, - LSAPI_CB_EnvHandler fn, void * arg ); - -int LSAPI_ForeachSpecialEnv_r( LSAPI_Request * pReq, - LSAPI_CB_EnvHandler fn, void * arg ); - -char * LSAPI_GetEnv_r( LSAPI_Request * pReq, const char * name ); - - -int LSAPI_ReadReqBody_r( LSAPI_Request * pReq, char * pBuf, int len ); - -int LSAPI_ReqBodyGetChar_r( LSAPI_Request * pReq ); - -int LSAPI_ReqBodyGetLine_r( LSAPI_Request * pReq, char * pBuf, int bufLen, int *getLF ); - - -int LSAPI_FinalizeRespHeaders_r( LSAPI_Request * pReq ); - -int LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, int len ); - -int LSAPI_Write_Stderr_r( LSAPI_Request * pReq, const char * pBuf, int len ); - -int LSAPI_Flush_r( LSAPI_Request * pReq ); - -int LSAPI_AppendRespHeader_r( LSAPI_Request * pHeader, char * pBuf, int len ); - -static inline int LSAPI_SetRespStatus_r( LSAPI_Request * pReq, int code ) -{ - if ( !pReq ) - return -1; - pReq->m_respHeader.m_respInfo.m_status = code; - return 0; -} - -static inline char * LSAPI_GetQueryString_r( LSAPI_Request * pReq ) -{ - if ( pReq ) - return pReq->m_pQueryString; - return NULL; -} - - -static inline char * LSAPI_GetScriptFileName_r( LSAPI_Request * pReq ) -{ - if ( pReq ) - return pReq->m_pScriptFile; - return NULL; -} - - -static inline char * LSAPI_GetScriptName_r( LSAPI_Request * pReq ) -{ - if ( pReq ) - return pReq->m_pScriptName; - return NULL; -} - - -static inline char * LSAPI_GetRequestMethod_r( LSAPI_Request * pReq) -{ - if ( pReq ) - return pReq->m_pRequestMethod; - return NULL; -} - - - -static inline int LSAPI_GetReqBodyLen_r( LSAPI_Request * pReq ) -{ - if ( pReq ) - return pReq->m_pHeader->m_reqBodyLen; - return -1; -} - -static inline int LSAPI_GetReqBodyRemain_r( LSAPI_Request * pReq ) -{ - if ( pReq ) - return pReq->m_pHeader->m_reqBodyLen - pReq->m_reqBodyRead; - return -1; -} - - -int LSAPI_Is_Listen(void); - -static inline int LSAPI_Accept( void ) -{ return LSAPI_Accept_r( &g_req ); } - -static inline int LSAPI_Finish(void) -{ return LSAPI_Finish_r( &g_req ); } - -static inline char * LSAPI_GetHeader( int headerIndex ) -{ return LSAPI_GetHeader_r( &g_req, headerIndex ); } - -static inline int LSAPI_ForeachHeader( LSAPI_CB_EnvHandler fn, void * arg ) -{ return LSAPI_ForeachHeader_r( &g_req, fn, arg ); } - -static inline int LSAPI_ForeachOrgHeader( - LSAPI_CB_EnvHandler fn, void * arg ) -{ return LSAPI_ForeachOrgHeader_r( &g_req, fn, arg ); } - -static inline int LSAPI_ForeachEnv( LSAPI_CB_EnvHandler fn, void * arg ) -{ return LSAPI_ForeachEnv_r( &g_req, fn, arg ); } - -static inline int LSAPI_ForeachSpecialEnv( LSAPI_CB_EnvHandler fn, void * arg ) -{ return LSAPI_ForeachSpecialEnv_r( &g_req, fn, arg ); } - -static inline char * LSAPI_GetEnv( const char * name ) -{ return LSAPI_GetEnv_r( &g_req, name ); } - -static inline char * LSAPI_GetQueryString() -{ return LSAPI_GetQueryString_r( &g_req ); } - -static inline char * LSAPI_GetScriptFileName() -{ return LSAPI_GetScriptFileName_r( &g_req ); } - -static inline char * LSAPI_GetScriptName() -{ return LSAPI_GetScriptName_r( &g_req ); } - -static inline char * LSAPI_GetRequestMethod() -{ return LSAPI_GetRequestMethod_r( &g_req ); } - -static inline int LSAPI_GetReqBodyLen() -{ return LSAPI_GetReqBodyLen_r( &g_req ); } - -static inline int LSAPI_GetReqBodyRemain() -{ return LSAPI_GetReqBodyRemain_r( &g_req ); } - -static inline int LSAPI_ReadReqBody( char * pBuf, int len ) -{ return LSAPI_ReadReqBody_r( &g_req, pBuf, len ); } - -static inline int LSAPI_ReqBodyGetChar() -{ return LSAPI_ReqBodyGetChar_r( &g_req ); } - -static inline int LSAPI_ReqBodyGetLine( char * pBuf, int len, int *getLF ) -{ return LSAPI_ReqBodyGetLine_r( &g_req, pBuf, len, getLF ); } - - - -static inline int LSAPI_FinalizeRespHeaders(void) -{ return LSAPI_FinalizeRespHeaders_r( &g_req ); } - -static inline int LSAPI_Write( const char * pBuf, int len ) -{ return LSAPI_Write_r( &g_req, pBuf, len ); } - -static inline int LSAPI_Write_Stderr( const char * pBuf, int len ) -{ return LSAPI_Write_Stderr_r( &g_req, pBuf, len ); } - -static inline int LSAPI_Flush() -{ return LSAPI_Flush_r( &g_req ); } - -static inline int LSAPI_AppendRespHeader( char * pBuf, int len ) -{ return LSAPI_AppendRespHeader_r( &g_req, pBuf, len ); } - -static inline int LSAPI_SetRespStatus( int code ) -{ return LSAPI_SetRespStatus_r( &g_req, code ); } - -int LSAPI_IsRunning(void); - -int LSAPI_CreateListenSock( const char * pBind, int backlog ); - -typedef int (*fn_select_t)( int, fd_set *, fd_set *, fd_set *, struct timeval * ); - -int LSAPI_Init_Prefork_Server( int max_children, fn_select_t fp, int avoidFork ); - -void LSAPI_Set_Server_fd( int fd ); - -int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq ); - -void LSAPI_Set_Max_Reqs( int reqs ); - -void LSAPI_Set_Max_Idle( int secs ); - -void LSAPI_Set_Max_Children( int maxChildren ); - -void LSAPI_Set_Max_Idle_Children( int maxIdleChld ); - -void LSAPI_Set_Server_Max_Idle_Secs( int serverMaxIdle ); - -void LSAPI_Set_Max_Process_Time( int secs ); - -void LSAPI_Init_Env_Parameters( fn_select_t fp ); - -#if defined (c_plusplus) || defined (__cplusplus) -} -#endif - - -#endif - - - - - - - diff --git a/sapi/milter/php_milter.c b/sapi/milter/php_milter.c index 0c51837bc1..5d1ddde135 100644 --- a/sapi/milter/php_milter.c +++ b/sapi/milter/php_milter.c @@ -770,42 +770,51 @@ PHP_MINFO_FUNCTION(milter) /* }}} */ /* {{{ arginfo */ +static ZEND_BEGIN_ARG_INFO_EX(arginfo_smfi_setflags, 0, 0, 1) ZEND_ARG_INFO(0, flags) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_smfi_settimeout, 0, 0, 1) ZEND_ARG_INFO(0, timeout) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_smfi_getsymval, 0, 0, 1) ZEND_ARG_INFO(0, macro) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_smfi_setreply, 0, 0, 3) ZEND_ARG_INFO(0, rcode) ZEND_ARG_INFO(0, xcode) ZEND_ARG_INFO(0, message) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_smfi_addheader, 0, 0, 2) ZEND_ARG_INFO(0, headerf) ZEND_ARG_INFO(0, headerv) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_smfi_chgheader, 0, 0, 2) ZEND_ARG_INFO(0, headerf) ZEND_ARG_INFO(0, headerv) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_smfi_addrcpt, 0, 0, 1) ZEND_ARG_INFO(0, rcpt) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_smfi_delrcpt, 0, 0, 1) ZEND_ARG_INFO(0, rcpt) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO_EX(arginfo_smfi_replacebody, 0, 0, 1) ZEND_ARG_INFO(0, body) ZEND_END_ARG_INFO() diff --git a/sapi/nsapi/nsapi.c b/sapi/nsapi/nsapi.c index bb448b51e8..490d64e066 100644 --- a/sapi/nsapi/nsapi.c +++ b/sapi/nsapi/nsapi.c @@ -60,6 +60,12 @@ * NSAPI includes */ #include "nsapi.h" +#include "base/pblock.h" +#include "base/session.h" +#include "frame/req.h" +#include "frame/protocol.h" /* protocol_start_response */ +#include "base/util.h" /* is_mozilla, getline */ +#include "frame/log.h" /* log_error */ #define NSLS_D struct nsapi_request_context *request_context #define NSLS_DC , NSLS_D @@ -164,13 +170,16 @@ ZEND_DECLARE_MODULE_GLOBALS(nsapi) /* {{{ arginfo */ +static ZEND_BEGIN_ARG_INFO_EX(arginfo_nsapi_virtual, 0, 0, 1) ZEND_ARG_INFO(0, uri) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO(arginfo_nsapi_request_headers, 0) ZEND_END_ARG_INFO() +static ZEND_BEGIN_ARG_INFO(arginfo_nsapi_response_headers, 0) ZEND_END_ARG_INFO() /* }}} */ @@ -440,6 +449,8 @@ PHP_FUNCTION(nsapi_response_headers) array_init(return_value); + php_header(TSRMLS_C); + for (i=0; i < rc->rq->srvhdrs->hsize; i++) { entry=rc->rq->srvhdrs->ht[i]; while (entry) { @@ -458,12 +469,9 @@ PHP_FUNCTION(nsapi_response_headers) static int sapi_nsapi_ub_write(const char *str, unsigned int str_length TSRMLS_DC) { int retval; - nsapi_request_context *rc = (nsapi_request_context *)SG(server_context); - - if (!SG(headers_sent)) { - sapi_send_headers(TSRMLS_C); - } + nsapi_request_context *rc; + rc = (nsapi_request_context *)SG(server_context); retval = net_write(rc->sn->csd, (char *)str, str_length); if (retval == IO_ERROR /* -1 */ || retval == IO_EOF /* 0 */) { php_handle_aborted_connection(); @@ -471,98 +479,38 @@ static int sapi_nsapi_ub_write(const char *str, unsigned int str_length TSRMLS_D return retval; } -/* modified version of apache2 */ -static void sapi_nsapi_flush(void *server_context) +static int sapi_nsapi_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) { - nsapi_request_context *rc = (nsapi_request_context *)server_context; - TSRMLS_FETCH(); - - if (!SG(headers_sent)) { - sapi_send_headers(TSRMLS_C); - } + char *header_name, *header_content, *p; + nsapi_request_context *rc = (nsapi_request_context *)SG(server_context); - /* flushing is only supported in iPlanet servers from version 6.1 on, make it conditional */ -#if NSAPI_VERSION >= 302 - if (net_flush(rc->sn->csd) < 0) { - php_handle_aborted_connection(); + header_name = sapi_header->header; + header_content = p = strchr(header_name, ':'); + if (p == NULL) { + efree(sapi_header->header); + return 0; } -#endif -} -/* callback for zend_llist_apply on SAPI_HEADER_DELETE_ALL operation */ -static int php_nsapi_remove_header(sapi_header_struct *sapi_header TSRMLS_DC) -{ - char *header_name, *p; - nsapi_request_context *rc = (nsapi_request_context *)SG(server_context); - - /* copy the header, because NSAPI needs reformatting and we do not want to change the parameter */ - header_name = nsapi_strdup(sapi_header->header); + *p = 0; + do { + header_content++; + } while (*header_content == ' '); - /* extract name, this works, if only the header without ':' is given, too */ - if (p = strchr(header_name, ':')) { - *p = 0; - } - - /* header_name to lower case because NSAPI reformats the headers and wants lowercase */ - for (p=header_name; *p; p++) { - *p=tolower(*p); + if (!strcasecmp(header_name, "Content-Type")) { + param_free(pblock_remove("content-type", rc->rq->srvhdrs)); + pblock_nvinsert("content-type", header_content, rc->rq->srvhdrs); + } else { + /* to lower case because NSAPI reformats the headers and wants lowercase */ + for (p=header_name; *p; p++) { + *p=tolower(*p); + } + if (sapi_header->replace) param_free(pblock_remove(header_name, rc->rq->srvhdrs)); + pblock_nvinsert(header_name, header_content, rc->rq->srvhdrs); } - - /* remove the header */ - param_free(pblock_remove(header_name, rc->rq->srvhdrs)); - nsapi_free(header_name); - - return ZEND_HASH_APPLY_KEEP; -} -static int sapi_nsapi_header_handler(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers TSRMLS_DC) -{ - char *header_name, *header_content, *p; - nsapi_request_context *rc = (nsapi_request_context *)SG(server_context); + sapi_free_header(sapi_header); - switch(op) { - case SAPI_HEADER_DELETE_ALL: - /* this only deletes headers set or overwritten by PHP, headers previously set by NSAPI are left intact */ - zend_llist_apply(&sapi_headers->headers, (llist_apply_func_t) php_nsapi_remove_header TSRMLS_CC); - return 0; - - case SAPI_HEADER_DELETE: - /* reuse the zend_llist_apply callback function for this, too */ - php_nsapi_remove_header(sapi_header TSRMLS_CC); - return 0; - - case SAPI_HEADER_ADD: - case SAPI_HEADER_REPLACE: - /* copy the header, because NSAPI needs reformatting and we do not want to change the parameter */ - header_name = nsapi_strdup(sapi_header->header); - - /* split header and align pointer for content */ - header_content = strchr(header_name, ':'); - if (header_content) { - *header_content = 0; - do { - header_content++; - } while (*header_content==' '); - - /* header_name to lower case because NSAPI reformats the headers and wants lowercase */ - for (p=header_name; *p; p++) { - *p=tolower(*p); - } - - /* if REPLACE, remove first. "Content-type" is always removed, as SAPI has a bug according to this */ - if (op==SAPI_HEADER_REPLACE || strcmp(header_name, "content-type")==0) { - param_free(pblock_remove(header_name, rc->rq->srvhdrs)); - } - /* ADD header to nsapi table */ - pblock_nvinsert(header_name, header_content, rc->rq->srvhdrs); - } - - nsapi_free(header_name); - return SAPI_HEADER_ADD; - - default: - return 0; - } + return 0; /* don't use the default SAPI mechanism, NSAPI duplicates this functionality */ } static int sapi_nsapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC) @@ -803,13 +751,6 @@ static int php_nsapi_startup(sapi_module_struct *sapi_module) return SUCCESS; } -static struct stat* sapi_nsapi_get_stat(TSRMLS_D) -{ - return request_stat_path( - SG(request_info).path_translated, - ((nsapi_request_context *)SG(server_context))->rq - ); -} static sapi_module_struct nsapi_sapi_module = { "nsapi", /* name */ @@ -822,8 +763,8 @@ static sapi_module_struct nsapi_sapi_module = { NULL, /* deactivate */ sapi_nsapi_ub_write, /* unbuffered write */ - sapi_nsapi_flush, /* flush */ - sapi_nsapi_get_stat, /* get uid/stat */ + NULL, /* flush */ + NULL, /* get uid */ NULL, /* getenv */ php_error, /* error handler */ @@ -913,10 +854,12 @@ int NSAPI_PUBLIC php5_init(pblock *pb, Session *sn, Request *rq) int threads=128; /* default for server */ /* fetch max threads from NSAPI and initialize TSRM with it */ - threads=conf_getglobals()->Vpool_maxthreads; +#if defined(pool_maxthreads) + threads=pool_maxthreads; if (threads<1) { threads=128; /* default for server */ } +#endif tsrm_startup(threads, 1, 0, NULL); core_globals = ts_resource(core_globals_id); @@ -964,7 +907,7 @@ int NSAPI_PUBLIC php5_execute(pblock *pb, Session *sn, Request *rq) int retval; nsapi_request_context *request_context; zend_file_handle file_handle = {0}; - struct stat *fst; + struct stat fst; char *path_info; char *query_string = pblock_findval("query", rq->reqpb); @@ -1036,8 +979,7 @@ int NSAPI_PUBLIC php5_execute(pblock *pb, Session *sn, Request *rq) file_handle.free_filename = 0; file_handle.opened_path = NULL; - fst = request_stat_path(SG(request_info).path_translated, rq); - if (fst && S_ISREG(fst->st_mode)) { + if (stat(SG(request_info).path_translated, &fst)==0 && S_ISREG(fst.st_mode)) { if (php_request_startup(TSRMLS_C) == SUCCESS) { php_execute_script(&file_handle TSRMLS_CC); php_request_shutdown(NULL); |