瀏覽代碼

add static middleware module

tags/v0.9.0
jimzhan 9 年之前
父節點
當前提交
2a93e14d0d
共有 1 個文件被更改,包括 94 次插入0 次删除
  1. +94
    -0
      modules/static.go

+ 94
- 0
modules/static.go 查看文件

@@ -0,0 +1,94 @@
/* ----------------------------------------------------------------------
* ______ ___ __
* / ____/___ / | ____ __ ___ __/ /_ ___ ________
* / / __/ __ \/ /| | / __ \/ / / / | /| / / __ \/ _ \/ ___/ _ \
* / /_/ / /_/ / ___ |/ / / / /_/ /| |/ |/ / / / / __/ / / __/
* \____/\____/_/ |_/_/ /_/\__. / |__/|__/_/ /_/\___/_/ \___/
* /____/
*
* (C) Copyright 2015 GoAnywhere (http://goanywhere.io).
* ----------------------------------------------------------------------
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ----------------------------------------------------------------------*/
package modules

import (
"net/http"
"path"
"strings"
)

// Static serves as file server for static assets,
// as convention, the given dir name will be used as the URL prefix.
func Static(dir string) func(http.Handler) http.Handler {
var (
fs = http.Dir(dir)
prefix = path.Join("/", dir)
)
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Accepts http GET | HEAD Only, ignores all requests not started with prefix.
if r.Method != "GET" && r.Method != "HEAD" {
next.ServeHTTP(w, r)
return
} else if !strings.HasPrefix(r.URL.Path, prefix) {
next.ServeHTTP(w, r)
return
}

filename := strings.TrimPrefix(r.URL.Path, prefix)
if filename != "" && filename[0] != '/' {
next.ServeHTTP(w, r)
return
}

file, err := fs.Open(filename)
if err != nil {
next.ServeHTTP(w, r)
return
}
defer file.Close()

stat, err := file.Stat()
if err != nil {
next.ServeHTTP(w, r)
return
}

// try to serve index filename
if stat.IsDir() {
// redirect if missing trailing slash
if !strings.HasSuffix(r.URL.Path, "/") {
http.Redirect(w, r, r.URL.Path+"/", http.StatusFound)
return
}

filename = path.Join(filename, "index.html")
file, err = fs.Open(filename)
if err != nil {
next.ServeHTTP(w, r)
return
}
defer file.Close()

stat, err = file.Stat()
if err != nil || stat.IsDir() {
next.ServeHTTP(w, r)
return
}
}

http.ServeContent(w, r, filename, stat.ModTime(), file)
})
}
}

Loading…
取消
儲存