diff options
author | Dmitry Stogov <dmitry@php.net> | 2010-07-14 15:20:44 +0000 |
---|---|---|
committer | Dmitry Stogov <dmitry@php.net> | 2010-07-14 15:20:44 +0000 |
commit | f33d2c5fb78e1f2c24ee0717f2f5d4d5158e0206 (patch) | |
tree | 6f737e89f3d2e696529b89e4f5c3968112685fbd /main | |
parent | 7c24be8672e03219e41ffd7b76ef5f8da552f86b (diff) | |
download | php-git-f33d2c5fb78e1f2c24ee0717f2f5d4d5158e0206.tar.gz |
Optimized defaut Content-Type HTTP header processing
Diffstat (limited to 'main')
-rw-r--r-- | main/SAPI.c | 138 | ||||
-rw-r--r-- | main/main.c | 2 |
2 files changed, 88 insertions, 52 deletions
diff --git a/main/SAPI.c b/main/SAPI.c index ca54b3d8af..0dec78142e 100644 --- a/main/SAPI.c +++ b/main/SAPI.c @@ -224,35 +224,61 @@ SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data) } -SAPI_API char *sapi_get_default_content_type(TSRMLS_D) +static inline char *get_default_content_type(uint prefix_len, uint *len TSRMLS_DC) { char *mimetype, *charset, *content_type; + uint mimetype_len, charset_len; - mimetype = SG(default_mimetype) ? SG(default_mimetype) : SAPI_DEFAULT_MIMETYPE; - charset = SG(default_charset) ? SG(default_charset) : SAPI_DEFAULT_CHARSET; + if (SG(default_mimetype)) { + mimetype = SG(default_mimetype); + mimetype_len = strlen(SG(default_mimetype)); + } else { + mimetype = SAPI_DEFAULT_MIMETYPE; + mimetype_len = sizeof(SAPI_DEFAULT_MIMETYPE) - 1; + } + if (SG(default_charset)) { + charset = SG(default_charset); + charset_len = strlen(SG(default_charset)); + } else { + charset = SAPI_DEFAULT_CHARSET; + charset_len = sizeof(SAPI_DEFAULT_CHARSET) - 1; + } + + if (*charset && strncasecmp(mimetype, "text/", 5) == 0) { + char *p; - if (strncasecmp(mimetype, "text/", 5) == 0 && *charset) { - int len = strlen(mimetype) + sizeof("; charset=") + strlen(charset); /* sizeof() includes \0 */ - content_type = emalloc(len); - snprintf(content_type, len, "%s; charset=%s", mimetype, charset); + *len = prefix_len + mimetype_len + sizeof("; charset=") - 1 + charset_len; + content_type = (char*)emalloc(*len + 1); + p = content_type + prefix_len; + memcpy(p, mimetype, mimetype_len); + p += mimetype_len; + memcpy(p, "; charset=", sizeof("; charset=") - 1); + p += sizeof("; charset=") - 1; + memcpy(p, charset, charset_len + 1); } else { - content_type = estrdup(mimetype); + *len = prefix_len + mimetype_len; + content_type = (char*)emalloc(*len + 1); + memcpy(content_type + prefix_len, mimetype, mimetype_len + 1); } return content_type; } +SAPI_API char *sapi_get_default_content_type(TSRMLS_D) +{ + uint len; + + return get_default_content_type(0, &len TSRMLS_CC); +} + + SAPI_API void sapi_get_default_content_type_header(sapi_header_struct *default_header TSRMLS_DC) { - char *default_content_type = sapi_get_default_content_type(TSRMLS_C); - int default_content_type_len = strlen(default_content_type); + uint len; - default_header->header_len = (sizeof("Content-type: ")-1) + default_content_type_len; - default_header->header = emalloc(default_header->header_len+1); - memcpy(default_header->header, "Content-type: ", sizeof("Content-type: ")); - memcpy(default_header->header+sizeof("Content-type: ")-1, default_content_type, default_content_type_len); - default_header->header[default_header->header_len] = 0; - efree(default_content_type); + default_header->header = get_default_content_type(sizeof("Content-type: ")-1, &len TSRMLS_CC); + default_header->header_len = len; + memcpy(default_header->header, "Content-type: ", sizeof("Content-type: ") - 1); } /* @@ -521,6 +547,27 @@ SAPI_API int sapi_add_header_ex(char *header_line, uint header_line_len, zend_bo return r; } +static void sapi_header_add_op(sapi_header_op_enum op, sapi_header_struct *sapi_header TSRMLS_DC) +{ + if (!sapi_module.header_handler || + (SAPI_HEADER_ADD & sapi_module.header_handler(sapi_header, op, &SG(sapi_headers) TSRMLS_CC))) { + if (op == SAPI_HEADER_REPLACE) { + char *colon_offset = strchr(sapi_header->header, ':'); + + if (colon_offset) { + char sav = *colon_offset; + + *colon_offset = 0; + zend_llist_del_element(&SG(sapi_headers).headers, sapi_header->header, (int(*)(void*, void*))sapi_find_matching_header); + *colon_offset = sav; + } + } + zend_llist_add_element(&SG(sapi_headers).headers, (void *) sapi_header); + } else { + sapi_free_header(sapi_header); + } +} + SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC) { int retval; @@ -577,8 +624,12 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC) header_line = estrndup(header_line, header_line_len); /* cut of trailing spaces, linefeeds and carriage-returns */ - while(header_line_len && isspace(header_line[header_line_len-1])) - header_line[--header_line_len]='\0'; + if (header_line_len && isspace(header_line[header_line_len-1])) { + do { + header_line_len--; + } while(header_line_len && isspace(header_line[header_line_len-1])); + header_line[--header_line_len]='\0'; + } if (op == SAPI_HEADER_DELETE) { if (strchr(header_line, ':')) { @@ -586,6 +637,14 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC) sapi_module.sapi_error(E_WARNING, "Header to delete may not contain colon."); return FAILURE; } + if (sapi_module.header_handler) { + sapi_header.header = header_line; + sapi_header.header_len = header_line_len; + sapi_module.header_handler(&sapi_header, op, &SG(sapi_headers) TSRMLS_CC); + } + zend_llist_del_element(&SG(sapi_headers).headers, header_line, (int(*)(void*, void*))sapi_find_matching_header); + efree(header_line); + return SUCCESS; } else { /* new line safety check */ char *s = header_line, *e = header_line + header_line_len, *p; @@ -603,15 +662,6 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC) sapi_header.header = header_line; sapi_header.header_len = header_line_len; - if (op == SAPI_HEADER_DELETE) { - if (sapi_module.header_handler) { - sapi_module.header_handler(&sapi_header, op, &SG(sapi_headers) TSRMLS_CC); - } - zend_llist_del_element(&SG(sapi_headers).headers, sapi_header.header, (int(*)(void*, void*))sapi_find_matching_header); - sapi_free_header(&sapi_header); - return SUCCESS; - } - /* Check the header for a few cases that we have special support for in SAPI */ if (header_line_len>=5 && !strncasecmp(header_line, "HTTP/", 5)) { @@ -689,28 +739,7 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC) if (http_response_code) { sapi_update_response_code(http_response_code TSRMLS_CC); } - if (sapi_module.header_handler) { - retval = sapi_module.header_handler(&sapi_header, op, &SG(sapi_headers) TSRMLS_CC); - } else { - retval = SAPI_HEADER_ADD; - } - if (retval & SAPI_HEADER_ADD) { - /* in replace mode first remove the header if it already exists in the headers llist */ - if (op == SAPI_HEADER_REPLACE) { - colon_offset = strchr(sapi_header.header, ':'); - if (colon_offset) { - char sav; - sav = *colon_offset; - *colon_offset = 0; - zend_llist_del_element(&SG(sapi_headers).headers, sapi_header.header, (int(*)(void*, void*))sapi_find_matching_header); - *colon_offset = sav; - } - } - - zend_llist_add_element(&SG(sapi_headers).headers, (void *) &sapi_header); - } else { - sapi_free_header(&sapi_header); - } + sapi_header_add_op(op, &sapi_header TSRMLS_CC); return SUCCESS; } @@ -729,8 +758,15 @@ SAPI_API int sapi_send_headers(TSRMLS_D) */ if (SG(sapi_headers).send_default_content_type && sapi_module.send_headers) { sapi_header_struct default_header; - sapi_get_default_content_type_header(&default_header TSRMLS_CC); - sapi_add_header_ex(default_header.header, default_header.header_len, 0, 0 TSRMLS_CC); + uint len; + + SG(sapi_headers).mimetype = get_default_content_type(0, &len TSRMLS_CC); + default_header.header_len = sizeof("Content-type: ") - 1 + len; + default_header.header = emalloc(default_header.header_len + 1); + memcpy(default_header.header, "Content-type: ", sizeof("Content-type: ") - 1); + memcpy(default_header.header + sizeof("Content-type: ") - 1, SG(sapi_headers).mimetype, len + 1); + sapi_header_add_op(SAPI_HEADER_ADD, &default_header TSRMLS_CC); + SG(sapi_headers).send_default_content_type = 0; } SG(headers_sent) = 1; diff --git a/main/main.c b/main/main.c index 9106b91e8f..9253092973 100644 --- a/main/main.c +++ b/main/main.c @@ -1047,7 +1047,7 @@ static void php_error_cb(int type, const char *error_filename, const uint error_ sapi_header_line ctr = {0}; ctr.line = "HTTP/1.0 500 Internal Server Error"; - ctr.line_len = strlen(ctr.line); + ctr.line_len = sizeof("HTTP/1.0 500 Internal Server Error") - 1; sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC); } /* the parser would return 1 (failure), we can bail out nicely */ |