/* $Id$ */
-
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
-#include "php.h"
+
+#define HTTP_WANT_CURL
+#include "php_http.h"
#if defined(ZEND_ENGINE_2) && defined(HTTP_HAVE_CURL)
#include "zend_interfaces.h"
-#include "php_http_std_defs.h"
-#include "php_http_request_object.h"
-#include "php_http_request_api.h"
-#include "php_http_request_pool_api.h"
-#include "php_http.h"
#include "php_http_api.h"
-#include "php_http_url_api.h"
+#include "php_http_exception_object.h"
#include "php_http_message_api.h"
#include "php_http_message_object.h"
-#include "php_http_exception_object.h"
-
-#include "missing.h"
-
-#ifdef PHP_WIN32
-# include <winsock2.h>
-#endif
-#include <curl/curl.h>
+#include "php_http_request_api.h"
+#include "php_http_request_object.h"
+#include "php_http_request_pool_api.h"
+#include "php_http_url_api.h"
ZEND_EXTERN_MODULE_GLOBALS(http);
HTTP_ARG_VAL(name, 0)
HTTP_END_ARGS;
-HTTP_EMPTY_ARGS(getResponseMessage, 1);
-HTTP_EMPTY_ARGS(getRequestMessage, 1);
-HTTP_EMPTY_ARGS(getHistory, 1);
+HTTP_EMPTY_ARGS(getResponseMessage, 0);
+HTTP_EMPTY_ARGS(getRawResponseMessage, 0);
+HTTP_EMPTY_ARGS(getRequestMessage, 0);
+HTTP_EMPTY_ARGS(getRawRequestMessage, 0);
+HTTP_EMPTY_ARGS(getHistory, 0);
HTTP_EMPTY_ARGS(clearHistory, 0);
-HTTP_EMPTY_ARGS(send, 1);
+HTTP_EMPTY_ARGS(send, 0);
HTTP_BEGIN_ARGS(get, 0, 1)
HTTP_ARG_VAL(url, 0)
HTTP_REQUEST_ME(getResponseBody, ZEND_ACC_PUBLIC)
HTTP_REQUEST_ME(getResponseInfo, ZEND_ACC_PUBLIC)
HTTP_REQUEST_ME(getResponseMessage, ZEND_ACC_PUBLIC)
+ HTTP_REQUEST_ME(getRawResponseMessage, ZEND_ACC_PUBLIC)
HTTP_REQUEST_ME(getRequestMessage, ZEND_ACC_PUBLIC)
+ HTTP_REQUEST_ME(getRawRequestMessage, ZEND_ACC_PUBLIC)
HTTP_REQUEST_ME(getHistory, ZEND_ACC_PUBLIC)
HTTP_REQUEST_ME(clearHistory, ZEND_ACC_PUBLIC)
o = ecalloc(1, sizeof(http_request_object));
o->zo.ce = ce;
- o->ch = ch;
+ o->request = http_request_init_ex(NULL, ch, 0, NULL);
+ phpstr_init(&o->history);
if (ptr) {
*ptr = o;
}
- phpstr_init(&o->history);
- phpstr_init(&o->request);
- phpstr_init_ex(&o->response, HTTP_CURLBUF_SIZE, 0);
-
ALLOC_HASHTABLE(OBJ_PROP(o));
zend_hash_init(OBJ_PROP(o), 0, NULL, ZVAL_PTR_DTOR, 0);
zend_hash_copy(OBJ_PROP(o), &ce->default_properties, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
getObject(http_request_object, old_obj);
old_zo = zend_objects_get_address(this_ptr TSRMLS_CC);
- new_ov = http_request_object_new_ex(old_zo->ce, curl_easy_duphandle(old_obj->ch), &new_obj);
+ new_ov = http_request_object_new_ex(old_zo->ce, curl_easy_duphandle(old_obj->request->ch), &new_obj);
zend_objects_clone_members(&new_obj->zo, new_ov, old_zo, Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC);
phpstr_append(&new_obj->history, old_obj->history.data, old_obj->history.used);
- phpstr_append(&new_obj->request, old_obj->request.data, old_obj->request.used);
- phpstr_append(&new_obj->response, old_obj->response.data, old_obj->response.used);
+ phpstr_append(&new_obj->request->conv.request, old_obj->request->conv.request.data, old_obj->request->conv.request.used);
+ phpstr_append(&new_obj->request->conv.response, old_obj->request->conv.response.data, old_obj->request->conv.response.used);
return new_ov;
}
DCL_PROP_N(PROTECTED, options);
DCL_PROP_N(PROTECTED, responseInfo);
DCL_PROP_N(PROTECTED, responseData);
- DCL_PROP_N(PROTECTED, responseCode);
+ DCL_PROP(PROTECTED, long, responseCode, 0);
DCL_PROP_N(PROTECTED, responseMessage);
DCL_PROP_N(PROTECTED, postFields);
DCL_PROP_N(PROTECTED, postFiles);
/*
* Auth Constants
*/
-# if LIBCURL_VERSION_NUM >= 0x070a05
DCL_CONST(long, "AUTH_BASIC", CURLAUTH_BASIC);
DCL_CONST(long, "AUTH_DIGEST", CURLAUTH_DIGEST);
DCL_CONST(long, "AUTH_NTLM", CURLAUTH_NTLM);
DCL_CONST(long, "AUTH_ANY", CURLAUTH_ANY);
-# endif /* LIBCURL_VERSION_NUM */
#endif /* WONKY */
}
zend_hash_destroy(OBJ_PROP(o));
FREE_HASHTABLE(OBJ_PROP(o));
}
- if (o->ch) {
- /* avoid nasty segfaults with already cleaned up callbacks */
- curl_easy_setopt(o->ch, CURLOPT_NOPROGRESS, 1);
- curl_easy_setopt(o->ch, CURLOPT_PROGRESSFUNCTION, NULL);
- curl_easy_setopt(o->ch, CURLOPT_VERBOSE, 0);
- curl_easy_setopt(o->ch, CURLOPT_DEBUGFUNCTION, NULL);
- curl_easy_cleanup(o->ch);
- }
- phpstr_dtor(&o->response);
- phpstr_dtor(&o->request);
+ http_request_free(&o->request);
phpstr_dtor(&o->history);
efree(o);
}
-STATUS _http_request_object_requesthandler(http_request_object *obj, zval *this_ptr, http_request_body *body TSRMLS_DC)
+STATUS _http_request_object_requesthandler(http_request_object *obj, zval *this_ptr TSRMLS_DC)
{
- zval *meth, *URL, *meth_p, *URL_p;
- char *request_uri;
+ zval *URL, *URL_p, *meth_p;
STATUS status = SUCCESS;
- if (!body) {
- return FAILURE;
- }
- HTTP_CHECK_CURL_INIT(obj->ch, curl_easy_init(), return FAILURE);
-
+ http_request_reset(obj->request);
+ HTTP_CHECK_CURL_INIT(obj->request->ch, curl_easy_init(), return FAILURE);
+
URL = convert_to_type_ex(IS_STRING, GET_PROP(obj, url), &URL_p);
- // HTTP_URI_MAXLEN+1 long char *
- if (!(request_uri = http_absolute_uri_ex(Z_STRVAL_P(URL), Z_STRLEN_P(URL), NULL, 0, NULL, 0, 0))) {
- if (URL_p) {
- zval_ptr_dtor(&URL_p);
- }
- return FAILURE;
- }
- if (URL_p) {
- zval_ptr_dtor(&URL_p);
- }
+ obj->request->url = http_absolute_url(Z_STRVAL_P(URL));
+ if (URL_p) zval_ptr_dtor(&URL_p);
- meth = convert_to_type_ex(IS_LONG, GET_PROP(obj, method), &meth_p);
- switch (Z_LVAL_P(meth))
+ switch (obj->request->meth = Z_LVAL_P(convert_to_type_ex(IS_LONG, GET_PROP(obj, method), &meth_p)))
{
case HTTP_GET:
case HTTP_HEAD:
- body->type = -1;
- body = NULL;
break;
case HTTP_PUT:
php_stream *stream = php_stream_open_wrapper(Z_STRVAL_P(GET_PROP(obj, putFile)), "rb", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL);
if (stream && !php_stream_stat(stream, &ssb)) {
- body->type = HTTP_REQUEST_BODY_UPLOADFILE;
- body->data = stream;
- body->size = ssb.sb.st_size;
+ http_request_body_init_ex(obj->request->body, HTTP_REQUEST_BODY_UPLOADFILE, stream, ssb.sb.st_size, 1);
} else {
status = FAILURE;
}
zval_ptr_dtor(&ctype_p);
}
- body->type = HTTP_REQUEST_BODY_CSTRING;
- body->data = estrndup(Z_STRVAL_P(raw_data), Z_STRLEN_P(raw_data));
- body->size = Z_STRLEN_P(raw_data);
+ obj->request->body = http_request_body_init_ex(obj->request->body, HTTP_REQUEST_BODY_CSTRING,
+ estrndup(Z_STRVAL_P(raw_data), Z_STRLEN_P(raw_data)), Z_STRLEN_P(raw_data), 1);
+
} else {
- status = http_request_body_fill(body, Z_ARRVAL_P(GET_PROP(obj, postFields)), Z_ARRVAL_P(GET_PROP(obj, postFiles)));
+ zval *fields_cpy, *files_cpy;
+ HashTable *fields = Z_ARRVAL_P(convert_to_type_ex(IS_ARRAY, GET_PROP(obj, postFields), &fields_cpy));
+ HashTable *files = Z_ARRVAL_P(convert_to_type_ex(IS_ARRAY, GET_PROP(obj, postFiles), &files_cpy));
+
+ if (!(obj->request->body = http_request_body_fill(obj->request->body, fields, files))) {
+ status = FAILURE;
+ }
+
+ if (fields_cpy) {
+ zval_ptr_dtor(&fields_cpy);
+ }
+ if (files_cpy) {
+ zval_ptr_dtor(&files_cpy);
+ }
}
if (raw_data_p) {
if (status == SUCCESS) {
zval *qdata_p, *qdata = convert_to_type_ex(IS_STRING, GET_PROP(obj, queryData), &qdata_p);
+ zval *opt_p, *options = convert_to_type_ex(IS_ARRAY, GET_PROP(obj, options), &opt_p);
if (Z_STRLEN_P(qdata)) {
- if (!strchr(request_uri, '?')) {
- strlcat(request_uri, "?", HTTP_URI_MAXLEN);
+ if (!strchr(obj->request->url, '?')) {
+ strlcat(obj->request->url, "?", HTTP_URL_MAXLEN);
} else {
- strlcat(request_uri, "&", HTTP_URI_MAXLEN);
+ strlcat(obj->request->url, "&", HTTP_URL_MAXLEN);
}
- strlcat(request_uri, Z_STRVAL_P(qdata), HTTP_URI_MAXLEN);
+ strlcat(obj->request->url, Z_STRVAL_P(qdata), HTTP_URL_MAXLEN);
}
+ http_request_prepare(obj->request, Z_ARRVAL_P(options));
+
+ if (opt_p) {
+ zval_ptr_dtor(&opt_p);
+ }
if (qdata_p) {
zval_ptr_dtor(&qdata_p);
}
-
- status = http_request_init(obj->ch, Z_LVAL_P(meth), request_uri, body, Z_ARRVAL_P(GET_PROP(obj, options)));
}
- efree(request_uri);
-
- /* clean previous response */
- phpstr_dtor(&obj->response);
- /* clean previous request */
- phpstr_dtor(&obj->request);
return status;
}
STATUS _http_request_object_responsehandler(http_request_object *obj, zval *this_ptr TSRMLS_DC)
{
http_message *msg;
-
- phpstr_fix(&obj->request);
- phpstr_fix(&obj->response);
- msg = http_message_parse(PHPSTR_VAL(&obj->response), PHPSTR_LEN(&obj->response));
+ phpstr_fix(&obj->request->conv.request);
+ phpstr_fix(&obj->request->conv.response);
+
+ msg = http_message_parse(PHPSTR_VAL(&obj->request->conv.response), PHPSTR_LEN(&obj->request->conv.response));
if (!msg) {
return FAILURE;
* the requests and the responses in separate chains
* for redirects
*/
- http_message *response = msg, *request = http_message_parse(PHPSTR_VAL(&obj->request), PHPSTR_LEN(&obj->request));
+ http_message *response = msg, *request = http_message_parse(PHPSTR_VAL(&obj->request->conv.request), PHPSTR_LEN(&obj->request->conv.request));
http_message *free_msg = request;
do {
UPD_PROP(obj, long, responseCode, msg->http.info.response.code);
- MAKE_STD_ZVAL(headers)
+ MAKE_STD_ZVAL(headers);
array_init(headers);
zend_hash_copy(Z_ARRVAL_P(headers), &msg->hdrs, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
SET_PROP(obj, responseMessage, message);
zval_ptr_dtor(&message);
- http_request_info(obj->ch, Z_ARRVAL_P(info));
+ http_request_info(obj->request, Z_ARRVAL_P(info));
SET_PROP(obj, responseInfo, info);
return SUCCESS;
* Set the request method.
*
* Expects an int as parameter specifying the request method to use.
- * In PHP 5.1+ HttpRequest::METH, otherwise the HTTP_METH constants can be used.
+ * In PHP 5.1+ HttpRequest::METH_*, otherwise the HTTP_METH_* constants can be used.
*
* Returns TRUE on success, or FALSE on failure.
*/
getObject(http_request_object, obj);
SET_EH_THROW_HTTP();
- if (msg = http_message_parse(PHPSTR_VAL(&obj->request), PHPSTR_LEN(&obj->request))) {
+ if ((msg = http_message_parse(PHPSTR_VAL(&obj->request->conv.request), PHPSTR_LEN(&obj->request->conv.request)))) {
ZVAL_OBJVAL(return_value, http_message_object_new_ex(http_message_object_ce, msg, NULL));
}
SET_EH_NORMAL();
}
/* }}} */
+/* {{{ proto string HttpRequest::getRawRequestMessage()
+ *
+ * Get sent HTTP message.
+ *
+ * Returns an HttpMessage in a form of a string
+ *
+ */
+PHP_METHOD(HttpRequest, getRawRequestMessage)
+{
+ NO_ARGS;
+
+ IF_RETVAL_USED {
+ getObject(http_request_object, obj);
+
+ RETURN_PHPSTR_DUP(&obj->request->conv.request);
+ }
+}
+/* }}} */
+
+/* {{{ proto string HttpRequest::getRawResponseMessage()
+ *
+ * Get the entire HTTP response.
+ *
+ * Returns the complete web server response, including the headers in a form of a string.
+ *
+ */
+PHP_METHOD(HttpRequest, getRawResponseMessage)
+{
+ NO_ARGS;
+
+ IF_RETVAL_USED {
+ getObject(http_request_object, obj);
+
+ RETURN_PHPSTR_DUP(&obj->request->conv.response);
+ }
+}
+/* }}} */
+
/* {{{ proto HttpMessage HttpRequest::getHistory()
*
* Get all sent requests and received responses as an HttpMessage object.
getObject(http_request_object, obj);
SET_EH_THROW_HTTP();
- if (msg = http_message_parse(PHPSTR_VAL(&obj->history), PHPSTR_LEN(&obj->history))) {
+ if ((msg = http_message_parse(PHPSTR_VAL(&obj->history), PHPSTR_LEN(&obj->history)))) {
ZVAL_OBJVAL(return_value, http_message_object_new_ex(http_message_object_ce, msg, NULL));
}
SET_EH_NORMAL();
* GET example:
* <pre>
* <?php
- * $r = new HttpRequest('http://example.com/feed.rss', HTTP_GET);
+ * $r = new HttpRequest('http://example.com/feed.rss', HttpRequest::METH_GET);
* $r->setOptions(array('lastmodified' => filemtime('local.rss')));
* $r->addQueryData(array('category' => 3));
* try {
* POST example:
* <pre>
* <?php
- * $r = new HttpRequest('http://example.com/form.php', HTTP_POST);
+ * $r = new HttpRequest('http://example.com/form.php', HttpRequest::METH_POST);
* $r->setOptions(array('cookies' => array('lang' => 'de')));
* $r->addPostFields(array('user' => 'mike', 'pass' => 's3c|r3t'));
* $r->addPostFile('image', 'profile.jpg', 'image/jpeg');
*/
PHP_METHOD(HttpRequest, send)
{
- http_request_body body = {0, NULL, 0};
getObject(http_request_object, obj);
NO_ARGS;
RETVAL_NULL();
- if ( (SUCCESS == http_request_object_requesthandler(obj, getThis(), &body)) &&
- (SUCCESS == http_request_exec(obj->ch, NULL, &obj->response, &obj->request)) &&
- (SUCCESS == http_request_object_responsehandler(obj, getThis()))) {
- RETVAL_OBJECT(GET_PROP(obj, responseMessage));
+ if (SUCCESS == http_request_object_requesthandler(obj, getThis())) {
+ http_request_exec(obj->request);
+ if (SUCCESS == http_request_object_responsehandler(obj, getThis())) {
+ RETVAL_OBJECT(GET_PROP(obj, responseMessage));
+ }
}
- http_request_body_dtor(&body);
SET_EH_NORMAL();
}