forked from apple/swift-nio-http2
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Police correct content-length headers. (apple#98)
Motivation: RFC 7540 requires that compliant specifications emit errors if content-length has been incorrectly set. We should have this behaviour by default, though we should allow it to be disabled if necessary. Modifications: - Added content-length checking. - Added flag to disable content-length checking. Result: Better RFC 7540 compliance.
- Loading branch information
Showing
12 changed files
with
908 additions
and
377 deletions.
There are no files selected for viewing
59 changes: 43 additions & 16 deletions
59
Sources/NIOHTTP2/ConnectionStateMachine/ConnectionStateMachine.swift
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This source file is part of the SwiftNIO open source project | ||
// | ||
// Copyright (c) 2019 Apple Inc. and the SwiftNIO project authors | ||
// Licensed under Apache License v2.0 | ||
// | ||
// See LICENSE.txt for license information | ||
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
import NIOHPACK | ||
|
||
/// An object that verifies that a content-length field on a HTTP request or | ||
/// response is respected. | ||
struct ContentLengthVerifier { | ||
private var expectedContentLength: Int? | ||
} | ||
|
||
extension ContentLengthVerifier { | ||
/// A chunk of data has been received from the network. | ||
mutating func receivedDataChunk(length: Int) throws { | ||
assert(length >= 0, "received data chunks must be positive") | ||
|
||
// If there was no content-length, don't keep track. | ||
guard let expectedContentLength = self.expectedContentLength else { | ||
return | ||
} | ||
|
||
let newContentLength = expectedContentLength - length | ||
if newContentLength < 0 { | ||
throw NIOHTTP2Errors.ContentLengthViolated() | ||
} | ||
self.expectedContentLength = newContentLength | ||
} | ||
|
||
/// Called when end of stream has been received. Validates that the complete body was received. | ||
func endOfStream() throws { | ||
switch self.expectedContentLength { | ||
case .none, .some(0): | ||
break | ||
default: | ||
throw NIOHTTP2Errors.ContentLengthViolated() | ||
} | ||
} | ||
} | ||
|
||
extension ContentLengthVerifier { | ||
internal init(_ headers: HPACKHeaders) { | ||
self.expectedContentLength = headers[canonicalForm: "content-length"].first.flatMap { Int($0, radix: 10) } | ||
} | ||
|
||
/// The verifier for use when content length verification is disabled. | ||
internal static var disabled: ContentLengthVerifier { | ||
return ContentLengthVerifier(expectedContentLength: nil) | ||
} | ||
} | ||
|
||
extension ContentLengthVerifier: CustomStringConvertible { | ||
var description: String { | ||
return "ContentLengthVerifier(length: \(String(describing: self.expectedContentLength)))" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.