2 +--------------------------------------------------------------------+
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-2010, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
17 #include "php_http_api.h"
18 #include "php_http_info_api.h"
20 PHP_HTTP_API
void _http_info_default_callback(void **nothing
, HashTable
**headers
, http_info
*info TSRMLS_DC
)
24 INIT_ZARR(array
, *headers
);
28 add_assoc_string(&array
, "Request Method", HTTP_INFO(info
).request
.method
, 1);
29 add_assoc_string(&array
, "Request Url", HTTP_INFO(info
).request
.url
, 1);
32 case IS_HTTP_RESPONSE
:
33 add_assoc_long(&array
, "Response Code", (long) HTTP_INFO(info
).response
.code
);
34 if (HTTP_INFO(info
).response
.status
) {
35 add_assoc_string(&array
, "Response Status", HTTP_INFO(info
).response
.status
, 1);
41 PHP_HTTP_API
void _http_info_dtor(http_info
*i
)
45 STR_SET(HTTP_INFO(i
).request
.method
, NULL
);
46 STR_SET(HTTP_INFO(i
).request
.url
, NULL
);
49 case IS_HTTP_RESPONSE
:
50 STR_SET(HTTP_INFO(i
).response
.status
, NULL
);
58 PHP_HTTP_API STATUS
_http_info_parse_ex(const char *pre_header
, http_info
*info
, zend_bool silent TSRMLS_DC
)
60 const char *end
, *http
;
63 if ((!pre_header
) || (!*pre_header
)) {
67 /* where's the end of the line */
68 if (!(end
= http_locate_eol(pre_header
, NULL
))) {
69 end
= pre_header
+ strlen(pre_header
);
72 /* there must be HTTP/1.x in the line */
73 if (!(http
= http_locate_str(pre_header
, end
- pre_header
, "HTTP/1.", lenof("HTTP/1.")))) {
77 /* and nothing than SPACE or NUL after HTTP/1.x */
78 if ( (!HTTP_IS_CTYPE(digit
, http
[lenof("HTTP/1.")])) ||
79 (http
[lenof("HTTP/1.1")] && (!HTTP_IS_CTYPE(space
, http
[lenof("HTTP/1.1")])))) {
81 http_error(HE_WARNING
, HTTP_E_MALFORMED_HEADERS
, "Invalid HTTP/1.x protocol identification");
88 char *line
= estrndup(pre_header
, end
- pre_header
);
89 fprintf(stderr
, "http_parse_info('%s')\n", line
);
94 info
->http
.version
= zend_strtod(http
+ lenof("HTTP/"), NULL
);
97 if (pre_header
== http
) {
99 const char *code
= http
+ sizeof("HTTP/1.1");
101 info
->type
= IS_HTTP_RESPONSE
;
102 while (' ' == *code
) ++code
;
103 if (code
&& end
> code
) {
104 HTTP_INFO(info
).response
.code
= strtol(code
, &status
, 10);
106 HTTP_INFO(info
).response
.code
= 0;
108 if (status
&& end
> status
) {
109 while (' ' == *status
) ++status
;
110 HTTP_INFO(info
).response
.status
= estrndup(status
, end
- status
);
112 HTTP_INFO(info
).response
.status
= NULL
;
119 else if (!http
[lenof("HTTP/1.x")] || http
[lenof("HTTP/1.x")] == '\r' || http
[lenof("HTTP/1.x")] == '\n') {
120 const char *url
= strchr(pre_header
, ' ');
122 info
->type
= IS_HTTP_REQUEST
;
123 if (url
&& http
> url
) {
124 HTTP_INFO(info
).request
.method
= estrndup(pre_header
, url
- pre_header
);
125 while (' ' == *url
) ++url
;
126 while (' ' == *(http
-1)) --http
;
128 HTTP_INFO(info
).request
.url
= estrndup(url
, http
- url
);
130 efree(HTTP_INFO(info
).request
.method
);
134 HTTP_INFO(info
).request
.method
= NULL
;
135 HTTP_INFO(info
).request
.url
= NULL
;
141 /* some darn header containing HTTP/1.x */
152 * vim600: noet sw=4 ts=4 fdm=marker
153 * vim<600: noet sw=4 ts=4