Skip to content

Commit 3206f9d

Browse files
authored
Merge pull request #1375 from saiHemak/message-split
2 parents 879e7f6 + 9483cae commit 3206f9d

File tree

4 files changed

+117
-93
lines changed

4 files changed

+117
-93
lines changed

Foundation.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@
309309
5BF9B8011FABD5DA00EE1A7C /* CFBundle_ResourceFork.c in Sources */ = {isa = PBXBuildFile; fileRef = 5BF9B7F61FABD5D400EE1A7C /* CFBundle_ResourceFork.c */; };
310310
5BF9B8021FABD5DA00EE1A7C /* CFBundle_Tables.c in Sources */ = {isa = PBXBuildFile; fileRef = 5BF9B7F71FABD5D400EE1A7C /* CFBundle_Tables.c */; };
311311
5FE52C951D147D1C00F7D270 /* TestNSTextCheckingResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FE52C941D147D1C00F7D270 /* TestNSTextCheckingResult.swift */; };
312+
6105D30F1FEBC5FC0022865A /* Message.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6105D30E1FEBC5FC0022865A /* Message.swift */; };
312313
61E0117D1C1B5590000037DD /* RunLoop.swift in Sources */ = {isa = PBXBuildFile; fileRef = EADE0B761BD15DFF00C49C64 /* RunLoop.swift */; };
313314
61E0117E1C1B55B9000037DD /* Timer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BDC3F481BCC5DCB00ED97BB /* Timer.swift */; };
314315
61E0117F1C1B5990000037DD /* CFRunLoop.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D88D81BBC9AD800234F36 /* CFRunLoop.c */; };
@@ -778,6 +779,7 @@
778779
5EB6A15C1C188FC40037DCB8 /* TestJSONSerialization.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestJSONSerialization.swift; sourceTree = "<group>"; };
779780
5EF673AB1C28B527006212A3 /* TestNotificationQueue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNotificationQueue.swift; sourceTree = "<group>"; };
780781
5FE52C941D147D1C00F7D270 /* TestNSTextCheckingResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSTextCheckingResult.swift; sourceTree = "<group>"; };
782+
6105D30E1FEBC5FC0022865A /* Message.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Message.swift; sourceTree = "<group>"; };
781783
61A395F91C2484490029B337 /* TestNSLocale.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSLocale.swift; sourceTree = "<group>"; };
782784
61D6C9EE1C1DFE9500DEF583 /* TestTimer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestTimer.swift; sourceTree = "<group>"; };
783785
61E0117B1C1B554D000037DD /* TestRunLoop.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestRunLoop.swift; sourceTree = "<group>"; };
@@ -1017,6 +1019,7 @@
10171019
5B1FD9D01D6D16580080E83C /* URLSessionDelegate.swift */,
10181020
5B1FD9D11D6D16580080E83C /* URLSessionTask.swift */,
10191021
5B1FD9D21D6D16580080E83C /* TaskRegistry.swift */,
1022+
6105D30E1FEBC5FC0022865A /* Message.swift */,
10201023
);
10211024
name = Session;
10221025
path = URLSession;
@@ -2206,6 +2209,7 @@
22062209
EADE0BCB1BD15E0000C49C64 /* XMLNode.swift in Sources */,
22072210
5BF7AEB01BCD51F9008F214A /* NSLocale.swift in Sources */,
22082211
EADE0BA31BD15E0000C49C64 /* NSKeyedArchiver.swift in Sources */,
2212+
6105D30F1FEBC5FC0022865A /* Message.swift in Sources */,
22092213
5BF7AEAD1BCD51F9008F214A /* NSError.swift in Sources */,
22102214
EADE0BB61BD15E0000C49C64 /* NSSortDescriptor.swift in Sources */,
22112215
5B23AB871CE62D17000DB898 /* Boxing.swift in Sources */,

Foundation/URLSession/Message.swift

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
// Foundation/URLSession/Message.swift - URLSession & libcurl
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
// -----------------------------------------------------------------------------
12+
///
13+
/// Common code for Header parsing
14+
///
15+
/// - SeeAlso: https://curl.haxx.se/libcurl/c/
16+
/// - SeeAlso: URLSession.swift
17+
///
18+
// -----------------------------------------------------------------------------
19+
20+
import CoreFoundation
21+
22+
extension _HTTPURLProtocol {
23+
/// An HTTP header being parsed.
24+
///
25+
/// It can either be complete (i.e. the final CR LF CR LF has been
26+
/// received), or partial.
27+
internal enum _ParsedResponseHeader {
28+
case partial(_ResponseHeaderLines)
29+
case complete(_ResponseHeaderLines)
30+
init() {
31+
self = .partial(_ResponseHeaderLines())
32+
}
33+
}
34+
/// A type safe wrapper around multiple lines of headers.
35+
///
36+
/// This can be converted into an `HTTPURLResponse`.
37+
internal struct _ResponseHeaderLines {
38+
let lines: [String]
39+
init() {
40+
self.lines = []
41+
}
42+
init(headerLines: [String]) {
43+
self.lines = headerLines
44+
}
45+
}
46+
}
47+
48+
extension _HTTPURLProtocol._ParsedResponseHeader {
49+
/// Parse a header line passed by libcurl.
50+
///
51+
/// These contain the <CRLF> ending and the final line contains nothing but
52+
/// that ending.
53+
/// - Returns: Returning nil indicates failure. Otherwise returns a new
54+
/// `ParsedResponseHeader` with the given line added.
55+
func byAppending(headerLine data: Data) -> _HTTPURLProtocol._ParsedResponseHeader? {
56+
// The buffer must end in CRLF
57+
guard
58+
2 <= data.count &&
59+
data[data.endIndex - 2] == _HTTPCharacters.CR &&
60+
data[data.endIndex - 1] == _HTTPCharacters.LF
61+
else { return nil }
62+
let lineBuffer = data.subdata(in: Range(data.startIndex..<data.endIndex-2))
63+
guard let line = String(data: lineBuffer, encoding: String.Encoding.utf8) else { return nil}
64+
return byAppending(headerLine: line)
65+
}
66+
/// Append a status line.
67+
///
68+
/// If the line is empty, it marks the end of the header, and the result
69+
/// is a complete header. Otherwise it's a partial header.
70+
/// - Note: Appending a line to a complete header results in a partial
71+
/// header with just that line.
72+
private func byAppending(headerLine line: String) -> _HTTPURLProtocol._ParsedResponseHeader {
73+
if line.isEmpty {
74+
switch self {
75+
case .partial(let header): return .complete(header)
76+
case .complete: return .partial(_HTTPURLProtocol._ResponseHeaderLines())
77+
}
78+
} else {
79+
let header = partialResponseHeader
80+
return .partial(header.byAppending(headerLine: line))
81+
}
82+
}
83+
private var partialResponseHeader: _HTTPURLProtocol._ResponseHeaderLines {
84+
switch self {
85+
case .partial(let header): return header
86+
case .complete: return _HTTPURLProtocol._ResponseHeaderLines()
87+
}
88+
}
89+
}
90+
91+
private extension _HTTPURLProtocol._ResponseHeaderLines {
92+
/// Returns a copy of the lines with the new line appended to it.
93+
func byAppending(headerLine line: String) -> _HTTPURLProtocol._ResponseHeaderLines {
94+
var l = self.lines
95+
l.append(line)
96+
return _HTTPURLProtocol._ResponseHeaderLines(headerLines: l)
97+
}
98+
}
99+
100+
// Characters that we need for HTTP parsing:
101+
struct _HTTPCharacters {
102+
/// *Carriage Return* symbol
103+
static let CR: UInt8 = 0x0d
104+
/// *Line Feed* symbol
105+
static let LF: UInt8 = 0x0a
106+
/// *Space* symbol
107+
static let Space = UnicodeScalar(0x20)
108+
static let HorizontalTab = UnicodeScalar(0x09)
109+
static let Colon = UnicodeScalar(0x3a)
110+
/// *Separators* according to RFC 2616
111+
static let Separators = NSCharacterSet(charactersIn: "()<>@,;:\\\"/[]?={} \t")
112+
}

Foundation/URLSession/http/HTTPMessage.swift

Lines changed: 0 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -19,83 +19,6 @@
1919

2020
import CoreFoundation
2121

22-
23-
extension _HTTPURLProtocol {
24-
/// An HTTP header being parsed.
25-
///
26-
/// It can either be complete (i.e. the final CR LF CR LF has been
27-
/// received), or partial.
28-
internal enum _ParsedResponseHeader {
29-
case partial(_ResponseHeaderLines)
30-
case complete(_ResponseHeaderLines)
31-
init() {
32-
self = .partial(_ResponseHeaderLines())
33-
}
34-
}
35-
/// A type safe wrapper around multiple lines of headers.
36-
///
37-
/// This can be converted into an `HTTPURLResponse`.
38-
internal struct _ResponseHeaderLines {
39-
let lines: [String]
40-
init() {
41-
self.lines = []
42-
}
43-
init(headerLines: [String]) {
44-
self.lines = headerLines
45-
}
46-
}
47-
}
48-
49-
extension _HTTPURLProtocol._ParsedResponseHeader {
50-
/// Parse a header line passed by libcurl.
51-
///
52-
/// These contain the <CRLF> ending and the final line contains nothing but
53-
/// that ending.
54-
/// - Returns: Returning nil indicates failure. Otherwise returns a new
55-
/// `ParsedResponseHeader` with the given line added.
56-
func byAppending(headerLine data: Data) -> _HTTPURLProtocol._ParsedResponseHeader? {
57-
// The buffer must end in CRLF
58-
guard
59-
2 <= data.count &&
60-
data[data.endIndex - 2] == _HTTPCharacters.CR &&
61-
data[data.endIndex - 1] == _HTTPCharacters.LF
62-
else { return nil }
63-
let lineBuffer = data.subdata(in: Range(data.startIndex..<data.endIndex-2))
64-
guard let line = String(data: lineBuffer, encoding: String.Encoding.utf8) else { return nil}
65-
return byAppending(headerLine: line)
66-
}
67-
/// Append a status line.
68-
///
69-
/// If the line is empty, it marks the end of the header, and the result
70-
/// is a complete header. Otherwise it's a partial header.
71-
/// - Note: Appending a line to a complete header results in a partial
72-
/// header with just that line.
73-
private func byAppending(headerLine line: String) -> _HTTPURLProtocol._ParsedResponseHeader {
74-
if line.isEmpty {
75-
switch self {
76-
case .partial(let header): return .complete(header)
77-
case .complete: return .partial(_HTTPURLProtocol._ResponseHeaderLines())
78-
}
79-
} else {
80-
let header = partialResponseHeader
81-
return .partial(header.byAppending(headerLine: line))
82-
}
83-
}
84-
private var partialResponseHeader: _HTTPURLProtocol._ResponseHeaderLines {
85-
switch self {
86-
case .partial(let header): return header
87-
case .complete: return _HTTPURLProtocol._ResponseHeaderLines()
88-
}
89-
}
90-
}
91-
private extension _HTTPURLProtocol._ResponseHeaderLines {
92-
/// Returns a copy of the lines with the new line appended to it.
93-
func byAppending(headerLine line: String) -> _HTTPURLProtocol._ResponseHeaderLines {
94-
var l = self.lines
95-
l.append(line)
96-
return _HTTPURLProtocol._ResponseHeaderLines(headerLines: l)
97-
}
98-
}
9922
internal extension _HTTPURLProtocol._ResponseHeaderLines {
10023
/// Create an `NSHTTPRULResponse` from the lines.
10124
///
@@ -184,22 +107,6 @@ extension _HTTPURLProtocol._HTTPMessage._Version {
184107
}
185108
}
186109

187-
188-
// Characters that we need for HTTP parsing:
189-
190-
struct _HTTPCharacters {
191-
/// *Carriage Return* symbol
192-
static let CR: UInt8 = 0x0d
193-
/// *Line Feed* symbol
194-
static let LF: UInt8 = 0x0a
195-
/// *Space* symbol
196-
static let Space = UnicodeScalar(0x20)
197-
static let HorizontalTab = UnicodeScalar(0x09)
198-
static let Colon = UnicodeScalar(0x3a)
199-
/// *Separators* according to RFC 2616
200-
static let Separators = NSCharacterSet(charactersIn: "()<>@,;:\\\"/[]?={} \t")
201-
}
202-
203110
private extension _HTTPURLProtocol._HTTPMessage._StartLine {
204111
init?(line: String) {
205112
guard let r = line.splitRequestLine() else { return nil }

build.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,7 @@
431431
'Foundation/URLSession/Configuration.swift',
432432
'Foundation/URLSession/libcurl/EasyHandle.swift',
433433
'Foundation/URLSession/BodySource.swift',
434+
'Foundation/URLSession/Message.swift',
434435
'Foundation/URLSession/http/HTTPMessage.swift',
435436
'Foundation/URLSession/libcurl/MultiHandle.swift',
436437
'Foundation/URLSession/URLSession.swift',

0 commit comments

Comments
 (0)