Send files in CURL from string

php.internals

Александр Москалёв

10 years ago
Hello! I have idea to make possible to send files with CURL from string. CURL library has few options to make it as easy as possible: CURLFORM_BUFFER, CURLFORM_BUFFERPTR, and CURLFORM_BUFFERLENGTH. But I got many problems with integration of this feature in current php curl file attachment design. Class CURLFile has one required $filename property, and two optional properties $mimetype and $postname. In my case we need two required properties $buffer and $postname, and one optional $mimetype. Also we have function curl_file_create, which just like alias function for CURLFile constructor with same arguments. So I tried to implement feature by different ways: 1) Create new class CURLFileBuffer by simple copy-paste code from CURLFile. (pull-request https://github.com/php/php-src/pull/1217 - code was removed, sorry) positive: - No BC break - API similar to CURLFile negative: - A lot of code duplication, hard to support in future. Thanks to Tony2001 and S.Malyshev for reviewing. 2) Integrate new feature to exists CURLFile class. (pull-request https://github.com/php/php-src/pull/1283) positive: - One class for new and old features - No code duplication - No BC break (* except some little not obviously cases) negative: - Not clear behavior if developer will set $filename and $buffer in same time. It require more documentation and not obviously for developers. - Not clear which values of $filename we must ignore to start use $buffer. - etc. Thanks to S.Malyshev for reviewing. 3) Like #2, but make CURLFile immutable after instance creation by curl_file_create and curl_file_buffer_create functions (or by little modified constructors). positive: - Clear behavior. negative: - Great BC break: CURLFile has public properties and setters methods. I like it, I think it will be great to make CURLFile immutable, but I'm sure no one want such BC. =( 4) Like #1, but move code duplication to common C code, used by two classes. It's impossible, because this classes so simple, so 95% of code like that:
>
/* {{{ proto string CURLFile::getFilename() Get file name */ ZEND_METHOD(CURLFile, getFilename) { curlfile_get_property("name", INTERNAL_FUNCTION_PARAM_PASSTHRU); } /* }}} */ So both classes required such doc block ({{{ proto ...) and call *_property methods. 5) Like #1, but move code duplication to abstract class, for example CURLFileAbstract. So we move $mimetype and $postname to abstract class, $filename to CURLFile, $buffer to CURLFileBuffer class. They will have own constructors with own arguments requiring. positive: - No BC break - less code duplication negative: - new abstract class, used ONLY for less code duplication in curl extension, it has no sense for developers. 6+) Your variant, please provide it. As you can see, so little change, like using few simple options from curl library, require so long mail, few pull-requests and too many time from internal php people. But I believe, we can do it. Thank you, and please help me to finish this small feature.
-- With regards, Alexander Moskalev irker@irker.net irker@php.net a.moskalev@corp.badoo.com

Александр Москалёв

10 years ago
Sorry for annoying mail, but it's really small and simple feature, which can be implemented by few lines of curl options. But with API realisation questions. Please, help me to choose correct way, and I will create new pull-request with code and tests.

Davey

10 years ago
On Tue, Jun 21, 2016 at 11:38 AM, Alexander Moskalev <irker@irker.net> wrote:
> Sorry for annoying mail, but it's really small and simple feature, which > can be implemented by few lines of curl options. But with API realisation > questions. > Please, help me to choose correct way, and I will create new pull-request > with code and tests. >
Hi Alexander, Thank you for this — I wonder if it's possible to make it so that you can pass a filename, or a valid stream (or stream URL) to CURLFile — this would solve the issue, as you can use a memory stream, have no extra classes, no ambiguity of "is it a filename" vs "is it a string of data". Thoughts? - Davey

Александр Москалёв

10 years ago
Thank you! 2016-06-21 23:31 GMT+03:00 Davey Shafik <davey@php.net>:
> you can use a memory stream
I thought about something like that. But if we created memory stream (php://memory ?), we have file pointer resource related to this stream. And we cannot read or write something in this stream without such file pointer provided. Example code:
> > $fp = fopen("php://memory", 'r+'); > fputs($fp, "foo\n"); > rewind($fp); > echo file_get_contents("php://memory"); // <- this doesn't work, and same > will be in curl. > echo stream_get_contents($fp); //<- this will work
Or you mean something else?
-- With regards, Alexander Moskalev irker@irker.net irker@php.net a.moskalev@corp.badoo.com

Davey

10 years ago
On Tue, Jun 21, 2016 at 2:28 PM, Alexander Moskalev <irker@irker.net> wrote:
> Thank you! > > 2016-06-21 23:31 GMT+03:00 Davey Shafik <davey@php.net>: > >> you can use a memory stream > > I thought about something like that. But if we created memory stream > (php://memory ?), we have file pointer resource related to this stream. And > we cannot read or write something in this stream without such file pointer > provided. > > Example code: >> >> $fp = fopen("php://memory", 'r+'); >> fputs($fp, "foo\n"); >> rewind($fp); >> echo file_get_contents("php://memory"); // <- this doesn't work, and same >> will be in curl. >> echo stream_get_contents($fp); //<- this will work > > > > Or you mean something else? >
In this one case, you would be _required_ to pass in the stream handle in. All other cases would work with either the resource URL (e.g. s3://<path>) or a stream handle. - Davey

Александр Москалёв

10 years ago
Ok, thank you! Not sure if it the best solution, but it will work. So, 6) make possible to work with file pointer and stream URL in $filename option. positive: - no code duplicates - no BC brake negative: - misleading in property name: getFileName method, $name property etc.
-- With regards, Alexander Moskalev irker@irker.net irker@php.net a.moskalev@corp.badoo.com

Александр Москалёв

10 years ago
Last try to highlight this thread
-- With regards, Alexander Moskalev irker@irker.net irker@php.net a.moskalev@corp.badoo.com