How to get full server URL from any endpoint handler in Gin

huangapple go评论119阅读模式
英文:

How to get full server URL from any endpoint handler in Gin

问题

我正在使用Go的Gin Web框架创建一个端点。我需要在处理函数中获取完整的服务器URL。例如,如果服务器运行在http://localhost:8080上,我的端点是/foo,那么当我的处理函数被调用时,我需要的是http://localhost:8080/foo

如果有人熟悉Python的FastAPI,Request对象有一个方法url_for(<endpoint_name>),它具有完全相同的功能:https://stackoverflow.com/a/63682957/5353128

在Go中,我尝试过访问context.FullPath(),但它只返回我的端点/foo,而不是完整的URL。除此之外,我在文档中找不到合适的方法:https://pkg.go.dev/github.com/gin-gonic/gin#Context

所以,是否可以通过gin.Context对象本身实现这个功能,或者还有其他方法吗?我对Go完全不熟悉。

英文:

I'm creating an endpoint using Go's Gin web framework. I need full server URL in my handler function. For example, if server is running on http://localhost:8080 and my endpoint is /foo then I need http://localhost:8080/foo when my handler is called.

If anyone is familiar with Python's fast API, the Request object has a method url_for(&lt;endpoint_name&gt;) which has the exact same functionality: https://stackoverflow.com/a/63682957/5353128

In Go, I've tried accessing context.FullPath() but that only returns my endpoint /foo and not the full URL. Other than this, I can't find appropriate method in docs: https://pkg.go.dev/github.com/gin-gonic/gin#Context

So is this possible via gin.Context object itself or are there other ways as well? I'm completely new to Go.

答案1

得分: 13

c.Request.Host+c.Request.URL.Path 应该可以工作,但是需要确定协议。

  1. package main
  2. import (
  3. "fmt"
  4. "github.com/gin-gonic/gin"
  5. )
  6. func main() {
  7. r := gin.Default()
  8. r.GET("/foo", func(c *gin.Context) {
  9. fmt.Println("The URL: ", c.Request.Host+c.Request.URL.Path)
  10. })
  11. r.Run(":8080")
  12. }

你可以确定协议,你可能已经知道。但你可以按照以下方式进行检查:

  1. scheme := "http"
  2. if c.Request.TLS != nil {
  3. scheme = "https"
  4. }

如果你的服务器在代理后面,你可以通过 c.Request.Header.Get("X-Forwarded-Proto") 获取协议。

英文:

c.Request.Host+c.Request.URL.Path should work but the scheme has to be determined.

  1. package main
  2. import (
  3. &quot;fmt&quot;
  4. &quot;github.com/gin-gonic/gin&quot;
  5. )
  6. func main() {
  7. r := gin.Default()
  8. r.GET(&quot;/foo&quot;, func(c *gin.Context) {
  9. fmt.Println(&quot;The URL: &quot;, c.Request.Host+c.Request.URL.Path)
  10. })
  11. r.Run(&quot;:8080&quot;)
  12. }

You can determine scheme which also you may know already. But you can check as follows:

  1. scheme := &quot;http&quot;
  2. if c.Request.TLS != nil {
  3. scheme = &quot;https&quot;
  4. }

If your server is behind the proxy, you can get the scheme by c.Request.Header.Get(&quot;X-Forwarded-Proto&quot;)

答案2

得分: 1

你可以从context.Request.Host获取localhost:8080host部分,从context.Request.URL.String()获取/foopath部分。

  1. package main
  2. import (
  3. "fmt"
  4. "net/http"
  5. "github.com/gin-gonic/gin"
  6. )
  7. func main() {
  8. r := gin.Default()
  9. r.GET("/foo", func(c *gin.Context) {
  10. c.String(http.StatusOK, "bar")
  11. fmt.Println(c.Request.Host + c.Request.URL.String())
  12. })
  13. // Listen and Server in 0.0.0.0:8080
  14. r.Run(":8080")
  15. }

你可以通过context.Request.Proto获取HTTP协议版本,但它无法确定是http还是https。你需要根据你的服务规范来获取它。

英文:

You can get host part localhost:8080 from context.Request.Host and path part /foo from context.Request.URL.String().

  1. package main
  2. import (
  3. &quot;fmt&quot;
  4. &quot;net/http&quot;
  5. &quot;github.com/gin-gonic/gin&quot;
  6. )
  7. func main() {
  8. r := gin.Default()
  9. r.GET(&quot;/foo&quot;, func(c *gin.Context) {
  10. c.String(http.StatusOK, &quot;bar&quot;)
  11. fmt.Println(c.Request.Host+c.Request.URL.String())
  12. })
  13. // Listen and Server in 0.0.0.0:8080
  14. r.Run(&quot;:8080&quot;)
  15. }

And you can get http protocol version by context.Request.Proto, But it will not determine http or https. you need to get it from your service specifications.

huangapple
  • 本文由 发表于 2021年8月19日 00:38:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/68836237.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定