mediaapi/writers/upload: Factor out doUpload from Upload
MODIFY
src/github.com/matrix-org/dendrite/mediaapi/writers/upload.go
src/github.com/matrix-org/dendrite/mediaapi/writers/upload.go
@@ -17,6 +17,7 @@ package writers
import (
"database/sql"
"fmt"
+ "io"
"net/http"
"net/url"
"path"
@@ -56,6 +57,47 @@ func Upload(req *http.Request, cfg *config.MediaAPI, db *storage.Database) util.
return *resErr
}
+ if resErr = r.doUpload(req.Body, cfg, db); resErr != nil {
+ return *resErr
+ }
+
+ return util.JSONResponse{
+ Code: 200,
+ JSON: uploadResponse{
+ ContentURI: fmt.Sprintf("mxc://%s/%s", cfg.ServerName, r.MediaMetadata.MediaID),
+ },
+ }
+}
+
+// parseAndValidateRequest parses the incoming upload request to validate and extract
+// all the metadata about the media being uploaded.
+// Returns either an uploadRequest or an error formatted as a util.JSONResponse
+func parseAndValidateRequest(req *http.Request, cfg *config.MediaAPI) (*uploadRequest, *util.JSONResponse) {
+ if req.Method != "POST" {
+ return nil, &util.JSONResponse{
+ Code: 400,
+ JSON: jsonerror.Unknown("HTTP request method must be POST."),
+ }
+ }
+
+ r := &uploadRequest{
+ MediaMetadata: &types.MediaMetadata{
+ Origin: cfg.ServerName,
+ FileSizeBytes: types.FileSizeBytes(req.ContentLength),
+ ContentType: types.ContentType(req.Header.Get("Content-Type")),
+ UploadName: types.Filename(url.PathEscape(req.FormValue("filename"))),
+ },
+ Logger: util.GetLogger(req.Context()),
+ }
+
+ if resErr := r.Validate(cfg.MaxFileSizeBytes); resErr != nil {
+ return nil, resErr
+ }
+
+ return r, nil
+}
+
+func (r *uploadRequest) doUpload(reqReader io.Reader, cfg *config.MediaAPI, db *storage.Database) *util.JSONResponse {
r.Logger.WithFields(log.Fields{
"Origin": r.MediaMetadata.Origin,
"UploadName": r.MediaMetadata.UploadName,
@@ -66,7 +108,7 @@ func Upload(req *http.Request, cfg *config.MediaAPI, db *storage.Database) util.
// The file data is hashed and the hash is used as the MediaID. The hash is useful as a
// method of deduplicating files to save storage, as well as a way to conduct
// integrity checks on the file data in the repository.
- hash, bytesWritten, tmpDir, copyError := fileutils.WriteTempFile(req.Body, cfg.MaxFileSizeBytes, cfg.AbsBasePath)
+ hash, bytesWritten, tmpDir, copyError := fileutils.WriteTempFile(reqReader, cfg.MaxFileSizeBytes, cfg.AbsBasePath)
if copyError != nil {
logFields := log.Fields{
"Origin": r.MediaMetadata.Origin,
@@ -77,7 +119,7 @@ func Upload(req *http.Request, cfg *config.MediaAPI, db *storage.Database) util.
}
r.Logger.WithError(copyError).WithFields(logFields).Warn("Error while transferring file")
fileutils.RemoveDir(tmpDir, r.Logger)
- return util.JSONResponse{
+ return &util.JSONResponse{
Code: 400,
JSON: jsonerror.Unknown(fmt.Sprintf("Failed to upload")),
}
@@ -101,7 +143,7 @@ func Upload(req *http.Request, cfg *config.MediaAPI, db *storage.Database) util.
if err == nil {
r.MediaMetadata = mediaMetadata
fileutils.RemoveDir(tmpDir, r.Logger)
- return util.JSONResponse{
+ return &util.JSONResponse{
Code: 200,
JSON: uploadResponse{
ContentURI: fmt.Sprintf("mxc://%s/%s", cfg.ServerName, r.MediaMetadata.MediaID),
@@ -113,45 +155,11 @@ func Upload(req *http.Request, cfg *config.MediaAPI, db *storage.Database) util.
// TODO: generate thumbnails
- resErr = r.storeFileAndMetadata(tmpDir, cfg.AbsBasePath, db)
- if resErr != nil {
- return *resErr
- }
-
- return util.JSONResponse{
- Code: 200,
- JSON: uploadResponse{
- ContentURI: fmt.Sprintf("mxc://%s/%s", cfg.ServerName, r.MediaMetadata.MediaID),
- },
- }
-}
-
-// parseAndValidateRequest parses the incoming upload request to validate and extract
-// all the metadata about the media being uploaded.
-// Returns either an uploadRequest or an error formatted as a util.JSONResponse
-func parseAndValidateRequest(req *http.Request, cfg *config.MediaAPI) (*uploadRequest, *util.JSONResponse) {
- if req.Method != "POST" {
- return nil, &util.JSONResponse{
- Code: 400,
- JSON: jsonerror.Unknown("HTTP request method must be POST."),
- }
- }
-
- r := &uploadRequest{
- MediaMetadata: &types.MediaMetadata{
- Origin: cfg.ServerName,
- FileSizeBytes: types.FileSizeBytes(req.ContentLength),
- ContentType: types.ContentType(req.Header.Get("Content-Type")),
- UploadName: types.Filename(url.PathEscape(req.FormValue("filename"))),
- },
- Logger: util.GetLogger(req.Context()),
- }
-
- if resErr := r.Validate(cfg.MaxFileSizeBytes); resErr != nil {
- return nil, resErr
+ if resErr := r.storeFileAndMetadata(tmpDir, cfg.AbsBasePath, db); resErr != nil {
+ return resErr
}
- return r, nil
+ return nil
}
// Validate validates the uploadRequest fields

mediaapi/writers/upload: Factor out doUpload from Upload