- fix compiler warnings (unused vars & missing includes)
[m6w6/ext-http] / http_api.c
index 9960f2bb77064aa765cfd34eb1095bb9ee345955..8ba8259b56dcee449c9cf5c4dbce5bb5e3d20dd8 100644 (file)
 #include <ctype.h>
 
 #include "php.h"
-#include "php_output.h"
-#include "ext/standard/md5.h"
 
 #include "php_http.h"
 #include "php_http_std_defs.h"
 #include "php_http_api.h"
-#include "php_http_send_api.h"
-#include "php_http_cache_api.h"
 #include "php_http_headers_api.h"
+#include "php_http_send_api.h"
 
 #ifdef ZEND_ENGINE_2
+#      include "zend_exceptions.h"
 #      include "php_http_exception_object.h"
 #endif
 
@@ -73,7 +71,7 @@ void _http_error_ex(long type, long code, const char *format, ...)
 #ifdef ZEND_ENGINE_2
                char *message;
                vspprintf(&message, 0, format, args);
-               zend_throw_exception(http_exception_get_default(), message, code TSRMLS_CC);
+               zend_throw_exception(http_exception_get_for_code(code), message, code TSRMLS_CC);
 #else
                type = E_WARNING;
 #endif
@@ -85,21 +83,39 @@ void _http_error_ex(long type, long code, const char *format, ...)
 }
 /* }}} */
 
-/* {{{ static STATUS http_ob_stack_get(php_ob_buffer *, php_ob_buffer **) */
-static STATUS http_ob_stack_get(php_ob_buffer *o, php_ob_buffer **s)
+/* {{{ STATUS http_exit(int, char*) */
+STATUS _http_exit_ex(int status, char *header, zend_bool free_header TSRMLS_DC)
 {
-       static int i = 0;
-       php_ob_buffer *b = emalloc(sizeof(php_ob_buffer));
-       b->handler_name = estrdup(o->handler_name);
-       b->buffer = estrndup(o->buffer, o->text_length);
-       b->text_length = o->text_length;
-       b->chunk_size = o->chunk_size;
-       b->erase = o->erase;
-       s[i++] = b;
+       if (SUCCESS != http_send_status_header(status, header)) {
+               http_error_ex(E_WARNING, HTTP_E_HEADER, "Failed to exit with status/header: %d - %s", status, header ? header : "");
+               if (free_header && header) {
+                       efree(header);
+               }
+               return FAILURE;
+       }
+       if (free_header && header) {
+               efree(header);
+       }
+       zend_bailout();
+       /* fake */
        return SUCCESS;
 }
 /* }}} */
 
+/* {{{ STATUS http_check_method(char *) */
+STATUS _http_check_method_ex(const char *method, const char *methods)
+{
+       const char *found;
+
+       if (    (found = strstr(methods, method)) &&
+                       (found == method || !isalpha(found[-1])) &&
+                       (!isalpha(found[strlen(method) + 1]))) {
+               return SUCCESS;
+       }
+       return FAILURE;
+}
+/* }}} */
+
 /* {{{ zval *http_get_server_var_ex(char *, size_t) */
 PHP_HTTP_API zval *_http_get_server_var_ex(const char *key, size_t key_size, zend_bool check TSRMLS_DC)
 {
@@ -115,86 +131,9 @@ PHP_HTTP_API zval *_http_get_server_var_ex(const char *key, size_t key_size, zen
 }
 /* }}} */
 
-/* {{{ void http_ob_etaghandler(char *, uint, char **, uint *, int) */
-PHP_HTTP_API void _http_ob_etaghandler(char *output, uint output_len,
-       char **handled_output, uint *handled_output_len, int mode TSRMLS_DC)
-{
-       char etag[33] = { 0 };
-       unsigned char digest[16];
-
-       if (mode & PHP_OUTPUT_HANDLER_START) {
-               PHP_MD5Init(&HTTP_G(etag_md5));
-       }
-
-       PHP_MD5Update(&HTTP_G(etag_md5), output, output_len);
-
-       if (mode & PHP_OUTPUT_HANDLER_END) {
-               PHP_MD5Final(digest, &HTTP_G(etag_md5));
-
-               /* just do that if desired */
-               if (HTTP_G(etag_started)) {
-                       make_digest(etag, digest);
 
-                       if (http_etag_match("HTTP_IF_NONE_MATCH", etag)) {
-                               http_send_status(304);
-                               zend_bailout();
-                       } else {
-                               http_send_etag(etag, 32);
-                       }
-               }
-       }
-
-       *handled_output_len = output_len;
-       *handled_output = estrndup(output, output_len);
-}
-/* }}} */
-
-/* {{{ STATUS http_start_ob_handler(php_output_handler_func_t, char *, uint, zend_bool) */
-PHP_HTTP_API STATUS _http_start_ob_handler(php_output_handler_func_t handler_func,
-       char *handler_name, uint chunk_size, zend_bool erase TSRMLS_DC)
-{
-       php_ob_buffer **stack;
-       int count, i;
-
-       if (count = OG(ob_nesting_level)) {
-               stack = ecalloc(count, sizeof(php_ob_buffer *));
-
-               if (count > 1) {
-                       zend_stack_apply_with_argument(&OG(ob_buffers), ZEND_STACK_APPLY_BOTTOMUP,
-                               (int (*)(void *elem, void *)) http_ob_stack_get, stack);
-               }
-
-               if (count > 0) {
-                       http_ob_stack_get(&OG(active_ob_buffer), stack);
-               }
-
-               while (OG(ob_nesting_level)) {
-                       php_end_ob_buffer(0, 0 TSRMLS_CC);
-               }
-       }
-
-       php_ob_set_internal_handler(handler_func, chunk_size, handler_name, erase TSRMLS_CC);
-
-       for (i = 0; i < count; i++) {
-               php_ob_buffer *s = stack[i];
-               if (strcmp(s->handler_name, "default output handler")) {
-                       php_start_ob_buffer_named(s->handler_name, s->chunk_size, s->erase TSRMLS_CC);
-               }
-               php_body_write(s->buffer, s->text_length TSRMLS_CC);
-               efree(s->handler_name);
-               efree(s->buffer);
-               efree(s);
-       }
-       if (count) {
-               efree(stack);
-       }
-
-       return SUCCESS;
-}
-/* }}} */
-
-/* {{{ STATUS http_chunked_decode(char *, size_t, char **, size_t *) */
-PHP_HTTP_API STATUS _http_chunked_decode(const char *encoded, size_t encoded_len,
+/* {{{ 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;
@@ -206,41 +145,38 @@ PHP_HTTP_API STATUS _http_chunked_decode(const char *encoded, size_t encoded_len
        e_ptr = encoded;
 
        while (((e_ptr - encoded) - encoded_len) > 0) {
-               char hex_len[9] = {0};
+               char *n_ptr;
                size_t chunk_len = 0;
-               int i = 0;
 
-               /* read in chunk size */
-               while (isxdigit(*e_ptr)) {
-                       if (i == 9) {
-                               http_error_ex(E_WARNING, HTTP_E_PARSE, "Chunk size is too long: 0x%s...", hex_len);
-                               efree(*decoded);
-                               return FAILURE;
+               chunk_len = strtol(e_ptr, &n_ptr, 16);
+
+               if (n_ptr == e_ptr) {
+                       /* 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 {
+                               char *error = estrndup(n_ptr, strcspn(n_ptr, "\r\n \0"));
+                               http_error_ex(E_WARNING, HTTP_E_PARSE, "Invalid chunk size: '%s' at pos %d", error, n_ptr - encoded);
+                               efree(error);
+                               return NULL;
                        }
-                       hex_len[i++] = *e_ptr++;
+               } else {
+                       e_ptr = n_ptr;
                }
 
                /* reached the end */
-               if (!strcmp(hex_len, "0")) {
+               if (!chunk_len) {
                        break;
                }
 
                /* new line */
                if (strncmp(e_ptr, HTTP_CRLF, 2)) {
-                       http_error_ex(E_WARNING, HTTP_E_PARSE, "Invalid character (expected 0x0D 0x0A; got: %x %x)", *e_ptr, *(e_ptr + 1));
+                       http_error_ex(E_WARNING, HTTP_E_PARSE,
+                               "Invalid character (expected 0x0D 0x0A; got: 0x%x 0x%x)", *e_ptr, *(e_ptr + 1));
                        efree(*decoded);
-                       return FAILURE;
-               }
-
-               /* hex to long */
-               {
-                       char *error = NULL;
-                       chunk_len = strtol(hex_len, &error, 16);
-                       if (error == hex_len) {
-                               http_error_ex(E_WARNING, HTTP_E_PARSE, "Invalid chunk size string: '%s'", hex_len);
-                               efree(*decoded);
-                               return FAILURE;
-                       }
+                       return NULL;
                }
 
                memcpy(d_ptr, e_ptr += 2, chunk_len);
@@ -249,7 +185,7 @@ PHP_HTTP_API STATUS _http_chunked_decode(const char *encoded, size_t encoded_len
                *decoded_len += chunk_len;
        }
 
-       return SUCCESS;
+       return e_ptr;
 }
 /* }}} */
 
@@ -285,7 +221,7 @@ PHP_HTTP_API STATUS _http_split_response_ex(char *response, size_t response_len,
                memcpy(*body, real_body, *body_len);
        }
 
-       return http_parse_headers_ex(header, real_body ? response_len - *body_len : response_len, headers, 1);
+       return http_parse_headers_ex(header, headers, 1);
 }
 /* }}} */