Skip to main content

UploadPack

Struct UploadPack 

Source
pub struct UploadPack<'a> { /* private fields */ }
Expand description

The server side of git-upload-pack.

One of these serves one connection. That matters for Self::fetch, which a v2 client calls once per negotiation round: the haves a client has already been answered about are memoised here rather than re-resolved against the object store every round. The memo holds no decisions, only facts about the store (see negotiate::HaveMemo), so a shared or reused instance answers the same, only slower.

Implementations§

Source§

impl<'a> UploadPack<'a>

Source

pub fn new(git: &'a dyn GitServe, hash_kind: Kind) -> Self

Serve objects/refs with default configuration.

Source

pub fn with_config(self, config: Config) -> Self

Replace the configuration.

The have memo is rebuilt, because its ceiling is derived from Config::limits — a configuration that lifted the request ceiling and left a memo capped at the old one would be honouring a limit nobody set.

Source

pub fn hash_kind(&self) -> Kind

The repository’s hash kind, and the only source of object-format.

Source

pub fn serve( &self, version: ProtocolVersion, input: &mut dyn BufRead, out: &mut dyn Write, ) -> Result<UploadSummary>

Serve one connection at the given protocol version.

Source

pub fn serve_session( &self, version: ProtocolVersion, session: Session, input: &mut dyn BufRead, out: &mut dyn Write, ) -> Result<UploadSummary>

Serve one call at the given protocol version and Session.

Session::Connected is what serve does and what SSH uses. Session::StatelessRpc is one smart-HTTP POST: no advertisement is written (it was a separate GET), and the call answers one round and returns.

Source

pub fn advertise( &self, version: ProtocolVersion, out: &mut dyn Write, ) -> Result<()>

The advertisement a smart-HTTP GET /info/refs?service=git-upload-pack answers with, for either protocol version.

The # service=git-upload-pack preamble is not written here: it is an HTTP framing detail (and one protocol v2 does not use at all), so it belongs to gunnar-http and not to a state machine that also runs over SSH, where no such line exists.

Source

pub fn capability_advertisement(&self) -> Result<Vec<u8>>

The v2 capability advertisement, as bytes.

Sent before the client says anything, exactly as git-upload-pack does.

Source

pub fn write_capability_advertisement(&self, out: &mut dyn Write) -> Result<()>

Write the v2 capability advertisement.

Source

pub fn serve_v2( &self, input: &mut dyn BufRead, out: &mut dyn Write, ) -> Result<UploadSummary>

The whole v2 session: advertisement, then commands until the client stops.

Source

pub fn serve_v2_session( &self, session: Session, input: &mut dyn BufRead, out: &mut dyn Write, ) -> Result<UploadSummary>

The v2 session, for either Session.

Under Session::StatelessRpc the advertisement is skipped and the call returns after one command, because that is what one HTTP POST carries. Returning after one is not merely equivalent to hitting EOF: a body carrying a second command would otherwise be served on a negotiation state the next POST cannot see, which is the shape of a clone that loops.

Source

pub fn ls_refs( &self, request: &LsRefsRequest, out: &mut dyn Write, ) -> Result<()>

command=ls-refs.

Source

pub fn fetch( &self, request: &FetchRequest, out: &mut dyn Write, ) -> Result<FetchOutcome>

command=fetch, one round.

Returns without a packfile when negotiation is not finished; the client then sends another command=fetch with more haves.

Source

pub fn write_ref_advertisement(&self, out: &mut dyn Write) -> Result<()>

The v0 reference advertisement.

Source

pub fn serve_v0( &self, input: &mut dyn BufRead, out: &mut dyn Write, ) -> Result<UploadSummary>

The whole v0 session.

Source

pub fn serve_v0_session( &self, session: Session, input: &mut dyn BufRead, out: &mut dyn Write, ) -> Result<UploadSummary>

The v0 session, for either Session.

§What stateless-rpc changes here, and it is one branch

v0 has no command= boundary, so a stateless round is delimited by the client’s flush-pkt after its have list. Under Session::StatelessRpc that flush ends the call: the server answers ACK/NAK and returns, and the client opens a new POST carrying its whole want list again plus the haves it has since decided to send. Under Session::Connected the same flush ends only a round and the loop keeps reading, which is what SSH needs.

Getting this wrong is not a subtle bug: a server that kept reading would block on a body that has already ended, and the client would sit waiting for a response that is waiting for it.

Source

pub fn report_error( &self, out: &mut dyn Write, sideband: bool, message: &str, ) -> Result<()>

Report a fatal condition to the client in whichever way this point of the protocol allows: an ERR line before a pack has started, band 3 once the sideband is open.

Auto Trait Implementations§

§

impl<'a> !Freeze for UploadPack<'a>

§

impl<'a> !RefUnwindSafe for UploadPack<'a>

§

impl<'a> !UnwindSafe for UploadPack<'a>

§

impl<'a> Send for UploadPack<'a>

§

impl<'a> Sync for UploadPack<'a>

§

impl<'a> Unpin for UploadPack<'a>

§

impl<'a> UnsafeUnpin for UploadPack<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more