- update
[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 Z_ARRVAL(array) = *headers;
36
37 switch (info->type)
38 {
39 case IS_HTTP_REQUEST:
40 add_assoc_string(&array, "Request Method", HTTP_INFO(info).request.method, 1);
41 add_assoc_string(&array, "Request Uri", HTTP_INFO(info).request.URI, 1);
42 break;
43
44 case IS_HTTP_RESPONSE:
45 add_assoc_long(&array, "Response Code", (long) HTTP_INFO(info).response.code);
46 add_assoc_string(&array, "Response Status", HTTP_INFO(info).response.status, 1);
47 break;
48 }
49 }
50
51 PHP_HTTP_API void _http_info_dtor(http_info *info)
52 {
53 http_info_t *i = (http_info_t *) info;
54
55 switch (info->type)
56 {
57 case IS_HTTP_REQUEST:
58 STR_SET(i->request.method, NULL);
59 STR_SET(i->request.URI, NULL);
60 break;
61
62 case IS_HTTP_RESPONSE:
63 STR_SET(i->response.status, NULL);
64 break;
65
66 default:
67 break;
68 }
69 }
70
71 PHP_HTTP_API STATUS _http_info_parse_ex(const char *pre_header, http_info *info, zend_bool silent TSRMLS_DC)
72 {
73 const char *end, *http;
74
75 /* sane parameter */
76 if ((!pre_header) || (!*pre_header)) {
77 if (!silent) {
78 http_error(HE_WARNING, HTTP_E_MALFORMED_HEADERS, "Empty pre-header HTTP info");
79 }
80 return FAILURE;
81 }
82
83 /* where's the end of the line */
84 if (!(end = http_locate_eol(pre_header, NULL))) {
85 end = pre_header + strlen(pre_header);
86 }
87
88 /* there must be HTTP/1.x in the line
89 * and nothing than SPACE or NUL after HTTP/1.x
90 */
91 if ( (!(http = strstr(pre_header, "HTTP/1."))) ||
92 (!(http < end)) ||
93 (!isdigit(http[lenof("HTTP/1.")])) ||
94 (http[lenof("HTTP/1.1")] && (!isspace(http[lenof("HTTP/1.1")])))) {
95 if (!silent) {
96 http_error(HE_WARNING, HTTP_E_MALFORMED_HEADERS, "Invalid or missing HTTP/1.x protocol identification");
97 }
98 return FAILURE;
99 }
100
101 #if 0
102 {
103 char *line = estrndup(pre_header, end - pre_header);
104 fprintf(stderr, "http_parse_info('%s')\n", line);
105 efree(line);
106 }
107 #endif
108
109 info->http.version = atof(http + lenof("HTTP/"));
110
111 /* is response */
112 if (pre_header == http) {
113 char *status = NULL;
114 const char *code = http + sizeof("HTTP/1.1");
115
116 info->type = IS_HTTP_RESPONSE;
117 HTTP_INFO(info).response.code = (code && (end > code)) ? strtol(code, &status, 10) : 0;
118 HTTP_INFO(info).response.status = (status && (end > ++status)) ? estrndup(status, end - status) : ecalloc(1,1);
119
120 return SUCCESS;
121 }
122
123 /* is request */
124 else {
125 const char *url = strchr(pre_header, ' ');
126
127 info->type = IS_HTTP_REQUEST;
128 if (url && http > url) {
129 HTTP_INFO(info).request.method = estrndup(pre_header, url - pre_header);
130 HTTP_INFO(info).request.URI = estrndup(url + 1, http - url - 2);
131 } else {
132 HTTP_INFO(info).request.method = ecalloc(1,1);
133 HTTP_INFO(info).request.URI = ecalloc(1,1);
134 }
135
136 return SUCCESS;
137 }
138 }
139
140
141 /*
142 * Local variables:
143 * tab-width: 4
144 * c-basic-offset: 4
145 * End:
146 * vim600: noet sw=4 ts=4 fdm=marker
147 * vim<600: noet sw=4 ts=4
148 */
149