Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Language redirection is too slow #478

Closed
i-rme opened this Issue Jul 23, 2014 · 20 comments

Comments

Projects
None yet
4 participants
Contributor

i-rme commented Jul 23, 2014

I am from Spain, when I access bitcoin.org I see the english version for 1 second and then I am redirected to https://bitcoin.org/es/

This redirection is done with javascript but it can be faster.

Contributor

saivann commented Jul 24, 2014

@i-rme At least I can drop the 200ms delay before javascript actually redirects the page (this was previously used to prevent bugs in browsers which weren't loading fonts correctly when redirecting too fast, but this may not be an issue anymore).

Otherwise the alternative option is to not detect the language and just redirect bitcoin.org/ to bitcoin.org/en/ (bitcoin.org doesn't use server-side scripting to do dynamic redirect). To me, this (still short) delay was worth the feature, but I'm OK too if other people think this is better.

Contributor

harding commented Jul 24, 2014

@saivann this isn't my specialty, but might it be possible to use content negotiation? This doesn't seem like server-side scripting to me, although I suppose it does add complexity.

Contributor

saivann commented Jul 24, 2014

@harding Thanks! I didn't know this could be supported right from the server configuration. I'll test this with nginx when I have a few minutes for it.

Contributor

saivann commented Jul 24, 2014

Well, I've just found that it works, and doesn't appear to slow down the server. The only downside is new languages must be added by hand in the configuration file.. Is the 1s delay worth it?

Contributor

harding commented Jul 24, 2014

@saivann do the languages need to be added by hand to the site configuration file, or can they be managed through an .htaccess-like file we keep in the repository? (That way the .htaccess update can be part of the new-language merge.)

Contributor

saivann commented Jul 25, 2014

@harding I don't think we can use .htaccess (we use nginx with as few modules as possible to make it fast & safe, as much as possible). Also, I guess this could allow however gains access to the repository to make potentially dangerous change to the server configuration.

But in any case, in the worse case scenario where it's hard to contact a person with access to the server, I guess only new languages wouldn't have auto-detect, so entering them by hands in the server config still seems pretty reasonable to me.

Contributor

harding commented Jul 25, 2014

@saivann manually adding the languages to the server config sounds reasonable to me. Thanks!

@saivann saivann closed this in 6458c16 Jul 26, 2014

Contributor

saivann commented Jul 26, 2014

@i-rme @harding This should be better now!

Contributor

schildbach commented Jul 26, 2014

Is it possible that this change causes the page being switched to German by default, even though my system language is English?

Contributor

harding commented Jul 26, 2014

@schildbach I get English on Bitcoin.org. This CGI script sends prints your browser's http headers. I get:

Accept-Language     en-US,en;q=0.5
Contributor

saivann commented Jul 26, 2014

Thanks for providing testing tools @harding !

@schildbach So far the website always picked the first language sent in the Accept-Language header by the browser in my case. It is possible though that the language preferences varies between the browser and system-wide preferences.

Contributor

schildbach commented Jul 26, 2014

I get "en,de;q=0.5" so it should pick English first.

@saivann saivann reopened this Jul 26, 2014

Contributor

saivann commented Jul 26, 2014

@schildbach @harding Then this configuration might not work exactly how I expect it to work, I've re-opened the issue, here's the relevant nginx configuration in case someone wants to do some tests:

map $http_accept_language $lang {
    default en;
    ~es es;
    ~fr fr;
    ~ar ar;
    ~bg bg;
    ~da da;
    ~de de;
    ~en en;
    ~es es;
    ~fa fa;
    ~fr fr;
    ~hi hi;
    ~hu hu;
    ~id id;
    ~it it;
    ~ja ja;
    ~ko ko;
    ~nl nl;
    ~pl pl;
    ~pt_BR pt_BR;
    ~ro ro;
    ~ru ru;
    ~sl sl;
    ~sv sv;
    ~tr tr;
    ~zh_CN zh_CN; 
    ~zh_TW zh_TW;
}

server {
    server_name bitcoin.org;
    location = / {
        return 302 /$lang/;
    }
}
Contributor

harding commented Jul 26, 2014

@saivann I can confirm @schildbach's problem when I use the same language string he has.

Is en in the list of languages to match, or do you just have it set as the defualt?

Contributor

saivann commented Jul 27, 2014

@harding Yes (I've updated the code sample), although I would expect it to choose "de" before "en". My browser sends fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4 and the website rightfully redirects to /fr/

Contributor

harding commented Jul 27, 2014

@saivann I installed nginx locally and played with it. I looks like you just need to prefix "^" to the regex. E.g.:

~^de de;
~^en en;
~^es es;

Doing that for each entry resolved @schildbach's problem. However, it introduces a new problem: if we don't support the user's preferred language, they get the default (en). So I just duplicated the list you have above which matches alphabetically. That makes the combined logic:

  1. Go to the user's first-listed language (if supported). If not, continue.
  2. Go to one of the user's preferred languages (if supported) in arbitrary order. If not supported, continue.
  3. Go to the English page.

Although imperfect, that seems reasonable to me. Here's the complete map I'm using. (Note: your map had duplicate entries for fr and es; I removed those and put the list in us-utf8 alphabetic order. All the other entries should still be there.)

map $http_accept_language $lang {
    default en;
    ~^ar ar;
    ~^bg bg;
    ~^da da;
    ~^de de;
    ~^en en;
    ~^es es;
    ~^fa fa;
    ~^fr fr;
    ~^hi hi;
    ~^hu hu;
    ~^id id;
    ~^it it;
    ~^ja ja;
    ~^ko ko;
    ~^nl nl;
    ~^pl pl;
    ~^pt_BR pt_BR;
    ~^ro ro;
    ~^ru ru;
    ~^sl sl;
    ~^sv sv;
    ~^tr tr;
    ~^zh_CN zh_CN; 
    ~^zh_TW zh_TW;

    ~ar ar;
    ~bg bg;
    ~da da;
    ~de de;
    ~en en;
    ~es es;
    ~fa fa;
    ~fr fr;
    ~hi hi;
    ~hu hu;
    ~id id;
    ~it it;
    ~ja ja;
    ~ko ko;
    ~nl nl;
    ~pl pl;
    ~pt_BR pt_BR;
    ~ro ro;
    ~ru ru;
    ~sl sl;
    ~sv sv;
    ~tr tr;
    ~zh_CN zh_CN; 
    ~zh_TW zh_TW;
}
Contributor

saivann commented Jul 27, 2014

@harding Make sense, thanks! I have just updated the server configuration. Does it work better now?

Contributor

harding commented Jul 27, 2014

@saivann works perfect for me using the settings @schildbach reported. I suggest we leave this issue open for a day or so to give him a chance to test and report back.

Contributor

schildbach commented Jul 27, 2014

Thanks, I now get the English version again.
However, I wonder why this standard usecase takes so much effort. Nginx is usually known for providing just the right defaults.

Contributor

harding commented Jul 27, 2014

@schildbach I wondered that also! When I searched last night, I found an unofficial add-on module which does the right thing. I haven't tested it, but it's only 140 lines of C, so I did skim it and it seems reasonable if @saivann wants to add a third-party module. (I got the impression he didn't.)

Closing this issue as the bug has been resolved. Thanks for reporting!

@harding harding closed this Jul 27, 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment