Skip to content
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

<link> vs <meta> #19

Closed
adrianhopebailie opened this issue Oct 14, 2019 · 24 comments · Fixed by #193
Closed

<link> vs <meta> #19

adrianhopebailie opened this issue Oct 14, 2019 · 24 comments · Fixed by #193
Labels
pr193 New Web Monetization Specification Proposal question Further information is requested

Comments

@adrianhopebailie
Copy link
Collaborator

From web-monetization created by marcoscaceres: adrianhopebailie/web-monetization#15

Semantically, the web monetization meta information seems to form a link relationship. Should we use link instead?

@adrianhopebailie
Copy link
Collaborator Author

Can you expand upon this? I'm not super familiar with link ... uhm ... tags?

@adrianhopebailie
Copy link
Collaborator Author

Correct, it wouldn’t... but it could cover any preconnection to a monetization server, for instance. Dynamic includes would be covered separately.

@adrianhopebailie
Copy link
Collaborator Author

Sure, each tag has very specific behavior in the browser. In particular link is wired up to retrieve resources/links (e.g., style sheets)... so there is network machinery underlying the implementation of the link tag. Again, not to throw you in the deep end, but just scan around a little bit of Gecko's link implementation to get an idea... or just to see how crazy the backing implementation is 😂

https://github.com/mozilla/gecko-dev/blob/master/dom/html/HTMLLinkElement.cpp

@adrianhopebailie
Copy link
Collaborator Author

Lol, cheers, grabbing dinner this side of the world :) I will look later.

Keen to see how this fits in with potentially dynamic (read JS injected)
monetization tags (be it link or meta or some body level wrapper or
whatever)

When I think of “parser” I am imagining you are referring to the bytes to
DOM level stage which wouldn’t, afaik, cover the dynamic case?

@Malvoz
Copy link

Malvoz commented Oct 15, 2019

Should this also be supported as an HTTP header? Imagine a user visits https://example.com/video/cats.mp4 (or MDN live example), as far as I know, it's not possible to add a <meta> or <link> elements as it is a direct link to a media format, and not a web page on the web authors domain. However the Link HTTP header field is the equivalent to the inline <link> element but a web author could respond with this header for all file types including video.

Example apache impl.:

<IfModule mod_headers.c>
  Header set Link "<https://secure-wallet.example.com/alice>; rel=monetization"
</IfModule>

Unfortunately that means only web authors with access to the server-side will be able to make sure they're properly monetized for all their content. Perhaps by adding an inline <link rel="monetization"> (or a Link HTTP header, or <meta>), browsers would just assume all content under that origin is monetized? Risks?

@adrianhopebailie
Copy link
Collaborator Author

the Link HTTP header field is the equivalent to the inline element but a web author could respond with this header for all file types including video.

Seems like another good argument for using <link>

@justmoon
Copy link
Contributor

While thinking about this, I noticed that Web Monetization does have some behaviors that are similar to how browsers handle <link rel="stylesheet" ...> - FWIW.

  • Both are requested immediately once the <link> tag is found.
  • Both are requested with a specific Accept header.
  • Both can be added/removed dynamically and the browser needs to react to those changes
  • We previously discussed that it would be nice if Web Monetization could be controlled managed via CSPs the same way that stylesheets/scripts/etc are.

I think overall I'm convinced that it would be desirable to change the standard to:

  • Use <link rel="monetization" ...> instead of <meta>
  • Stop allowing $... and require https://... (I think it would be weird to have <link> with something other than a normal URL. We'll have to explain to people that they need to manually replace the $ with https:// but I think that's a reasonable thing to expect from a web developer.)

Is monetization the right name if it is a relation? It seems like it could also be something like pay or wallet. Hope I'm not starting a massive bikeshedding debate with this. For reference, here is a list of other link types.

@marcoscaceres
Copy link
Contributor

Hate to also bikeshed but "monetization" is a bit of mouthful :) Seems like "wallet" might be good fit.

@adrianhopebailie
Copy link
Collaborator Author

https://www.iana.org/assignments/link-relations/link-relations.xhtml

There is already a "payment" rel link registered which has no reference and appears to have very little prior use.

It is also defined in the registry as doing exactly what we need and the details suggest our usage fits with the intent.

@sharafian
Copy link
Collaborator

sharafian commented Oct 17, 2019

👍 I like the idea of using something pre-existing. I have little attachment to the name "monetization" other than an aversion to breaking changes but it sounds like we'll get our fair share of those in the future anyways

@da2x
Copy link

da2x commented Feb 7, 2020

I’d just like to share some thoughts on this from my blog:

“The Interledger Protocol Payment Pointer is a URL where the https:// prefix has been replaced by a $ character (presumably for marketing purposes). The requirement to use a dollar sign may be seen as an unwanted Americanization outside markets that use it as their currency. Furthermore, URLs don’t belong in <meta> elements  […].”

Semantically, <link> is a metadata element for link-type relations (which is what a Payment Pointer is). It’s better suited than the generic string-literal type <meta> element. The second link goes more into detail what practical differences this makes.

The most important difference is that the link[href] attribute should be parsed using the URL Standard. This means that browsers would normalize it and handle protocol-relative, root-relative, and document-relative paths automatically.

On a more trivial note, href="https://example.com/" will generally compress better than content="$example.com since there’s a much higher probability that the browser can re-use the href="https:// character sequence. It literally costs a a couple of bytes more to serve a page with the latter compared to the former.

@marcoscaceres
Copy link
Contributor

@da2x wrote,

Semantically, <link> is a metadata element for link-type relations (which is what a Payment Pointer is). It’s better suited than the generic string-literal type element. The second link goes more into detail what practical differences this makes.

@da2x, you are definitely not wrong. However, there are a few additional "moving parts" with link that are governed by the HTML spec. They relate to the interaction between href and various other attributes: crossorigin, integrity, and referrerpolicy.

The most important difference is that the link[href] attribute should be parsed using the URL Standard. This means that browsers would normalize it and handle protocol-relative, root-relative, and document-relative paths automatically.

Put differently, do we want what is currently going into the "content" (e.g., "$example.com") attribute to be an actual URL? What's the protocol? And would it have any interaction with the crossorigin, integrity, and referrerpolicy attributes?

If the answer is "not a URL" and "no interaction", then <meta> is ok. However, there is some network magic happening with <meta> and this spec, so if <link> is appropriate is still up for debate.

@justmoon
Copy link
Contributor

justmoon commented Jun 8, 2020

Put differently, do we want what is currently going into the "content" (e.g., "$example.com") attribute to be an actual URL?

It's a slight trade-off in my opinion. The reason the payment pointer spec uses "$example.com" in the first place, instead of "https://example.com/.well-known/pay" is to allow payment pointers to appear in things like chat messages and be accurately recognized the same way, e.g. email addresses are.

If we stick with the current <meta ... content="$example.com"> tag, the upside is that as a web developer, I can put the payment pointer in the usual formatting without having to know the rules for turning a payment pointer into a URL or having to use a tool.

If we change to the <link ... href="https://example.com/.well-known/pay"> format, the upside is that it's more obvious that this is a URL and it does make things like integrity available. This feels useful but I also haven't been able to come up with a concrete use case as to why someone would need it. As I mentioned in my previous comment, it feels like this feature acts similar to other <link> tags, but whether that translates into being easier to implement in browsers, I'm the wrong person to opine on.

What's the protocol?

I think similar to how other link tags work, the browser could use the Accept header to indicate what types of file it understands. For example, CSS is the de-facto standard format for stylesheets. For Web Monetization, we effectively have such a de-facto standard (SPSP) as well. This might still evolve somewhat as adoption grows and more use cases become supported but there are already enough sites using it that we would want to maintain backwards compatibility.

@sublimator
Copy link
Collaborator

I added a preview implementation of the link tag in (the yet to be published) version 0.0.51 of the extension.
In order to keep the implementation simple while keeping the 1:1 relationship between a tag and request/session uuid, upon seeing a <link> tag for the first time (per page load), it only responds to those, ignoring any <meta> tags.

@adrianhopebailie
Copy link
Collaborator Author

@sublimator is it possible to know if the website returned a link header in the original response? i.e. Could we also support this?

@sublimator
Copy link
Collaborator

sublimator commented Jul 17, 2020 via email

@sharafian
Copy link
Collaborator

yeah I think that would require us to intercept all requests (because any request could have a link header in it). Let's see if there's anything else we can do but if that's the only way to implement it we should probably hold off on that feature for now.

@adrianhopebailie
Copy link
Collaborator Author

It may make more sense to support this when WM is baked into browsers because it seems like asking for the extra permissions is a big change for minimal gain.

@sidvishnoi
Copy link
Contributor

I’ve been researching the challenges outlined in this bug for a few weeks as part of a Grant for the Web project - and in consultation with @marcoscaceres on Firefox internals. I'll try to summarize my findings in relation to the above discussions, and expand on a few bits for the community’s consideration. Ultimately, I’d like us to settle the debate around <link> VS <meta> to allow me to proceed with a prototype implementation of WM in Gecko (Firefox).

<link> vs <meta>

Why <link>:

  • networking behavior is built-into HTMLLinkElement browser implementations already:
    • easier to specify/implement, as it just uses existing link relationship fetching behavior (quite similar to CSS stylesheet and Web manifest)
  • HTMLLinkElement is semantically correct for this use case
  • supports Link header to monetize non-documents with a little extra code.

Why <meta>:

  • can use payment pointers without conflicting with HTML specification requirements. However, it means we don’t get any security assurances and we have to specify all behavior (unlike , where we get a lot of stuff for free!). ,
  • already in use and known to the Web Monetization community

For <meta>, the lack of backing networking behavior is a significant drawback.

<link> and Payment Pointers:

As said earlier, payment pointers are not “valid URLs” (per the URL spec), so they are incompatible with <link> elements. Formally, as per HTML spec:

If the href attribute is present, then its value must be a valid non-empty URL potentially surrounded by spaces.
https://html.spec.whatwg.org/multipage/semantics.html#the-link-element:valid-non-empty-url-potentially-surrounded-by-spaces

As an aside, I did consider creating a new scheme such as pay://payment-pointer-without-$-sign.

$example.com => pay://example.com -> https://example.com/.well-known/pay.

We're making a tradeoff of using https URL against more catchy payment pointers. A middle ground could be to mint a new scheme, as that would retain compatibility with the HTML spec/parser. However, the W3C TAG and IETF strongly discourage this:

Relevant excerpt from https://tools.ietf.org/html/rfc2718:

2.3 Demonstrated utility

URL schemes should have demonstrated utility. New URL schemes are
expensive things to support. Often they require special code in
browsers, proxies, and/or servers. Having a lot of ways to say
the same thing needless complicates these programs without adding
value to the Internet.

The kinds of things that are useful include:
o Things that cannot be referred to in any other way.
o Things where it is much easier to get at them using this scheme
than (for instance) a proxy gateway.

W3C TAG also advises against creating new schemes: https://www.w3.org/TR/webarch/#URI-scheme

Recommendation is to drop the payment pointers and just use https://. The rationale being:

  • We already have a well understood and widely deployed scheme and communication protocol fit for purpose (https + tls).
  • Browsers won’t need new logic to handle a one-off scheme: payment pointers add significant complexity with limited benefit over what already exists.
  • Payment pointers add indirection + duplication: a payment pointer is dereferenced to a HTTP request - which both the https:// scheme and protocol already handle.
  • Payment pointers don’t adhere to a standardized URI scheme structure, requiring a custom parser in every browser. This is a burden and expense for the ecosystem as a whole, in that it adds additional costs to learn, maintain, secure, etc. what is effectively a completely new URI scheme format.

Link: HTTP header

The Link: HTTP header could provide an alternative means of enabling Web Monetization for a document or a media resource within a document (e.g., a video, or audio clip), or even non-web content like viewing a standalone PDF file.

Although some additional implementation separate from in-HTML link tag is required (relevant Gecko code), we're getting it for free with the <link> element.

This would require further exploration.

Link element’s attributes

By adopting the <link> element, we would also benefit indirectly from the following HTML attributes (which form part of every “link relationship”):

  • integrity allows the browser to check if the resource has been manipulated. It won't make sense here as the GET <SPSP endpoint> will return a different response on each request. If we go the link route, we might not want to support this explicitly.

  • crossorigin defines how the element handles cross-origin requests. A good default would be anonymous (send credentials only to same-origin), as the credentials are not a concern to the WM receiver here. However, we may want to allow a website to set this attribute if needed.

  • referrerpolicy controls how much information we send in the Referer header for this request. We might not want to disclose the path to a third-party WM receiver, but if the site itself is running the WM receiver, there is no point in hiding it, so, we might use strict-origin-when-cross-origin by default. This will only reveal the user’s origin, and also add additional privacy protections at the HTTP layer.

Once we reach a consensus, I can start prototyping it in Gecko and help specify things more formally in the spec.

@sublimator
Copy link
Collaborator

@sidvishnoi

Sounds great! Good to hear you are implementing WM in Gecko!

allow me to proceed with a prototype implementation of WM

Don't let meta vs link hold you back :)
It's not a large part of impl WM

@adrianhopebailie
Copy link
Collaborator Author

Thanks for this analysis @sidvishnoi.

The Coil extension already ships with support for both tags so we're well on our to migrating.

Recommendation is to drop the payment pointers and just use https://

Payment Pointers are URLs. But I am nit-picking and I agree with your suggestion that we use the full URL form (and not the shortened form with the $ prefix) when embedding them into HTML. The purpose of the shortened form is for cases where the Payment Pointer is seen by users and provides an easily recognisable format.

Link: HTTP header

I'm interested to explore this more. We won't encourage websites to use headers yet as these wouldn't be accessible from extensions (the only implementation we have available today) but there is some interesting potential and use cases to look at down the road.

Link element’s attributes

We'd like to maximise on privacy here.

  • integrity - we expect to have a dynamic resource at the end of the URL so I think this should be explicitly not allowed.
  • crossorigin - I think this should always be anonymous
  • referrerpolicy - I think this should always be no-referrer

@da2x
Copy link

da2x commented Oct 8, 2020

The Coil extension already ships with support for both tags so we're well on our to migrating.

So is it time to switch the recommendation in https://webmonetization.org/docs/getting-started/ ?

@marcoscaceres
Copy link
Contributor

If we want to keep using payment pointers for display purposes, I wonder if there should be a static method defined somewhere to do the conversion to (or from?) a URL? Like wm.toPaymentPointer(url) or the other way around. That way, a developer can continue to display and take payment pointers, but then easily/safely convert them to URLs to use with <link>?

@sidvishnoi
Copy link
Contributor

sidvishnoi commented Oct 9, 2020

referrerpolicy - I think this should always be no-referrer

That makes sense. We might want to have a balance between privacy and security here though, as it may be helpful for WM receivers to know what sites are sending requests in order to prevent abuse.
Although, it's better if we can start with stricter modes, and get lenient if needed.

Edit: Gave it more a thought. Let's stick with no-referrer. We don't really want to tie user to site they're visiting and disclose it to WM receiver.

Additionally, I'm a bit concerned about allowing URL parameters in the link tag (payment pointers are relatively safe here), as they can easily render the no-referrer part useless. However, we can't really avoid explicit tracking.

Don't let meta vs link hold you back :)
It's not a large part of impl WM

From browser implementation perspective, I'd say it's a significant part 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pr193 New Web Monetization Specification Proposal question Further information is requested
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants