I've set up a dynamic link in the web console, https://mysite.example.com/foo/bar
It deep links to https://mysite.example.com?campaign=123
At least, that's what it shows it deep linking to in the console. In practice it's actually deep linking me to https://mysite.example.com/?campaign=123, note the trailing slash.
It's not the end of the world, but is there any way to change this behavior? Or is it just a bug?
Ah, turns out that adding the "trailing slash" before the query params is the correct syntax, as pointed out here. According to RFC1738 3.3:
An HTTP URL takes the form:
http://<host>:<port>/<path>?<searchpart>
where <host> and <port> are as described in Section 3.1. If :<port>
is omitted, the port defaults to 80. No user name or password is
allowed. <path> is an HTTP selector, and <searchpart> is a query
string. The <path> is optional, as is the <searchpart> and its
preceding "?". If neither <path> nor <searchpart> is present, the "/"
may also be omitted.
Related
I need help in rewriting the URL in nginx configuration which should work as below :
/products/#details to /produce/#items
but it is not working as # is creating a problem.
Note : # in the URL denotes the page section
e.g. www.test.com/products/#details should get redirected to www.test.com/produce/#items
This is impossible using nginx because browsers don't send hashtags (#details) to servers. So you cannot rewrite in nginx or any other web servers.
In other words, hashtags is available to the browser only, so you have to deal it with Javascript. The server can not read it.
https://www.rfc-editor.org/rfc/rfc2396#section-4
When a URI reference is used to perform a retrieval action on the identified resource, the optional fragment identifier, separated from the URI by a crosshatch ("#") character, consists of additional reference information to be interpreted by the user agent after the retrieval action has been successfully completed. As such, it is not part of a URI, but is often used in conjunction with a URI.
There is no way to do this rewrite. The # and everything that precedes it will not be sent to the server, it is completely handled on the client side.
I'm using http.FileServer in Go to serve some static file into a directory.
This is how I map it using mux as a router:
r.PathPrefix("/download").Handler(http.StripPrefix("/download", http.FileServer(http.Dir(dirPath)))).Methods("GET")
where dirPath is an absolute path of a directory in my file system.
Now it seems to work fine when asking the directory listing with localhost:8080/download, because it returns a page like this
<pre>
a.xml
b.zip
</pre>
Unfortunately the links are broken because I expect them to be mapped, for example to localhost:8080/download/a.xml , while file server maps them to localhost:8080/a.xml.
How can I make my directory listing keep the /download path prefix in links?
The problem is the pattern you register you handler with: "/download".
There are 2 problems with it:
The generated URLs are wrong because the handler returned by the http.FileServer() function generates relative URLs to files and subfolders; relative to the root folder passed to http.FileServer(), and if your page is available under the path /download, a relative URL like href="a.xml" will be resolved to /a.xml, and not to /download/a.xml.
Even if the URLs would be good, the files would not be served as the requests would not get routed to your handled (to the file server handler). You must add a trailing slash, as "/download" only matches this single path, and not all paths starting with it. Add a trailing slash: "/download/" and it will match the rooted subtree /download/*.
So the solution is:
r.PathPrefix("/download/").Handler(
http.StripPrefix("/download", http.FileServer(http.Dir(dirPath))),
).Methods("GET")
This is documented at http.ServeMux:
Patterns name fixed, rooted paths, like "/favicon.ico", or rooted subtrees, like "/images/" (note the trailing slash).
Note that even though we're now using the "/download/" registered path, users are not required to type the trailing slash in the browser, as leaving that out the server will send a redirect to the path that ends with a trailing slash. This will happen automatically. This is also documented at http.ServeMux:
If a subtree has been registered and a request is received naming the subtree root without its trailing slash, ServeMux redirects that request to the subtree root (adding the trailing slash). This behavior can be overridden with a separate registration for the path without the trailing slash. For example, registering "/images/" causes ServeMux to redirect a request for "/images" to "/images/", unless "/images" has been registered separately.
Read related question: Go web server is automatically redirecting POST requests
Here's a simple file server app using only the standard library:
http.Handle("/dl/",
http.StripPrefix("/dl", http.FileServer(http.Dir("/home/bob/Downloads"))),
)
panic(http.ListenAndServe("localhost:8080", nil))
I have a very simple Go server code setup with mux and when I use curl with GET request params (localhost:8080/suggestions/?locale=en), I get 301 status code (Move permanently). But when there's no get parameters, it's working just fine.
func main() {
router := mux.NewRouter().StrictSlash(true)
router.HandleFunc("/suggestions", handleSuggestions).Methods("GET")
log.Fatal(http.ListenAndServe("localhost:8080", router))
}
Can somebody shed me a light on this.Thanks
go doc mux.StrictSlash states:
func (r *Router) StrictSlash(value bool) *Router
StrictSlash defines the trailing slash behavior for new routes. The initial
value is false.
When true, if the route path is "/path/", accessing "/path" will redirect to
the former and vice versa. In other words, your application will always see
the path as specified in the route.
When false, if the route path is "/path", accessing "/path/" will not match
this route and vice versa.
Special case: when a route sets a path prefix using the PathPrefix() method,
strict slash is ignored for that route because the redirect behavior can't
be determined from a prefix alone. However, any subrouters created from that
route inherit the original StrictSlash setting.
So to avoid the redirects you can either mux.NewRouter().StrictSlash(false) which is equivalent to mux.NewRouter() or use a URL with a trailing slash i.e. router.HandleFunc("/suggestions/", handleSuggestions).Methods("GET")
That's simply because you registered the path /suggestions (note: there is no trailing slash), and you call the URL localhost:8080/suggestions/?locale=en (there is a trailing slash after /suggestions).
You router detects that there's a registered path which would match the requested path without the trailing slash (based on your Router.StrictSlash() policy), so it sends a redirect which when followed would lead you to a valid, registered path.
Simply use a URL without trailing slash after suggestions:
localhost:8080/suggestions?locale=en
I have two URLs:
http://example.com/foo
and
http://example.com/foo/
Are they different URLs or the same? The same question is and about FTP protocol (ftp://example.com/foo[/])
In the URI standard, the relevant section is Normalization and Comparison:
After doing a simple string comparison, these URIs are not equivalent.
After applying syntax-based normalization, these URIs are not equivalent.
For scheme-based normalization, you have to refer to the specifications of the http/https and ftp URI schemes, and check if any scheme-specific rules are defined:
For http/https, these rules are in the section http and https URI Normalization and Comparison, and there don’t seem to be any for your case.
For ftp, there don’t seem to be defined any normalization/comparison rules.
For protocol-based normalization, you have to take something like redirects into account (in case of http).
tl;dr: The URIs are not equivalent.
Note that this is not the case for an empty path in HTTP(S) URIs, as the section linked above defines:
[…] an empty path component is equivalent to an absolute path of "/" […]
So the following URIs are equivalent:
http://example.com/
http://example.com
By the way, for the protocol-based normalization, the standard gives your case as an example:
[…] For example, if they observe that a URI such as
http://example.com/data
redirects to a URI differing only in the trailing slash
http://example.com/data/
they will likely regard the two as equivalent in the future. […]
Yes, they are different resource.
It's particularly important in HTML.
If you have a relative link bar (blah):
In the https://www.example.com/foo, that link resolves to the https://www.example.com/bar
While in the https://www.example.com/foo/, that link resolves to https://www.example.com/foo/bar
But HTTP servers will usually redirect the https://www.example.com/foo to the https://www.example.com/foo/, when foo is a folder, to avoid this confusion.
With the FTP protocol, it's probably client-specific, as the FTP protocol itself does not work with URLs.
So it depends on the FTP client how it behaves, if you use the https://www.example.com/foo, when the foo is actually a folder. The "FTP client" in this case typically means a web browser, as these work with URLs. Dedicated FTP clients usually do not work with URLs either.
As far as I understand, an URL consists of the folowing fields:
Protocol (http, https, ftp, etc.)
User name
User Password
Host address (an IP address or a DNS FQDN)
Port (which can be implied)
Path to a document inside the server documents root
Set of arguments and values
Document part (#)
as
protocol://user:password#host:port/path/document?arg1=val1&arg2=val2#part
But I've just met an example of using "http://" inside the path part: there is a redirection service (showing ads and paying money for traffic you route through it) which just adds a target URL (in full form, with "http://") to its own. Is it considered ok from standards point of view? Doesn't it break anything? Normally I'd never expect to meet "//" double slash, a colon or a "#" inside a valid URL but on the places they are in the example above.
No, it is not okay from a standards perspective.
Per Section 3.3 Path Component in RFC-2396, path cannot contain the following characters - "/", ";", "=", and "?"
Usually, browsers encode such malformed URIs before making the http request, which is why it works in practice.