shlinkio / shlink

The definitive self-hosted URL shortener
https://shlink.io
MIT License
3.15k stars 253 forks source link

Base path feature malformed CLI output and lacking documentation #1402

Closed contactalexliu closed 2 years ago

contactalexliu commented 2 years ago

How Shlink is set-up

Summary

The base path feature seems bugged. Short URLs return 404 errors, the API endpoints return 404 errors, and the CLI output does not look correct (though unfortunately this last issue seems cosmetic).

Current behavior

The DEFAULT_DOMAIN is set to example.com and the BASE_PATH is set to shlink in generated-config.php, but the Short URL field output by bin/cli short-url:list is https://example.comshlink/shlink/ZJxAM instead of the expected https://example.com/shlink/ZJxAM. When trying to use the short URL https://example.com/shlink/ZJxAM, Shlink shows the generic 404 page and logs a regular_404 error in the database.

Edit 1: When BASE_PATH is set to /s, the Short URL output becomes https://example.com/s/s/ZJxAM. Changing the nginx configuration to match does not solve the issue: Shlink still shows the generic 404 page and logs a regular_404 error in the database (with the visited_url correctly logged as https://example.com/s/s/ZJxAM, suggesting the CLI output is wrong). I’ve tried setting BASE_PATH to s, /s, /s/, and leaving it empty and putting example.com/s in the DEFAULT_DOMAIN, all without luck.

Edit 2: Now things are looking weird. Even when I configure BASE_PATH to be empty (the Short URL becomes https://example.com/ZJxAM) and use nginx to rewrite the path before passing it on to openswoole so Shlink sees https://example.com/s/ZJxAM as just https://example.com/ZJxAM, I’m getting 404 errors.

Edit 3: Deleted data/cache/fastroute_cached_routes.php; solved the empty base path 404 problem in Edit 2. I will let nginx continue “lying” to Shlink for now as a workaround.

Edit 4: Deleting data/cache/fastroute_cached_routes.php was the missing magic sauce. It seems like I need to manually do this step every time I test a new BASE_PATH even though vendor/bin/shlink-installer set-option claims it has “properly updated” the configuration. This would be a really great note to add to the troubleshooting documentation, along with an example of how to set BASE_PATH so people don’t need to guess whether to use path (which doesn’t work) or /path (works) or /path/ (haven’t tested)!

Now I have confirmed that setting BASE_PATH to /shlink works, redirecting https://example.com/shlink/ZJxAM as expected. However, bin/cli short-url:list continues to return malformed Short URLs like https://example.com/shlink/shlink/ZJxAM. At least it’s confirmed the issue is cosmetic.

Expected behavior

When the DEFAULT_DOMAIN is set to example.com and the BASE_PATH is set to shlink in generated-config.php, the Short URL field output by bin/cli short-url:list should be https://example.com/shlink/ZJxAM, not https://example.comshlink/shlink/ZJxAM. When trying to use the short URL https://example.com/shlink/ZJxAM, Shlink redirects according to the configuration (301) and logs the visit normally in the database.

How to reproduce

Install Shlink from the openswoole dist release on an Ubuntu 20.04 LTS Minimal Google Compute Engine instance with nginx and mariadb, configuring the default domain as example.com and the base path as shlink.

nginx configuration ``` server { listen %ip%:%web_ssl_port% ssl http2; server_name %domain_idn% %alias_idn%; root %docroot%; index index.php index.html index.htm; access_log /var/log/nginx/domains/%domain%.log combined; access_log /var/log/nginx/domains/%domain%.bytes bytes; error_log /var/log/nginx/domains/%domain%.error.log error; ssl_certificate %ssl_pem%; ssl_certificate_key %ssl_key%; ssl_stapling on; ssl_stapling_verify on; include %home%/%user%/conf/web/%domain%/nginx.hsts.conf*; location = /favicon.ico { log_not_found off; access_log off; } location = /robots.txt { allow all; log_not_found off; access_log off; } location ~ /\.(?!well-known\/) { deny all; return 404; } location / { try_files $uri $uri/ /index.php?$args; location ~* ^.+\.(ogg|ogv|svg|svgz|swf|eot|otf|woff|woff2|mov|mp3|mp4|webm|flv|ttf|rss|atom|jpg|jpeg|gif|png|webp|ico|bmp|mid|midi|wav|rtf|css|js|jar)$ { expires 30d; fastcgi_hide_header "Set-Cookie"; } location ~* /(?:uploads|files)/.*.php$ { deny all; return 404; } location ~ [^/]\.php(/|$) { fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; try_files $uri =404; fastcgi_pass %backend_lsnr%; fastcgi_index index.php; include /etc/nginx/fastcgi_params; include %home%/%user%/conf/web/%domain%/nginx.fastcgi_cache.conf*; if ($request_uri ~* "/wp-admin/|wp-.*.php|xmlrpc.php|index.php|/store.*|/cart.*|/my-account.*|/checkout.*") { set $no_cache 1; } if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in|woocommerce_items_in_cart|woocommerce_cart_hash|PHPSESSID") { set $no_cache 1; } } } location /error/ { alias %home%/%user%/web/%domain%/document_errors/; } location /vstats/ { alias %home%/%user%/web/%domain%/stats/; include %home%/%user%/web/%domain%/stats/auth.conf*; } location ^~ /shlink/ { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://localhost:8080; proxy_read_timeout 90s; } proxy_hide_header Upgrade; include /etc/nginx/conf.d/phpmyadmin.inc*; include /etc/nginx/conf.d/phppgadmin.inc*; include %home%/%user%/conf/web/%domain%/nginx.ssl.conf_*; } ```
acelaya commented 2 years ago

The base URL needs to include the leading bar, so in your case it should be /shlink, not shlink.

I'll try to improve the documentation to make it clear.

Edit 4: Deleting data/cache/fastroute_cached_routes.php was the missing magic sauce

This one is a bug. This particular option affects routes, which have a separated cached config. I missed this use case.

I'll get it fixed.

However, bin/cli short-url:list continues to return malformed Short URLs like https://example.com/shlink/shlink/ZJxAM.

I'll investigate this one.

acelaya commented 2 years ago

I have just fixed the missing deletion of the fastroute config cache, and the cosmetic duplicated base path. Both fixes will be included in Shlink 3.1.0

I will update the documentation about the base path next.