-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gateway: attempt to resolve hostname to ipfs path #726
Conversation
Unless im misunderstanding the change, this was already possible through ipns. but maybe im missing something, the gateway isnt a super familiar part of the codebase for me. |
Ah, wait, i got it, if you make (for example) |
@kevinwallace thanks for the PR! I'll get to reviewing this in more detail in the next few hrs. I'll add a couple comments now. |
@@ -12,8 +12,7 @@ func GatewayOption(writable bool) ServeOption { | |||
if err != nil { | |||
return err | |||
} | |||
mux.Handle("/ipfs/", gateway) | |||
mux.Handle("/ipns/", gateway) | |||
mux.Handle("/", gateway) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here, I think we want to keep using the muxer. We're going towards:
mux.Handle("/ipfs/", ipfsHandler)
mux.Handle("/ipns/", ipnsHandler) // ipnsHandler is sort of middleware that uses ipfsHandler
mux.Handle("/", base)
where baseHandler
can be mux between:
base.Handle("/webui", redirectToWebUIHandler)
base.Handle("/", rootHandler) // give the user some information about IPFS + links (e.g. to WebUI, ipfs.io, etc)
// base should handle 404s with custom error pages.
cc @mappum
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. In that case, this is probably best expressed as a pre-muxer request processing stage, which tries to resolve req.Host
as an IPNS name, and if successful, rewrites the request path to /ipfs/<resolved name><path>
and allows the muxer/gateway to process the rewritten request. I'd need to extend ServeOption
to support registering such a stage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may be doable by having two muxers:
- one mounted on the server at
"/"
. performs the check, possibly rewriting the path, and then calls the other: - one which handles everything else.
PTAL -- I've updated my approach per @jbenet's comments. A |
Thanks @kevinwallace -- beautiful, this LGTM. On tests, maybe the right way is to test it in Go with a mock If we were to go for a well-known subdomain, we could do something like |
Lets go for that last addition and then merge this? |
@jbenet Sounds good. Are you imagining something that tests overall gateway functionality end-to-end (including IPNS hostnames), or just the request rewriting option in isolation from the gateway? About the well-known subdomain: I was thinking about what this would look like if it were done DNS-SD style (which uses names like
|
I'm imagining testing with http requests to the gateway (in go), with a mocked naming system. Yeah, i need to read the spec closely too. Wish |
Just as a heads-up, I'm likely going to be preoccupied with other things for the next couple of days, so I'm not sure I'll be able to get to this until this weekend. It's not forgotten, though! |
@kevinwallace, no worries! you wont be forgotten |
Each option now additionally returns the mux to be used by future options. If every options returns the mux it was passed, the current behavior is unchanged. However, if the option returns an a new mux, it can mediate requests to handlers provided by future options: return func(n *core.IpfsNode, mux *http.ServeMux) (*http.ServeMux, error) { childMux := http.NewServeMux() mux.Handle("/", handlerThatDelegatesToChildMux) return childMux, nil } License: MIT Signed-off-by: Kevin Wallace <[email protected]>
This allows someone to host a static site by pointing a TXT record at their content in IPFS, and a CNAME record at an IPFS gateway. Note that such a setup technically violates RFC1912 (section 2.4; "A CNAME record is not allowed to coexist with any other data."), but tends to work in practice. We may want to consider changing the DNS->IPFS resolution scheme to allow this scenario to be RFC-compliant (e.g. store the mapping on a well-known subdomain to allow CNAME records on the domain itself). License: MIT Signed-off-by: Kevin Wallace <[email protected]>
License: MIT Signed-off-by: Kevin Wallace <[email protected]>
License: MIT Signed-off-by: Kevin Wallace <[email protected]>
OK, finally got around to this. Sorry it took so long! Added |
func (m mockNamesys) CanResolve(name string) bool { | ||
_, ok := m[name] | ||
return ok | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should probably just return true
. this is likely a doc failure, but the CanResolve
func is supposed to return whether "a name is resolvable by the system" i.e. a DNSResolver
would check if the string is a domain.
(can we think of a clearer name for this func?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LooksResolvable
, LooksApplicable
? I like the Looks
prefix to indicate that we're only examining the name on a surface level, but I don't like the way either of those names read...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Matches
, NameMatches
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like Looks
as well... CanResolve
implies a little more action than we are actually doing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it will be written ns.<word>(name)
ns.LooksApplicable(name)
ns.LooksResolvable(name)
ns.Compatible(name)
ns.CompatibleWith(name)
ns.MayResolve(name)
ns.CanResolve(name)
ns.IsResolvable(name)
ns.Resolvable(name)
This LGTM. thanks again for the PR! |
gateway: attempt to resolve hostname to ipfs path
👍 |
Thanks! |
This allows someone to host a static site by pointing a TXT record at their
content in IPFS, and a CNAME record at an IPFS gateway.
Note that such a setup technically violates RFC1912 (section 2.4; "A CNAME
record is not allowed to coexist with any other data."), but tends to work in
practice.
We may want to consider changing the DNS->IPFS resolution scheme to allow this
scenario to be RFC-compliant (e.g. store the mapping on a well-known subdomain
to allow CNAME records on the domain itself).
Also note that while this has been tested by hand, I don't see a good way to
test it with the existing sharness gateway tests -- how do you mock a DNS entry
from a shell script?