}
/* }}} */
-/* {{{ proto string http_build_url(mixed url[, mixed parts[, int flags = HTTP_URL_REPLACE[, array &new_url]]])
+/* {{{ proto string http_build_url([mixed url[, mixed parts[, int flags = HTTP_URL_REPLACE[, array &new_url]]]])
*
* Build an URL.
*
* <pre>
* - HTTP_URL_REPLACE: (default) set parts of the second url will replace the parts in the first
* - HTTP_URL_JOIN_PATH: the path of the second url will be merged into the one of the first
- * - HTTP_URL_JOIN_QUERY: the two querystrings will be merged naivly; no replacements are done
+ * - HTTP_URL_JOIN_QUERY: the two querystrings will be merged recursively
* - HTTP_URL_STRIP_USER: the user part will not appear in the result
* - HTTP_URL_STRIP_PASS: the password part will not appear in the result
* - HTTP_URL_STRIP_AUTH: neither the user nor the password part will appear in the result
zval *z_old_url = NULL, *z_new_url = NULL, *z_composed_url = NULL;
php_url *old_url = NULL, *new_url = NULL, *composed_url = NULL;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/|z/lz", &z_old_url, &z_new_url, &flags, &z_composed_url) != SUCCESS) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z/z/lz", &z_old_url, &z_new_url, &flags, &z_composed_url) != SUCCESS) {
RETURN_FALSE;
}
}
}
- if (Z_TYPE_P(z_old_url) == IS_ARRAY || Z_TYPE_P(z_old_url) == IS_OBJECT) {
- old_url = array2url(HASH_OF(z_old_url));
- } else {
- convert_to_string(z_old_url);
- if (!(old_url = php_url_parse_ex(Z_STRVAL_P(z_old_url), Z_STRLEN_P(z_old_url)))) {
- if (new_url) {
- php_url_free(new_url);
+ if (z_old_url) {
+ if (Z_TYPE_P(z_old_url) == IS_ARRAY || Z_TYPE_P(z_old_url) == IS_OBJECT) {
+ old_url = array2url(HASH_OF(z_old_url));
+ } else {
+ convert_to_string(z_old_url);
+ if (!(old_url = php_url_parse_ex(Z_STRVAL_P(z_old_url), Z_STRLEN_P(z_old_url)))) {
+ if (new_url) {
+ php_url_free(new_url);
+ }
+ http_error_ex(HE_WARNING, HTTP_E_URL, "Could not parse URL (%s)", Z_STRVAL_P(z_old_url));
+ RETURN_FALSE;
}
- http_error_ex(HE_WARNING, HTTP_E_URL, "Could not parse URL (%s)", Z_STRVAL_P(z_old_url));
- RETURN_FALSE;
}
}
if (new_url) {
php_url_free(new_url);
}
- php_url_free(old_url);
+ if (old_url) {
+ php_url_free(old_url);
+ }
RETURN_STRINGL(url_str, url_len, 0);
}
*/
PHP_FUNCTION(http_redirect)
{
- int url_len;
+ int url_len = 0;
size_t query_len = 0;
zend_bool session = 0, free_params = 0;
zval *params = NULL;
http_request_dtor(&request);
}
/* }}} */
+
+/* {{{ proto string http_request(int method, string url[, string body[, array options[, array &info]]])
+ *
+ * Performs a custom HTTP request on the supplied url.
+ *
+ * Expects the first parameter to be an integer specifying the request method to use.
+ * Accepts an optional third string parameter containing the raw request body.
+ * See http_get() for a full list of available options.
+ *
+ * Returns the HTTP response(s) as string on success, or FALSE on failure.
+ */
+PHP_FUNCTION(http_request)
+{
+ long meth;
+ char *URL, *data = NULL;
+ int URL_len, data_len = 0;
+ zval *options = NULL, *info = NULL;
+ http_request_body body;
+ http_request request;
+
+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls|sa/!z", &meth, &URL, &URL_len, &data, &data_len, &options, &info)) {
+ RETURN_FALSE;
+ }
+
+ if (info) {
+ zval_dtor(info);
+ array_init(info);
+ }
+
+ RETVAL_FALSE;
+
+ http_request_init_ex(&request, NULL, meth, URL);
+ request.body = http_request_body_init_ex(&body, HTTP_REQUEST_BODY_CSTRING, data, data_len, 0);
+ if (SUCCESS == http_request_prepare(&request, options?Z_ARRVAL_P(options):NULL)) {
+ http_request_exec(&request);
+ if (info) {
+ http_request_info(&request, Z_ARRVAL_P(info));
+ }
+ RETVAL_RESPONSE_OR_BODY(request);
+ }
+ http_request_dtor(&request);
+}
+/* }}} */
+
+static char *file_get_contents(char *file, size_t *len TSRMLS_DC)
+{
+ php_stream *s = NULL;
+ char *buf = NULL;
+
+ if ((s = php_stream_open_wrapper_ex(file, "rb", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL, HTTP_DEFAULT_STREAM_CONTEXT))) {
+ *len = php_stream_copy_to_mem(s, &buf, (size_t) -1, 0);
+ php_stream_close(s);
+ } else {
+ *len = 0;
+ }
+ return buf;
+}
+struct FormData {
+ struct FormData *next;
+ int type;
+ char *line;
+ size_t length;
+};
+CURLcode Curl_getFormData(struct FormData **, struct curl_httppost *post, curl_off_t *size);
+
+/* {{{ proto string http_request_body_encode(array fields, array files)
+ *
+ * Generate x-www-form-urlencoded resp. form-data encoded request body.
+ *
+ * Returns encoded string on success, or FALSE on failure.
+ */
+PHP_FUNCTION(http_request_body_encode)
+{
+ zval *fields = NULL, *files = NULL;
+ HashTable *fields_ht, *files_ht;
+ http_request_body body;
+ phpstr rbuf;
+ struct FormData *data, *ptr;
+ curl_off_t size;
+ char *fdata = NULL;
+ size_t fsize = 0;
+ CURLcode rc;
+ int fgc_error = 0;
+
+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a!a!", &fields, &files)) {
+ RETURN_FALSE;
+ }
+
+ fields_ht = (fields && Z_TYPE_P(fields) == IS_ARRAY) ? Z_ARRVAL_P(fields) : NULL;
+ files_ht = (files && Z_TYPE_P(files) == IS_ARRAY) ? Z_ARRVAL_P(files) : NULL;
+ if (!http_request_body_fill(&body, fields_ht, files_ht)) {
+ RETURN_FALSE;
+ }
+
+ switch (body.type)
+ {
+ case HTTP_REQUEST_BODY_CURLPOST:
+ if (CURLE_OK != (rc = Curl_getFormData(&data, body.data, &size))) {
+ http_error_ex(HE_WARNING, HTTP_E_RUNTIME, "Could not encode request body: %s", curl_easy_strerror(rc));
+ RETVAL_FALSE;
+ } else {
+ phpstr_init_ex(&rbuf, (size_t) size, PHPSTR_INIT_PREALLOC);
+ for (ptr = data; ptr; ptr = ptr->next) {
+ if (!fgc_error) {
+ if (ptr->type) {
+ if ((fdata = file_get_contents(ptr->line, &fsize TSRMLS_CC))) {
+ phpstr_append(&rbuf, fdata, fsize);
+ efree(fdata);
+ } else {
+ fgc_error = 1;
+ }
+ } else {
+ phpstr_append(&rbuf, ptr->line, ptr->length);
+ }
+ }
+ curl_free(ptr->line);
+ }
+ curl_free(data);
+ if (fgc_error) {
+ phpstr_dtor(&rbuf);
+ RETVAL_FALSE;
+ } else {
+ RETVAL_PHPSTR_VAL(&rbuf);
+ }
+ }
+ http_request_body_dtor(&body);
+ break;
+
+ case HTTP_REQUEST_BODY_CSTRING:
+ RETVAL_STRINGL(body.data, body.size, 0);
+ break;
+
+ default:
+ http_request_body_dtor(&body);
+ RETVAL_FALSE;
+ break;
+ }
+}
#endif /* HTTP_HAVE_CURL */
/* }}} HAVE_CURL */