PHP_FE(http_send_stream, NULL)
PHP_FE(http_chunked_decode, NULL)
PHP_FE(http_split_response, NULL)
+ PHP_FE(http_parse_header, NULL)
#ifdef HTTP_HAVE_CURL
PHP_FE(http_get, NULL)
PHP_FE(http_head, NULL)
MAKE_STD_ZVAL(zheaders);
array_init(zheaders);
- http_split_response(zresponse, zheaders, zbody);
+ if (SUCCESS != http_split_response(zresponse, zheaders, zbody)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not parse HTTP response");
+ RETURN_FALSE;
+ }
array_init(return_value);
add_index_zval(return_value, 0, zheaders);
}
/* }}} */
+/* {{{ proto array http_parse_header(string header) */
+PHP_FUNCTION(http_parse_header)
+{
+ 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")) {
+ header_len = rnrn - header + 2;
+ }
+ if (SUCCESS != http_parse_header(header, header_len, return_value)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not parse HTTP header");
+ zval_dtor(return_value);
+ RETURN_FALSE;
+ }
+}
+/* }}}*/
+
/* {{{ HAVE_CURL */
#ifdef HTTP_HAVE_CURL
}
/* }}} */
-/* {{{ proto void http_split_response(zval *, zval *, zval *) */
-PHP_HTTP_API void _http_split_response(const zval *zresponse, zval *zheaders,
+/* {{{ proto STATUS http_split_response(zval *, zval *, zval *) */
+PHP_HTTP_API STATUS _http_split_response(const zval *zresponse, zval *zheaders,
zval *zbody TSRMLS_DC)
{
char *header, *response, *body = NULL;
Z_TYPE_P(zbody) = IS_NULL;
}
- /* check for HTTP status - FIXXME: strchr() */
+ return http_parse_header(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)
+{
+ char *colon = NULL, *line = NULL, *begin = header;
+
+ if (header_len < 8) {
+ return FAILURE;
+ }
+
+ /* status code */
if (!strncmp(header, "HTTP/1.", 7)) {
- char *end = strchr(header, '\r');
- add_assoc_stringl(zheaders, "Status",
+ char *end = strstr(header, "\r\n");
+ add_assoc_stringl(array, "Status",
header + strlen("HTTP/1.x "),
end - (header + strlen("HTTP/1.x ")), 1);
header = end + 2;
}
- /* split headers */
- {
- char *colon = NULL, *line = header;
- while ( (line - Z_STRVAL_P(zresponse) + 3) <
- (body - Z_STRVAL_P(zresponse))) {
- switch (*line++)
- {
- case '\r':
- if (colon && (*line == '\n')) {
- char *key = estrndup(header, colon - header);
- add_assoc_stringl(zheaders, key,
- colon + 2, line - colon - 3, 1);
- efree(key);
-
- colon = NULL;
- header += line - header + 1;
- }
- break;
+ line = header;
- case ':':
- if (!colon) {
- colon = line - 1;
- }
- break;
- }
+ /*
+ * FIXXME: support for folded headers
+ */
+ while (header_len > (line - begin)) {
+ switch (*line++)
+ {
+ case 0:
+ case '\r':
+ if (colon && (*line == '\n')) {
+ char *key = estrndup(header, colon - header);
+ add_assoc_stringl(array, key, colon + 2, line - colon - 3, 1);
+ efree(key);
+
+ colon = NULL;
+ header += line - header + 1;
+ }
+ break;
+
+ case ':':
+ if (!colon) {
+ colon = line - 1;
+ }
+ break;
}
}
+ return SUCCESS;
}
/* }}} */
PHP_HTTP_API STATUS _http_chunked_decode(const char *encoded, const size_t encoded_len, char **decoded, size_t *decoded_len TSRMLS_DC);
#define http_split_response(r, h, b) _http_split_response((r), (h), (b) TSRMLS_CC)
-PHP_HTTP_API void _http_split_response(const zval *zresponse, zval *zheaders, zval *zbody TSRMLS_DC);
+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);
/* {{{ HAVE_CURL */
#ifdef HTTP_HAVE_CURL