#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 "php_http_exception_object.h"
+#endif
ZEND_EXTERN_MODULE_GLOBALS(http);
/* char *pretty_key(char *, size_t, zend_bool, zebd_bool) */
-char *pretty_key(char *key, size_t key_len, zend_bool uctitle, zend_bool xhyphen)
+char *_http_pretty_key(char *key, size_t key_len, zend_bool uctitle, zend_bool xhyphen)
{
if (key && key_len) {
unsigned i, wasalpha;
}
/* }}} */
-/* {{{ 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)
+/* {{{ void http_error(long, long, char*) */
+void _http_error_ex(long type, long code, const char *format, ...)
+{
+ va_list args;
+ TSRMLS_FETCH();
+
+ va_start(args, format);
+ if (type == E_THROW) {
+#ifdef ZEND_ENGINE_2
+ char *message;
+ vspprintf(&message, 0, format, args);
+ zend_throw_exception(http_exception_get_default(), message, code TSRMLS_CC);
+#else
+ type = E_WARNING;
+#endif
+ }
+ if (type != E_THROW) {
+ php_verror(NULL, "", type, format, args TSRMLS_CC);
+ }
+ va_end(args);
+}
+/* }}} */
+
+/* {{{ 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;
}
/* }}} */
}
/* }}} */
-/* {{{ 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,
/* read in chunk size */
while (isxdigit(*e_ptr)) {
if (i == 9) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
- "Chunk size is too long: 0x%s...", hex_len);
+ http_error_ex(E_WARNING, HTTP_E_PARSE, "Chunk size is too long: 0x%s...", hex_len);
efree(*decoded);
return FAILURE;
}
/* new line */
if (strncmp(e_ptr, HTTP_CRLF, 2)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
- "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: %x %x)", *e_ptr, *(e_ptr + 1));
efree(*decoded);
return FAILURE;
}
char *error = NULL;
chunk_len = strtol(hex_len, &error, 16);
if (error == hex_len) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
- "Invalid chunk size string: '%s'", hex_len);
+ http_error_ex(E_WARNING, HTTP_E_PARSE, "Invalid chunk size string: '%s'", hex_len);
efree(*decoded);
return FAILURE;
}