5 Star 11 Fork 7

Gitee 极速下载/go-git

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
此仓库是为了提升国内下载速度的镜像仓库,每日同步一次。 原始仓库: https://github.com/src-d/go-git
克隆/下载
srvresp.go 2.71 KB
一键复制 编辑 原始数据 按行查看 历史
ferhat elmas 提交于 2017-11-29 02:24 . all: simplification
package packp
import (
"bufio"
"bytes"
"errors"
"fmt"
"io"
"gopkg.in/src-d/go-git.v4/plumbing"
"gopkg.in/src-d/go-git.v4/plumbing/format/pktline"
)
const ackLineLen = 44
// ServerResponse object acknowledgement from upload-pack service
type ServerResponse struct {
ACKs []plumbing.Hash
}
// Decode decodes the response into the struct, isMultiACK should be true, if
// the request was done with multi_ack or multi_ack_detailed capabilities.
func (r *ServerResponse) Decode(reader *bufio.Reader, isMultiACK bool) error {
// TODO: implement support for multi_ack or multi_ack_detailed responses
if isMultiACK {
return errors.New("multi_ack and multi_ack_detailed are not supported")
}
s := pktline.NewScanner(reader)
for s.Scan() {
line := s.Bytes()
if err := r.decodeLine(line); err != nil {
return err
}
// we need to detect when the end of a response header and the beginning
// of a packfile header happened, some requests to the git daemon
// produces a duplicate ACK header even when multi_ack is not supported.
stop, err := r.stopReading(reader)
if err != nil {
return err
}
if stop {
break
}
}
return s.Err()
}
// stopReading detects when a valid command such as ACK or NAK is found to be
// read in the buffer without moving the read pointer.
func (r *ServerResponse) stopReading(reader *bufio.Reader) (bool, error) {
ahead, err := reader.Peek(7)
if err == io.EOF {
return true, nil
}
if err != nil {
return false, err
}
if len(ahead) > 4 && r.isValidCommand(ahead[0:3]) {
return false, nil
}
if len(ahead) == 7 && r.isValidCommand(ahead[4:]) {
return false, nil
}
return true, nil
}
func (r *ServerResponse) isValidCommand(b []byte) bool {
commands := [][]byte{ack, nak}
for _, c := range commands {
if bytes.Equal(b, c) {
return true
}
}
return false
}
func (r *ServerResponse) decodeLine(line []byte) error {
if len(line) == 0 {
return fmt.Errorf("unexpected flush")
}
if bytes.Equal(line[0:3], ack) {
return r.decodeACKLine(line)
}
if bytes.Equal(line[0:3], nak) {
return nil
}
return fmt.Errorf("unexpected content %q", string(line))
}
func (r *ServerResponse) decodeACKLine(line []byte) error {
if len(line) < ackLineLen {
return fmt.Errorf("malformed ACK %q", line)
}
sp := bytes.Index(line, []byte(" "))
h := plumbing.NewHash(string(line[sp+1 : sp+41]))
r.ACKs = append(r.ACKs, h)
return nil
}
// Encode encodes the ServerResponse into a writer.
func (r *ServerResponse) Encode(w io.Writer) error {
if len(r.ACKs) > 1 {
return errors.New("multi_ack and multi_ack_detailed are not supported")
}
e := pktline.NewEncoder(w)
if len(r.ACKs) == 0 {
return e.Encodef("%s\n", nak)
}
return e.Encodef("%s %s\n", ack, r.ACKs[0].String())
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/mirrors/go-git.git
git@gitee.com:mirrors/go-git.git
mirrors
go-git
go-git
v4.4.0

搜索帮助