3 +----------------------------------------------------------------------+
7 +----------------------------------------------------------------------+
9 | This source file is subject to version 3.0 of the PHP license, that |
11 | is bundled with this package in the file LICENSE, and is available |
13 | through the world-wide-web at http://www.php.net/license/3_0.txt. |
15 | If you did not receive a copy of the PHP license and are unable to |
17 | obtain it through the world-wide-web, please send a note to |
19 | license@php.net so we can mail you a copy immediately. |
21 +----------------------------------------------------------------------+
23 | Copyright (c) 2004-2005 Michael Wallner <mike@php.net> |
25 +----------------------------------------------------------------------+
47 #include "ext/standard/info.h"
49 #include "ext/session/php_session.h"
51 #include "ext/standard/php_string.h"
59 #include "phpstr/phpstr.h"
65 #include "php_http_std_defs.h"
67 #include "php_http_api.h"
69 #include "php_http_auth_api.h"
71 #include "php_http_request_api.h"
73 #include "php_http_cache_api.h"
75 #include "php_http_request_api.h"
77 #include "php_http_date_api.h"
79 #include "php_http_headers_api.h"
81 #include "php_http_message_api.h"
83 #include "php_http_send_api.h"
85 #include "php_http_url_api.h"
89 ZEND_EXTERN_MODULE_GLOBALS(http
)
93 /* {{{ proto string http_date([int timestamp])
97 * This function returns a valid HTTP date regarding RFC 822/1123
99 * looking like: "Wed, 22 Dec 2004 11:34:47 GMT"
105 PHP_FUNCTION(http_date
)
113 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &t
) != SUCCESS
) {
123 t
= (long) time(NULL
);
129 RETURN_STRING(http_date(t
), 0);
137 /* {{{ proto string http_absolute_uri(string url[, string proto[, string host[, int port]]])
141 * This function returns an absolute URI constructed from url.
143 * If the url is already abolute but a different proto was supplied,
145 * only the proto part of the URI will be updated. If url has no
147 * path specified, the path of the current REQUEST_URI will be taken.
149 * The host will be taken either from the Host HTTP header of the client
151 * the SERVER_NAME or just localhost if prior are not available.
159 * url = "page.php" => http://www.example.com/current/path/page.php
161 * url = "/page.php" => http://www.example.com/page.php
163 * url = "/page.php", proto = "https" => https://www.example.com/page.php
171 PHP_FUNCTION(http_absolute_uri
)
175 char *url
= NULL
, *proto
= NULL
, *host
= NULL
;
177 int url_len
= 0, proto_len
= 0, host_len
= 0;
183 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s|ssl", &url
, &url_len
, &proto
, &proto_len
, &host
, &host_len
, &port
) != SUCCESS
) {
191 RETURN_STRING(http_absolute_uri_ex(url
, url_len
, proto
, proto_len
, host
, host_len
, port
), 0);
199 /* {{{ proto string http_negotiate_language(array supported[, string default = 'en-US'])
203 * This function negotiates the clients preferred language based on its
205 * Accept-Language HTTP header. It returns the negotiated language or
207 * the default language if none match.
211 * The qualifier is recognized and languages without qualifier are rated highest.
215 * The supported parameter is expected to be an array having
217 * the supported languages as array values.
245 * include './langs/'. http_negotiate_language($langs) .'.php';
255 PHP_FUNCTION(http_negotiate_language
)
267 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "a|s", &supported
, &def
, &def_len
) != SUCCESS
) {
283 RETURN_STRING(http_negotiate_language(supported
, def
), 0);
291 /* {{{ proto string http_negotiate_charset(array supported[, string default = 'iso-8859-1'])
295 * This function negotiates the clients preferred charset based on its
297 * Accept-Charset HTTP header. It returns the negotiated charset or
299 * the default charset if none match.
303 * The qualifier is recognized and charset without qualifier are rated highest.
307 * The supported parameter is expected to be an array having
309 * the supported charsets as array values.
321 * 'iso-8859-1', // default
331 * $pref = http_negotiate_charset($charsets);
333 * if (!strcmp($pref, 'iso-8859-1')) {
335 * iconv_set_encoding('internal_encoding', 'iso-8859-1');
337 * iconv_set_encoding('output_encoding', $pref);
339 * ob_start('ob_iconv_handler');
349 PHP_FUNCTION(http_negotiate_charset
)
361 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "a|s", &supported
, &def
, &def_len
) != SUCCESS
) {
377 RETURN_STRING(http_negotiate_charset(supported
, def
), 0);
385 /* {{{ proto bool http_send_status(int status)
389 * Send HTTP status code.
395 PHP_FUNCTION(http_send_status
)
403 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l", &status
) != SUCCESS
) {
409 if (status
< 100 || status
> 510) {
411 http_error_ex(E_WARNING
, HTTP_E_HEADER
, "Invalid HTTP status code (100-510): %d", status
);
419 RETURN_SUCCESS(http_send_status(status
));
427 /* {{{ proto bool http_send_last_modified([int timestamp])
431 * This converts the given timestamp to a valid HTTP date and
433 * sends it as "Last-Modified" HTTP header. If timestamp is
435 * omitted, current time is sent.
441 PHP_FUNCTION(http_send_last_modified
)
449 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &t
) != SUCCESS
) {
459 t
= (long) time(NULL
);
465 RETURN_SUCCESS(http_send_last_modified(t
));
473 /* {{{ proto bool http_send_content_type([string content_type = 'application/x-octetstream'])
477 * Sets the content type.
483 PHP_FUNCTION(http_send_content_type
)
493 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|s", &ct
, &ct_len
) != SUCCESS
) {
503 RETURN_SUCCESS(http_send_content_type("application/x-octetstream", lenof("application/x-octetstream")));
507 RETURN_SUCCESS(http_send_content_type(ct
, ct_len
));
515 /* {{{ proto bool http_send_content_disposition(string filename[, bool inline = false])
519 * Set the Content Disposition. The Content-Disposition header is very useful
521 * if the data actually sent came from a file or something similar, that should
523 * be "saved" by the client/user (i.e. by browsers "Save as..." popup window).
529 PHP_FUNCTION(http_send_content_disposition
)
537 zend_bool send_inline
= 0;
541 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s|b", &filename
, &f_len
, &send_inline
) != SUCCESS
) {
547 RETURN_SUCCESS(http_send_content_disposition(filename
, f_len
, send_inline
));
555 /* {{{ proto bool http_match_modified([int timestamp[, for_range = false]])
559 * Matches the given timestamp against the clients "If-Modified-Since" resp.
561 * "If-Unmodified-Since" HTTP headers.
567 PHP_FUNCTION(http_match_modified
)
573 zend_bool for_range
= 0;
577 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|lb", &t
, &for_range
) != SUCCESS
) {
585 // current time if not supplied (senseless though)
589 t
= (long) time(NULL
);
597 RETURN_BOOL(http_match_last_modified("HTTP_IF_UNMODIFIED_SINCE", t
));
601 RETURN_BOOL(http_match_last_modified("HTTP_IF_MODIFIED_SINCE", t
));
609 /* {{{ proto bool http_match_etag(string etag[, for_range = false])
613 * This matches the given ETag against the clients
615 * "If-Match" resp. "If-None-Match" HTTP headers.
621 PHP_FUNCTION(http_match_etag
)
629 zend_bool for_range
= 0;
633 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s|b", &etag
, &etag_len
, &for_range
) != SUCCESS
) {
643 RETURN_BOOL(http_match_etag("HTTP_IF_MATCH", etag
));
647 RETURN_BOOL(http_match_etag("HTTP_IF_NONE_MATCH", etag
));
655 /* {{{ proto bool http_cache_last_modified([int timestamp_or_expires]])
659 * If timestamp_or_expires is greater than 0, it is handled as timestamp
661 * and will be sent as date of last modification. If it is 0 or omitted,
663 * the current time will be sent as Last-Modified date. If it's negative,
665 * it is handled as expiration time in seconds, which means that if the
667 * requested last modification date is not between the calculated timespan,
669 * the Last-Modified header is updated and the actual body will be sent.
675 PHP_FUNCTION(http_cache_last_modified
)
679 long last_modified
= 0, send_modified
= 0, t
;
685 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|l", &last_modified
) != SUCCESS
) {
693 t
= (long) time(NULL
);
699 if (!last_modified
) {
701 /* does the client have? (att: caching "forever") */
703 if (zlm
= http_get_server_var("HTTP_IF_MODIFIED_SINCE")) {
705 last_modified
= send_modified
= http_parse_date(Z_STRVAL_P(zlm
));
707 /* send current time */
715 /* negative value is supposed to be expiration time */
717 } else if (last_modified
< 0) {
723 /* send supplied time explicitly */
727 send_modified
= last_modified
;
733 RETURN_SUCCESS(http_cache_last_modified(last_modified
, send_modified
, HTTP_DEFAULT_CACHECONTROL
, lenof(HTTP_DEFAULT_CACHECONTROL
)));
741 /* {{{ proto bool http_cache_etag([string etag])
745 * This function attempts to cache the HTTP body based on an ETag,
747 * either supplied or generated through calculation of the MD5
749 * checksum of the output (uses output buffering).
753 * If clients "If-None-Match" header matches the supplied/calculated
755 * ETag, the body is considered cached on the clients side and
757 * a "304 Not Modified" status code is issued.
763 PHP_FUNCTION(http_cache_etag
)
773 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|s", &etag
, &etag_len
) != SUCCESS
) {
781 RETURN_SUCCESS(http_cache_etag(etag
, etag_len
, HTTP_DEFAULT_CACHECONTROL
, lenof(HTTP_DEFAULT_CACHECONTROL
)));
789 /* {{{ proto string ob_etaghandler(string data, int mode)
793 * For use with ob_start().
797 PHP_FUNCTION(ob_etaghandler
)
809 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sl", &data
, &data_len
, &mode
)) {
817 Z_TYPE_P(return_value
) = IS_STRING
;
819 http_ob_etaghandler(data
, data_len
, &Z_STRVAL_P(return_value
), &Z_STRLEN_P(return_value
), mode
);
827 /* {{{ proto void http_redirect([string url[, array params[, bool session,[ bool permanent]]]])
831 * Redirect to a given url.
833 * The supplied url will be expanded with http_absolute_uri(), the params array will
835 * be treated with http_build_query() and the session identification will be appended
837 * if session is true.
841 * Depending on permanent the redirection will be issued with a permanent
843 * ("301 Moved Permanently") or a temporary ("302 Found") redirection
849 * To be RFC compliant, "Redirecting to <a>URI</a>." will be displayed,
851 * if the client doesn't redirect immediatly.
855 PHP_FUNCTION(http_redirect
)
861 size_t query_len
= 0;
863 zend_bool session
= 0, permanent
= 0;
867 char *query
, *url
, *URI
,
869 LOC
[HTTP_URI_MAXLEN
+ sizeof("Location: ")],
871 RED
[HTTP_URI_MAXLEN
* 2 + sizeof("Redirecting to <a href=\"%s?%s\">%s?%s</a>.\n")];
875 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|sa!/bb", &url
, &url_len
, ¶ms
, &session
, &permanent
) != SUCCESS
) {
883 /* append session info */
885 if (session
&& (PS(session_status
) == php_session_active
)) {
889 MAKE_STD_ZVAL(params
);
895 if (add_assoc_string(params
, PS(session_name
), PS(id
), 1) != SUCCESS
) {
897 http_error(E_WARNING
, HTTP_E_ENCODE
, "Could not append session information");
905 /* treat params array with http_build_query() */
909 if (SUCCESS
!= http_urlencode_hash_ex(Z_ARRVAL_P(params
), 0, NULL
, 0, &query
, &query_len
)) {
919 URI
= http_absolute_uri(url
);
925 snprintf(LOC
, HTTP_URI_MAXLEN
+ sizeof("Location: "), "Location: %s?%s", URI
, query
);
927 sprintf(RED
, "Redirecting to <a href=\"%s?%s\">%s?%s</a>.\n", URI
, query
, URI
, query
);
933 snprintf(LOC
, HTTP_URI_MAXLEN
+ sizeof("Location: "), "Location: %s", URI
);
935 sprintf(RED
, "Redirecting to <a href=\"%s\">%s</a>.\n", URI
, URI
);
943 if ((SUCCESS
== http_send_header(LOC
)) && (SUCCESS
== http_send_status((permanent
? 301 : 302)))) {
945 php_body_write(RED
, strlen(RED
) TSRMLS_CC
);
959 /* {{{ proto bool http_send_data(string data)
963 * Sends raw data with support for (multiple) range requests.
969 PHP_FUNCTION(http_send_data
)
977 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "z", &zdata
) != SUCCESS
) {
985 convert_to_string_ex(&zdata
);
987 RETURN_SUCCESS(http_send_data(Z_STRVAL_P(zdata
), Z_STRLEN_P(zdata
)));
995 /* {{{ proto bool http_send_file(string file)
999 * Sends a file with support for (multiple) range requests.
1005 PHP_FUNCTION(http_send_file
)
1015 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &file
, &flen
) != SUCCESS
) {
1029 RETURN_SUCCESS(http_send_file(file
));
1037 /* {{{ proto bool http_send_stream(resource stream)
1041 * Sends an already opened stream with support for (multiple) range requests.
1047 PHP_FUNCTION(http_send_stream
)
1057 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "r", &zstream
) != SUCCESS
) {
1065 php_stream_from_zval(file
, &zstream
);
1067 RETURN_SUCCESS(http_send_stream(file
));
1075 /* {{{ proto string http_chunked_decode(string encoded)
1079 * This function decodes a string that was HTTP-chunked encoded.
1081 * Returns false on failure.
1085 PHP_FUNCTION(http_chunked_decode
)
1089 char *encoded
= NULL
, *decoded
= NULL
;
1091 int encoded_len
= 0, decoded_len
= 0;
1095 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &encoded
, &encoded_len
) != SUCCESS
) {
1103 if (NULL
!= http_chunked_decode(encoded
, encoded_len
, &decoded
, &decoded_len
)) {
1105 RETURN_STRINGL(decoded
, decoded_len
, 0);
1119 /* {{{ proto array http_split_response(string http_response)
1123 * This function splits an HTTP response into an array with headers and the
1125 * content body. The returned array may look simliar to the following example:
1137 * 'Response Status' => '200 Ok',
1139 * 'Content-Type' => 'text/plain',
1141 * 'Content-Language' => 'en-US'
1145 * 1 => "Hello World!"
1155 PHP_FUNCTION(http_split_response
)
1159 zval
*zresponse
, *zbody
, *zheaders
;
1163 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "z", &zresponse
) != SUCCESS
) {
1171 convert_to_string(zresponse
);
1175 MAKE_STD_ZVAL(zbody
);
1177 MAKE_STD_ZVAL(zheaders
);
1179 array_init(zheaders
);
1183 if (SUCCESS
!= http_split_response(zresponse
, zheaders
, zbody
)) {
1185 http_error(E_WARNING
, HTTP_E_PARSE
, "Could not parse HTTP response");
1193 array_init(return_value
);
1195 add_index_zval(return_value
, 0, zheaders
);
1197 add_index_zval(return_value
, 1, zbody
);
1205 /* {{{ proto array http_parse_headers(string header)
1211 PHP_FUNCTION(http_parse_headers
)
1221 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s", &header
, &header_len
)) {
1229 array_init(return_value
);
1231 if (SUCCESS
!= http_parse_headers(header
, return_value
)) {
1233 http_error(E_WARNING
, HTTP_E_PARSE
, "Could not parse HTTP headers");
1235 zval_dtor(return_value
);
1247 /* {{{ proto array http_get_request_headers(void)
1253 PHP_FUNCTION(http_get_request_headers
)
1261 array_init(return_value
);
1263 http_get_request_headers(return_value
);
1273 #ifdef HTTP_HAVE_CURL
1277 /* {{{ proto string http_get(string url[, array options[, array &info]])
1281 * Performs an HTTP GET request on the supplied url.
1285 * The second parameter is expected to be an associative
1287 * array where the following keys will be recognized:
1291 * - redirect: int, whether and how many redirects to follow
1293 * - unrestrictedauth: bool, whether to continue sending credentials on
1295 * redirects to a different host
1297 * - proxyhost: string, proxy host in "host[:port]" format
1299 * - proxyport: int, use another proxy port as specified in proxyhost
1301 * - proxyauth: string, proxy credentials in "user:pass" format
1303 * - proxyauthtype: int, HTTP_AUTH_BASIC and/or HTTP_AUTH_NTLM
1305 * - httpauth: string, http credentials in "user:pass" format
1307 * - httpauthtype: int, HTTP_AUTH_BASIC, DIGEST and/or NTLM
1309 * - compress: bool, whether to allow gzip/deflate content encoding
1311 * (defaults to true)
1313 * - port: int, use another port as specified in the url
1315 * - referer: string, the referer to sends
1317 * - useragent: string, the user agent to send
1319 * (defaults to PECL::HTTP/version (PHP/version)))
1321 * - headers: array, list of custom headers as associative array
1323 * like array("header" => "value")
1325 * - cookies: array, list of cookies as associative array
1327 * like array("cookie" => "value")
1329 * - cookiestore: string, path to a file where cookies are/will be stored
1331 * - resume: int, byte offset to start the download from;
1333 * if the server supports ranges
1335 * - maxfilesize: int, maximum file size that should be downloaded;
1337 * has no effect, if the size of the requested entity is not known
1339 * - lastmodified: int, timestamp for If-(Un)Modified-Since header
1341 * - timeout: int, seconds the request may take
1343 * - connecttimeout: int, seconds the connect may take
1345 * - onprogress: mixed, progress callback
1347 * - ondebug: mixed, debug callback
1353 * The optional third parameter will be filled with some additional information
1355 * in form af an associative array, if supplied, like the following example:
1363 * 'effective_url' => 'http://localhost',
1365 * 'response_code' => 403,
1367 * 'total_time' => 0.017,
1369 * 'namelookup_time' => 0.013,
1371 * 'connect_time' => 0.014,
1373 * 'pretransfer_time' => 0.014,
1375 * 'size_upload' => 0,
1377 * 'size_download' => 202,
1379 * 'speed_download' => 11882,
1381 * 'speed_upload' => 0,
1383 * 'header_size' => 145,
1385 * 'request_size' => 62,
1387 * 'ssl_verifyresult' => 0,
1391 * 'content_length_download' => 202,
1393 * 'content_length_upload' => 0,
1395 * 'starttransfer_time' => 0.017,
1397 * 'content_type' => 'text/html; charset=iso-8859-1',
1399 * 'redirect_time' => 0,
1401 * 'redirect_count' => 0,
1405 * 'http_connectcode' => 0,
1407 * 'httpauth_avail' => 0,
1409 * 'proxyauth_avail' => 0,
1419 PHP_FUNCTION(http_get
)
1423 zval
*options
= NULL
, *info
= NULL
;
1433 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s|a/!z", &URL
, &URL_len
, &options
, &info
) != SUCCESS
) {
1451 phpstr_init_ex(&response
, HTTP_CURLBUF_SIZE
, 0);
1453 if (SUCCESS
== http_get(URL
, options
? Z_ARRVAL_P(options
) : NULL
, info
? Z_ARRVAL_P(info
) : NULL
, &response
)) {
1455 RETURN_PHPSTR_VAL(response
);
1469 /* {{{ proto string http_head(string url[, array options[, array &info]])
1473 * Performs an HTTP HEAD request on the suppied url.
1475 * Returns the HTTP response as string.
1477 * See http_get() for a full list of available options.
1481 PHP_FUNCTION(http_head
)
1485 zval
*options
= NULL
, *info
= NULL
;
1495 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s|a/!z", &URL
, &URL_len
, &options
, &info
) != SUCCESS
) {
1513 phpstr_init_ex(&response
, HTTP_CURLBUF_SIZE
, 0);
1515 if (SUCCESS
== http_head(URL
, options
? Z_ARRVAL_P(options
) : NULL
, info
? Z_ARRVAL_P(info
) : NULL
, &response
)) {
1517 RETURN_PHPSTR_VAL(response
);
1531 /* {{{ proto string http_post_data(string url, string data[, array options[, &info]])
1535 * Performs an HTTP POST request, posting data.
1537 * Returns the HTTP response as string.
1539 * See http_get() for a full list of available options.
1543 PHP_FUNCTION(http_post_data
)
1547 zval
*options
= NULL
, *info
= NULL
;
1549 char *URL
, *postdata
;
1551 int postdata_len
, URL_len
;
1555 http_request_body body
;
1559 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss|a/!z", &URL
, &URL_len
, &postdata
, &postdata_len
, &options
, &info
) != SUCCESS
) {
1577 body
.type
= HTTP_REQUEST_BODY_CSTRING
;
1579 body
.data
= postdata
;
1581 body
.size
= postdata_len
;
1585 phpstr_init_ex(&response
, HTTP_CURLBUF_SIZE
, 0);
1587 if (SUCCESS
== http_post(URL
, &body
, options
? Z_ARRVAL_P(options
) : NULL
, info
? Z_ARRVAL_P(info
) : NULL
, &response
)) {
1589 RETVAL_PHPSTR_VAL(response
);
1597 http_request_body_dtor(&body
);
1605 /* {{{ proto string http_post_fields(string url, array data[, array files[, array options[, array &info]]])
1609 * Performs an HTTP POST request, posting www-form-urlencoded array data.
1611 * Returns the HTTP response as string.
1613 * See http_get() for a full list of available options.
1617 PHP_FUNCTION(http_post_fields
)
1621 zval
*options
= NULL
, *info
= NULL
, *fields
, *files
= NULL
;
1629 http_request_body body
;
1633 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "sa|aa/!z", &URL
, &URL_len
, &fields
, &files
, &options
, &info
) != SUCCESS
) {
1641 if (SUCCESS
!= http_request_body_fill(&body
, Z_ARRVAL_P(fields
), files
? Z_ARRVAL_P(files
) : NULL
)) {
1659 phpstr_init_ex(&response
, HTTP_CURLBUF_SIZE
, 0);
1661 if (SUCCESS
== http_post(URL
, &body
, options
? Z_ARRVAL_P(options
) : NULL
, info
? Z_ARRVAL_P(info
) : NULL
, &response
)) {
1663 RETVAL_PHPSTR_VAL(response
);
1671 http_request_body_dtor(&body
);
1687 /* {{{ proto bool http_auth_basic(string user, string pass[, string realm = "Restricted"])
1697 * if (!http_auth_basic('mike', 's3c|r3t')) {
1699 * die('<h1>Authorization failed!</h1>');
1709 PHP_FUNCTION(http_auth_basic
)
1713 char *realm
= NULL
, *user
, *pass
, *suser
, *spass
;
1715 int r_len
, u_len
, p_len
;
1719 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "ss|s", &user
, &u_len
, &pass
, &p_len
, &realm
, &r_len
) != SUCCESS
) {
1729 realm
= "Restricted";
1735 if (SUCCESS
!= http_auth_credentials(&suser
, &spass
)) {
1737 http_auth_header("Basic", realm
);
1745 if (strcasecmp(suser
, user
)) {
1747 http_auth_header("Basic", realm
);
1755 if (strcmp(spass
, pass
)) {
1757 http_auth_header("Basic", realm
);
1773 /* {{{ proto bool http_auth_basic_cb(mixed callback[, string realm = "Restricted"])
1783 * function auth_cb($user, $pass)
1789 * $query = 'SELECT pass FROM users WHERE user='. $db->quoteSmart($user);
1791 * if (strlen($realpass = $db->getOne($query)) {
1793 * return $pass === $realpass;
1801 * if (!http_auth_basic_cb('auth_cb')) {
1803 * die('<h1>Authorization failed</h1>');
1813 PHP_FUNCTION(http_auth_basic_cb
)
1819 char *realm
= NULL
, *user
, *pass
;
1825 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "z|s", &cb
, &realm
, &r_len
) != SUCCESS
) {
1835 realm
= "Restricted";
1841 if (SUCCESS
!= http_auth_credentials(&user
, &pass
)) {
1843 http_auth_header("Basic", realm
);
1851 zval
*zparams
[2] = {NULL
, NULL
}, retval
;
1857 MAKE_STD_ZVAL(zparams
[0]);
1859 MAKE_STD_ZVAL(zparams
[1]);
1861 ZVAL_STRING(zparams
[0], user
, 0);
1863 ZVAL_STRING(zparams
[1], pass
, 0);
1867 if (SUCCESS
== call_user_function(EG(function_table
), NULL
, cb
,
1869 &retval
, 2, zparams TSRMLS_CC
)) {
1871 result
= Z_LVAL(retval
);
1889 http_auth_header("Basic", realm
);
1895 RETURN_BOOL(result
);
1905 /* {{{ Sara Golemons http_build_query() */
1907 #ifndef ZEND_ENGINE_2
1911 /* {{{ proto string http_build_query(mixed formdata [, string prefix[, string arg_separator]])
1913 Generates a form-encoded query string from an associative array or object. */
1915 PHP_FUNCTION(http_build_query
)
1921 char *prefix
= NULL
, *arg_sep
= INI_STR("arg_separator.output");
1923 int prefix_len
= 0, arg_sep_len
= strlen(arg_sep
);
1929 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "z|ss", &formdata
, &prefix
, &prefix_len
, &arg_sep
, &arg_sep_len
) != SUCCESS
) {
1937 if (Z_TYPE_P(formdata
) != IS_ARRAY
&& Z_TYPE_P(formdata
) != IS_OBJECT
) {
1939 http_error(E_WARNING
, HTTP_E_PARAM
, "Parameter 1 expected to be Array or Object. Incorrect value given.");
1949 arg_sep
= HTTP_URL_ARGSEP
;
1955 formstr
= phpstr_new();
1957 if (SUCCESS
!= http_urlencode_hash_implementation_ex(HASH_OF(formdata
), formstr
, arg_sep
, prefix
, prefix_len
, NULL
, 0, NULL
, 0, (Z_TYPE_P(formdata
) == IS_OBJECT
? formdata
: NULL
))) {
1959 phpstr_free(formstr
);
1967 if (!formstr
->used
) {
1969 phpstr_free(formstr
);
1977 RETURN_PHPSTR_PTR(formstr
);
1983 #endif /* !ZEND_ENGINE_2 */
1989 PHP_FUNCTION(http_test
)
2009 * vim600: noet sw=4 ts=4 fdm=marker
2011 * vim<600: noet sw=4 ts=4