Golang。要使用什么? http.ServeFile(..)或http.FileServer(..)? [英] Golang. What to use? http.ServeFile(..) or http.FileServer(..)?

查看:984
本文介绍了Golang。要使用什么? http.ServeFile(..)或http.FileServer(..)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有点困惑。很多例子显示了两者的用法: http.ServeFile(..) http.FileServer(..),但似乎他们有非常密切的功能。另外我还没有找到有关如何设置自定义NotFound处理程序的信息。

  //这可以从路径
中去除/ static /片段fs:= http.FileServer(http .dir(static))
http.Handle(/ static /,http.StripPrefix(/ static /,fs))

//这也可以,但/ static2 /片段仍然存在,需要手动分条
http.HandleFunc(/ static2 /,func(w http.ResponseWriter,r * http.Request){
http.ServeFile(w ,r,r.URL.Path [1:])
})

http.ListenAndServe(:8080,nil)

我尝试读取源代码,并且它们都使用 serveFile(ResponseWriter,* Request,FileSystem,string,bool)底层函数。然而 http.FileServer 返回 fileHandler 以及它自己的 ServeHTTP()方法并在提供文件之前做一些准备工作(例如path.Clean())。

那么为什么需要这种分离呢?哪种方法更好用?我怎样才能设置自定义NotFound处理程序,例如当找不到请求的文件时? 主要区别在于 http.FileServer 有效地将HTTP前缀与文件系统几乎进行1:1映射。用简单的英语,它提供了一个完整的目录路径。和其所有的孩子。



假设您有一个名为 / home / bob / static 的目录,并且您有此设置:

  fs:= http.FileServer(http.Dir(/ home / bob / static))
http.Handle(/ static /,http.StripPrefix(/ static,fs))

你的服务器会收到例如 )

相比之下, ServeFile 是一个较低级别的帮助程序,可用于实现与FileServer类似的功能,或者可能实现自己的路径,以及任何数量的事情。它只需获取指定的本地文件并通过HTTP连接发送它。本身,它不会提供一个完整的目录前缀(除非你编写了一个类似于FileServer的查找处理程序)



注意天真地建立一个文件系统是一个潜在的危险的事情(有可能的方式来打破根源树),因此我建议,除非你真的知道你在做什么,可以使用 http.FileServer http.Dir ,因为它们包含检查以确保人们无法摆脱FS ServeFile 不会。



附录
您的第二个问题,您如何进行自定义不幸的是,NotFound处理程序不容易回答。因为这是从内部函数 serveFile 调用的,因此您没有超级简单的地方可以打开它。可能有一些偷偷摸摸的事情,例如拦截你自己的 ResponseWriter 来拦截404响应代码,但我会将这个练习留给你。


I'm a little bit confused. Much of examples shows usage of both: http.ServeFile(..) and http.FileServer(..), but seems they have very close functionality. Also I have found no information about how to set custom NotFound handler.

// This works and strip "/static/" fragment from path
fs := http.FileServer(http.Dir("static"))
http.Handle("/static/", http.StripPrefix("/static/", fs))

// This works too, but "/static2/" fragment remains and need to be striped manually
http.HandleFunc("/static2/", func(w http.ResponseWriter, r *http.Request) {
    http.ServeFile(w, r, r.URL.Path[1:])
})

http.ListenAndServe(":8080", nil)

I've tried to read source code and both of them use serveFile(ResponseWriter, *Request, FileSystem, string, bool) underlying function. However http.FileServer return fileHandler with its own ServeHTTP() method and make some preparation work before serving file (eg path.Clean()).

So why need this separation? Which method better to use? And how can I set custom NotFound handler, for example when requested file not found?

解决方案

The main difference is that http.FileServer does effectively almost 1:1 mapping of an HTTP prefix with a filesystem. In plain english, it serves up an entire directory path. and all its children.

Say you had a directory called /home/bob/static and you had this setup:

fs := http.FileServer(http.Dir("/home/bob/static"))
http.Handle("/static/", http.StripPrefix("/static", fs))

Your server would take requests for e.g. /static/foo/bar and serve whatever is at /home/bob/static/foo/bar (or 404)

In contrast, the ServeFile is a lower level helper that can be used to implement something similar to FileServer, or implement your own path munging potentially, and any number of things. It simply takes the named local file and sends it over the HTTP connection. By itself, it won't serve a whole directory prefix (unless you wrote a handler that did some lookup similar to FileServer)

NOTE Serving up a filesystem naively is a potentially dangerous thing (there are potentially ways to break out of the rooted tree) hence I recommend that unless you really know what you're doing, use http.FileServer and http.Dir as they include checks to make sure people can't break out of the FS, which ServeFile doesn't.

Addendum Your secondary question, how do you do a custom NotFound handler, unfortunately, is not easily answered. Because this is called from internal function serveFile as you noticed, there's no super easy place to break into that. There are potentially some sneaky things like intercepting the response with your own ResponseWriter which intercepts the 404 response code, but I'll leave that exercise to you.

这篇关于Golang。要使用什么? http.ServeFile(..)或http.FileServer(..)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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