2020-12-02 10:09:37 -05:00
|
|
|
package git
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"net/http"
|
|
|
|
|
2021-06-08 11:10:00 -04:00
|
|
|
"gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"
|
2020-12-02 10:09:37 -05:00
|
|
|
|
2022-05-18 05:07:58 -04:00
|
|
|
"gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
|
2021-07-21 11:08:52 -04:00
|
|
|
"gitlab.com/gitlab-org/gitlab/workhorse/internal/gitaly"
|
|
|
|
"gitlab.com/gitlab-org/gitlab/workhorse/internal/helper"
|
|
|
|
"gitlab.com/gitlab-org/gitlab/workhorse/internal/log"
|
|
|
|
"gitlab.com/gitlab-org/gitlab/workhorse/internal/senddata"
|
2020-12-02 10:09:37 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
type snapshot struct {
|
|
|
|
senddata.Prefix
|
|
|
|
}
|
|
|
|
|
|
|
|
type snapshotParams struct {
|
2022-05-18 05:07:58 -04:00
|
|
|
GitalyServer api.GitalyServer
|
2020-12-02 10:09:37 -05:00
|
|
|
GetSnapshotRequest string
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
SendSnapshot = &snapshot{"git-snapshot:"}
|
|
|
|
)
|
|
|
|
|
|
|
|
func (s *snapshot) Inject(w http.ResponseWriter, r *http.Request, sendData string) {
|
|
|
|
var params snapshotParams
|
|
|
|
|
|
|
|
if err := s.Unpack(¶ms, sendData); err != nil {
|
|
|
|
helper.Fail500(w, r, fmt.Errorf("SendSnapshot: unpack sendData: %v", err))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
request := &gitalypb.GetSnapshotRequest{}
|
|
|
|
if err := gitaly.UnmarshalJSON(params.GetSnapshotRequest, request); err != nil {
|
|
|
|
helper.Fail500(w, r, fmt.Errorf("SendSnapshot: unmarshal GetSnapshotRequest: %v", err))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-05-18 05:07:58 -04:00
|
|
|
ctx, c, err := gitaly.NewRepositoryClient(
|
|
|
|
r.Context(),
|
|
|
|
params.GitalyServer,
|
|
|
|
gitaly.WithFeatures(params.GitalyServer.Features),
|
|
|
|
)
|
|
|
|
|
2020-12-02 10:09:37 -05:00
|
|
|
if err != nil {
|
|
|
|
helper.Fail500(w, r, fmt.Errorf("SendSnapshot: gitaly.NewRepositoryClient: %v", err))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
reader, err := c.SnapshotReader(ctx, request)
|
|
|
|
if err != nil {
|
|
|
|
helper.Fail500(w, r, fmt.Errorf("SendSnapshot: client.SnapshotReader: %v", err))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
w.Header().Del("Content-Length")
|
|
|
|
w.Header().Set("Content-Disposition", `attachment; filename="snapshot.tar"`)
|
|
|
|
w.Header().Set("Content-Type", "application/x-tar")
|
|
|
|
w.Header().Set("Content-Transfer-Encoding", "binary")
|
|
|
|
w.Header().Set("Cache-Control", "private")
|
|
|
|
w.WriteHeader(http.StatusOK) // Errors aren't detectable beyond this point
|
|
|
|
|
|
|
|
if _, err := io.Copy(w, reader); err != nil {
|
2021-01-11 10:10:32 -05:00
|
|
|
log.WithRequest(r).WithError(fmt.Errorf("SendSnapshot: copy gitaly output: %v", err)).Error()
|
2020-12-02 10:09:37 -05:00
|
|
|
}
|
|
|
|
}
|