提交 357b34e3 编写于 作者: C Christian Noon

Added percent escaping tests around reserved / unreserved / illegal characters.

上级 12528b6c
......@@ -150,8 +150,40 @@ public enum ParameterEncoding {
return components
}
/**
Returns a percent escaped string following RFC 3986 for query string formatting.
RFC 3986 states that the following characters are "reserved" characters.
- General Delimiters: ":", "#", "[", "]", "@", "?", "/"
- Sub-Delimiters: "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "="
Core Foundation interprets RFC 3986 in terms of legal and illegal characters.
- Legal Numbers: "0123456789"
- Legal Letters: "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- Legal Characters: "!", "$", "&", "'", "(", ")", "*", "+", ",", "-",
".", "/", ":", ";", "=", "?", "@", "_", "~", "\""
- Illegal Characters: All characters not listed as Legal
While the Core Foundation `CFURLCreateStringByAddingPercentEscapes` documentation states
that it follows RFC 3986, the headers actually point out that it follows RFC 2396. This
explains why it does not consider "[", "]" and "#" to be "legal" characters even though
they are specified as "reserved" characters in RFC 3986. The following rdar has been filed
to hopefully get the documentation updated.
- https://openradar.appspot.com/radar?id=5058257274011648
In RFC 3986 - Section 3.4, it states that the "?" and "/" characters should not be escaped to allow
query strings to include a URL. Therefore, all "reserved" characters with the exception of "?" and "/"
should be percent escaped in the query string.
:param: string The string to be percent escaped.
:returns: The percent escaped string.
*/
func escape(string: String) -> String {
let generalDelimiters = ":#[]@" // dropping "?" and "/" due to RFC 3986 - Section 3.4
let generalDelimiters = ":#[]@" // does not include "?" or "/" due to RFC 3986 - Section 3.4
let subDelimiters = "!$&'()*+,;="
let legalURLCharactersToBeEscaped: CFStringRef = generalDelimiters + subDelimiters
......
......@@ -30,15 +30,12 @@ class ParameterEncodingTestCase: BaseTestCase {
// MARK: -
/**
The URL parameter encoding tests cover a variety of cases for encoding query parameters in addition to percent escaping reserved characters. The percent escaping implementation follows RFC 3986 - Sections 2.2, 2.4 and 3.4. All reserved characters are percent encoded with the exception of the "?" and "/" characters. This exception was made to allow other URIs to be included as query parameters without issue. See RFC 3986 - Section 3.4 for more details.
*/
class URLParameterEncodingTestCase: ParameterEncodingTestCase {
// MARK: Properties
let encoding: ParameterEncoding = .URL
// MARK: Tests
// MARK: Tests - Parameter Types
func testURLParameterEncodeNilParameters() {
// Given
......@@ -164,6 +161,78 @@ class URLParameterEncodingTestCase: ParameterEncodingTestCase {
XCTAssertEqual(URLRequest.URL?.query ?? "", "foo%5Bbar%5D%5Bbaz%5D%5B%5D=a&foo%5Bbar%5D%5Bbaz%5D%5B%5D=1&foo%5Bbar%5D%5Bbaz%5D%5B%5D=1", "query is incorrect")
}
// MARK: Tests - All Reserved / Unreserved / Illegal Characters According to RFC 3986
func testThatReservedCharactersArePercentEscapedMinusQuestionMarkAndForwardSlash() {
// Given
let generalDelimiters = ":#[]@"
let subDelimiters = "!$&'()*+,;="
let parameters = ["reserved": "\(generalDelimiters)\(subDelimiters)"]
// When
let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: parameters)
// Then
XCTAssertEqual(URLRequest.URL?.query ?? "", "reserved=%3A%23%5B%5D%40%21%24%26%27%28%29%2A%2B%2C%3B%3D", "query is incorrect")
}
func testThatReservedCharactersQuestionMarkAndForwardSlashAreNotPercentEscaped() {
// Given
let parameters = ["reserved": "?/"]
// When
let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: parameters)
// Then
XCTAssertEqual(URLRequest.URL?.query ?? "", "reserved=?/", "query is incorrect")
}
func testThatUnreservedNumericCharactersAreNotPercentEscaped() {
// Given
let parameters = ["numbers": "0123456789"]
// When
let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: parameters)
// Then
XCTAssertEqual(URLRequest.URL?.query ?? "", "numbers=0123456789", "query is incorrect")
}
func testThatUnreservedLowercaseCharactersAreNotPercentEscaped() {
// Given
let parameters = ["lowercase": "abcdefghijklmnopqrstuvwxyz"]
// When
let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: parameters)
// Then
XCTAssertEqual(URLRequest.URL?.query ?? "", "lowercase=abcdefghijklmnopqrstuvwxyz", "query is incorrect")
}
func testThatUnreservedUppercaseCharactersAreNotPercentEscaped() {
// Given
let parameters = ["uppercase": "ABCDEFGHIJKLMNOPQRSTUVWXYZ"]
// When
let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: parameters)
// Then
XCTAssertEqual(URLRequest.URL?.query ?? "", "uppercase=ABCDEFGHIJKLMNOPQRSTUVWXYZ", "query is incorrect")
}
func testThatIllegalASCIICharactersArePercentEscaped() {
// Given
let parameters = ["illegal": " \"#%<>[]\\^`{}|"]
// When
let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: parameters)
// Then
XCTAssertEqual(URLRequest.URL?.query ?? "", "illegal=%20%22%23%25%3C%3E%5B%5D%5C%5E%60%7B%7D%7C", "query is incorrect")
}
// MARK: Tests - Special Character Queries
func testURLParameterEncodeStringWithAmpersandKeyStringWithAmpersandValueParameter() {
// Given
let parameters = ["foo&bar": "baz&qux", "foobar": "bazqux"]
......@@ -219,17 +288,6 @@ class URLParameterEncodingTestCase: ParameterEncodingTestCase {
XCTAssertEqual(URLRequest.URL?.query ?? "", "%2Bfoo%2B=%2Bbar%2B", "query is incorrect")
}
func testURLParameterEncodeStringKeyAllowedCharactersStringValueParameter() {
// Given
let parameters = ["allowed": " =\"#%<>@\\^`{}[]|&"]
// When
let (URLRequest, error) = self.encoding.encode(self.URLRequest, parameters: parameters)
// Then
XCTAssertEqual(URLRequest.URL?.query ?? "", "allowed=%20%3D%22%23%25%3C%3E%40%5C%5E%60%7B%7D%5B%5D%7C%26", "query is incorrect")
}
func testURLParameterEncodeStringKeyPercentEncodedStringValueParameter() {
// Given
let parameters = ["percent": "%25"]
......@@ -281,6 +339,8 @@ class URLParameterEncodingTestCase: ParameterEncodingTestCase {
XCTAssertEqual(URLRequest.URL?.query ?? "", "hd=%5B1%5D&%2Bfoo%2B=%2Bbar%2B", "query is incorrect")
}
// MARK: Tests - Varying HTTP Methods
func testURLParameterEncodeGETParametersInURL() {
// Given
var mutableURLRequest = self.URLRequest.mutableCopy() as! NSMutableURLRequest
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册