高朗.用什么?http.ServeFile(..) 还是 http.FileServer(..)? [英] Golang. What to use? http.ServeFile(..) or http.FileServer(..)?

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

问题描述

我有点困惑.许多示例都显示了两者的用法:http.ServeFile(..)http.FileServer(..),但它们似乎具有非常接近的功能.我也没有找到有关如何设置自定义 NotFound 处理程序的信息.

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)

我尝试阅读源代码,他们都使用 serveFile(ResponseWriter, *Request, FileSystem, string, bool) 底层函数.但是 http.FileServer 返回 fileHandler 和它自己的 ServeHTTP() 方法并在服务文件之前做一些准备工作(例如 path.Clean()).

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()).

那为什么需要这种分离呢?使用哪种方法更好?以及如何设置自定义 NotFound 处理程序,例如在找不到请求的文件时?

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?

推荐答案

主要区别在于 http.FileServer 可以有效地将 HTTP 前缀与文件系统进行几乎 1:1 的映射.用简单的英语,它提供了一个完整的目录路径.以及它所有的孩子.

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.

假设您有一个名为 /home/bob/static 的目录,并且您进行了以下设置:

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))

您的服务器会接受请求,例如/static/foo/bar 并提供 /home/bob/static/foo/bar(或 404)

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

相比之下,ServeFile 是一个较低级别的帮助程序,可用于实现类似于 FileServer 的东西,或实现您自己的潜在路径调整,以及任何数量的东西.它只是获取命名的本地文件并通过 HTTP 连接发送它.就其本身而言,它不会提供整个目录前缀(除非您编写了一个执行类似于 FileServer 的查找的处理程序)

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)

注意 天真地提供文件系统是一件潜在的危险事情(有可能突破根树的方法)因此我建议除非您真的知道什么你正在做,使用 http.FileServerhttp.Dir 因为它们包括检查以确保人们不能突破 FS,ServeFile 没有.

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.

附录你的第二个问题,不幸的是,你如何做一个自定义的 NotFound 处理程序并不容易回答.因为这是从内部函数 serveFile 调用的,正如您所注意到的,没有非常容易的地方可以破解它.可能有一些偷偷摸摸的事情,比如用你自己的 ResponseWriter 拦截响应,它拦截 404 响应代码,但我会把这个练习留给你.

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.

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

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