Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

URLRequest equality doesn't include httpBody

Overview

There are 2 URLRequests, one with httpBody and one with no httpBody.
However when compared, it shows both are equal.

Question

Is this expected behaviour or am I missing something ?

Code

let url = URL(string: "www.somevalidURL.com")!

var r1 = URLRequest(url: url)
r1.addValue("Content-Type", forHTTPHeaderField: "application/json; charset=utf-8")
r1.httpBody = makeBody(withParameters: ["email" : "[email protected]"])

var r2 = URLRequest(url: url)
r2.addValue("Content-Type", forHTTPHeaderField: "application/json; charset=utf-8")

if r1 == r2 {
    print("requests are equal")
}
else {
    print("requests are not equal")
}

if r1.httpBody == r2.httpBody {
    print("body is equal")
}
else {
    print("body is not equal")
}

func makeBody(withParameters bodyParameters: [String : Any]?) -> Data? {
    guard let bodyParameters = bodyParameters,
        !bodyParameters.isEmpty else {
            return nil
    }
    let body : Data?
    do {
        body = try JSONSerialization.data(withJSONObject: bodyParameters,
                                          options: .prettyPrinted)
    }
    catch {
        print("Error in creating Web Service Body = \(error)")
        body = nil
    }
    return body
}

Output

requests are equal
body is not equal

Xcode 10
Swift Version: 4.2

like image 870
user1046037 Avatar asked Sep 21 '18 09:09

user1046037


People also ask

What is the difference between HTTP and urlrequest?

In addition, for HTTP and HTTPS requests, URLRequest includes the HTTP method ( GET, POST, and so on) and the HTTP headers. URLRequest only represents information about the request. Use other classes, such as URLSession, to send the request to a server.

Do HTTP requests have to have a body?

Yes. In other words, any HTTP request message is allowed to contain a message body, and thus must parse messages with that in mind. Server semantics for GET, however, are restricted such that a body, if any, has no semantic meaning to the request.

What is the difference between get and HTTP request?

In other words, any HTTP request message is allowed to contain a message body, and thus must parse messages with that in mind. Server semantics for GET, however, are restricted such that a body, if any, has no semantic meaning to the request.

Why can't I use the message body in a GET request?

The point is that, even if the message body is no longer forbidden by the HTTP spec, some client or server libraries or frameworks might still comply with the old spec and reject the message body from the GET request. Show activity on this post. GET, with a body!?


1 Answers

URLRequest is the Swift overlay type for the Foundation type NSURLRequest, so that that == ultimately calls the isEqual() method of the NSURLRequest.

The Foundation library is open source for non-Apple platforms, and at NSURLRequest.swift#L252 we find:

open override func isEqual(_ object: Any?) -> Bool {
    //On macOS this fields do not determine the result:
    //allHTTPHeaderFields
    //timeoutInterval
    //httBody
    //networkServiceType
    //httpShouldUsePipelining
    guard let other = object as? NSURLRequest else { return false }
    return other === self
        || (other.url == self.url
            && other.mainDocumentURL == self.mainDocumentURL
            && other.httpMethod == self.httpMethod
            && other.cachePolicy == self.cachePolicy
            && other.httpBodyStream == self.httpBodyStream
            && other.allowsCellularAccess == self.allowsCellularAccess
            && other.httpShouldHandleCookies == self.httpShouldHandleCookies)

So that seems to be intentional.

like image 181
Martin R Avatar answered Oct 04 '22 17:10

Martin R