HTTP 404 when text/html is not first in accept request header

The order of the MIME types in the accept request header as sent to the Discourse server seems to matter:

curl -i -H 'Accept: text/plain, text/html' https://meta.discourse.org
HTTP/2 404 
...
curl -i -H 'Accept: text/html, text/plain' https://meta.discourse.org
HTTP/2 200
...
4 Likes

This would mainly impact API consumers I guess. Open to a PR that corrects this.

4 Likes

I tried this on the dev build, I’m getting 200 OK from Rails::WelcomeController#index for both headers Accept: text/html, text/plain and Accept: text/plain, text/html.

Started GET "/" for 127.0.0.1 at 2023-03-30 15:52:45 +0300
Processing by Rails::WelcomeController#index as TEXT
  Rendering /Users/machine/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/railties-7.0.4.3/lib/rails/templates/rails/welcome/index.html.erb
  Rendered /Users/machine/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/railties-7.0.4.3/lib/rails/templates/rails/welcome/index.html.erb (Duration: 0.1ms | Allocations: 36)
Completed 200 OK in 1ms (Views: 1.3ms | ActiveRecord: 0.0ms | Allocations: 796)
machine@machines-MacBook-Pro discourse % curl -I -H 'Accept: text/html, text/plain' http://127.0.01:4200 
HTTP/1.1 200 OK
X-Powered-By: Express
cache-control: no-store, must-revalidate, private, max-age=0
connection: close
content-security-policy: base-uri 'self'; object-src 'none'; script-src http://127.0.01:4200/assets/ http://127.0.01:4200/ember-cli-live-reload.js http://127.0.01:4200/_lr/ http://127.0.01:4200/logs/ http://127.0.01:4200/sidekiq/ http://127.0.01:4200/mini-profiler-resources/ http://127.0.01:4200/assets/ http://127.0.01:4200/brotli_asset/ http://127.0.01:4200/extra-locales/ http://127.0.01:4200/highlight-js/ http://127.0.01:4200/javascripts/ http://127.0.01:4200/plugins/ http://127.0.01:4200/theme-javascripts/ http://127.0.01:4200/svg-sprite/ 'unsafe-eval' http://127.0.01:4200/ember-cli-live-reload.js http://127.0.01:4200/_lr/ 'sha256-Gty3/aPWFfSvz7pdT39HY97/+2opLup9V0L19ZF0IwY='; worker-src 'self' http://127.0.01:4200/assets/ http://127.0.01:4200/brotli_asset/ http://127.0.01:4200/javascripts/ http://127.0.01:4200/plugins/; frame-ancestors 'self'; manifest-src 'self'
Content-Type: text/html; charset=utf-8
date: Thu, 30 Mar 2023 12:51:19 GMT
referrer-policy: strict-origin-when-cross-origin
set-cookie: __profilin=p%3Dt; path=/; HttpOnly; SameSite=Lax
Vary: Accept, Accept-Encoding
x-content-type-options: nosniff
x-discourse-route: list/latest
x-download-options: noopen
x-frame-options: SAMEORIGIN
x-miniprofiler-ids: 3uaox120htfj3nkrwxvy,v4ylpbinbd6pz2p7ar2l,8snf28djimkyzf5vpe5v,iq2fhxx37pkunle3zzxv,o5b5ae8lxmj9vgazlydh,spjovt9bn2x0ziaikfxh,ut7qvfhrp7pt2hflvf1r,m428xr7orlndjj5fm17n,eryv846zt9oqyiccvw4,t8fp5g9iqbfxrmkd3qv9,jea1zbtm7vu2zbmb1kdk,u5h4t1804men5vx9xuvd
x-miniprofiler-original-cache-control: no-cache, no-store
x-permitted-cross-domain-policies: none
x-request-id: be9de952-9043-41a9-adca-1c5124b1ff90
x-xss-protection: 0
content-encoding: null
Content-Length: 0
ETag: W/"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"

machine@machines-MacBook-Pro discourse % curl -I -H 'Accept: text/plain, text/html' http://127.0.01:4200 
HTTP/1.1 200 OK
X-Powered-By: Express
cache-control: no-store, must-revalidate, private, max-age=0
connection: close
content-security-policy: base-uri 'self'; object-src 'none'; script-src http://127.0.01:4200/assets/ http://127.0.01:4200/ember-cli-live-reload.js http://127.0.01:4200/_lr/ http://127.0.01:4200/logs/ http://127.0.01:4200/sidekiq/ http://127.0.01:4200/mini-profiler-resources/ http://127.0.01:4200/assets/ http://127.0.01:4200/brotli_asset/ http://127.0.01:4200/extra-locales/ http://127.0.01:4200/highlight-js/ http://127.0.01:4200/javascripts/ http://127.0.01:4200/plugins/ http://127.0.01:4200/theme-javascripts/ http://127.0.01:4200/svg-sprite/ 'unsafe-eval' http://127.0.01:4200/ember-cli-live-reload.js http://127.0.01:4200/_lr/ 'sha256-Gty3/aPWFfSvz7pdT39HY97/+2opLup9V0L19ZF0IwY='; worker-src 'self' http://127.0.01:4200/assets/ http://127.0.01:4200/brotli_asset/ http://127.0.01:4200/javascripts/ http://127.0.01:4200/plugins/; frame-ancestors 'self'; manifest-src 'self'
Content-Type: text/html; charset=utf-8
date: Thu, 30 Mar 2023 12:51:26 GMT
referrer-policy: strict-origin-when-cross-origin
set-cookie: __profilin=p%3Dt; path=/; HttpOnly; SameSite=Lax
Vary: Accept, Accept-Encoding
x-content-type-options: nosniff
x-download-options: noopen
x-frame-options: SAMEORIGIN
x-miniprofiler-ids: fw6wmg2wtmnuc4qqk5ri,3uaox120htfj3nkrwxvy,v4ylpbinbd6pz2p7ar2l,8snf28djimkyzf5vpe5v,iq2fhxx37pkunle3zzxv,o5b5ae8lxmj9vgazlydh,spjovt9bn2x0ziaikfxh,ut7qvfhrp7pt2hflvf1r,m428xr7orlndjj5fm17n,eryv846zt9oqyiccvw4,t8fp5g9iqbfxrmkd3qv9,jea1zbtm7vu2zbmb1kdk,u5h4t1804men5vx9xuvd
x-permitted-cross-domain-policies: none
x-request-id: 00c3add3-15ec-42d5-9c82-9d6ce09b09fd
x-xss-protection: 0
content-encoding: null
Content-Length: 0
ETag: W/"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"

machine@machines-MacBook-Pro discourse % 

@sam can you please provide some direction on how to fix this?

This is not going to be easy to debug, it may be related to the NGINX configuration in production, maybe this is in Rails I am not sure.

I would try to first make the request direct to the Rails process and not to the express proxy, if that works then I would next debug a production docker setup on local.

Yep, sending the requests directly to the Rails process doesn’t reproduce the issue either

machine@machines-MacBook-Pro discourse % curl -I -H 'Accept: text/plain, text/html' http://127.0.0.1:3000
HTTP/1.1 200 OK
Date: Fri, 31 Mar 2023 00:17:12 GMT
Connection: close
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 0
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Permitted-Cross-Domain-Policies: none
Referrer-Policy: strict-origin-when-cross-origin
Content-Type: text/html; charset=utf-8
Vary: Accept
Content-Security-Policy: base-uri 'self'; object-src 'none'; script-src http://127.0.0.1:3000/logs/ http://127.0.0.1:3000/sidekiq/ http://127.0.0.1:3000/mini-profiler-resources/ http://127.0.0.1:3000/assets/ http://127.0.0.1:3000/brotli_asset/ http://127.0.0.1:3000/extra-locales/ http://127.0.0.1:3000/highlight-js/ http://127.0.0.1:3000/javascripts/ http://127.0.0.1:3000/plugins/ http://127.0.0.1:3000/theme-javascripts/ http://127.0.0.1:3000/svg-sprite/ 'unsafe-eval' http://127.0.0.1:3000/ember-cli-live-reload.js http://127.0.0.1:3000/_lr/ 'sha256-Gty3/aPWFfSvz7pdT39HY97/+2opLup9V0L19ZF0IwY='; worker-src 'self' http://127.0.0.1:3000/assets/ http://127.0.0.1:3000/brotli_asset/ http://127.0.0.1:3000/javascripts/ http://127.0.0.1:3000/plugins/; frame-ancestors 'self'; manifest-src 'self'
X-Request-Id: 9a58c127-bc9e-4c27-a6a4-2ac5b9d34e5f
Cache-Control: no-store, must-revalidate, private, max-age=0
X-MiniProfiler-Ids: vit385ud6hkrs02yr6r,3izsng340krymolreb78,cq88v42hj61giemunux3,dq9oli1nmmat6k4o274k,37obrexoyg8146xozpqg,qucwk4opydg3vjyj3kz2,b54tne0pbtipq7rie4j9,m2syvsy4jl6wi0q3c2g5,72du4xsbgjmr67p4mhdx,zw5wg2t6susof6zele0y,kar63by1273tae1l0qgw
Set-Cookie: __profilin=p%3Dt; path=/; HttpOnly; SameSite=Lax

machine@machines-MacBook-Pro discourse % curl -I -H 'Accept: text/html, text/plain' http://127.0.0.1:3000
HTTP/1.1 200 OK
Date: Fri, 31 Mar 2023 00:17:15 GMT
Connection: close
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 0
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Permitted-Cross-Domain-Policies: none
Referrer-Policy: strict-origin-when-cross-origin
X-Discourse-Route: list/latest
Content-Type: text/html; charset=utf-8
Vary: Accept
Cache-Control: no-store, must-revalidate, private, max-age=0
Content-Security-Policy: base-uri 'self'; object-src 'none'; script-src http://127.0.0.1:3000/logs/ http://127.0.0.1:3000/sidekiq/ http://127.0.0.1:3000/mini-profiler-resources/ http://127.0.0.1:3000/assets/ http://127.0.0.1:3000/brotli_asset/ http://127.0.0.1:3000/extra-locales/ http://127.0.0.1:3000/highlight-js/ http://127.0.0.1:3000/javascripts/ http://127.0.0.1:3000/plugins/ http://127.0.0.1:3000/theme-javascripts/ http://127.0.0.1:3000/svg-sprite/ 'unsafe-eval' http://127.0.0.1:3000/ember-cli-live-reload.js http://127.0.0.1:3000/_lr/ 'sha256-Gty3/aPWFfSvz7pdT39HY97/+2opLup9V0L19ZF0IwY='; worker-src 'self' http://127.0.0.1:3000/assets/ http://127.0.0.1:3000/brotli_asset/ http://127.0.0.1:3000/javascripts/ http://127.0.0.1:3000/plugins/; frame-ancestors 'self'; manifest-src 'self'
X-Request-Id: 8ac7c6b7-512e-4c1b-b868-88f3a1ea200c
X-MiniProfiler-Original-Cache-Control: no-cache, no-store
X-MiniProfiler-Ids: tae1e7defycsvswht8d2,vit385ud6hkrs02yr6r,3izsng340krymolreb78,cq88v42hj61giemunux3,dq9oli1nmmat6k4o274k,37obrexoyg8146xozpqg,qucwk4opydg3vjyj3kz2,b54tne0pbtipq7rie4j9,m2syvsy4jl6wi0q3c2g5,72du4xsbgjmr67p4mhdx,zw5wg2t6susof6zele0y,kar63by1273tae1l0qgw
Set-Cookie: __profilin=p%3Dt; path=/; HttpOnly; SameSite=Lax

I will investigate further with a production docker setup on local :+1:

1 Like