- allow negative time offsets
[m6w6/ext-http] / http_info_api.c
1 /*
2 +----------------------------------------------------------------------+
3 | PECL :: http |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.0 of the PHP license, that |
6 | is bundled with this package in the file LICENSE, and is available |
7 | through the world-wide-web at http://www.php.net/license/3_0.txt. |
8 | If you did not receive a copy of the PHP license and are unable to |
9 | obtain it through the world-wide-web, please send a note to |
10 | license@php.net so we can mail you a copy immediately. |
11 +----------------------------------------------------------------------+
12 | Copyright (c) 2004-2005 Michael Wallner <mike@php.net> |
13 +----------------------------------------------------------------------+
14 */
15
16 /* $Id$ */
17
18 #ifdef HAVE_CONFIG_H
19 # include "config.h"
20 #endif
21 #include "php.h"
22
23 #include "php_http.h"
24 #include "php_http_api.h"
25 #include "php_http_std_defs.h"
26 #include "php_http_info_api.h"
27
28 #include <ctype.h>
29
30 ZEND_EXTERN_MODULE_GLOBALS(http);
31
32 PHP_HTTP_API void _http_info_default_callback(void **nothing, HashTable **headers, http_info *info TSRMLS_DC)
33 {
34 zval array;
35
36 INIT_ZARR(array, *headers);
37
38 switch (info->type)
39 {
40 case IS_HTTP_REQUEST:
41 add_assoc_string(&array, "Request Method", HTTP_INFO(info).request.method, 1);
42 add_assoc_string(&array, "Request Uri", HTTP_INFO(info).request.URI, 1);
43 break;
44
45 case IS_HTTP_RESPONSE:
46 add_assoc_long(&array, "Response Code", (long) HTTP_INFO(info).response.code);
47 add_assoc_string(&array, "Response Status", HTTP_INFO(info).response.status, 1);
48 break;
49 }
50 }
51
52 PHP_HTTP_API void _http_info_dtor(http_info *info)
53 {
54 http_info_t *i = (http_info_t *) info;
55
56 switch (info->type)
57 {
58 case IS_HTTP_REQUEST:
59 STR_SET(i->request.method, NULL);
60 STR_SET(i->request.URI, NULL);
61 break;
62
63 case IS_HTTP_RESPONSE:
64 STR_SET(i->response.status, NULL);
65 break;
66
67 default:
68 break;
69 }
70 }
71
72 PHP_HTTP_API STATUS _http_info_parse_ex(const char *pre_header, http_info *info, zend_bool silent TSRMLS_DC)
73 {
74 const char *end, *http;
75
76 /* sane parameter */
77 if ((!pre_header) || (!*pre_header)) {
78 if (!silent) {
79 http_error(HE_WARNING, HTTP_E_MALFORMED_HEADERS, "Empty pre-header HTTP info");
80 }
81 return FAILURE;
82 }
83
84 /* where's the end of the line */
85 if (!(end = http_locate_eol(pre_header, NULL))) {
86 end = pre_header + strlen(pre_header);
87 }
88
89 /* there must be HTTP/1.x in the line
90 * and nothing than SPACE or NUL after HTTP/1.x
91 */
92 if ( (!(http = strstr(pre_header, "HTTP/1."))) ||
93 (!(http < end)) ||
94 (!isdigit(http[lenof("HTTP/1.")])) ||
95 (http[lenof("HTTP/1.1")] && (!isspace(http[lenof("HTTP/1.1")])))) {
96 if (!silent) {
97 http_error(HE_WARNING, HTTP_E_MALFORMED_HEADERS, "Invalid or missing HTTP/1.x protocol identification");
98 }
99 return FAILURE;
100 }
101
102 #if 0
103 {
104 char *line = estrndup(pre_header, end - pre_header);
105 fprintf(stderr, "http_parse_info('%s')\n", line);
106 efree(line);
107 }
108 #endif
109
110 info->http.version = atof(http + lenof("HTTP/"));
111
112 /* is response */
113 if (pre_header == http) {
114 char *status = NULL;
115 const char *code = http + sizeof("HTTP/1.1");
116
117 info->type = IS_HTTP_RESPONSE;
118 HTTP_INFO(info).response.code = (code && (end > code)) ? strtol(code, &status, 10) : 0;
119 HTTP_INFO(info).response.status = (status && (end > ++status)) ? estrndup(status, end - status) : ecalloc(1,1);
120
121 return SUCCESS;
122 }
123
124 /* is request */
125 else {
126 const char *url = strchr(pre_header, ' ');
127
128 info->type = IS_HTTP_REQUEST;
129 if (url && http > url) {
130 HTTP_INFO(info).request.method = estrndup(pre_header, url - pre_header);
131 HTTP_INFO(info).request.URI = estrndup(url + 1, http - url - 2);
132 } else {
133 HTTP_INFO(info).request.method = ecalloc(1,1);
134 HTTP_INFO(info).request.URI = ecalloc(1,1);
135 }
136
137 return SUCCESS;
138 }
139 }
140
141
142 /*
143 * Local variables:
144 * tab-width: 4
145 * c-basic-offset: 4
146 * End:
147 * vim600: noet sw=4 ts=4 fdm=marker
148 * vim<600: noet sw=4 ts=4
149 */
150