WICG / webmonetization

Proposed Web Monetization standard
https://webmonetization.org
Other
440 stars 150 forks source link

`<link>` vs `<meta>` #19

Closed adrianhopebailie closed 1 year ago

adrianhopebailie commented 4 years ago

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 commented 4 years ago

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

adrianhopebailie commented 4 years ago

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

adrianhopebailie commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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

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

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 commented 4 years ago

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

adrianhopebailie commented 4 years ago

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 commented 4 years ago

:+1: 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 commented 4 years ago

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 commented 4 years ago

@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 commented 4 years ago

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 commented 3 years ago

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 commented 3 years ago

@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 commented 3 years ago

we could (99% sure) but it would be an extra permission (we already have full content ...)

I can look into it anyway

sharafian commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

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>:

Why <meta>:

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:

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”):

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

sublimator commented 3 years ago

@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 commented 3 years ago

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.

da2x commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

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 :sweat_smile: