-
Notifications
You must be signed in to change notification settings - Fork 125
Ignore uncleanShutdown error when state is .head or .body #77
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ignore uncleanShutdown error when state is .head or .body #77
Conversation
Can one of the admins verify this patch? |
I am...unsure about this. This is the only place where What it may be worth doing is making this behaviour configurable, so for users who don't care they can choose to ignore this error and always treat it as a clean EOF. |
Please read We know EOF when tcp connection close even if we ignore |
No we don't, we only know that when content-length is set: that is, we know it in The problem is that when content-length is not set, the complete response body is signalled by shutting the connection down as discussed in RFC 7230 § 3.3.3 Message Body Length:
In this case, the I am open to having settings put in place to allow you to ignore this error, but defaulting to reporting this error is the correct thing to do. |
@Lukasa Yes, you are right. we can configurate it now, please continue to review. |
@@ -276,19 +276,23 @@ public class HTTPClient { | |||
public var timeout: Timeout | |||
/// Upstream proxy, defaults to no proxy. | |||
public var proxy: Proxy? | |||
/// Enables ignore NIOSSLError.uncleanShutdown when state is .head or .body, defaults to `false`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need a better description. Maybe: "Ignore TLS unclean shutdown errors".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was updated.
|
||
public init(tlsConfiguration: TLSConfiguration? = nil, followRedirects: Bool = false, timeout: Timeout = Timeout(), proxy: Proxy? = nil) { | ||
public init(tlsConfiguration: TLSConfiguration? = nil, followRedirects: Bool = false, timeout: Timeout = Timeout(), proxy: Proxy? = nil, ignoreNIOSSLUncleanShutdownError: Bool = false) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change needs to be done differently, I'm afraid. This is a breaking API change, as you are allowed to refer to functions in Swift by their complete set of labels, and this changes the set of labels here. You need to do this:
public init(tlsConfiguration: TLSConfiguration? = nil, followRedirects: Bool = false, timeout: Timeout = Timeout(), proxy: Proxy? = nil) {
self.init(tlsConfiguration: tlsConfiguration, followRedirects: followRedirects, timeout: timeout, proxy: proxy, ignoreNIOSSLUncleanShutdownError: true)
}
public init(tlsConfiguration: TLSConfiguration? = nil, followRedirects: Bool = false, timeout: Timeout = Timeout(), proxy: Proxy? = nil, ignoreNIOSSLUncleanShutdownError: Bool) {
self.tlsConfiguration = tlsConfiguration
self.followRedirects = followRedirects
self.timeout = timeout
self.proxy = proxy
self.ignoreNIOSSLUncleanShutdownError = ignoreNIOSSLUncleanShutdownError
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was reverted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Lukasa we are not tagged 1.0.0
yet, do you think we can update the signature? It's unlikely imho that someone will be referencing those particular functions, wdyt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, if we're not maintaining a stable API we can do that.
} | ||
|
||
public init(certificateVerification: CertificateVerification, followRedirects: Bool = false, timeout: Timeout = Timeout(), proxy: Proxy? = nil) { | ||
public init(certificateVerification: CertificateVerification, followRedirects: Bool = false, timeout: Timeout = Timeout(), proxy: Proxy? = nil, ignoreNIOSSLUncleanShutdownError: Bool = false) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This requires a similar change as the one above: we need two functions, not one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was reverted too.
/// we can also ignore this error like .end . | ||
break | ||
} | ||
fallthrough |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can I propose using a where
clause here? That would be:
case .head where self.ignoreNIOSSLUncleanShutdownError,
.body where self.ignoreNIOSSLUncleanShutdownError:
break
That avoids the need for a fall through or the internal if
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's better to use internal if. it was updated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I'm happy with this, but we'll need review from at least one other person.
@@ -276,19 +276,31 @@ public class HTTPClient { | |||
public var timeout: Timeout | |||
/// Upstream proxy, defaults to no proxy. | |||
public var proxy: Proxy? | |||
/// Ignore TLS unclean shutdown error, defaults to `false`. | |||
public var ignoreNIOSSLUncleanShutdownError: Bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
=> ignoreNIOSSLUncleanShutdownError
is a mouthful imo, maybe ignoreUncleanSSLShutdown
? or something even shorter if someone can come up with a suggestion?
=> what are the arguments for the default to be false vs. true?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’m in favour of a shorter name.
False is a good default because we already ignore it in the cases where it’s 100% safe to do so: setting this switch to true would ignore it in the cases where it potentially opens your application up to some theoretical risks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe ignoreSSLUncleanShutdown
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ignoreUncleanSSLShutdown
seems more natural? subjective obviously, so up to @artemredkin
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 for ignoreUncleanSSLShutdown
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tomerd It was renamed.
@swift-server-bot test this please |
} | ||
|
||
XCTAssertThrowsError(try httpClient.get(url: "https://localhost:\(httpBin.port)/wrongcontentlength").wait(), "Should fail") { error in | ||
guard case let error = error as? HTTPParserError, case .invalidEOFState = error else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use ==
instead of guard case
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, it's my mistakes. it was updated, and I have run tests in swift 5.0 .
} | ||
|
||
XCTAssertThrowsError(try httpClient.get(url: "https://localhost:\(httpBin.port)/wrongcontentlength").wait(), "Should fail") { error in | ||
guard case let error = error as? NIOSSLError, case .uncleanShutdown = error else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use ==
instead of guard case
.
} | ||
|
||
XCTAssertThrowsError(try httpClient.get(url: "https://localhost:\(httpBin.port)/noresponse").wait(), "Should fail") { error in | ||
guard case let error = error as? NIOSSLError, case .uncleanShutdown = error else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use ==
instead of guard case
.
} | ||
|
||
XCTAssertThrowsError(try httpClient.get(url: "https://localhost:\(httpBin.port)/noresponse").wait(), "Should fail") { error in | ||
guard case let error = error as? NIOSSLError, case .uncleanShutdown = error else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use ==
instead of guard case
.
} | ||
|
||
XCTAssertThrowsError(try httpClient.get(url: "https://localhost:\(httpBin.port)/nocontentlength").wait(), "Should fail") { error in | ||
guard case let error = error as? NIOSSLError, case .uncleanShutdown = error else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use ==
instead of guard case
.
…client into ignore-uncleanShutdown
@swift-server-bot test this please |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@vkill thank you! |
Hi there,
I think we should ignore uncleanShutdown when state is
.head
or.body
, please review it. thx.