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-2005, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
19 #define HTTP_WANT_NETDB
24 #include "php_output.h"
26 #include "php_http_api.h"
27 #include "php_http_url_api.h"
29 ZEND_EXTERN_MODULE_GLOBALS(http
);
31 PHP_HTTP_API
char *_http_absolute_url(const char *url TSRMLS_DC
)
33 char *abs
= estrdup(url
);
34 php_url
*purl
= php_url_parse(abs
);
39 http_build_url(purl
, NULL
, NULL
, &abs
, NULL
);
46 /* {{{ void http_build_url(const php_url *, const php_url *, php_url **, char **, size_t *) */
47 PHP_HTTP_API
void _http_build_url(const php_url
*old_url
, const php_url
*new_url
, php_url
**url_ptr
, char **url_str
, size_t *url_len TSRMLS_DC
)
49 #if defined(PHP_WIN32) || defined(HAVE_NETDB_H)
52 php_url
*url
= emalloc(sizeof(php_url
));
55 url->n = (new_url&&new_url->n) ? estrdup(new_url->n) : ((old_url&&old_url->n) ? estrdup(old_url->n) : NULL)
56 url
->port
= (new_url
&&new_url
->port
) ? new_url
->port
: ((old_url
) ? old_url
->port
: 0);
69 url
->scheme
= estrndup("https", lenof("https"));
72 #if !defined(PHP_WIN32) && !defined(HAVE_NETDB_H)
76 url
->scheme
= estrndup("http", lenof("http"));
79 #if defined(PHP_WIN32) || defined(HAVE_NETDB_H)
81 if ((se
= getservbyport(htons(url
->port
), "tcp")) && se
->s_name
) {
82 url
->scheme
= estrdup(se
->s_name
);
84 url
->scheme
= estrndup("http", lenof("http"));
94 if ((((zhost
= http_get_server_var("HTTP_HOST")) ||
95 (zhost
= http_get_server_var("SERVER_NAME")))) && Z_STRLEN_P(zhost
)) {
96 url
->host
= estrndup(Z_STRVAL_P(zhost
), Z_STRLEN_P(zhost
));
98 url
->host
= estrndup("localhost", lenof("localhost"));
102 /* FIXXME: dirname(REQUEST_URI) if path is relative */
104 if (SG(request_info
).request_uri
) {
105 const char *q
= strchr(SG(request_info
).request_uri
, '?');
108 url
->path
= estrndup(SG(request_info
).request_uri
, q
- SG(request_info
).request_uri
);
110 url
->path
= estrdup(SG(request_info
).request_uri
);
113 url
->path
= ecalloc(1, 1);
118 if ( ((url
->port
== 80) && !strcmp(url
->scheme
, "http"))
119 || ((url
->port
==443) && !strcmp(url
->scheme
, "https"))
120 #if defined(PHP_WIN32) || defined(HAVE_NETDB_H)
121 || ((se
= getservbyname(url
->scheme
, "tcp")) && se
->s_port
&&
122 (url
->port
== ntohs(se
->s_port
)))
132 *url_str
= emalloc(HTTP_URL_MAXLEN
+ 1);
135 strlcat(*url_str
, url
->scheme
, HTTP_URL_MAXLEN
);
136 strlcat(*url_str
, "://", HTTP_URL_MAXLEN
);
138 if (url
->user
&& *url
->user
) {
139 strlcat(*url_str
, url
->user
, HTTP_URL_MAXLEN
);
140 if (url
->pass
&& *url
->pass
) {
141 strlcat(*url_str
, ":", HTTP_URL_MAXLEN
);
142 strlcat(*url_str
, url
->pass
, HTTP_URL_MAXLEN
);
144 strlcat(*url_str
, "@", HTTP_URL_MAXLEN
);
147 strlcat(*url_str
, url
->host
, HTTP_URL_MAXLEN
);
150 char port_str
[6] = {0};
152 snprintf(port_str
, 5, "%d", (int) url
->port
);
153 strlcat(*url_str
, ":", HTTP_URL_MAXLEN
);
154 strlcat(*url_str
, port_str
, HTTP_URL_MAXLEN
);
157 if (*url
->path
!= '/') {
158 strlcat(*url_str
, "/", HTTP_URL_MAXLEN
);
160 strlcat(*url_str
, url
->path
, HTTP_URL_MAXLEN
);
162 if (url
->query
&& *url
->query
) {
163 strlcat(*url_str
, "?", HTTP_URL_MAXLEN
);
164 strlcat(*url_str
, url
->query
, HTTP_URL_MAXLEN
);
167 if (url
->fragment
&& *url
->fragment
) {
168 strlcat(*url_str
, "#", HTTP_URL_MAXLEN
);
169 strlcat(*url_str
, url
->fragment
, HTTP_URL_MAXLEN
);
172 if (HTTP_URL_MAXLEN
== (len
= strlen(*url_str
))) {
173 http_error(HE_NOTICE
, HTTP_E_URL
, "Length of URL exceeds HTTP_URL_MAXLEN");
188 /* {{{ STATUS http_urlencode_hash_ex(HashTable *, zend_bool, char *, size_t, char **, size_t *) */
189 PHP_HTTP_API STATUS
_http_urlencode_hash_ex(HashTable
*hash
, zend_bool override_argsep
,
190 char *pre_encoded_data
, size_t pre_encoded_len
,
191 char **encoded_data
, size_t *encoded_len TSRMLS_DC
)
195 phpstr
*qstr
= phpstr_new();
197 if (override_argsep
|| !(arg_sep_len
= strlen(arg_sep
= INI_STR("arg_separator.output")))) {
198 arg_sep
= HTTP_URL_ARGSEP
;
199 arg_sep_len
= lenof(HTTP_URL_ARGSEP
);
202 if (pre_encoded_len
&& pre_encoded_data
) {
203 phpstr_append(qstr
, pre_encoded_data
, pre_encoded_len
);
206 if (SUCCESS
!= http_urlencode_hash_recursive(hash
, qstr
, arg_sep
, arg_sep_len
, NULL
, 0)) {
211 phpstr_data(qstr
, encoded_data
, encoded_len
);
218 /* {{{ http_urlencode_hash_recursive */
219 PHP_HTTP_API STATUS
_http_urlencode_hash_recursive(HashTable
*ht
, phpstr
*str
, const char *arg_sep
, size_t arg_sep_len
, const char *prefix
, size_t prefix_len TSRMLS_DC
)
228 http_error(HE_WARNING
, HTTP_E_INVALID_PARAM
, "Invalid parameters");
231 if (ht
->nApplyCount
> 0) {
235 FOREACH_HASH_KEYLENVAL(pos
, ht
, key
, len
, idx
, data
) {
240 if (!data
|| !*data
) {
245 if (len
&& key
[len
- 1] == '\0') {
248 encoded_key
= php_url_encode(key
, len
, &encoded_len
);
251 encoded_len
= spprintf(&encoded_key
, 0, "%ld", idx
);
255 phpstr_init(&new_prefix
);
256 if (prefix
&& prefix_len
) {
257 phpstr_append(&new_prefix
, prefix
, prefix_len
);
258 phpstr_appends(&new_prefix
, "[");
261 phpstr_append(&new_prefix
, encoded_key
, encoded_len
);
264 if (prefix
&& prefix_len
) {
265 phpstr_appends(&new_prefix
, "]");
267 phpstr_fix(&new_prefix
);
270 if (Z_TYPE_PP(data
) == IS_ARRAY
) {
273 status
= http_urlencode_hash_recursive(Z_ARRVAL_PP(data
), str
, arg_sep
, arg_sep_len
, PHPSTR_VAL(&new_prefix
), PHPSTR_LEN(&new_prefix
));
275 if (SUCCESS
!= status
) {
276 phpstr_dtor(&new_prefix
);
282 zval
*cpy
, *val
= convert_to_type_ex(IS_STRING
, *data
, &cpy
);
284 if (PHPSTR_LEN(str
)) {
285 phpstr_append(str
, arg_sep
, arg_sep_len
);
287 phpstr_append(str
, PHPSTR_VAL(&new_prefix
), PHPSTR_LEN(&new_prefix
));
288 phpstr_appends(str
, "=");
290 encoded_val
= php_url_encode(Z_STRVAL_P(val
), Z_STRLEN_P(val
), &encoded_len
);
291 phpstr_append(str
, encoded_val
, encoded_len
);
299 phpstr_dtor(&new_prefix
);
310 * vim600: noet sw=4 ts=4 fdm=marker
311 * vim<600: noet sw=4 ts=4