From b23b4edaebd71ff76579b97f3ee353f43e83bd25 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 23 Jan 2007 15:47:13 +0000 Subject: [PATCH] - add HttpMessage::fromEnv(int type[, string class_name]) --- http_headers_api.c | 26 +++++++++++++++ http_message_api.c | 66 +++++++++++++++++++++++++++++++++++++++ http_message_object.c | 31 ++++++++++++++++++ http_response_object.c | 20 ++---------- package2.xml | 5 ++- php_http.h | 2 +- php_http_headers_api.h | 3 ++ php_http_message_api.h | 2 ++ php_http_message_object.h | 1 + 9 files changed, 134 insertions(+), 22 deletions(-) diff --git a/http_headers_api.c b/http_headers_api.c index 95fbdec..99eb188 100644 --- a/http_headers_api.c +++ b/http_headers_api.c @@ -12,6 +12,7 @@ /* $Id$ */ +#define HTTP_WANT_SAPI #include "php_http.h" #include "ext/standard/url.h" @@ -24,6 +25,14 @@ # define HTTP_DBG_NEG 0 #endif +/* {{{ static void http_grab_response_headers(void *, void *) */ +static void http_grab_response_headers(void *data, void *arg TSRMLS_DC) +{ + phpstr_appendl(PHPSTR(arg), ((sapi_header_struct *)data)->header); + phpstr_appends(PHPSTR(arg), HTTP_CRLF); +} +/* }}} */ + /* {{{ static int http_sort_q(const void *, const void *) */ static int http_sort_q(const void *a, const void *b TSRMLS_DC) { @@ -456,6 +465,23 @@ PHP_HTTP_API void _http_get_request_headers(HashTable *headers TSRMLS_DC) } /* }}} */ +/* {{{ STATUS http_get_response_headers(HashTable *) */ +PHP_HTTP_API STATUS _http_get_response_headers(HashTable *headers_ht TSRMLS_DC) +{ + STATUS status; + phpstr headers; + + phpstr_init(&headers); + zend_llist_apply_with_argument(&SG(sapi_headers).headers, http_grab_response_headers, &headers TSRMLS_CC); + phpstr_fix(&headers); + + status = http_parse_headers_ex(PHPSTR_VAL(&headers), headers_ht, 1); + phpstr_dtor(&headers); + + return status; +} +/* }}} */ + /* {{{ zend_bool http_match_request_header(char *, char *) */ PHP_HTTP_API zend_bool _http_match_request_header_ex(const char *header, const char *value, zend_bool match_case TSRMLS_DC) { diff --git a/http_message_api.c b/http_message_api.c index 85b2b00..88c89fc 100644 --- a/http_message_api.c +++ b/http_message_api.c @@ -76,6 +76,72 @@ PHP_HTTP_API http_message *_http_message_init_ex(http_message *message, http_mes return message; } +PHP_HTTP_API http_message *_http_message_init_env(http_message *message, http_message_type type TSRMLS_DC ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) +{ + int free_msg; + http_info inf; + zval *sval, tval; + char *body_str; + size_t body_len; + + if ((free_msg = !message)) { + message = http_message_init_rel(NULL, HTTP_MSG_NONE); + } + + memset(&inf, 0, sizeof(http_info)); + switch (inf.type = type) { + case HTTP_MSG_REQUEST: + if ((sval = http_get_server_var("SERVER_PROTOCOL", 1)) && !strncmp(Z_STRVAL_P(sval), ZEND_STRL("HTTP/"))) { + inf.http.version = atof(Z_STRVAL_P(sval) + lenof("HTTP/")); + } else { + inf.http.version = 1.1; + } + if ((sval = http_get_server_var("REQUEST_METHOD", 1))) { + inf.http.info.request.method = estrdup(Z_STRVAL_P(sval)); + } else { + inf.http.info.request.method = ecalloc(1, 1); + } + if ((sval = http_get_server_var("REQUEST_URI", 1))) { + inf.http.info.request.url = estrdup(Z_STRVAL_P(sval)); + } else { + inf.http.info.request.url = ecalloc(1, 1); + } + + http_message_set_info(message, &inf); + http_get_request_headers(&message->hdrs); + if (SUCCESS == http_get_request_body_ex(&body_str, &body_len, 0)) { + phpstr_from_string_ex(&message->body, body_str, body_len); + } + break; + + case HTTP_MSG_RESPONSE: + if (!SG(sapi_headers).http_status_line || SUCCESS != http_info_parse_ex(SG(sapi_headers).http_status_line, &inf, 0)) { + inf.http.version = 1.1; + inf.http.info.response.code = 200; + inf.http.info.response.status = estrdup("Ok"); + } + + http_message_set_info(message, &inf); + http_get_response_headers(&message->hdrs); + if (SUCCESS == php_ob_get_buffer(&tval TSRMLS_CC)) { + message->body.data = Z_STRVAL(tval); + message->body.used = Z_STRLEN(tval); + message->body.free = 1; /* "\0" */ + } + break; + + default: + if (free_msg) { + http_message_free(&message); + } else { + message = NULL; + } + break; + } + http_info_dtor(&inf); + + return message; +} PHP_HTTP_API void _http_message_set_type(http_message *message, http_message_type type) { diff --git a/http_message_object.c b/http_message_object.c index 235ffc4..32a0e32 100644 --- a/http_message_object.c +++ b/http_message_object.c @@ -32,6 +32,7 @@ #include "php_http_request_method_api.h" #include "php_http_request_api.h" #include "php_http_request_object.h" +#include "php_http_headers_api.h" #if defined(HTTP_HAVE_SPL) && !defined(WONKY) /* SPL doesn't install its headers */ @@ -51,6 +52,11 @@ HTTP_BEGIN_ARGS(factory, 0) HTTP_ARG_VAL(class_name, 0) HTTP_END_ARGS; +HTTP_BEGIN_ARGS(fromEnv, 1) + HTTP_ARG_VAL(type, 0) + HTTP_ARG_VAL(class_name, 0) +HTTP_END_ARGS; + HTTP_EMPTY_ARGS(getBody); HTTP_BEGIN_ARGS(setBody, 1) HTTP_ARG_VAL(body, 0) @@ -185,6 +191,7 @@ zend_function_entry http_message_object_fe[] = { HTTP_MESSAGE_ME(factory, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_MALIAS(HttpMessage, fromString, factory, HTTP_ARGS(HttpMessage, factory), ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + HTTP_MESSAGE_ME(fromEnv, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) HTTP_MESSAGE_ME(detach, ZEND_ACC_PUBLIC) HTTP_MESSAGE_ME(prepend, ZEND_ACC_PUBLIC) @@ -735,6 +742,30 @@ PHP_METHOD(HttpMessage, factory) } /* }}} */ +/* {{{ proto static HttpMessage HttpMessage::fromEnv(int type[, string class_name = "HttpMessage"]) + Create a new HttpMessage object from environment representing either current request or response */ +PHP_METHOD(HttpMessage, fromEnv) +{ + char *cn = NULL; + int cl = 0; + long type; + http_message_object *obj = NULL; + zend_object_value ov; + + RETVAL_NULL(); + SET_EH_THROW_HTTP(); + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|s", &type, &cn, &cl)) { + if (SUCCESS == http_object_new(&ov, cn, cl, _http_message_object_new_ex, http_message_object_ce, http_message_init_env(NULL, type), &obj)) { + RETVAL_OBJVAL(ov, 0); + } + if (obj && !obj->message) { + obj->message = http_message_new(); + } + } + SET_EH_NORMAL(); +} +/* }}} */ + /* {{{ proto string HttpMessage::getBody() Get the body of the parsed HttpMessage. */ PHP_METHOD(HttpMessage, getBody) diff --git a/http_response_object.c b/http_response_object.c index bd141dd..a9f60c4 100644 --- a/http_response_object.c +++ b/http_response_object.c @@ -132,9 +132,6 @@ HTTP_EMPTY_ARGS(getRequestHeaders); HTTP_EMPTY_ARGS(getRequestBody); HTTP_EMPTY_ARGS(getRequestBodyStream); -#define http_grab_response_headers _http_grab_response_headers -static void _http_grab_response_headers(void *data, void *arg TSRMLS_DC); - #define OBJ_PROP_CE http_response_object_ce zend_class_entry *http_response_object_ce; zend_function_entry http_response_object_fe[] = { @@ -224,12 +221,6 @@ PHP_MINIT_FUNCTION(http_response_object) return SUCCESS; } -static void _http_grab_response_headers(void *data, void *arg TSRMLS_DC) -{ - phpstr_appendl(PHPSTR(arg), ((sapi_header_struct *)data)->header); - phpstr_appends(PHPSTR(arg), HTTP_CRLF); -} - /* ### USERLAND ### */ /* {{{ proto static bool HttpResponse::setHeader(string name[, mixed value[, bool replace = true]]) @@ -263,22 +254,17 @@ PHP_METHOD(HttpResponse, getHeader) { char *name = NULL; int name_len = 0; - phpstr headers; if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &name, &name_len)) { RETURN_FALSE; } - phpstr_init(&headers); - zend_llist_apply_with_argument(&SG(sapi_headers).headers, http_grab_response_headers, &headers TSRMLS_CC); - phpstr_fix(&headers); - if (name && name_len) { zval **header; HashTable headers_ht; zend_hash_init(&headers_ht, sizeof(zval *), NULL, ZVAL_PTR_DTOR, 0); - if ( (SUCCESS == http_parse_headers_ex(PHPSTR_VAL(&headers), &headers_ht, 1)) && + if ( (SUCCESS == http_get_response_headers(&headers_ht)) && (SUCCESS == zend_hash_find(&headers_ht, name, name_len + 1, (void *) &header))) { RETVAL_ZVAL(*header, 1, 0); } else { @@ -287,10 +273,8 @@ PHP_METHOD(HttpResponse, getHeader) zend_hash_destroy(&headers_ht); } else { array_init(return_value); - http_parse_headers_ex(PHPSTR_VAL(&headers), Z_ARRVAL_P(return_value), 1); + http_get_response_headers(Z_ARRVAL_P(return_value)); } - - phpstr_dtor(&headers); } /* }}} */ diff --git a/package2.xml b/package2.xml index d417fa6..f428d29 100644 --- a/package2.xml +++ b/package2.xml @@ -30,16 +30,15 @@ support. Parallel requests are available for PHP 5 and greater. 2007-01-23 - 1.4.0 + 1.5.0dev 1.4.0 - stable + beta stable BSD, revised diff --git a/php_http.h b/php_http.h index 67509c9..caa5c0c 100644 --- a/php_http.h +++ b/php_http.h @@ -15,7 +15,7 @@ #ifndef PHP_EXT_HTTP_H #define PHP_EXT_HTTP_H -#define PHP_EXT_HTTP_VERSION "1.4.0" +#define PHP_EXT_HTTP_VERSION "1.5.0dev" #ifdef HAVE_CONFIG_H # include "config.h" diff --git a/php_http_headers_api.h b/php_http_headers_api.h index a4cf819..231f599 100644 --- a/php_http_headers_api.h +++ b/php_http_headers_api.h @@ -55,6 +55,9 @@ PHP_HTTP_API http_range_status _http_get_request_ranges(HashTable *ranges, size_ #define http_get_request_headers(h) _http_get_request_headers((h) TSRMLS_CC) PHP_HTTP_API void _http_get_request_headers(HashTable *headers TSRMLS_DC); +#define http_get_response_headers(h) _http_get_response_headers((h) TSRMLS_CC) +PHP_HTTP_API STATUS _http_get_response_headers(HashTable *headers_ht TSRMLS_DC); + #define http_match_request_header(h, v) http_match_request_header_ex((h), (v), 0) #define http_match_request_header_ex(h, v, c) _http_match_request_header_ex((h), (v), (c) TSRMLS_CC) PHP_HTTP_API zend_bool _http_match_request_header_ex(const char *header, const char *value, zend_bool match_case TSRMLS_DC); diff --git a/php_http_message_api.h b/php_http_message_api.h index 4688c71..7857030 100644 --- a/php_http_message_api.h +++ b/php_http_message_api.h @@ -44,6 +44,8 @@ struct _http_message_t { #define http_message_init_ex(m, t) _http_message_init_ex((m), (t) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC) #define http_message_init_rel(m, t) _http_message_init_ex((m), (t) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC) PHP_HTTP_API http_message *_http_message_init_ex(http_message *m, http_message_type t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC); +#define http_message_init_env(m, t) _http_message_init_env((m), (t) TSRMLS_CC ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC) +PHP_HTTP_API http_message *_http_message_init_env(http_message *m, http_message_type t TSRMLS_DC ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC); #define http_message_set_type(m, t) _http_message_set_type((m), (t)) PHP_HTTP_API void _http_message_set_type(http_message *m, http_message_type t); diff --git a/php_http_message_object.h b/php_http_message_object.h index 2d9fcb1..4e4cd38 100644 --- a/php_http_message_object.h +++ b/php_http_message_object.h @@ -112,6 +112,7 @@ PHP_METHOD(HttpMessage, key); PHP_METHOD(HttpMessage, next); PHP_METHOD(HttpMessage, factory); +PHP_METHOD(HttpMessage, fromEnv); PHP_METHOD(HttpMessage, detach); PHP_METHOD(HttpMessage, prepend); -- 2.30.2