Fix serving of raw wiki files other than .md (#5814)
* Fix serving of raw wiki files other than .md Closes #4690. Closes #4395. Signed-off-by: Gabriel Silva Simões <simoes.sgabriel@gmail.com> * Simplify code at routers/repo/wiki.go Signed-off-by: Gabriel Silva Simões <simoes.sgabriel@gmail.com> * Add more files to user2/repo1.wiki for testing Signed-off-by: Gabriel Silva Simões <simoes.sgabriel@gmail.com> * Update macaron to v1.3.2 Signed-off-by: Gabriel Silva Simões <simoes.sgabriel@gmail.com> * Add tests for WikiRaw Signed-off-by: Gabriel Silva Simões <simoes.sgabriel@gmail.com> * Fix NewResponseWriter usage due to macaron update Signed-off-by: Gabriel Silva Simões <simoes.sgabriel@gmail.com> * Add raw to reserved wiki names Signed-off-by: Gabriel Silva Simões <simoes.sgabriel@gmail.com>
This commit is contained in:
parent
4a747aef7b
commit
3b7f41f9f7
17 changed files with 77 additions and 31 deletions
6
Gopkg.lock
generated
6
Gopkg.lock
generated
|
@ -1108,12 +1108,12 @@
|
||||||
version = "v2.5.1"
|
version = "v2.5.1"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:cfe1730a152ff033ad7d9c115d22e36b19eec6d5928c06146b9119be45d39dc0"
|
digest = "1:de2e7294c9bd0b7d07ada8e98ad02cbbaabacff90eedebe7454ebdbab50d0d19"
|
||||||
name = "gopkg.in/macaron.v1"
|
name = "gopkg.in/macaron.v1"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
pruneopts = "NUT"
|
pruneopts = "NUT"
|
||||||
revision = "75f2e9b42e99652f0d82b28ccb73648f44615faa"
|
revision = "dfcb80ca86e8534962c62812efd93209c7e600e7"
|
||||||
version = "v1.2.4"
|
version = "v1.3.2"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:00126f697efdcab42f07c89ac8bf0095fb2328aef6464e070055154088cea859"
|
digest = "1:00126f697efdcab42f07c89ac8bf0095fb2328aef6464e070055154088cea859"
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
xŽŃmÄ DóMŰŔY¬Í<1A>˘(ůJ©`<60>5ÇÉś-›K*Ki,Hi!?ŁŃ<éiâVki0Z˙ÔXH“D(Z6ĨGňSb» 3“JDŢhµó!÷uB¬ĚDaJpˇ íśŮčFôLĆą4+~´ëvŔ;‡ŁČ
|
||||||
|
eýäžőç[Nx>KÝäÎü‡_sĺ˛q«/€]09MHpѤµękżÜä_dę-%¸í’‡Űž<C5B0>ď vÎ_Ą]ˇÔ^Ő/čI[t
|
Binary file not shown.
|
@ -0,0 +1 @@
|
||||||
|
xÆM‚@†á¯MÛ àºré›°6ñœ&&&¬ü9LežÅ›w½Ý×åt<#ÞñÃÍ¡ªmv-·•0w¬b¦¢jyÌ–†¤Ú—~Ý‹[žæÉçý=HÄ÷.¾"à‚íµÄçÇ<>=
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,2 @@
|
||||||
|
xŽÝmÃ0ƒû¬)n<>ú±t2íSèçÓÙ`ņ¥¶“e‚,VY¡/Hâ#È[)¹<>EûÒ@NÈq¦è툎Ñr2«)DöÅ0âŒj§C®ìÑLÂ<4C>ŸœaCÓÃ&š4B<34>v]$Eßí²ðIÓ‘e…¯¼þP×r¿I…sÍe“zªË³~_
|
||||||
|
åõÄ[yã‡è¢v£<76>WíµV=í—›ü˘úH vZ~s»@݉%Á•Š¨?TÊZH
|
Binary file not shown.
|
@ -1 +1 @@
|
||||||
2c54faec6c45d31c1abfaecdab471eac6633738a
|
0cf15c3f66ec8384480ed9c3cf87c9e97fbb0ec3
|
||||||
|
|
|
@ -22,7 +22,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
reservedWikiNames = []string{"_pages", "_new", "_edit"}
|
reservedWikiNames = []string{"_pages", "_new", "_edit", "raw"}
|
||||||
wikiWorkingPool = sync.NewExclusivePool()
|
wikiWorkingPool = sync.NewExclusivePool()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ func createContext(req *http.Request) (*macaron.Context, *httptest.ResponseRecor
|
||||||
c := &macaron.Context{
|
c := &macaron.Context{
|
||||||
Injector: inject.New(),
|
Injector: inject.New(),
|
||||||
Req: macaron.Request{Request: req},
|
Req: macaron.Request{Request: req},
|
||||||
Resp: macaron.NewResponseWriter(resp),
|
Resp: macaron.NewResponseWriter(req.Method, resp),
|
||||||
Render: &macaron.DummyRender{ResponseWriter: resp},
|
Render: &macaron.DummyRender{ResponseWriter: resp},
|
||||||
Data: make(map[string]interface{}),
|
Data: make(map[string]interface{}),
|
||||||
}
|
}
|
||||||
|
|
|
@ -295,26 +295,41 @@ func WikiRaw(ctx *context.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
providedPath := ctx.Params("*")
|
providedPath := ctx.Params("*")
|
||||||
if strings.HasSuffix(providedPath, ".md") {
|
|
||||||
providedPath = providedPath[:len(providedPath)-3]
|
|
||||||
}
|
|
||||||
wikiPath := models.WikiNameToFilename(providedPath)
|
|
||||||
var entry *git.TreeEntry
|
var entry *git.TreeEntry
|
||||||
if commit != nil {
|
if commit != nil {
|
||||||
entry, err = findEntryForFile(commit, wikiPath)
|
// Try to find a file with that name
|
||||||
|
entry, err = findEntryForFile(commit, providedPath)
|
||||||
|
if err != nil {
|
||||||
|
ctx.ServerError("findFile", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if entry == nil {
|
||||||
|
// Try to find a wiki page with that name
|
||||||
|
if strings.HasSuffix(providedPath, ".md") {
|
||||||
|
providedPath = providedPath[:len(providedPath)-3]
|
||||||
|
}
|
||||||
|
|
||||||
|
wikiPath := models.WikiNameToFilename(providedPath)
|
||||||
|
entry, err = findEntryForFile(commit, wikiPath)
|
||||||
|
if err != nil {
|
||||||
|
ctx.ServerError("findFile", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err != nil {
|
|
||||||
ctx.ServerError("findFile", err)
|
if entry != nil {
|
||||||
return
|
if err = ServeBlob(ctx, entry.Blob()); err != nil {
|
||||||
} else if entry == nil {
|
ctx.ServerError("ServeBlob", err)
|
||||||
ctx.NotFound("findEntryForFile", nil)
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = ServeBlob(ctx, entry.Blob()); err != nil {
|
ctx.NotFound("findEntryForFile", nil)
|
||||||
ctx.ServerError("ServeBlob", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewWiki render wiki create page
|
// NewWiki render wiki create page
|
||||||
|
|
|
@ -77,7 +77,7 @@ func TestWiki(t *testing.T) {
|
||||||
Wiki(ctx)
|
Wiki(ctx)
|
||||||
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
|
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
|
||||||
assert.EqualValues(t, "Home", ctx.Data["Title"])
|
assert.EqualValues(t, "Home", ctx.Data["Title"])
|
||||||
assertPagesMetas(t, []string{"Home"}, ctx.Data["Pages"])
|
assertPagesMetas(t, []string{"Home", "Page With Image", "Page With Spaced Name"}, ctx.Data["Pages"])
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWikiPages(t *testing.T) {
|
func TestWikiPages(t *testing.T) {
|
||||||
|
@ -87,7 +87,7 @@ func TestWikiPages(t *testing.T) {
|
||||||
test.LoadRepo(t, ctx, 1)
|
test.LoadRepo(t, ctx, 1)
|
||||||
WikiPages(ctx)
|
WikiPages(ctx)
|
||||||
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
|
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
|
||||||
assertPagesMetas(t, []string{"Home"}, ctx.Data["Pages"])
|
assertPagesMetas(t, []string{"Home", "Page With Image", "Page With Spaced Name"}, ctx.Data["Pages"])
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewWiki(t *testing.T) {
|
func TestNewWiki(t *testing.T) {
|
||||||
|
@ -185,3 +185,23 @@ func TestDeleteWikiPagePost(t *testing.T) {
|
||||||
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
|
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
|
||||||
assertWikiNotExists(t, ctx.Repo.Repository, "Home")
|
assertWikiNotExists(t, ctx.Repo.Repository, "Home")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWikiRaw(t *testing.T) {
|
||||||
|
for filepath, filetype := range map[string]string{
|
||||||
|
"jpeg.jpg": "image/jpeg",
|
||||||
|
"Page With Spaced Name": "text/plain; charset=utf-8",
|
||||||
|
"Page-With-Spaced-Name": "text/plain; charset=utf-8",
|
||||||
|
"Page With Spaced Name.md": "text/plain; charset=utf-8",
|
||||||
|
"Page-With-Spaced-Name.md": "text/plain; charset=utf-8",
|
||||||
|
} {
|
||||||
|
models.PrepareTestEnv(t)
|
||||||
|
|
||||||
|
ctx := test.MockContext(t, "user2/repo1/wiki/raw/"+filepath)
|
||||||
|
ctx.SetParams("*", filepath)
|
||||||
|
test.LoadUser(t, ctx, 2)
|
||||||
|
test.LoadRepo(t, ctx, 1)
|
||||||
|
WikiRaw(ctx)
|
||||||
|
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
|
||||||
|
assert.EqualValues(t, filetype, ctx.Resp.Header().Get("Content-Type"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
4
vendor/gopkg.in/macaron.v1/context.go
generated
vendored
4
vendor/gopkg.in/macaron.v1/context.go
generated
vendored
|
@ -262,7 +262,7 @@ func (ctx *Context) Params(name string) string {
|
||||||
|
|
||||||
// SetParams sets value of param with given name.
|
// SetParams sets value of param with given name.
|
||||||
func (ctx *Context) SetParams(name, val string) {
|
func (ctx *Context) SetParams(name, val string) {
|
||||||
if !strings.HasPrefix(name, ":") {
|
if name != "*" && !strings.HasPrefix(name, ":") {
|
||||||
name = ":" + name
|
name = ":" + name
|
||||||
}
|
}
|
||||||
ctx.params[name] = val
|
ctx.params[name] = val
|
||||||
|
@ -270,7 +270,7 @@ func (ctx *Context) SetParams(name, val string) {
|
||||||
|
|
||||||
// ReplaceAllParams replace all current params with given params
|
// ReplaceAllParams replace all current params with given params
|
||||||
func (ctx *Context) ReplaceAllParams(params Params) {
|
func (ctx *Context) ReplaceAllParams(params Params) {
|
||||||
ctx.params = params;
|
ctx.params = params
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParamsEscape returns escapred params result.
|
// ParamsEscape returns escapred params result.
|
||||||
|
|
4
vendor/gopkg.in/macaron.v1/macaron.go
generated
vendored
4
vendor/gopkg.in/macaron.v1/macaron.go
generated
vendored
|
@ -32,7 +32,7 @@ import (
|
||||||
"github.com/go-macaron/inject"
|
"github.com/go-macaron/inject"
|
||||||
)
|
)
|
||||||
|
|
||||||
const _VERSION = "1.2.4.1123"
|
const _VERSION = "1.3.2.1216"
|
||||||
|
|
||||||
func Version() string {
|
func Version() string {
|
||||||
return _VERSION
|
return _VERSION
|
||||||
|
@ -194,7 +194,7 @@ func (m *Macaron) createContext(rw http.ResponseWriter, req *http.Request) *Cont
|
||||||
index: 0,
|
index: 0,
|
||||||
Router: m.Router,
|
Router: m.Router,
|
||||||
Req: Request{req},
|
Req: Request{req},
|
||||||
Resp: NewResponseWriter(rw),
|
Resp: NewResponseWriter(req.Method, rw),
|
||||||
Render: &DummyRender{rw},
|
Render: &DummyRender{rw},
|
||||||
Data: make(map[string]interface{}),
|
Data: make(map[string]interface{}),
|
||||||
}
|
}
|
||||||
|
|
13
vendor/gopkg.in/macaron.v1/response_writer.go
generated
vendored
13
vendor/gopkg.in/macaron.v1/response_writer.go
generated
vendored
|
@ -42,11 +42,12 @@ type ResponseWriter interface {
|
||||||
type BeforeFunc func(ResponseWriter)
|
type BeforeFunc func(ResponseWriter)
|
||||||
|
|
||||||
// NewResponseWriter creates a ResponseWriter that wraps an http.ResponseWriter
|
// NewResponseWriter creates a ResponseWriter that wraps an http.ResponseWriter
|
||||||
func NewResponseWriter(rw http.ResponseWriter) ResponseWriter {
|
func NewResponseWriter(method string, rw http.ResponseWriter) ResponseWriter {
|
||||||
return &responseWriter{rw, 0, 0, nil}
|
return &responseWriter{method, rw, 0, 0, nil}
|
||||||
}
|
}
|
||||||
|
|
||||||
type responseWriter struct {
|
type responseWriter struct {
|
||||||
|
method string
|
||||||
http.ResponseWriter
|
http.ResponseWriter
|
||||||
status int
|
status int
|
||||||
size int
|
size int
|
||||||
|
@ -59,13 +60,15 @@ func (rw *responseWriter) WriteHeader(s int) {
|
||||||
rw.status = s
|
rw.status = s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rw *responseWriter) Write(b []byte) (int, error) {
|
func (rw *responseWriter) Write(b []byte) (size int, err error) {
|
||||||
if !rw.Written() {
|
if !rw.Written() {
|
||||||
// The status will be StatusOK if WriteHeader has not been called yet
|
// The status will be StatusOK if WriteHeader has not been called yet
|
||||||
rw.WriteHeader(http.StatusOK)
|
rw.WriteHeader(http.StatusOK)
|
||||||
}
|
}
|
||||||
size, err := rw.ResponseWriter.Write(b)
|
if rw.method != "HEAD" {
|
||||||
rw.size += size
|
size, err = rw.ResponseWriter.Write(b)
|
||||||
|
rw.size += size
|
||||||
|
}
|
||||||
return size, err
|
return size, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
5
vendor/gopkg.in/macaron.v1/router.go
generated
vendored
5
vendor/gopkg.in/macaron.v1/router.go
generated
vendored
|
@ -96,7 +96,7 @@ func NewRouter() *Router {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetAutoHead sets the value who determines whether add HEAD method automatically
|
// SetAutoHead sets the value who determines whether add HEAD method automatically
|
||||||
// when GET method is added. Combo router will not be affected by this value.
|
// when GET method is added.
|
||||||
func (r *Router) SetAutoHead(v bool) {
|
func (r *Router) SetAutoHead(v bool) {
|
||||||
r.autoHead = v
|
r.autoHead = v
|
||||||
}
|
}
|
||||||
|
@ -341,6 +341,9 @@ func (cr *ComboRouter) route(fn func(string, ...Handler) *Route, method string,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cr *ComboRouter) Get(h ...Handler) *ComboRouter {
|
func (cr *ComboRouter) Get(h ...Handler) *ComboRouter {
|
||||||
|
if cr.router.autoHead {
|
||||||
|
cr.Head(h...)
|
||||||
|
}
|
||||||
return cr.route(cr.router.Get, "GET", h...)
|
return cr.route(cr.router.Get, "GET", h...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue