package xrpc import ( "net/http" "tangled.org/core/knotserver/vcs" xrpcerr "tangled.org/core/xrpc/errors" "tangled.org/core/api/tangled" ) // RepoPijulTree is kept as an alias for backwards compatibility. // It delegates to the unified RepoTree handler. func (x *Xrpc) RepoPijulTree(w http.ResponseWriter, r *http.Request) { // Map channel param to ref if present, then delegate q := r.URL.Query() if channel := q.Get("channel"); channel != "" && q.Get("ref") == "" { q.Set("ref", channel) r.URL.RawQuery = q.Encode() } x.RepoTree(w, r) } // RepoPijulBlob handles the sh.tangled.repo.pijulBlob endpoint // Returns file content from a Pijul repository func (x *Xrpc) RepoPijulBlob(w http.ResponseWriter, r *http.Request) { repo := r.URL.Query().Get("repo") repoPath, err := x.parseRepoParam(repo) if err != nil { writeError(w, err.(xrpcerr.XrpcError), http.StatusBadRequest) return } channel := r.URL.Query().Get("channel") path := r.URL.Query().Get("path") if path == "" { writeError(w, xrpcerr.NewXrpcError( xrpcerr.WithTag("InvalidRequest"), xrpcerr.WithMessage("missing path parameter"), ), http.StatusBadRequest) return } rv, err := vcs.Open(repoPath, channel) if err != nil { writeError(w, xrpcerr.NewXrpcError( xrpcerr.WithTag("RepoNotFound"), xrpcerr.WithMessage("failed to open pijul repository"), ), http.StatusNotFound) return } // Try to read as text first const maxSize = 1024 * 1024 // 1MB content, err := rv.FileContentN(path, maxSize) if err != nil { if vcs.IsBinaryFileError(err) { // Return binary indicator response := tangled.RepoPijulBlob_Output{ Is_binary: true, Path: path, Ref: &channel, } writeJson(w, response) return } x.Logger.Error("failed to read file", "error", err, "path", path) writeError(w, xrpcerr.NewXrpcError( xrpcerr.WithTag("PathNotFound"), xrpcerr.WithMessage("failed to read file"), ), http.StatusNotFound) return } contentStr := string(content) response := tangled.RepoPijulBlob_Output{ Contents: &contentStr, Path: path, Ref: &channel, } writeJson(w, response) }