summaryrefslogtreecommitdiffstats
path: root/modules/context
diff options
context:
space:
mode:
authorwxiaoguang <wxiaoguang@gmail.com>2023-05-09 15:34:36 +0800
committerGitHub <noreply@github.com>2023-05-09 15:34:36 +0800
commit023a048f52b5bf8c4b715285245a129f04e05a8c (patch)
tree2ea5c0d940a9439e9760b00f735d869444d87165 /modules/context
parentc090f87a8db5b51e0aa9c7278b38ddc862c048ac (diff)
downloadgitea-023a048f52b5bf8c4b715285245a129f04e05a8c.tar.gz
gitea-023a048f52b5bf8c4b715285245a129f04e05a8c.zip
Make repository response support HTTP range request (#24592)
Replace #20480 Replace #18448 Close #16414
Diffstat (limited to 'modules/context')
-rw-r--r--modules/context/context_serve.go61
-rw-r--r--modules/context/context_test.go24
2 files changed, 9 insertions, 76 deletions
diff --git a/modules/context/context_serve.go b/modules/context/context_serve.go
index 44dd739eff..5569efbc7e 100644
--- a/modules/context/context_serve.go
+++ b/modules/context/context_serve.go
@@ -4,71 +4,20 @@
package context
import (
- "fmt"
"io"
"net/http"
- "net/url"
- "strconv"
- "strings"
- "time"
- "code.gitea.io/gitea/modules/httpcache"
- "code.gitea.io/gitea/modules/typesniffer"
+ "code.gitea.io/gitea/modules/httplib"
)
-type ServeHeaderOptions struct {
- ContentType string // defaults to "application/octet-stream"
- ContentTypeCharset string
- ContentLength *int64
- Disposition string // defaults to "attachment"
- Filename string
- CacheDuration time.Duration // defaults to 5 minutes
- LastModified time.Time
-}
-
-// SetServeHeaders sets necessary content serve headers
-func (ctx *Context) SetServeHeaders(opts *ServeHeaderOptions) {
- header := ctx.Resp.Header()
-
- contentType := typesniffer.ApplicationOctetStream
- if opts.ContentType != "" {
- if opts.ContentTypeCharset != "" {
- contentType = opts.ContentType + "; charset=" + strings.ToLower(opts.ContentTypeCharset)
- } else {
- contentType = opts.ContentType
- }
- }
- header.Set("Content-Type", contentType)
- header.Set("X-Content-Type-Options", "nosniff")
-
- if opts.ContentLength != nil {
- header.Set("Content-Length", strconv.FormatInt(*opts.ContentLength, 10))
- }
-
- if opts.Filename != "" {
- disposition := opts.Disposition
- if disposition == "" {
- disposition = "attachment"
- }
-
- backslashEscapedName := strings.ReplaceAll(strings.ReplaceAll(opts.Filename, `\`, `\\`), `"`, `\"`) // \ -> \\, " -> \"
- header.Set("Content-Disposition", fmt.Sprintf(`%s; filename="%s"; filename*=UTF-8''%s`, disposition, backslashEscapedName, url.PathEscape(opts.Filename)))
- header.Set("Access-Control-Expose-Headers", "Content-Disposition")
- }
-
- duration := opts.CacheDuration
- if duration == 0 {
- duration = 5 * time.Minute
- }
- httpcache.SetCacheControlInHeader(header, duration)
+type ServeHeaderOptions httplib.ServeHeaderOptions
- if !opts.LastModified.IsZero() {
- header.Set("Last-Modified", opts.LastModified.UTC().Format(http.TimeFormat))
- }
+func (ctx *Context) SetServeHeaders(opt *ServeHeaderOptions) {
+ httplib.ServeSetHeaders(ctx.Resp, (*httplib.ServeHeaderOptions)(opt))
}
// ServeContent serves content to http request
func (ctx *Context) ServeContent(r io.ReadSeeker, opts *ServeHeaderOptions) {
- ctx.SetServeHeaders(opts)
+ httplib.ServeSetHeaders(ctx.Resp, (*httplib.ServeHeaderOptions)(opts))
http.ServeContent(ctx.Resp, ctx.Req, opts.Filename, opts.LastModified, r)
}
diff --git a/modules/context/context_test.go b/modules/context/context_test.go
index e1460c1fd7..a6facc9788 100644
--- a/modules/context/context_test.go
+++ b/modules/context/context_test.go
@@ -7,32 +7,16 @@ import (
"net/http"
"testing"
+ "code.gitea.io/gitea/modules/httplib"
"code.gitea.io/gitea/modules/setting"
"github.com/stretchr/testify/assert"
)
-type mockResponseWriter struct {
- header http.Header
-}
-
-func (m *mockResponseWriter) Header() http.Header {
- return m.header
-}
-
-func (m *mockResponseWriter) Write(bytes []byte) (int, error) {
- panic("implement me")
-}
-
-func (m *mockResponseWriter) WriteHeader(statusCode int) {
- panic("implement me")
-}
-
func TestRemoveSessionCookieHeader(t *testing.T) {
- w := &mockResponseWriter{}
- w.header = http.Header{}
- w.header.Add("Set-Cookie", (&http.Cookie{Name: setting.SessionConfig.CookieName, Value: "foo"}).String())
- w.header.Add("Set-Cookie", (&http.Cookie{Name: "other", Value: "bar"}).String())
+ w := httplib.NewMockResponseWriter()
+ w.Header().Add("Set-Cookie", (&http.Cookie{Name: setting.SessionConfig.CookieName, Value: "foo"}).String())
+ w.Header().Add("Set-Cookie", (&http.Cookie{Name: "other", Value: "bar"}).String())
assert.Len(t, w.Header().Values("Set-Cookie"), 2)
removeSessionCookieHeader(w)
assert.Len(t, w.Header().Values("Set-Cookie"), 1)