/*
- +----------------------------------------------------------------------+
- | PECL :: http |
- +----------------------------------------------------------------------+
- | This source file is subject to version 3.0 of the PHP license, that |
- | is bundled with this package in the file LICENSE, and is available |
- | through the world-wide-web at http://www.php.net/license/3_0.txt. |
- | If you did not receive a copy of the PHP license and are unable to |
- | obtain it through the world-wide-web, please send a note to |
- | license@php.net so we can mail you a copy immediately. |
- +----------------------------------------------------------------------+
- | Copyright (c) 2004-2005 Michael Wallner <mike@php.net> |
- +----------------------------------------------------------------------+
+ +--------------------------------------------------------------------+
+ | PECL :: http |
+ +--------------------------------------------------------------------+
+ | Redistribution and use in source and binary forms, with or without |
+ | modification, are permitted provided that the conditions mentioned |
+ | in the accompanying LICENSE file are met. |
+ +--------------------------------------------------------------------+
+ | Copyright (c) 2004-2005, Michael Wallner <mike@php.net> |
+ +--------------------------------------------------------------------+
*/
/* $Id$ */
#include "php_http_std_defs.h"
#include "php_http_api.h"
#include "php_http_headers_api.h"
+#include "php_http_request_api.h"
#include "php_http_send_api.h"
#ifdef ZEND_ENGINE_2
ZEND_EXTERN_MODULE_GLOBALS(http);
+PHP_MINIT_FUNCTION(http_support)
+{
+ HTTP_LONG_CONSTANT("HTTP_SUPPORT", HTTP_SUPPORT);
+ HTTP_LONG_CONSTANT("HTTP_SUPPORT_REQUESTS", HTTP_SUPPORT_REQUESTS);
+ HTTP_LONG_CONSTANT("HTTP_SUPPORT_MAGICMIME", HTTP_SUPPORT_MAGICMIME);
+ HTTP_LONG_CONSTANT("HTTP_SUPPORT_ENCODINGS", HTTP_SUPPORT_ENCODINGS);
+ HTTP_LONG_CONSTANT("HTTP_SUPPORT_MHASHETAGS", HTTP_SUPPORT_MHASHETAGS);
+ HTTP_LONG_CONSTANT("HTTP_SUPPORT_SSLREQUESTS", HTTP_SUPPORT_SSLREQUESTS);
+
+ return SUCCESS;
+}
+
+PHP_HTTP_API long _http_support(long feature)
+{
+ long support = HTTP_SUPPORT;
+
+#ifdef HTTP_HAVE_CURL
+ support |= HTTP_SUPPORT_REQUESTS;
+# ifdef HTTP_HAVE_SSL
+ support |= HTTP_SUPPORT_SSLREQUESTS;
+# endif
+#endif
+#ifdef HTTP_HAVE_MHASH
+ support |= HTTP_SUPPORT_MHASHETAGS;
+#endif
+#ifdef HTTP_HAVE_MAGIC
+ support |= HTTP_SUPPORT_MAGICMIME;
+#endif
+#if defined(HTTP_HAVE_ZLIB) || defined(HAVE_ZLIB)
+ support |= HTTP_SUPPORT_ENCODINGS;
+#endif
+
+ if (feature) {
+ return (feature == (support & feature));
+ }
+ return support;
+}
+
/* char *pretty_key(char *, size_t, zend_bool, zend_bool) */
char *_http_pretty_key(char *key, size_t key_len, zend_bool uctitle, zend_bool xhyphen)
{
if (key && key_len) {
size_t i;
int wasalpha;
- if (wasalpha = isalpha((int) key[0])) {
+ if ((wasalpha = isalpha((int) key[0]))) {
key[0] = (char) (uctitle ? toupper((int) key[0]) : tolower((int) key[0]));
}
for (i = 1; i < key_len; i++) {
strftime(datetime, sizeof(datetime), "%Y-%m-%d %H:%M:%S", php_localtime_r(&now, &nowtm));
#define HTTP_LOG_WRITE(file, type, msg) \
- if (file && strlen(file)) { \
+ if (file && *file) { \
php_stream *log = php_stream_open_wrapper(file, "ab", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL); \
\
if (log) { \
}
/* }}} */
+static void http_ob_blackhole(char *output, uint output_len, char **handled_output, uint *handled_output_len, int mode TSRMLS_DC)
+{
+ *handled_output = ecalloc(1,1);
+ *handled_output_len = 0;
+}
+
/* {{{ STATUS http_exit(int, char*, char*) */
STATUS _http_exit_ex(int status, char *header, char *body, zend_bool send_header TSRMLS_DC)
{
- if (status || send_header) {
- if (SUCCESS != http_send_status_header(status, send_header ? header : NULL)) {
- http_error_ex(HE_WARNING, HTTP_E_HEADER, "Failed to exit with status/header: %d - %s", status, header ? header : "");
- STR_FREE(header);
- STR_FREE(body);
- return FAILURE;
- }
+ if ( (send_header && (SUCCESS != http_send_status_header(status, header))) ||
+ (!send_header && status && (SUCCESS != http_send_status(status)))) {
+ http_error_ex(HE_WARNING, HTTP_E_HEADER, "Failed to exit with status/header: %d - %s", status, header ? header : "");
+ STR_FREE(header);
+ STR_FREE(body);
+ return FAILURE;
}
+ php_end_ob_buffers(0 TSRMLS_CC);
if (php_header(TSRMLS_C) && body) {
PHPWRITE(body, strlen(body));
}
STR_FREE(header);
STR_FREE(body);
- zend_bailout();
- /* fake */
+ if (HTTP_G(force_exit)) {
+ zend_bailout();
+ } else {
+ php_ob_set_internal_handler(http_ob_blackhole, 4096, "blackhole", 0 TSRMLS_CC);
+ }
+
return SUCCESS;
}
/* }}} */
}
/* }}} */
-/* {{{ char *http_chunked_decode(char *, size_t, char **, size_t *) */
-PHP_HTTP_API const char *_http_chunked_decode(const char *encoded, size_t encoded_len, char **decoded, size_t *decoded_len TSRMLS_DC)
-{
- const char *e_ptr;
- char *d_ptr;
- long rest;
-
- *decoded_len = 0;
- *decoded = ecalloc(1, encoded_len);
- d_ptr = *decoded;
- e_ptr = encoded;
-
- while ((rest = encoded + encoded_len - e_ptr) > 0) {
- long chunk_len = 0;
- int EOL_len = 0, eol_mismatch = 0;
- char *n_ptr;
-
- chunk_len = strtol(e_ptr, &n_ptr, 16);
-
- /* check if:
- * - we could not read in chunk size
- * - we got a negative chunk size
- * - chunk size is greater then remaining size
- * - chunk size is not followed by (CR)LF|NUL
- */
- if ( (n_ptr == e_ptr) || (chunk_len < 0) || (chunk_len > rest) ||
- (*n_ptr && (eol_mismatch = (n_ptr != http_locate_eol(e_ptr, &EOL_len))))) {
- /* don't fail on apperently not encoded data */
- if (e_ptr == encoded) {
- memcpy(*decoded, encoded, encoded_len);
- *decoded_len = encoded_len;
- return encoded + encoded_len;
- } else {
- efree(*decoded);
- if (eol_mismatch) {
- if (EOL_len == 2) {
- http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Invalid character (expected 0x0D 0x0A; got: 0x%X 0x%X)", *n_ptr, *(n_ptr + 1));
- } else {
- http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Invalid character (expected 0x0A; got: 0x%X)", *n_ptr);
- }
- } else {
- char *error = estrndup(n_ptr, strcspn(n_ptr, "\r\n "));
- http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Invalid chunk size: '%s' at pos %d", error, n_ptr - encoded);
- efree(error);
- }
- return NULL;
- }
- } else {
- e_ptr = n_ptr;
- }
-
- /* reached the end */
- if (!chunk_len) {
- break;
- }
-
- memcpy(d_ptr, e_ptr += EOL_len, chunk_len);
- d_ptr += chunk_len;
- e_ptr += chunk_len + EOL_len;
- *decoded_len += chunk_len;
- }
-
- return e_ptr;
-}
-/* }}} */
/* {{{ char *http_guess_content_type(char *magic_file, long magic_mode, void *data, size_t size, http_send_mode mode) */
PHP_HTTP_API char *_http_guess_content_type(const char *magicfile, long magicmode, void *data_ptr, size_t data_len, http_send_mode data_mode TSRMLS_DC)