[WIP] Add remote_address to HTTP::Server::Context#7302
[WIP] Add remote_address to HTTP::Server::Context#7302omarroth wants to merge 1 commit intocrystal-lang:masterfrom omarroth:add-remote-ip
Conversation
|
This is so needed. looks like one potential issue on linux though based on the CI output |
|
IMHO this PR is premature. We should continue the discussion about how to expose and implement this in #5784. |
|
I agree it's premature, which is why it's marked as [WIP]. This comment in #453 is mostly the reason for this PR. What is implemented here is minimal functionality with the expectation that it will be expanded to include support for e.g. My hope for this PR is to further discussion. There doesn't appear to be much consensus reached in #5784, although I would be happy to move this functionality into |
|
A couple thoughts: In #1722 there's an option to use headers to determine the IP, namely This example exposes It makes sense to me that this should belong in Currently this PR supports HTTP servers, with and without SSL. Are there any other protocols/sockets that need to be supported? |
ysbaddaden
left a comment
There was a problem hiding this comment.
My problem is always the same: asking for the remote address should be on demand, not called on each and every connection.
It should also be located on Request. It should also be a nilable, or a raise on nil since the IO is expected to be a socket, but that's not always the case.
As you state in the next paragraph, these are two different concepts: a) The remote address of the immediate network connection. b) The client address of a HTTP connection which may be equal to the remote address, but that could also be some kind of proxy or other intermediary. I think both should be made available in stdlib's HTTP implementation, but this PR focuses on a) which needs to come first. b) is the next step.
The server is specific to HTTP, so no other application servers need to be supported. But obviously all kinds of HTTP transport streams, i.e. TCP and Unix sockets with and without SSL. |
|
Thanks for taking a look at this everyone. I moved Currently it's handling the socket twice. Once to unwrap it if necessary and then again to determine the underlying type. It may be necessary to delegate it to |
ysbaddaden
left a comment
There was a problem hiding this comment.
Why was the method moved the response object? It doesn't make sense.
HTTP::Server::Response musn't require OpenSSL, please implement #remote_address on SSLSocket, so the method can be reduced as a mere delegate to io, and we can keep building the compiler or a HTTP server without OpenSSL. That is:
def remote_address
if (io = @io).responds_to?(:remote_address)
io.remote_address
else
raise "#{@io} doesn't have a remote address"
end
end
def remote_address?
if (io = @io).responds_to?(:remote_address)
io.remote_address
end
end|
Where would you suggest exposing this? |
|
The request object. Later we can implement |
|
That was essentially the consensus in #5784 and why previous attempts like #5870 failed. It just didn't work out yet because |
|
Apologies for not giving this PR much attention. I moved I'll add specs when I have a free moment. |
src/http/request.cr
Outdated
| @io : IO? | ||
|
|
||
| def initialize(@method : String, @resource : String, headers : Headers? = nil, body : String | Bytes | IO | Nil = nil, @version = "HTTP/1.1") | ||
| def initialize(@method : String, @resource : String, headers : Headers? = nil, body : String | Bytes | IO | Nil = nil, @version = "HTTP/1.1", @io : IO | Nil = nil) |
There was a problem hiding this comment.
IO | Nil can be changed to IO? to match Headers?
|
Closing in favor of #7610. |
Would appear to close #453 and #5784.
This PR adds support for
remote_addressby pulling it from the underlying IO.I'm currently unsure if adding this as a separate field to
Contextis appropriate. It may make more sense to provide aContext::InfoorContext::Metadata, which could containremote_addressandlocal_address, or other useful information that would be relevant in some cases, with functionality similar to #1722.Example use:
This PR also patches
OpenSSL::SSL::Socketso theIPAddresscan be determined for servers with SSL enabled.It might be good to change this line to a warning or safer default.
Still needs tests.