# Expose FollowInfoRefsRedirect through public gitsync API

`e658292`→[main](/content/gh/entireio/git-sync/commits/main/index.html)·  
  
nodo·2mo ago·6 files·+118 added/-8 removed

The flag was previously on gitproto.Conn but unreachable from normal gitsync callers — gitproto is an internal package, and neither syncer.Endpoint, internalbridge.Endpoint, nor pkg/gitsync.Endpoint carried it. This made the flag dead config for CLI and library users.

Wire it through the endpoint-shaped layers (pkg/gitsync.Endpoint → internalbridge.Endpoint → syncer.Endpoint → gitproto.Conn). Per- endpoint rather than whole-Config so source and target can opt in independently — mirror-worker only needs it on the target.

Adds two tests:

- An integration test at the gitproto level that runs the full info/refs → follow-up POST sequence against two httptest servers (entry that 307s, node that serves the pack) and asserts the POST lands on the node, not the entry. This is the property that makes the feature useful.
- A plumbing test at the syncer level proving newConn propagates the flag from Endpoint to Conn — guards against the exact regression the reviewer flagged.

## Changes

6

- internal
  
  - gitproto
  
    - Msmarthttp_test.go+66
  
  - syncer
  
    - Msyncer.go+9/-1
    - Msyncer_test.go+23

- pkg/gitsync
  
  - Mclient.go+4/-1
  
  - internalbridge
  
    - Mconfig.go+8/-6

- Mtypes.go+8

```
207 unmodified lines

210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279

207 unmodified lines

}
}

// TestRequestInfoRefs_FollowInfoRefsRedirect_SubsequentPOSTHitsRedirectedHost
// is the reviewer-requested integration test: it runs the full sequence
// (GET /info/refs → 307 → 200 on hosting node → POST /git-upload-pack) and
// asserts the POST lands on the hosting node, not the entry domain. This is
// the property that makes the flag useful — the whole point is that packs
// follow info/refs.
func TestRequestInfoRefs_FollowInfoRefsRedirect_SubsequentPOSTHitsRedirectedHost(t *testing.T) {
    var nodeGotPOST bool
    node := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        switch {
        case r.Method == http.MethodGet && strings.HasSuffix(r.URL.Path, "/info/refs"):
            w.Header().Set("Content-Type", "application/x-git-upload-pack-advertisement")
            if _, err := w.Write([]byte("001e# service=git-upload-pack\n0000")); err != nil {
                t.Errorf("node info/refs write: %v", err)
            }
        case r.Method == http.MethodPost && strings.HasSuffix(r.URL.Path, "/git-upload-pack"):
            nodeGotPOST = true
            w.Header().Set("Content-Type", "application/x-git-upload-pack-result")
            w.WriteHeader(http.StatusOK)
        default:
            t.Errorf("node: unexpected %s %s", r.Method, r.URL.Path)
        }
    }))
    defer node.Close()

var entryGotPOST bool
    entry := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        if r.Method == http.MethodPost {
            entryGotPOST = true
            http.Error(w, "LB rejects packs", http.StatusMethodNotAllowed)
            return
        }
        http.Redirect(w, r, node.URL+r.URL.Path+"?"+r.URL.RawQuery, http.StatusTemporaryRedirect)
    }))
    defer entry.Close()

ep, err := transport.NewEndpoint(entry.URL + "/repo.git")
    if err != nil {
        t.Fatalf("parse endpoint: %v", err)
    }
    conn := NewConn(ep, "test", nil, http.DefaultTransport)
    conn.FollowInfoRefsRedirect = true

if _, err := RequestInfoRefs(t.Context(), conn, transport.UploadPackService, ""); err != nil {
        t.Fatalf("RequestInfoRefs: %v", err)
    }

// Now do the follow-up upload-pack POST. Without the flag this hits the
    // entry domain (rejected with 405); with the flag it hits the node.
    body, err := PostRPC(t.Context(), conn, transport.UploadPackService, []byte("0000"), false, "upload-pack integration-test")
    if err != nil {
        t.Fatalf("PostRPC: %v", err)
    }
    if len(body) != 0 {
        // body shape is not what we're asserting; just demand it didn't fail
        _ = body
    }

if entryGotPOST {
        t.Error("POST hit the entry domain instead of the redirected node")
    }
    if !nodeGotPOST {
        t.Error("POST did not hit the redirected node")
    }
}

// TestRequestInfoRefs_DoesNotFollowByDefault confirms the default behaviour
// is unchanged: Endpoint is stable even if the server 307s.
func TestRequestInfoRefs_DoesNotFollowByDefault(t *testing.T) {
}
