Don't join Set-Cookie headers together

This commit is contained in:
Cory Benfield 2017-10-09 10:37:13 -07:00
parent cdfa66d081
commit 47ac46bbe3
3 changed files with 53 additions and 11 deletions

View File

@ -149,6 +149,17 @@ public struct HTTPHeaders : Sequence, CustomStringConvertible {
func write(buffer: inout ByteBuffer) {
for (key, values) in storage {
if key != "set-cookie" {
writeListHeaderValues(buffer: &buffer, key: key, values: values)
} else {
writeSequentialHeaderValues(buffer: &buffer, key: key, values: values)
}
}
buffer.write(staticString: crlf)
}
/// Used for most HTTP headers, which can be represented as a single line joined by commas.
private func writeListHeaderValues(buffer: inout ByteBuffer, key: String, values: [(String, String)]) {
buffer.write(string: key)
buffer.write(staticString: headerSeparator)
@ -162,8 +173,16 @@ public struct HTTPHeaders : Sequence, CustomStringConvertible {
buffer.moveWriterIndex(to: writerIndex)
buffer.write(staticString: crlf)
}
/// Used for HTTP headers that cannot be joined with commas, e.g. set-cookie.
private func writeSequentialHeaderValues(buffer: inout ByteBuffer, key: String, values: [(String, String)]) {
for (_, value) in values {
buffer.write(string: key)
buffer.write(staticString: headerSeparator)
buffer.write(string: value)
buffer.write(staticString: crlf)
}
}
public func makeIterator() -> AnyIterator<(name: String, value: String)> {
return AnyIterator(HTTPHeadersIterator(wrapping: storage.makeIterator()))

View File

@ -27,6 +27,7 @@ extension HTTPHeadersTest {
static var allTests : [(String, (HTTPHeadersTest) -> () throws -> Void)] {
return [
("testCasePreservedButInsensitiveLookup", testCasePreservedButInsensitiveLookup),
("testWriteHeadersSeparately", testWriteHeadersSeparately),
]
}
}

View File

@ -14,6 +14,7 @@
import Foundation
import XCTest
@testable import NIO
@testable import NIOHTTP1
class HTTPHeadersTest : XCTestCase {
@ -49,4 +50,25 @@ class HTTPHeadersTest : XCTestCase {
}
}
}
func testWriteHeadersSeparately() {
let originalHeaders = [ ("User-Agent", "1"),
("host", "2"),
("X-SOMETHING", "3"),
("X-Something", "4"),
("SET-COOKIE", "foo=bar"),
("Set-Cookie", "buz=cux")]
let headers = HTTPHeaders(originalHeaders)
let channel = EmbeddedChannel()
var buffer = channel.allocator.buffer(capacity: 1024)
headers.write(buffer: &buffer)
let writtenBytes = buffer.string(at: buffer.readerIndex, length: buffer.readableBytes)!
XCTAssertTrue(writtenBytes.contains("user-agent: 1\r\n"))
XCTAssertTrue(writtenBytes.contains("host: 2\r\n"))
XCTAssertTrue(writtenBytes.contains("x-something: 3,4\r\n"))
XCTAssertTrue(writtenBytes.contains("set-cookie: foo=bar\r\n"))
XCTAssertTrue(writtenBytes.contains("set-cookie: buz=cux\r\n"))
}
}