X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=http_request_body_api.c;h=bc1648cb97cd091c05629a573b3f51e42f8ba83b;hp=fcaa635d00f54603a9ba1c820aa944e70427cef1;hb=0e0def98a4ea4463bf8c21c6f161b2b37aa8c49d;hpb=669d2e6a8bdc642b6b52693f4593f199ddd7e8d2 diff --git a/http_request_body_api.c b/http_request_body_api.c index fcaa635..bc1648c 100644 --- a/http_request_body_api.c +++ b/http_request_body_api.c @@ -21,6 +21,63 @@ #include "php_http_url_api.h" #include "php_http_request_body_api.h" +#if defined(HAVE_CURL_GETFORMDATA) && !defined(HAVE_CURL_FORMGET) +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); + +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; +} + +static int curl_formget(struct FormData *post, phpstr *str TSRMLS_DC) +{ + int fgc_error = 0; + char *fdata; + size_t fsize; + struct FormData *next, *pptr = post; + + while (pptr) { + next = pptr->next; + + if (!fgc_error) { + if (pptr->type) { + if ((fdata = file_get_contents(pptr->line, &fsize TSRMLS_CC))) { + phpstr_append(str, fdata, fsize); + efree(fdata); + } else { + fgc_error = 1; + } + } else { + phpstr_append(str, pptr->line, pptr->length); + } + } + + curl_free(pptr->line); + curl_free(pptr); + pptr = next; + } + + return fgc_error; +} +#endif + + /* {{{ http_request_body *http_request_body_new() */ PHP_HTTP_API http_request_body *_http_request_body_init_ex(http_request_body *body, int type, void *data, size_t size, zend_bool free ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC) { @@ -42,22 +99,21 @@ PHP_HTTP_API http_request_body *_http_request_body_init_ex(http_request_body *bo PHP_HTTP_API http_request_body *_http_request_body_fill(http_request_body *body, HashTable *fields, HashTable *files ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC) { if (files && (zend_hash_num_elements(files) > 0)) { - char *key = NULL; - ulong idx; + HashKey key = initHashKey(0); zval **data; HashPosition pos; struct curl_httppost *http_post_data[2] = {NULL, NULL}; /* normal data */ if (fields) { - FOREACH_HASH_KEYVAL(pos, fields, key, idx, data) { - if (key) { + FOREACH_HASH_KEYVAL(pos, fields, key, data) { + if (key.type == HASH_KEY_IS_STRING) { CURLcode err; zval *orig = *data; convert_to_string_ex(data); err = curl_formadd(&http_post_data[0], &http_post_data[1], - CURLFORM_COPYNAME, key, + CURLFORM_COPYNAME, key.str, CURLFORM_COPYCONTENTS, Z_STRVAL_PP(data), CURLFORM_CONTENTSLENGTH, (long) Z_STRLEN_PP(data), CURLFORM_END @@ -72,9 +128,6 @@ PHP_HTTP_API http_request_body *_http_request_body_fill(http_request_body *body, curl_formfree(http_post_data[0]); return NULL; } - - /* reset */ - key = NULL; } } } @@ -143,27 +196,75 @@ PHP_HTTP_API http_request_body *_http_request_body_fill(http_request_body *body, } } +/* STATUS http_request_body_encode(http_request_body *, char**, size_t *) */ +PHP_HTTP_API STATUS _http_request_body_encode(http_request_body *body, char **buf, size_t *len TSRMLS_DC) +{ + switch (body->type) { + case HTTP_REQUEST_BODY_CURLPOST: + { +#if defined(HAVE_CURL_FORMGET) + phpstr str; + + phpstr_init_ex(&str, 0x8000, 0); + if (curl_formget(body->data, &str, (curl_formget_callback) phpstr_append)) { + phpstr_dtor(&str); + } else { + phpstr_fix(&str); + *buf = PHPSTR_VAL(&str); + *len = PHPSTR_LEN(&str); + return SUCCESS; + } +#elif defined(HAVE_CURL_GETFORMDATA) + struct FormData *data; + curl_off_t size; + + if (!Curl_getFormData(&data, body->data, &size)) { + phpstr str; + + phpstr_init_ex(&str, (size_t) size, 0); + if (curl_formget(data, &str TSRMLS_CC)) { + phpstr_dtor(&str); + } else { + phpstr_fix(&str); + *buf = PHPSTR_VAL(&str); + *len = PHPSTR_LEN(&len); + return SUCCESS; + } + } +#endif + break; + } + + case HTTP_REQUEST_BODY_CSTRING: + *buf = estrndup(body->data, *len = body->size); + return SUCCESS; + + default: + break; + } + return FAILURE; +} +/* }}} */ /* {{{ void http_request_body_dtor(http_request_body *) */ PHP_HTTP_API void _http_request_body_dtor(http_request_body *body TSRMLS_DC) { if (body) { if (body->free) { - switch (body->type) - { + switch (body->type) { case HTTP_REQUEST_BODY_CSTRING: if (body->data) { efree(body->data); } - break; + break; case HTTP_REQUEST_BODY_CURLPOST: curl_formfree(body->data); - break; + break; case HTTP_REQUEST_BODY_UPLOADFILE: php_stream_close(body->data); - break; + break; } } memset(body, 0, sizeof(http_request_body));