-
Notifications
You must be signed in to change notification settings - Fork 32
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
Protocol handler API #2
Comments
There is some relevant discussion in regards to going with Service Worker like API at https://github.com/Gozala/libdweb/issues/8#issuecomment-390437124 |
Made some progress on this issue last week. As things stand now above described API is available to the background script if Only other thing that I'm considering is going with |
It seems that for whatever reason loader spinner for new tab into which content from custom protocol handler is loaded never finishes spinning. Oddly enough it works fine for the first tab. Maybe it's related to #issuecomment-390724031 ? |
In separate conversation @olizilla asked if we could support CSP headers in custom protocols ? At least that is a mechanics in Electron. Support for HTTP headers in non-http protocol seems odd on one hand, but on the other hand it's reasonable request. According to the [
I wonder if implementing @olizilla I also as I mentioned in that conversation there are some protocol flags that could be used to control policies to a much lesser degree. |
@Gozala a somehow related question: are these flags taken in consideration when browser decides if loaded resource is a Secure Context? Asking because localhost is marked as a Secure Context (even on HTTP without encryption), and I see flags like |
Turns out
But loaded page still reports
In case of As of At the moment protocol handler uses |
In regards to
Then looking at the current implementation of 😞 |
Turns out there is a bug 1328695 that says " 😌 😀 |
Infinite loading issue is finally resolved! |
Unfortunately I discovered yet another issue this time it's a clam that connection is not secure: And I have also verified it's not related to the |
@lidel @olizilla @mafintosh above "connection is not secure" raised some interesting questions, specifically:
|
Dat does validate all of its content against the public key. We also only use DNS names which we can receive from authenticated sources (spec here). |
@pfrazee maybe I did not described what I meant properly, I assume there is some audit happening that content you get is authored by the owner of the private key, I imagine wanting to update status of the stream when this validation can be done. |
@Gozala oh you mean the timing? Yeah the data is verified when it is received, prior to it ever being used. I suppose one of the tricks here is that "secure" has a different meaning than with https, since https is referring to the TLS session. If you're looking at just whether dat's data is verified, it always will be and invalid data is basically just ignored -- so arguably it's always secure? But there is channel encryption, and that has to be negotiated too. |
Yeah I meant this in a broader sense, what kind of security properties does protocol needs to communicate with a browser and what API would make sense to expose to do so.
What if some data is invalid should not that be communicated in some way to a browser ? What if you encounter alternate forks of the same archive ? I imagine it is another thing that is worth communicating with a browser in some form.
I think in more concrete terms how should we change current draft of the protocol handle interface to allow network protocol implementation to communicate status updates of the request with a browser. And how do we make this not tied to an individual protocol like Dat or IPFS as they might have a different properties to communicate. Also what other properties does protocol handler needs to communicate with browser here example that come into my mind:
I could really use some help in terms of API change suggestions. |
Since any peer can show up and start giving bad data, I'm not sure I'd communicate that. It's not something the user needs to know (IMO).
That's something that might be worth communicating, because it currently means the Dat is corrupted and can't be recovered. We don't yet do that in Beaker though (one day at a time).
Maybe a good issue for https://github.com/datprotocol/DEPs |
@Gozala to answer your two questions from #2 (comment):
Will think about it some more tho. |
@lidel Thanks for the feedback. I suggest to think about browser as a node itself rather that something that talks to IPFS node. If you angle things that way I think communicating back any status / progress update would make sense. I also suspect that existing status flags and security info in gecko doesn't quit translate in IPFS and I don't suggest we shoehorn it, but it worth documenting what we'd like to be able to do. In terms of UI also agree that current door-hanger makes little sense, but how we present that info if at all is a separate problem, ideally we still want to provide browser with all the info as it arrives. I also do understand that both IPFS and Dat do audit data as it arrives, never the less I imagine there could be an instance where node receives some malicious data and I imagine that is worth reporting to the browser. And what if valid data can't be found that's also worth reporting. On the somewhat related note does is anything like HTTP Status codes, or Headers make sense in either of these contexts ? |
Open to debate, but IMO you only need to escalate in Dat if it's a corruption event. Misbehaving non-author peers will degrade performance, but that's all. If valid data can't be found, you just get a timeout (but keep searching).
The way that I've approached this is by thinking of the Dat protocol handler like a server. It's another area that's open to debate but you can see how we've approached it here. |
I wonder if that was somewhat driven by the Electron API itself ? In gecko protocol handler does not impose HTTP headers or status codes that is part of the http protocol handler implementation itself. If you approach it from this angle you might start questioning whether replicating HTTP headers and status codes make any sense and if it does, would not it make sense to do that at the protocol level rather than at the protocol handler level ? To be clear this doesn't block us here, but as I face this issues it's helpful to discuss that with protocol authors. Another thing that I have being thinking is that unlike HTTP in Dat / IPFS space completed request is not necessarily complete in a sense that you might continue seeding as long as you have that resource loaded. In theory it might be useful to display graphs of activity (kind of like we see them on servers) I wonder if it would make sense to let protocol channel keep reporting status updates even after content is loaded or whether it makes sense to have a separate service that browser UI can subscribe to receive network activity updates on that resource. |
Sure. We're basically using the headers and status codes as a way to configure the browser handling. It wouldn't have to be that way. |
Main uses I see:
IMO these are generic building blocks that could be useful for different protocols, even if we make them a lot less powerful than HTTP ones. Headers could be optional, and if not explicitly defined could have an implicit OK Status. An open question is if/how much of HTTP abstractions should be copied. a) My initial intuition is that going with HTTP-like semantics: Headers with mandatory Status Code following HTTP conventions (2xx == OK, 3xx == Redirtect, etc) would simplify wiring new protocols into the browser (eg. dev tools) and reduce cognitive load for developers that consume the API, like it did in Beaker. But I also understand it may not be possible due to constrains/complexity that I am not aware of. b) May be also better to keep the API small and provide simple DSL/API for mentioned uses, similar to On a related note, I noticed some additional edge cases specific to
|
why copy anything from HTTP? let’s keep the API simple. If someone wants to add headers and redirections to their protocol, let them parse them from the content themselves, right? |
I think it's a benefit to be able to use the features provided by HTTP headers. Content Security Policy and Caching immediately come to mind; I'm sure there will be more over time. If we say, "These new protocols are not HTTP so they shouldn't use HTTP codes & headers," I think we may find ourselves porting over the functionality repeatedly. Can we generalize "HTTP" headers into "Request and Response Headers" ? With that line of thinking, we're able to inherit all of the features and minimize the amount of novel work, and then we add new features to them. There's definitely some differences in terms of potential response states, for instance:
And so on. But my gut reaction is, we should adapt the HTTP behaviors unless it completely fails to map in some key fashion. |
Maybe I’m missing something, but we want to support arbitrary protocols, right? But if we add abstractions for HTTP-like headers, and if a protocol sends data that looks like HTTP headers but isn’t, it will be annoying or impossible to get the data out of the headers back into its original form in order to be parsed properly. E.g. HTTP headers are just ASCII. what if some protocol sends
This would parse to Response {
headers: {
Set: <ASCIIDecodeError>,
},
content: AsnycIterator([
ArrayBuffer('Hey!'),
]),
} If we do something like that, the header part of the API should be an adapter or wrapper around the raw content API. |
It seems the use-cases for making HTTP headers part of this API are tied to wanting some aspects of the browser security model to seamlessly apply to new protocols. As we are loading these pages on a web browser, we expect the tooling to behave like the web platform does. That means CSP and cross-origin restrictions etc. However, these features are tightly coupled with HTTP, and rely on HTTP verbs and headers which may not have equivalents on different protocols. If this is to be a header-less protocol handler, it may be useful to enable some configurability of the browser environment. The concept of origins may or may not be appropriate, depending on the protocol, and questions such as whether pages on custom protocols can then load third-party content on other protocols. |
That’s connected to a protocol handling URLs or the more general URIs:
Yes, The protocol handler API should accept URIs, which means that the concept of origin(=authority) doesn’t necessarily apply to things we handle. Therefore my suggestion: Give users a nice wrapper to create HTTP-like protocols with all the goodies we’re accustomed to but leave the base API maximally powerful. |
My main interest is minimizing the amount of effort this takes. I'm not in favor of changing the definitions of origins (ie My point is that the HTTP semantics are not hard to map to these protocols, and so I think we ought to be approaching this from the standpoint of asking "how do the request/response semantics actually need to change?" rather than assuming we need to start from a blank slate. For Dat, we need mechanisms that are functionally equivalent to status codes and HTTP headers. It's also useful that |
Bug preventing secure context was fixed and is available nightly builds. I also have landed 5751026 take make use of it in our protocol API and with that we have secure context: |
I believe omitting |
@lidel It would be challenging, but might be doable. I would encourage you to give it a shot. I personally would rather spend time on other issues, because:
That being said here is some pointers that might provide necessary context to try implementing this.
One more thing to consider is that I do not know how to wrap all this into a nice API where uses that don't care about such redirects won't end up with
I think my comment above should clarify what are the options and challenges here. Only other thing I could add there might be an option to return some bastardized
I'm not entirely sure what is your suggesting here, if it just switching to case-insensitive CID 👍 Otherwise you'd need all the things I've described above. Also keep in mind that you have to choose between standard URLs which have notion of relative URLs and proper origin support but require case-insensitive hostname and URIs that have neither but are case-sensitive.
I'm not sure actually how
I totally understand. How migration costs compares to implementation + added complexity costs that I don't know. I'd suggest to explore if current behavior can be preserved by using |
Problem is we'd have to port them anyway for custom protocol anyway. On one hand it sure makes it easier for ipfs, dat, ssb folks as to not think about that, on the other hand if we do think about it and decide on a subset it would make porting that easier.
The way gecko is setup I don't think it's possible. It's individual protocol handler implementation that do parsing and interpreting those into specific actions. So nsIHTTPProtocolHandler does that in gecko what that means I'd need to replicate all that it does, which is not only challenging but I'm almost certain it also makes use of some non-scriptable APIs to do that which means it would have to be done in the gecko and land into firefox itself. That is why I would very much prefer to minimize the scope by considering what does and does not make sense. Additional benefit is considering all this would be helpful any standardization effort we might consider. Also from what I can tell Request Headers don't make any sense in this context, or am I missing something ? |
Most of these are tight to Cross protocol interactions is another good topic to discuss and I suspect Moz Security will have opinions in this regard too. |
👍 I totally agree.
I don't really suggest starting from blank slate, rather I'm trying to reduce the scope. Think of it not as reinvent status codes / headers but rather picking just subset we need as it would greatly simplify implementation efforts.
Custom protocols in gecko are more similar to I think what you really want is small subset of features provided by combination of HTTP status codes and headers. If we could figure out what that subset is it would be a lot easier to add support for it. |
If it's not possible to reuse any existing HTTP handling code, then I can understand why my suggestion (to not reinvent) doesn't get us much. Here's what we currently use from the HTTP semantics right now for dat in Beaker. I'll rate how important they are for us, but that's just to say we do/dont need the functionality but it could be by other mechanisms. Requests:
Responses:
Hope that's helpful |
@pfrazee thanks for this list, it's very helpful. Just one followup question, in which context are these request methods / headers are used ? Is it just to support XHR / fetch APIs or is there some other use cases ? And if it's used by XHR / fetch how is that preferable over use of DatArchive API ? |
Mainly they are used for browsing - for visiting pages and for embedded resources. (The range requests come in for video/audio, for instance.) Generally the DatArchive API is the ideal choice, but XMR / fetch is useful when you want to be transport-agnostic. A dat url works just as well as an http url in that API. |
I was attending Mozilla All Hands meeting last week and that gave me a chance to talk to necko (gecko networking stack) engineers. About some of the still open issues in regards to custom protocol handlers. More coordination & research+work will be required to address remaining limitations but here is a some takeaways:
Sadly I don't have C++ experience to tackle Request / Response headers, if anyone interested in this work does please let me know and I'll be happy to get you started and connect to people who can mentor you in this process. Otherwise I'll probably end up tackling this myself but only after everything else here is solid. |
Moved out remaining items into individual issues. Closing this one. |
Primary goal of this milestone is to enable Firefox addon to provide custom network protocol implementation. This will not enable add-on to provide full IPFS, Dat, SSB implementations (as that would for example require exposing UDP socket API to add-ons) but it would enable add-on to add associated protocol handler and possibly delegate actual networking to local node via native messaging API or a through a public gateway. Unlike current support of decentralized network protocols this will not redirect request but rather load them under specified URL and have content origin be set to
scheme://${hostname}
.Option 1
Allow addon to register ServiceWorker against custom network protocol, allowing Firefox to delegate all network requests to the dedicated ServiceWorker run in the separate background thread.
Option 2
There is already established Electron API used by Beaker Browser and IPFS extension for Brave browser to do exactly that. Compatible Firefox addon API could be exposed to enable that in Firefox. Firefox could leverage existing components like nsIProtocolHandler, nsIStandardURL, nsIURL to expose such API.
🐞 1271553
API Draft
Current work-in progress implementation has a following API exposed under
browser.protocol
namespaceStatus
nsIProtocolHandler
The text was updated successfully, but these errors were encountered: