array_init(return_value);
if (SUCCESS != http_parse_headers(header, return_value)) {
zval_dtor(return_value);
+ http_error(HE_WARNING, HTTP_E_MALFORMED_HEADERS, "Failed to parse headers");
RETURN_FALSE;
}
}
PHP_HTTP_API STATUS _http_parse_headers_ex(const char *header, HashTable *headers, zend_bool prettify,
http_info_callback callback_func, void **callback_data TSRMLS_DC)
{
- const char *colon = NULL, *line = NULL, *begin = header;
- const char *body = http_locate_body(header);
- size_t header_len;
+ const char *colon = NULL, *line = header;
zval array;
INIT_ZARR(array, headers);
- if (body) {
- header_len = body - header;
- } else {
- header_len = strlen(header) + 1;
- }
- line = header;
-
- if (header_len) do {
+ do {
int value_len = 0;
+
switch (*line++)
{
case ':':
}
efree(key);
}
+ } else {
+ return FAILURE;
}
colon = NULL;
value_len = 0;
}
break;
}
- } while (header_len > (size_t) (line - begin));
+ } while (*(line-1) && !(*(line-1) == '\n' && (*line == '\n' || *line == '\r')));
return SUCCESS;
}
/* there must be HTTP/1.x in the line
* and nothing than SPACE or NUL after HTTP/1.x
*/
- if ( (!(http = strstr(pre_header, "HTTP/1."))) ||
+ if ( (!(http = php_memnstr((char *) pre_header, "HTTP/1.", lenof("HTTP/1."), (char *)end))) ||
(!(http < end)) ||
(!isdigit(http[lenof("HTTP/1.")])) ||
(http[lenof("HTTP/1.1")] && (!isspace(http[lenof("HTTP/1.1")])))) {
</stability>
<license>BSD, revised</license>
<notes><![CDATA[
+- Improved performance of the message and header parser
+* Fixed internal http_parse_headers() always returning success
* Fixed missing "parentMessage" entry in print_r($HttpMessageObject)
]]></notes>
<contents>
#define http_locate_body _http_locate_body
static inline const char *_http_locate_body(const char *message)
{
- const char *cr = strstr(message, "\r\n\r\n");
- const char *lf = strstr(message, "\n\n");
-
- if (lf && cr) {
- return MIN(lf + 2, cr + 4);
- } else if (lf || cr) {
- return MAX(lf + 2, cr + 4);
- } else {
- return NULL;
+ const char *body = NULL, *msg = message;
+
+ while (*msg) {
+ if (*msg == '\n') {
+ if (*(msg+1) == '\n') {
+ body = msg + 2;
+ break;
+ } else if (*(msg+1) == '\r' && *(msg+2) == '\n' && msg != message && *(msg-1) == '\r') {
+ body = msg + 3;
+ break;
+ }
+ }
+ ++msg;
}
+ return body;
}
#define http_locate_eol _http_locate_eol