lucky icon indicating copy to clipboard operation
lucky copied to clipboard

Lucky couldn't figure out what format the client accepts. The client's Accept header: 'image/*;q=0.8'

Open wezm opened this issue 4 years ago • 5 comments

I have the following action for handing the favicon. (I need to have it as its own action instead of it falling back to asset handing because I have have a catch all route /:category elsewhere in the application):

class Favicon::Show < BrowserAction
  include Auth::AllowGuests

  before cache_publicly(1.day)

  get "/favicon.ico" do
    file "public/favicon.ico", disposition: "inline"
  end
end

When I access a page in Mobile Firefox on iOS and it requests the favicon, I see this error.

GET /favicon.ico
 ▸ Handled by Favicon::Show
 ▸ Exception Lucky couldn't figure out what format the client accepts.

    The client's Accept header: 'image/*;q=0.8'

You can teach Lucky how to handle this header:

    # Add this in config/mime_types.cr
    Lucky::MimeType.register "image/*;q=0.8", :custom_format

Or use one of these headers Lucky knows about:

    text/html, application/json, text/json, application/jsonrequest, text/javascript, application/xml, application/rss+xml, application/atom+xml, application/x-yaml, text/yaml, text/csv, text/css, text/calendar, text/plain, multipart/form-data, application/x-www-form-urlencoded

 (Lucky::UnknownAcceptHeaderError)
  from lib/lucky/src/lucky/request_type_helpers.cr:0:7 in 'determine_clients_desired_format'
  from lib/lucky/src/lucky/request_type_helpers.cr:44:41 in 'clients_desired_format'
  from src/actions/favicon/show.cr:6:3 in 'call'
  from lib/lucky/src/lucky/renderable.cr:97:16 in 'perform_action'
  from lib/lucky/src/lucky/route_handler.cr:10:7 in 'call'
  from /home/wmoore/.crenv/versions/0.31.1/share/crystal/src/http/server/handler.cr:26:7 in 'call_next'
  from lib/lucky/src/lucky/error_handler.cr:15:5 in 'call'
  from /home/wmoore/.crenv/versions/0.31.1/share/crystal/src/http/server/handler.cr:26:7 in 'call_next'
  from lib/lucky/src/lucky/flash_handler.cr:5:5 in 'call'
  from /home/wmoore/.crenv/versions/0.31.1/share/crystal/src/http/server/handler.cr:26:7 in 'call_next'
  from lib/lucky/src/lucky/session_handler.cr:5:5 in 'call'
  from /home/wmoore/.crenv/versions/0.31.1/share/crystal/src/http/server/handler.cr:26:7 in 'call_next'
  from lib/lucky/src/lucky/log_handler.cr:17:5 in 'call'
  from /home/wmoore/.crenv/versions/0.31.1/share/crystal/src/http/server/handler.cr:26:7 in 'call_next'
  from lib/lucky/src/lucky/http_method_override_handler.cr:11:5 in 'call'
  from /home/wmoore/.crenv/versions/0.31.1/share/crystal/src/http/server/handler.cr:26:7 in 'call_next'
  from lib/lucky/src/lucky/force_ssl_handler.cr:37:7 in 'call'
  from /home/wmoore/.crenv/versions/0.31.1/share/crystal/src/http/server/request_processor.cr:48:11 in 'process'
  from /home/wmoore/.crenv/versions/0.31.1/share/crystal/src/http/server/request_processor.cr:22:3 in 'process'
  from /home/wmoore/.crenv/versions/0.31.1/share/crystal/src/http/server.cr:497:5 in 'handle_client'
  from /home/wmoore/.crenv/versions/0.31.1/share/crystal/src/http/server.cr:463:13 in '->'
  from /home/wmoore/.crenv/versions/0.31.1/share/crystal/src/fiber.cr:255:3 in 'run'
  from /home/wmoore/.crenv/versions/0.31.1/share/crystal/src/fiber.cr:48:34 in '->'
  from ???

I tried adding Lucky::MimeType.register "image/x-icon", :ico to the config/mime_types.cr as suggested but the error still occurs.

Lucky: 0.18.0 Crystal: 0.31.0

wezm avatar Dec 09 '19 07:12 wezm

Could you post back your page source? Specifically how you render favicon? Something along the lines of :

<link rel="icon" type="image/x-icon" class="js-site-favicon" href="https://github.githubassets.com/favicon.ico">

Without seeing that, I would venture that this maybe not related to Lucky per se.

See: Firefox - List of default Accept values .

  • "image/*;q=0.8" is specifically the "Accept Header" that's being sent by client.
  • It sounds like the browser ( client) may be requesting/expecting a png?
  • Could also that's specifically that header/mime time that's being sent/requested?

Can you try these two options

Lucky::MimeType.register "image/*;q=0.8", :ico
# Or this.  You will need to convert your ico to png
Lucky::MimeType.register "image/*;q=0.8", :png

Also if you want to handle both PNG & ICO favicons Your page can provide both options like so ( for different use cases)

<link rel="shortcut icon" href="https://mysite.com/favicon.ico"> 
<link rel="apple-touch-icon" href="https://mysite.com/apple-touch-icon.png"> 

konung avatar Dec 09 '19 16:12 konung

Could you post back your page source? Specifically how you render favicon?

The website is Read Rust, the favicon is an ICO file, not PNG. I don't point at the favicon in my markup. I just rely on the default browser of looking for favicon.ico at the root of the domain, which is where this route maps to.

It sounds like the browser ( client) may be requesting/expecting a png?

I'm not sure that's the case, I think it's looking for anything with an image mime type (image/*).

Can you try these two options

Lucky::MimeType.register "image/*;q=0.8", :ico

Does it make sense to include the quality factor (q) in the registered mime type? I would have thought this was a matching concern only.

wezm avatar Dec 09 '19 22:12 wezm

My first guess is you have to tell the action which mimetype you want to use like:

class Favicon::Show < BrowserAction
  include Auth::AllowGuests

  accepted_formats [:ico, :png], default: :ico
  before cache_publicly(1.day)

  get "/favicon.ico" do
    file "public/favicon.ico", disposition: "inline"
  end
end

Otherwise it'll think you're returning HTML. You'll have to register those ico or png.

Now my second though is, why do it in an action, and not in the view directly? My app is multi-tenant, so I need a differen favicon for each site, but I use this:

 # call this in the layout
  def favicon_tag(path)
    empty_tag("link", rel: "shortcut icon", href: dynamic_asset("images/#{path}"))
  end

jwoertink avatar Dec 09 '19 22:12 jwoertink

My first guess is you have to tell the action which mimetype you want to use like

Thanks, I'll give that a try.

why do it in an action, and not in the view directly?

I like not needing to add markup for this. Using dynamic asset would add a fingerprint to the path, and then it would not longer be at /favicon.ico.

wezm avatar Dec 09 '19 23:12 wezm

Fair enough. Always good to make sure alternate methods work out anyway 😄

jwoertink avatar Dec 09 '19 23:12 jwoertink