Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[HttpClient] Support file uploads by nesting resource streams inbody option#49911

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
fabpot merged 1 commit intosymfony:6.3fromnicolas-grekas:hc-multipart
Apr 20, 2023

Conversation

nicolas-grekas
Copy link
Member

QA
Branch?6.3
Bug fix?no
New feature?yes
Deprecations?no
Tickets-
LicenseMIT
Doc PR-

This PR makes it easy to upload files usingmultipart/form-data.

Nesting streams in option "body" is all one needs to do:

$h =fopen('/path/to/the/file' 'r');$client->request('POST','https://...', ['body' => ['the_file' =>$h]]);

By default, the code will populate thefilename using the base-name of the opened file.
It's possible to override this by callingstream_context_set_option($h, 'http', 'filename', 'the-name.txt').

When forwarding an HTTP request coming either from the nativehttp stream wrapper or from Symfony'sStreamableInterface, the code will forward the content-type. It's also possible to set the content-type usingstream_context_set_option($h, 'http', 'content_type', 'my/content-type').

When possible, the code will generate aContent-Length header. This enables the destination server to reject the request early if it's too big and it allows tracking the progress of uploads on the client-side.

Renrhaf reacted with hooray emojilyrixx, ajgarlag, and Renrhaf reacted with heart emoji
@carsonbotcarsonbot added this to the6.3 milestoneApr 3, 2023
@nicolas-grekasnicolas-grekasforce-pushed thehc-multipart branch 5 times, most recently frome485a34 to45f3844CompareApril 3, 2023 14:37
@OskarStarkOskarStark changed the title[HttpClient] Support file uploads by nesting resource streams in option "body"[HttpClient] Support file uploads by nesting resource streams inbody optionApr 6, 2023
@nicolas-grekasnicolas-grekasforce-pushed thehc-multipart branch 2 times, most recently from6f4b407 toc9c47ddCompareApril 7, 2023 14:42
{
if (\is_array($body)) {
array_walk_recursive($body, $caster = static function (&$v) use (&$caster) {
if (\is_object($v)) {
static $cookie;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

why is this a static variable instead of a local variable ? Do we really need a hidden global state here ?

Copy link
MemberAuthor

@nicolas-grekasnicolas-grekasApr 20, 2023
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

We need this to generate a random boundary without consuming too much entropy from the system.
We don't care about the hidden state because this is just a random string that is updated after use.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I'm not against using a variable. But it could be a normal one, so that each call toprepareBody is independant.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Or you should not reuse that cookie when generating the multipart boundary that is visible to the outside.

Copy link
MemberAuthor

@nicolas-grekasnicolas-grekasApr 20, 2023
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Each call is already independent from the previous one thanks to the randomization provided by thexxh128 hashing.
I don't want to callrandom_bytes all the time.

foreach ($body as [$k, $part, $h]) {
yield $part;

while (null !== $h && !feof($h)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

shouldn't we close the resource once we are done reading it ? Due to the async nature of the component, it would be very hard to keep the ownership of the resource in the caller code while avoiding to close it too early (it must not be closed until http-client is done with it).
Guzzle has a feature allowing to create a body from a stream, and it takes ownership of the resource for such reason.

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I'd prefer not. The current code allows the outer scope to rewind the stream if needed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

but how do you handle closing those streams to avoid leaking them ?

Copy link
MemberAuthor

@nicolas-grekasnicolas-grekasApr 20, 2023
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I addedunset($body[$i]); and$h = null at the end of the generator. Stream resources are auto-closed by PHP when released from memory.

@nicolas-grekasnicolas-grekasforce-pushed thehc-multipart branch 4 times, most recently from29b0c79 tob6e6d17CompareApril 20, 2023 12:55
nicolas-grekas added a commit that referenced this pull requestApr 20, 2023
…t instances from working together (nicolas-grekas)This PR was merged into the 5.4 branch.Discussion----------[HttpClient] Fix global state preventing two CurlHttpClient instances from working together| Q             | A| ------------- | ---| Branch?       | 5.4| Bug fix?      | yes| New feature?  | no| Deprecations? | no| Tickets       | Fix -| License       | MIT| Doc PR        | -Spotted while working on#49911Commits-------200027c [HttpClient] Fix global state preventing two CurlHttpClient instances from working together
@fabpot
Copy link
Member

Thank you@nicolas-grekas.

@fabpotfabpot merged commite957514 intosymfony:6.3Apr 20, 2023
@nicolas-grekasnicolas-grekas deleted the hc-multipart branchApril 20, 2023 14:55
nicolas-grekas added a commit that referenced this pull requestFeb 13, 2025
…body is empty (nicolas-grekas)This PR was merged into the 6.4 branch.Discussion----------[HttpClient] Don't send any default content-type when the body is empty| Q             | A| ------------- | ---| Branch?       | 6.4| Bug fix?      | yes| New feature?  | no| Deprecations? | no| Issues        | -| License       | MITIssue was introduced in#49911Commits-------4a475e0 [HttpClient] Don't send any default content-type when the body is empty
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@stofstofstof approved these changes

Assignees
No one assigned
Projects
None yet
Milestone
6.3
Development

Successfully merging this pull request may close these issues.

4 participants
@nicolas-grekas@fabpot@stof@carsonbot

[8]ページ先頭

©2009-2025 Movatter.jp