X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=http_methods.c;h=eaf3642c8c32baac478756207886906f3e7a61a1;hp=49c57a4f6f438f275ad668f3afbf3956a22e9f31;hb=4d20cb224c9ef093507bfff0267ae1ebf53dcc7a;hpb=30e2b03a47f16cf8dcfb900314db792ac88fa17e diff --git a/http_methods.c b/http_methods.c index 49c57a4..eaf3642 100644 --- a/http_methods.c +++ b/http_methods.c @@ -24,7 +24,7 @@ #include "php_http_std_defs.h" #include "php_http_api.h" #include "php_http_cache_api.h" -#include "php_http_curl_api.h" +#include "php_http_request_api.h" #include "php_http_date_api.h" #include "php_http_headers_api.h" #include "php_http_message_api.h" @@ -317,7 +317,7 @@ PHP_METHOD(HttpResponse, setData) zval *the_data; getObject(http_response_object, obj); - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &the_data)) { + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/", &the_data)) { RETURN_FALSE; } @@ -532,6 +532,7 @@ PHP_METHOD(HttpMessage, fromString) char *string = NULL; int length = 0; http_message *msg = NULL; + http_message_object obj; if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &string, &length)) { RETURN_NULL(); @@ -546,45 +547,30 @@ PHP_METHOD(HttpMessage, fromString) } /* }}} */ -/* {{{ proto void HttpMessage::__construct([string raw_message]) +/* {{{ proto void HttpMessage::__construct([string message]) * - * Instantiate a new HttpMessage object based on the optionally provided - * raw message. An HTTP Message can be either a response or a request. + * Instantiate a new HttpMessage object. */ PHP_METHOD(HttpMessage, __construct) { - zval *message = NULL; + char *message = NULL; + int length = 0; getObject(http_message_object, obj); SET_EH_THROW_HTTP(); - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z/", &message)) { - if (message) { - convert_to_string(message); - SET_PROP(obj, raw, message); + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &message, &length) && message && length) { + if (obj->message = http_message_parse(message, length)) { + if (obj->message->parent) { + obj->parent = http_message_object_from_msg(obj->message->parent); + } } + } else if (!obj->message) { + obj->message = http_message_new(); } SET_EH_NORMAL(); } /* }}} */ -/* {{{ proto void HttpMessage::setRaw(string raw_message) - * - * Parse a new raw message. - */ -PHP_METHOD(HttpMessage, setRaw) -{ - zval *message; - getObject(http_message_object, obj); - - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/", &message)) { - return; - } - - convert_to_string(message); - SET_PROP(obj, raw, message); -} -/* }}} */ - /* {{{ proto string HttpMessage::getBody() * * Get the body of the parsed Message. @@ -596,8 +582,7 @@ PHP_METHOD(HttpMessage, getBody) NO_ARGS; - body = GET_PROP(obj, body); - RETURN_STRINGL(Z_STRVAL_P(body), Z_STRLEN_P(body), 1); + RETURN_PHPSTR(&obj->message->body, PHPSTR_FREE_NOT, 1); } /* }}} */ @@ -607,14 +592,14 @@ PHP_METHOD(HttpMessage, getBody) */ PHP_METHOD(HttpMessage, getHeaders) { - zval *headers; + zval headers; getObject(http_message_object, obj); NO_ARGS; - headers = GET_PROP(obj, headers); + Z_ARRVAL(headers) = &obj->message->hdrs; array_init(return_value); - array_copy(headers, return_value); + array_copy(&headers, return_value); } /* }}} */ @@ -624,14 +609,16 @@ PHP_METHOD(HttpMessage, getHeaders) */ PHP_METHOD(HttpMessage, setHeaders) { - zval *headers; + zval *new_headers, old_headers; getObject(http_message_object, obj); - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/", &headers)) { + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/", &new_headers)) { return; } - SET_PROP(obj, headers, headers); + zend_hash_clean(&obj->message->hdrs); + Z_ARRVAL(old_headers) = &obj->message->hdrs; + array_copy(new_headers, &old_headers); } /* }}} */ @@ -641,7 +628,7 @@ PHP_METHOD(HttpMessage, setHeaders) */ PHP_METHOD(HttpMessage, addHeaders) { - zval *old_headers, *new_headers; + zval old_headers, *new_headers; zend_bool append = 0; getObject(http_message_object, obj); @@ -649,13 +636,12 @@ PHP_METHOD(HttpMessage, addHeaders) return; } - old_headers = GET_PROP(obj, headers); + Z_ARRVAL(old_headers) = &obj->message->hdrs; if (append) { - array_append(new_headers, old_headers); + array_append(new_headers, &old_headers); } else { - array_merge(new_headers, old_headers); + array_merge(new_headers, &old_headers); } - SET_PROP(obj, headers, old_headers); } /* }}} */ @@ -665,13 +651,11 @@ PHP_METHOD(HttpMessage, addHeaders) */ PHP_METHOD(HttpMessage, getType) { - zval *type; getObject(http_message_object, obj); NO_ARGS; - type = GET_PROP(obj, type); - RETURN_LONG(Z_LVAL_P(type)); + RETURN_LONG(obj->message->type); } /* }}} */ @@ -687,7 +671,7 @@ PHP_METHOD(HttpMessage, setType) if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &type)) { return; } - UPD_PROP(obj, long, type, type); + http_message_set_type(obj->message, type); } /* }}} */ @@ -697,18 +681,16 @@ PHP_METHOD(HttpMessage, setType) */ PHP_METHOD(HttpMessage, getResponseCode) { - zval *status; getObject(http_message_object, obj); NO_ARGS; - if (obj->message->type != HTTP_MSG_RESPONSE) { + if (!HTTP_MSG_TYPE(RESPONSE, obj->message)) { http_error(E_NOTICE, HTTP_E_MSG, "HttpMessage is not of type HTTP_MSG_RESPONSE"); RETURN_NULL(); } - status = GET_PROP(obj, responseCode); - RETURN_LONG(Z_LVAL_P(status)); + RETURN_LONG(obj->message->info.response.code); } /* }}} */ @@ -736,7 +718,7 @@ PHP_METHOD(HttpMessage, setResponseCode) RETURN_FALSE; } - UPD_PROP(obj, long, responseCode, code); + obj->message->info.response.code = code; RETURN_TRUE; } /* }}} */ @@ -748,7 +730,6 @@ PHP_METHOD(HttpMessage, setResponseCode) */ PHP_METHOD(HttpMessage, getRequestMethod) { - zval *method; getObject(http_message_object, obj); NO_ARGS; @@ -758,8 +739,7 @@ PHP_METHOD(HttpMessage, getRequestMethod) RETURN_NULL(); } - method = GET_PROP(obj, requestMethod); - RETURN_STRINGL(Z_STRVAL_P(method), Z_STRLEN_P(method), 1); + RETURN_STRING(obj->message->info.request.method, 1); } /* }}} */ @@ -786,8 +766,15 @@ PHP_METHOD(HttpMessage, setRequestMethod) http_error(E_WARNING, HTTP_E_PARAM, "Cannot set HttpMessage::requestMethod to an empty string"); RETURN_FALSE; } + if (SUCCESS != http_check_method(method)) { + http_error_ex(E_WARNING, HTTP_E_PARAM, "Unkown request method: %s", method); + RETURN_FALSE; + } - UPD_PROP(obj, string, requestMethod, method); + if (obj->message->info.request.method) { + efree(obj->message->info.request.method); + } + obj->message->info.request.method = estrndup(method, method_len); RETURN_TRUE; } /* }}} */ @@ -804,11 +791,11 @@ PHP_METHOD(HttpMessage, getRequestUri) NO_ARGS; if (obj->message->type != HTTP_MSG_REQUEST) { + http_error(E_WARNING, HTTP_E_MSG, "HttpMessage is not of type HTTP_MSG_REQUEST"); RETURN_NULL(); } - uri = GET_PROP(obj, requestUri); - RETURN_STRINGL(Z_STRVAL_P(uri), Z_STRLEN_P(uri), 1); + RETURN_STRING(obj->message->info.request.URI, 1); } /* }}} */ @@ -836,7 +823,10 @@ PHP_METHOD(HttpMessage, setRequestUri) RETURN_FALSE; } - UPD_PROP(obj, string, requestUri, URI); + if (obj->message->info.request.URI) { + efree(obj->message->info.request.URI); + } + obj->message->info.request.URI = estrndup(URI, URIlen); RETURN_TRUE; } /* }}} */ @@ -847,19 +837,27 @@ PHP_METHOD(HttpMessage, setRequestUri) */ PHP_METHOD(HttpMessage, getHttpVersion) { - zval *version; char ver[4] = {0}; + float version; getObject(http_message_object, obj); NO_ARGS; - version = GET_PROP(obj, httpVersion); + switch (obj->message->type) + { + case HTTP_MSG_RESPONSE: + version = obj->message->info.response.http_version; + break; - if (Z_TYPE_P(version) == IS_NULL) { - RETURN_NULL(); - } + case HTTP_MSG_REQUEST: + version = obj->message->info.request.http_version; + break; - sprintf(ver, "1.1f", Z_DVAL_P(version)); + case HTTP_MSG_NONE: + default: + RETURN_NULL(); + } + sprintf(ver, "%1.1f", version); RETURN_STRINGL(ver, 3, 1); } /* }}} */ @@ -875,22 +873,64 @@ PHP_METHOD(HttpMessage, setHttpVersion) zval *zv, *version; getObject(http_message_object, obj); - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zv)) { + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/", &zv)) { return; } + if (obj->message->type == HTTP_MSG_NONE) { + http_error(E_WARNING, HTTP_E_MSG, "Message is neither of type HTTP_MSG_RESPONSE nor HTTP_MSG_REQUEST"); + RETURN_FALSE; + } + convert_to_double_ex(&zv); sprintf(v, "%1.1f", Z_DVAL_P(zv)); if (strcmp(v, "1.0") && strcmp(v, "1.1")) { - http_error_ex(E_WARNING, HTTP_E_PARAM, "Invalid HTTP version (1.0 or 1.1): %s", v); + http_error_ex(E_WARNING, HTTP_E_PARAM, "Invalid HTTP protocol version (1.0 or 1.1): %s", v); RETURN_FALSE; } - SET_PROP(obj, httpVersion, zv); + if (obj->message->type == HTTP_MSG_RESPONSE) { + obj->message->info.response.http_version = (float) Z_DVAL_P(zv); + } else { + obj->message->info.request.http_version = (float) Z_DVAL_P(zv); + } + RETURN_TRUE; } /* }}} */ -/* {{{ proto string HttpMessage::toString() +/* {{{ proto HttpMessage HttpMessage::getParentMessage() + * + * Get parent Message. + */ +PHP_METHOD(HttpMessage, getParentMessage) +{ + getObject(http_message_object, obj); + + NO_ARGS; + + if (obj->message->parent) { + RETVAL_OBJVAL(obj->parent); + } else { + RETVAL_NULL(); + } +} +/* }}} */ + +/* {{{ proto bool HttpMessage::send() + * + * Send the Message according to its type as Response or Request. + */ +PHP_METHOD(HttpMessage, send) +{ + getObject(http_message_object, obj); + + NO_ARGS; + + RETURN_SUCCESS(http_message_send(obj->message)); +} +/* }}} */ + +/* {{{ proto string HttpMessage::toString([bool include_parent = true]) * * Get the string representation of the Message. */ @@ -898,11 +938,18 @@ PHP_METHOD(HttpMessage, toString) { char *string; size_t length; + zend_bool include_parent = 1; getObject(http_message_object, obj); - NO_ARGS; + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &include_parent)) { + RETURN_FALSE; + } - http_message_tostring(obj->message, &string, &length); + if (include_parent) { + http_message_serialize(obj->message, &string, &length); + } else { + http_message_tostring(obj->message, &string, &length); + } RETURN_STRINGL(string, length, 0); } /* }}} */ @@ -1873,75 +1920,24 @@ PHP_METHOD(HttpRequest, send) switch (Z_LVAL_P(meth)) { case HTTP_GET: - status = http_get_ex(obj->ch, request_uri, Z_ARRVAL_P(opts), Z_ARRVAL_P(info), &obj->response); + case HTTP_HEAD: + status = http_request_ex(obj->ch, Z_LVAL_P(meth), request_uri, NULL, Z_ARRVAL_P(opts), Z_ARRVAL_P(info), &obj->response); break; - case HTTP_HEAD: - status = http_head_ex(obj->ch, request_uri, Z_ARRVAL_P(opts), Z_ARRVAL_P(info), &obj->response); + case HTTP_PUT: break; case HTTP_POST: - { - zval *post_files, *post_data; - - post_files = GET_PROP(obj, postFiles); - post_data = GET_PROP(obj, postData); - - if (!zend_hash_num_elements(Z_ARRVAL_P(post_files))) { - - /* urlencoded post */ - status = http_post_array_ex(obj->ch, request_uri, Z_ARRVAL_P(post_data), Z_ARRVAL_P(opts), Z_ARRVAL_P(info), &obj->response); - - } else { - - /* - * multipart post - */ - char *key = NULL; - long idx; - zval **data; - struct curl_httppost *http_post_data[2] = {NULL, NULL}; - - /* normal data */ - FOREACH_KEYVAL(post_data, key, idx, data) { - if (key) { - convert_to_string_ex(data); - curl_formadd(&http_post_data[0], &http_post_data[1], - CURLFORM_COPYNAME, key, - CURLFORM_COPYCONTENTS, Z_STRVAL_PP(data), - CURLFORM_CONTENTSLENGTH, Z_STRLEN_PP(data), - CURLFORM_END - ); - - /* reset */ - key = NULL; - } - } - - /* file data */ - FOREACH_VAL(post_files, data) { - zval **file, **type, **name; - - if ( SUCCESS == zend_hash_find(Z_ARRVAL_PP(data), "name", sizeof("name"), (void **) &name) && - SUCCESS == zend_hash_find(Z_ARRVAL_PP(data), "type", sizeof("type"), (void **) &type) && - SUCCESS == zend_hash_find(Z_ARRVAL_PP(data), "file", sizeof("file"), (void **) &file)) { - - curl_formadd(&http_post_data[0], &http_post_data[1], - CURLFORM_COPYNAME, Z_STRVAL_PP(name), - CURLFORM_FILE, Z_STRVAL_PP(file), - CURLFORM_CONTENTTYPE, Z_STRVAL_PP(type), - CURLFORM_END - ); - } - } + default: + { + http_request_body body; + zval *fields = GET_PROP(obj, postData), *files = GET_PROP(obj, postFiles); - status = http_post_curldata_ex(obj->ch, request_uri, http_post_data[0], Z_ARRVAL_P(opts), Z_ARRVAL_P(info), &obj->response); - curl_formfree(http_post_data[0]); - } + if (SUCCESS == (status = http_request_body_fill(&body, Z_ARRVAL_P(fields), Z_ARRVAL_P(files)))) { + status = http_request_ex(obj->ch, Z_LVAL_P(meth), request_uri, &body, Z_ARRVAL_P(opts), Z_ARRVAL_P(info), &obj->response); + http_request_body_dtor(&body); } - break; - - default: + } break; } @@ -1994,4 +1990,3 @@ PHP_METHOD(HttpRequest, send) * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ -