Skip to content

Commit 85b2bd5

Browse files
authored
Merge pull request codeskyblue#64 from chenwx36/master
better features
2 parents c8d67ed + fdec6aa commit 85b2bd5

File tree

4 files changed

+64
-30
lines changed

4 files changed

+64
-30
lines changed

README.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,13 @@ docker run -it --rm -p 8000:8000 -v $PWD:/app/public --name gohttpserver \
9898
--auth-type openid
9999
```
100100

101+
To build image yourself, please change the PWD to the root of this repo.
102+
103+
```bash
104+
cd gohttpserver/
105+
docker build -t codeskyblue/gohttpserver -f docker/Dockerfile .
106+
```
107+
101108
## Authentication options
102109
- Enable basic http authentication
103110

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

114-
- Use oauth2 with (TODO: need more details)
121+
- Use oauth2-proxy with
115122

116123
```sh
117124
$ gohttpserver --auth-type oauth2-proxy
118125
```
126+
You can configure to let a http reverse proxy handling authentication.
127+
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.
128+
Please config your oauth2 reverse proxy yourself.
129+
More about [oauth2-proxy](https://github.com/bitly/oauth2_proxy).
130+
131+
All required headers list as following.
132+
133+
|header|value|
134+
|---|---|
135+
|X-Auth-Request-Email| userId |
136+
|X-Auth-Request-Fullname| user's display name(urlencoded) |
137+
|X-Auth-Request-User| user's nickname (mostly email prefix) |
119138

120139
- Enable upload
121140

assets/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@
141141
<td class="hidden-xs">{{formatTime(f.mtime)}}</td>
142142
<td style="text-align: left">
143143
<template v-if="f.type == 'dir'">
144-
<a class="btn btn-default btn-xs" href="/-/zip/{{f.path}}">
144+
<a class="btn btn-default btn-xs" href="/{{f.path}}/?op=archive">
145145
<span class="hidden-xs">Archive</span> Zip
146146
<span class="glyphicon glyphicon-download-alt"></span>
147147
</a>

assets/js/index.js

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,22 @@ function getQueryString(name) {
2121
return null;
2222
}
2323

24+
function checkPathNameLegal(name) {
25+
var reg = new RegExp("[\\/:*<>|]");
26+
var r = name.match(reg)
27+
return r == null;
28+
}
29+
30+
function showErrorMessage(jqXHR) {
31+
let errMsg = jqXHR.getResponseHeader("x-auth-authentication-message")
32+
if (errMsg == null) {
33+
errMsg = jqXHR.responseText
34+
}
35+
alert(String(jqXHR.status).concat(":", errMsg));
36+
console.error(errMsg)
37+
}
38+
39+
2440
var vm = new Vue({
2541
el: "#app",
2642
data: {
@@ -243,31 +259,38 @@ var vm = new Vue({
243259
$("#file-info-content").text(JSON.stringify(res, null, 4));
244260
$("#file-info-modal").modal("show");
245261
// console.log(JSON.stringify(res, null, 4));
262+
},
263+
error: function (jqXHR, textStatus, errorThrown) {
264+
showErrorMessage(jqXHR)
246265
}
247266
})
248267
},
249268
makeDirectory: function () {
250-
var name = window.prompt("Directory name?")
269+
var name = window.prompt("current path: " + location.pathname + "\nplease enter the new directory name", "")
251270
console.log(name)
252271
if (!name) {
253272
return
254273
}
274+
if(!checkPathNameLegal(name)) {
275+
alert("Name should not contains any of \\/:*<>|")
276+
return
277+
}
255278
$.ajax({
256279
url: pathJoin(["/", location.pathname, "/", name]),
257280
method: "POST",
258281
success: function (res) {
259282
console.log(res)
260283
loadFileList()
261284
},
262-
error: function (err) {
263-
alert(err.responseText);
285+
error: function (jqXHR, textStatus, errorThrown) {
286+
showErrorMessage(jqXHR)
264287
}
265288
})
266289
},
267290
deletePathConfirm: function (f, e) {
268291
e.preventDefault();
269292
if (!e.altKey) { // skip confirm when alt pressed
270-
if (!window.confirm("Delete " + f.name + " ?")) {
293+
if (!window.confirm("Delete " + location.pathname + "/" + f.name + " ?")) {
271294
return;
272295
}
273296
}
@@ -277,8 +300,8 @@ var vm = new Vue({
277300
success: function (res) {
278301
loadFileList()
279302
},
280-
error: function (err) {
281-
alert(err.responseText);
303+
error: function (jqXHR, textStatus, errorThrown) {
304+
showErrorMessage(jqXHR)
282305
}
283306
});
284307
},
@@ -369,20 +392,15 @@ function loadFileList(pathname) {
369392
})
370393
vm.files = res.files;
371394
vm.auth = res.auth;
395+
vm.updateBreadcrumb(pathname);
372396
},
373397
error: function (jqXHR, textStatus, errorThrown) {
374-
let errMsg = jqXHR.getResponseHeader("x-auth-authentication-message")
375-
if (errMsg == null) {
376-
errMsg = jqXHR.statusText
377-
}
378-
alert(String(jqXHR.status).concat(":", errMsg));
379-
console.error(errMsg)
398+
showErrorMessage(jqXHR)
380399
},
381400
});
382401

383402
}
384403

385-
vm.updateBreadcrumb(pathname);
386404
vm.previewMode = getQueryString("raw") == "false";
387405
if (vm.previewMode) {
388406
vm.loadPreviewFile();

httpstaticserver.go

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -83,18 +83,10 @@ func NewHTTPStaticServer(root string) *HTTPStaticServer {
8383
}
8484
}()
8585

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

94-
// TODO: /ipa/info
95-
m.HandleFunc("/-/info/{path:.*}", s.hInfo)
96-
m.HandleFunc("/-/mkdir/{path:.*}", s.hMkdir)
97-
9890
m.HandleFunc("/{path:.*}", s.hIndex).Methods("GET", "HEAD")
9991
m.HandleFunc("/{path:.*}", s.hUploadOrMkdir).Methods("POST")
10092
m.HandleFunc("/{path:.*}", s.hDelete).Methods("DELETE")
@@ -118,6 +110,11 @@ func (s *HTTPStaticServer) hIndex(w http.ResponseWriter, r *http.Request) {
118110
return
119111
}
120112

113+
if r.FormValue("op") == "archive" {
114+
s.hZip(w, r)
115+
return
116+
}
117+
121118
log.Println("GET", path, relPath)
122119
if r.FormValue("raw") == "false" || isDir(relPath) {
123120
if r.Method == "HEAD" {
@@ -139,12 +136,6 @@ func (s *HTTPStaticServer) hIndex(w http.ResponseWriter, r *http.Request) {
139136
}
140137
}
141138

142-
func (s *HTTPStaticServer) hStatus(w http.ResponseWriter, r *http.Request) {
143-
data, _ := json.MarshalIndent(s, "", " ")
144-
w.Header().Set("Content-Type", "application/json")
145-
w.Write(data)
146-
}
147-
148139
func (s *HTTPStaticServer) hMkdir(w http.ResponseWriter, req *http.Request) {
149140
path := filepath.Dir(mux.Vars(req)["path"])
150141
auth := s.readAccessConf(path)
@@ -174,9 +165,15 @@ func (s *HTTPStaticServer) hDelete(w http.ResponseWriter, req *http.Request) {
174165
http.Error(w, "Delete forbidden", http.StatusForbidden)
175166
return
176167
}
168+
177169
err := os.Remove(filepath.Join(s.Root, path))
178170
if err != nil {
179-
http.Error(w, err.Error(), 500)
171+
pathErr, ok := err.(*os.PathError)
172+
if ok{
173+
http.Error(w, pathErr.Op + " " + path + ": " + pathErr.Err.Error(), 500)
174+
} else {
175+
http.Error(w, err.Error(), 500)
176+
}
180177
return
181178
}
182179
w.Write([]byte("Success"))

0 commit comments

Comments
 (0)