1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
package server
import (
"io"
"codeberg.org/lindenii/furgit/format/pktline"
"codeberg.org/lindenii/furgit/format/sideband64k"
"codeberg.org/lindenii/furgit/objectid"
)
// Options configures one server-side v0/v1 session.
type Options struct {
// Version selects protocol v0 or v1 framing.
Version Version
// Algorithm is the repository object ID algorithm for this session.
Algorithm objectid.Algorithm
}
// Session is one stateful server-side v0/v1 server protocol session.
type Session struct {
dec *pktline.Decoder
enc *pktline.Encoder
sideband *sideband64k.Encoder
opts Options
useSideBand bool
}
// NewSession creates one v0/v1 server session over r and w.
func NewSession(r io.Reader, w pktline.WriteFlusher, opts Options) *Session {
return &Session{
dec: pktline.NewDecoder(r, pktline.ReadOptions{}),
enc: pktline.NewEncoder(w),
sideband: sideband64k.NewEncoder(w),
opts: opts,
}
}
// Algorithm returns the session object ID algorithm.
func (session *Session) Algorithm() objectid.Algorithm {
return session.opts.Algorithm
}
// ReadFrame reads one low-level pkt-line frame from the session input.
func (session *Session) ReadFrame() (Frame, error) {
return session.dec.ReadFrame()
}
// EnableSideBand64K enables side-band-64k output framing for subsequent data,
// progress, error, and flush writes.
func (session *Session) EnableSideBand64K() {
session.useSideBand = true
}
// WriteData writes one primary output packet.
func (session *Session) WriteData(p []byte) error {
if session.useSideBand {
return session.sideband.WriteData(p)
}
return session.enc.WriteData(p)
}
// WriteProgress writes one progress packet.
func (session *Session) WriteProgress(p []byte) error {
if !session.useSideBand {
return ErrSideBandNotEnabled
}
return session.sideband.WriteProgress(p)
}
// WriteError writes one fatal error packet.
func (session *Session) WriteError(p []byte) error {
if !session.useSideBand {
return ErrSideBandNotEnabled
}
return session.sideband.WriteError(p)
}
// WriteFlush writes one trailing flush packet.
func (session *Session) WriteFlush() error {
if session.useSideBand {
return session.sideband.WriteFlush()
}
return session.enc.WriteFlush()
}
// ProgressWriter returns one chunking writer for sideband progress output.
//
// When side-band-64k was not negotiated, writes are discarded.
func (session *Session) ProgressWriter() io.Writer {
if !session.useSideBand {
return io.Discard
}
return sideband64k.NewChunkWriter(session.sideband, sideband64k.BandProgress)
}
// ErrorWriter returns one chunking writer for sideband error output.
//
// When side-band-64k was not negotiated, writes are discarded.
func (session *Session) ErrorWriter() io.Writer {
if !session.useSideBand {
return io.Discard
}
return sideband64k.NewChunkWriter(session.sideband, sideband64k.BandError)
}
|