Jippe Holwerda
04/01/2021, 7:19 PMSinglePageAppRoutingHandler
and ServerFilters.Cors
filter do not play nice together. The CORS OPTION request is being handled by SinglePageAppRoutingHandler
. Since it doesn't match a resource, the fallbackHandler
is used with a new GET request (without headers). When that request is handled by the Cors filter, the Origin header is missing causing the request to fail...s4nchez
04/01/2021, 8:36 PMHttpHandler
so the .then
function won't execute the filter (in this case Cors) after the routing matching attempt.
Let me see how it goes. If it doesn't help, please provide an example and I'll try to help troubleshooting.Jippe Holwerda
04/02/2021, 7:20 AMHttpHandler
and wrapping it in routes
worked.fun router(): (AppContext) -> HttpHandler =
{ context ->
allRoutesFilter(context).then(
routes(
"/auth".let { path ->
AuthenticationApi.routes()(context.copy(env = context.env.with(Config.authBasePath of path))).withBasePath(path)
},
internalApiFilter(context).then(
routes(
"/aandachtspunten" bind AandachtspuntenApi.routes()(context),
"/beheer" bind BeheerApi.routes()(context),
"/stamdata" bind StamdataApi.routes()(context),
"/gebruiker" bind GebruikerApi.routes()(context),
"/medewerkers" bind MedewerkerApi.routes()(context),
"/milieubelastende-activiteiten" bind MilieubelastendeActiviteitApi.routes()(context),
"/milieubelastende-activiteit-types" bind MilieubelastendeActiviteitTypeApi.routes()(context),
"/overheidsorganisaties" bind OverheidsOrganisatieApi.routes()(context),
"/rechtspersonen" bind RechtspersoonApi.routes()(context),
"/roles" bind RolesApi.routes()(context),
"/kvk" bind KvkApi.routes()(context),
"/bag" bind BagApi.routes()(context),
"/zaaktype" bind ZaaktypeApi.routes()(context),
"/zaken" bind ZaakApi.routes()(context),
"/ztc" bind ZtcApi.routes()(context)
).withBasePath("/internal-api")
),
routes(
"/config" bind ConfigApi.routes(context.env)
).withBasePath("/public-api"),
"/static" bind static(Classpath("/static"))
.withFilter(ResponseFilters.EtagSupport()),
MockAuthenticateApi.routes(context.env).withBasePath("__authenticate"),
routes(
Method.GET to (singlePageApp(extraFileExtensionToContentTypes = ContentTypes.staticContentTypes)
.withFilter(Filters.VueResourceCaching())
.withFilter(ResponseFilters.GZip()) as HttpHandler)
),
)
)
}
fun allRoutesFilter(context: AppContext): Filter =
ServerFilters.InitialiseRequestContext(contexts)
.let {
requestSlowdownInMs(context.env).let { time -> if (time > 0) it.then(Filters.SlowDownFilter(time)) else it }
}
.then(Filters.Cors(context))
.then(Filters.SecurityHeaders(contentSecurityPolicy(context.env)))
.then(Filters.UniqueRequestReference())
.then(Filters.ReportTransactionAndError { event -> events(event) })
.then(ErrorHandling.CatchAll(context.env))
.then(storeAuth(context.env, context.httpClient))
fun internalApiFilter(context: AppContext): Filter =
DebuggingFilters.PrintRequestAndResponse()
.then(Authentication.authenticated)
.then(DatabaseFactory.inTransaction(context.jooqConfiguration, context.datasource))
.then(ErrorHandling.CatchLensFailure(context.env))
.then(Authorization.storeGebruiker()(context.gebruikerRepository))
.then(Authorization.storePermissies()(context.gebruikerRepository))
.then(MedewerkerFilter.storeMedewerker()(context.medewerkerRepository))
routes(
Method.GET to (singlePageApp(extraFileExtensionToContentTypes = ContentTypes.staticContentTypes)
.withFilter(Filters.VueResourceCaching())
.withFilter(ResponseFilters.GZip()) as HttpHandler)
),
s4nchez
04/02/2021, 7:36 AMJippe Holwerda
04/06/2021, 11:33 AM<http://Pathmethod.to|Pathmethod.to>
the SinglePageAppRouteHandler
is wrapped in a TemplateRouter
which doesn't match the request spa resources4nchez
04/06/2021, 12:20 PMMethod.GET to
part? you should be able to just combine routinghandlers if my memory servesJippe Holwerda
04/06/2021, 12:23 PMs4nchez
04/06/2021, 12:28 PMJippe Holwerda
04/06/2021, 12:36 PMs4nchez
04/06/2021, 12:45 PMJippe Holwerda
04/06/2021, 12:49 PMs4nchez
04/06/2021, 2:07 PMJippe Holwerda
04/09/2021, 9:20 AMs4nchez
04/09/2021, 9:21 AMdave
04/10/2021, 9:11 AMMatched (without verb)
MatchedWithoutHandler (this is used internally)
MethodNotMatched
Unmatched
An example of AND is matching a path AND a verb ( "/" bind GET to {}
)
An example of OR is matching routes("/api" bind ... , singlePageApp()
) <-- what we have here.
The problem is that the "/api" router returns a MethodNotMatched, and the SPA is greedy and will return the default index page for all requests (including OPTIONS).
On the following branch, I have stopped SPAs from accepting OPTIONS requests, which seems to fix the problem:
https://github.com/http4k/http4k/pull/605Jippe Holwerda
04/11/2021, 8:25 AMdave
04/11/2021, 8:27 AMJippe Holwerda
04/11/2021, 8:32 AM