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

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

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 应该可以工作,但是需要确定协议。

package main

import (
	"fmt"

	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()

	r.GET("/foo", func(c *gin.Context) {
		fmt.Println("The URL: ", c.Request.Host+c.Request.URL.Path)
	})

	r.Run(":8080")
}

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

scheme := "http"
if c.Request.TLS != nil {
    scheme = "https"
}

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

英文:

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

package main

import (
	&quot;fmt&quot;

	&quot;github.com/gin-gonic/gin&quot;
)

func main() {
	r := gin.Default()

	r.GET(&quot;/foo&quot;, func(c *gin.Context) {
		fmt.Println(&quot;The URL: &quot;, c.Request.Host+c.Request.URL.Path)
	})

	r.Run(&quot;:8080&quot;)
}

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

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

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部分。

package main

import (
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()
	r.GET("/foo", func(c *gin.Context) {
		c.String(http.StatusOK, "bar")
		fmt.Println(c.Request.Host + c.Request.URL.String())
	})
	// Listen and Server in 0.0.0.0:8080
	r.Run(":8080")
}

你可以通过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().

package main

import (
	&quot;fmt&quot;
	&quot;net/http&quot;

	&quot;github.com/gin-gonic/gin&quot;
)

func main() {
	r := gin.Default()
	r.GET(&quot;/foo&quot;, func(c *gin.Context) {
		c.String(http.StatusOK, &quot;bar&quot;)
		fmt.Println(c.Request.Host+c.Request.URL.String())
	})
	// Listen and Server in 0.0.0.0:8080
	r.Run(&quot;:8080&quot;)
}

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:

确定