mirror of
https://github.com/hamburghammer/gohttpserver.git
synced 2025-03-14 07:15:56 +01:00
support .ghs.yml add google analytics
This commit is contained in:
parent
2a229b80ab
commit
43cb263853
7 changed files with 118 additions and 29 deletions
1
.fsw.yml
1
.fsw.yml
|
@ -2,6 +2,7 @@ desc: Auto generated by fswatch [gohttp-vue]
|
|||
triggers:
|
||||
- name: ""
|
||||
pattens:
|
||||
- '!.git/'
|
||||
- '**/*.go'
|
||||
- '**/*.tmpl.html'
|
||||
env:
|
||||
|
|
21
README.md
21
README.md
|
@ -41,7 +41,7 @@ Upload size now limited to 1G
|
|||
1. [x] Hidden work `download` and `qrcode` in small screen
|
||||
1. [x] Theme select support
|
||||
1. [x] OK to working behide Nginx
|
||||
1. [ ] \.htaccess support
|
||||
1. [ ] \.ghs.yml support (like \.htaccess)
|
||||
1. [ ] Calculate md5sum and sha
|
||||
1. [ ] Folder upload
|
||||
1. [ ] Support sort by size or modified time
|
||||
|
@ -64,6 +64,25 @@ Listen port 8000 on all interface, and enable upload
|
|||
./gohttpserver -r ./ --addr :8000 --upload
|
||||
```
|
||||
|
||||
## Advanced usage
|
||||
Support update access rule if there is a file named `.ghs.yml` under directory. `.ghs.yml` example
|
||||
|
||||
```yaml
|
||||
---
|
||||
upload: false
|
||||
```
|
||||
|
||||
For example, if there is such file under directory `foo`, directory `foo` can not be uploaded, while `bar` can't.
|
||||
|
||||
```
|
||||
root -
|
||||
|-- foo
|
||||
| |-- .ghs.yml
|
||||
| `-- world.txt
|
||||
`-- bar
|
||||
`-- hello.txt
|
||||
```
|
||||
|
||||
### ipa plist proxy
|
||||
This is used for server which not https enabled. default use <https://plistproxy.herokuapp.com/plist>
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-yaml/yaml"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
|
@ -23,11 +24,12 @@ type IndexFileItem struct {
|
|||
}
|
||||
|
||||
type HTTPStaticServer struct {
|
||||
Root string
|
||||
Theme string
|
||||
Upload bool
|
||||
Title string
|
||||
PlistProxy string
|
||||
Root string
|
||||
Theme string
|
||||
Upload bool
|
||||
Title string
|
||||
PlistProxy string
|
||||
GoogleTrackerId string
|
||||
|
||||
indexes []IndexFileItem
|
||||
m *mux.Router
|
||||
|
@ -41,7 +43,7 @@ func NewHTTPStaticServer(root string) *HTTPStaticServer {
|
|||
if !strings.HasSuffix(root, "/") {
|
||||
root = root + "/"
|
||||
}
|
||||
log.Printf("Root path: %s\n", root)
|
||||
log.Printf("root path: %s\n", root)
|
||||
m := mux.NewRouter()
|
||||
s := &HTTPStaticServer{
|
||||
Root: root,
|
||||
|
@ -50,10 +52,12 @@ func NewHTTPStaticServer(root string) *HTTPStaticServer {
|
|||
}
|
||||
|
||||
go func() {
|
||||
time.Sleep(1 * time.Second)
|
||||
for {
|
||||
log.Println("making fs index ...")
|
||||
startTime := time.Now()
|
||||
log.Println("Started making search index")
|
||||
s.makeIndex()
|
||||
log.Println("indexing finished, next index after 10 minutes")
|
||||
log.Printf("Completed search index in %v", time.Since(startTime))
|
||||
//time.Sleep(time.Second * 1)
|
||||
time.Sleep(time.Minute * 10)
|
||||
}
|
||||
|
@ -101,6 +105,15 @@ func (s *HTTPStaticServer) hStatus(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
func (s *HTTPStaticServer) hUpload(w http.ResponseWriter, req *http.Request) {
|
||||
path := mux.Vars(req)["path"]
|
||||
|
||||
// check auth
|
||||
auth := s.readAccessConf(path)
|
||||
if !auth.Upload {
|
||||
http.Error(w, "Upload forbidden", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
err := req.ParseMultipartForm(1 << 30) // max memory 1G
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
|
@ -111,7 +124,6 @@ func (s *HTTPStaticServer) hUpload(w http.ResponseWriter, req *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
path := mux.Vars(req)["path"]
|
||||
dirpath := filepath.Join(s.Root, path)
|
||||
|
||||
for _, mfile := range req.MultipartForm.File["file"] {
|
||||
|
@ -263,6 +275,10 @@ type ListResponse struct {
|
|||
Size string `json:"size"`
|
||||
}
|
||||
|
||||
type AccessConf struct {
|
||||
Upload bool `yaml:"upload" json:"upload"`
|
||||
}
|
||||
|
||||
func (s *HTTPStaticServer) hJSONList(w http.ResponseWriter, r *http.Request) {
|
||||
requestPath := mux.Vars(r)["path"]
|
||||
localPath := filepath.Join(s.Root, requestPath)
|
||||
|
@ -292,6 +308,7 @@ func (s *HTTPStaticServer) hJSONList(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
// turn file list -> json
|
||||
lrs := make([]ListResponse, 0)
|
||||
for path, info := range fileInfoMap {
|
||||
lr := ListResponse{
|
||||
|
@ -318,7 +335,10 @@ func (s *HTTPStaticServer) hJSONList(w http.ResponseWriter, r *http.Request) {
|
|||
lrs = append(lrs, lr)
|
||||
}
|
||||
|
||||
data, _ := json.Marshal(lrs)
|
||||
data, _ := json.Marshal(map[string]interface{}{
|
||||
"files": lrs,
|
||||
"auth": s.readAccessConf(requestPath),
|
||||
})
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(data)
|
||||
}
|
||||
|
@ -366,6 +386,29 @@ func (s *HTTPStaticServer) findIndex(text string) []IndexFileItem {
|
|||
return ret
|
||||
}
|
||||
|
||||
func (s *HTTPStaticServer) defaultAccessConf() AccessConf {
|
||||
return AccessConf{
|
||||
Upload: s.Upload,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *HTTPStaticServer) readAccessConf(requestPath string) (ac AccessConf) {
|
||||
ac = s.defaultAccessConf()
|
||||
cfgFile := filepath.Join(s.Root, requestPath, ".ghs.yml")
|
||||
data, err := ioutil.ReadFile(cfgFile)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return
|
||||
}
|
||||
log.Printf("Err read .ghs.yml: %v", err)
|
||||
}
|
||||
err = yaml.Unmarshal(data, &ac)
|
||||
if err != nil {
|
||||
log.Printf("Err format .ghs.yml: %v", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func deepPath(basedir, name string) string {
|
||||
isDir := true
|
||||
// loop max 5, incase of for loop not finished
|
||||
|
|
32
main.go
32
main.go
|
@ -18,24 +18,25 @@ import (
|
|||
)
|
||||
|
||||
type Configure struct {
|
||||
Addr string
|
||||
Root string
|
||||
HttpAuth string
|
||||
Cert string
|
||||
Key string
|
||||
Cors bool
|
||||
Theme string
|
||||
XHeaders bool
|
||||
Upload bool
|
||||
PlistProxy *url.URL
|
||||
Title string
|
||||
Addr string
|
||||
Root string
|
||||
HttpAuth string
|
||||
Cert string
|
||||
Key string
|
||||
Cors bool
|
||||
Theme string
|
||||
XHeaders bool
|
||||
Upload bool
|
||||
PlistProxy *url.URL
|
||||
Title string
|
||||
GoogleTrackerId string
|
||||
}
|
||||
|
||||
type logger struct {
|
||||
}
|
||||
|
||||
func (l logger) Log(record accesslog.LogRecord) {
|
||||
log.Printf("%s [code %d] %s", record.Method, record.Status, record.Uri)
|
||||
log.Printf("%s - %s %d %s", record.Ip, record.Method, record.Status, record.Uri)
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -83,6 +84,7 @@ func parseFlags() {
|
|||
kingpin.Flag("cors", "enable cross-site HTTP request").BoolVar(&gcfg.Cors)
|
||||
kingpin.Flag("plistproxy", "plist proxy when server is not https").Default(defaultPlistProxy).Short('p').URLVar(&gcfg.PlistProxy)
|
||||
kingpin.Flag("title", "server title").Default("Go HTTP File Server").StringVar(&gcfg.Title)
|
||||
kingpin.Flag("google-tracker-id", "set to empty to disable it").Default("UA-81205425-2").StringVar(&gcfg.GoogleTrackerId)
|
||||
|
||||
kingpin.Parse()
|
||||
}
|
||||
|
@ -93,6 +95,7 @@ func main() {
|
|||
ss := NewHTTPStaticServer(gcfg.Root)
|
||||
ss.Theme = gcfg.Theme
|
||||
ss.Title = gcfg.Title
|
||||
ss.GoogleTrackerId = gcfg.GoogleTrackerId
|
||||
|
||||
if gcfg.Upload {
|
||||
ss.EnableUpload()
|
||||
|
@ -129,7 +132,10 @@ func main() {
|
|||
w.Write(data)
|
||||
})
|
||||
|
||||
log.Printf("Listening on addr: %s\n", strconv.Quote(gcfg.Addr))
|
||||
if !strings.Contains(gcfg.Addr, ":") {
|
||||
gcfg.Addr = ":" + gcfg.Addr
|
||||
}
|
||||
log.Printf("listening on %s\n", strconv.Quote(gcfg.Addr))
|
||||
|
||||
var err error
|
||||
if gcfg.Key != "" && gcfg.Cert != "" {
|
||||
|
|
|
@ -67,11 +67,9 @@
|
|||
<button class="btn btn-xs btn-default" v-on:click='toggleHidden()'>
|
||||
Show hidden <i class="fa" v-bind:class='showHidden ? "fa-eye" : "fa-eye-slash"'></i>
|
||||
</button>
|
||||
[[ if .Upload ]]
|
||||
<button class="btn btn-xs btn-default" data-toggle="modal" data-target="#upload-modal">
|
||||
<button class="btn btn-xs btn-default" v-if="auth.upload" data-toggle="modal" data-target="#upload-modal">
|
||||
Upload file <i class="fa fa-upload"></i>
|
||||
</button>
|
||||
[[ end ]]
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -179,6 +177,24 @@
|
|||
<script src="/-/res/js/dropzone.js"></script>
|
||||
<script src="/-/res/bootstrap-3.3.5/js/bootstrap.min.js"></script>
|
||||
<script src="/-/res/js/index.js"></script>
|
||||
[[if .GoogleTrackerId ]]
|
||||
<script>
|
||||
(function(i, s, o, g, r, a, m) {
|
||||
i['GoogleAnalyticsObject'] = r;
|
||||
i[r] = i[r] || function() {
|
||||
(i[r].q = i[r].q || []).push(arguments)
|
||||
}, i[r].l = 1 * new Date();
|
||||
a = s.createElement(o),
|
||||
m = s.getElementsByTagName(o)[0];
|
||||
a.async = 1;
|
||||
a.src = g;
|
||||
m.parentNode.insertBefore(a, m)
|
||||
})(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga');
|
||||
|
||||
ga('create', '[[.GoogleTrackerId]]', 'auto');
|
||||
ga('send', 'pageview');
|
||||
</script>
|
||||
[[ end ]]
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
|
@ -27,6 +27,7 @@ var vm = new Vue({
|
|||
showHidden: false,
|
||||
previewFile: null,
|
||||
version: "loading",
|
||||
auth: {},
|
||||
search: getQueryString("search"),
|
||||
files: [{
|
||||
name: "loading ...",
|
||||
|
@ -200,13 +201,14 @@ function loadFileList(pathname) {
|
|||
dataType: "json",
|
||||
cache: false,
|
||||
success: function(res) {
|
||||
res.sort(function(a, b) {
|
||||
res.files.sort(function(a, b) {
|
||||
var obj2n = function(v) {
|
||||
return v.type == "dir" ? 0 : 1;
|
||||
}
|
||||
return obj2n(a) - obj2n(b);
|
||||
})
|
||||
vm.files = res;
|
||||
vm.files = res.files;
|
||||
vm.auth = res.auth;
|
||||
},
|
||||
error: function(err) {
|
||||
console.error(err)
|
||||
|
|
2
testdata/uploadable/.ghs.yml
vendored
Normal file
2
testdata/uploadable/.ghs.yml
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
upload: true
|
Loading…
Add table
Reference in a new issue