- add HttpMessage::fromEnv(int type[, string class_name])
[m6w6/ext-http] / http_message_api.c
index 4da4e88e517b498dc56c82e573ccf4e0f467cb8f..88c89fc6cebae5192fea1dc14e6917daa7b55b8d 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)
 {
@@ -308,9 +374,9 @@ PHP_HTTP_API http_message *_http_message_parse_ex(http_message *msg, const char
 PHP_HTTP_API void _http_message_tostring(http_message *msg, char **string, size_t *length)
 {
        phpstr str;
-       char *key, *data;
-       ulong idx;
+       HashKey key = initHashKey(0);
        zval **header;
+       char *data;
        HashPosition pos1;
 
        phpstr_init_ex(&str, 4096, 0);
@@ -336,24 +402,22 @@ PHP_HTTP_API void _http_message_tostring(http_message *msg, char **string, size_
                        break;
        }
 
-       FOREACH_HASH_KEYVAL(pos1, &msg->hdrs, key, idx, header) {
-               if (key) {
+       FOREACH_HASH_KEYVAL(pos1, &msg->hdrs, key, header) {
+               if (key.type == HASH_KEY_IS_STRING) {
                        HashPosition pos2;
                        zval **single_header;
 
                        switch (Z_TYPE_PP(header)) {
                                case IS_STRING:
-                                       phpstr_appendf(&str, "%s: %s" HTTP_CRLF, key, Z_STRVAL_PP(header));
+                                       phpstr_appendf(&str, "%s: %s" HTTP_CRLF, key.str, Z_STRVAL_PP(header));
                                        break;
 
                                case IS_ARRAY:
                                        FOREACH_VAL(pos2, *header, single_header) {
-                                               phpstr_appendf(&str, "%s: %s" HTTP_CRLF, key, Z_STRVAL_PP(single_header));
+                                               phpstr_appendf(&str, "%s: %s" HTTP_CRLF, key.str, Z_STRVAL_PP(single_header));
                                        }
                                        break;
                        }
-
-                       key = NULL;
                }
        }
 
@@ -500,16 +564,13 @@ PHP_HTTP_API STATUS _http_message_send(http_message *message TSRMLS_DC)
        switch (message->type) {
                case HTTP_MSG_RESPONSE:
                {
-                       char *key;
-                       uint len;
-                       ulong idx;
+                       HashKey key = initHashKey(0);
                        zval **val;
                        HashPosition pos;
 
-                       FOREACH_HASH_KEYLENVAL(pos, &message->hdrs, key, len, idx, val) {
-                               if (key) {
-                                       http_send_header_zval_ex(key, len-1, val, 1);
-                                       key = NULL;
+                       FOREACH_HASH_KEYVAL(pos, &message->hdrs, key, val) {
+                               if (key.type == HASH_KEY_IS_STRING) {
+                                       http_send_header_zval_ex(key.str, key.len-1, val, 1);
                                }
                        }
                        rs =    SUCCESS == http_send_status(message->http.info.response.code) &&