Fix /verify LFS handler expecting wrong content-type (#7015)
Fixes #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]: https://github.com/git-lfs/git-lfs/issues/3662
This commit is contained in:
		
							parent
							
								
									61f00bc238
								
							
						
					
					
						commit
						844f9a4bd8
					
				| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -348,7 +346,7 @@ func VerifyHandler(ctx *context.Context) {
 | 
			
		|||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !ContentMatcher(ctx.Req) {
 | 
			
		||||
	if !MetaMatcher(ctx.Req) {
 | 
			
		||||
		writeStatus(ctx, 400)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -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 {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue