Read-only git smart-HTTP frontend (protocol v0, git-upload-pack only).
Serves git clone and git fetch over HTTP on top of the git core
reader and git.pack packfile generation. Provides serve which builds
a handler function for http.server, plus the underlying protocol
pieces (info_refs, upload_pack, pkt-line helpers) for direct use
and testing.
Negotiation is deliberately naive: all have lines are ignored and a
full pack of everything reachable from the wanted refs is sent once the
client says done. Correct for both clone and fetch, just not
bandwidth-optimal on incremental fetches. Shallow (--depth) and
partial (--filter) requests are rejected with an ERR pkt.
The pack is assembled in memory (see git.pack), so peak memory use
is roughly the compressed pack size — fine for small and medium
repositories.
| Name | Signature |
|---|---|
| encode_pkt | encode_pkt(data) -> pkt |
| decode_pkts | decode_pkts(body) -> pkts, err |
| info_refs | info_refs(git_dir) -> body |
| parse_upload_pack_request | parse_upload_pack_request(body) -> req, err |
| upload_pack | upload_pack(git_dir, body) -> response |
| serve | serve(repos) -> handle, err |
encode_pkt(
data) ->pkt
Encode a pkt-line
decode_pkts(
body) ->pkts,err
Decode a pkt-line stream into an array of { kind = "line"|"flush", data } entries
info_refs(
git_dir) ->body
Build the info/refs smart advertisement for service=git-upload-pack
parse_upload_pack_request(
body) ->req,err
Parse an upload-pack request body (want/have/done pkt-lines)
Returns { wants = {sha, ...}, haves = n, done = bool, side_band = bool, side_band_64k = bool }. Shallow and filter requests yield an error.
upload_pack(
git_dir,body) ->response
Answer an upload-pack POST body with an upload-pack response
Stateless-RPC negotiation: rounds without done get a bare NAK (all
haves are ignored); once the client sends done, a full pack of
everything reachable from the wants follows, side-band framed when the
client requested it. Errors become ERR pkts / band-3 messages.
serve(
repos) ->handle,err
Build an http.server handler serving the given repositories read-only
repos maps URL prefixes to repository paths, e.g.
{ ["/lilush"] = "/srv/git/lilush.git" }. Each path must be a git
directory (bare repository) or a worktree containing .git. URLs may
carry an optional .git suffix (clone http://host/lilush.git works).
The returned function matches the http.server handler contract:
handle(method, query, args, headers, body, ctx).