use the new params parser
[m6w6/ext-http] / php_http_info.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-2011, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
11 */
12
13 #include "php_http.h"
14
15 PHP_HTTP_API void php_http_info_default_callback(void **nothing, HashTable **headers, php_http_info_t *info TSRMLS_DC)
16 {
17 zval array;
18 (void) nothing;
19
20 INIT_PZVAL_ARRAY(&array, *headers);
21
22 switch (info->type) {
23 case PHP_HTTP_REQUEST:
24 add_assoc_string(&array, "Request Method", PHP_HTTP_INFO(info).request.method, 1);
25 add_assoc_string(&array, "Request Url", PHP_HTTP_INFO(info).request.url, 1);
26 break;
27
28 case PHP_HTTP_RESPONSE:
29 add_assoc_long(&array, "Response Code", (long) PHP_HTTP_INFO(info).response.code);
30 add_assoc_string(&array, "Response Status", PHP_HTTP_INFO(info).response.status, 1);
31 break;
32
33 case PHP_HTTP_NONE:
34 break;
35 }
36 }
37
38 PHP_HTTP_API php_http_info_t *php_http_info_init(php_http_info_t *i TSRMLS_DC)
39 {
40 if (!i) {
41 i = emalloc(sizeof(*i));
42 }
43
44 memset(i, 0, sizeof(*i));
45
46 return i;
47 }
48
49 PHP_HTTP_API void php_http_info_dtor(php_http_info_t *i)
50 {
51 switch (i->type) {
52 case PHP_HTTP_REQUEST:
53 STR_SET(PHP_HTTP_INFO(i).request.method, NULL);
54 STR_SET(PHP_HTTP_INFO(i).request.url, NULL);
55 break;
56
57 case PHP_HTTP_RESPONSE:
58 STR_SET(PHP_HTTP_INFO(i).response.status, NULL);
59 break;
60
61 default:
62 break;
63 }
64 }
65
66 PHP_HTTP_API void php_http_info_free(php_http_info_t **i)
67 {
68 if (*i) {
69 php_http_info_dtor(*i);
70 efree(*i);
71 *i = NULL;
72 }
73 }
74
75 PHP_HTTP_API php_http_info_t *php_http_info_parse(php_http_info_t *info, const char *pre_header TSRMLS_DC)
76 {
77 const char *end, *http;
78 zend_bool free_info = !info;
79
80 /* sane parameter */
81 if ((!pre_header) || (!*pre_header)) {
82 return NULL;
83 }
84
85 /* where's the end of the line */
86 if (!(end = php_http_locate_eol(pre_header, NULL))) {
87 end = pre_header + strlen(pre_header);
88 }
89
90 /* there must be HTTP/1.x in the line */
91 if (!(http = php_http_locate_str(pre_header, end - pre_header, "HTTP/1.", lenof("HTTP/1.")))) {
92 return NULL;
93 }
94
95 info = php_http_info_init(info TSRMLS_CC);
96
97 /* and nothing than SPACE or NUL after HTTP/1.x */
98 if (!php_http_version_parse(&info->http.version, http TSRMLS_CC)
99 || (http[lenof("HTTP/1.1")] && (!PHP_HTTP_IS_CTYPE(space, http[lenof("HTTP/1.1")])))) {
100 if (free_info) {
101 php_http_info_free(&info);
102 }
103 return NULL;
104 }
105
106 #if 0
107 {
108 char *line = estrndup(pre_header, end - pre_header);
109 fprintf(stderr, "http_parse_info('%s')\n", line);
110 efree(line);
111 }
112 #endif
113
114 /* is response */
115 if (pre_header == http) {
116 char *status = NULL;
117 const char *code = http + sizeof("HTTP/1.1");
118
119 info->type = PHP_HTTP_RESPONSE;
120 while (' ' == *code) ++code;
121 if (code && end > code) {
122 PHP_HTTP_INFO(info).response.code = strtol(code, &status, 10);
123 } else {
124 PHP_HTTP_INFO(info).response.code = 0;
125 }
126 if (status && end > status) {
127 while (' ' == *status) ++status;
128 PHP_HTTP_INFO(info).response.status = estrndup(status, end - status);
129 } else {
130 PHP_HTTP_INFO(info).response.status = NULL;
131 }
132
133 return info;
134 }
135
136 /* is request */
137 else if (!http[lenof("HTTP/1.x")] || http[lenof("HTTP/1.x")] == '\r' || http[lenof("HTTP/1.x")] == '\n') {
138 const char *url = strchr(pre_header, ' ');
139
140 info->type = PHP_HTTP_REQUEST;
141 if (url && http > url) {
142 PHP_HTTP_INFO(info).request.method = estrndup(pre_header, url - pre_header);
143 while (' ' == *url) ++url;
144 while (' ' == *(http-1)) --http;
145 if (http > url) {
146 PHP_HTTP_INFO(info).request.url = estrndup(url, http - url);
147 } else {
148 efree(PHP_HTTP_INFO(info).request.method);
149 return NULL;
150 }
151 } else {
152 PHP_HTTP_INFO(info).request.method = NULL;
153 PHP_HTTP_INFO(info).request.url = NULL;
154 }
155
156 return info;
157 }
158
159 /* some darn header containing HTTP/1.x */
160 else {
161 if (free_info) {
162 php_http_info_free(&info);
163 }
164 return NULL;
165 }
166 }
167
168 /*
169 * Local variables:
170 * tab-width: 4
171 * c-basic-offset: 4
172 * End:
173 * vim600: noet sw=4 ts=4 fdm=marker
174 * vim<600: noet sw=4 ts=4
175 */
176