- add HttpMessage::fromEnv(int type[, string class_name])
authorMichael Wallner <mike@php.net>
Tue, 23 Jan 2007 15:47:13 +0000 (15:47 +0000)
committerMichael Wallner <mike@php.net>
Tue, 23 Jan 2007 15:47:13 +0000 (15:47 +0000)
http_headers_api.c
http_message_api.c
http_message_object.c
http_response_object.c
package2.xml
php_http.h
php_http_headers_api.h
php_http_message_api.h
php_http_message_object.h

index 95fbdec..99eb188 100644 (file)
@@ -12,6 +12,7 @@
 
 /* $Id$ */
 
+#define HTTP_WANT_SAPI
 #include "php_http.h"
 
 #include "ext/standard/url.h"
 #      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)
 {
index 85b2b00..88c89fc 100644 (file)
@@ -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)
 {
index 235ffc4..32a0e32 100644 (file)
@@ -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)
index bd141dd..a9f60c4 100644 (file)
@@ -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);
 }
 /* }}} */
 
index d417fa6..f428d29 100644 (file)
@@ -30,16 +30,15 @@ support. Parallel requests are available for PHP 5 and greater.
  </lead>
  <date>2007-01-23</date>
  <version>
-  <release>1.4.0</release>
+  <release>1.5.0dev</release>
   <api>1.4.0</api>
  </version>
  <stability>
-  <release>stable</release>
+  <release>beta</release>
   <api>stable</api>
  </stability>
  <license>BSD, revised</license>
  <notes><![CDATA[
-* Allow response codes up to 599 in HttpMessage::setResponseCode()
 ]]></notes>
  <contents>
   <dir name="/">
index 67509c9..caa5c0c 100644 (file)
@@ -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"
index a4cf819..231f599 100644 (file)
@@ -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);
index 4688c71..7857030 100644 (file)
@@ -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);
index 2d9fcb1..4e4cd38 100644 (file)
@@ -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);