2 +--------------------------------------------------------------------+
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the conditions mentioned |
7 | in the accompanying LICENSE file are met. |
8 +--------------------------------------------------------------------+
9 | Copyright (c) 2004-2007, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
15 #define HTTP_WANT_CURL
20 #include "php_http_api.h"
21 #include "php_http_url_api.h"
22 #include "php_http_request_body_api.h"
24 /* {{{ http_request_body *http_request_body_new() */
25 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
)
28 body
= emalloc_rel(sizeof(http_request_body
));
41 /* {{{ http_request_body *http_request_body_fill(http_request_body *body, HashTable *, HashTable *) */
42 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
)
44 if (files
&& (zend_hash_num_elements(files
) > 0)) {
45 HashKey key
= initHashKey(0);
48 struct curl_httppost
*http_post_data
[2] = {NULL
, NULL
};
52 FOREACH_HASH_KEYVAL(pos
, fields
, key
, data_ptr
) {
53 if (key
.type
== HASH_KEY_IS_STRING
) {
55 zval
*data
= http_zsep(IS_STRING
, *data_ptr
);
57 err
= curl_formadd(&http_post_data
[0], &http_post_data
[1],
58 CURLFORM_COPYNAME
, key
.str
,
59 CURLFORM_COPYCONTENTS
, Z_STRVAL_P(data
),
60 CURLFORM_CONTENTSLENGTH
, (long) Z_STRLEN_P(data
),
66 if (CURLE_OK
!= err
) {
67 http_error_ex(HE_WARNING
, HTTP_E_ENCODING
, "Could not encode post fields: %s", curl_easy_strerror(err
));
68 curl_formfree(http_post_data
[0]);
76 FOREACH_HASH_VAL(pos
, files
, data_ptr
) {
77 zval
**file_ptr
, **type_ptr
, **name_ptr
;
79 if (Z_TYPE_PP(data_ptr
) != IS_ARRAY
) {
80 http_error(HE_NOTICE
, HTTP_E_INVALID_PARAM
, "Unrecognized type of post file array entry");
81 } else if ( SUCCESS
!= zend_hash_find(Z_ARRVAL_PP(data_ptr
), "name", sizeof("name"), (void *) &name_ptr
) ||
82 SUCCESS
!= zend_hash_find(Z_ARRVAL_PP(data_ptr
), "type", sizeof("type"), (void *) &type_ptr
) ||
83 SUCCESS
!= zend_hash_find(Z_ARRVAL_PP(data_ptr
), "file", sizeof("file"), (void *) &file_ptr
)) {
84 http_error(HE_NOTICE
, HTTP_E_INVALID_PARAM
, "Post file array entry misses either 'name', 'type' or 'file' entry");
88 zval
*file
= http_zsep(IS_STRING
, *file_ptr
);
89 zval
*type
= http_zsep(IS_STRING
, *type_ptr
);
90 zval
*name
= http_zsep(IS_STRING
, *name_ptr
);
92 HTTP_CHECK_OPEN_BASEDIR(Z_STRVAL_P(file
), curl_formfree(http_post_data
[0]); return NULL
);
94 /* this is blatant but should be sufficient for most cases */
95 if (strncasecmp(Z_STRVAL_P(file
), "file://", lenof("file://"))) {
96 path
= Z_STRVAL_P(file
);
98 path
= Z_STRVAL_P(file
) + lenof("file://");
101 err
= curl_formadd(&http_post_data
[0], &http_post_data
[1],
102 CURLFORM_COPYNAME
, Z_STRVAL_P(name
),
104 CURLFORM_CONTENTTYPE
, Z_STRVAL_P(type
),
108 zval_ptr_dtor(&file
);
109 zval_ptr_dtor(&type
);
110 zval_ptr_dtor(&name
);
112 if (CURLE_OK
!= err
) {
113 http_error_ex(HE_WARNING
, HTTP_E_ENCODING
, "Could not encode post files: %s", curl_easy_strerror(err
));
114 curl_formfree(http_post_data
[0]);
120 return http_request_body_init_rel(body
, HTTP_REQUEST_BODY_CURLPOST
, http_post_data
[0], 0, 1);
126 if (SUCCESS
!= http_urlencode_hash_ex(fields
, 1, NULL
, 0, &encoded
, &encoded_len
)) {
127 http_error(HE_WARNING
, HTTP_E_ENCODING
, "Could not encode post data");
131 return http_request_body_init_rel(body
, HTTP_REQUEST_BODY_CSTRING
, encoded
, encoded_len
, 1);
133 return http_request_body_init_rel(body
, HTTP_REQUEST_BODY_CSTRING
, estrndup("", 0), 0, 1);
137 /* STATUS http_request_body_encode(http_request_body *, char**, size_t *) */
138 PHP_HTTP_API STATUS
_http_request_body_encode(http_request_body
*body
, char **buf
, size_t *len TSRMLS_DC
)
140 switch (body
->type
) {
141 case HTTP_REQUEST_BODY_CURLPOST
:
143 #ifdef HAVE_CURL_FORMGET
146 phpstr_init_ex(&str
, 0x8000, 0);
147 if (curl_formget(body
->data
, &str
, (curl_formget_callback
) phpstr_append
)) {
151 *buf
= PHPSTR_VAL(&str
);
152 *len
= PHPSTR_LEN(&str
);
159 case HTTP_REQUEST_BODY_CSTRING
:
160 *buf
= estrndup(body
->data
, *len
= body
->size
);
170 /* {{{ void http_request_body_dtor(http_request_body *) */
171 PHP_HTTP_API
void _http_request_body_dtor(http_request_body
*body TSRMLS_DC
)
175 switch (body
->type
) {
176 case HTTP_REQUEST_BODY_CSTRING
:
182 case HTTP_REQUEST_BODY_CURLPOST
:
183 curl_formfree(body
->data
);
186 case HTTP_REQUEST_BODY_UPLOADFILE
:
187 php_stream_close(body
->data
);
191 memset(body
, 0, sizeof(http_request_body
));
196 /* {{{ void http_request_body_free(http_request_body *) */
197 PHP_HTTP_API
void _http_request_body_free(http_request_body
**body TSRMLS_DC
)
200 http_request_body_dtor(*body
);
207 #endif /* HTTP_HAVE_CURL */
214 * vim600: noet sw=4 ts=4 fdm=marker
215 * vim<600: noet sw=4 ts=4