Browse Source

[PR #2047] Added missing charset to the JSONEncoding encode API.

The charset is needed to make sure, that the server uses the correct charset for decoding. This in necessary since JSON can be encoded in various forms of unicode.

RFC 7158 - Section 8.1:

JSON text SHALL be encoded in UTF-8, UTF-16, or UTF-32.  The default encoding is UTF-8, and JSON texts that are encoded in UTF-8 are interoperable in the sense that they will be read successfully by the maximum number of implementations; there are many implementations that cannot successfully read texts in other encodings (such as UTF-16 and UTF-32).
Laurenz Lazarus 8 years ago
parent
commit
c8700ac7ea

+ 3 - 3
Source/ParameterEncoding.swift

@@ -267,7 +267,7 @@ public struct URLEncoding: ParameterEncoding {
 // MARK: -
 // MARK: -
 
 
 /// Uses `JSONSerialization` to create a JSON representation of the parameters object, which is set as the body of the
 /// Uses `JSONSerialization` to create a JSON representation of the parameters object, which is set as the body of the
-/// request. The `Content-Type` HTTP header field of an encoded request is set to `application/json`.
+/// request. The `Content-Type` HTTP header field of an encoded request is set to `application/json; charset=utf-8`.
 public struct JSONEncoding: ParameterEncoding {
 public struct JSONEncoding: ParameterEncoding {
 
 
     // MARK: Properties
     // MARK: Properties
@@ -311,7 +311,7 @@ public struct JSONEncoding: ParameterEncoding {
             let data = try JSONSerialization.data(withJSONObject: parameters, options: options)
             let data = try JSONSerialization.data(withJSONObject: parameters, options: options)
 
 
             if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil {
             if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil {
-                urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
+                urlRequest.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
             }
             }
 
 
             urlRequest.httpBody = data
             urlRequest.httpBody = data
@@ -339,7 +339,7 @@ public struct JSONEncoding: ParameterEncoding {
             let data = try JSONSerialization.data(withJSONObject: jsonObject, options: options)
             let data = try JSONSerialization.data(withJSONObject: jsonObject, options: options)
 
 
             if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil {
             if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil {
-                urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
+                urlRequest.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
             }
             }
 
 
             urlRequest.httpBody = data
             urlRequest.httpBody = data

+ 2 - 2
Tests/ParameterEncodingTests.swift

@@ -631,7 +631,7 @@ class JSONParameterEncodingTestCase: ParameterEncodingTestCase {
             // Then
             // Then
             XCTAssertNil(URLRequest.url?.query)
             XCTAssertNil(URLRequest.url?.query)
             XCTAssertNotNil(URLRequest.value(forHTTPHeaderField: "Content-Type"))
             XCTAssertNotNil(URLRequest.value(forHTTPHeaderField: "Content-Type"))
-            XCTAssertEqual(URLRequest.value(forHTTPHeaderField: "Content-Type"), "application/json")
+            XCTAssertEqual(URLRequest.value(forHTTPHeaderField: "Content-Type"), "application/json; charset=utf-8")
             XCTAssertNotNil(URLRequest.httpBody)
             XCTAssertNotNil(URLRequest.httpBody)
 
 
             if let httpBody = URLRequest.httpBody {
             if let httpBody = URLRequest.httpBody {
@@ -663,7 +663,7 @@ class JSONParameterEncodingTestCase: ParameterEncodingTestCase {
             // Then
             // Then
             XCTAssertNil(URLRequest.url?.query)
             XCTAssertNil(URLRequest.url?.query)
             XCTAssertNotNil(URLRequest.value(forHTTPHeaderField: "Content-Type"))
             XCTAssertNotNil(URLRequest.value(forHTTPHeaderField: "Content-Type"))
-            XCTAssertEqual(URLRequest.value(forHTTPHeaderField: "Content-Type"), "application/json")
+            XCTAssertEqual(URLRequest.value(forHTTPHeaderField: "Content-Type"), "application/json; charset=utf-8")
             XCTAssertNotNil(URLRequest.httpBody)
             XCTAssertNotNil(URLRequest.httpBody)
 
 
             if let httpBody = URLRequest.httpBody {
             if let httpBody = URLRequest.httpBody {

+ 1 - 1
Tests/RequestTests.swift

@@ -581,7 +581,7 @@ class RequestDebugDescriptionTestCase: BaseTestCase {
         XCTAssertEqual(components[0..<3], ["$", "curl", "-i"])
         XCTAssertEqual(components[0..<3], ["$", "curl", "-i"])
         XCTAssertEqual(components[3..<5], ["-X", "POST"])
         XCTAssertEqual(components[3..<5], ["-X", "POST"])
 
 
-        XCTAssertNotNil(request.debugDescription.range(of: "-H \"Content-Type: application/json\""))
+        XCTAssertNotNil(request.debugDescription.range(of: "-H \"Content-Type: application/json; charset=utf-8\""))
         XCTAssertNotNil(request.debugDescription.range(of: "-d \"{"))
         XCTAssertNotNil(request.debugDescription.range(of: "-d \"{"))
         XCTAssertNotNil(request.debugDescription.range(of: "\\\"f'oo\\\":\\\"ba'r\\\""))
         XCTAssertNotNil(request.debugDescription.range(of: "\\\"f'oo\\\":\\\"ba'r\\\""))
         XCTAssertNotNil(request.debugDescription.range(of: "\\\"fo\\\\\\\"o\\\":\\\"b\\\\\\\"ar\\\""))
         XCTAssertNotNil(request.debugDescription.range(of: "\\\"fo\\\\\\\"o\\\":\\\"b\\\\\\\"ar\\\""))

+ 4 - 4
Tests/ValidationTests.swift

@@ -158,8 +158,8 @@ class ContentTypeValidationTestCase: BaseTestCase {
         // When
         // When
         Alamofire.request(urlString)
         Alamofire.request(urlString)
             .validate(contentType: ["application/json"])
             .validate(contentType: ["application/json"])
-            .validate(contentType: ["application/json;charset=utf8"])
-            .validate(contentType: ["application/json;q=0.8;charset=utf8"])
+            .validate(contentType: ["application/json; charset=utf-8"])
+            .validate(contentType: ["application/json; q=0.8; charset=utf-8"])
             .response { resp in
             .response { resp in
                 requestError = resp.error
                 requestError = resp.error
                 expectation1.fulfill()
                 expectation1.fulfill()
@@ -167,8 +167,8 @@ class ContentTypeValidationTestCase: BaseTestCase {
 
 
         Alamofire.download(urlString)
         Alamofire.download(urlString)
             .validate(contentType: ["application/json"])
             .validate(contentType: ["application/json"])
-            .validate(contentType: ["application/json;charset=utf8"])
-            .validate(contentType: ["application/json;q=0.8;charset=utf8"])
+            .validate(contentType: ["application/json; charset=utf-8"])
+            .validate(contentType: ["application/json; q=0.8; charset=utf-8"])
             .response { resp in
             .response { resp in
                 downloadError = resp.error
                 downloadError = resp.error
                 expectation2.fulfill()
                 expectation2.fulfill()