96 lines
3.8 KiB
Diff
96 lines
3.8 KiB
Diff
12a13
|
|
> "net/url"
|
|
81c82,99
|
|
< isPull = ctx.Req.Method == "GET"
|
|
---
|
|
> // In addition to GET requests, HEAD requests are also "pull"
|
|
> // operations (reads), so they should also not require
|
|
> // authentication. This is necessary for git-annex to operate
|
|
> // properly, as it emits HEAD requests to check for the
|
|
> // existence of keys, e.g. before dropping locally, and asking
|
|
> // for authentication would break unauthenticated http usage in
|
|
> // this situation.
|
|
> // It should be safe to make all HEAD requests require no
|
|
> // authentication, but as it is only necessary for the
|
|
> // annex/objects endpoints to fix git-annex' drop operations it
|
|
> // is limited to those for now.
|
|
> r, err := regexp.Compile("^/?" + username + "/" + reponame + "(.git)?/annex/objects")
|
|
> if err != nil {
|
|
> ctx.ServerError("failed to create URL path regex", err)
|
|
> return nil
|
|
> }
|
|
> isPull = ctx.Req.Method == "GET" ||
|
|
> r.MatchString(ctx.Req.URL.Path) && ctx.Req.Method == "HEAD"
|
|
470c488
|
|
< if !git.IsErrCanceledOrKilled(err) {
|
|
---
|
|
> if err.Error() != "signal: killed" {
|
|
547a566,601
|
|
> // GetConfig implements fetching the git config of a repository
|
|
> func GetConfig(ctx *context.Context) {
|
|
> h := httpBase(ctx)
|
|
> if h != nil {
|
|
> setHeaderNoCache(ctx)
|
|
> config, err := os.ReadFile(filepath.Join(h.getRepoDir(), "config"))
|
|
> if err != nil {
|
|
> log.Error("Failed to read git config file: %v", err)
|
|
> ctx.Resp.WriteHeader(http.StatusInternalServerError)
|
|
> return
|
|
> }
|
|
> if !setting.Annex.DisableP2PHTTP {
|
|
> appURL, err := url.Parse(setting.AppURL)
|
|
> if err != nil {
|
|
> log.Error("Could not parse 'setting.AppURL': %v", err)
|
|
> ctx.Resp.WriteHeader(http.StatusInternalServerError)
|
|
> return
|
|
> }
|
|
> if appURL.Port() == "" {
|
|
> // If there is no port set then set the http(s) default ports.
|
|
> // Without this, git-annex would try its own default port (9417) and fail.
|
|
> if appURL.Scheme == "http" {
|
|
> appURL.Host += ":80"
|
|
> }
|
|
> if appURL.Scheme == "https" {
|
|
> appURL.Host += ":443"
|
|
> }
|
|
> }
|
|
> config = append(config, []byte("[annex]\n\turl = annex+"+appURL.String()+"git-annex-p2phttp\n")...)
|
|
> }
|
|
> ctx.Resp.Header().Set("Content-Type", "text/plain")
|
|
> ctx.Resp.Header().Set("Content-Length", fmt.Sprintf("%d", len(config)))
|
|
> http.ServeContent(ctx.Resp, ctx.Req, "config", time.Now(), bytes.NewReader(config))
|
|
> }
|
|
> }
|
|
>
|
|
597a652,682
|
|
> }
|
|
> }
|
|
>
|
|
> // GetAnnexObject implements git-annex dumb HTTP
|
|
> func GetAnnexObject(ctx *context.Context) {
|
|
> h := httpBase(ctx)
|
|
> if h != nil {
|
|
> // git-annex objects are stored in .git/annex/objects/{hash1}/{hash2}/{key}/{key}
|
|
> // where key is a string containing the size and (usually SHA256) checksum of the file,
|
|
> // and hash1+hash2 are the first few bits of the md5sum of key itself.
|
|
> // ({hash1}/{hash2}/ is just there to avoid putting too many files in one directory)
|
|
> // ref: https://git-annex.branchable.com/internals/hashing/
|
|
>
|
|
> // keyDir should = key, but we don't enforce that
|
|
> object := filepath.Join(ctx.Params("hash1"), ctx.Params("hash2"), ctx.Params("keyDir"), ctx.Params("key"))
|
|
>
|
|
> // Sanitize the input against directory traversals.
|
|
> //
|
|
> // This works because at the filesystem root, "/.." = "/";
|
|
> // So if a path starts rooted ("/"), path.Clean(), which
|
|
> // path.Join() calls internally, removes all '..' prefixes.
|
|
> // After, this unroots the path unconditionally ([1:]), which
|
|
> // works because we know the input is never supposed to be rooted.
|
|
> //
|
|
> // The router code probably also disallows "..", so this
|
|
> // should be redundant, but it's defensive to keep it
|
|
> // whenever touching filesystem paths with user input.
|
|
> object = filepath.Join(string(filepath.Separator), object)[1:]
|
|
>
|
|
> setHeaderCacheForever(ctx)
|
|
> h.sendFile(ctx, "application/octet-stream", "annex/objects/"+object)
|