Thank you for the workaround.
Without any registered appHost.CustomErrorHttpHandlers[HttpStatusCode.NotFound]
it works as expected:
curl -s -i https://localhost:5001/some/where | head -n 20
HTTP/1.1 404 Not Found
Date: Mon, 18 Oct 2021 08:55:48 GMT
Server: Kestrel
Content-Length: 0
With the default handler (in the template from ServiceStack), the response code is changed incorrectly. So
appHost.CustomErrorHttpHandlers[HttpStatusCode.NotFound] = new SharpPageHandler("/notfound");
gives
curl -s -i https://localhost:5001/some/where | head -n 20
HTTP/1.1 200 OK
Date: Mon, 18 Oct 2021 08:54:42 GMT
Content-Type: text/html
Server: Kestrel
Transfer-Encoding: chunked
<!DOCTYPE HTML>
<html>
<head>
<title>Page Not Found</title>
When using your workaround
appHost.CustomErrorHttpHandlers[HttpStatusCode.NotFound] =
new SharpPageHandler("/notfound")
{
ValidateFn = req =>
{
req.Response.StatusCode = 404;
return true;
}
};
It works the way it should
curl -s -i https://localhost:5001/some/where | head -n 20
HTTP/1.1 404 Not Found
Date: Mon, 18 Oct 2021 08:51:45 GMT
Content-Type: text/html
Server: Kestrel
Transfer-Encoding: chunked
<!DOCTYPE HTML>
<html>
<head>
<title>Page Not Found</title>
So the SharpPageHandler
overrides the response code it is registered for, and changes the 404
into 200
, and that is both wrong and surprising.
I think that either the examples should be updated to add your workaround, or that the SharpPageHandler
should receive the original http response code, and preserve it.
On that note, the same is the case for the appHost.CustomErrorHttpHandlers[HttpStatusCode.Forbidden] = new SharpPageHandler("/forbidden");
.
It should return a 403
response code for html as well as the API, but it returns a 200
instead:
curl -s -i https://localhost:5001/hello | head -n 20
HTTP/1.1 200 OK
Date: Mon, 18 Oct 2021 09:08:21 GMT
Content-Type: text/plain
Server: Kestrel
Transfer-Encoding: chunked
Set-Cookie: ss-id=42jDIrssfMDonvo1L8L1; path=/; secure; samesite=lax; httponly
Set-Cookie: ss-pid=Loky3Oi2FqjJzoGYJovf; expires=Fri, 18 Oct 2041 09:08:21 GMT; path=/; secure; samesite=lax; httponly
Vary: Accept
X-Powered-By: ServiceStack/5.121 NetCore/OSX
Forbidden
So the same fix in ServiceStack, or modification of templates to correctly set the response code, should be applied as well.
So in summary, if you experience incorrect response code for html pages, you get a 200 OK
when you expected a 404 Not Found
or a 403 Forbidden
, and you have CustomErrorHttpHandlers
using SharpPageHandler
, then use the following workaround from @mythz instead of the suggestions in the ServiceStack templates.
public void Configure(IAppHost appHost)
{
appHost.CustomErrorHttpHandlers[HttpStatusCode.NotFound] =
new SharpPageHandler("/notfound")
{
ValidateFn = req =>
{
req.Response.StatusCode = (int)HttpStatusCode.NotFound;
return true;
}
};
appHost.CustomErrorHttpHandlers[HttpStatusCode.Forbidden] =
new SharpPageHandler("/forbidden")
{
ValidateFn = req =>
{
req.Response.StatusCode = (int)HttpStatusCode.NotFound;
return true;
}
};
}
Thank you for your help @mythz.