X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=php_http_version.c;h=7adef9d3c897ce66f5923b981c74bd3b46a992d0;hp=4561b8fbd13d851fa53e3be68f150c7da942b780;hb=refs%2Fheads%2Fv2.3.x;hpb=8d05291f42b3b42159b3fe91492aa4862f3d4405 diff --git a/php_http_version.c b/php_http_version.c index 4561b8f..7adef9d 100644 --- a/php_http_version.c +++ b/php_http_version.c @@ -6,13 +6,13 @@ | modification, are permitted provided that the conditions mentioned | | in the accompanying LICENSE file are met. | +--------------------------------------------------------------------+ - | Copyright (c) 2004-2011, Michael Wallner | + | Copyright (c) 2004-2014, Michael Wallner | +--------------------------------------------------------------------+ */ -#include "php_http.h" +#include "php_http_api.h" -PHP_HTTP_API php_http_version_t *php_http_version_init(php_http_version_t *v, unsigned major, unsigned minor TSRMLS_DC) +php_http_version_t *php_http_version_init(php_http_version_t *v, unsigned major, unsigned minor TSRMLS_DC) { if (!v) { v = emalloc(sizeof(*v)); @@ -24,44 +24,53 @@ PHP_HTTP_API php_http_version_t *php_http_version_init(php_http_version_t *v, un return v; } -PHP_HTTP_API php_http_version_t *php_http_version_parse(php_http_version_t *v, const char *str TSRMLS_DC) +php_http_version_t *php_http_version_parse(php_http_version_t *v, const char *str TSRMLS_DC) { - php_http_version_t tmp; + long major, minor; char separator = 0; + register const char *ptr = str; - if (3 != sscanf(str, "HTTP/%u%c%u", &tmp.major, &separator, &tmp.minor) - && 3 != sscanf(str, "%u%c%u", &tmp.major, &separator, &tmp.minor)) { - php_http_error(HE_WARNING, PHP_HTTP_E_MALFORMED_HEADERS, "Could not parse HTTP protocol version '%s'", str); - return NULL; + switch (*ptr) { + case 'h': + case 'H': + ++ptr; if (*ptr != 't' && *ptr != 'T') break; + ++ptr; if (*ptr != 't' && *ptr != 'T') break; + ++ptr; if (*ptr != 'p' && *ptr != 'P') break; + ++ptr; if (*ptr != '/') break; + ++ptr; + /* no break */ + default: + /* rfc7230#2.6 The HTTP version number consists of two decimal digits separated by a "." (period or decimal point) */ + major = *ptr++ - '0'; + if (major >= 0 && major <= 9) { + separator = *ptr++; + if (separator) { + if (separator != '.' && separator != ',') { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Non-standard version separator '%c' in HTTP protocol version '%s'", separator, ptr - 2); + } + minor = *ptr - '0'; + if (minor >= 0 && minor <= 9) { + return php_http_version_init(v, major, minor TSRMLS_CC); + } + } + } } - if (separator && separator != '.' && separator != ',') { - php_http_error(HE_NOTICE, PHP_HTTP_E_MALFORMED_HEADERS, "Non-standard version separator '%c' in HTTP protocol version '%s'", separator, str); - } - - return php_http_version_init(v, tmp.major, tmp.minor TSRMLS_CC); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not parse HTTP protocol version '%s'", str); + return NULL; } -PHP_HTTP_API void php_http_version_to_string(php_http_version_t *v, char **str, size_t *len, const char *pre, const char *post TSRMLS_DC) +void php_http_version_to_string(php_http_version_t *v, char **str, size_t *len, const char *pre, const char *post TSRMLS_DC) { *len = spprintf(str, 0, "%s%u.%u%s", pre ? pre : "", v->major, v->minor, post ? post : ""); } -PHP_HTTP_API void php_http_version_to_struct(php_http_version_t *v, HashTable *strct TSRMLS_DC) -{ - zval tmp; - - INIT_PZVAL_ARRAY(&tmp, strct); - add_assoc_long(&tmp, "major", v->major); - add_assoc_long(&tmp, "minor", v->minor); -} - -PHP_HTTP_API void php_http_version_dtor(php_http_version_t *v) +void php_http_version_dtor(php_http_version_t *v) { (void) v; } -PHP_HTTP_API void php_http_version_free(php_http_version_t **v) +void php_http_version_free(php_http_version_t **v) { if (*v) { php_http_version_dtor(*v);