package handlers import ( "net/http" "net/netip" "path/filepath" "testing" "time" "github.com/go-chi/chi/v5" "go.uber.org/fx" "go.uber.org/fx/fxtest" "sneak.berlin/go/pixa/internal/config" "sneak.berlin/go/pixa/internal/database" "sneak.berlin/go/pixa/internal/globals" "sneak.berlin/go/pixa/internal/healthcheck" "sneak.berlin/go/pixa/internal/logger" ) // TestHandlersBuildTheirOwnFetcherWhenNoneIsProvided builds the handlers as // pixad does, in an fx app that provides no fetcher, and requests an image // from 192.0.2.10, which is on the allowlist and in blocked_networks. The URL // check accepts that address; only the dialer that refuses internal // addresses checks blocked_networks, so the answer is 403 only if the // fetcher the handlers build from the config connects with that dialer. Any // other dialer would try to connect until the upstream fetch timeout, which // is short so that the test then fails quickly. func TestHandlersBuildTheirOwnFetcherWhenNoneIsProvided(t *testing.T) { t.Parallel() const host = "192.0.2.10" stateDir := t.TempDir() cfg := &config.Config{ SigningKey: testSigningKey, StateDir: stateDir, DBURL: "file:" + filepath.Join(stateDir, "state.sqlite3"), AllowlistHosts: []string{host}, BlockedNetworks: []netip.Prefix{netip.MustParsePrefix("192.0.2.0/24")}, UpstreamFetchTimeout: 2 * time.Second, // With no connection slots, the fetch would fail before dialing. UpstreamConnections: config.DefaultUpstreamConnections, } var h *Handlers app := fxtest.New(t, fx.Supply(cfg), fx.Provide(globals.New, logger.New, database.New, healthcheck.New, New), fx.Populate(&h), ) app.RequireStart() t.Cleanup(app.RequireStop) r := chi.NewRouter() r.Get("/v1/image/*", h.HandleImage()) rec := sendGet(t, r, photoURL(host)) checkErrorBody(t, rec, http.StatusForbidden, "forbidden") }