diff options
author | wxiaoguang <wxiaoguang@gmail.com> | 2023-05-09 15:34:36 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-09 15:34:36 +0800 |
commit | 023a048f52b5bf8c4b715285245a129f04e05a8c (patch) | |
tree | 2ea5c0d940a9439e9760b00f735d869444d87165 /modules/context | |
parent | c090f87a8db5b51e0aa9c7278b38ddc862c048ac (diff) | |
download | gitea-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.go | 61 | ||||
-rw-r--r-- | modules/context/context_test.go | 24 |
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) |