如何限制使用Golang编写的Web服务器,只允许特定的地址而不是模式?

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

How to restrict web server written in golang to allow a particular address instead of a pattern?

问题

当我使用以下代码时:

http.HandleFunc("/", serveRest)  // serveRest 是处理请求的方法
http.ListenAndServe("localhost:4000", nil)

它将接受以"/"开头的所有请求。我如何限制它只服务于"localhost:4000"而不是每个地址,比如"localhost:4000/*"?

还有,你们能给我推荐一个好的Go教程吗?

英文:

When I use

http.HandleFunc("/", serveRest)  //serveRest is the method to handle request
http.ListenAndServe("localhost:4000", nil)

It will accept all request starting with "/". How do I restrict it to serve only "localhost:4000" instead of every address like "localhost:4000/*"?

And can you guys suggest me a good tutorial for Go?

答案1

得分: 7

你注册处理程序的URL模式在http.ServeMux类型中有详细说明:

模式可以是固定的、根路径,例如"/favicon.ico",或者是根子树,例如"/images/"(注意末尾的斜杠)。较长的模式优先于较短的模式,因此如果同时为"/images/"和"/images/thumbnails/"注册了处理程序,后者将用于以"/images/thumbnails/"开头的路径,而前者将用于"/images/"子树中的任何其他路径的请求。

请注意,由于以斜杠结尾的模式表示根子树,模式"/"匹配所有未被其他注册模式匹配的路径,而不仅仅是路径为"/"的URL。

因此,不幸的是,没有仅匹配根路径("/")的模式。

但是,你可以在处理程序中轻松检查这一点,并在请求路径不是根路径时执行你想要的操作:

func serveRest(w http.ResponseWriter, r *http.Request) {
    if r.URL.Path != "/" {
        w.Write([]byte("不是根路径!"))
        return
    }
    
    w.Write([]byte("你好,这是根路径!"))
}

如果你想为非根路径返回HTTP 404 Not found错误:

func serveRest(w http.ResponseWriter, r *http.Request) {
    if r.URL.Path != "/" {
        http.NotFound(w, r)
        return
    }

    w.Write([]byte("你好!"))
}

Go教程:https://tour.golang.org/

还可以在SO上查看<kbd>Go</kbd>标签信息,其中有一个Go教程部分。

英文:

The URL pattern to which you register your handlers is documented in the http.ServeMux type:

> Patterns name fixed, rooted paths, like "/favicon.ico", or rooted subtrees, like "/images/" (note the trailing slash). Longer patterns take precedence over shorter ones, so that if there are handlers registered for both "/images/" and "/images/thumbnails/", the latter handler will be called for paths beginning "/images/thumbnails/" and the former will receive requests for any other paths in the "/images/" subtree.
>
> Note that since a pattern ending in a slash names a rooted subtree, the pattern "/" matches all paths not matched by other registered patterns, not just the URL with Path == "/".

So unfortunately there is no pattern which matches only the root (&quot;/&quot;).

But you can easily check this in your handler, and do whatever you want to if the request path is not the root:

func serveRest(w http.ResponseWriter, r *http.Request) {
    if r.URL.Path != &quot;/&quot; {
        w.Write([]byte(&quot;Not root!&quot;))
        return
    }
    
    w.Write([]byte(&quot;Hi, this is the root!&quot;))
}

If you want to return HTTP 404 Not found error for non-roots:

func serveRest(w http.ResponseWriter, r *http.Request) {
    if r.URL.Path != &quot;/&quot; {
        http.NotFound(w, r)
        return
    }

    w.Write([]byte(&quot;Hi!&quot;))
}

And Go tutorial: https://tour.golang.org/

Also check out the <kbd>Go</kbd> tag info here on SO, it has a section Go Tutorials.

答案2

得分: 1

你可以查看https://github.com/julienschmidt/httprouter

根据它的自述文件:

> 仅显式匹配:与其他路由器(如http.ServeMux)不同,请求的URL路径可能与多个模式匹配。因此,它们具有一些尴尬的模式优先级规则,如最长匹配或先注册先匹配。通过设计,该路由器的请求只能完全匹配一个或零个路由。因此,也不会出现意外匹配,这对于SEO和改善用户体验非常有用。

这里有一些很好的Go入门视频内容。

英文:

You could check out
https://github.com/julienschmidt/httprouter

Per its readme:

> Only explicit matches: With other routers, like http.ServeMux, a
> requested URL path could match multiple patterns. Therefore they have
> some awkward pattern priority rules, like longest match or first
> registered, first matched. By design of this router, a request can
> only match exactly one or no route. As a result, there are also no
> unintended matches, which makes it great for SEO and improves the user
> experience.

Here is some good video content to get started in Go.

huangapple
  • 本文由 发表于 2015年8月7日 20:03:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/31877296.html
匿名

发表评论

匿名网友

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

确定