travis: allow_failures
[m6w6/ext-http] / src / php_http_version.c
1 /*
2 +--------------------------------------------------------------------+
3 | PECL :: http |
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the conditions mentioned |
7 | in the accompanying LICENSE file are met. |
8 +--------------------------------------------------------------------+
9 | Copyright (c) 2004-2014, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
11 */
12
13 #include "php_http_api.h"
14
15 php_http_version_t *php_http_version_init(php_http_version_t *v, unsigned major, unsigned minor)
16 {
17 if (!v) {
18 v = emalloc(sizeof(*v));
19 }
20
21 v->major = major;
22 v->minor = minor;
23
24 return v;
25 }
26
27 php_http_version_t *php_http_version_parse(php_http_version_t *v, const char *str)
28 {
29 long major, minor;
30 char separator = 0;
31 register const char *ptr = str;
32
33 switch (*ptr) {
34 case 'h':
35 case 'H':
36 ++ptr; if (*ptr != 't' && *ptr != 'T') break;
37 ++ptr; if (*ptr != 't' && *ptr != 'T') break;
38 ++ptr; if (*ptr != 'p' && *ptr != 'P') break;
39 ++ptr; if (*ptr != '/') break;
40 ++ptr;
41 /* no break */
42 default:
43 /* rfc7230#2.6 The HTTP version number consists of two decimal digits separated by a "." (period or decimal point) */
44 major = *ptr++ - '0';
45 if (major >= 0 && major <= 9) {
46 separator = *ptr++;
47 switch (separator) {
48 default:
49 php_error_docref(NULL, E_NOTICE, "Non-standard version separator '%c' in HTTP protocol version '%s'", separator, ptr - 2);
50 /* no break */
51 case '.':
52 case ',':
53 minor = *ptr - '0';
54 break;
55
56 case ' ':
57 if (major > 1) {
58 minor = 0;
59 } else {
60 goto error;
61 }
62 }
63 if (minor >= 0 && minor <= 9) {
64 return php_http_version_init(v, major, minor);
65 }
66 }
67 }
68
69 error:
70 php_error_docref(NULL, E_WARNING, "Could not parse HTTP protocol version '%s'", str);
71 return NULL;
72 }
73
74 void php_http_version_to_string(php_http_version_t *v, char **str, size_t *len, const char *pre, const char *post)
75 {
76 /* different semantics for different versions */
77 if (v->major == 2) {
78 *len = spprintf(str, 0, "%s2%s", STR_PTR(pre), STR_PTR(post));
79 } else {
80 *len = spprintf(str, 0, "%s%u.%u%s", STR_PTR(pre), v->major, v->minor, STR_PTR(post));
81 }
82 }
83
84 void php_http_version_dtor(php_http_version_t *v)
85 {
86 (void) v;
87 }
88
89 void php_http_version_free(php_http_version_t **v)
90 {
91 if (*v) {
92 php_http_version_dtor(*v);
93 efree(*v);
94 *v = NULL;
95 }
96 }
97
98 /*
99 * Local variables:
100 * tab-width: 4
101 * c-basic-offset: 4
102 * End:
103 * vim600: noet sw=4 ts=4 fdm=marker
104 * vim<600: noet sw=4 ts=4
105 */
106