-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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
net/http: configurable error message for Client sent an HTTP request to an HTTPS server. #49310
Comments
Thanks for raising the issue. From my read this sounds more like a feature request as opposed to a bug, correct? |
The feature request is to respond to an HTTP request on an HTTPS port with a configurable error message. Testing several major websites (www.google.com, www.amazon.com, www.microsoft.com), none of them respond with an error message to an HTTP request on port 443. Two close the connection without response, one leaves the connection open but does not respond. I have not checked any other HTTPS server implementations (Apache, nginx, etc.) to see how they handle this condition. It would be interesting to know if any attempt to report an error to the peer in this case. In the absence of evidence that this is a common feature, I don't think we should add this. |
Hi ! This is a feature request, not a bug. I found some examples of Nginx configuring HTTP redirection to HTTPS:https://linuxize.com/post/redirect-http-to-https-in-nginx/
I want to replace nginx's auto-jump feature with Golang. |
HTTP redirection is different from the filed issue. It's already possible by listening on both HTTP and HTTPS ports and handling the redirection within the handlers
|
Yes, different port forwarding is also possible, but I need a forwarding on the same port |
An |
I would also like to make some comments on this issue
|
Yes, any core modifications don't seem to be standard-compliant, but, that's the truth, we need a way to intercept when "Client send an HTTP request to an HTTPS server" happens, or have a kind of friendly wrapper that allows him to Controllable output, because "Client send an HTTP request to an HTTPS server" directly output to the browser is very unfriendly, and it is uncontrollable and unexpected |
I would also like that this is configurable. Maybe TLSHandshakeBadRequest func(conn net.Conn) And if not defined, current: io.WriteString(re.Conn, "HTTP/1.0 400 Bad Request\r\n\r\nClient sent an HTTP request to an HTTPS server.\n") is called. Otherwise Open to other field names. |
i have same problem that response content not friendly, i wish can configurable the content |
The nginx example you provided is incorrect, it should be like this: # port 443
error_page 497 https://$host$request_uri;
# other ports
error_page 497 https://$host:$server_port$request_uri; Then, attempting to access the HTTPS port using HTTP will return a 302 redirect. |
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
Change https://go.dev/cl/564997 mentions this issue: |
It looks like nginx responds to an HTTP request on an HTTPS port with an error 497 (an nginx-specific code), and permits code-specific error handler overrides. The example nginx configuration from above is interesting, because it seems to indicate that nginx is parsing the full HTTP request in this case:
This points at a question: Is the desired feature request to customize the static message we send when responding to a misdirected HTTP request, or to respond with a redirect to the correct location? The latter is substantially more complicated to implement, because it requires effectively restarting the connection. If were were to add a feature, I could imagine something like:
But that's static, and it sounds like a common use case is a redirect. So maybe what people want is:
Although in that case, what happens when someone inevitably sets Server.Handler and Server.HTTPOnHTTPSPortErrorHandler to the same thing? Does that work? Should that work? Are there edge cases where it fails? I think implementation for this would also be complicated; unless I'm wrong, I don't think this is something we'd want to do. A middle ground, suggested by @mitar above, is essentially a roll-your-own handler where we hand the
You're going to want the already-consumed bytes from the I don't have any clear answers here. There's been a fair bit of discussion on this issue over time, but half of it is about cases other than an HTTP request sent to an HTTPS port. (For example, redirecting from HTTP on port 80 to HTTPS on port 443, which of course is something you can do today.) Some of the example use cases (such as that nginx config) involve more than just customizing the error string. Would a statically customizable response string be enough? That's at least implementable without adding a ton of complexity. |
This comment was marked as outdated.
This comment was marked as outdated.
@neild Yea, I realized this in https://go-review.googlesource.com/c/go/+/564997 as well. I think we could have:
But I think those recorded bytes are really optional and it might be hard for later on for implementation to change its behavior. If we look at current code, it does not use those bytes, it just writes to the connection:
So I was envisioning that the I am not sure how much utility is in inspecting |
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
I see. To allow virtual hosts redirects. And if |
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
@bddjr Please read contributing guide. I think this proposal has not yet been accepted. Making a pull request is fine to be able to discuss code, but until the proposal is accepted it cannot be merged. And about your last proposal: personally, I think the Config is overkill, I think we should have only one function callback and not so many options. Also, what is |
This comment was marked as outdated.
This comment was marked as outdated.
✅ I made a go mod to implement this feature ✨👉 https://github.com/bddjr/hlfhr 👈 It uses the Support HTTP/2 on HTTPS // Use hlfhr.New
srv := hlfhr.New(&http.Server{
// Write something...
})
// Then just use it like [http.Server]
err := srv.ListenAndServeTLS("localhost.crt", "localhost.key") srv.HttpOnHttpsPortErrorHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
url := "https://" + r.Host + r.URL.Path
if r.URL.ForceQuery || r.URL.RawQuery != "" {
url += "?" + r.URL.RawQuery
}
w.Header().Set("Location", url)
w.WriteHeader(302)
}) |
This comment was marked as resolved.
This comment was marked as resolved.
A simple example of the redirect method.
|
This comment was marked as off-topic.
This comment was marked as off-topic.
In theory, implementing this feature only requires an additional buffer and handler parameter. When the first byte of the request is detected to be like an HTTP method, the TLS handshake is skipped and the HTTP/1.1 handler is directly entered. |
After verification in multiple browsers, they can meet my needs. Test the 7439 kB request header, and the verification result is normal: |
This comment was marked as off-topic.
This comment was marked as off-topic.
Your implementation approach has a bug, it will cause the HTTPS don't use HTTP2. ✅ The mod I wrote would obviously be more in line with neild's wishes.👉 https://github.com/bddjr/hlfhr 👈 It uses the Support HTTP/2 on HTTPS // Use hlfhr.New
srv := hlfhr.New(&http.Server{
// Write something...
})
// Then just use it like [http.Server]
err := srv.ListenAndServeTLS("localhost.crt", "localhost.key") |
The existing solution can solve this problem without using the standard library, so it has been closed. |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as resolved.
This comment was marked as resolved.
Please reopen the issue, it is not yet solved in standard library. |
I have write a library that can auto redirect http to https at same port. https://github.com/bronze1man/httpRedirectToHttps |
Your code isn't as good as mine. |
Your code do not have "auto check correct" test. But my code have . (https://github.com/bronze1man/httpRedirectToHttps/blob/master/httpRedirectToHttpsTest/example_test.go) |
☝ You plagiarized my project: https://github.com/bddjr/hahosp srv := &http.Server{
Addr: ":5688"
// Use hahosp.HandlerSelector
Handler: &hahosp.HandlerSelector{
HTTPS: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "ok\n")
}),
HTTP: nil, // If nil, redirect to HTTPS.
},
}
// Use hahosp.ListenAndServe
err := hahosp.ListenAndServe(srv, "localhost.crt", "localhost.key") ✅ The mod I wrote would obviously be more in line with neild's wishes.👉 https://github.com/bddjr/hlfhr 👈 It uses the Support HTTP/2 on HTTPS // Use hlfhr.New
srv := hlfhr.New(&http.Server{
// Write something...
})
// Then just use it like [http.Server]
err := srv.ListenAndServeTLS("localhost.crt", "localhost.key") |
As the various implementations demonstrate, this is quite possible to do outside of the standard library. See https://go.dev/doc/faq#x_in_std |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
yes.
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Start the HTTPS service written in golang, and the user accesses the HTTP address.
What did you expect to see?
Display localized language information or customize html page or automatically jump to https address.
What did you see instead?
Chrome and Firefox:
display the following information
Other browsers:
The IE browser prompts a 400 error, and the instructional content is not displayed.
Browsers using the Chromium kernel do not display any visible content.
Users will not be able to understand the current situation.
The text was updated successfully, but these errors were encountered: