iain / http_accept_language

Ruby on Rails plugin. Fishes out the Accept-Language header into an array.
http://rails-i18n.org/
782 stars 119 forks source link

Returning wrong locale sometimes #32

Closed fullofcaffeine closed 10 years ago

fullofcaffeine commented 10 years ago

I have the following code in my Rails app's ApplicationController:

before_filter :set_locale

And the method definition:

  def set_locale
  logger.warn("*** Available locales: #{I18n.available_locales}")
    logger.warn("*** Preferred language:  #{http_accept_language.preferred_language_from(I18n.available_locales)}")
    I18n.locale = (params[:locale] || http_accept_language.preferred_language_from(I18n.available_locales) || I18n.default_locale)
  end

I have two locales in the app as of now: :en and :pt. If I setup Portuguese to take precedence in my user agent (Chrome) and reload the page, sometimes it still returns english, even though the it's set to Portuguese.

It looks as if some of the unicorn workers still have the I18n.locale cached somehow. Would that be possible?

Any insights would be greatly appreciated!

DouweM commented 10 years ago

I have had some problems with I18n.locale "leaking" into other requests, which I solved by adding def set_locale; I18n.locale = I18n.default_locale; end to my ApplicationController, but I'm not sure that's the same issue you're describing.

You say "it still returns english", do you mean that http_accept_language.preferred_language_from(...) returns :en even when the Accept-Language header specificies Portuguese? Could you perhaps add some logging to lib/http_accept_language/middleware.rb and other http_accept_language files?

fullofcaffeine commented 10 years ago

Hi,

Thank you for the reply!

http_accept_language.preferred_language_from(I18n.available_locales) is behaving inconsistently.

The logs below are form Rails' production log. I just set Chrome's language settings to give preference to English. I then made a bunch of requests, here are the results:

204.16.155.2 GET /users/sign_in 200 OK Devise::SessionsController#new HTML 14.6 (DB 0.0, View 9.5) {} {} * Accept-Language Header: en-US,en;q=0.8,pt;q=0.6,es-419;q=0.4,es;q=0.2 * Available locales: [:pt, :en] * Preferred language:
204.16.155.2 GET /users/sign_in 200 OK Devise::SessionsController#new HTML 12.2 (DB 0.0, View 9.4) {} {}
* Accept-Language Header: en-US,en;q=0.8,pt;q=0.6,es-419;q=0.4,es;q=0.2 * Available locales: [:pt, :en] * Preferred language:
204.16.155.2 GET /users/sign_in 200 OK Devise::SessionsController#new HTML 12.2 (DB 0.0, View 9.4) {} {} * Accept-Language Header: en-US,en;q=0.8,pt;q=0.6,es-419;q=0.4,es;q=0.2 * Available locales: [:pt, :en] * Preferred language: pt 204.16.155.2 GET /users/sign_in 200 OK Devise::SessionsController#new HTML 12.2 (DB 0.0, View 9.5) {} {} * Accept-Language Header: en-US,en;q=0.8,pt;q=0.6,es-419;q=0.4,es;q=0.2 * Available locales: [:pt, :en] * Preferred language:
204.16.155.2 GET /users/sign_in 200 OK Devise::SessionsController#new HTML 12.4 (DB 0.0, View 9.6) {} {} * Accept-Language Header: en-US,en;q=0.8,pt;q=0.6,es-419;q=0.4,es;q=0.2 * Available locales: [:pt, :en] * Preferred language: en 204.16.155.2 GET /users/sign_in 200 OK Devise::SessionsController#new HTML 11.8 (DB 0.0, View 9.0) {} {} * Accept-Language Header: en-US,en;q=0.8,pt;q=0.6,es-419;q=0.4,es;q=0.2 * Available locales: [:pt, :en] * Preferred language: pt 204.16.155.2 GET /users/sign_in 200 OK Devise::SessionsController#new HTML 12.2 (DB 0.0, View 9.4) {} {} * Accept-Language Header: en-US,en;q=0.8,pt;q=0.6,es-419;q=0.4,es;q=0.2 * Available locales: [:pt, :en] * Preferred language: en 204.16.155.2 GET /users/sign_in 200 OK Devise::SessionsController#new HTML 13.1 (DB 0.0, View 9.3) {} {} * Accept-Language Header: en-US,en;q=0.8,pt;q=0.6,es-419;q=0.4,es;q=0.2 * Available locales: [:pt, :en] * Preferred language: pt 204.16.155.2 GET /users/sign_in 200 OK Devise::SessionsController#new HTML 11.8 (DB 0.0, View 9.1) {} {} * Accept-Language Header: en-US,en;q=0.8,pt;q=0.6,es-419;q=0.4,es;q=0.2 * Available locales: [:pt, :en] * Preferred language: pt 204.16.155.2 GET /users/sign_in 200 OK Devise::SessionsController#new HTML 17.8 (DB 0.0, View 10.0) {} {} * Accept-Language Header:
* Available locales: [:pt, :en] * Preferred language: pt

You can see that for some of the requests, it returns an empty string, for some en (expected) and for others pt.

Here's the gems list:

Gems included by the bundle:

Any insights appreciated.

Marcelo

On Wednesday, December 4, 2013 at 6:22 PM, Douwe Maan wrote:

I have had some problems with I18n.locale "leaking" into other requests, which I solved by adding def set_locale; I18n.locale = I18n.default_locale; end to my ApplicationController, but I'm not sure that's the same issue you're describing.
You say "it still returns english", do you mean that http_accept_language.preferred_language_from(...) returns :en even when the Accept-Language header specificies Portuguese? Could you perhaps add some logging to lib/http_accept_language/middleware.rb (https://github.com/iain/http_accept_language/blob/master/lib/http_accept_language/middleware.rb) and other http_accept_language files?

— Reply to this email directly or view it on GitHub (https://github.com/iain/http_accept_language/issues/32#issuecomment-29860361).

fullofcaffeine commented 10 years ago

By the way, the value logged for Preferred language comes from http_accept_language.preferred_language_from(I18n.available_locales) is behaving inconsistently. Here's the method definition (right now I'm forcing the locale to :en in the last line, to avoid users from getting the inconsistent behavior):

def set_locale logger.warn("* Accept-Language Header: #{request.headers['Accept-Language']}") logger.warn("* Available locales: #{I18n.available_locales}") logger.warn("*\ Preferred language: #{http_accept_language.preferred_language_from(I18n.available_locales)}")

I18n.locale = (params[:locale] || http_accept_language.preferred_language_from(I18n.available_locales) || I18n.default_locale)

I18n.locale = :en end

Marcelo

On Wednesday, December 4, 2013 at 6:53 PM, Marcelo Serpa wrote:

Hi,

Thank you for the reply!

http_accept_language.preferred_language_from(I18n.available_locales) is behaving inconsistently.

The logs below are form Rails' production log. I just set Chrome's language settings to give preference to English. I then made a bunch of requests, here are the results:

204.16.155.2 GET /users/sign_in 200 OK Devise::SessionsController#new HTML 14.6 (DB 0.0, View 9.5) {} {} * Accept-Language Header: en-US,en;q=0.8,pt;q=0.6,es-419;q=0.4,es;q=0.2 * Available locales: [:pt, :en] * Preferred language:
204.16.155.2 GET /users/sign_in 200 OK Devise::SessionsController#new HTML 12.2 (DB 0.0, View 9.4) {} {}
* Accept-Language Header: en-US,en;q=0.8,pt;q=0.6,es-419;q=0.4,es;q=0.2 * Available locales: [:pt, :en] * Preferred language:
204.16.155.2 GET /users/sign_in 200 OK Devise::SessionsController#new HTML 12.2 (DB 0.0, View 9.4) {} {} * Accept-Language Header: en-US,en;q=0.8,pt;q=0.6,es-419;q=0.4,es;q=0.2 * Available locales: [:pt, :en] * Preferred language: pt 204.16.155.2 GET /users/sign_in 200 OK Devise::SessionsController#new HTML 12.2 (DB 0.0, View 9.5) {} {} * Accept-Language Header: en-US,en;q=0.8,pt;q=0.6,es-419;q=0.4,es;q=0.2 * Available locales: [:pt, :en] * Preferred language:
204.16.155.2 GET /users/sign_in 200 OK Devise::SessionsController#new HTML 12.4 (DB 0.0, View 9.6) {} {} * Accept-Language Header: en-US,en;q=0.8,pt;q=0.6,es-419;q=0.4,es;q=0.2 * Available locales: [:pt, :en] * Preferred language: en 204.16.155.2 GET /users/sign_in 200 OK Devise::SessionsController#new HTML 11.8 (DB 0.0, View 9.0) {} {} * Accept-Language Header: en-US,en;q=0.8,pt;q=0.6,es-419;q=0.4,es;q=0.2 * Available locales: [:pt, :en] * Preferred language: pt 204.16.155.2 GET /users/sign_in 200 OK Devise::SessionsController#new HTML 12.2 (DB 0.0, View 9.4) {} {} * Accept-Language Header: en-US,en;q=0.8,pt;q=0.6,es-419;q=0.4,es;q=0.2 * Available locales: [:pt, :en] * Preferred language: en 204.16.155.2 GET /users/sign_in 200 OK Devise::SessionsController#new HTML 13.1 (DB 0.0, View 9.3) {} {} * Accept-Language Header: en-US,en;q=0.8,pt;q=0.6,es-419;q=0.4,es;q=0.2 * Available locales: [:pt, :en] * Preferred language: pt 204.16.155.2 GET /users/sign_in 200 OK Devise::SessionsController#new HTML 11.8 (DB 0.0, View 9.1) {} {} * Accept-Language Header: en-US,en;q=0.8,pt;q=0.6,es-419;q=0.4,es;q=0.2 * Available locales: [:pt, :en] * Preferred language: pt 204.16.155.2 GET /users/sign_in 200 OK Devise::SessionsController#new HTML 17.8 (DB 0.0, View 10.0) {} {} * Accept-Language Header:
* Available locales: [:pt, :en] * Preferred language: pt

You can see that for some of the requests, it returns an empty string, for some en (expected) and for others pt.

Here's the gems list:

Gems included by the bundle:

  • actionmailer (3.2.13)
  • actionpack (3.2.13)
  • activemodel (3.2.13)
  • activerecord (3.2.13)
  • activeresource (3.2.13)
  • activesupport (3.2.13)
  • annotate (2.5.0)
  • arel (3.0.3)
  • atomic (1.1.14)
  • aws-sdk (1.27.0)
  • bcrypt-ruby (3.1.2)
  • better_errors (1.0.1)
  • binding_of_caller (0.7.2)
  • bootstrap-sass (2.3.2.2)
  • bourbon (3.1.8)
  • builder (3.0.4)
  • bundler (1.3.5)
  • callsite (0.0.11)
  • cancan (1.6.10)
  • capistrano (2.15.5)
  • capybara (2.1.0)
  • childprocess (0.3.9)
  • climate_control (0.0.3)
  • cocaine (0.5.3)
  • coderay (1.1.0)
  • columnize (0.3.6)
  • custom_configuration (0.0.2)
  • daemons (1.1.9)
  • debug_inspector (0.0.2)
  • debugger (1.6.2)
  • debugger-linecache (1.2.0)
  • debugger-ruby_core_source (1.2.3)
  • devise (3.2.1)
  • diff-lcs (1.2.5)
  • erubis (2.7.0)
  • eventmachine (1.0.3)
  • execjs (2.0.2)
  • factory_girl (4.3.0)
  • factory_girl_rails (4.3.0)
  • faraday (0.8.8)
  • ffi (1.9.3)
  • figaro (0.7.0)
  • font-awesome-sass-rails (3.0.2.2)
  • gli (2.8.1)
  • hashie (2.0.5)
  • highline (1.6.20)
  • hike (1.2.3)
  • http_accept_language (2.0.0.pre fa57cfb)
  • i18n (0.6.1)
  • i18n-js (2.1.2)
  • journey (1.0.4)
  • jquery-fileupload-rails (0.4.1)
  • jquery-rails (2.3.0)
  • json (1.8.1)
  • kgio (2.7.4)
  • libv8 (3.16.14.3)
  • localeapp (0.6.14)
  • mail (2.5.4)
  • meta_request (0.2.8)
  • mime-types (1.25)
  • mini_portile (0.5.2)
  • multi_json (1.8.2)
  • multipart-post (1.2.0)
  • net-scp (1.1.2)
  • net-sftp (2.1.2)
  • net-ssh (2.7.0)
  • net-ssh-gateway (1.2.0)
  • newrelic_rpm (3.6.9.171)
  • nokogiri (1.6.0)
  • omniauth (1.1.4)
  • orm_adapter (0.5.0)
  • paperclip (3.5.2)
  • pg (0.17.0)
  • polyglot (0.3.3)
  • quiet_assets (1.0.2)
  • rack (1.4.5)
  • rack-cache (1.2)
  • rack-contrib (1.1.0)
  • rack-ssl (1.3.3)
  • rack-test (0.6.2)
  • rails (3.2.13)
  • railties (3.2.13)
  • raindrops (0.10.0)
  • rake (10.1.0)
  • rdoc (3.12.2)
  • ref (1.0.5)
  • rest-client (1.6.7)
  • rspec-core (2.14.7)
  • rspec-expectations (2.14.4)
  • rspec-mocks (2.14.4)
  • rspec-rails (2.14.0)
  • rubyzip (1.0.0)
  • sass (3.2.12)
  • sass-rails (3.2.6)
  • selenium-webdriver (2.37.0)
  • sentry-raven (0.6.0)
  • simple_form (2.1.0)
  • sprockets (2.2.2)
  • state_machine (1.2.0)
  • stripe (1.8.9 28ac4ff)
  • therubyracer (0.12.0)
  • thin (1.6.1)
  • thor (0.18.1)
  • thread_safe (0.1.3)
  • tilt (1.4.1)
  • treetop (1.4.15)
  • turbo-sprockets-rails3 (0.3.10)
  • tzinfo (0.3.38)
  • uglifier (2.3.1)
  • unicorn (4.4.0)
  • uuidtools (2.1.4)
  • warden (1.2.3)
  • websocket (1.0.7)
  • xpath (2.0.0)
  • ya2yaml (0.31)

Any insights appreciated.

Marcelo

On Wednesday, December 4, 2013 at 6:22 PM, Douwe Maan wrote:

I have had some problems with I18n.locale "leaking" into other requests, which I solved by adding def set_locale; I18n.locale = I18n.default_locale; end to my ApplicationController, but I'm not sure that's the same issue you're describing.
You say "it still returns english", do you mean that http_accept_language.preferred_language_from(...) returns :en even when the Accept-Language header specificies Portuguese? Could you perhaps add some logging to lib/http_accept_language/middleware.rb (https://github.com/iain/http_accept_language/blob/master/lib/http_accept_language/middleware.rb) and other http_accept_language files?

— Reply to this email directly or view it on GitHub (https://github.com/iain/http_accept_language/issues/32#issuecomment-29860361).

DouweM commented 10 years ago

Looks like there's some Unicorn caching going on. Could you add some logging to lib/http_accept_language/middleware.rb and other http_accept_language files?

fullofcaffeine commented 10 years ago

What kind of logging would you like me to add? The problem is that it's a production app, and it would take some time to reproduce the same env in a, say, Vagrant Box (but I could try to do it later on to debug it).

When you say "Unicorn Caching", what are you referring to exactly?

Thanks,

Marcelo

On Thursday, December 5, 2013 at 7:24 AM, Douwe Maan wrote:

Looks like there's some Unicorn caching going on. Could you add some logging to lib/http_accept_language/middleware.rb (https://github.com/iain/http_accept_language/blob/master/lib/http_accept_language/middleware.rb) and other http_accept_language files?

— Reply to this email directly or view it on GitHub (https://github.com/iain/http_accept_language/issues/32#issuecomment-29896891).

DouweM commented 10 years ago

We're using Unicorn as well, and I haven't experienced anything like what you're describing. As for "Unicorn Caching", I'm not referring to anything specifically, it's just that this sounds like some object is being re-used across requests, causing the header to not be parsed again.

I'd add logging to Middleware#call to

  1. make sure it's called,
  2. make sure env["HTTP_ACCEPT_LANGUAGE"] contains what you'd expect,
  3. make sure env["http_accept_language.parser"].user_preferred_languages contains what you'd expect,
  4. make sure preferred_language_from contains what you'd expect,
  5. make sure EasyAccess#http_accept_language contains what you'd expect
fullofcaffeine commented 10 years ago

Here's my nginx unicorn configuration, as a reference:

upstream app_server { server 127.0.0.1:3030 fail_timeout=0; } server { listen 80 default; server_name www.myapp.com; client_max_body_size 4G; keepalive_timeout 5; root /var/www/apps/app/current/public; try_files $uri/index.html $uri.html $uri @app; location @app { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header Accept-Language $http_accept_language; proxy_redirect off; proxy_pass http://app_server; } error_page 500 502 503 504 /500.html; location = /500.html { root /var/www/apps/sample/current/public; } }

And the unicorn configuration:

What ports/sockets to listen on, and what options for them.

listen "3030", :tcp_nodelay => true, :backlog => 100

working_directory '/var/www/apps/app/current'

stderr_path "/tmp/unicorn.stderr" stdout_path "/tmp/unicorn.stdout"

What the timeout for killing busy workers is, in seconds

timeout 60

Whether the app should be pre-loaded

preload_app false

How many worker processes

worker_processes 8

What to do before we fork a worker

before_fork do |server, worker| sleep 1 end

I'm using runit to start/stop/restart it. The run script:

!/bin/bash

cd /var/www/apps/app/current

exec 2>&1 exec /usr/bin/chpst -u deploy:deploy bundle exec unicorn -E production -c /etc/unicorn/app.rb

That's pretty much it. Do you see anything too different from your own setup?

Thank you for the help,

Marcelo

On Thursday, December 5, 2013 at 12:11 PM, Douwe Maan wrote:

We're using Unicorn as well, and I haven't experienced anything like what you're describing. As for "Unicorn Caching", I'm not referring to anything specifically, it's just that this sounds like some object is being re-used across requests, causing the header to not be parsed again. I'd add logging to Middleware#call to

  1. make sure it's called,
  2. make sure env["HTTP_ACCEPT_LANGUAGE"] contains what you'd expect,
  3. make sure env["http_accept_language.parser"].user_preferred_languages contains what you'd expect,
  4. make sure preferred_language_from contains what you'd expect,
  5. make sure EasyAccess#http_accept_language contains what you'd expect

— Reply to this email directly or view it on GitHub (https://github.com/iain/http_accept_language/issues/32#issuecomment-29922260).

DouweM commented 10 years ago

I'll compare that to my own config tomorrow, but it'd really help if you acquired those logs!

–Douwe

On 6 dec. 2013, at 00:39, Marcelo de Moraes Serpa notifications@github.com wrote:

Here's my nginx unicorn configuration, as a reference:

upstream app_server { server 127.0.0.1:3030 fail_timeout=0; } server { listen 80 default; server_name www.myapp.com; client_max_body_size 4G; keepalive_timeout 5; root /var/www/apps/app/current/public; try_files $uri/index.html $uri.html $uri @app; location @app { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header Accept-Language $http_accept_language; proxy_redirect off; proxy_pass http://app_server; } error_page 500 502 503 504 /500.html; location = /500.html { root /var/www/apps/sample/current/public; } }

And the unicorn configuration:

What ports/sockets to listen on, and what options for them.

listen "3030", :tcp_nodelay => true, :backlog => 100

working_directory '/var/www/apps/app/current'

stderr_path "/tmp/unicorn.stderr" stdout_path "/tmp/unicorn.stdout"

What the timeout for killing busy workers is, in seconds

timeout 60

Whether the app should be pre-loaded

preload_app false

How many worker processes

worker_processes 8

What to do before we fork a worker

before_fork do |server, worker| sleep 1 end

I'm using runit to start/stop/restart it. The run script:

!/bin/bash

cd /var/www/apps/app/current

exec 2>&1 exec /usr/bin/chpst -u deploy:deploy bundle exec unicorn -E production -c /etc/unicorn/app.rb

That's pretty much it. Do you see anything too different from your own setup?

Thank you for the help,

Marcelo

On Thursday, December 5, 2013 at 12:11 PM, Douwe Maan wrote:

We're using Unicorn as well, and I haven't experienced anything like what you're describing. As for "Unicorn Caching", I'm not referring to anything specifically, it's just that this sounds like some object is being re-used across requests, causing the header to not be parsed again. I'd add logging to Middleware#call to

  1. make sure it's called,
  2. make sure env["HTTP_ACCEPT_LANGUAGE"] contains what you'd expect,
  3. make sure env["http_accept_language.parser"].user_preferred_languages contains what you'd expect,
  4. make sure preferred_language_from contains what you'd expect,
  5. make sure EasyAccess#http_accept_language contains what you'd expect

— Reply to this email directly or view it on GitHub (https://github.com/iain/http_accept_language/issues/32#issuecomment-29922260). — Reply to this email directly or view it on GitHub.

DouweM commented 10 years ago

For the unicorn config, the only difference I see is that we have preload_app set to true.

fullofcaffeine commented 10 years ago

Thank you for checking. It doesn't seem to have anything to do with the unicorn conf.

I'm outputting some data from middleware.rb and parser:

parser.rb:

def user_preferred_languages
  @user_preferred_languages ||= header.gsub(/\s+/, '').split(/,/).collect do |l|
    l += ';q=1.0' unless l =~ /;q=\d+\.\d+$/
      l.split(';q=')
  end.sort do |x,y|
    raise "Not correctly formatted" unless x.first =~ /^[a-z\-0-9]+$/i
    y.last.to_f <=> x.last.to_f
  end.collect do |l|
    l.first.downcase.gsub(/-[a-z0-9]+$/i) { |x| x.upcase }
  end

==> puts "Parser: #{@user_preferred_languages}" @user_preferred_languages rescue # Just rescue anything if the browser messed up badly. [] end

middleware.rb:

def call(env) def env.http_accept_language ==> puts "HEADER --> #{self['HTTP_ACCEPT_LANGUAGE']}" @http_accept_language ||= Parser.new(self['HTTP_ACCEPT_LANGUAGE']) end @app.call(env) end

When I force many subsequent requests from a user agent (Chrome), and I'm tailing the unicorn STDOUT I get this:

HEADER --> pt,en-US;q=0.8,en;q=0.6 Parser: ["en-US"]

HEADER --> pt,en-US;q=0.8,en;q=0.6 Parser: ["pt", "en-US", "en"]

HEADER --> pt,en-US;q=0.8,en;q=0.6 Parser: ["en-US"]

The accept header is forced to Portuguese in Chrome (you can see it in the HEADER --> log), but for some reason, the parser returns en-US sometimes.

Any ideas?

Marcelo

On Friday, December 6, 2013 at 4:12 AM, Douwe Maan wrote:

For the unicorn config, the only difference I see is that we have preload_app set to true.

— Reply to this email directly or view it on GitHub (https://github.com/iain/http_accept_language/issues/32#issuecomment-29977318).

fullofcaffeine commented 10 years ago

It does look like the bug is somewhere in http_accept_language. If I just use the following code directly in the ApplicationController (hence, getting http_accept_language out of the equation), everything works fine:

def set_locale logger.debug "* Accept-Language: #{request.env['HTTP_ACCEPT_LANGUAGE']}" I18n.locale = extract_locale_from_accept_language_header logger.debug "* Locale set to '#{I18n.locale}'" end private def extract_locale_from_accept_language_header request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first end

Marcelo

On Sunday, December 8, 2013 at 12:55 PM, Marcelo Serpa wrote:

Thank you for checking. It doesn't seem to have anything to do with the unicorn conf.

I'm outputting some data from middleware.rb and parser:

parser.rb:

def user_preferred_languages
  @user_preferred_languages ||= header.gsub(/\s+/, '').split(/,/).collect do |l|
    l += ';q=1.0' unless l =~ /;q=\d+\.\d+$/
      l.split(';q=')
  end.sort do |x,y|
    raise "Not correctly formatted" unless x.first =~ /^[a-z\-0-9]+$/i
    y.last.to_f <=> x.last.to_f
  end.collect do |l|
    l.first.downcase.gsub(/-[a-z0-9]+$/i) { |x| x.upcase }
  end

==> puts "Parser: #{@user_preferred_languages}" @user_preferred_languages rescue # Just rescue anything if the browser messed up badly. [] end

middleware.rb:

def call(env) def env.http_accept_language ==> puts "HEADER --> #{self['HTTP_ACCEPT_LANGUAGE']}" @http_accept_language ||= Parser.new(self['HTTP_ACCEPT_LANGUAGE']) end @app.call(env) end

When I force many subsequent requests from a user agent (Chrome), and I'm tailing the unicorn STDOUT I get this:

HEADER --> pt,en-US;q=0.8,en;q=0.6 Parser: ["en-US"]

HEADER --> pt,en-US;q=0.8,en;q=0.6 Parser: ["pt", "en-US", "en"]

HEADER --> pt,en-US;q=0.8,en;q=0.6 Parser: ["en-US"]

The accept header is forced to Portuguese in Chrome (you can see it in the HEADER --> log), but for some reason, the parser returns en-US sometimes.

Any ideas?

Marcelo

On Friday, December 6, 2013 at 4:12 AM, Douwe Maan wrote:

For the unicorn config, the only difference I see is that we have preload_app set to true.

— Reply to this email directly or view it on GitHub (https://github.com/iain/http_accept_language/issues/32#issuecomment-29977318).

fullofcaffeine commented 10 years ago

I'd love to help debugging it further. I'm also intrigued on why it doesn't work as it should. For now, I'll just use the simpler approach from the previous message.

Marcelo

On Sunday, December 8, 2013 at 1:00 PM, Marcelo Serpa wrote:

It does look like the bug is somewhere in http_accept_language. If I just use the following code directly in the ApplicationController (hence, getting http_accept_language out of the equation), everything works fine:

def set_locale logger.debug "* Accept-Language: #{request.env['HTTP_ACCEPT_LANGUAGE']}" I18n.locale = extract_locale_from_accept_language_header logger.debug "* Locale set to '#{I18n.locale}'" end private def extract_locale_from_accept_language_header request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first end

Marcelo

On Sunday, December 8, 2013 at 12:55 PM, Marcelo Serpa wrote:

Thank you for checking. It doesn't seem to have anything to do with the unicorn conf.

I'm outputting some data from middleware.rb and parser:

parser.rb:

def user_preferred_languages
  @user_preferred_languages ||= header.gsub(/\s+/, '').split(/,/).collect do |l|
    l += ';q=1.0' unless l =~ /;q=\d+\.\d+$/
      l.split(';q=')
  end.sort do |x,y|
    raise "Not correctly formatted" unless x.first =~ /^[a-z\-0-9]+$/i
    y.last.to_f <=> x.last.to_f
  end.collect do |l|
    l.first.downcase.gsub(/-[a-z0-9]+$/i) { |x| x.upcase }
  end

==> puts "Parser: #{@user_preferred_languages}" @user_preferred_languages rescue # Just rescue anything if the browser messed up badly. [] end

middleware.rb:

def call(env) def env.http_accept_language ==> puts "HEADER --> #{self['HTTP_ACCEPT_LANGUAGE']}" @http_accept_language ||= Parser.new(self['HTTP_ACCEPT_LANGUAGE']) end @app.call(env) end

When I force many subsequent requests from a user agent (Chrome), and I'm tailing the unicorn STDOUT I get this:

HEADER --> pt,en-US;q=0.8,en;q=0.6 Parser: ["en-US"]

HEADER --> pt,en-US;q=0.8,en;q=0.6 Parser: ["pt", "en-US", "en"]

HEADER --> pt,en-US;q=0.8,en;q=0.6 Parser: ["en-US"]

The accept header is forced to Portuguese in Chrome (you can see it in the HEADER --> log), but for some reason, the parser returns en-US sometimes.

Any ideas?

Marcelo

On Friday, December 6, 2013 at 4:12 AM, Douwe Maan wrote:

For the unicorn config, the only difference I see is that we have preload_app set to true.

— Reply to this email directly or view it on GitHub (https://github.com/iain/http_accept_language/issues/32#issuecomment-29977318).

fullofcaffeine commented 10 years ago

Ping.

DouweM commented 10 years ago

Pong. I haven't forgotten about this, although I admit it hasn't been at the top of my todo list. With a little bit of luck, I'll have time to investigate further this weekend. This time, it is marked on my calendar. Thanks for your patience.

–Douwe

On 21 jan. 2014, at 22:24, Marcelo de Moraes Serpa notifications@github.com wrote:

Ping.

— Reply to this email directly or view it on GitHub.

DouweM commented 10 years ago

@fullofcaffeine Could you try again with the latest version? I didn't notice this at first, but you're still on an old version which doesn't contain this commit: 47b02bededf87c9d9923006bff6e6006645043ed which addresses your problem specifically. Version 2.0 which contains this fix was released over 5 months ago.

I'm closing this issue for now.

k0nserv commented 9 years ago

We are still seeing this issue on version 2.0.5 using rails 4.2 and unicorn. We haven't been able to reproduce it reliably either

dgilperez commented 9 years ago

Same over here.