👔 Created download route for media HTTP delivery with test
This commit is contained in:
parent
e822d7273f
commit
de300a6413
|
@ -1,10 +1,12 @@
|
||||||
package http
|
package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
"mime"
|
"mime"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
"source.toby3d.me/toby3d/pub/internal/common"
|
"source.toby3d.me/toby3d/pub/internal/common"
|
||||||
"source.toby3d.me/toby3d/pub/internal/domain"
|
"source.toby3d.me/toby3d/pub/internal/domain"
|
||||||
|
@ -31,21 +33,44 @@ func NewHandler(media media.UseCase, config domain.Config) *Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
switch r.Method {
|
||||||
|
default:
|
||||||
|
WriteError(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
|
||||||
|
case "", http.MethodGet:
|
||||||
|
h.handleDownload(w, r)
|
||||||
|
case http.MethodPost:
|
||||||
|
h.handleUpload(w, r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Handler) handleDownload(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.Method != "" && r.Method != http.MethodGet {
|
||||||
|
WriteError(w, "method MUST be "+http.MethodGet, http.StatusMethodNotAllowed)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := h.media.Download(r.Context(), r.RequestURI)
|
||||||
|
if err != nil {
|
||||||
|
WriteError(w, "cannot download media: "+err.Error(), http.StatusInternalServerError)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
http.ServeContent(w, r, out.LogicalName(), time.Time{}, bytes.NewReader(out.Content))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Handler) handleUpload(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method != http.MethodPost {
|
if r.Method != http.MethodPost {
|
||||||
WriteError(w, "method MUST be "+http.MethodPost, http.StatusBadRequest)
|
WriteError(w, "method MUST be "+http.MethodPost, http.StatusMethodNotAllowed)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
mediaType, _, err := mime.ParseMediaType(r.Header.Get(common.HeaderContentType))
|
mediaType, _, err := mime.ParseMediaType(r.Header.Get(common.HeaderContentType))
|
||||||
if err != nil {
|
if err != nil || mediaType != common.MIMEMultipartForm {
|
||||||
WriteError(w, "Content-Type header MUST be "+common.MIMEMultipartForm, http.StatusBadRequest)
|
WriteError(w, common.HeaderContentType+" header MUST be "+common.MIMEMultipartForm,
|
||||||
|
http.StatusBadRequest)
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if mediaType != common.MIMEMultipartForm {
|
|
||||||
WriteError(w, "Content-Type header MUST be "+common.MIMEMultipartForm, http.StatusBadRequest)
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package http_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"io"
|
||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
@ -13,7 +14,7 @@ import (
|
||||||
delivery "source.toby3d.me/toby3d/pub/internal/media/delivery/http"
|
delivery "source.toby3d.me/toby3d/pub/internal/media/delivery/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestUpload(t *testing.T) {
|
func TestHandler_Upload(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testConfig := domain.TestConfig(t)
|
testConfig := domain.TestConfig(t)
|
||||||
|
@ -54,3 +55,37 @@ func TestUpload(t *testing.T) {
|
||||||
t.Errorf("%s %s = %s, want not empty", req.Method, req.RequestURI, location)
|
t.Errorf("%s %s = %s, want not empty", req.Method, req.RequestURI, location)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHandler_Download(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
testConfig := domain.TestConfig(t)
|
||||||
|
testFile := domain.TestFile(t)
|
||||||
|
|
||||||
|
req := httptest.NewRequest(http.MethodGet, "https://example.com/media/"+testFile.LogicalName(), nil)
|
||||||
|
w := httptest.NewRecorder()
|
||||||
|
|
||||||
|
delivery.NewHandler(
|
||||||
|
media.NewStubUseCase(nil, testFile, nil), *testConfig).
|
||||||
|
ServeHTTP(w, req)
|
||||||
|
|
||||||
|
resp := w.Result()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
t.Errorf("%s %s = %d, want %d", req.Method, req.RequestURI, resp.StatusCode, http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
contentType, mediaType := resp.Header.Get(common.HeaderContentType), testFile.MediaType()
|
||||||
|
if contentType != mediaType {
|
||||||
|
t.Errorf("%s %s = '%s', want '%s'", req.Method, req.RequestURI, contentType, mediaType)
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !bytes.Equal(body, testFile.Content) {
|
||||||
|
t.Error("stored and received file contents is not the same")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user