Skip to content

NSUrlSessionHandler might not always rewind HttpContent stream before sending #24162

@tipa

Description

@tipa

Apple platform

iOS

Framework version

net10.0-*

Affected platform version

.net10-rc2

Description

I have the suspicion that NSUrlSessionHandler not always sends the entire request body when re-sending the same HttpContent.

I started noticing that multipart uploads to Google Drive returned an BadRequest error with error message Invalid multipart request with 0 mime parts., but only when the same MultipartContent was re-sent after a first attempt failed with an error (e.g. timeout). What made me curious is that this only happened on Android and iOS, but not on macOS or Windows. After some investigation I noticed that on Android the AndroidMessageHandler did not correctly rewind the HttpContent stream before or after sending it, causing only parts of it being sent on the next attempt. I filed an issue about this here and started manually rewinding the HttpContent stream in my code before resending to workaround the issue. After adding this workaround, I did no longer see this error.

For iOS I was seeing this error way less often, but still 7 times in the last 30 days. It also only happened when re-sending the same MultipartContent after a previously failed request, which makes me think there is a similar bug in the NSUrlSessionHandler. At first glance, it does seem like the content is rewound before sending it (see below), but maybe there is some edge-case that causes a bug somewhere else in the implementation.

// Rewind the stream to the beginning in case the HttpContent implementation
// will be accessed again (e.g. for retry/redirect) and it keeps its stream open behind the scenes.
if (stream.CanSeek)
stream.Seek (0, SeekOrigin.Begin);

Steps to Reproduce

Unfortunately I was not able to reproduce this issue yet locally.
At least in one case the problem happened after the first sending attempt failed with The request was canceled due to the configured HttpClient.Timeout of 100 seconds elapsing.
What I noticed is that in all 7 occurrences in the last 30 days, the UIApplication.State was either Inactive (2x) or Background (5x). This could be coincidence, but I wanted to mention it since I remember there has been problems and workarounds in the past regarding NSUrlSessionHandler and backgrounding

Did you find any workaround?

Perhaps manually rewinding the stream before resending it could work just like on Android, but I have not yet tested this

Relevant logs

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    need-infoWaiting for more information before the bug can be investigatednetworkingIf an issue or pull request is related to networking

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions