Improve installer extraction, login failures, and upload handling
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
@@ -65,6 +66,9 @@ func newReleaseUploadError(status int, code string, err error) error {
|
||||
|
||||
func (r *router) readReleasePackageUpload(w http.ResponseWriter, req *http.Request) (releases.UploadedPackageFile, releases.UploadOptions, func(), error) {
|
||||
limit := r.releaseUploadLimit()
|
||||
if req.ContentLength > limit+(8<<20) {
|
||||
return releases.UploadedPackageFile{}, releases.UploadOptions{}, func() {}, newReleaseUploadError(http.StatusRequestEntityTooLarge, "PACKAGE_TOO_LARGE", errors.New("release package or form data exceeds upload limit"))
|
||||
}
|
||||
req.Body = http.MaxBytesReader(w, req.Body, limit+(8<<20))
|
||||
reader, err := req.MultipartReader()
|
||||
if err != nil {
|
||||
@@ -146,11 +150,18 @@ func (r *router) streamReleaseUploadPart(part *multipart.Part, limit int64) (rel
|
||||
}()
|
||||
hash := sha256.New()
|
||||
limited := &io.LimitedReader{R: part, N: limit + 1}
|
||||
written, err := io.Copy(tmp, io.TeeReader(limited, hash))
|
||||
written, err := io.Copy(io.MultiWriter(tmp, hash), limited)
|
||||
if err == nil {
|
||||
err = tmp.Sync()
|
||||
}
|
||||
if closeErr := tmp.Close(); err == nil {
|
||||
err = closeErr
|
||||
}
|
||||
if err != nil {
|
||||
var pathErr *os.PathError
|
||||
if errors.As(err, &pathErr) {
|
||||
return releases.UploadedPackageFile{}, newReleaseUploadError(http.StatusInternalServerError, "UPLOAD_STORAGE_FAILED", err)
|
||||
}
|
||||
return releases.UploadedPackageFile{}, classifyMultipartReadError(err)
|
||||
}
|
||||
if written > limit {
|
||||
@@ -179,6 +190,9 @@ func classifyMultipartReadError(err error) error {
|
||||
if errors.As(err, &maxErr) {
|
||||
return newReleaseUploadError(http.StatusRequestEntityTooLarge, "PACKAGE_TOO_LARGE", errors.New("发布包或表单数据超过上传上限"))
|
||||
}
|
||||
if errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, context.Canceled) {
|
||||
return newReleaseUploadError(http.StatusBadRequest, "UPLOAD_INTERRUPTED", errors.New("upload was interrupted before the package was complete"))
|
||||
}
|
||||
return newReleaseUploadError(http.StatusBadRequest, "INVALID_UPLOAD", err)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user