Skip to content

Commit c17bddf

Browse files
calvincestarigh-action-runner
authored and
gh-action-runner
committed
fix: Multipart chunk content type (apollographql/apollo-ios-dev#572)
1 parent a94ebd7 commit c17bddf

3 files changed

+24
-22
lines changed

Sources/Apollo/MultipartResponseDeferParser.swift

+6-12
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ struct MultipartResponseDeferParser: MultipartResponseSpecificationParser {
2323
}
2424

2525
private enum DataLine {
26-
case contentHeader(type: String)
26+
case contentHeader(directives: [String])
2727
case json(object: JSONObject)
2828
case unknown
2929

@@ -32,14 +32,8 @@ struct MultipartResponseDeferParser: MultipartResponseSpecificationParser {
3232
}
3333

3434
private static func parse(_ dataLine: String) -> DataLine {
35-
var contentTypeHeader: StaticString { "content-type:" }
36-
37-
if dataLine.starts(with: contentTypeHeader.description) {
38-
let contentType = (dataLine
39-
.components(separatedBy: ":").last ?? dataLine
40-
).trimmingCharacters(in: .whitespaces)
41-
42-
return .contentHeader(type: contentType)
35+
if let directives = dataLine.parseContentTypeDirectives() {
36+
return .contentHeader(directives: directives)
4337
}
4438

4539
if
@@ -58,9 +52,9 @@ struct MultipartResponseDeferParser: MultipartResponseSpecificationParser {
5852
static func parse(_ chunk: String) -> Result<Data?, any Error> {
5953
for dataLine in chunk.components(separatedBy: Self.dataLineSeparator.description) {
6054
switch DataLine(dataLine.trimmingCharacters(in: .newlines)) {
61-
case let .contentHeader(type):
62-
guard type == "application/json" else {
63-
return .failure(ParsingError.unsupportedContentType(type: type))
55+
case let .contentHeader(directives):
56+
guard directives.contains("application/json") else {
57+
return .failure(ParsingError.unsupportedContentType(type: directives.joined(separator: ";")))
6458
}
6559

6660
case let .json(object):

Sources/Apollo/MultipartResponseParsingInterceptor.swift

+12
Original file line numberDiff line numberDiff line change
@@ -182,4 +182,16 @@ extension String {
182182

183183
return nil
184184
}
185+
186+
func parseContentTypeDirectives() -> [String]? {
187+
var lowercasedContentTypeHeader: StaticString { "content-type:" }
188+
189+
guard lowercased().starts(with: lowercasedContentTypeHeader.description) else {
190+
return nil
191+
}
192+
193+
return dropFirst(lowercasedContentTypeHeader.description.count)
194+
.components(separatedBy: ";")
195+
.map({ $0.trimmingCharacters(in: .whitespaces) })
196+
}
185197
}

Sources/Apollo/MultipartResponseSubscriptionParser.swift

+6-10
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ struct MultipartResponseSubscriptionParser: MultipartResponseSpecificationParser
3030

3131
private enum DataLine {
3232
case heartbeat
33-
case contentHeader(type: String)
33+
case contentHeader(directives: [String])
3434
case json(object: JSONObject)
3535
case unknown
3636

@@ -46,12 +46,8 @@ struct MultipartResponseSubscriptionParser: MultipartResponseSpecificationParser
4646
return .heartbeat
4747
}
4848

49-
if dataLine.lowercased().starts(with: contentTypeHeader.description) {
50-
let contentType = (dataLine
51-
.components(separatedBy: ":").last ?? dataLine
52-
).trimmingCharacters(in: .whitespaces)
53-
54-
return .contentHeader(type: contentType)
49+
if let directives = dataLine.parseContentTypeDirectives() {
50+
return .contentHeader(directives: directives)
5551
}
5652

5753
if
@@ -74,9 +70,9 @@ struct MultipartResponseSubscriptionParser: MultipartResponseSpecificationParser
7470
// Periodically sent by the router - noop
7571
break
7672

77-
case let .contentHeader(type):
78-
guard type == "application/json" else {
79-
return .failure(ParsingError.unsupportedContentType(type: type))
73+
case let .contentHeader(directives):
74+
guard directives.contains("application/json") else {
75+
return .failure(ParsingError.unsupportedContentType(type: directives.joined(separator: ";")))
8076
}
8177

8278
case let .json(object):

0 commit comments

Comments
 (0)