Skip to main content

Module web_edit

Module web_edit 

Source
Expand description

POST <prefix>/api/repos/<owner>/<repo>/edit: commit one file over HTTP, the GitHub web-editor equivalent.

Follows the JSS forge tier 3.7 (apiRepoEdit, cleanEditPath, withCors, cited by name only; all code original). The request body is {"path", "content", "message"?, "branch"?}.

§Authorisation

Owner-signed by default: no credential is 401 (with a Bearer challenge), a credential for another namespace is 403. With ForgeConfig::open_edit (JSS openEdit) no authorisation check runs at all: an anonymous caller may edit any repository. JSS has no “demo namespace” restriction and neither does this port; the flag is for throwaway demo forges only and ForgeService::new logs a warning when it is on.

§How the commit is made

JSS clones the bare repository into a temporary working tree. This port never checks anything out: it hashes the content with git hash-object, stages it into a private index file (GIT_INDEX_FILE, seeded with read-tree), writes the tree, creates the commit with commit-tree and advances the branch with update-ref <ref> <new> <old>. The old value is the tip read under the per-repository lock, so a racing push makes the write fail with 409 instead of being overwritten (compare-and-swap). Every git invocation goes through the hardened argv-only runner; no value supplied by the caller ever reaches git as an option.

§Path rules

See clean_edit_path. Compared with JSS this port is deliberately stricter in three places: the .git check is case-insensitive (so .GIT and .Git are refused), segments made only of dots (., ...) and NTFS spellings of .git (.git., git~1) are refused, and an existing symlink, submodule or directory at the target (or a symlink or file on the way to it) is a 409, never written through.

§Examples

use solid_pod_rs_forge::web_edit::{clean_edit_path, clean_message};

assert_eq!(clean_edit_path("docs/guide.md").as_deref(), Some("docs/guide.md"));
assert!(clean_edit_path("../x").is_none());
assert!(clean_edit_path("a/.GIT/config").is_none());
assert_eq!(clean_message(Some("  fix\n\ttypo "), "a.txt"), "fix typo");
assert_eq!(clean_message(None, "a.txt"), "web edit: a.txt");

Constants§

EDIT_BODY_CAP
Largest request body read: content cap plus 128 KiB of JSON framing (JSS readJsonBody(request, EDIT_CONTENT_CAP + 128 * 1024)).
EDIT_CONTENT_CAP
Largest file content accepted, in bytes (JSS EDIT_CONTENT_CAP, 1 MiB).
EDIT_MSG_CAP
Longest commit message kept, in characters (JSS EDIT_MSG_CAP).
EDIT_PATH_CAP
Longest accepted path, in characters (JSS EDIT_PATH_CAP).

Functions§

clean_edit_path
Validate a repo-relative edit path (JSS cleanEditPath). Returns the clean path, or None.
clean_message
The commit message for an edit: control-character runs become one space, the result is trimmed and cut to EDIT_MSG_CAP characters (never inside a UTF-8 sequence), and an empty result becomes web edit: <path>.