io.Readerio.Readerwww.baidu.comhttp://localhost:8080/

通过这篇文章你可以学到:

  1. 托管一个静态文件

  2. 托管一个目录

  3. 如何实现FTP服务器效果

  4. 自定义托管内容类型

  5. 托管一个Reader

  6. 静态文件托管原理分析

  7. Gin是如何禁止目录列表的

  8. 镜像百度网站

  9. 封装一个直接拿来用的镜像服务代理

  10. 多域名API服务聚合(API 网关?),解决CROS跨域问题

精彩文章推荐

flysnow_org

托管一个静态文件

StaticFile
func main() {
    router := gin.Default()
    router.StaticFile("/adobegc.log", "/tmp/adobegc.log")
    router.Run(":8080")
}
StaticFile/tmp/adobegc.log/adobegc.loghttp://localhost:8080/adobegc.log
Content-Type
StaticFile

托管一个目录

Static
router.Static("/static", "/tmp")
Static
http://localhost:8080/static/adobegc.logadobegc.loghttp://localhost:8080/adobegc.log

实现一个FTP服务器

http://localhost:8080/static/
http://localhost:8080/static//tmp/
router.StaticFS("/static1", gin.Dir("/tmp", true))
StaticFS/static1
gin.Dirtrue
// if listDirectory == true, then it works the same as http.Dir() otherwise it returns
// a filesystem that prevents http.FileServer() to list the directory files.
func Dir(root string, listDirectory bool) http.FileSystem 
http://localhost:8080/static1/

自定义托管内容类型

以上的示例都是托管一个静态文件或者目录,我们并没有太多的自定义能力,比如设置内容类型,托管一个文件的部分内容等等。

Dataadobegc.log
router.GET("/adobegc.log", func(c *gin.Context) {
    data, err := ioutil.ReadFile("/tmp/adobegc.log")
    if err != nil {
        c.AbortWithError(500, err)
    } else {
        c.Data(200, "text/plain; charset=utf-8", data)
    }
})
c.Data
func (c *Context) Data(code int, contentType string, data []byte) 
contentTypedata

功能更强大的Reader托管。

[]byteio.ReaderDataFromReader
func (c *Context) DataFromReader(code int, contentLength int64, contentType string, reader io.Reader, extraHeaders map[string]string)

从上面的方法签名我们可以看到我们可以自定义的内容:

  1. 要显示的内容长度

  2. 内容的类型

  3. 一个内容源Reader

  4. 响应的头信息extraHeaders

Data

基于源代码分析原理

会使用和知道原理是两码事,面试的时候,面试官也喜欢问具体的源代码实现,这样才能更看出一个人的能力。

localhost:8080
StaticFile