diff --git a/quickwit.go b/quickwit.go index c86ffb9..4eb76de 100644 --- a/quickwit.go +++ b/quickwit.go @@ -447,7 +447,7 @@ func (c *Client) Search(ctx context.Context, query string, opt *SearchOpt) (*Sea return nil, err } - req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.endpoint+"/search", bytes.NewReader(reqBody)) + req, err := http.NewRequestWithContext(ctx, http.MethodPost, strings.TrimSuffix(c.endpoint, "/")+"/search", bytes.NewReader(reqBody)) if err != nil { return nil, err } diff --git a/quickwit_test.go b/quickwit_test.go index 99428ff..8fce6d8 100644 --- a/quickwit_test.go +++ b/quickwit_test.go @@ -2,6 +2,7 @@ package quickwit_test import ( "bytes" + "context" "encoding/json" "io" "net/http" @@ -179,3 +180,28 @@ func TestIngest_OversizeBatchPreservesOrder(t *testing.T) { } } } + +// Regression: Search did not strip a trailing slash from the endpoint before appending +// "/search", producing a double-slash URL that many servers/proxies reject. +func TestSearch_TrailingSlashEndpoint(t *testing.T) { + var capturedPath string + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + capturedPath = r.URL.Path + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write([]byte(`{"hits":[],"num_hits":0,"elapsed_time_micros":1}`)) + })) + defer server.Close() + + // Intentionally add trailing slash to endpoint + c := quickwit.NewClient(server.URL + "/api/v1/test/") + ctx := context.Background() + c.Search(ctx, "*", nil) + + if strings.Contains(capturedPath, "//") { + t.Errorf("Search URL contains double slash: %s", capturedPath) + } + if !strings.HasSuffix(capturedPath, "/search") { + t.Errorf("Search URL does not end with /search: %s", capturedPath) + } +}