Skip to content
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

Basic support for unix domain sockets #187

Merged
merged 11 commits into from
Apr 2, 2019
Merged

Conversation

pushkarnk
Copy link
Contributor

This is a replication of the unix domain socket support on Kitura-net. This pull request proposes an additive change to the HTTP.request() and ClientRequest.init(options:) APIs via the addition of a new optional argument named socketPath, which defaults to nil to ensure zero breakage of ClientRequest. That's about the client side support. For the sake of testing, we also have an internal listen(unixDomainSocket:) that provides server-side support for listening on unix domain sockets. One of the existing Kitura-NIO tests testLargePosts is modified to work with a unix socket.

@pushkarnk pushkarnk changed the title Basic support for unix domain sockets [prototype]Basic support for unix domain sockets Mar 22, 2019
@codecov-io
Copy link

codecov-io commented Mar 24, 2019

Codecov Report

Merging #187 into master will increase coverage by 0.27%.
The diff coverage is 84.31%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #187      +/-   ##
==========================================
+ Coverage   68.35%   68.63%   +0.27%     
==========================================
  Files          20       20              
  Lines        1324     1358      +34     
==========================================
+ Hits          905      932      +27     
- Misses        419      426       +7
Flag Coverage Δ
#KituraNet 68.63% <84.31%> (+0.27%) ⬆️
Impacted Files Coverage Δ
Sources/KituraNet/HTTP/HTTPRequestHandler.swift 82.66% <ø> (-0.23%) ⬇️
Sources/KituraNet/HTTP/HTTP.swift 95.83% <100%> (ø) ⬆️
Sources/KituraNet/HTTP/HTTPServer.swift 57.33% <81.81%> (+3.01%) ⬆️
Sources/KituraNet/ClientRequest.swift 75.13% <87.5%> (+0.2%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ad5e257...41062b6. Read the comment docs.

Copy link
Contributor

@djones6 djones6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although the initial purpose was to provide client-side support, I think it's worth making the server-side facility public also (since this implements it). We need to get the -net and -NIO implementations in sync with respect to this (and naming), then merge and tag both.

I'll work on the corresponding Kitura PR.

Sources/KituraNet/ClientRequest.swift Show resolved Hide resolved
@@ -48,8 +48,8 @@ public class HTTP {
return ClientRequest(url: url, callback: callback)
}

public static func request(_ options: [ClientRequest.Options], callback: @escaping ClientRequest.Callback) -> ClientRequest {
return ClientRequest(options: options, callback: callback)
public static func request(_ options: [ClientRequest.Options], socketPath: String? = nil, callback: @escaping ClientRequest.Callback) -> ClientRequest {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whole function seems to be missing API documentation... Kitura-net's doc is far from exemplary in this instance, but does attempt to describe the params.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A recently merged PR has copied all of the documentation comments from Kitura-net to Kitura-NIO :)

@@ -207,8 +210,9 @@ public class ClientRequest {
///
/// - Parameter options: An array of `Options' describing the request
/// - Parameter callback: The closure of type `Callback` to be used for the callback.
init(options: [Options], callback: @escaping Callback) {
init(options: [Options], socketPath: String? = nil, callback: @escaping Callback) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's call this parameter unixDomainSocketPath to be consistent.

@@ -34,6 +34,8 @@ public class HTTPServer: Server {
/// Port number for listening for new connections.
public private(set) var port: Int?

var unixDomainSocketPath: String?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Kitura/Kitura-net#296, I went with

    /// The Unix domain socket path on which this server listens for new connections. If `nil`, this server does not listen on a Unix socket.
    public private(set) var unixDomainSocketPath: String?

...as we provide a similar property for accessing the port. I also updated the API doc for port to include:

If nil, this server does not listen on a TCP socket.

@@ -160,11 +162,25 @@ public class HTTPServer: Server {
return nil
}

enum SocketType {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be private?

case unixDomainSocket(String)
}

func listen(unixDomainSocketPath: String) throws {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be public to match public func listen(on port: Int). It could also do with documentation (could be a copy-paste of Kitura/Kitura-net#296)

@@ -39,10 +39,25 @@ class LargePayloadTests: KituraNetTest {

private let delegate = TestServerDelegate()

private func uniqueTemporaryFilePath() -> String {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This all looks fine, I used a slightly different implementation in the equivalent Kitura-net PR - take a look at my setUp() and tearDown() in Tests/KituraNetTests/UnixSocketTests.swift
- in particular, it would be nice to not leave a bunch of temporary files lying around after running the tests.

Also, is it possible for the test to assert that the client is connecting over a Unix socket? I did this in the test I referred to above, but I'm not sure if this is feasible with NIO.

@pushkarnk
Copy link
Contributor Author

Thanks for the review @djones6 I've addressed all of your comments.

@djones6 djones6 self-requested a review March 29, 2019 16:07
Copy link
Contributor

@djones6 djones6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes look good to me now, however, I'd like to understand why the CI for Kitura is failing here: Kitura/Kitura#1434

I'm trying to run the whole Kitura test suite over Unix sockets. This works for Kitura-net, but the tests that send a redirect seem to be failing with NIO when using Unix sockets.

@djones6
Copy link
Contributor

djones6 commented Mar 29, 2019

@pushkarnk I pushed f04d4eb because it is otherwise not possible to start, stop and then restart the server. This also makes it consistent with BlueSocket, which removes the file at the socket path if it already exists.

serverChannel = try bootstrap.bind(host: "0.0.0.0", port: port).wait()
switch socket {
case SocketType.tcp(let port):
listenerDescription = "port \(port)"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just realized this isn't quite right: this will result in port 0 when listening on an ephemeral port.

Copy link
Contributor Author

@pushkarnk pushkarnk Mar 30, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've fixed this in 450882a

@pushkarnk
Copy link
Contributor Author

@djones6 Redirection creates new ClientRequest objects. If an HTTP server listening on a unix domain socket returns a redirection request (302), the new ClientRequest must also connect to the same unix domain socket (if the value of the Location header is just another path i.e starts with /). If the value of the Location header is a full URL, we cannot make assumptions about it being hosted on the same unix domain socket.

This commit handles the case of the Location having just a different path 41062b6

With this the Kitura tests must pass.

@pushkarnk pushkarnk changed the title [prototype]Basic support for unix domain sockets Basic support for unix domain sockets Mar 31, 2019
@djones6 djones6 merged commit d403683 into master Apr 2, 2019
@djones6 djones6 deleted the unix-domain-sockets-support branch April 2, 2019 16:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants