Use standard HTTP library to serve files (#24693)

`http.ServeFile/ServeContent` handles `If-xxx`, `Content-Length`,
`Range` and `Etag` correctly

After this PR, storage files (eg: avatar) could be responded with
correct Content-Length.
This commit is contained in:
wxiaoguang 2023-05-13 22:04:57 +08:00 committed by GitHub
parent f745016092
commit a94a8d0ab1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 22 additions and 157 deletions

View file

@ -1,35 +0,0 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package httplib
import (
"bytes"
"net/http"
)
type MockResponseWriter struct {
header http.Header
StatusCode int
BodyBuffer bytes.Buffer
}
func (m *MockResponseWriter) Header() http.Header {
return m.header
}
func (m *MockResponseWriter) Write(bytes []byte) (int, error) {
if m.StatusCode == 0 {
m.StatusCode = http.StatusOK
}
return m.BodyBuffer.Write(bytes)
}
func (m *MockResponseWriter) WriteHeader(statusCode int) {
m.StatusCode = statusCode
}
func NewMockResponseWriter() *MockResponseWriter {
return &MockResponseWriter{header: http.Header{}}
}

View file

@ -6,6 +6,7 @@ package httplib
import (
"fmt"
"net/http"
"net/http/httptest"
"net/url"
"os"
"strings"
@ -25,12 +26,12 @@ func TestServeContentByReader(t *testing.T) {
r.Header.Set("Range", fmt.Sprintf("bytes=%s", rangeStr))
}
reader := strings.NewReader(data)
w := NewMockResponseWriter()
w := httptest.NewRecorder()
ServeContentByReader(r, w, "test", int64(len(data)), reader)
assert.Equal(t, expectedStatusCode, w.StatusCode)
assert.Equal(t, expectedStatusCode, w.Code)
if expectedStatusCode == http.StatusPartialContent || expectedStatusCode == http.StatusOK {
assert.Equal(t, fmt.Sprint(len(expectedContent)), w.Header().Get("Content-Length"))
assert.Equal(t, expectedContent, w.BodyBuffer.String())
assert.Equal(t, expectedContent, w.Body.String())
}
}
@ -76,12 +77,12 @@ func TestServeContentByReadSeeker(t *testing.T) {
}
defer seekReader.Close()
w := NewMockResponseWriter()
w := httptest.NewRecorder()
ServeContentByReadSeeker(r, w, "test", time.Time{}, seekReader)
assert.Equal(t, expectedStatusCode, w.StatusCode)
assert.Equal(t, expectedStatusCode, w.Code)
if expectedStatusCode == http.StatusPartialContent || expectedStatusCode == http.StatusOK {
assert.Equal(t, fmt.Sprint(len(expectedContent)), w.Header().Get("Content-Length"))
assert.Equal(t, expectedContent, w.BodyBuffer.String())
assert.Equal(t, expectedContent, w.Body.String())
}
}