Skip to content
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-2617] corelibs-foundation URLSession.dataTask() ignores httpBody #4447

Closed
swift-ci opened this issue Sep 12, 2016 · 10 comments
Closed

[SR-2617] corelibs-foundation URLSession.dataTask() ignores httpBody #4447

swift-ci opened this issue Sep 12, 2016 · 10 comments

Comments

@swift-ci
Copy link
Contributor

Previous ID SR-2617
Radar None
Original Reporter klassobanieras (JIRA User)
Type Bug
Status Resolved
Resolution Done
Environment

swift-3.0-GM-CANDIDATE
Ubuntu 14.04.5 LTS (GNU/Linux 4.4.0-34-generic x86_64)

Additional Detail from JIRA
Votes 1
Component/s Foundation
Labels Bug
Assignee seabaylea (JIRA)
Priority Medium

md5: 14dfeae41c1d30c4881bf7cdc79537be

Issue Description:

Sending a URLRequest with httpBody set, using URLSession.dataTask(), ignores the httpBody on Linux + corelibs-foundation. A body is only sent if passed directly to uploadTask().

The following illustrates the difference when run on Mac vs Linux:

import Foundation
import Dispatch

var req = URLRequest(url: URL(string: "http://httpbin.org/post")!)
req.httpMethod = "POST"
req.httpBody = "Hello! You should see me in the 'form' parameter of the result.".data(using: .utf8)

let sesh = URLSession(configuration: URLSessionConfiguration.default)

let dataTask = sesh.dataTask(with: req) { data, _, _ in
        print(String(data: data!, encoding: .utf8)!)
        exit(0)
}
dataTask.resume()
dispatchMain()
@swift-ci
Copy link
Contributor Author

Comment by Chris Bailey (JIRA)

The The call to URLSession.dataTask() creates a task with the following constructor:

URLSessionDataTask(session: self, request: r, taskIdentifier: i)
this in turn calls:

init(session: session, request: request, taskIdentifier: taskIdentifier, body: .none)
ie, we create a task with no body.

Its fairly straightforward to fix that - however it doesn't fix the overall test case due to a second problem - on Linux we fail to set the "Content-Type" header value to "application/x-www-form-urlencoded".

I'll raise a PR for the first part to try to get that in as quickly as possible. The second part can be temporarily worked around by setting the header value manually using:

req.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type" )

@swift-ci
Copy link
Contributor Author

Comment by Chris Bailey (JIRA)

I've raised PR 633:
#633

@swift-ci
Copy link
Contributor Author

Comment by Mike Ferenduros (JIRA)

Related: It looks like in Foundation, uploadTask(with: request, from: data) sends (data ?? request.httpBody) as the request body (although I can't derive this from the docs). Presumably the same applies to URL vs httpBodyStream ❓

@swift-ci
Copy link
Contributor Author

Comment by Chris Bailey (JIRA)

Are you referring to
open func uploadTask(with request: URLRequest, from bodyData: Data?, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Swift.Void) -> URLSessionUploadTask

That looks like the only point that Data is an optional, where yes we could fall back to request.httpBody (which it doesn't today.

@swift-ci
Copy link
Contributor Author

Comment by Mike Ferenduros (JIRA)

Yep, thats the one.

Would it be useful for me to flesh out the tests with this stuff, and some more validations against httpbin.org for things like auth, redirection etc?

@swift-ci
Copy link
Contributor Author

Comment by Chris Bailey (JIRA)

Absolutely - at the moment the tests we have are somewhat limited, so anything you can provide would be hugely valuable.

@swift-ci
Copy link
Contributor Author

Comment by Mike Ferenduros (JIRA)

Cool 🙂

Working on it here:
https://github.com/mike-ferenduros/swift-corelibs-foundation/tree/more-urlsession-tests (NB: untested on Linux)

It's pretty early but I hit a few issues:

  • 302 redirects are apparently misinterpreting the 'Location' header and hence failing

  • The redirect delegate method is getting called after the response is delivered, which I think contradicts the docs (although it's woolly)

  • No basic or digest auth

@swift-ci
Copy link
Contributor Author

Comment by Andrey Fidrya (JIRA)

Copying from PR 633:
In some situations httpBody is still not sent. Below is the code which reproduces the issue. If "Content-Type" line is uncommented, second dataTask won't send httpBody:

import Foundation
import Dispatch

var req = URLRequest(url: URL(string: "http://httpbin.org/post")!)
req.httpMethod = "POST"
req.httpBody = "a=b&c=d".data(using: .utf8)
//req.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")

let sesh = URLSession(configuration: URLSessionConfiguration.default)

let dataTask1 = sesh.dataTask(with: req) { data, _, _ in
            print(String(data: data!, encoding: .utf8)!)
}
dataTask1.resume()

let dataTask2 = sesh.dataTask(with: req) { data, _, _ in
            print(String(data: data!, encoding: .utf8)!)
}
dataTask2.resume()

dispatchMain()

@swift-ci
Copy link
Contributor Author

Comment by sai Hema k (JIRA)

klassobanieras (JIRA User) This issue seems to be fixed now.Can you please verify and close this ?

@spevans
Copy link
Collaborator

spevans commented Mar 13, 2020

Tested as working on both swift 4.2 and 5.1.4

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@shahmishal shahmishal transferred this issue from apple/swift May 5, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants