func (s *GitUploadPackService) Fetch(r *common.GitUploadPackRequest) (io.ReadCloser, error) { url := fmt.Sprintf("%s/%s", s.endpoint, common.GitUploadPackServiceName) res, err := s.doRequest("POST", url, r.Reader()) if err != nil { return nil, err } h := make([]byte, 8) if _, err := res.Body.Read(h); err != nil { return nil, core.NewUnexpectedError(err) } return res.Body, nil }
// Fetch retrieves the GitUploadPack form the repository. // You must be connected to the repository before using this method // (using the ConnectWithAuth() method). // TODO: fetch should really reuse the info session instead of openning a new // one func (s *GitUploadPackService) Fetch(r *common.GitUploadPackRequest) (rc io.ReadCloser, err error) { if !s.connected { return nil, ErrNotConnected } session, err := s.client.NewSession() if err != nil { return nil, err } defer func() { // the session can be closed by the other endpoint, // therefore we must ignore a close error. _ = session.Close() }() si, err := session.StdinPipe() if err != nil { return nil, err } so, err := session.StdoutPipe() if err != nil { return nil, err } go func() { fmt.Fprintln(si, r.String()) err = si.Close() }() err = session.Start("git-upload-pack " + s.vcs.FullName + ".git") if err != nil { return nil, err } // TODO: inestigate this *ExitError type (command fails or // doesn't complete successfully), as it is happenning all // the time, but everyting seems to work fine. err = session.Wait() if err != nil { if _, ok := err.(*ssh.ExitError); !ok { return nil, err } } // read until the header of the second answer soBuf := bufio.NewReader(so) token := "0000" for { var line string line, err = soBuf.ReadString('\n') if err == io.EOF { return nil, ErrUploadPackAnswerFormat } if line[0:len(token)] == token { break } } data, err := ioutil.ReadAll(soBuf) if err != nil { return nil, err } buf := bytes.NewBuffer(data) return ioutil.NopCloser(buf), nil }