Skip to content

Commit

Permalink
Fix /verify LFS handler expecting wrong content-type (go-gitea#7015)
Browse files Browse the repository at this point in the history
Fixes go-gitea#6960

According to [spec][1], /verify requests must have `Accept: application/vnd.git-lfs+json`

Previous code works because `git-lfs` also [violates spec and doesn't send any Accept header at all][2]
For other clients that DO set `Accept: application/vnd.git-lfs+json`, addition of `Accept: application/vnd.git-lfs`
either forces them to violate the spec or is ignored, depending on order in what they create header list.

[1]: https://github.com/git-lfs/git-lfs/blob/master/docs/api/basic-transfers.md#verification
[2]: git-lfs/git-lfs#3662
  • Loading branch information
slonopotamus authored and jeffliu27 committed Jul 18, 2019
1 parent 78faa26 commit eeb4532
Showing 1 changed file with 15 additions and 18 deletions.
33 changes: 15 additions & 18 deletions modules/lfs/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ import (
)

const (
contentMediaType = "application/vnd.git-lfs"
metaMediaType = contentMediaType + "+json"
metaMediaType = "application/vnd.git-lfs+json"
)

// RequestVars contain variables from the HTTP request. Variables from routing, json body decoding, and
Expand Down Expand Up @@ -101,11 +100,10 @@ func ObjectOidHandler(ctx *context.Context) {
getMetaHandler(ctx)
return
}
if ContentMatcher(ctx.Req) || len(ctx.Params("filename")) > 0 {
getContentHandler(ctx)
return
}
} else if ctx.Req.Method == "PUT" && ContentMatcher(ctx.Req) {

getContentHandler(ctx)
return
} else if ctx.Req.Method == "PUT" {
PutHandler(ctx)
return
}
Expand Down Expand Up @@ -348,7 +346,7 @@ func VerifyHandler(ctx *context.Context) {
return
}

if !ContentMatcher(ctx.Req) {
if !MetaMatcher(ctx.Req) {
writeStatus(ctx, 400)
return
}
Expand Down Expand Up @@ -385,7 +383,6 @@ func Represent(rv *RequestVars, meta *models.LFSMetaObject, download, upload boo
}

header := make(map[string]string)
header["Accept"] = contentMediaType

if rv.Authorization == "" {
//https://github.com/github/git-lfs/issues/1088
Expand All @@ -404,20 +401,20 @@ func Represent(rv *RequestVars, meta *models.LFSMetaObject, download, upload boo

if upload && !download {
// Force client side verify action while gitea lacks proper server side verification
rep.Actions["verify"] = &link{Href: rv.VerifyLink(), Header: header}
verifyHeader := make(map[string]string)
for k, v := range header {
verifyHeader[k] = v
}

// This is only needed to workaround https://github.com/git-lfs/git-lfs/issues/3662
verifyHeader["Accept"] = metaMediaType

rep.Actions["verify"] = &link{Href: rv.VerifyLink(), Header: verifyHeader}
}

return rep
}

// ContentMatcher provides a mux.MatcherFunc that only allows requests that contain
// an Accept header with the contentMediaType
func ContentMatcher(r macaron.Request) bool {
mediaParts := strings.Split(r.Header.Get("Accept"), ";")
mt := mediaParts[0]
return mt == contentMediaType
}

// MetaMatcher provides a mux.MatcherFunc that only allows requests that contain
// an Accept header with the metaMediaType
func MetaMatcher(r macaron.Request) bool {
Expand Down

0 comments on commit eeb4532

Please sign in to comment.