TestHandleConnectLogsOpenAndClose drives a real HTTPS CONNECT tunnel through the proxy and asserts that: - "Forward-proxy CONNECT opened." fires when the tunnel is established; - "Forward-proxy CONNECT closed." fires once both legs finish, with the correct sent/recv byte counts. Without this, ever
(t *testing.T)
| 986 | proxy := newTestProxy(t) |
| 987 | |
| 988 | var gotAuth, gotDate string |
| 989 | _, originURL := newTestServer(t, func(w http.ResponseWriter, r *http.Request) { |
| 990 | gotAuth = r.Header.Get("Authorization") |
| 991 | gotDate = r.Header.Get("X-Amz-Date") |
| 992 | w.WriteHeader(http.StatusOK) |
| 993 | _, _ = w.Write([]byte("ok")) |
| 994 | }) |
| 995 | |
| 996 | h := http.Header{ |
| 997 | "Range": []string{"bytes=0-1"}, |
| 998 | "Authorization": []string{"AWS4-HMAC-SHA256 Credential=AKIATEST/20260101/us-east-1/s3/aws4_request, SignedHeaders=host, Signature=abcdef"}, |
| 999 | "X-Amz-Date": []string{"20260101T000000Z"}, |
| 1000 | "X-Amz-Content-Sha256": []string{"UNSIGNED-PAYLOAD"}, |
| 1001 | // Hop-by-hop header must NOT be forwarded. |
| 1002 | "Proxy-Connection": []string{"Keep-Alive"}, |
| 1003 | } |
| 1004 | rec := doForwardProxyRequest(proxy, "GET", originURL+"/bucket/signed", h) |
| 1005 | if rec.Code != http.StatusPartialContent { |
| 1006 | t.Fatalf("status = %d, want 206", rec.Code) |
| 1007 | } |
| 1008 | if !strings.Contains(gotAuth, "Signature=abcdef") { |
| 1009 | t.Errorf("origin Authorization = %q, want SigV4 preserved", gotAuth) |
| 1010 | } |
| 1011 | if gotDate != "20260101T000000Z" { |
| 1012 | t.Errorf("origin X-Amz-Date = %q, want 20260101T000000Z", gotDate) |
| 1013 | } |
| 1014 | } |
| 1015 | |
| 1016 | // Sanity check that Content-Length set via serveBody matches body length. |
| 1017 | func TestServeBodyContentLength(t *testing.T) { |
| 1018 | proxy := newTestProxy(t) |
| 1019 | payload := []byte("abcdef") |
| 1020 | _, originURL := newTestServer(t, func(w http.ResponseWriter, r *http.Request) { |
| 1021 | w.WriteHeader(http.StatusOK) |
| 1022 | _, _ = w.Write(payload) |
| 1023 | }) |
| 1024 | rec := doForwardProxyRequest(proxy, "GET", originURL+"/b/k", http.Header{"Range": []string{"bytes=0-5"}}) |
| 1025 | if rec.Header().Get("Content-Length") != fmt.Sprintf("%d", len(payload)) { |
| 1026 | t.Errorf("Content-Length = %q, want %d", rec.Header().Get("Content-Length"), len(payload)) |
| 1027 | } |
| 1028 | got, _ := io.ReadAll(rec.Body) |
| 1029 | if string(got) != string(payload) { |
| 1030 | t.Errorf("body = %q, want %q", got, payload) |
| 1031 | } |
| 1032 | } |
| 1033 | |
| 1034 | // TestForwardUncachedLogsSuccess locks in the invariant that a successful |
| 1035 | // PUT/POST through the forward-proxy path produces a log line. Pre-PR this |
| 1036 | // path was completely silent, leaving operators with no proxy-side |
| 1037 | // breadcrumb to correlate against a downstream client error. |
| 1038 | func TestForwardUncachedLogsSuccess(t *testing.T) { |
| 1039 | buf, restore := captureSlog(t) |
| 1040 | defer restore() |
| 1041 | |
| 1042 | proxy := newTestProxy(t) |
| 1043 | _, originURL := newTestServer(t, func(w http.ResponseWriter, r *http.Request) { |
| 1044 | w.WriteHeader(http.StatusOK) |
| 1045 | _, _ = w.Write([]byte("ack")) |
nothing calls this directly
no test coverage detected