I have a terrible confusion concerning http.FileServer and slashes.
I need to serve a script to a html page. In the directory I'm working I have the page index.html and I have a static directory with myscript.js inside of it.
First question: is it correct to write
<script src="/static/myscript.js"></script>
? I have also seen src="static/myscript.js" and I don't know if there is a reason for using one or the other (but I guess it influences the handler we have to write on the server).
Let's suppose we settle for the first version. Second question: on the server side, I want to register the handler for directory static. Inspired by this example, I do:
fs := http.FileServer(http.Dir("./static"))
http.Handle("/static", http.StripPrefix("/static", fs))
but I get a 404. However, if I use:
fs := http.FileServer(http.Dir("./static"))
http.Handle("/static/", http.StripPrefix("/static/", fs))
with the ending slashes, it works fine!
I'm really new to web servers, so I would appreciate any explanation that includes what are the actual addresses passed around by functions. For example, I don't know (and I can't figure it out from the net/http documentation ) what is the address that is passed to the handler when serving a /static request. I guess it's /static/myscript.js since we are using http.StripPrefix but I have no actual way of proving it.
http.Handle("/static", http.StripPrefix("/static", fs)) registers a fixed name pattern.
http.Handle("/static/", http.StripPrefix("/static/", fs)) registers a rooted subtree pattern.
The former matches only requests where URL.path = "/static". The latter matches every path that starts with "/static/". The 404 indicates that it could not match any pattern for the given request, not that the requested file wasn't found. (It does not even get to execute the FileServer's handler!)
And to answer your first question:
<script src="/static/myscript.js"></script>
URLs starting with a slash / are absolute. That means it does not matter on what page you are, it will always append to the domain name e.g. example.com/some/page + /static/myscript.js = example.com/static/myscript.js
<script src="static/myscript.js"></script>
Is a relative path. That means it will be appended to URL of the currently visited page e.g. example.com/some/page + static/myscript.js = example.com/some/page/static/myscript.js
Related
I've got a Ratpack application and I'm trying to configure an endpoint for GET requests which delegates to a handler based on a prefix. However, my URL path may contain multiple slashes, which I'd want to capture and use in my handler.
Example:
Given the requests http://localhost:8080/myEndpoint/foo/bar/ and http://localhost:8080/myEndpoint/baz/qux/fred/, I'd like to delegate to my handler MyEndpointHandler in both cases since the request paths are prefixed by myEndpoint. Inside MyEndpointHandler, I'd need to retrieve /foo/bar and /baz/qux/fred/ respectively, since these are the remaining parts of the path after the /myEndpoint prefix.
My original thinking was to do something like:
chain.path("myEndpoint/:restOfPath?", new MyEndpointHandler());
However this only seems to work for one slash (i.e. a request to http://localhost:8080/myEndpoint/foo is fine and I have access to /foo, but a request to http://localhost:8080/myEndpoint/foo/bar returns a 404).
I have also tried:
chain.prefix("myEndpoint", c1 -> c1.path(new MyEndpointHandler()));
However this returned a 404 for all requests regardless of the path after /myEndpoint.
Looking at the docs, https://ratpack.io/manual/current/api/ratpack/core/path/PathBinding.html#getPastBinding() seems like exactly what I need to be able to get the /foo/bar part of these requests, but I'm struggling to bind my handler to the chain in the right way to be able to access this "past binding".
Thanks in advance for the help!
When I use
http.HandleFunc("/", serveRest) //serveRest is the method to handle request
http.ListenAndServe("localhost:4000", nil)
It will accept all request starting with "/". How do I restrict it to serve only "localhost:4000" instead of every address like "localhost:4000/*"?
And can you guys suggest me a good tutorial for Go?
The URL pattern to which you register your handlers is documented in the http.ServeMux type:
Patterns name fixed, rooted paths, like "/favicon.ico", or rooted subtrees, like "/images/" (note the trailing slash). Longer patterns take precedence over shorter ones, so that if there are handlers registered for both "/images/" and "/images/thumbnails/", the latter handler will be called for paths beginning "/images/thumbnails/" and the former will receive requests for any other paths in the "/images/" subtree.
Note that since a pattern ending in a slash names a rooted subtree, the pattern "/" matches all paths not matched by other registered patterns, not just the URL with Path == "/".
So unfortunately there is no pattern which matches only the root ("/").
But you can easily check this in your handler, and do whatever you want to if the request path is not the root:
func serveRest(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
w.Write([]byte("Not root!"))
return
}
w.Write([]byte("Hi, this is the root!"))
}
If you want to return HTTP 404 Not found error for non-roots:
func serveRest(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
http.NotFound(w, r)
return
}
w.Write([]byte("Hi!"))
}
And Go tutorial: https://tour.golang.org/
Also check out the Go tag info here on SO, it has a section Go Tutorials.
You could check out
https://github.com/julienschmidt/httprouter
Per its readme:
Only explicit matches: With other routers, like http.ServeMux, a
requested URL path could match multiple patterns. Therefore they have
some awkward pattern priority rules, like longest match or first
registered, first matched. By design of this router, a request can
only match exactly one or no route. As a result, there are also no
unintended matches, which makes it great for SEO and improves the user
experience.
Here is some good video content to get started in Go.
What I'm trying to do for a PoC and is to add a href to web pages coming from a dynamic backend server. Adding the href is easy using "subs_filter", but I need to use information embedded within the response to construct the href.
Is it possible to use LUA to process the response from proxy_pass, modify it and return to requester (client)?
Any and all suggestions welcome.
Below is the code I'm looking at, now I understand Lua better and how nginx uses it I see that 'body_filter' is the correct way to. However the code seems simple enough but i can't get the regex to work.
Further background, I'm trying to parse the returned proxy_pass response, parse it for a start and end time, then construct a JS script url placed into the head.
Example response that I want to regex against.
Informações Adicionais
Horário de início: 08H50
Horário de término: 09H14
The code from within the 'location {}'
body_filter_by_lua '
-- my regex which is validate but doesn't seem to be within LUAJIT
--local from, to, err = ngx.re.find(ngx.arg[1], "(.início: *\d{2}H\d{2})", "jo")
local from, to, err = ngx.re.find(ngx.arg[1], "início", "jo")
replacestr = string.sub(ngx.arg[1], to, 5)
replaceme = "<script></script></head>"
ngx.arg[1] = ngx.re.sub(ngx.arg[1],"</head>", replaceme)
';
Changing "início" to "head" for example works, so I'm assuming it is the accented char but I'm unable to find confirmation of this.
Changing "início" to "\d{2}H\d{2}" fails, with "body_filter_by_lua:5: invalid escape sequence near '"'"
I discovered what I mentioned in the comments regarding 'nix.header.content_length' and importantly nginx and lua require double escaping see: lua-nginx-module special pcre sequences for more details.
The accented chars needed the flag 'u' adding to 'jo' of the 'ngx.re.find'
user "body_filter_by_lua_file"
Equivalent to body_filter_by_lua, except that the file specified by contains the Lua code, or, as from the v0.5.0rc32 release, the Lua/LuaJIT bytecode to be executed.
When a relative path like foo/bar.lua is given, they will be turned into the absolute path relative to the server prefix path determined by the -p PATH command-line option while starting the Nginx server.
This directive was first introduced in the v0.5.0rc32 release.
I've been reading about url's. Absolute, scheme relative, root relative, location relative.
I still don't understand difference between these two:
//domain.com/index.html - scheme relative
domain.com/index.html - ?
.
Question 1:
Correct me if I am wrong //domain.com/index.html will resolve to absolute url like this:
http://domain.com/index.html
https://domain.com/index.html
ftp://domain.com/index.html
file://domain.com/index.html -- if in email
And browsers will act differently: ie6 doesn't support, ie7,8 will fetch data twice(http https).
.
Question 2:
How will domain.com/index.html resolve? Same as scheme relative url in Q1? Or is it something else?
.
Question 3:
Is there any difference between these url's, what is it and why?
//www.domain.com/index.html
www.domain.com/index.html
.
Question 4:
How will //www.domain.com/index.html resolve?
.
Question 5:
How will www.domain.com/index.html resolve?
It's very easy, looking at URLs like these, to apply your human knowledge of what they probably mean, rather than the much simpler rules implemented by software like web browsers.
The simplest type of URL (or more accurately URI, since some schemes don't represent a Location, only an Identifier) is absolute; it starts with a scheme, then a colon, and no context is needed to resolve it. Examples:
http://example.com
https://www.example.com/foo/bar.baz
http://127.0.0.1:8001
mailto:someone#example.com
data:text/plain,test
urn:example
Then there are location-relative URLs; that is, anything without a scheme, and without a leading slash. These replace everything after the slash in the current context, but leave the rest in place. If the current context is http://example.com/foo/bar.baz, you could have relative URLs like so:
bob.baz -> http://example.com/foo/bob.baz
thing/widget.gizmo -> http://example.com/foo/thing/widget.gizmo
example.com/page -> http://example.com/foo/example.com/page
Note that that last example looks like a domain name at first glance, but is actually exactly the same as all the other relative URLs.
Root-relative URLs, with a leading slash, are similar, but instead of deleting after the last slash, they delete after the first. Given the same context, the previous examples become:
/bob.baz -> http://example.com/bob.baz
/thing/widget.gizmo -> http://example.com/thing/widget.gizmo
/example.com/page -> http://example.com/example.com/page
A root-relative URL could also contain a colon, because the leading slash cannot be part of a scheme prefix:
/foo:bar -> http://example.com/foo:bar
/urn:example -> http://example.com/urn:example
Finally, there are scheme-relative URLs, with two leading slashes. They replace everything after the original double-slash, so keep only the scheme:
if the context is http://example.com/foo/bar then //example.org/bob means http://example.org/bob
if the context is https://example.com/foo/bar then //example.org/bob means https://example.org/bob
if the context is http://example.com, then //foo.bar means http://foo.bar
Note that that last example doesn't look like a domain name to us, but it still follows the same rules. Whether a URL is actually useful is not taken into account when parsing any of the relative forms.
Conventions like "begins with www." and "ends with .com" cannot be relied on, and are not used to determine if a URL is relative or not, so all you need do to answer all your questions is follow this simple set of rules:
If there are two leading slashes, it is scheme relative
If there is one leading slash, it is root relative
If there is no leading slash, but there is a colon, assume it is an absolute URI
If there is no leading slash, and no colon, it is location relative
They are very different. The second one is a relative reference to a path "domain.com/index.html".
WRT "domain.com" vs "www.domain.com": these are simply different host names (or path names in the second variant)
I just learned from a colleague that omitting the "http | https" part of a URL in a link will make that URL use whatever scheme the page it's on uses.
So for example, if my page is accessed at http://www.example.com and I have a link (notice the '//' at the front):
Google
That link will go to http://www.google.com.
But if I access the page at https://www.example.com with the same link, it will go to https://www.google.com
I wanted to look online for more information about this, but I'm having trouble thinking of a good search phrase. If I search for "URLs without HTTP" the pages returned are about urls with this form: "www.example.com", which is not what I'm looking for.
Would you call that a schemeless URL? A protocol-less URL?
Does this work in all browsers? I tested it in FF and IE 8 and it worked in both. Is this part of a standard, or should I test more browsers?
Protocol relative URL
You may receive unusual security warnings in some browsers.
See also, Wikipedia Protocol-relative URLs for a brief definition.
At one time, it was recommended; but going forward, it should be avoided.
See also the Stack Overflow question Why use protocol-relative URLs at all?.
It is called network-path reference (the part that is missing is called scheme or protocol) defined in RFC3986 Section 4.2
4.2 Relative Reference
A relative reference takes advantage of the hierarchical syntax
(Section 1.2.3) to express a URI reference relative to the name space
of another hierarchical URI.
relative-ref = relative-part [ "?" query ] [ "#" fragment ]
relative-part = "//" authority path-abempty
/ path-absolute
/ path-noscheme
/ path-empty
The URI referred to by a relative reference, also known as the target URI, is obtained by applying the reference resolution
algorithm of Section 5.
A relative reference that begins with two slash characters is
termed a network-path reference (emphasis mine); such references are rarely used.
A relative reference that begins with a single slash character is termed an absolute-path reference. A relative reference that does not begin with a slash character is termed a relative-path reference.
A path segment that contains a colon character (e.g., "this:that") cannot be used as the first segment of a relative-path reference, as it would be mistaken for a scheme name. Such a segment must be preceded by a dot-segment (e.g., "./this:that") to make a relative- path reference.