PHP_FE(http_send_stream, NULL)
PHP_FE(http_chunked_decode, NULL)
PHP_FE(http_split_response, NULL)
- PHP_FE(http_parse_header, NULL)
+ PHP_FE(http_parse_headers, NULL)
#ifdef HTTP_HAVE_CURL
PHP_FE(http_get, NULL)
PHP_FE(http_head, NULL)
}
/* }}} */
-/* {{{ proto array http_parse_header(string header) */
-PHP_FUNCTION(http_parse_header)
+/* {{{ proto array http_parse_headers(string header) */
+PHP_FUNCTION(http_parse_headers)
{
char *header, *rnrn;
int header_len;
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &header, &header_len)) {
RETURN_FALSE;
}
-
+
array_init(return_value);
-
- if (rnrn = strstr(header, "\r\n\r\n")) {
+
+ if (rnrn = strstr(header, HTTP_CRLF HTTP_CRLF)) {
header_len = rnrn - header + 2;
}
- if (SUCCESS != http_parse_header(header, header_len, return_value)) {
+ if (SUCCESS != http_parse_headers(header, header_len, return_value)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not parse HTTP header");
zval_dtor(return_value);
RETURN_FALSE;
}
/* write boundary once more */
- php_body_write("\r\n", 1 TSRMLS_CC);
+ php_body_write(HTTP_CRLF, 1 TSRMLS_CC);
php_body_write(bound, strlen(bound) TSRMLS_CC);
return SUCCESS;
char *d_ptr;
*decoded_len = 0;
- *decoded = (char *) ecalloc(1, encoded_len);
+ *decoded = (char *) ecalloc(encoded_len, 1);
d_ptr = *decoded;
e_ptr = encoded;
hex_len[i++] = *e_ptr++;
}
+ /* reached the end */
+ if (!strcmp(hex_len, "0")) {
+ break;
+ }
+
+ /* new line */
+ if (strncmp(e_ptr, HTTP_CRLF, 2)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "Invalid character (expected 0x0D 0x0A; got: %x %x)",
+ *e_ptr, *(e_ptr + 1));
+ efree(*decoded);
+ return FAILURE;
+ }
+
/* hex to long */
- if (strcmp(hex_len, "0")) {
+ {
char *error = NULL;
chunk_len = strtol(hex_len, &error, 16);
if (error == hex_len) {
efree(*decoded);
return FAILURE;
}
- } else {
- break;
}
- /* new line */
- if (*e_ptr++ != '\r' || *e_ptr++ != '\n') {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
- "Invalid character (expected 0x0A, 0x0D; got: %x)",
- *(e_ptr - 1));
- efree(*decoded);
- return FAILURE;
- }
-
- memcpy(d_ptr, e_ptr, chunk_len);
+ memcpy(d_ptr, e_ptr += 2, chunk_len);
d_ptr += chunk_len;
e_ptr += chunk_len + 2;
*decoded_len += chunk_len;
Z_TYPE_P(zbody) = IS_NULL;
}
- return http_parse_header(header, body - Z_STRVAL_P(zresponse), zheaders);
+ return http_parse_headers(header, body - Z_STRVAL_P(zresponse), zheaders);
}
/* }}} */
-/* {{{ STATUS http_parse_header(char *, long, zval *) */
-PHP_HTTP_API STATUS _http_parse_header(char *header, long header_len, zval *array TSRMLS_DC)
+/* {{{ STATUS http_parse_headers(char *, long, zval *) */
+PHP_HTTP_API STATUS _http_parse_headers(char *header, int header_len, zval *array TSRMLS_DC)
{
char *colon = NULL, *line = NULL, *begin = header;
/* status code */
if (!strncmp(header, "HTTP/1.", 7)) {
- char *end = strstr(header, "\r\n");
+ char *end = strstr(header, HTTP_CRLF);
add_assoc_stringl(array, "Status",
header + strlen("HTTP/1.x "),
end - (header + strlen("HTTP/1.x ")), 1);
header = end + 2;
}
-
+
line = header;
- /*
- * FIXXME: support for folded headers
- */
while (header_len > (line - begin)) {
switch (*line++)
{
case 0:
- case '\r':
- if (colon && (*line == '\n')) {
+ case '\n':
+ if (colon && (*line != ' ') && (*line != '\t')) {
char *key = estrndup(header, colon - header);
- add_assoc_stringl(array, key, colon + 2, line - colon - 3, 1);
+ add_assoc_stringl(array, key, colon + 2, line - colon - 4, 1);
efree(key);
colon = NULL;
- header += line - header + 1;
+ header += line - header;
}
break;
} http_send_mode;
/* }}} */
+/* CR LF */
+#define HTTP_CRLF "\r\n"
+
/* max URI length */
#define HTTP_URI_MAXLEN 2048
#define http_split_response(r, h, b) _http_split_response((r), (h), (b) TSRMLS_CC)
PHP_HTTP_API STATUS _http_split_response(const zval *zresponse, zval *zheaders, zval *zbody TSRMLS_DC);
-#define http_parse_header(h, l, a) _http_parse_header((h), (l), (a) TSRMLS_CC)
-PHP_HTTP_API STATUS _http_parse_header(char *header, long header_len, zval *array TSRMLS_DC);
+#define http_parse_headers(h, l, a) _http_parse_headers((h), (l), (a) TSRMLS_CC)
+PHP_HTTP_API STATUS _http_parse_headers(char *header, int header_len, zval *array TSRMLS_DC);
/* {{{ HAVE_CURL */
#ifdef HTTP_HAVE_CURL