librespeed / speedtest-go

Go backend for LibreSpeed
GNU Lesser General Public License v3.0
700 stars 151 forks source link

Allow custom path prefix #8

Closed mildis closed 3 years ago

mildis commented 3 years ago

This would allow speedtest-go to answer as a sub-path instead of its own subdomain
(that is www.example.com/speedtest instead of speedtest.example.com)

Allowing this directly in the backend would avoid rewriting to append on an upstream reverse-proxy and would benefit every resources served.

maddie commented 3 years ago

You can still easily map speedtest-go under a sub-path with reverse-proxy. I don't think it's best to implement this in the backend.

nginx example:

server {
    listen 80;
    listen [::]:80;
    server_name example.com;

    location / { # your website
        root /var/www;
                 try_files index.html =404;
    }

    location /speedtest/ { # speed test
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header X-Forwarded-Server $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://127.0.0.1:8989/;
    }
}
AlphaJack commented 3 years ago

@maddie unfortunately, this would not work. Nginx gets flooded with 404 requests and speedtest results drop as low as 0.8Mb/s.

Page is https://example.com/speedtest/, forwarded to http://127.0.0.1:8989/ with your directives. librespeed server is started as systemd service, and tests work fine via direct access to LAN IP and port 8989.

Nginx access logs:

client - - [date] "GET /speedtest/ HTTP/2.0" 200 3397 "-" "useragent"
client - - [date] "GET /speedtest/speedtest.js HTTP/2.0" 200 4473 "-" useragent"
client - - [date] "GET /favicon.ico HTTP/2.0" 200 3397 "-" "useragent"
client - - [date] "GET /speedtest/speedtest_worker.js?r=0.49586569694446636 HTTP/2.0" 200 7202 "-" "useragent"
client - - [date] "GET /getIP?isp=true&distance=km&r=0.39082717761835817 HTTP/2.0" 404 340 "-" "useragent"
client - - [date] "GET /empty?r=0.9634918182895288 HTTP/2.0" 404 340 "-" "useragent"
[...] x10
client - - [date] "GET /garbage?r=0.25764575583950733&ckSize=100 HTTP/2.0" 404 340 "-" "useragent"
[...] x2000

Librespeed logs (systemd):

date host librespeed[17607]: 2020/10/03 20:54:56 "GET http://example.com/ HTTP/1.0" from client - 200 10585B in 2.165525ms
date host librespeed[17607]: 2020/10/03 20:54:56 "GET http://example.com/speedtest.js HTTP/1.0" from client - 200 16996B in 2.080524ms
date host librespeed[17607]: 2020/10/03 20:54:58 "GET http://example.com/speedtest_worker.js?r=0.49586569694446636 HTTP/1.0" from client - 200 27965B in 2.088597ms
date host librespeed[17607]: 2020/10/03 20:55:13 "GET http://example.com/ HTTP/1.0" from client - 200 10585B in 2.645057ms
date host librespeed[17607]: 2020/10/03 20:55:13 "GET http://example.com/speedtest.js HTTP/1.0" from client - 200 16996B in 1.777556ms
date host librespeed[17607]: 2020/10/03 21:07:43 "GET http://example.com/speedtest_worker.js?r=0.18126294744703864 HTTP/1.0" from client - 200 27965B in 2.124795ms

I believe this feature should be implemented in the backend and added as an option in settings.toml. Some Go webapps like Navidrome use this system.

maddie commented 3 years ago

Then why I'm running this set up just fine? Check your Nginx config again.

AlphaJack commented 3 years ago

No luck even with a separate server, sourced by the include nginx-librespeed.conf directive at "http" level in nginx.conf.

Correct speedtest result, obtained via direct access at http://192.168.1.2:8989 is real

In the previous post, Nginx URL was https://example.com/speedtest/ . Keep in mind that server only has Fast Ethernet capability, this is the result (custom 404 error page): fake1

URL in this new case is http://192.168.1.2:81/speedtest/ and the Nginx server has no additional configs. This is the result (default 404 error page): fake2

The server configuration is similar to yours: nginx-librespeed.conf

server {
 listen 81;

 location / {
  root /usr/share/nginx/html;
  index index.html;
  try_files index.html =404;
 }

 location /speedtest/ {
  proxy_set_header Host $http_host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-Host $http_host;
  proxy_set_header X-Forwarded-Server $http_host;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;
  proxy_pass http://127.0.0.1:8989/;
 }
}

I also tried to symlink the "assets" dir to "$root/speedtest/assets", but it didn't change anything because everything under /speedtest/ is handled to librespeed

maddie commented 3 years ago

I see the problem now. Your log shows the assets are accessed under / instead of /speedtest.

Check your HTML file, see the paths are relative paths (not starting with /, e.g. empty.php instead of /empty.php).

AlphaJack commented 3 years ago

Thank you, I got it working by replacing

var server = {
        name: "demo",
        server:window.location.protocol + "//" + window.location.host,
        dlURL:"garbage",
        ulURL:"empty",
        pingURL:"empty",
        getIpURL:"getIP",
};

with

var server = {
        name: "demo",
        server:window.location.protocol + "//" + window.location.host,
        dlURL:"speedtest/garbage",
        ulURL:"speedtest/empty",
        pingURL:"speedtest/empty",
        getIpURL:"speedtest/getIP",
};

in the index.html file