Skip to content

Commit

Permalink
Merge pull request #64 from chenwx36/master
Browse files Browse the repository at this point in the history
better features
  • Loading branch information
codeskyblue committed Mar 2, 2019
2 parents c8d67ed + fdec6aa commit 85b2bd5
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 30 deletions.
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ docker run -it --rm -p 8000:8000 -v $PWD:/app/public --name gohttpserver \
--auth-type openid
```

To build image yourself, please change the PWD to the root of this repo.

```bash
cd gohttpserver/
docker build -t codeskyblue/gohttpserver -f docker/Dockerfile .
```

## Authentication options
- Enable basic http authentication

Expand All @@ -111,11 +118,23 @@ docker run -it --rm -p 8000:8000 -v $PWD:/app/public --name gohttpserver \
$ gohttpserver --auth-type openid --auth-openid https://login.example-hostname.com/openid/
```

- Use oauth2 with (TODO: need more details)
- Use oauth2-proxy with

```sh
$ gohttpserver --auth-type oauth2-proxy
```
You can configure to let a http reverse proxy handling authentication.
When using oauth2-proxy, the backend will use identification info from request headers `X-Auth-Request-Email` as userId and `X-Auth-Request-Fullname` as user's display name.
Please config your oauth2 reverse proxy yourself.
More about [oauth2-proxy](https://github.com/bitly/oauth2_proxy).

All required headers list as following.

|header|value|
|---|---|
|X-Auth-Request-Email| userId |
|X-Auth-Request-Fullname| user's display name(urlencoded) |
|X-Auth-Request-User| user's nickname (mostly email prefix) |

- Enable upload

Expand Down
2 changes: 1 addition & 1 deletion assets/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@
<td class="hidden-xs">{{formatTime(f.mtime)}}</td>
<td style="text-align: left">
<template v-if="f.type == 'dir'">
<a class="btn btn-default btn-xs" href="/-/zip/{{f.path}}">
<a class="btn btn-default btn-xs" href="/{{f.path}}/?op=archive">
<span class="hidden-xs">Archive</span> Zip
<span class="glyphicon glyphicon-download-alt"></span>
</a>
Expand Down
44 changes: 31 additions & 13 deletions assets/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,22 @@ function getQueryString(name) {
return null;
}

function checkPathNameLegal(name) {
var reg = new RegExp("[\\/:*<>|]");
var r = name.match(reg)
return r == null;
}

function showErrorMessage(jqXHR) {
let errMsg = jqXHR.getResponseHeader("x-auth-authentication-message")
if (errMsg == null) {
errMsg = jqXHR.responseText
}
alert(String(jqXHR.status).concat(":", errMsg));
console.error(errMsg)
}


var vm = new Vue({
el: "#app",
data: {
Expand Down Expand Up @@ -243,31 +259,38 @@ var vm = new Vue({
$("#file-info-content").text(JSON.stringify(res, null, 4));
$("#file-info-modal").modal("show");
// console.log(JSON.stringify(res, null, 4));
},
error: function (jqXHR, textStatus, errorThrown) {
showErrorMessage(jqXHR)
}
})
},
makeDirectory: function () {
var name = window.prompt("Directory name?")
var name = window.prompt("current path: " + location.pathname + "\nplease enter the new directory name", "")
console.log(name)
if (!name) {
return
}
if(!checkPathNameLegal(name)) {
alert("Name should not contains any of \\/:*<>|")
return
}
$.ajax({
url: pathJoin(["/", location.pathname, "/", name]),
method: "POST",
success: function (res) {
console.log(res)
loadFileList()
},
error: function (err) {
alert(err.responseText);
error: function (jqXHR, textStatus, errorThrown) {
showErrorMessage(jqXHR)
}
})
},
deletePathConfirm: function (f, e) {
e.preventDefault();
if (!e.altKey) { // skip confirm when alt pressed
if (!window.confirm("Delete " + f.name + " ?")) {
if (!window.confirm("Delete " + location.pathname + "/" + f.name + " ?")) {
return;
}
}
Expand All @@ -277,8 +300,8 @@ var vm = new Vue({
success: function (res) {
loadFileList()
},
error: function (err) {
alert(err.responseText);
error: function (jqXHR, textStatus, errorThrown) {
showErrorMessage(jqXHR)
}
});
},
Expand Down Expand Up @@ -369,20 +392,15 @@ function loadFileList(pathname) {
})
vm.files = res.files;
vm.auth = res.auth;
vm.updateBreadcrumb(pathname);
},
error: function (jqXHR, textStatus, errorThrown) {
let errMsg = jqXHR.getResponseHeader("x-auth-authentication-message")
if (errMsg == null) {
errMsg = jqXHR.statusText
}
alert(String(jqXHR.status).concat(":", errMsg));
console.error(errMsg)
showErrorMessage(jqXHR)
},
});

}

vm.updateBreadcrumb(pathname);
vm.previewMode = getQueryString("raw") == "false";
if (vm.previewMode) {
vm.loadPreviewFile();
Expand Down
27 changes: 12 additions & 15 deletions httpstaticserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,18 +83,10 @@ func NewHTTPStaticServer(root string) *HTTPStaticServer {
}
}()

m.HandleFunc("/-/status", s.hStatus) //unused
m.HandleFunc("/-/zip/{path:.*}", s.hZip)
m.HandleFunc("/-/unzip/{zip_path:.*}/-/{path:.*}", s.hUnzip)
m.HandleFunc("/-/json/{path:.*}", s.hJSONList)
// routers for Apple *.ipa
m.HandleFunc("/-/ipa/plist/{path:.*}", s.hPlist)
m.HandleFunc("/-/ipa/link/{path:.*}", s.hIpaLink)

// TODO: /ipa/info
m.HandleFunc("/-/info/{path:.*}", s.hInfo)
m.HandleFunc("/-/mkdir/{path:.*}", s.hMkdir)

m.HandleFunc("/{path:.*}", s.hIndex).Methods("GET", "HEAD")
m.HandleFunc("/{path:.*}", s.hUploadOrMkdir).Methods("POST")
m.HandleFunc("/{path:.*}", s.hDelete).Methods("DELETE")
Expand All @@ -118,6 +110,11 @@ func (s *HTTPStaticServer) hIndex(w http.ResponseWriter, r *http.Request) {
return
}

if r.FormValue("op") == "archive" {
s.hZip(w, r)
return
}

log.Println("GET", path, relPath)
if r.FormValue("raw") == "false" || isDir(relPath) {
if r.Method == "HEAD" {
Expand All @@ -139,12 +136,6 @@ func (s *HTTPStaticServer) hIndex(w http.ResponseWriter, r *http.Request) {
}
}

func (s *HTTPStaticServer) hStatus(w http.ResponseWriter, r *http.Request) {
data, _ := json.MarshalIndent(s, "", " ")
w.Header().Set("Content-Type", "application/json")
w.Write(data)
}

func (s *HTTPStaticServer) hMkdir(w http.ResponseWriter, req *http.Request) {
path := filepath.Dir(mux.Vars(req)["path"])
auth := s.readAccessConf(path)
Expand Down Expand Up @@ -174,9 +165,15 @@ func (s *HTTPStaticServer) hDelete(w http.ResponseWriter, req *http.Request) {
http.Error(w, "Delete forbidden", http.StatusForbidden)
return
}

err := os.Remove(filepath.Join(s.Root, path))
if err != nil {
http.Error(w, err.Error(), 500)
pathErr, ok := err.(*os.PathError)
if ok{
http.Error(w, pathErr.Op + " " + path + ": " + pathErr.Err.Error(), 500)
} else {
http.Error(w, err.Error(), 500)
}
return
}
w.Write([]byte("Success"))
Expand Down

0 comments on commit 85b2bd5

Please sign in to comment.