-
- RETURN_SUCCESS(http_send_etag(etag, etag_len));
-}
-/* }}} */
-
-/* {{{ proto void http_redirect([string url[, array params[, bool session,[ bool permanent]]]])
- *
- * Redirect to a given url.
- * The supplied url will be expanded with http_absolute_uri(), the params array will
- * be treated with http_build_query() and the session identification will be appended
- * if session is true.
- *
- * Depending on permanent the redirection will be issued with a permanent
- * ("301 Moved Permanently") or a temporary ("302 Found") redirection
- * status code.
- *
- * To be RFC compliant, "Redirecting to <a>URI</a>." will be displayed,
- * if the client doesn't redirect immediatly.
- */
-PHP_FUNCTION(http_redirect)
-{
- int url_len;
- zend_bool session = 0, permanent = 0;
- zval *params = NULL;
- smart_str qstr = {0};
- char *url, *URI, LOC[HTTP_URI_MAXLEN + 9], RED[HTTP_URI_MAXLEN * 2 + 34];
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sa!/bb", &url, &url_len, ¶ms, &session, &permanent) != SUCCESS) {
- RETURN_FALSE;
- }
-
- /* append session info */
- if (session && (PS(session_status) == php_session_active)) {
- if (!params) {
- MAKE_STD_ZVAL(params);
- array_init(params);
- }
- if (add_assoc_string(params, PS(session_name), PS(id), 1) != SUCCESS) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not append session information");
- }
- }
-
- /* treat params array with http_build_query() */
- if (params) {
- if (php_url_encode_hash_ex(Z_ARRVAL_P(params), &qstr, NULL,0,NULL,0,NULL,0,NULL TSRMLS_CC) != SUCCESS) {
- if (qstr.c) {
- efree(qstr.c);
- }
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not encode query parameters");
- RETURN_FALSE;
- }
- smart_str_0(&qstr);
- }
-
- URI = http_absolute_uri(url, NULL);
- if (qstr.c) {
- snprintf(LOC, HTTP_URI_MAXLEN + strlen("Location: "), "Location: %s?%s", URI, qstr.c);
- sprintf(RED, "Redirecting to <a href=\"%s?%s\">%s?%s</a>.\n", URI, qstr.c, URI, qstr.c);
- efree(qstr.c);
- } else {
- snprintf(LOC, HTTP_URI_MAXLEN + strlen("Location: "), "Location: %s", URI);
- sprintf(RED, "Redirecting to <a href=\"%s\">%s</a>.\n", URI, URI);
- }
- efree(URI);
-
- if ((SUCCESS == http_send_header(LOC)) && (SUCCESS == http_send_status((permanent ? 301 : 302)))) {
- php_body_write(RED, strlen(RED) TSRMLS_CC);
- RETURN_TRUE;
- }
- RETURN_FALSE;
-}
-/* }}} */
-
-/* {{{ proto bool http_send_data(string data)
- *
- * Sends raw data with support for (multiple) range requests.
- *
- */
-PHP_FUNCTION(http_send_data)
-{
- zval *zdata;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zdata) != SUCCESS) {
- RETURN_FALSE;
- }
-
- convert_to_string_ex(&zdata);
- http_send_header("Accept-Ranges: bytes");
- RETURN_SUCCESS(http_send_data(zdata));
-}
-/* }}} */
-
-/* {{{ proto bool http_send_file(string file)
- *
- * Sends a file with support for (multiple) range requests.
- *
- */
-PHP_FUNCTION(http_send_file)
-{
- zval *zfile;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zfile) != SUCCESS) {
- RETURN_FALSE;
- }
-
- convert_to_string_ex(&zfile);
- http_send_header("Accept-Ranges: bytes");
- RETURN_SUCCESS(http_send_file(zfile));
-}
-/* }}} */
-
-/* {{{ proto bool http_send_stream(resource stream)
- *
- * Sends an already opened stream with support for (multiple) range requests.
- *
- */
-PHP_FUNCTION(http_send_stream)
-{
- zval *zstream;
- php_stream *file;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zstream) != SUCCESS) {
- RETURN_FALSE;
- }
-
- php_stream_from_zval(file, &zstream);
- http_send_header("Accept-Ranges: bytes");
- RETURN_SUCCESS(http_send_stream(file));
-}
-/* }}} */
-
-/* {{{ proto bool http_content_type([string content_type = 'application/x-octetstream'])
- *
- * Sets the content type.
- *
- */
-PHP_FUNCTION(http_content_type)
-{
- char *ct, *content_type;
- int ct_len = 0;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &ct, &ct_len) != SUCCESS) {
- RETURN_FALSE;
- }
-
- if (!ct_len) {
- RETURN_SUCCESS(http_send_header("Content-Type: application/x-octetstream"));
- }
-
- /* remember for multiple ranges */
- if (HTTP_G(ctype)) {
- efree(HTTP_G(ctype));
- }
- HTTP_G(ctype) = estrndup(ct, ct_len);
-
- content_type = (char *) emalloc(strlen("Content-Type: ") + ct_len + 1);
- sprintf(content_type, "Content-Type: %s", ct);
-
- RETVAL_BOOL(SUCCESS == http_send_header(content_type));
- efree(content_type);
-}
-/* }}} */
-
-/* {{{ proto bool http_content_disposition(string filename[, bool inline = false])
- *
- * Set the Content Disposition. The Content-Disposition header is very useful
- * if the data actually sent came from a file or something similar, that should
- * be "saved" by the client/user (i.e. by browsers "Save as..." popup window).
- *
- */
-PHP_FUNCTION(http_content_disposition)
-{
- char *filename, *header;
- int f_len;
- zend_bool send_inline = 0;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &filename, &f_len, &send_inline) != SUCCESS) {
- RETURN_FALSE;
- }
-
- if (send_inline) {
- header = (char *) emalloc(strlen("Content-Disposition: inline; filename=\"\"") + f_len + 1);
- sprintf(header, "Content-Disposition: inline; filename=\"%s\"", filename);
- } else {
- header = (char *) emalloc(strlen("Content-Disposition: attachment; filename=\"\"") + f_len + 1);
- sprintf(header, "Content-Disposition: attachment; filename=\"%s\"", filename);
- }
-
- RETVAL_BOOL(SUCCESS == http_send_header(header));
- efree(header);
-}
-/* }}} */
-
-/* {{{ proto string http_chunked_decode(string encoded)
- *
- * This function decodes a string that was HTTP-chunked encoded.
- * Returns false on failure.
- */
-PHP_FUNCTION(http_chunked_decode)
-{
- char *encoded = NULL, *decoded = NULL;
- int encoded_len = 0, decoded_len = 0;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &encoded, &encoded_len) != SUCCESS) {
- RETURN_FALSE;
- }
-
- if (SUCCESS == http_chunked_decode(encoded, encoded_len, &decoded, &decoded_len)) {
- RETURN_STRINGL(decoded, decoded_len, 0);
- } else {
- RETURN_FALSE;
- }
-}
-/* }}} */
-
-/* {{{ proto array http_split_response(string http_response)
- *
- * This function splits an HTTP response into an array with headers and the
- * content body. The returned array may look simliar to the following example:
- *
- * <pre>
- * array(
- * 0 => array(
- * 'Status' => '200 Ok',
- * 'Content-Type' => 'text/plain',
- * 'Content-Language' => 'en-US'
- * ),
- * 1 => "Hello World!"
- * );
- * </pre>
- */
-PHP_FUNCTION(http_split_response)
-{
- zval *zresponse, *zbody, *zheaders;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zresponse) != SUCCESS) {
- RETURN_FALSE;
- }
-
- convert_to_string_ex(&zresponse);
-
- MAKE_STD_ZVAL(zbody);
- MAKE_STD_ZVAL(zheaders);
- array_init(zheaders);
-
- http_split_response(zresponse, zheaders, zbody);
-
- array_init(return_value);
- add_index_zval(return_value, 0, zheaders);
- add_index_zval(return_value, 1, zbody);