diff --git a/.travis.yml b/.travis.yml index 90c3b8b..dafae61 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,7 @@ language: go go: - 1.5 - 1.6 + - 1.7 env: global: - GO15VENDOREXPERIMENT=1 diff --git a/README.md b/README.md index 0332f4c..85d021e 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,16 @@ root - Use config file. specfied with `--conf`, see [example config.yml](testdata/config.yml). Note that command line option can overwrite conf in `config.yml` +block visual some files, just add the following code to `.ghs.yml` + +```yaml +accessTables: +- regex: block.file + allow: false +- regex: visual.file + allow: true +``` + ### ipa plist proxy This is used for server which not https enabled. default use diff --git a/httpstaticserver.go b/httpstaticserver.go index 89c19a2..641db81 100644 --- a/httpstaticserver.go +++ b/httpstaticserver.go @@ -15,6 +15,8 @@ import ( "strings" "time" + "regexp" + "github.com/go-yaml/yaml" "github.com/gorilla/mux" ) @@ -333,15 +335,42 @@ type HTTPFileInfo struct { ModTime int64 `json:"mtime"` } +type AccessTable struct { + Regex string `yaml:"regex"` + Allow bool `yaml:"allow"` +} + type AccessConf struct { - Upload bool `yaml:"upload" json:"upload"` - Delete bool `yaml:"delete" json:"delete"` + Upload bool `yaml:"upload" json:"upload"` + Delete bool `yaml:"delete" json:"delete"` + AccessTables []AccessTable `yaml:"accessTables"` +} + +var reCache = make(map[string]*regexp.Regexp) + +func (c *AccessConf) checkAccess(fileName string) bool { + for _, table := range c.AccessTables { + pattern, ok := reCache[table.Regex] + if !ok { + pattern, _ = regexp.Compile(table.Regex) + reCache[table.Regex] = pattern + } + // skip wrong format regex + if pattern == nil { + continue + } + if pattern.MatchString(fileName) { + return table.Allow + } + } + return true } func (s *HTTPStaticServer) hJSONList(w http.ResponseWriter, r *http.Request) { requestPath := mux.Vars(r)["path"] localPath := filepath.Join(s.Root, requestPath) search := r.FormValue("search") + auth := s.readAccessConf(requestPath) // path string -> info os.FileInfo fileInfoMap := make(map[string]os.FileInfo, 0) @@ -370,6 +399,9 @@ func (s *HTTPStaticServer) hJSONList(w http.ResponseWriter, r *http.Request) { // turn file list -> json lrs := make([]HTTPFileInfo, 0) for path, info := range fileInfoMap { + if !auth.checkAccess(info.Name()) { + continue + } lr := HTTPFileInfo{ Name: info.Name(), Path: path, @@ -397,7 +429,7 @@ func (s *HTTPStaticServer) hJSONList(w http.ResponseWriter, r *http.Request) { data, _ := json.Marshal(map[string]interface{}{ "files": lrs, - "auth": s.readAccessConf(requestPath), + "auth": auth, }) w.Header().Set("Content-Type", "application/json") w.Write(data) diff --git a/main.go b/main.go index 3d98673..a429162 100644 --- a/main.go +++ b/main.go @@ -25,7 +25,7 @@ type Configure struct { Conf *os.File `yaml:"-"` Addr string `yaml:"addr"` Root string `yaml:"root"` - HttpAuth string `yaml:"httpauth"` + HTTPAuth string `yaml:"httpauth"` Cert string `yaml:"cert"` Key string `yaml:"key"` Cors bool `yaml:"cors"` @@ -38,8 +38,7 @@ type Configure struct { GoogleTrackerId string `yaml:"google-tracker-id"` } -type logger struct { -} +type logger struct{} func (l logger) Log(record accesslog.LogRecord) { log.Printf("%s - %s %d %s", record.Ip, record.Method, record.Status, record.Uri) @@ -92,7 +91,7 @@ func parseFlags() error { kingpin.Flag("addr", "listen address, default :8000").Short('a').StringVar(&gcfg.Addr) kingpin.Flag("cert", "tls cert.pem path").StringVar(&gcfg.Cert) kingpin.Flag("key", "tls key.pem path").StringVar(&gcfg.Key) - kingpin.Flag("httpauth", "HTTP basic auth (ex: user:pass)").StringVar(&gcfg.HttpAuth) + kingpin.Flag("httpauth", "HTTP basic auth (ex: user:pass)").StringVar(&gcfg.HTTPAuth) kingpin.Flag("theme", "web theme, one of ").StringVar(&gcfg.Theme) kingpin.Flag("upload", "enable upload support").BoolVar(&gcfg.Upload) kingpin.Flag("xheaders", "used when behide nginx").BoolVar(&gcfg.XHeaders) @@ -146,7 +145,7 @@ func main() { hdlr = accesslog.NewLoggingHandler(hdlr, l) // HTTP Basic Authentication - userpass := strings.SplitN(gcfg.HttpAuth, ":", 2) + userpass := strings.SplitN(gcfg.HTTPAuth, ":", 2) if len(userpass) == 2 { user, pass := userpass[0], userpass[1] hdlr = httpauth.SimpleBasicAuth(user, pass)(hdlr) diff --git a/testdata/deletable/.ghs.yml b/testdata/deletable/.ghs.yml index 886d0ea..b2f39f2 100644 --- a/testdata/deletable/.ghs.yml +++ b/testdata/deletable/.ghs.yml @@ -1,2 +1,7 @@ upload: true delete: true +accessTables: +- regex: block.file + allow: false +- regex: visual.file + allow: true \ No newline at end of file diff --git a/testdata/deletable/block.file b/testdata/deletable/block.file new file mode 100644 index 0000000..e69de29 diff --git a/testdata/deletable/other.file b/testdata/deletable/other.file new file mode 100644 index 0000000..e69de29 diff --git a/testdata/deletable/visual.file b/testdata/deletable/visual.file new file mode 100644 index 0000000..e69de29