Nutikas HTTP
Pitmaster suhtleb git-serveritega HTTPS kaudu, kasutades nutikat HTTP-protokolli. See on peamine võrguedastusviis. See kasutab PHP natiivseid voo-funktsioone (fopen voo kontekstiga) HTTP päringute jaoks, seega peab allow_url_fopen olema lubatud.
SmartHttpClient
use Pitmaster\Protocol\SmartHttpClient;
$http = new SmartHttpClient();
// Or with custom timeout:
$http = new SmartHttpClient(timeout: 60);
Vaikimisi on ajalõpp konstant PITMASTER_HTTP_TIMEOUT (täisarv) või 30 sekundit, kui see pole määratud.
Viidete tuvastamine
$discovery = $http->discoverRefs('https://github.com/user/repo.git');
foreach ($discovery->refs() as $name => $id) {
echo "{$id->hex} {$name}\n";
}
// HEAD symref (e.g., 'refs/heads/main')
$defaultBranch = $discovery->headSymref();
// Specific ref
$mainId = $discovery->ref('refs/heads/main');
// Server capabilities (a Capability object, or null)
$caps = $discovery->capabilities();
discoverReceivePackRefs() teeb sama git-receive-pack puhul. Viidete tuvastamise päring saadetakse aadressile:
GET <url>/info/refs?service=git-upload-pack
Vastus on pkt-line-kodeeringus viidete loend, mille esimesel real on võimalused.
Paketi üleslaadimine (toomine)
$response = $http->uploadPack($url, $requestBody);
Saadab aadressile <url>/git-upload-pack POST-päringu, mille sisuks on want/have läbirääkimisandmed. Tagastab toore vastusekeha (pkt-read, NAK ja side-band-andmed). UploadPackClient koostab päringu ja eraldab paketi:
use Pitmaster\Protocol\UploadPackClient;
$client = new UploadPackClient($http);
$packData = $client->fetch($url, $wants, $haves); // ObjectId[] wants and haves
Paketi vastuvõtmine (tõukamine)
$response = $http->receivePack($url, $requestBody);
Saadab aadressile <url>/git-receive-pack POST-päringu koos viidete uuenduskäskude ja paketiandmetega.
PktLine'i kodeering
git-protokoll kasutab kogu side jaoks pkt-line-raamistust. Iga rea ees on selle kogupikkus (koos 4-baidise pikkuse eesliitega), mis on kodeeritud 4 kuueteistkümnendnumbrina.
use Pitmaster\Protocol\PktLine;
// Encode a single line
$encoded = PktLine::encode("want abc123def456\n");
// "0016want abc123def456\n"
// Flush packet (end of section)
$flush = PktLine::flush();
// "0000"
// Delimiter packet (protocol v2)
$delim = PktLine::delimiter();
// "0001"
// Decode a stream
$lines = PktLine::decode($rawData);
// Each element is: string (data), null (flush), or false (delimiter)
Pikkusreeglid
- Andmerea minimaalne pikkus:
0005(1 baidi kasulik koormus) - Andmerea maksimaalne pikkus:
fff0(65516 baidi kasulik koormus) - Tühjenduspakett:
0000 - Eraldajapakett:
0001 - Vastuse lõpp:
0002(protokolli v2; seda käsitlebProtocolV2::decode(),PktLine::decode()lükkab selle tagasi)
PktLine::MAX_PAYLOAD; // 65516 (65520 - 4)
Viidete tuvastamine
RefDiscovery klass parsib serveri viiteteate.
use Pitmaster\Protocol\RefDiscovery;
$discovery = RefDiscovery::parse($pktLines);
// All refs
$refs = $discovery->refs();
// ['refs/heads/main' => ObjectId, 'refs/tags/v1.0' => ObjectId, ...]
// Single ref
$id = $discovery->ref('refs/heads/main');
// HEAD symbolic ref (from capabilities)
$symref = $discovery->headSymref();
// 'refs/heads/main' or null
// Server capabilities
$caps = $discovery->capabilities();
// Capability object (see below), or null
Viiteteate vorming
Teate esimene rida sisaldab võimalusi:
<hash> HEAD\0<capability list>\n
<hash> refs/heads/main\n
<hash> refs/tags/v1.0\n
0000
Võimalused
Capability klass parsib ja haldab protokolli võimalusi.
use Pitmaster\Protocol\Capability;
$caps = Capability::parse('thin-pack side-band-64k ofs-delta symref=HEAD:refs/heads/main');
$caps->has('thin-pack'); // true
$caps->get('symref'); // 'HEAD:refs/heads/main'
$caps->all(); // ['thin-pack' => null, ..., 'symref' => 'HEAD:refs/heads/main']
Levinud võimalused
| Võimalus | Tähendus |
|---|---|
multi_ack |
Server toetab mitme ACK-ga läbirääkimist |
thin-pack |
Server saadab õhukesi pakette (baasobjektid võivad puududa). Pitmaster küsib seda, kuid ei suuda veel õhukesi pakette indekseerida (#16) |
side-band |
Server kasutab paketiandmete jaoks side-band'i (piirang 1000 baidile) |
side-band-64k |
Server kasutab paketiandmete jaoks 64K side-band'i |
ofs-delta |
Pakett võib kasutada OFS_DELTA-objekte |
shallow |
Server toetab madalat kloonimist |
no-done |
Server ei nõua rida "done" |
symref=HEAD:refs/heads/main |
HEAD-i sümboolne sihtmärk |
agent=git/2.45.0 |
Serveri git-versioon |
Side-band-kanalite eraldamine
Kui server kasutab side-band'i, multipleksitakse paketiandmed edenemis- ja veateadetega. Iga pkt-line'i kasuliku koormuse esimene bait näitab kanalit:
| Kanal | Tähendus |
|---|---|
| 1 | Paketiandmed |
| 2 | Edenemisteated (stderr) |
| 3 | Saatuslikud veateated |
Pitmaster UploadPackClient eemaldab kanali baidid ja paneb paketiandmed uuesti kokku.
Protokolli versioonid
v1 (vaikimisi)
Traditsiooniline protokoll. Viidete tuvastamisel saadetakse kõik viited korraga. Pitmaster peab läbirääkimisi ühes voorus: saadab oma soovid, iga kohaliku viite tipu kui have ning done.
v2
Lihtsam ja parema jõudlusega protokoll.
Peamised erinevused võrreldes protokolliga v1:
- Viidete tuvastamine on eraldi käsk
ls-refs(viiteid saab filtreerida) - Toomine on üks käsk
fetchstruktureeritud parameetritega - Sektsioonide eraldamiseks kasutatakse eraldajapakette (
0001)
clone() ja fetch() kasutavad alati v1. v2 on saadaval, kui kutsute selle selgesõnaliselt:
$discovery = $http->discoverRefsV2($url); // ls-refs
$packData = (new UploadPackClient($http))->fetchV2($url, $wants, $haves);
HTTP päringuvoog
Kloonimine/toomine
1. GET /info/refs?service=git-upload-pack
Response: pkt-line encoded ref list
2. POST /git-upload-pack
Request: want <hash>\n ... have <hash>\n ... done\n
Response: NAK\n + pack data (possibly side-band wrapped)
Tõukamine
1. GET /info/refs?service=git-receive-pack
Response: pkt-line encoded ref list
2. POST /git-receive-pack
Request: <old-hash> <new-hash> refs/heads/main\0<capabilities>\n
0000
PACK<pack data>
Response: unpack ok\n + ref status lines
Vigade käsitlemine
Võrguvead põhjustavad ProtocolException. Kui nutikas HTTP-vahetus clone() või fetch() korral nurjub, proovib Pitmaster uuesti rumala HTTP kaudu ja viskab ebaõnnestumise korral algse vea uuesti. Muud tõrked (tundmatu kaugserver, protsessita käepide, indekseerimatu pakett) põhjustavad teist tüüpi erindeid:
use Pitmaster\Exceptions\ProtocolException;
try {
$repo->fetch();
} catch (ProtocolException $e) {
echo "Network error: {$e->getMessage()}\n";
}
Levinud vead:
- Server pole kättesaadav (ajalõpp)
- Nõutakse autentimist või repositooriumi ei leitud (teatatuna kui
Unexpected HTTP status 401,403või404) - Ootamatu
Content-Typevastuses - Vigased pkt-line-andmed
- Side-band'i veakanali teade