mirror of https://github.com/Xhofe/alist
feat(webdav): delete privacy header and optimize 302 (#2534)
* fix: delete set-cookie from sharepoint webdav response header * fix: avoid two redirects when using webdav * fix: return the correct Content-Type instead of just `application/octet-stream` * feat: webdav backend localOnly -> proxyOnlypull/2543/head
parent
83644dab85
commit
f9788ea7cf
|
@ -73,24 +73,14 @@ func (d *WebDav) List(ctx context.Context, dir model.Obj, args model.ListArgs) (
|
||||||
//}
|
//}
|
||||||
|
|
||||||
func (d *WebDav) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
|
func (d *WebDav) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
|
||||||
callback := func(r *http.Request) {
|
url, header, err := d.client.Link(file.GetPath())
|
||||||
if args.Header.Get("Range") != "" {
|
|
||||||
r.Header.Set("Range", args.Header.Get("Range"))
|
|
||||||
}
|
|
||||||
if args.Header.Get("If-Range") != "" {
|
|
||||||
r.Header.Set("If-Range", args.Header.Get("If-Range"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reader, header, err := d.client.ReadStream(file.GetPath(), callback)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
link := &model.Link{Data: reader}
|
return &model.Link{
|
||||||
if header.Get("Content-Range") != "" {
|
URL: url,
|
||||||
link.Status = 206
|
Header: header,
|
||||||
link.Header = header
|
}, nil
|
||||||
}
|
|
||||||
return link, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *WebDav) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
|
func (d *WebDav) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
|
||||||
|
|
|
@ -16,7 +16,7 @@ type Addition struct {
|
||||||
var config = driver.Config{
|
var config = driver.Config{
|
||||||
Name: "WebDav",
|
Name: "WebDav",
|
||||||
LocalSort: true,
|
LocalSort: true,
|
||||||
OnlyLocal: true,
|
OnlyProxy: true,
|
||||||
DefaultRoot: "/",
|
DefaultRoot: "/",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -342,6 +342,58 @@ func (c *Client) Read(path string) ([]byte, error) {
|
||||||
return buf.Bytes(), nil
|
return buf.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Client) Link(path string) (string, http.Header, error) {
|
||||||
|
method := "HEAD"
|
||||||
|
url := PathEscape(Join(c.root, path))
|
||||||
|
r, err := http.NewRequest(method, url, nil)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, newPathErrorErr("Link", path, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, vals := range c.headers {
|
||||||
|
for _, v := range vals {
|
||||||
|
r.Header.Add(k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.authMutex.Lock()
|
||||||
|
auth := c.auth
|
||||||
|
c.authMutex.Unlock()
|
||||||
|
|
||||||
|
auth.Authorize(r, method, path)
|
||||||
|
|
||||||
|
if c.interceptor != nil {
|
||||||
|
c.interceptor(method, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
rs, err := c.c.Do(r)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, newPathErrorErr("Link", path, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rs.StatusCode == 401 {
|
||||||
|
wwwAuthenticateHeader := strings.ToLower(rs.Header.Get("Www-Authenticate"))
|
||||||
|
if strings.Contains(wwwAuthenticateHeader, "digest") {
|
||||||
|
c.authMutex.Lock()
|
||||||
|
c.auth = &DigestAuth{auth.User(), auth.Pass(), digestParts(rs)}
|
||||||
|
c.auth.Authorize(r, method, path)
|
||||||
|
c.authMutex.Unlock()
|
||||||
|
} else if strings.Contains(wwwAuthenticateHeader, "basic") {
|
||||||
|
c.authMutex.Lock()
|
||||||
|
c.auth = &BasicAuth{auth.User(), auth.Pass()}
|
||||||
|
c.auth.Authorize(r, method, path)
|
||||||
|
c.authMutex.Unlock()
|
||||||
|
} else {
|
||||||
|
return "", nil, newPathError("Authorize", c.root, rs.StatusCode)
|
||||||
|
}
|
||||||
|
} else if rs.StatusCode > 400 {
|
||||||
|
return "", nil, newPathError("Authorize", path, rs.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.URL.String(), r.Header, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ReadStream reads the stream for a given path
|
// ReadStream reads the stream for a given path
|
||||||
func (c *Client) ReadStream(path string, callback func(rq *http.Request)) (io.ReadCloser, http.Header, error) {
|
func (c *Client) ReadStream(path string, callback func(rq *http.Request)) (io.ReadCloser, http.Header, error) {
|
||||||
rs, err := c.req("GET", path, nil, callback)
|
rs, err := c.req("GET", path, nil, callback)
|
||||||
|
|
|
@ -28,6 +28,8 @@ func Proxy(w http.ResponseWriter, r *http.Request, link *model.Link, file model.
|
||||||
w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"; filename*=UTF-8''%s`, file.GetName(), url.QueryEscape(file.GetName())))
|
w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"; filename*=UTF-8''%s`, file.GetName(), url.QueryEscape(file.GetName())))
|
||||||
w.Header().Set("Content-Length", strconv.FormatInt(file.GetSize(), 10))
|
w.Header().Set("Content-Length", strconv.FormatInt(file.GetSize(), 10))
|
||||||
if link.Header != nil {
|
if link.Header != nil {
|
||||||
|
// TODO clean header with blacklist or whitelist
|
||||||
|
link.Header.Del("set-cookie")
|
||||||
for h, val := range link.Header {
|
for h, val := range link.Header {
|
||||||
w.Header()[h] = val
|
w.Header()[h] = val
|
||||||
}
|
}
|
||||||
|
@ -81,6 +83,8 @@ func Proxy(w http.ResponseWriter, r *http.Request, link *model.Link, file model.
|
||||||
_ = res.Body.Close()
|
_ = res.Body.Close()
|
||||||
}()
|
}()
|
||||||
log.Debugf("proxy status: %d", res.StatusCode)
|
log.Debugf("proxy status: %d", res.StatusCode)
|
||||||
|
// TODO clean header with blacklist or whitelist
|
||||||
|
res.Header.Del("set-cookie")
|
||||||
for h, v := range res.Header {
|
for h, v := range res.Header {
|
||||||
w.Header()[h] = v
|
w.Header()[h] = v
|
||||||
}
|
}
|
||||||
|
|
|
@ -218,7 +218,8 @@ func (h *Handler) handleGetHeadPost(w http.ResponseWriter, r *http.Request) (sta
|
||||||
w.Header().Set("ETag", etag)
|
w.Header().Set("ETag", etag)
|
||||||
// Let ServeContent determine the Content-Type header.
|
// Let ServeContent determine the Content-Type header.
|
||||||
storage, _ := fs.GetStorage(reqPath)
|
storage, _ := fs.GetStorage(reqPath)
|
||||||
if storage.GetStorage().WebdavNative() {
|
downProxyUrl := storage.GetStorage().DownProxyUrl
|
||||||
|
if storage.GetStorage().WebdavNative() || (storage.GetStorage().WebdavProxy() && downProxyUrl == "") {
|
||||||
link, _, err := fs.Link(ctx, reqPath, model.LinkArgs{Header: r.Header})
|
link, _, err := fs.Link(ctx, reqPath, model.LinkArgs{Header: r.Header})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return http.StatusInternalServerError, err
|
return http.StatusInternalServerError, err
|
||||||
|
@ -227,19 +228,19 @@ func (h *Handler) handleGetHeadPost(w http.ResponseWriter, r *http.Request) (sta
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return http.StatusInternalServerError, err
|
return http.StatusInternalServerError, err
|
||||||
}
|
}
|
||||||
} else if storage.Config().MustProxy() || storage.GetStorage().WebdavProxy() {
|
} else if storage.GetStorage().WebdavProxy() && downProxyUrl != "" {
|
||||||
u := fmt.Sprintf("%s/p%s?sign=%s",
|
u := fmt.Sprintf("%s%s?sign=%s",
|
||||||
common.GetApiUrl(r),
|
strings.Split(downProxyUrl, "\n")[0],
|
||||||
utils.EncodePath(reqPath, true),
|
utils.EncodePath(reqPath, true),
|
||||||
sign.Sign(reqPath))
|
sign.Sign(reqPath))
|
||||||
w.Header().Set("Cache-Control", "max-age=0, no-cache, no-store, must-revalidate")
|
w.Header().Set("Cache-Control", "max-age=0, no-cache, no-store, must-revalidate")
|
||||||
http.Redirect(w, r, u, 302)
|
http.Redirect(w, r, u, http.StatusFound)
|
||||||
} else {
|
} else {
|
||||||
link, _, err := fs.Link(ctx, reqPath, model.LinkArgs{IP: utils.ClientIP(r)})
|
link, _, err := fs.Link(ctx, reqPath, model.LinkArgs{IP: utils.ClientIP(r)})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return http.StatusInternalServerError, err
|
return http.StatusInternalServerError, err
|
||||||
}
|
}
|
||||||
http.Redirect(w, r, link.URL, 302)
|
http.Redirect(w, r, link.URL, http.StatusFound)
|
||||||
}
|
}
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue