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
					
				
					 1 changed files with 15 additions and 18 deletions
				
			
		|  | @ -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 a new issue