获取当前请求URL的方案 [英] Get scheme of the current request URL

查看:132
本文介绍了获取当前请求URL的方案的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Ruby/Rack中,我能够获取scheme#request 中当前请求URL的方案.但是,在Go中, http.Request.URL.Scheme 返回一个空字符串:

In Ruby/Rack, I'm able to get the scheme of the current request URL from scheme#request. However, in Go, http.Request.URL.Scheme returns an empty string:

package main

import (
    "fmt"
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/", handler)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "%#v\n", r.URL.Scheme) // Always shows empty string
}

如何获取当前请求网址的方案?

How do I get scheme of the current request URL?

推荐答案

快速的grep显示r.URL.Scheme从未设置为除net/http中任何地方的空字符串以外的任何内容.我个人认为应该尽可能,但显然我有少数意见.

A quick grep shows that r.URL.Scheme is never set to anything other than the empty string anywhere in net/http. Personally I think it should be, as far as possible, but apparently I have a minority opinion.

如果您使用http.ListenAndServeTLS()自己打开了TLS侦听器,那么大概您已经知道该方案已经是https.在这种情况下,您可以使用普通的中间件处理程序来填充r.URL.Scheme.

If you opened a TLS listener yourself with http.ListenAndServeTLS() then presumably you know the scheme is https already. You can use a trivial middleware handler that fills in r.URL.Scheme in this case.

func AlwaysHTTPS(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        r.URL.Scheme = "https"

        next.ServeHTTP(w, r)
    })
}

如果您在Web服务器后面运行,则它可能在标头(例如X-Forwarded-Proto)中传递请求协议.在这种情况下,您可以使用诸如gorilla的处理程序之类的处理程序.

If you're running behind a web server, then it may pass the request protocol in a header such as X-Forwarded-Proto. In this case, you can use a handler like gorilla's handlers.ProxyHeaders() to fill in the missing fields.

使用大猩猩复用器的示例:

An example using gorilla mux:

package main

import (
    "log"
    "net/http"

    "github.com/gorilla/handlers"
    "github.com/gorilla/mux"
)

func main() {
    r := mux.NewRouter()
    r.Use(handlers.ProxyHeaders)

    http.Handle("/", r)
    log.Fatal(http.ListenAndServe("[::]:8009", nil))
}

从评论中:

ProxyHeaders检查常见的反向代理标头,并在HTTP请求结构中设置相应的字段.这些是用于远程(客户端)IP地址的X-Forwarded-For和X-Real-IP,用于方案(http | https)的X-Forwarded-Proto或X-Forwarded-Scheme和RFC7239转发的标头,其中可能包括客户端IP和方案.

ProxyHeaders inspects common reverse proxy headers and sets the corresponding fields in the HTTP request struct. These are X-Forwarded-For and X-Real-IP for the remote (client) IP address, X-Forwarded-Proto or X-Forwarded-Scheme for the scheme (http|https) and the RFC7239 Forwarded header, which may include both client IPs and schemes.

注意:仅当在反向代理(如nginx,HAProxy或Apache)后面使用此中间件时,才应使用.反向代理不(或配置为不)从客户端请求中剥离这些标头,或者在按原样"接受这些标头的情况下使用反向代理.如果您的应用程序使用这些标头来验证请求的可信赖性",则来自远程客户端(例如,Go不在代理之后)可能会显示为漏洞.

NOTE: This middleware should only be used when behind a reverse proxy like nginx, HAProxy or Apache. Reverse proxies that don't (or are configured not to) strip these headers from client requests, or where these headers are accepted "as is" from a remote client (e.g. when Go is not behind a proxy), can manifest as a vulnerability if your application uses these headers for validating the 'trustworthiness' of a request.

这篇关于获取当前请求URL的方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆