InfoGrab DocsInfoGrab Docs

Geo 프록시

요약

보조 사이트는 거의 모든 HTTP 요청을 Workhorse를 통해 기본 사이트로 프록시하므로, 보조 사이트에 접속한 사용자에게는 읽기-쓰기 UI가 표시되며 기본 사이트에서 수행할 수 있는 모든 작업을 수행할 수 있습니다.

보조 사이트는 거의 모든 HTTP 요청을 Workhorse를 통해 기본 사이트로 프록시하므로, 보조 사이트에 접속한 사용자에게는 읽기-쓰기 UI가 표시되며 기본 사이트에서 수행할 수 있는 모든 작업을 수행할 수 있습니다.

고수준 구성 요소#

GitLab UI 및 API HTTP 요청의 프록시 처리는 gitlab-workhorse 구성 요소가 담당합니다. Geo 보조 사이트의 Rails 애플리케이션으로 전송되는 트래픽은 기본 Geo 사이트의 내부 URL로 프록시됩니다.

HTTP를 통한 Git 요청의 프록시 처리는 gitlab-workhorse 구성 요소가 담당하지만, 프록시 여부에 대한 결정은 Rails 애플리케이션이 처리합니다. Rails는 요청이 push인지 pull인지, 그리고 원하는 Git 데이터가 최신 상태인지를 고려하여 결정합니다.

SSH를 통한 Git 트래픽의 프록시 처리는 gitlab-shell 구성 요소가 담당하지만, 프록시 여부에 대한 결정은 Rails 애플리케이션이 처리합니다. Rails는 요청이 push인지 pull인지, 그리고 원하는 Git 데이터가 최신 상태인지를 고려하여 결정합니다.

요청 라이프사이클#

최상위 수준 개요#

프록시 상호 작용은 다음 다이어그램을 통해 높은 수준에서 설명할 수 있습니다:

sequenceDiagram actor client participant secondary participant primary

client->>secondary: GET /explore secondary-->>primary: GET /explore (proxied) primary-->>secondary: HTTP/1.1 200 OK [..] secondary->>client: HTTP/1.1 200 OK [..]

프록시 감지 메커니즘#

Geo가 활성화된 경우, Workhorse는 기본 사이트로 요청을 프록시해야 하는지 여부와 기본 사이트의 URL(데이터베이스에 저장됨)을 알기 위해 내부 API를 주기적으로 폴링합니다. 프록시가 활성화되어야 하는 경우, 내부 API는 기본 사이트 URL과 JWT 서명된 데이터를 응답합니다. 이 데이터는 모든 요청에서 기본 사이트로 전달됩니다.

sequenceDiagram participant W as Workhorse (secondary) participant API as Internal Rails API W->API: GET /api/v4/geo/proxy (internal) loop Poll every 10 seconds API-->W: {geo_proxy_primary_url, geo_proxy_extra_data}, update config end

심층 요청 흐름 및 프록시와 로컬 데이터 가속 비교#

구현을 자세히 살펴보면, 보조(요청) 사이트의 Workhorse가 데이터를 프록시할지 여부를 결정합니다. 데이터 유형을 "가속"할 수 있는 경우(즉, 왕복 요청을 절약하기 위해 로컬에서 제공할 수 있는 경우) 데이터를 즉시 반환합니다. 그렇지 않으면 트래픽은 기본 사이트의 내부 URL로 전송되고, 기본 사이트의 Workhorse가 직접 요청과 동일하게 처리합니다. 응답은 동일한 연결에서 보조 Workhorse를 통해 사용자에게 다시 프록시됩니다.

flowchart LR A[Client]--->W1["Workhorse (secondary)"] W1 --> W1C[Serve data locally?] W1C -- "Yes" ----> W1 W1C -- "No (proxy)" ----> W2["Workhorse (primary)"] W2 --> W1 ----> A

로그인#

인증이 필요한 기본 사이트로 프록시되는 요청#

sequenceDiagram autoNumber participant Client participant Secondary participant Primary

Client->>Secondary: /group/project request Secondary->>Primary: proxy /group/project opt primary not signed in Primary-->>Secondary: 302 redirect Secondary-->>Client: proxy 302 redirect Client->>Secondary: /users/sign_in Secondary->>Primary: proxy /users/sign_in Note right of Primary: authentication happens, POST to same URL etc Primary-->>Secondary: 302 redirect Secondary-->>Client: proxy 302 redirect Client->>Secondary: /group/project Secondary->>Primary: proxy /group/project end Primary-->>Secondary: /group/project logged in response (session on primary created) Secondary-->>Client: proxy full response

Git pull#

Git pull 포워드 경로는 GitLab 17.10에서 더 명확한 이름을 위해 레거시 이름 push_from_secondary에서 from_secondary로 변경되었습니다.

HTTP(S)를 통한 Git pull#

가속 리포지터리#

리포지터리가 보조 사이트에 존재하고 기본 사이트와 최신 상태임을 감지하면, 프록시 대신 직접 제공합니다.

sequenceDiagram participant C as Git client participant Wsec as "Workhorse (secondary)" participant Rsec as "Rails (secondary)" participant Gsec as "Gitaly (secondary)" C->>Wsec: GET /foo/bar.git/info/refs/?service=git-upload-pack Wsec->>Rsec: note over Rsec: decide that the repo is synced and up to date Rsec-->>Wsec: 401 Unauthorized Wsec-->>C: C->>Wsec: GET /foo/bar.git/info/refs/?service=git-upload-pack Wsec->>Rsec: Rsec-->>Wsec: Render Workhorse OK Wsec-->>C: 200 OK C->>Wsec: POST /foo/bar.git/git-upload-pack Wsec->>Rsec: GitHttpController#git_receive_pack Rsec-->>Wsec: Render Workhorse OK Wsec->>Gsec: Workhorse gets the connection details from Rails, connects to Gitaly: SmartHTTP Service, UploadPack RPC (check the proto for details) Gsec-->>Wsec: Return a stream of Proto messages Wsec-->>C: Pipe messages to the Git client

프록시 리포지터리#

요청된 리포지터리가 동기화되지 않았거나 최신 상태가 아님을 감지한 경우, 최신 변경 사항을 가져오기 위해 요청이 기본 사이트로 프록시됩니다.

sequenceDiagram participant C as Git client participant Wsec as "Workhorse (secondary)" participant Rsec as "Rails (secondary)" participant W as "Workhorse (primary)" participant R as "Rails (primary)" participant G as "Gitaly (primary)" C->>Wsec: GET /foo/bar.git/info/refs/?service=git-upload-pack Wsec->>Rsec: note over Rsec: decide that the repo is out of date Rsec-->>Wsec: 302 Redirect to /-/from_secondary/2/foo/bar.git/info/refs?service=git-upload-pack Wsec-->>C: C->>Wsec: GET /-/from_secondary/2/foo/bar.git/info/refs/?service=git-upload-pack Wsec->>W: W->>R: R-->>W: 401 Unauthorized W-->>Wsec: Wsec-->>C: C->>Wsec: GET /-/from_secondary/2/foo/bar.git/info/refs/?service=git-upload-pack note over W: proxied Wsec->>W: W->>R: R-->>W: Render Workhorse OK W-->>Wsec: Wsec-->>C: C->>Wsec: POST /-/from_secondary/2/foo/bar.git/git-upload-pack Wsec->>W: W->>R: GitHttpController#git_receive_pack R-->>W: Render Workhorse OK W->>G: Workhorse gets the connection details from Rails, connects to Gitaly: SmartHTTP Service, UploadPack RPC (check the proto for details) G-->>W: Return a stream of Proto messages W-->>Wsec: Pipe messages to the Git client Wsec-->>C: Return piped messages from Git

SSH를 통한 Git pull#

SSH 작업은 Workhorse 대신 GitLab Shell을 통해 이루어지므로, Workhorse 요청에 사용되는 메커니즘을 통해 프록시되지 않습니다. SSH 작업의 경우, 보조 사이트 Rails 내부 API에 의해 기본 사이트로의 Git HTTP 요청으로 프록시됩니다.

가속 리포지터리#

리포지터리가 보조 사이트에 존재하고 기본 사이트와 최신 상태임을 감지하면, 프록시 대신 직접 제공합니다.

sequenceDiagram participant C as Git client participant S as GitLab Shell (secondary) participant I as Internal API (secondary Rails) participant G as Gitaly (secondary) C->>S: git pull S->>I: SSH key validation (api/v4/internal/authorized_keys?key=..) I-->>S: HTTP/1.1 200 OK S->>G: InfoRefs:UploadPack RPC G-->>S: stream Git response back S-->>C: stream Git response back C-->>S: stream Git data to push S->>G: UploadPack RPC G-->>S: stream Git response back S-->>C: stream Git response back

프록시 리포지터리#

요청된 리포지터리가 동기화되지 않았거나 최신 상태가 아님을 감지한 경우, 최신 변경 사항을 가져오기 위해 요청이 기본 사이트로 프록시됩니다.

sequenceDiagram participant C as Git client participant S as GitLab Shell (secondary) participant I as Internal API (secondary Rails) participant P as Primary API C->>S: git pull S->>I: SSH key validation (api/v4/internal/authorized_keys?key=..) I-->>S: HTTP/1.1 300 (custom action status) with {endpoint, msg, primary_repo} S->>I: POST /api/v4/geo/proxy_git_ssh/info_refs_upload_pack I->>P: POST $PRIMARY/foo/bar.git/info/refs/?service=git-upload-pack P-->>I: HTTP/1.1 200 OK I-->>S: S-->>C: return Git response from primary C-->>S: stream Git data to push S->>I: POST /api/v4/geo/proxy_git_ssh/upload_pack I->>P: POST $PRIMARY/foo/bar.git/git-upload-pack P-->>I: HTTP/1.1 200 OK I-->>S: S-->>C: return Git response from primary

Git push#

SSH를 통한 Git push#

SSH 작업은 Workhorse 대신 GitLab Shell을 통해 이루어지므로, Workhorse 요청에 사용되는 메커니즘을 통해 프록시되지 않습니다. SSH 작업의 경우, 보조 사이트 Rails 내부 API에 의해 기본 사이트로의 Git HTTP 요청으로 프록시됩니다.

sequenceDiagram participant C as Git client participant S as GitLab Shell (secondary) participant I as Internal API (secondary Rails) participant P as Primary API C->>S: git push S->>I: SSH key validation (api/v4/internal/authorized_keys?key=..) I-->>S: HTTP/1.1 300 (custom action status) with {endpoint, msg, primary_repo} S->>I: POST /api/v4/geo/proxy_git_ssh/info_refs_receive_pack I->>P: POST $PRIMARY/foo/bar.git/info/refs/?service=git-receive-pack P-->>I: HTTP/1.1 200 OK I-->>S: S-->>C: return Git response from primary C-->>S: stream Git data to push S->>I: POST /api/v4/geo/proxy_git_ssh/receive_pack I->>P: POST $PRIMARY/foo/bar.git/git-receive-pack P-->>I: HTTP/1.1 200 OK I-->>S: S-->>C: return Git response from primary

HTTP(S)를 통한 Git push#

요청된 리포지터리가 동기화되지 않았거나 최신 상태가 아님을 감지한 경우, 요청이 기본 사이트로 프록시되며, push는 /-/from_secondary/$SECONDARY_ID/* 형식의 로컬 경로로 리다이렉트됩니다. 이 경로를 통한 추가 요청은 기본 사이트로 프록시되어 push를 처리합니다.

sequenceDiagram participant C as Git client participant Wsec as Workhorse (secondary) participant W as Workhorse (primary) participant R as Rails (primary) participant G as Gitaly (primary) C->>Wsec: GET /foo/bar.git/info/refs/?service=git-receive-pack Wsec->>C: 302 Redirect to /-/from_secondary/2/foo/bar.git/info/refs?service=git-receive-pack C->>Wsec: GET /-/from_secondary/2/foo/bar.git/info/refs/?service=git-receive-pack Wsec->>W: W->>R: R-->>W: 401 Unauthorized W-->>Wsec: Wsec-->>C: C->>Wsec: GET /-/from_secondary/2/foo/bar.git/info/refs/?service=git-receive-pack Wsec->>W: W->>R: R-->>W: Render Workhorse OK W-->>Wsec: Wsec-->>C: C->>Wsec: POST /-/from_secondary/2/foo/bar.git/git-receive-pack Wsec->>W: W->>R: GitHttpController:git_receive_pack R-->>W: Render Workhorse OK W->>G: Get connection details from Rails and connects to SmartHTTP Service, ReceivePack RPC G-->>W: Return a stream of Proto messages W-->>Wsec: Pipe messages to the Git client Wsec-->>C: Return piped messages from Git

Geo 프록시

GitLab v19.1
원문 보기
요약

보조 사이트는 거의 모든 HTTP 요청을 Workhorse를 통해 기본 사이트로 프록시하므로, 보조 사이트에 접속한 사용자에게는 읽기-쓰기 UI가 표시되며 기본 사이트에서 수행할 수 있는 모든 작업을 수행할 수 있습니다.

보조 사이트는 거의 모든 HTTP 요청을 Workhorse를 통해 기본 사이트로 프록시하므로, 보조 사이트에 접속한 사용자에게는 읽기-쓰기 UI가 표시되며 기본 사이트에서 수행할 수 있는 모든 작업을 수행할 수 있습니다.

고수준 구성 요소#

GitLab UI 및 API HTTP 요청의 프록시 처리는 gitlab-workhorse 구성 요소가 담당합니다. Geo 보조 사이트의 Rails 애플리케이션으로 전송되는 트래픽은 기본 Geo 사이트의 내부 URL로 프록시됩니다.

HTTP를 통한 Git 요청의 프록시 처리는 gitlab-workhorse 구성 요소가 담당하지만, 프록시 여부에 대한 결정은 Rails 애플리케이션이 처리합니다. Rails는 요청이 push인지 pull인지, 그리고 원하는 Git 데이터가 최신 상태인지를 고려하여 결정합니다.

SSH를 통한 Git 트래픽의 프록시 처리는 gitlab-shell 구성 요소가 담당하지만, 프록시 여부에 대한 결정은 Rails 애플리케이션이 처리합니다. Rails는 요청이 push인지 pull인지, 그리고 원하는 Git 데이터가 최신 상태인지를 고려하여 결정합니다.

요청 라이프사이클#

최상위 수준 개요#

프록시 상호 작용은 다음 다이어그램을 통해 높은 수준에서 설명할 수 있습니다:

sequenceDiagram actor client participant secondary participant primary

client->>secondary: GET /explore secondary-->>primary: GET /explore (proxied) primary-->>secondary: HTTP/1.1 200 OK [..] secondary->>client: HTTP/1.1 200 OK [..]

프록시 감지 메커니즘#

Geo가 활성화된 경우, Workhorse는 기본 사이트로 요청을 프록시해야 하는지 여부와 기본 사이트의 URL(데이터베이스에 저장됨)을 알기 위해 내부 API를 주기적으로 폴링합니다. 프록시가 활성화되어야 하는 경우, 내부 API는 기본 사이트 URL과 JWT 서명된 데이터를 응답합니다. 이 데이터는 모든 요청에서 기본 사이트로 전달됩니다.

sequenceDiagram participant W as Workhorse (secondary) participant API as Internal Rails API W->API: GET /api/v4/geo/proxy (internal) loop Poll every 10 seconds API-->W: {geo_proxy_primary_url, geo_proxy_extra_data}, update config end

심층 요청 흐름 및 프록시와 로컬 데이터 가속 비교#

구현을 자세히 살펴보면, 보조(요청) 사이트의 Workhorse가 데이터를 프록시할지 여부를 결정합니다. 데이터 유형을 "가속"할 수 있는 경우(즉, 왕복 요청을 절약하기 위해 로컬에서 제공할 수 있는 경우) 데이터를 즉시 반환합니다. 그렇지 않으면 트래픽은 기본 사이트의 내부 URL로 전송되고, 기본 사이트의 Workhorse가 직접 요청과 동일하게 처리합니다. 응답은 동일한 연결에서 보조 Workhorse를 통해 사용자에게 다시 프록시됩니다.

flowchart LR A[Client]--->W1["Workhorse (secondary)"] W1 --> W1C[Serve data locally?] W1C -- "Yes" ----> W1 W1C -- "No (proxy)" ----> W2["Workhorse (primary)"] W2 --> W1 ----> A

로그인#

인증이 필요한 기본 사이트로 프록시되는 요청#

sequenceDiagram autoNumber participant Client participant Secondary participant Primary

Client->>Secondary: /group/project request Secondary->>Primary: proxy /group/project opt primary not signed in Primary-->>Secondary: 302 redirect Secondary-->>Client: proxy 302 redirect Client->>Secondary: /users/sign_in Secondary->>Primary: proxy /users/sign_in Note right of Primary: authentication happens, POST to same URL etc Primary-->>Secondary: 302 redirect Secondary-->>Client: proxy 302 redirect Client->>Secondary: /group/project Secondary->>Primary: proxy /group/project end Primary-->>Secondary: /group/project logged in response (session on primary created) Secondary-->>Client: proxy full response

Git pull#

Git pull 포워드 경로는 GitLab 17.10에서 더 명확한 이름을 위해 레거시 이름 push_from_secondary에서 from_secondary로 변경되었습니다.

HTTP(S)를 통한 Git pull#

가속 리포지터리#

리포지터리가 보조 사이트에 존재하고 기본 사이트와 최신 상태임을 감지하면, 프록시 대신 직접 제공합니다.

sequenceDiagram participant C as Git client participant Wsec as "Workhorse (secondary)" participant Rsec as "Rails (secondary)" participant Gsec as "Gitaly (secondary)" C->>Wsec: GET /foo/bar.git/info/refs/?service=git-upload-pack Wsec->>Rsec: note over Rsec: decide that the repo is synced and up to date Rsec-->>Wsec: 401 Unauthorized Wsec-->>C: C->>Wsec: GET /foo/bar.git/info/refs/?service=git-upload-pack Wsec->>Rsec: Rsec-->>Wsec: Render Workhorse OK Wsec-->>C: 200 OK C->>Wsec: POST /foo/bar.git/git-upload-pack Wsec->>Rsec: GitHttpController#git_receive_pack Rsec-->>Wsec: Render Workhorse OK Wsec->>Gsec: Workhorse gets the connection details from Rails, connects to Gitaly: SmartHTTP Service, UploadPack RPC (check the proto for details) Gsec-->>Wsec: Return a stream of Proto messages Wsec-->>C: Pipe messages to the Git client

프록시 리포지터리#

요청된 리포지터리가 동기화되지 않았거나 최신 상태가 아님을 감지한 경우, 최신 변경 사항을 가져오기 위해 요청이 기본 사이트로 프록시됩니다.

sequenceDiagram participant C as Git client participant Wsec as "Workhorse (secondary)" participant Rsec as "Rails (secondary)" participant W as "Workhorse (primary)" participant R as "Rails (primary)" participant G as "Gitaly (primary)" C->>Wsec: GET /foo/bar.git/info/refs/?service=git-upload-pack Wsec->>Rsec: note over Rsec: decide that the repo is out of date Rsec-->>Wsec: 302 Redirect to /-/from_secondary/2/foo/bar.git/info/refs?service=git-upload-pack Wsec-->>C: C->>Wsec: GET /-/from_secondary/2/foo/bar.git/info/refs/?service=git-upload-pack Wsec->>W: W->>R: R-->>W: 401 Unauthorized W-->>Wsec: Wsec-->>C: C->>Wsec: GET /-/from_secondary/2/foo/bar.git/info/refs/?service=git-upload-pack note over W: proxied Wsec->>W: W->>R: R-->>W: Render Workhorse OK W-->>Wsec: Wsec-->>C: C->>Wsec: POST /-/from_secondary/2/foo/bar.git/git-upload-pack Wsec->>W: W->>R: GitHttpController#git_receive_pack R-->>W: Render Workhorse OK W->>G: Workhorse gets the connection details from Rails, connects to Gitaly: SmartHTTP Service, UploadPack RPC (check the proto for details) G-->>W: Return a stream of Proto messages W-->>Wsec: Pipe messages to the Git client Wsec-->>C: Return piped messages from Git

SSH를 통한 Git pull#

SSH 작업은 Workhorse 대신 GitLab Shell을 통해 이루어지므로, Workhorse 요청에 사용되는 메커니즘을 통해 프록시되지 않습니다. SSH 작업의 경우, 보조 사이트 Rails 내부 API에 의해 기본 사이트로의 Git HTTP 요청으로 프록시됩니다.

가속 리포지터리#

리포지터리가 보조 사이트에 존재하고 기본 사이트와 최신 상태임을 감지하면, 프록시 대신 직접 제공합니다.

sequenceDiagram participant C as Git client participant S as GitLab Shell (secondary) participant I as Internal API (secondary Rails) participant G as Gitaly (secondary) C->>S: git pull S->>I: SSH key validation (api/v4/internal/authorized_keys?key=..) I-->>S: HTTP/1.1 200 OK S->>G: InfoRefs:UploadPack RPC G-->>S: stream Git response back S-->>C: stream Git response back C-->>S: stream Git data to push S->>G: UploadPack RPC G-->>S: stream Git response back S-->>C: stream Git response back

프록시 리포지터리#

요청된 리포지터리가 동기화되지 않았거나 최신 상태가 아님을 감지한 경우, 최신 변경 사항을 가져오기 위해 요청이 기본 사이트로 프록시됩니다.

sequenceDiagram participant C as Git client participant S as GitLab Shell (secondary) participant I as Internal API (secondary Rails) participant P as Primary API C->>S: git pull S->>I: SSH key validation (api/v4/internal/authorized_keys?key=..) I-->>S: HTTP/1.1 300 (custom action status) with {endpoint, msg, primary_repo} S->>I: POST /api/v4/geo/proxy_git_ssh/info_refs_upload_pack I->>P: POST $PRIMARY/foo/bar.git/info/refs/?service=git-upload-pack P-->>I: HTTP/1.1 200 OK I-->>S: S-->>C: return Git response from primary C-->>S: stream Git data to push S->>I: POST /api/v4/geo/proxy_git_ssh/upload_pack I->>P: POST $PRIMARY/foo/bar.git/git-upload-pack P-->>I: HTTP/1.1 200 OK I-->>S: S-->>C: return Git response from primary

Git push#

SSH를 통한 Git push#

SSH 작업은 Workhorse 대신 GitLab Shell을 통해 이루어지므로, Workhorse 요청에 사용되는 메커니즘을 통해 프록시되지 않습니다. SSH 작업의 경우, 보조 사이트 Rails 내부 API에 의해 기본 사이트로의 Git HTTP 요청으로 프록시됩니다.

sequenceDiagram participant C as Git client participant S as GitLab Shell (secondary) participant I as Internal API (secondary Rails) participant P as Primary API C->>S: git push S->>I: SSH key validation (api/v4/internal/authorized_keys?key=..) I-->>S: HTTP/1.1 300 (custom action status) with {endpoint, msg, primary_repo} S->>I: POST /api/v4/geo/proxy_git_ssh/info_refs_receive_pack I->>P: POST $PRIMARY/foo/bar.git/info/refs/?service=git-receive-pack P-->>I: HTTP/1.1 200 OK I-->>S: S-->>C: return Git response from primary C-->>S: stream Git data to push S->>I: POST /api/v4/geo/proxy_git_ssh/receive_pack I->>P: POST $PRIMARY/foo/bar.git/git-receive-pack P-->>I: HTTP/1.1 200 OK I-->>S: S-->>C: return Git response from primary

HTTP(S)를 통한 Git push#

요청된 리포지터리가 동기화되지 않았거나 최신 상태가 아님을 감지한 경우, 요청이 기본 사이트로 프록시되며, push는 /-/from_secondary/$SECONDARY_ID/* 형식의 로컬 경로로 리다이렉트됩니다. 이 경로를 통한 추가 요청은 기본 사이트로 프록시되어 push를 처리합니다.

sequenceDiagram participant C as Git client participant Wsec as Workhorse (secondary) participant W as Workhorse (primary) participant R as Rails (primary) participant G as Gitaly (primary) C->>Wsec: GET /foo/bar.git/info/refs/?service=git-receive-pack Wsec->>C: 302 Redirect to /-/from_secondary/2/foo/bar.git/info/refs?service=git-receive-pack C->>Wsec: GET /-/from_secondary/2/foo/bar.git/info/refs/?service=git-receive-pack Wsec->>W: W->>R: R-->>W: 401 Unauthorized W-->>Wsec: Wsec-->>C: C->>Wsec: GET /-/from_secondary/2/foo/bar.git/info/refs/?service=git-receive-pack Wsec->>W: W->>R: R-->>W: Render Workhorse OK W-->>Wsec: Wsec-->>C: C->>Wsec: POST /-/from_secondary/2/foo/bar.git/git-receive-pack Wsec->>W: W->>R: GitHttpController:git_receive_pack R-->>W: Render Workhorse OK W->>G: Get connection details from Rails and connects to SmartHTTP Service, ReceivePack RPC G-->>W: Return a stream of Proto messages W-->>Wsec: Pipe messages to the Git client Wsec-->>C: Return piped messages from Git