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