mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08:00 
			
		
		
		
	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:
		
				
					committed by
					
						
						zeripath
					
				
			
			
				
	
			
			
			
						parent
						
							61f00bc238
						
					
				
				
					commit
					844f9a4bd8
				
			@@ -22,8 +22,7 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	contentMediaType = "application/vnd.git-lfs"
 | 
						metaMediaType = "application/vnd.git-lfs+json"
 | 
				
			||||||
	metaMediaType    = contentMediaType + "+json"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RequestVars contain variables from the HTTP request. Variables from routing, json body decoding, and
 | 
					// 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)
 | 
								getMetaHandler(ctx)
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if ContentMatcher(ctx.Req) || len(ctx.Params("filename")) > 0 {
 | 
					
 | 
				
			||||||
			getContentHandler(ctx)
 | 
							getContentHandler(ctx)
 | 
				
			||||||
			return
 | 
							return
 | 
				
			||||||
		}
 | 
						} else if ctx.Req.Method == "PUT" {
 | 
				
			||||||
	} else if ctx.Req.Method == "PUT" && ContentMatcher(ctx.Req) {
 | 
					 | 
				
			||||||
		PutHandler(ctx)
 | 
							PutHandler(ctx)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -348,7 +346,7 @@ func VerifyHandler(ctx *context.Context) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if !ContentMatcher(ctx.Req) {
 | 
						if !MetaMatcher(ctx.Req) {
 | 
				
			||||||
		writeStatus(ctx, 400)
 | 
							writeStatus(ctx, 400)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -385,7 +383,6 @@ func Represent(rv *RequestVars, meta *models.LFSMetaObject, download, upload boo
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	header := make(map[string]string)
 | 
						header := make(map[string]string)
 | 
				
			||||||
	header["Accept"] = contentMediaType
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if rv.Authorization == "" {
 | 
						if rv.Authorization == "" {
 | 
				
			||||||
		//https://github.com/github/git-lfs/issues/1088
 | 
							//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 {
 | 
						if upload && !download {
 | 
				
			||||||
		// Force client side verify action while gitea lacks proper server side verification
 | 
							// 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
 | 
						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
 | 
					// MetaMatcher provides a mux.MatcherFunc that only allows requests that contain
 | 
				
			||||||
// an Accept header with the metaMediaType
 | 
					// an Accept header with the metaMediaType
 | 
				
			||||||
func MetaMatcher(r macaron.Request) bool {
 | 
					func MetaMatcher(r macaron.Request) bool {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user