Skip to content
This repository was archived by the owner on Nov 25, 2024. It is now read-only.

Commit ed6d964

Browse files
authored
Fix function signature, use default random boundary (#3422)
Fixes the function signature of `parseMultipartResponse` and uses the default random boundary when creating a new multipart response.
1 parent 002fed3 commit ed6d964

File tree

2 files changed

+13
-20
lines changed

2 files changed

+13
-20
lines changed

mediaapi/routing/download.go

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ import (
3333
"sync"
3434
"unicode"
3535

36-
"github.com/google/uuid"
3736
"github.com/matrix-org/dendrite/mediaapi/fileutils"
3837
"github.com/matrix-org/dendrite/mediaapi/storage"
3938
"github.com/matrix-org/dendrite/mediaapi/thumbnailer"
@@ -400,22 +399,16 @@ func (r *downloadRequest) respondFromLocalFile(
400399
}
401400

402401
func multipartResponse(w http.ResponseWriter, r *downloadRequest, contentType string, responseFile io.Reader) (int64, error) {
402+
mw := multipart.NewWriter(w)
403403
// Update the header to be multipart/mixed; boundary=$randomBoundary
404-
boundary := uuid.NewString()
405-
w.Header().Set("Content-Type", "multipart/mixed; boundary="+boundary)
406-
404+
w.Header().Set("Content-Type", "multipart/mixed; boundary="+mw.Boundary())
407405
w.Header().Del("Content-Length") // let Go handle the content length
408-
mw := multipart.NewWriter(w)
409406
defer func() {
410407
if err := mw.Close(); err != nil {
411408
r.Logger.WithError(err).Error("Failed to close multipart writer")
412409
}
413410
}()
414411

415-
if err := mw.SetBoundary(boundary); err != nil {
416-
return 0, fmt.Errorf("failed to set multipart boundary: %w", err)
417-
}
418-
419412
// JSON object part
420413
jsonWriter, err := mw.CreatePart(textproto.MIMEHeader{
421414
"Content-Type": {"application/json"},
@@ -858,7 +851,7 @@ func (r *downloadRequest) fetchRemoteFile(
858851
var reader io.Reader
859852
var parseErr error
860853
if isAuthed {
861-
parseErr, contentLength, reader = parseMultipartResponse(r, resp, maxFileSizeBytes)
854+
contentLength, reader, parseErr = parseMultipartResponse(r, resp, maxFileSizeBytes)
862855
} else {
863856
// The reader returned here will be limited either by the Content-Length
864857
// and/or the configured maximum media size.
@@ -928,48 +921,48 @@ func (r *downloadRequest) fetchRemoteFile(
928921
return types.Path(finalPath), duplicate, nil
929922
}
930923

931-
func parseMultipartResponse(r *downloadRequest, resp *http.Response, maxFileSizeBytes config.FileSizeBytes) (error, int64, io.Reader) {
924+
func parseMultipartResponse(r *downloadRequest, resp *http.Response, maxFileSizeBytes config.FileSizeBytes) (int64, io.Reader, error) {
932925
_, params, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
933926
if err != nil {
934-
return err, 0, nil
927+
return 0, nil, err
935928
}
936929
if params["boundary"] == "" {
937-
return fmt.Errorf("no boundary header found on media %s from %s", r.MediaMetadata.MediaID, r.MediaMetadata.Origin), 0, nil
930+
return 0, nil, fmt.Errorf("no boundary header found on media %s from %s", r.MediaMetadata.MediaID, r.MediaMetadata.Origin)
938931
}
939932
mr := multipart.NewReader(resp.Body, params["boundary"])
940933

941934
// Get the first, JSON, part
942935
p, err := mr.NextPart()
943936
if err != nil {
944-
return err, 0, nil
937+
return 0, nil, err
945938
}
946939
defer p.Close() // nolint: errcheck
947940

948941
if p.Header.Get("Content-Type") != "application/json" {
949-
return fmt.Errorf("first part of the response must be application/json"), 0, nil
942+
return 0, nil, fmt.Errorf("first part of the response must be application/json")
950943
}
951944
// Try to parse media meta information
952945
meta := mediaMeta{}
953946
if err = json.NewDecoder(p).Decode(&meta); err != nil {
954-
return err, 0, nil
947+
return 0, nil, err
955948
}
956949
defer p.Close() // nolint: errcheck
957950

958951
// Get the actual media content
959952
p, err = mr.NextPart()
960953
if err != nil {
961-
return err, 0, nil
954+
return 0, nil, err
962955
}
963956

964957
redirect := p.Header.Get("Location")
965958
if redirect != "" {
966-
return fmt.Errorf("Location header is not yet supported"), 0, nil
959+
return 0, nil, fmt.Errorf("Location header is not yet supported")
967960
}
968961

969962
contentLength, reader, err := r.GetContentLengthAndReader(p.Header.Get("Content-Length"), p, maxFileSizeBytes)
970963
// For multipart requests, we need to get the Content-Type of the second part, which is the actual media
971964
r.MediaMetadata.ContentType = types.ContentType(p.Header.Get("Content-Type"))
972-
return err, contentLength, reader
965+
return contentLength, reader, err
973966
}
974967

975968
// contentDispositionFor returns the Content-Disposition for a given

mediaapi/routing/download_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func Test_Multipart(t *testing.T) {
3535
assert.NoError(t, err)
3636
defer resp.Body.Close()
3737
// contentLength is always 0, since there's no Content-Length header on the multipart part.
38-
err, _, reader := parseMultipartResponse(r, resp, 1000)
38+
_, reader, err := parseMultipartResponse(r, resp, 1000)
3939
assert.NoError(t, err)
4040
gotResponse, err := io.ReadAll(reader)
4141
assert.NoError(t, err)

0 commit comments

Comments
 (0)