mirror of
https://gitlab.com/news-flash/article_scraper.git
synced 2025-07-07 16:15:32 +02:00
fix url completion for hash urls
This commit is contained in:
parent
b52212bf34
commit
027fab7602
10 changed files with 895 additions and 170 deletions
|
@ -12,7 +12,7 @@
|
||||||
<p><a href="http://fakehost/test/base/foo/bar/baz.html" target="_blank">link</a></p>
|
<p><a href="http://fakehost/test/base/foo/bar/baz.html" target="_blank">link</a></p>
|
||||||
<p><a href="http://fakehost/test/base/foo/bar/baz.html" target="_blank">link</a></p>
|
<p><a href="http://fakehost/test/base/foo/bar/baz.html" target="_blank">link</a></p>
|
||||||
<p><a href="http://fakehost/foo/bar/baz.html" target="_blank">link</a></p>
|
<p><a href="http://fakehost/foo/bar/baz.html" target="_blank">link</a></p>
|
||||||
<p><a href="http://fakehost/test/base/#foo" target="_blank">link</a></p>
|
<p><a href="#foo">link</a></p>
|
||||||
<p><a href="http://fakehost/test/base/baz.html#foo" target="_blank">link</a></p>
|
<p><a href="http://fakehost/test/base/baz.html#foo" target="_blank">link</a></p>
|
||||||
<p><a href="http://fakehost/foo/bar/baz.html#foo" target="_blank">link</a></p>
|
<p><a href="http://fakehost/foo/bar/baz.html#foo" target="_blank">link</a></p>
|
||||||
<p><a href="http://test/foo/bar/baz.html" target="_blank">link</a></p>
|
<p><a href="http://test/foo/bar/baz.html" target="_blank">link</a></p>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<h4> Gallery: Xbox One
|
<h4> Gallery: Xbox One
|
||||||
X | 14 Photos </h4>
|
X | 14 Photos </h4>
|
||||||
<div data-behavior="lightbox_trigger" data-engadget-slideshow-id="803271" data-eng-bang='{"gallery":803271,"slide":7142088,"index":0}' data-eng-mn="93511844">
|
<div data-behavior="lightbox_trigger" data-engadget-slideshow-id="803271" data-eng-bang='{"gallery":803271,"slide":7142088,"index":0}' data-eng-mn="93511844">
|
||||||
<p><a href="http://fakehost/test/base/#" data-index="0" data-engadget-slide-id="7142088" data-eng-bang='{"gallery":803271,"slide":7142088,"index":0}' target="_blank">
|
<p><a href="#" data-index="0" data-engadget-slide-id="7142088" data-eng-bang='{"gallery":803271,"slide":7142088,"index":0}'>
|
||||||
<img src="https://o.aolcdn.com/images/dims?thumbnail=980%2C653&quality=80&image_uri=https%3A%2F%2Fs.blogcdn.com%2Fslideshows%2Fimages%2Fslides%2F714%2F208%2F8%2FS7142088%2Fslug%2Fl%2Fxbox-one-x-review-gallery-1-1.jpg&client=cbc79c14efcebee57402&signature=9bb08b52e12de8e4060f863a52c613489529818d">
|
<img src="https://o.aolcdn.com/images/dims?thumbnail=980%2C653&quality=80&image_uri=https%3A%2F%2Fs.blogcdn.com%2Fslideshows%2Fimages%2Fslides%2F714%2F208%2F8%2FS7142088%2Fslug%2Fl%2Fxbox-one-x-review-gallery-1-1.jpg&client=cbc79c14efcebee57402&signature=9bb08b52e12de8e4060f863a52c613489529818d">
|
||||||
</a></p>
|
</a></p>
|
||||||
|
|
||||||
|
@ -193,7 +193,7 @@
|
||||||
<h3> Gallery: Xbox
|
<h3> Gallery: Xbox
|
||||||
One X screenshots | 9 Photos </h3>
|
One X screenshots | 9 Photos </h3>
|
||||||
<div data-behavior="lightbox_trigger" data-engadget-slideshow-id="803330" data-eng-bang='{"gallery":803330,"slide":7142924}' data-eng-mn="93511844">
|
<div data-behavior="lightbox_trigger" data-engadget-slideshow-id="803330" data-eng-bang='{"gallery":803330,"slide":7142924}' data-eng-mn="93511844">
|
||||||
<p><a href="http://fakehost/test/base/#" data-index="0" data-engadget-slide-id="7142924" data-eng-bang='{"gallery":803330,"slide":7142924}' target="_blank">
|
<p><a href="#" data-index="0" data-engadget-slide-id="7142924" data-eng-bang='{"gallery":803330,"slide":7142924}'>
|
||||||
<img src="https://o.aolcdn.com/images/dims?thumbnail=980%2C653&quality=80&image_uri=https%3A%2F%2Fs.blogcdn.com%2Fslideshows%2Fimages%2Fslides%2F714%2F292%2F4%2FS7142924%2Fslug%2Fl%2Fxbox-one-x-screenshot-gallery-2-1.jpg&client=cbc79c14efcebee57402&signature=38c95635c7aad58a8a48038e05589f5cf35b1e28">
|
<img src="https://o.aolcdn.com/images/dims?thumbnail=980%2C653&quality=80&image_uri=https%3A%2F%2Fs.blogcdn.com%2Fslideshows%2Fimages%2Fslides%2F714%2F292%2F4%2FS7142924%2Fslug%2Fl%2Fxbox-one-x-screenshot-gallery-2-1.jpg&client=cbc79c14efcebee57402&signature=38c95635c7aad58a8a48038e05589f5cf35b1e28">
|
||||||
</a></p>
|
</a></p>
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
|
|
||||||
<dd>
|
<dd>
|
||||||
<p>
|
<p>
|
||||||
A notification intended to be read by a human and that is pushed to a system such as a bug or ticket queue, an email alias, or a pager. Respectively, these alerts are classified as <em>tickets</em>, <em>email alerts</em>,<sup><a data-type="noteref" id="id-LvQuvtYS7UvI8h4-marker" href="http://fakehost/test/base/#id-LvQuvtYS7UvI8h4" target="_blank">22</a></sup> and <em>pages</em>.
|
A notification intended to be read by a human and that is pushed to a system such as a bug or ticket queue, an email alias, or a pager. Respectively, these alerts are classified as <em>tickets</em>, <em>email alerts</em>,<sup><a data-type="noteref" id="id-LvQuvtYS7UvI8h4-marker" href="#id-LvQuvtYS7UvI8h4">22</a></sup> and <em>pages</em>.
|
||||||
</p>
|
</p>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@
|
||||||
|
|
||||||
<dd>
|
<dd>
|
||||||
<p>
|
<p>
|
||||||
Dashboards should answer basic questions about your service, and normally include some form of the four golden signals (discussed in <a data-type="xref" href="http://fakehost/test/base/#xref_monitoring_golden-signals" target="_blank">The Four Golden Signals</a>).
|
Dashboards should answer basic questions about your service, and normally include some form of the four golden signals (discussed in <a data-type="xref" href="#xref_monitoring_golden-signals">The Four Golden Signals</a>).
|
||||||
</p>
|
</p>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@
|
||||||
Your monitoring system should address two questions: what’s broken, and why?
|
Your monitoring system should address two questions: what’s broken, and why?
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
The "what’s broken" indicates the symptom; the "why" indicates a (possibly intermediate) cause. <a data-type="xref" href="http://fakehost/test/base/#table_monitoring_symptoms" target="_blank">Table 6-1</a> lists some hypothetical symptoms and corresponding causes.
|
The "what’s broken" indicates the symptom; the "why" indicates a (possibly intermediate) cause. <a data-type="xref" href="#table_monitoring_symptoms">Table 6-1</a> lists some hypothetical symptoms and corresponding causes.
|
||||||
</p>
|
</p>
|
||||||
<table id="table_monitoring_symptoms">
|
<table id="table_monitoring_symptoms">
|
||||||
<caption>
|
<caption>
|
||||||
|
@ -285,7 +285,7 @@
|
||||||
Worrying About Your Tail (or, Instrumentation and Performance)
|
Worrying About Your Tail (or, Instrumentation and Performance)
|
||||||
</h2>
|
</h2>
|
||||||
<p>
|
<p>
|
||||||
When building a monitoring system from scratch, it’s tempting to design a system based upon the mean of some quantity: the mean latency, the mean CPU usage of your nodes, or the mean fullness of your databases. The danger presented by the latter two cases is obvious: CPUs and databases can easily be utilized in a very imbalanced way. The same holds for latency. If you run a web service with an average latency of 100 ms at 1,000 requests per second, 1% of requests might easily take 5 seconds.<sup><a data-type="noteref" id="id-QQLuAIXFxCz-marker" href="http://fakehost/test/base/#id-QQLuAIXFxCz" target="_blank">23</a></sup> If your users depend on several such web services to render their page, the 99th percentile of one backend can easily become the median response of your <span>frontend</span>.
|
When building a monitoring system from scratch, it’s tempting to design a system based upon the mean of some quantity: the mean latency, the mean CPU usage of your nodes, or the mean fullness of your databases. The danger presented by the latter two cases is obvious: CPUs and databases can easily be utilized in a very imbalanced way. The same holds for latency. If you run a web service with an average latency of 100 ms at 1,000 requests per second, 1% of requests might easily take 5 seconds.<sup><a data-type="noteref" id="id-QQLuAIXFxCz-marker" href="#id-QQLuAIXFxCz">23</a></sup> If your users depend on several such web services to render their page, the 99th percentile of one backend can easily become the median response of your <span>frontend</span>.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
The simplest way to differentiate between a slow average and a very slow "tail" of requests is to collect request counts bucketed by latencies (suitable for rendering a histogram), rather than actual latencies: how many requests did I serve that took between 0 ms and 10 ms, between 10 ms and 30 ms, between 30 ms and 100 ms, between 100 ms and 300 ms, and so on? Distributing the histogram boundaries approximately exponentially (in this case by factors of roughly 3) is often an easy way to visualize the distribution of your requests.
|
The simplest way to differentiate between a slow average and a very slow "tail" of requests is to collect request counts bucketed by latencies (suitable for rendering a histogram), rather than actual latencies: how many requests did I serve that took between 0 ms and 10 ms, between 10 ms and 30 ms, between 30 ms and 100 ms, between 100 ms and 300 ms, and so on? Distributing the histogram boundaries approximately exponentially (in this case by factors of roughly 3) is often an easy way to visualize the distribution of your requests.
|
||||||
|
@ -362,10 +362,10 @@
|
||||||
The principles discussed in this chapter can be tied together into a philosophy on monitoring and alerting that’s widely endorsed and followed within Google SRE teams. While this monitoring philosophy is a bit aspirational, it’s a good starting point for writing or reviewing a new alert, and it can help your organization ask the right questions, regardless of the size of your organization or the complexity of your service or system.
|
The principles discussed in this chapter can be tied together into a philosophy on monitoring and alerting that’s widely endorsed and followed within Google SRE teams. While this monitoring philosophy is a bit aspirational, it’s a good starting point for writing or reviewing a new alert, and it can help your organization ask the right questions, regardless of the size of your organization or the complexity of your service or system.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
When creating rules for monitoring and alerting, asking the following questions can help you avoid false positives and pager burnout:<sup><a data-type="noteref" id="id-a82udF8IBfx-marker" href="http://fakehost/test/base/#id-a82udF8IBfx" target="_blank">24</a></sup>
|
When creating rules for monitoring and alerting, asking the following questions can help you avoid false positives and pager burnout:<sup><a data-type="noteref" id="id-a82udF8IBfx-marker" href="#id-a82udF8IBfx">24</a></sup>
|
||||||
</p>
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Does this rule detect <em>an otherwise undetected condition</em> that is urgent, actionable, and actively or imminently user-visible?<sup><a data-type="noteref" id="id-0vYuEFpSjSMtLfG-marker" href="http://fakehost/test/base/#id-0vYuEFpSjSMtLfG" target="_blank">25</a></sup>
|
<li>Does this rule detect <em>an otherwise undetected condition</em> that is urgent, actionable, and actively or imminently user-visible?<sup><a data-type="noteref" id="id-0vYuEFpSjSMtLfG-marker" href="#id-0vYuEFpSjSMtLfG">25</a></sup>
|
||||||
</li>
|
</li>
|
||||||
<li>Will I ever be able to ignore this alert, knowing it’s benign? When and why will I be able to ignore this alert, and how can I avoid this scenario?
|
<li>Will I ever be able to ignore this alert, knowing it’s benign? When and why will I be able to ignore this alert, and how can I avoid this scenario?
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<meta itemprop="url" content="https://i.guim.co.uk/img/media/05cb692c634cd90e5411aab92ca3e649474ff786/0_0_4800_3200/master/4800.jpg?width=700&quality=85&auto=format&fit=max&s=f5b3d20f0dc5c22a83f96fb709ecd204">
|
<meta itemprop="url" content="https://i.guim.co.uk/img/media/05cb692c634cd90e5411aab92ca3e649474ff786/0_0_4800_3200/master/4800.jpg?width=700&quality=85&auto=format&fit=max&s=f5b3d20f0dc5c22a83f96fb709ecd204">
|
||||||
<meta itemprop="width" content="4800">
|
<meta itemprop="width" content="4800">
|
||||||
<meta itemprop="height" content="3200">
|
<meta itemprop="height" content="3200">
|
||||||
<a href="http://fakehost/test/base/#img-2" data-link-name="Launch Article Lightbox" data-is-ajax="" target="_blank">
|
<a href="#img-2" data-link-name="Launch Article Lightbox" data-is-ajax="">
|
||||||
<div>
|
<div>
|
||||||
<picture>
|
<picture>
|
||||||
<source media="(min-width: 1300px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 1300px) and (min-resolution: 120dpi)" sizes="880px" srcset="https://i.guim.co.uk/img/media/05cb692c634cd90e5411aab92ca3e649474ff786/0_0_4800_3200/master/4800.jpg?width=880&quality=45&auto=format&fit=max&dpr=2&s=adbbf5d870d9cc7f0b9a24eb5472ebf3 1760w"></source> <source media="(min-width: 1300px)" sizes="880px" srcset="https://i.guim.co.uk/img/media/05cb692c634cd90e5411aab92ca3e649474ff786/0_0_4800_3200/master/4800.jpg?width=880&quality=85&auto=format&fit=max&s=f0a6d8fa60b5571e9e0e9a5673e407b7 880w"></source> <source media="(min-width: 1140px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 1140px) and (min-resolution: 120dpi)" sizes="800px" srcset="https://i.guim.co.uk/img/media/05cb692c634cd90e5411aab92ca3e649474ff786/0_0_4800_3200/master/4800.jpg?width=800&quality=45&auto=format&fit=max&dpr=2&s=d39897e20bb677fda3feb14113aad381 1600w"></source> <source media="(min-width: 1140px)" sizes="800px" srcset="https://i.guim.co.uk/img/media/05cb692c634cd90e5411aab92ca3e649474ff786/0_0_4800_3200/master/4800.jpg?width=800&quality=85&auto=format&fit=max&s=dbf240ee147c5a0a43321f1634ee41eb 800w"></source> <source media="(min-width: 980px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 980px) and (min-resolution: 120dpi)" sizes="640px" srcset="https://i.guim.co.uk/img/media/05cb692c634cd90e5411aab92ca3e649474ff786/0_0_4800_3200/master/4800.jpg?width=640&quality=45&auto=format&fit=max&dpr=2&s=f7926915234cc22c9fe718771f5837cc 1280w"></source> <source media="(min-width: 980px)" sizes="640px" srcset="https://i.guim.co.uk/img/media/05cb692c634cd90e5411aab92ca3e649474ff786/0_0_4800_3200/master/4800.jpg?width=640&quality=85&auto=format&fit=max&s=fa3edf920739ca39d41e3fce38ab277b 640w"></source> <source media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" sizes="620px" srcset="https://i.guim.co.uk/img/media/05cb692c634cd90e5411aab92ca3e649474ff786/0_0_4800_3200/master/4800.jpg?width=620&quality=45&auto=format&fit=max&dpr=2&s=f9fd7969943957bd4893fe29d248626c 1240w"></source> <source media="(min-width: 660px)" sizes="620px" srcset="https://i.guim.co.uk/img/media/05cb692c634cd90e5411aab92ca3e649474ff786/0_0_4800_3200/master/4800.jpg?width=620&quality=85&auto=format&fit=max&s=61ab70443d54f672febc609b4bfbc5c0 620w"></source> <source media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" sizes="605px" srcset="https://i.guim.co.uk/img/media/05cb692c634cd90e5411aab92ca3e649474ff786/0_0_4800_3200/master/4800.jpg?width=605&quality=45&auto=format&fit=max&dpr=2&s=a416bff5ba9e0d62f1634aee83308528 1210w"></source> <source media="(min-width: 480px)" sizes="605px" srcset="https://i.guim.co.uk/img/media/05cb692c634cd90e5411aab92ca3e649474ff786/0_0_4800_3200/master/4800.jpg?width=605&quality=85&auto=format&fit=max&s=5ae3b22ecb3c7bde8b49a212d52b707c 605w"></source> <source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 0px) and (min-resolution: 120dpi)" sizes="445px" srcset="https://i.guim.co.uk/img/media/05cb692c634cd90e5411aab92ca3e649474ff786/0_0_4800_3200/master/4800.jpg?width=445&quality=45&auto=format&fit=max&dpr=2&s=c43d04fbea54b99991b541ce674da43d 890w"></source> <source media="(min-width: 0px)" sizes="445px" srcset="https://i.guim.co.uk/img/media/05cb692c634cd90e5411aab92ca3e649474ff786/0_0_4800_3200/master/4800.jpg?width=445&quality=85&auto=format&fit=max&s=a0c813b07b8d5b99a33a7133ea7185db 445w"></source>
|
<source media="(min-width: 1300px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 1300px) and (min-resolution: 120dpi)" sizes="880px" srcset="https://i.guim.co.uk/img/media/05cb692c634cd90e5411aab92ca3e649474ff786/0_0_4800_3200/master/4800.jpg?width=880&quality=45&auto=format&fit=max&dpr=2&s=adbbf5d870d9cc7f0b9a24eb5472ebf3 1760w"></source> <source media="(min-width: 1300px)" sizes="880px" srcset="https://i.guim.co.uk/img/media/05cb692c634cd90e5411aab92ca3e649474ff786/0_0_4800_3200/master/4800.jpg?width=880&quality=85&auto=format&fit=max&s=f0a6d8fa60b5571e9e0e9a5673e407b7 880w"></source> <source media="(min-width: 1140px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 1140px) and (min-resolution: 120dpi)" sizes="800px" srcset="https://i.guim.co.uk/img/media/05cb692c634cd90e5411aab92ca3e649474ff786/0_0_4800_3200/master/4800.jpg?width=800&quality=45&auto=format&fit=max&dpr=2&s=d39897e20bb677fda3feb14113aad381 1600w"></source> <source media="(min-width: 1140px)" sizes="800px" srcset="https://i.guim.co.uk/img/media/05cb692c634cd90e5411aab92ca3e649474ff786/0_0_4800_3200/master/4800.jpg?width=800&quality=85&auto=format&fit=max&s=dbf240ee147c5a0a43321f1634ee41eb 800w"></source> <source media="(min-width: 980px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 980px) and (min-resolution: 120dpi)" sizes="640px" srcset="https://i.guim.co.uk/img/media/05cb692c634cd90e5411aab92ca3e649474ff786/0_0_4800_3200/master/4800.jpg?width=640&quality=45&auto=format&fit=max&dpr=2&s=f7926915234cc22c9fe718771f5837cc 1280w"></source> <source media="(min-width: 980px)" sizes="640px" srcset="https://i.guim.co.uk/img/media/05cb692c634cd90e5411aab92ca3e649474ff786/0_0_4800_3200/master/4800.jpg?width=640&quality=85&auto=format&fit=max&s=fa3edf920739ca39d41e3fce38ab277b 640w"></source> <source media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" sizes="620px" srcset="https://i.guim.co.uk/img/media/05cb692c634cd90e5411aab92ca3e649474ff786/0_0_4800_3200/master/4800.jpg?width=620&quality=45&auto=format&fit=max&dpr=2&s=f9fd7969943957bd4893fe29d248626c 1240w"></source> <source media="(min-width: 660px)" sizes="620px" srcset="https://i.guim.co.uk/img/media/05cb692c634cd90e5411aab92ca3e649474ff786/0_0_4800_3200/master/4800.jpg?width=620&quality=85&auto=format&fit=max&s=61ab70443d54f672febc609b4bfbc5c0 620w"></source> <source media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" sizes="605px" srcset="https://i.guim.co.uk/img/media/05cb692c634cd90e5411aab92ca3e649474ff786/0_0_4800_3200/master/4800.jpg?width=605&quality=45&auto=format&fit=max&dpr=2&s=a416bff5ba9e0d62f1634aee83308528 1210w"></source> <source media="(min-width: 480px)" sizes="605px" srcset="https://i.guim.co.uk/img/media/05cb692c634cd90e5411aab92ca3e649474ff786/0_0_4800_3200/master/4800.jpg?width=605&quality=85&auto=format&fit=max&s=5ae3b22ecb3c7bde8b49a212d52b707c 605w"></source> <source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 0px) and (min-resolution: 120dpi)" sizes="445px" srcset="https://i.guim.co.uk/img/media/05cb692c634cd90e5411aab92ca3e649474ff786/0_0_4800_3200/master/4800.jpg?width=445&quality=45&auto=format&fit=max&dpr=2&s=c43d04fbea54b99991b541ce674da43d 890w"></source> <source media="(min-width: 0px)" sizes="445px" srcset="https://i.guim.co.uk/img/media/05cb692c634cd90e5411aab92ca3e649474ff786/0_0_4800_3200/master/4800.jpg?width=445&quality=85&auto=format&fit=max&s=a0c813b07b8d5b99a33a7133ea7185db 445w"></source>
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
<meta itemprop="url" content="https://i.guim.co.uk/img/media/98c683a7df9c83b2c13de2d93ca1825199ed5150/0_0_4800_3166/master/4800.jpg?width=700&quality=85&auto=format&fit=max&s=d2432083289db6bd42f6ad7adc64a78d">
|
<meta itemprop="url" content="https://i.guim.co.uk/img/media/98c683a7df9c83b2c13de2d93ca1825199ed5150/0_0_4800_3166/master/4800.jpg?width=700&quality=85&auto=format&fit=max&s=d2432083289db6bd42f6ad7adc64a78d">
|
||||||
<meta itemprop="width" content="4800">
|
<meta itemprop="width" content="4800">
|
||||||
<meta itemprop="height" content="3166">
|
<meta itemprop="height" content="3166">
|
||||||
<a href="http://fakehost/test/base/#img-3" data-link-name="Launch Article Lightbox" data-is-ajax="" target="_blank">
|
<a href="#img-3" data-link-name="Launch Article Lightbox" data-is-ajax="">
|
||||||
<div>
|
<div>
|
||||||
<picture>
|
<picture>
|
||||||
<source media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" sizes="620px" srcset="https://i.guim.co.uk/img/media/98c683a7df9c83b2c13de2d93ca1825199ed5150/0_0_4800_3166/master/4800.jpg?width=620&quality=45&auto=format&fit=max&dpr=2&s=7234718ccc92b4251bdfe4c505f064f8 1240w"></source> <source media="(min-width: 660px)" sizes="620px" srcset="https://i.guim.co.uk/img/media/98c683a7df9c83b2c13de2d93ca1825199ed5150/0_0_4800_3166/master/4800.jpg?width=620&quality=85&auto=format&fit=max&s=b80f7e8fcfbbe8e12fa6954ddeb3bd1e 620w"></source> <source media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" sizes="605px" srcset="https://i.guim.co.uk/img/media/98c683a7df9c83b2c13de2d93ca1825199ed5150/0_0_4800_3166/master/4800.jpg?width=605&quality=45&auto=format&fit=max&dpr=2&s=78ebc960d0c15f627bfbe60cd770a139 1210w"></source> <source media="(min-width: 480px)" sizes="605px" srcset="https://i.guim.co.uk/img/media/98c683a7df9c83b2c13de2d93ca1825199ed5150/0_0_4800_3166/master/4800.jpg?width=605&quality=85&auto=format&fit=max&s=1319684ba57c18162a45e56384d418b0 605w"></source> <source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 0px) and (min-resolution: 120dpi)" sizes="445px" srcset="https://i.guim.co.uk/img/media/98c683a7df9c83b2c13de2d93ca1825199ed5150/0_0_4800_3166/master/4800.jpg?width=445&quality=45&auto=format&fit=max&dpr=2&s=3170b3a80d76d6c6422b65045444829e 890w"></source> <source media="(min-width: 0px)" sizes="445px" srcset="https://i.guim.co.uk/img/media/98c683a7df9c83b2c13de2d93ca1825199ed5150/0_0_4800_3166/master/4800.jpg?width=445&quality=85&auto=format&fit=max&s=e835570164cc241d4009af47fc1051f7 445w"></source>
|
<source media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" sizes="620px" srcset="https://i.guim.co.uk/img/media/98c683a7df9c83b2c13de2d93ca1825199ed5150/0_0_4800_3166/master/4800.jpg?width=620&quality=45&auto=format&fit=max&dpr=2&s=7234718ccc92b4251bdfe4c505f064f8 1240w"></source> <source media="(min-width: 660px)" sizes="620px" srcset="https://i.guim.co.uk/img/media/98c683a7df9c83b2c13de2d93ca1825199ed5150/0_0_4800_3166/master/4800.jpg?width=620&quality=85&auto=format&fit=max&s=b80f7e8fcfbbe8e12fa6954ddeb3bd1e 620w"></source> <source media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" sizes="605px" srcset="https://i.guim.co.uk/img/media/98c683a7df9c83b2c13de2d93ca1825199ed5150/0_0_4800_3166/master/4800.jpg?width=605&quality=45&auto=format&fit=max&dpr=2&s=78ebc960d0c15f627bfbe60cd770a139 1210w"></source> <source media="(min-width: 480px)" sizes="605px" srcset="https://i.guim.co.uk/img/media/98c683a7df9c83b2c13de2d93ca1825199ed5150/0_0_4800_3166/master/4800.jpg?width=605&quality=85&auto=format&fit=max&s=1319684ba57c18162a45e56384d418b0 605w"></source> <source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 0px) and (min-resolution: 120dpi)" sizes="445px" srcset="https://i.guim.co.uk/img/media/98c683a7df9c83b2c13de2d93ca1825199ed5150/0_0_4800_3166/master/4800.jpg?width=445&quality=45&auto=format&fit=max&dpr=2&s=3170b3a80d76d6c6422b65045444829e 890w"></source> <source media="(min-width: 0px)" sizes="445px" srcset="https://i.guim.co.uk/img/media/98c683a7df9c83b2c13de2d93ca1825199ed5150/0_0_4800_3166/master/4800.jpg?width=445&quality=85&auto=format&fit=max&s=e835570164cc241d4009af47fc1051f7 445w"></source>
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
<meta itemprop="url" content="https://i.guim.co.uk/img/media/0447972cf47ca67882fcfc648edf7e574b0853bc/0_0_4800_3200/master/4800.jpg?width=700&quality=85&auto=format&fit=max&s=0e7302276c6cc7cb65be9bcdacd3081f">
|
<meta itemprop="url" content="https://i.guim.co.uk/img/media/0447972cf47ca67882fcfc648edf7e574b0853bc/0_0_4800_3200/master/4800.jpg?width=700&quality=85&auto=format&fit=max&s=0e7302276c6cc7cb65be9bcdacd3081f">
|
||||||
<meta itemprop="width" content="4800">
|
<meta itemprop="width" content="4800">
|
||||||
<meta itemprop="height" content="3200">
|
<meta itemprop="height" content="3200">
|
||||||
<a href="http://fakehost/test/base/#img-4" data-link-name="Launch Article Lightbox" data-is-ajax="" target="_blank">
|
<a href="#img-4" data-link-name="Launch Article Lightbox" data-is-ajax="">
|
||||||
<div>
|
<div>
|
||||||
<picture>
|
<picture>
|
||||||
<source media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" sizes="620px" srcset="https://i.guim.co.uk/img/media/0447972cf47ca67882fcfc648edf7e574b0853bc/0_0_4800_3200/master/4800.jpg?width=620&quality=45&auto=format&fit=max&dpr=2&s=933c5693fbf9195f6e83a8928283f85e 1240w"></source> <source media="(min-width: 660px)" sizes="620px" srcset="https://i.guim.co.uk/img/media/0447972cf47ca67882fcfc648edf7e574b0853bc/0_0_4800_3200/master/4800.jpg?width=620&quality=85&auto=format&fit=max&s=e07b988894308f3bfc052d1ff9dfc1e2 620w"></source> <source media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" sizes="605px" srcset="https://i.guim.co.uk/img/media/0447972cf47ca67882fcfc648edf7e574b0853bc/0_0_4800_3200/master/4800.jpg?width=605&quality=45&auto=format&fit=max&dpr=2&s=113cf92fe80bc5996634c34b3c7a0c09 1210w"></source> <source media="(min-width: 480px)" sizes="605px" srcset="https://i.guim.co.uk/img/media/0447972cf47ca67882fcfc648edf7e574b0853bc/0_0_4800_3200/master/4800.jpg?width=605&quality=85&auto=format&fit=max&s=5a7358223e80941bd1b0e0f427beefde 605w"></source> <source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 0px) and (min-resolution: 120dpi)" sizes="445px" srcset="https://i.guim.co.uk/img/media/0447972cf47ca67882fcfc648edf7e574b0853bc/0_0_4800_3200/master/4800.jpg?width=445&quality=45&auto=format&fit=max&dpr=2&s=292e941797de1671c185c1b074c688ad 890w"></source> <source media="(min-width: 0px)" sizes="445px" srcset="https://i.guim.co.uk/img/media/0447972cf47ca67882fcfc648edf7e574b0853bc/0_0_4800_3200/master/4800.jpg?width=445&quality=85&auto=format&fit=max&s=d1bc1c4d9341f9b6d63b64861a3de711 445w"></source>
|
<source media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" sizes="620px" srcset="https://i.guim.co.uk/img/media/0447972cf47ca67882fcfc648edf7e574b0853bc/0_0_4800_3200/master/4800.jpg?width=620&quality=45&auto=format&fit=max&dpr=2&s=933c5693fbf9195f6e83a8928283f85e 1240w"></source> <source media="(min-width: 660px)" sizes="620px" srcset="https://i.guim.co.uk/img/media/0447972cf47ca67882fcfc648edf7e574b0853bc/0_0_4800_3200/master/4800.jpg?width=620&quality=85&auto=format&fit=max&s=e07b988894308f3bfc052d1ff9dfc1e2 620w"></source> <source media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" sizes="605px" srcset="https://i.guim.co.uk/img/media/0447972cf47ca67882fcfc648edf7e574b0853bc/0_0_4800_3200/master/4800.jpg?width=605&quality=45&auto=format&fit=max&dpr=2&s=113cf92fe80bc5996634c34b3c7a0c09 1210w"></source> <source media="(min-width: 480px)" sizes="605px" srcset="https://i.guim.co.uk/img/media/0447972cf47ca67882fcfc648edf7e574b0853bc/0_0_4800_3200/master/4800.jpg?width=605&quality=85&auto=format&fit=max&s=5a7358223e80941bd1b0e0f427beefde 605w"></source> <source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 0px) and (min-resolution: 120dpi)" sizes="445px" srcset="https://i.guim.co.uk/img/media/0447972cf47ca67882fcfc648edf7e574b0853bc/0_0_4800_3200/master/4800.jpg?width=445&quality=45&auto=format&fit=max&dpr=2&s=292e941797de1671c185c1b074c688ad 890w"></source> <source media="(min-width: 0px)" sizes="445px" srcset="https://i.guim.co.uk/img/media/0447972cf47ca67882fcfc648edf7e574b0853bc/0_0_4800_3200/master/4800.jpg?width=445&quality=85&auto=format&fit=max&s=d1bc1c4d9341f9b6d63b64861a3de711 445w"></source>
|
||||||
|
@ -77,7 +77,7 @@
|
||||||
<meta itemprop="url" content="https://i.guim.co.uk/img/media/416800b8d06039780c3e6de28564e6f277b4e7b7/0_0_4800_3200/master/4800.jpg?width=700&quality=85&auto=format&fit=max&s=249ddc3119aa637c3a1ae4998509f604">
|
<meta itemprop="url" content="https://i.guim.co.uk/img/media/416800b8d06039780c3e6de28564e6f277b4e7b7/0_0_4800_3200/master/4800.jpg?width=700&quality=85&auto=format&fit=max&s=249ddc3119aa637c3a1ae4998509f604">
|
||||||
<meta itemprop="width" content="4800">
|
<meta itemprop="width" content="4800">
|
||||||
<meta itemprop="height" content="3200">
|
<meta itemprop="height" content="3200">
|
||||||
<a href="http://fakehost/test/base/#img-5" data-link-name="Launch Article Lightbox" data-is-ajax="" target="_blank">
|
<a href="#img-5" data-link-name="Launch Article Lightbox" data-is-ajax="">
|
||||||
<div>
|
<div>
|
||||||
<picture>
|
<picture>
|
||||||
<source media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" sizes="620px" srcset="https://i.guim.co.uk/img/media/416800b8d06039780c3e6de28564e6f277b4e7b7/0_0_4800_3200/master/4800.jpg?width=620&quality=45&auto=format&fit=max&dpr=2&s=4197b7a2bc3c7e32d3eaee927b9d08e6 1240w"></source> <source media="(min-width: 660px)" sizes="620px" srcset="https://i.guim.co.uk/img/media/416800b8d06039780c3e6de28564e6f277b4e7b7/0_0_4800_3200/master/4800.jpg?width=620&quality=85&auto=format&fit=max&s=82d6908c6ffe622566e1cc6513d60ddd 620w"></source> <source media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" sizes="605px" srcset="https://i.guim.co.uk/img/media/416800b8d06039780c3e6de28564e6f277b4e7b7/0_0_4800_3200/master/4800.jpg?width=605&quality=45&auto=format&fit=max&dpr=2&s=222e300fb2a60da1a841fbbc2bc8f752 1210w"></source> <source media="(min-width: 480px)" sizes="605px" srcset="https://i.guim.co.uk/img/media/416800b8d06039780c3e6de28564e6f277b4e7b7/0_0_4800_3200/master/4800.jpg?width=605&quality=85&auto=format&fit=max&s=63ba1cfe4b5e7c7d741d311d58997fcf 605w"></source> <source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 0px) and (min-resolution: 120dpi)" sizes="445px" srcset="https://i.guim.co.uk/img/media/416800b8d06039780c3e6de28564e6f277b4e7b7/0_0_4800_3200/master/4800.jpg?width=445&quality=45&auto=format&fit=max&dpr=2&s=231139825b311ede8d01e6c702d6d12c 890w"></source> <source media="(min-width: 0px)" sizes="445px" srcset="https://i.guim.co.uk/img/media/416800b8d06039780c3e6de28564e6f277b4e7b7/0_0_4800_3200/master/4800.jpg?width=445&quality=85&auto=format&fit=max&s=1065dd4439e14c72fe520c19566172e2 445w"></source>
|
<source media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" sizes="620px" srcset="https://i.guim.co.uk/img/media/416800b8d06039780c3e6de28564e6f277b4e7b7/0_0_4800_3200/master/4800.jpg?width=620&quality=45&auto=format&fit=max&dpr=2&s=4197b7a2bc3c7e32d3eaee927b9d08e6 1240w"></source> <source media="(min-width: 660px)" sizes="620px" srcset="https://i.guim.co.uk/img/media/416800b8d06039780c3e6de28564e6f277b4e7b7/0_0_4800_3200/master/4800.jpg?width=620&quality=85&auto=format&fit=max&s=82d6908c6ffe622566e1cc6513d60ddd 620w"></source> <source media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" sizes="605px" srcset="https://i.guim.co.uk/img/media/416800b8d06039780c3e6de28564e6f277b4e7b7/0_0_4800_3200/master/4800.jpg?width=605&quality=45&auto=format&fit=max&dpr=2&s=222e300fb2a60da1a841fbbc2bc8f752 1210w"></source> <source media="(min-width: 480px)" sizes="605px" srcset="https://i.guim.co.uk/img/media/416800b8d06039780c3e6de28564e6f277b4e7b7/0_0_4800_3200/master/4800.jpg?width=605&quality=85&auto=format&fit=max&s=63ba1cfe4b5e7c7d741d311d58997fcf 605w"></source> <source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 0px) and (min-resolution: 120dpi)" sizes="445px" srcset="https://i.guim.co.uk/img/media/416800b8d06039780c3e6de28564e6f277b4e7b7/0_0_4800_3200/master/4800.jpg?width=445&quality=45&auto=format&fit=max&dpr=2&s=231139825b311ede8d01e6c702d6d12c 890w"></source> <source media="(min-width: 0px)" sizes="445px" srcset="https://i.guim.co.uk/img/media/416800b8d06039780c3e6de28564e6f277b4e7b7/0_0_4800_3200/master/4800.jpg?width=445&quality=85&auto=format&fit=max&s=1065dd4439e14c72fe520c19566172e2 445w"></source>
|
||||||
|
@ -90,7 +90,7 @@
|
||||||
<meta itemprop="url" content="https://i.guim.co.uk/img/media/8c207197c0a9e6f407dcddfded5f868a142c9cab/0_0_4800_3200/master/4800.jpg?width=700&quality=85&auto=format&fit=max&s=bcfefc5593dcc2bdb0dd3b0543cfa4eb">
|
<meta itemprop="url" content="https://i.guim.co.uk/img/media/8c207197c0a9e6f407dcddfded5f868a142c9cab/0_0_4800_3200/master/4800.jpg?width=700&quality=85&auto=format&fit=max&s=bcfefc5593dcc2bdb0dd3b0543cfa4eb">
|
||||||
<meta itemprop="width" content="4800">
|
<meta itemprop="width" content="4800">
|
||||||
<meta itemprop="height" content="3200">
|
<meta itemprop="height" content="3200">
|
||||||
<a href="http://fakehost/test/base/#img-6" data-link-name="Launch Article Lightbox" data-is-ajax="" target="_blank">
|
<a href="#img-6" data-link-name="Launch Article Lightbox" data-is-ajax="">
|
||||||
<div>
|
<div>
|
||||||
<picture>
|
<picture>
|
||||||
<source media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" sizes="620px" srcset="https://i.guim.co.uk/img/media/8c207197c0a9e6f407dcddfded5f868a142c9cab/0_0_4800_3200/master/4800.jpg?width=620&quality=45&auto=format&fit=max&dpr=2&s=d272c4dc57408daa0dcdf5461a230e9e 1240w"></source> <source media="(min-width: 660px)" sizes="620px" srcset="https://i.guim.co.uk/img/media/8c207197c0a9e6f407dcddfded5f868a142c9cab/0_0_4800_3200/master/4800.jpg?width=620&quality=85&auto=format&fit=max&s=890f0e0cee54663a90292471a16f95d2 620w"></source> <source media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" sizes="605px" srcset="https://i.guim.co.uk/img/media/8c207197c0a9e6f407dcddfded5f868a142c9cab/0_0_4800_3200/master/4800.jpg?width=605&quality=45&auto=format&fit=max&dpr=2&s=59a57c5bded93fe0efe0046226fe7c69 1210w"></source> <source media="(min-width: 480px)" sizes="605px" srcset="https://i.guim.co.uk/img/media/8c207197c0a9e6f407dcddfded5f868a142c9cab/0_0_4800_3200/master/4800.jpg?width=605&quality=85&auto=format&fit=max&s=f1b2a4c79e965aa76a322ad25072a052 605w"></source> <source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 0px) and (min-resolution: 120dpi)" sizes="445px" srcset="https://i.guim.co.uk/img/media/8c207197c0a9e6f407dcddfded5f868a142c9cab/0_0_4800_3200/master/4800.jpg?width=445&quality=45&auto=format&fit=max&dpr=2&s=ffbdfd671eb45e3a87e3dc9137e8b006 890w"></source> <source media="(min-width: 0px)" sizes="445px" srcset="https://i.guim.co.uk/img/media/8c207197c0a9e6f407dcddfded5f868a142c9cab/0_0_4800_3200/master/4800.jpg?width=445&quality=85&auto=format&fit=max&s=c560f0b0ef9736c1a66215cc29c59d43 445w"></source>
|
<source media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" sizes="620px" srcset="https://i.guim.co.uk/img/media/8c207197c0a9e6f407dcddfded5f868a142c9cab/0_0_4800_3200/master/4800.jpg?width=620&quality=45&auto=format&fit=max&dpr=2&s=d272c4dc57408daa0dcdf5461a230e9e 1240w"></source> <source media="(min-width: 660px)" sizes="620px" srcset="https://i.guim.co.uk/img/media/8c207197c0a9e6f407dcddfded5f868a142c9cab/0_0_4800_3200/master/4800.jpg?width=620&quality=85&auto=format&fit=max&s=890f0e0cee54663a90292471a16f95d2 620w"></source> <source media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" sizes="605px" srcset="https://i.guim.co.uk/img/media/8c207197c0a9e6f407dcddfded5f868a142c9cab/0_0_4800_3200/master/4800.jpg?width=605&quality=45&auto=format&fit=max&dpr=2&s=59a57c5bded93fe0efe0046226fe7c69 1210w"></source> <source media="(min-width: 480px)" sizes="605px" srcset="https://i.guim.co.uk/img/media/8c207197c0a9e6f407dcddfded5f868a142c9cab/0_0_4800_3200/master/4800.jpg?width=605&quality=85&auto=format&fit=max&s=f1b2a4c79e965aa76a322ad25072a052 605w"></source> <source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 0px) and (min-resolution: 120dpi)" sizes="445px" srcset="https://i.guim.co.uk/img/media/8c207197c0a9e6f407dcddfded5f868a142c9cab/0_0_4800_3200/master/4800.jpg?width=445&quality=45&auto=format&fit=max&dpr=2&s=ffbdfd671eb45e3a87e3dc9137e8b006 890w"></source> <source media="(min-width: 0px)" sizes="445px" srcset="https://i.guim.co.uk/img/media/8c207197c0a9e6f407dcddfded5f868a142c9cab/0_0_4800_3200/master/4800.jpg?width=445&quality=85&auto=format&fit=max&s=c560f0b0ef9736c1a66215cc29c59d43 445w"></source>
|
||||||
|
@ -137,7 +137,7 @@
|
||||||
<meta itemprop="url" content="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=700&quality=85&auto=format&fit=max&s=d73916fda0f6c60b5eebcb71fea643e9">
|
<meta itemprop="url" content="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=700&quality=85&auto=format&fit=max&s=d73916fda0f6c60b5eebcb71fea643e9">
|
||||||
<meta itemprop="width" content="4800">
|
<meta itemprop="width" content="4800">
|
||||||
<meta itemprop="height" content="2334">
|
<meta itemprop="height" content="2334">
|
||||||
<a href="http://fakehost/test/base/#img-7" data-link-name="Launch Article Lightbox" data-is-ajax="" target="_blank">
|
<a href="#img-7" data-link-name="Launch Article Lightbox" data-is-ajax="">
|
||||||
<div>
|
<div>
|
||||||
<picture>
|
<picture>
|
||||||
<source media="(min-width: 1300px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 1300px) and (min-resolution: 120dpi)" sizes="1300px" srcset="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=1300&quality=45&auto=format&fit=max&dpr=2&s=524b92a6590a1b5c139bfe50581476a1 2600w"></source> <source media="(min-width: 1300px)" sizes="1300px" srcset="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=1300&quality=85&auto=format&fit=max&s=837d7df48e565ffad49febab20fbd179 1300w"></source> <source media="(min-width: 1140px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 1140px) and (min-resolution: 120dpi)" sizes="1140px" srcset="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=1140&quality=45&auto=format&fit=max&dpr=2&s=fe98f4515ae3490f53804235a4dcf84b 2280w"></source> <source media="(min-width: 1140px)" sizes="1140px" srcset="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=1140&quality=85&auto=format&fit=max&s=a3ec73ab7f20798ec264f5ecb59f6bcc 1140w"></source> <source media="(min-width: 980px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 980px) and (min-resolution: 120dpi)" sizes="1125px" srcset="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=1125&quality=45&auto=format&fit=max&dpr=2&s=3ac3fd319accb248cf8a13e8ef55ebcc 2250w"></source> <source media="(min-width: 980px)" sizes="1125px" srcset="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=1125&quality=85&auto=format&fit=max&s=2561c80af0d0e8eed2fc7c535be48696 1125w"></source> <source media="(min-width: 740px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 740px) and (min-resolution: 120dpi)" sizes="965px" srcset="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=965&quality=45&auto=format&fit=max&dpr=2&s=539617a30ea852b01218eec69d6066e6 1930w"></source> <source media="(min-width: 740px)" sizes="965px" srcset="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=965&quality=85&auto=format&fit=max&s=624139eae65dd4c96efd1a90243b9286 965w"></source> <source media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" sizes="725px" srcset="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=725&quality=45&auto=format&fit=max&dpr=2&s=633619afab6a0ee26a3839b69160e854 1450w"></source> <source media="(min-width: 660px)" sizes="725px" srcset="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=725&quality=85&auto=format&fit=max&s=98b9351340e8ee30063a4b6eb6501d6f 725w"></source> <source media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" sizes="645px" srcset="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=645&quality=45&auto=format&fit=max&dpr=2&s=e11a31f8adaab06b457fd9c7dda6bf6d 1290w"></source> <source media="(min-width: 480px)" sizes="645px" srcset="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=645&quality=85&auto=format&fit=max&s=912104c53b38d1cd424bfb82302480e1 645w"></source> <source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 0px) and (min-resolution: 120dpi)" sizes="465px" srcset="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=465&quality=45&auto=format&fit=max&dpr=2&s=209259fab8ec9e81386838f2d5cdecc3 930w"></source> <source media="(min-width: 0px)" sizes="465px" srcset="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=465&quality=85&auto=format&fit=max&s=06848a63793084a21bc86aa613b126a7 465w"></source>
|
<source media="(min-width: 1300px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 1300px) and (min-resolution: 120dpi)" sizes="1300px" srcset="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=1300&quality=45&auto=format&fit=max&dpr=2&s=524b92a6590a1b5c139bfe50581476a1 2600w"></source> <source media="(min-width: 1300px)" sizes="1300px" srcset="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=1300&quality=85&auto=format&fit=max&s=837d7df48e565ffad49febab20fbd179 1300w"></source> <source media="(min-width: 1140px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 1140px) and (min-resolution: 120dpi)" sizes="1140px" srcset="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=1140&quality=45&auto=format&fit=max&dpr=2&s=fe98f4515ae3490f53804235a4dcf84b 2280w"></source> <source media="(min-width: 1140px)" sizes="1140px" srcset="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=1140&quality=85&auto=format&fit=max&s=a3ec73ab7f20798ec264f5ecb59f6bcc 1140w"></source> <source media="(min-width: 980px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 980px) and (min-resolution: 120dpi)" sizes="1125px" srcset="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=1125&quality=45&auto=format&fit=max&dpr=2&s=3ac3fd319accb248cf8a13e8ef55ebcc 2250w"></source> <source media="(min-width: 980px)" sizes="1125px" srcset="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=1125&quality=85&auto=format&fit=max&s=2561c80af0d0e8eed2fc7c535be48696 1125w"></source> <source media="(min-width: 740px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 740px) and (min-resolution: 120dpi)" sizes="965px" srcset="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=965&quality=45&auto=format&fit=max&dpr=2&s=539617a30ea852b01218eec69d6066e6 1930w"></source> <source media="(min-width: 740px)" sizes="965px" srcset="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=965&quality=85&auto=format&fit=max&s=624139eae65dd4c96efd1a90243b9286 965w"></source> <source media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" sizes="725px" srcset="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=725&quality=45&auto=format&fit=max&dpr=2&s=633619afab6a0ee26a3839b69160e854 1450w"></source> <source media="(min-width: 660px)" sizes="725px" srcset="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=725&quality=85&auto=format&fit=max&s=98b9351340e8ee30063a4b6eb6501d6f 725w"></source> <source media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" sizes="645px" srcset="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=645&quality=45&auto=format&fit=max&dpr=2&s=e11a31f8adaab06b457fd9c7dda6bf6d 1290w"></source> <source media="(min-width: 480px)" sizes="645px" srcset="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=645&quality=85&auto=format&fit=max&s=912104c53b38d1cd424bfb82302480e1 645w"></source> <source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 0px) and (min-resolution: 120dpi)" sizes="465px" srcset="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=465&quality=45&auto=format&fit=max&dpr=2&s=209259fab8ec9e81386838f2d5cdecc3 930w"></source> <source media="(min-width: 0px)" sizes="465px" srcset="https://i.guim.co.uk/img/media/0d13adeb0790af5c5fa317ce477c323d0e1c773c/0_0_4800_2334/master/4800.jpg?width=465&quality=85&auto=format&fit=max&s=06848a63793084a21bc86aa613b126a7 465w"></source>
|
||||||
|
@ -163,7 +163,7 @@
|
||||||
<meta itemprop="url" content="https://i.guim.co.uk/img/media/4973b41f53b8ade499f99a305b01157eca659ca5/0_0_1200_900/master/1200.jpg?width=700&quality=85&auto=format&fit=max&s=ee921715aaf10e0816dcf15dfc3a21f5">
|
<meta itemprop="url" content="https://i.guim.co.uk/img/media/4973b41f53b8ade499f99a305b01157eca659ca5/0_0_1200_900/master/1200.jpg?width=700&quality=85&auto=format&fit=max&s=ee921715aaf10e0816dcf15dfc3a21f5">
|
||||||
<meta itemprop="width" content="1200">
|
<meta itemprop="width" content="1200">
|
||||||
<meta itemprop="height" content="900">
|
<meta itemprop="height" content="900">
|
||||||
<a href="http://fakehost/test/base/#img-8" data-link-name="Launch Article Lightbox" data-is-ajax="" target="_blank">
|
<a href="#img-8" data-link-name="Launch Article Lightbox" data-is-ajax="">
|
||||||
<div>
|
<div>
|
||||||
<picture>
|
<picture>
|
||||||
<source media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" sizes="620px" srcset="https://i.guim.co.uk/img/media/4973b41f53b8ade499f99a305b01157eca659ca5/0_0_1200_900/master/1200.jpg?width=620&quality=45&auto=format&fit=max&dpr=2&s=8eb5af62092c8a0eb0d283cb0887f5c5 1240w"></source> <source media="(min-width: 660px)" sizes="620px" srcset="https://i.guim.co.uk/img/media/4973b41f53b8ade499f99a305b01157eca659ca5/0_0_1200_900/master/1200.jpg?width=620&quality=85&auto=format&fit=max&s=9ace0f595be568263c5991993632dae8 620w"></source> <source media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" sizes="605px" srcset="https://i.guim.co.uk/img/media/4973b41f53b8ade499f99a305b01157eca659ca5/0_0_1200_900/master/1200.jpg?width=605&quality=45&auto=format&fit=max&dpr=2&s=97219f131f1013d15fed7c63308f2b2f 1210w"></source> <source media="(min-width: 480px)" sizes="605px" srcset="https://i.guim.co.uk/img/media/4973b41f53b8ade499f99a305b01157eca659ca5/0_0_1200_900/master/1200.jpg?width=605&quality=85&auto=format&fit=max&s=17191691b6cd81c2a67730d5475db08b 605w"></source> <source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 0px) and (min-resolution: 120dpi)" sizes="445px" srcset="https://i.guim.co.uk/img/media/4973b41f53b8ade499f99a305b01157eca659ca5/0_0_1200_900/master/1200.jpg?width=445&quality=45&auto=format&fit=max&dpr=2&s=30d51b75767551399ba174bae5c39e94 890w"></source> <source media="(min-width: 0px)" sizes="445px" srcset="https://i.guim.co.uk/img/media/4973b41f53b8ade499f99a305b01157eca659ca5/0_0_1200_900/master/1200.jpg?width=445&quality=85&auto=format&fit=max&s=936568b6e7da0a710abcd2c015fd0a8b 445w"></source>
|
<source media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" sizes="620px" srcset="https://i.guim.co.uk/img/media/4973b41f53b8ade499f99a305b01157eca659ca5/0_0_1200_900/master/1200.jpg?width=620&quality=45&auto=format&fit=max&dpr=2&s=8eb5af62092c8a0eb0d283cb0887f5c5 1240w"></source> <source media="(min-width: 660px)" sizes="620px" srcset="https://i.guim.co.uk/img/media/4973b41f53b8ade499f99a305b01157eca659ca5/0_0_1200_900/master/1200.jpg?width=620&quality=85&auto=format&fit=max&s=9ace0f595be568263c5991993632dae8 620w"></source> <source media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" sizes="605px" srcset="https://i.guim.co.uk/img/media/4973b41f53b8ade499f99a305b01157eca659ca5/0_0_1200_900/master/1200.jpg?width=605&quality=45&auto=format&fit=max&dpr=2&s=97219f131f1013d15fed7c63308f2b2f 1210w"></source> <source media="(min-width: 480px)" sizes="605px" srcset="https://i.guim.co.uk/img/media/4973b41f53b8ade499f99a305b01157eca659ca5/0_0_1200_900/master/1200.jpg?width=605&quality=85&auto=format&fit=max&s=17191691b6cd81c2a67730d5475db08b 605w"></source> <source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 0px) and (min-resolution: 120dpi)" sizes="445px" srcset="https://i.guim.co.uk/img/media/4973b41f53b8ade499f99a305b01157eca659ca5/0_0_1200_900/master/1200.jpg?width=445&quality=45&auto=format&fit=max&dpr=2&s=30d51b75767551399ba174bae5c39e94 890w"></source> <source media="(min-width: 0px)" sizes="445px" srcset="https://i.guim.co.uk/img/media/4973b41f53b8ade499f99a305b01157eca659ca5/0_0_1200_900/master/1200.jpg?width=445&quality=85&auto=format&fit=max&s=936568b6e7da0a710abcd2c015fd0a8b 445w"></source>
|
||||||
|
@ -189,7 +189,7 @@
|
||||||
<meta itemprop="url" content="https://i.guim.co.uk/img/media/d1941b6a6908314fab28f44da222a4c892213341/0_0_4800_3120/master/4800.jpg?width=700&quality=85&auto=format&fit=max&s=4e46b70079819caee86359a058c92be1">
|
<meta itemprop="url" content="https://i.guim.co.uk/img/media/d1941b6a6908314fab28f44da222a4c892213341/0_0_4800_3120/master/4800.jpg?width=700&quality=85&auto=format&fit=max&s=4e46b70079819caee86359a058c92be1">
|
||||||
<meta itemprop="width" content="4800">
|
<meta itemprop="width" content="4800">
|
||||||
<meta itemprop="height" content="3120">
|
<meta itemprop="height" content="3120">
|
||||||
<a href="http://fakehost/test/base/#img-9" data-link-name="Launch Article Lightbox" data-is-ajax="" target="_blank">
|
<a href="#img-9" data-link-name="Launch Article Lightbox" data-is-ajax="">
|
||||||
<div>
|
<div>
|
||||||
<picture>
|
<picture>
|
||||||
<source media="(min-width: 1300px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 1300px) and (min-resolution: 120dpi)" sizes="880px" srcset="https://i.guim.co.uk/img/media/d1941b6a6908314fab28f44da222a4c892213341/0_0_4800_3120/master/4800.jpg?width=880&quality=45&auto=format&fit=max&dpr=2&s=b775d649981f7bc36cf0753dd9f47862 1760w"></source> <source media="(min-width: 1300px)" sizes="880px" srcset="https://i.guim.co.uk/img/media/d1941b6a6908314fab28f44da222a4c892213341/0_0_4800_3120/master/4800.jpg?width=880&quality=85&auto=format&fit=max&s=3aa0de336dad5991ff92d488288fcc92 880w"></source> <source media="(min-width: 1140px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 1140px) and (min-resolution: 120dpi)" sizes="800px" srcset="https://i.guim.co.uk/img/media/d1941b6a6908314fab28f44da222a4c892213341/0_0_4800_3120/master/4800.jpg?width=800&quality=45&auto=format&fit=max&dpr=2&s=9133cf8cd42d42bb1342dbefbfc67c22 1600w"></source> <source media="(min-width: 1140px)" sizes="800px" srcset="https://i.guim.co.uk/img/media/d1941b6a6908314fab28f44da222a4c892213341/0_0_4800_3120/master/4800.jpg?width=800&quality=85&auto=format&fit=max&s=2916efc01252a457768bfd28b40591ee 800w"></source> <source media="(min-width: 980px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 980px) and (min-resolution: 120dpi)" sizes="640px" srcset="https://i.guim.co.uk/img/media/d1941b6a6908314fab28f44da222a4c892213341/0_0_4800_3120/master/4800.jpg?width=640&quality=45&auto=format&fit=max&dpr=2&s=c7044b93d3aa73f7eac1b56ab9d77d86 1280w"></source> <source media="(min-width: 980px)" sizes="640px" srcset="https://i.guim.co.uk/img/media/d1941b6a6908314fab28f44da222a4c892213341/0_0_4800_3120/master/4800.jpg?width=640&quality=85&auto=format&fit=max&s=2342e6519bfe1ce74a04ca96c06ed4cd 640w"></source> <source media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" sizes="620px" srcset="https://i.guim.co.uk/img/media/d1941b6a6908314fab28f44da222a4c892213341/0_0_4800_3120/master/4800.jpg?width=620&quality=45&auto=format&fit=max&dpr=2&s=b6218129f26e09d8133bf226df3e9bed 1240w"></source> <source media="(min-width: 660px)" sizes="620px" srcset="https://i.guim.co.uk/img/media/d1941b6a6908314fab28f44da222a4c892213341/0_0_4800_3120/master/4800.jpg?width=620&quality=85&auto=format&fit=max&s=9d20a1ca789f2efe7ba2dfdef9c28725 620w"></source> <source media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" sizes="605px" srcset="https://i.guim.co.uk/img/media/d1941b6a6908314fab28f44da222a4c892213341/0_0_4800_3120/master/4800.jpg?width=605&quality=45&auto=format&fit=max&dpr=2&s=73fb4a4f8d59a92325fef9faa2ddf90d 1210w"></source> <source media="(min-width: 480px)" sizes="605px" srcset="https://i.guim.co.uk/img/media/d1941b6a6908314fab28f44da222a4c892213341/0_0_4800_3120/master/4800.jpg?width=605&quality=85&auto=format&fit=max&s=7894b6600fbb6af1ec6552007ad12da8 605w"></source> <source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 0px) and (min-resolution: 120dpi)" sizes="445px" srcset="https://i.guim.co.uk/img/media/d1941b6a6908314fab28f44da222a4c892213341/0_0_4800_3120/master/4800.jpg?width=445&quality=45&auto=format&fit=max&dpr=2&s=19022ce9fcafebe383880059f34add78 890w"></source> <source media="(min-width: 0px)" sizes="445px" srcset="https://i.guim.co.uk/img/media/d1941b6a6908314fab28f44da222a4c892213341/0_0_4800_3120/master/4800.jpg?width=445&quality=85&auto=format&fit=max&s=ded05f2c1859d70d3b8d3de3dcb75e0f 445w"></source>
|
<source media="(min-width: 1300px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 1300px) and (min-resolution: 120dpi)" sizes="880px" srcset="https://i.guim.co.uk/img/media/d1941b6a6908314fab28f44da222a4c892213341/0_0_4800_3120/master/4800.jpg?width=880&quality=45&auto=format&fit=max&dpr=2&s=b775d649981f7bc36cf0753dd9f47862 1760w"></source> <source media="(min-width: 1300px)" sizes="880px" srcset="https://i.guim.co.uk/img/media/d1941b6a6908314fab28f44da222a4c892213341/0_0_4800_3120/master/4800.jpg?width=880&quality=85&auto=format&fit=max&s=3aa0de336dad5991ff92d488288fcc92 880w"></source> <source media="(min-width: 1140px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 1140px) and (min-resolution: 120dpi)" sizes="800px" srcset="https://i.guim.co.uk/img/media/d1941b6a6908314fab28f44da222a4c892213341/0_0_4800_3120/master/4800.jpg?width=800&quality=45&auto=format&fit=max&dpr=2&s=9133cf8cd42d42bb1342dbefbfc67c22 1600w"></source> <source media="(min-width: 1140px)" sizes="800px" srcset="https://i.guim.co.uk/img/media/d1941b6a6908314fab28f44da222a4c892213341/0_0_4800_3120/master/4800.jpg?width=800&quality=85&auto=format&fit=max&s=2916efc01252a457768bfd28b40591ee 800w"></source> <source media="(min-width: 980px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 980px) and (min-resolution: 120dpi)" sizes="640px" srcset="https://i.guim.co.uk/img/media/d1941b6a6908314fab28f44da222a4c892213341/0_0_4800_3120/master/4800.jpg?width=640&quality=45&auto=format&fit=max&dpr=2&s=c7044b93d3aa73f7eac1b56ab9d77d86 1280w"></source> <source media="(min-width: 980px)" sizes="640px" srcset="https://i.guim.co.uk/img/media/d1941b6a6908314fab28f44da222a4c892213341/0_0_4800_3120/master/4800.jpg?width=640&quality=85&auto=format&fit=max&s=2342e6519bfe1ce74a04ca96c06ed4cd 640w"></source> <source media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" sizes="620px" srcset="https://i.guim.co.uk/img/media/d1941b6a6908314fab28f44da222a4c892213341/0_0_4800_3120/master/4800.jpg?width=620&quality=45&auto=format&fit=max&dpr=2&s=b6218129f26e09d8133bf226df3e9bed 1240w"></source> <source media="(min-width: 660px)" sizes="620px" srcset="https://i.guim.co.uk/img/media/d1941b6a6908314fab28f44da222a4c892213341/0_0_4800_3120/master/4800.jpg?width=620&quality=85&auto=format&fit=max&s=9d20a1ca789f2efe7ba2dfdef9c28725 620w"></source> <source media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" sizes="605px" srcset="https://i.guim.co.uk/img/media/d1941b6a6908314fab28f44da222a4c892213341/0_0_4800_3120/master/4800.jpg?width=605&quality=45&auto=format&fit=max&dpr=2&s=73fb4a4f8d59a92325fef9faa2ddf90d 1210w"></source> <source media="(min-width: 480px)" sizes="605px" srcset="https://i.guim.co.uk/img/media/d1941b6a6908314fab28f44da222a4c892213341/0_0_4800_3120/master/4800.jpg?width=605&quality=85&auto=format&fit=max&s=7894b6600fbb6af1ec6552007ad12da8 605w"></source> <source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 0px) and (min-resolution: 120dpi)" sizes="445px" srcset="https://i.guim.co.uk/img/media/d1941b6a6908314fab28f44da222a4c892213341/0_0_4800_3120/master/4800.jpg?width=445&quality=45&auto=format&fit=max&dpr=2&s=19022ce9fcafebe383880059f34add78 890w"></source> <source media="(min-width: 0px)" sizes="445px" srcset="https://i.guim.co.uk/img/media/d1941b6a6908314fab28f44da222a4c892213341/0_0_4800_3120/master/4800.jpg?width=445&quality=85&auto=format&fit=max&s=ded05f2c1859d70d3b8d3de3dcb75e0f 445w"></source>
|
||||||
|
@ -218,7 +218,7 @@
|
||||||
<meta itemprop="url" content="https://i.guim.co.uk/img/media/14b462f5d9489def554e0f9f436f13aec332f7b8/0_0_4278_4800/master/4278.jpg?width=700&quality=85&auto=format&fit=max&s=b8bf0c299908608310fb47e4163afb38">
|
<meta itemprop="url" content="https://i.guim.co.uk/img/media/14b462f5d9489def554e0f9f436f13aec332f7b8/0_0_4278_4800/master/4278.jpg?width=700&quality=85&auto=format&fit=max&s=b8bf0c299908608310fb47e4163afb38">
|
||||||
<meta itemprop="width" content="4278">
|
<meta itemprop="width" content="4278">
|
||||||
<meta itemprop="height" content="4800">
|
<meta itemprop="height" content="4800">
|
||||||
<a href="http://fakehost/test/base/#img-10" data-link-name="Launch Article Lightbox" data-is-ajax="" target="_blank">
|
<a href="#img-10" data-link-name="Launch Article Lightbox" data-is-ajax="">
|
||||||
<div>
|
<div>
|
||||||
<picture>
|
<picture>
|
||||||
<source media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" sizes="620px" srcset="https://i.guim.co.uk/img/media/14b462f5d9489def554e0f9f436f13aec332f7b8/0_0_4278_4800/master/4278.jpg?width=620&quality=45&auto=format&fit=max&dpr=2&s=1a392a17d0c74d513ff14129ae5f7e6c 1240w"></source> <source media="(min-width: 660px)" sizes="620px" srcset="https://i.guim.co.uk/img/media/14b462f5d9489def554e0f9f436f13aec332f7b8/0_0_4278_4800/master/4278.jpg?width=620&quality=85&auto=format&fit=max&s=d5b05458659a4a06ff6583046f712ad1 620w"></source> <source media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" sizes="605px" srcset="https://i.guim.co.uk/img/media/14b462f5d9489def554e0f9f436f13aec332f7b8/0_0_4278_4800/master/4278.jpg?width=605&quality=45&auto=format&fit=max&dpr=2&s=649c2127cfbab69a7d6e4085ea098d95 1210w"></source> <source media="(min-width: 480px)" sizes="605px" srcset="https://i.guim.co.uk/img/media/14b462f5d9489def554e0f9f436f13aec332f7b8/0_0_4278_4800/master/4278.jpg?width=605&quality=85&auto=format&fit=max&s=d45dfb664b5479650ba067c6a5af16c3 605w"></source> <source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 0px) and (min-resolution: 120dpi)" sizes="445px" srcset="https://i.guim.co.uk/img/media/14b462f5d9489def554e0f9f436f13aec332f7b8/0_0_4278_4800/master/4278.jpg?width=445&quality=45&auto=format&fit=max&dpr=2&s=f94f4c652479979124e52c237804eb83 890w"></source> <source media="(min-width: 0px)" sizes="445px" srcset="https://i.guim.co.uk/img/media/14b462f5d9489def554e0f9f436f13aec332f7b8/0_0_4278_4800/master/4278.jpg?width=445&quality=85&auto=format&fit=max&s=f6c8d3b38a8af6d197d0a60d22a326f3 445w"></source>
|
<source media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" sizes="620px" srcset="https://i.guim.co.uk/img/media/14b462f5d9489def554e0f9f436f13aec332f7b8/0_0_4278_4800/master/4278.jpg?width=620&quality=45&auto=format&fit=max&dpr=2&s=1a392a17d0c74d513ff14129ae5f7e6c 1240w"></source> <source media="(min-width: 660px)" sizes="620px" srcset="https://i.guim.co.uk/img/media/14b462f5d9489def554e0f9f436f13aec332f7b8/0_0_4278_4800/master/4278.jpg?width=620&quality=85&auto=format&fit=max&s=d5b05458659a4a06ff6583046f712ad1 620w"></source> <source media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" sizes="605px" srcset="https://i.guim.co.uk/img/media/14b462f5d9489def554e0f9f436f13aec332f7b8/0_0_4278_4800/master/4278.jpg?width=605&quality=45&auto=format&fit=max&dpr=2&s=649c2127cfbab69a7d6e4085ea098d95 1210w"></source> <source media="(min-width: 480px)" sizes="605px" srcset="https://i.guim.co.uk/img/media/14b462f5d9489def554e0f9f436f13aec332f7b8/0_0_4278_4800/master/4278.jpg?width=605&quality=85&auto=format&fit=max&s=d45dfb664b5479650ba067c6a5af16c3 605w"></source> <source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 0px) and (min-resolution: 120dpi)" sizes="445px" srcset="https://i.guim.co.uk/img/media/14b462f5d9489def554e0f9f436f13aec332f7b8/0_0_4278_4800/master/4278.jpg?width=445&quality=45&auto=format&fit=max&dpr=2&s=f94f4c652479979124e52c237804eb83 890w"></source> <source media="(min-width: 0px)" sizes="445px" srcset="https://i.guim.co.uk/img/media/14b462f5d9489def554e0f9f436f13aec332f7b8/0_0_4278_4800/master/4278.jpg?width=445&quality=85&auto=format&fit=max&s=f6c8d3b38a8af6d197d0a60d22a326f3 445w"></source>
|
||||||
|
@ -231,7 +231,7 @@
|
||||||
<meta itemprop="url" content="https://i.guim.co.uk/img/media/e2cf54c36f17c6894844ea0cdd4346288a002da9/915_0_3172_3189/master/3172.jpg?width=700&quality=85&auto=format&fit=max&s=3691946929b4105ba35ff9d306cb4fbc">
|
<meta itemprop="url" content="https://i.guim.co.uk/img/media/e2cf54c36f17c6894844ea0cdd4346288a002da9/915_0_3172_3189/master/3172.jpg?width=700&quality=85&auto=format&fit=max&s=3691946929b4105ba35ff9d306cb4fbc">
|
||||||
<meta itemprop="width" content="3172">
|
<meta itemprop="width" content="3172">
|
||||||
<meta itemprop="height" content="3189">
|
<meta itemprop="height" content="3189">
|
||||||
<a href="http://fakehost/test/base/#img-11" data-link-name="Launch Article Lightbox" data-is-ajax="" target="_blank">
|
<a href="#img-11" data-link-name="Launch Article Lightbox" data-is-ajax="">
|
||||||
<div>
|
<div>
|
||||||
<picture>
|
<picture>
|
||||||
<source media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" sizes="620px" srcset="https://i.guim.co.uk/img/media/e2cf54c36f17c6894844ea0cdd4346288a002da9/915_0_3172_3189/master/3172.jpg?width=620&quality=45&auto=format&fit=max&dpr=2&s=be6cf9beea564e7be872193b01c329a3 1240w"></source> <source media="(min-width: 660px)" sizes="620px" srcset="https://i.guim.co.uk/img/media/e2cf54c36f17c6894844ea0cdd4346288a002da9/915_0_3172_3189/master/3172.jpg?width=620&quality=85&auto=format&fit=max&s=c74497ec55bb1b680169d62684aa803d 620w"></source> <source media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" sizes="605px" srcset="https://i.guim.co.uk/img/media/e2cf54c36f17c6894844ea0cdd4346288a002da9/915_0_3172_3189/master/3172.jpg?width=605&quality=45&auto=format&fit=max&dpr=2&s=06b2c03638556f85da582e419cf1817a 1210w"></source> <source media="(min-width: 480px)" sizes="605px" srcset="https://i.guim.co.uk/img/media/e2cf54c36f17c6894844ea0cdd4346288a002da9/915_0_3172_3189/master/3172.jpg?width=605&quality=85&auto=format&fit=max&s=8cc04403e3902dbe1e4a9b01b8d4e517 605w"></source> <source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 0px) and (min-resolution: 120dpi)" sizes="445px" srcset="https://i.guim.co.uk/img/media/e2cf54c36f17c6894844ea0cdd4346288a002da9/915_0_3172_3189/master/3172.jpg?width=445&quality=45&auto=format&fit=max&dpr=2&s=893cbf39d6db1d28ba8fc85419382f9d 890w"></source> <source media="(min-width: 0px)" sizes="445px" srcset="https://i.guim.co.uk/img/media/e2cf54c36f17c6894844ea0cdd4346288a002da9/915_0_3172_3189/master/3172.jpg?width=445&quality=85&auto=format&fit=max&s=6df725aaf59e21b09434b967e05b3272 445w"></source>
|
<source media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" sizes="620px" srcset="https://i.guim.co.uk/img/media/e2cf54c36f17c6894844ea0cdd4346288a002da9/915_0_3172_3189/master/3172.jpg?width=620&quality=45&auto=format&fit=max&dpr=2&s=be6cf9beea564e7be872193b01c329a3 1240w"></source> <source media="(min-width: 660px)" sizes="620px" srcset="https://i.guim.co.uk/img/media/e2cf54c36f17c6894844ea0cdd4346288a002da9/915_0_3172_3189/master/3172.jpg?width=620&quality=85&auto=format&fit=max&s=c74497ec55bb1b680169d62684aa803d 620w"></source> <source media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" sizes="605px" srcset="https://i.guim.co.uk/img/media/e2cf54c36f17c6894844ea0cdd4346288a002da9/915_0_3172_3189/master/3172.jpg?width=605&quality=45&auto=format&fit=max&dpr=2&s=06b2c03638556f85da582e419cf1817a 1210w"></source> <source media="(min-width: 480px)" sizes="605px" srcset="https://i.guim.co.uk/img/media/e2cf54c36f17c6894844ea0cdd4346288a002da9/915_0_3172_3189/master/3172.jpg?width=605&quality=85&auto=format&fit=max&s=8cc04403e3902dbe1e4a9b01b8d4e517 605w"></source> <source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 0px) and (min-resolution: 120dpi)" sizes="445px" srcset="https://i.guim.co.uk/img/media/e2cf54c36f17c6894844ea0cdd4346288a002da9/915_0_3172_3189/master/3172.jpg?width=445&quality=45&auto=format&fit=max&dpr=2&s=893cbf39d6db1d28ba8fc85419382f9d 890w"></source> <source media="(min-width: 0px)" sizes="445px" srcset="https://i.guim.co.uk/img/media/e2cf54c36f17c6894844ea0cdd4346288a002da9/915_0_3172_3189/master/3172.jpg?width=445&quality=85&auto=format&fit=max&s=6df725aaf59e21b09434b967e05b3272 445w"></source>
|
||||||
|
@ -253,7 +253,7 @@
|
||||||
<meta itemprop="url" content="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=700&quality=85&auto=format&fit=max&s=72146577e379bdf9a21bc47994de5fb6">
|
<meta itemprop="url" content="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=700&quality=85&auto=format&fit=max&s=72146577e379bdf9a21bc47994de5fb6">
|
||||||
<meta itemprop="width" content="4800">
|
<meta itemprop="width" content="4800">
|
||||||
<meta itemprop="height" content="3073">
|
<meta itemprop="height" content="3073">
|
||||||
<a href="http://fakehost/test/base/#img-12" data-link-name="Launch Article Lightbox" data-is-ajax="" target="_blank">
|
<a href="#img-12" data-link-name="Launch Article Lightbox" data-is-ajax="">
|
||||||
<div>
|
<div>
|
||||||
<picture>
|
<picture>
|
||||||
<source media="(min-width: 1300px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 1300px) and (min-resolution: 120dpi)" sizes="1300px" srcset="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=1300&quality=45&auto=format&fit=max&dpr=2&s=4bd713ae6f60b56e36378bb2fe45e9eb 2600w"></source> <source media="(min-width: 1300px)" sizes="1300px" srcset="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=1300&quality=85&auto=format&fit=max&s=b93c6d33ca7496220eb30d0c8bfaccf9 1300w"></source> <source media="(min-width: 1140px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 1140px) and (min-resolution: 120dpi)" sizes="1140px" srcset="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=1140&quality=45&auto=format&fit=max&dpr=2&s=f66f5a256170eced3c0a52aee235ae29 2280w"></source> <source media="(min-width: 1140px)" sizes="1140px" srcset="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=1140&quality=85&auto=format&fit=max&s=1f60eb7cf5fc6f899c7c9af9c05df9a0 1140w"></source> <source media="(min-width: 980px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 980px) and (min-resolution: 120dpi)" sizes="1125px" srcset="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=1125&quality=45&auto=format&fit=max&dpr=2&s=27526c9caf1a62110dfa16214ceccf14 2250w"></source> <source media="(min-width: 980px)" sizes="1125px" srcset="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=1125&quality=85&auto=format&fit=max&s=7d47ba3d7898a398e1f9d8f2d19d391e 1125w"></source> <source media="(min-width: 740px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 740px) and (min-resolution: 120dpi)" sizes="965px" srcset="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=965&quality=45&auto=format&fit=max&dpr=2&s=8974cfeb3e33bc51b55518f1bc81e68d 1930w"></source> <source media="(min-width: 740px)" sizes="965px" srcset="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=965&quality=85&auto=format&fit=max&s=04f953b4ec9555178204a1621b8a1f59 965w"></source> <source media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" sizes="725px" srcset="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=725&quality=45&auto=format&fit=max&dpr=2&s=7e2c1494173f83f555806120a1fe43cc 1450w"></source> <source media="(min-width: 660px)" sizes="725px" srcset="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=725&quality=85&auto=format&fit=max&s=8f53cf25b514e283cce3d995220ca19b 725w"></source> <source media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" sizes="645px" srcset="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=645&quality=45&auto=format&fit=max&dpr=2&s=2b770ca04273c921c8abe0a7de72030a 1290w"></source> <source media="(min-width: 480px)" sizes="645px" srcset="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=645&quality=85&auto=format&fit=max&s=0da775328d9ade5ca605079a9118a64a 645w"></source> <source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 0px) and (min-resolution: 120dpi)" sizes="465px" srcset="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=465&quality=45&auto=format&fit=max&dpr=2&s=e2e51037c5a6b8bf22d87cb927e45888 930w"></source> <source media="(min-width: 0px)" sizes="465px" srcset="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=465&quality=85&auto=format&fit=max&s=7ecf73b514ceb1b5e0391f17c7a4d3b0 465w"></source>
|
<source media="(min-width: 1300px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 1300px) and (min-resolution: 120dpi)" sizes="1300px" srcset="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=1300&quality=45&auto=format&fit=max&dpr=2&s=4bd713ae6f60b56e36378bb2fe45e9eb 2600w"></source> <source media="(min-width: 1300px)" sizes="1300px" srcset="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=1300&quality=85&auto=format&fit=max&s=b93c6d33ca7496220eb30d0c8bfaccf9 1300w"></source> <source media="(min-width: 1140px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 1140px) and (min-resolution: 120dpi)" sizes="1140px" srcset="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=1140&quality=45&auto=format&fit=max&dpr=2&s=f66f5a256170eced3c0a52aee235ae29 2280w"></source> <source media="(min-width: 1140px)" sizes="1140px" srcset="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=1140&quality=85&auto=format&fit=max&s=1f60eb7cf5fc6f899c7c9af9c05df9a0 1140w"></source> <source media="(min-width: 980px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 980px) and (min-resolution: 120dpi)" sizes="1125px" srcset="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=1125&quality=45&auto=format&fit=max&dpr=2&s=27526c9caf1a62110dfa16214ceccf14 2250w"></source> <source media="(min-width: 980px)" sizes="1125px" srcset="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=1125&quality=85&auto=format&fit=max&s=7d47ba3d7898a398e1f9d8f2d19d391e 1125w"></source> <source media="(min-width: 740px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 740px) and (min-resolution: 120dpi)" sizes="965px" srcset="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=965&quality=45&auto=format&fit=max&dpr=2&s=8974cfeb3e33bc51b55518f1bc81e68d 1930w"></source> <source media="(min-width: 740px)" sizes="965px" srcset="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=965&quality=85&auto=format&fit=max&s=04f953b4ec9555178204a1621b8a1f59 965w"></source> <source media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" sizes="725px" srcset="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=725&quality=45&auto=format&fit=max&dpr=2&s=7e2c1494173f83f555806120a1fe43cc 1450w"></source> <source media="(min-width: 660px)" sizes="725px" srcset="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=725&quality=85&auto=format&fit=max&s=8f53cf25b514e283cce3d995220ca19b 725w"></source> <source media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" sizes="645px" srcset="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=645&quality=45&auto=format&fit=max&dpr=2&s=2b770ca04273c921c8abe0a7de72030a 1290w"></source> <source media="(min-width: 480px)" sizes="645px" srcset="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=645&quality=85&auto=format&fit=max&s=0da775328d9ade5ca605079a9118a64a 645w"></source> <source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 0px) and (min-resolution: 120dpi)" sizes="465px" srcset="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=465&quality=45&auto=format&fit=max&dpr=2&s=e2e51037c5a6b8bf22d87cb927e45888 930w"></source> <source media="(min-width: 0px)" sizes="465px" srcset="https://i.guim.co.uk/img/media/b5f3736b2ba2ef4df364258b0efcaba26f571d6e/0_0_4800_3073/master/4800.jpg?width=465&quality=85&auto=format&fit=max&s=7ecf73b514ceb1b5e0391f17c7a4d3b0 465w"></source>
|
||||||
|
@ -282,7 +282,7 @@
|
||||||
<meta itemprop="url" content="https://i.guim.co.uk/img/media/d5aaf60e3a427f278747acf0c3e7ba39b39ef923/0_0_4800_3200/master/4800.jpg?width=700&quality=85&auto=format&fit=max&s=1d00d3ea91d32110b40d85ff43227728">
|
<meta itemprop="url" content="https://i.guim.co.uk/img/media/d5aaf60e3a427f278747acf0c3e7ba39b39ef923/0_0_4800_3200/master/4800.jpg?width=700&quality=85&auto=format&fit=max&s=1d00d3ea91d32110b40d85ff43227728">
|
||||||
<meta itemprop="width" content="4800">
|
<meta itemprop="width" content="4800">
|
||||||
<meta itemprop="height" content="3200">
|
<meta itemprop="height" content="3200">
|
||||||
<a href="http://fakehost/test/base/#img-13" data-link-name="Launch Article Lightbox" data-is-ajax="" target="_blank">
|
<a href="#img-13" data-link-name="Launch Article Lightbox" data-is-ajax="">
|
||||||
<div>
|
<div>
|
||||||
<picture>
|
<picture>
|
||||||
<source media="(min-width: 1300px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 1300px) and (min-resolution: 120dpi)" sizes="880px" srcset="https://i.guim.co.uk/img/media/d5aaf60e3a427f278747acf0c3e7ba39b39ef923/0_0_4800_3200/master/4800.jpg?width=880&quality=45&auto=format&fit=max&dpr=2&s=2a64f318f02a31bdf9f17ae01fca72a3 1760w"></source> <source media="(min-width: 1300px)" sizes="880px" srcset="https://i.guim.co.uk/img/media/d5aaf60e3a427f278747acf0c3e7ba39b39ef923/0_0_4800_3200/master/4800.jpg?width=880&quality=85&auto=format&fit=max&s=811b3a2ecee1a87b72813d328f59aa85 880w"></source> <source media="(min-width: 1140px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 1140px) and (min-resolution: 120dpi)" sizes="800px" srcset="https://i.guim.co.uk/img/media/d5aaf60e3a427f278747acf0c3e7ba39b39ef923/0_0_4800_3200/master/4800.jpg?width=800&quality=45&auto=format&fit=max&dpr=2&s=47418e3f630c00af6124c471fdc54c20 1600w"></source> <source media="(min-width: 1140px)" sizes="800px" srcset="https://i.guim.co.uk/img/media/d5aaf60e3a427f278747acf0c3e7ba39b39ef923/0_0_4800_3200/master/4800.jpg?width=800&quality=85&auto=format&fit=max&s=93ec03888887d5eb6eabf07e40f2ed3b 800w"></source> <source media="(min-width: 980px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 980px) and (min-resolution: 120dpi)" sizes="640px" srcset="https://i.guim.co.uk/img/media/d5aaf60e3a427f278747acf0c3e7ba39b39ef923/0_0_4800_3200/master/4800.jpg?width=640&quality=45&auto=format&fit=max&dpr=2&s=476d165704890f40cc5f2d74f4d09b95 1280w"></source> <source media="(min-width: 980px)" sizes="640px" srcset="https://i.guim.co.uk/img/media/d5aaf60e3a427f278747acf0c3e7ba39b39ef923/0_0_4800_3200/master/4800.jpg?width=640&quality=85&auto=format&fit=max&s=6179da6bca697f83ac063a56660aa31b 640w"></source> <source media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" sizes="620px" srcset="https://i.guim.co.uk/img/media/d5aaf60e3a427f278747acf0c3e7ba39b39ef923/0_0_4800_3200/master/4800.jpg?width=620&quality=45&auto=format&fit=max&dpr=2&s=df0c5b9ccac02dcd010d7f3ed8ff8c85 1240w"></source> <source media="(min-width: 660px)" sizes="620px" srcset="https://i.guim.co.uk/img/media/d5aaf60e3a427f278747acf0c3e7ba39b39ef923/0_0_4800_3200/master/4800.jpg?width=620&quality=85&auto=format&fit=max&s=e9fd2eedc9bb80286a6cabd1c7c3b0e2 620w"></source> <source media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" sizes="605px" srcset="https://i.guim.co.uk/img/media/d5aaf60e3a427f278747acf0c3e7ba39b39ef923/0_0_4800_3200/master/4800.jpg?width=605&quality=45&auto=format&fit=max&dpr=2&s=e48f277772be7e455f9a4a4139b3bf4c 1210w"></source> <source media="(min-width: 480px)" sizes="605px" srcset="https://i.guim.co.uk/img/media/d5aaf60e3a427f278747acf0c3e7ba39b39ef923/0_0_4800_3200/master/4800.jpg?width=605&quality=85&auto=format&fit=max&s=2e0af911fcd7011f04ee91d445290e84 605w"></source> <source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 0px) and (min-resolution: 120dpi)" sizes="445px" srcset="https://i.guim.co.uk/img/media/d5aaf60e3a427f278747acf0c3e7ba39b39ef923/0_0_4800_3200/master/4800.jpg?width=445&quality=45&auto=format&fit=max&dpr=2&s=15161e07957f327b44aa124d94ae8291 890w"></source> <source media="(min-width: 0px)" sizes="445px" srcset="https://i.guim.co.uk/img/media/d5aaf60e3a427f278747acf0c3e7ba39b39ef923/0_0_4800_3200/master/4800.jpg?width=445&quality=85&auto=format&fit=max&s=ef6c6809f2adcff0f4ff32899095839b 445w"></source>
|
<source media="(min-width: 1300px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 1300px) and (min-resolution: 120dpi)" sizes="880px" srcset="https://i.guim.co.uk/img/media/d5aaf60e3a427f278747acf0c3e7ba39b39ef923/0_0_4800_3200/master/4800.jpg?width=880&quality=45&auto=format&fit=max&dpr=2&s=2a64f318f02a31bdf9f17ae01fca72a3 1760w"></source> <source media="(min-width: 1300px)" sizes="880px" srcset="https://i.guim.co.uk/img/media/d5aaf60e3a427f278747acf0c3e7ba39b39ef923/0_0_4800_3200/master/4800.jpg?width=880&quality=85&auto=format&fit=max&s=811b3a2ecee1a87b72813d328f59aa85 880w"></source> <source media="(min-width: 1140px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 1140px) and (min-resolution: 120dpi)" sizes="800px" srcset="https://i.guim.co.uk/img/media/d5aaf60e3a427f278747acf0c3e7ba39b39ef923/0_0_4800_3200/master/4800.jpg?width=800&quality=45&auto=format&fit=max&dpr=2&s=47418e3f630c00af6124c471fdc54c20 1600w"></source> <source media="(min-width: 1140px)" sizes="800px" srcset="https://i.guim.co.uk/img/media/d5aaf60e3a427f278747acf0c3e7ba39b39ef923/0_0_4800_3200/master/4800.jpg?width=800&quality=85&auto=format&fit=max&s=93ec03888887d5eb6eabf07e40f2ed3b 800w"></source> <source media="(min-width: 980px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 980px) and (min-resolution: 120dpi)" sizes="640px" srcset="https://i.guim.co.uk/img/media/d5aaf60e3a427f278747acf0c3e7ba39b39ef923/0_0_4800_3200/master/4800.jpg?width=640&quality=45&auto=format&fit=max&dpr=2&s=476d165704890f40cc5f2d74f4d09b95 1280w"></source> <source media="(min-width: 980px)" sizes="640px" srcset="https://i.guim.co.uk/img/media/d5aaf60e3a427f278747acf0c3e7ba39b39ef923/0_0_4800_3200/master/4800.jpg?width=640&quality=85&auto=format&fit=max&s=6179da6bca697f83ac063a56660aa31b 640w"></source> <source media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" sizes="620px" srcset="https://i.guim.co.uk/img/media/d5aaf60e3a427f278747acf0c3e7ba39b39ef923/0_0_4800_3200/master/4800.jpg?width=620&quality=45&auto=format&fit=max&dpr=2&s=df0c5b9ccac02dcd010d7f3ed8ff8c85 1240w"></source> <source media="(min-width: 660px)" sizes="620px" srcset="https://i.guim.co.uk/img/media/d5aaf60e3a427f278747acf0c3e7ba39b39ef923/0_0_4800_3200/master/4800.jpg?width=620&quality=85&auto=format&fit=max&s=e9fd2eedc9bb80286a6cabd1c7c3b0e2 620w"></source> <source media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" sizes="605px" srcset="https://i.guim.co.uk/img/media/d5aaf60e3a427f278747acf0c3e7ba39b39ef923/0_0_4800_3200/master/4800.jpg?width=605&quality=45&auto=format&fit=max&dpr=2&s=e48f277772be7e455f9a4a4139b3bf4c 1210w"></source> <source media="(min-width: 480px)" sizes="605px" srcset="https://i.guim.co.uk/img/media/d5aaf60e3a427f278747acf0c3e7ba39b39ef923/0_0_4800_3200/master/4800.jpg?width=605&quality=85&auto=format&fit=max&s=2e0af911fcd7011f04ee91d445290e84 605w"></source> <source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 0px) and (min-resolution: 120dpi)" sizes="445px" srcset="https://i.guim.co.uk/img/media/d5aaf60e3a427f278747acf0c3e7ba39b39ef923/0_0_4800_3200/master/4800.jpg?width=445&quality=45&auto=format&fit=max&dpr=2&s=15161e07957f327b44aa124d94ae8291 890w"></source> <source media="(min-width: 0px)" sizes="445px" srcset="https://i.guim.co.uk/img/media/d5aaf60e3a427f278747acf0c3e7ba39b39ef923/0_0_4800_3200/master/4800.jpg?width=445&quality=85&auto=format&fit=max&s=ef6c6809f2adcff0f4ff32899095839b 445w"></source>
|
||||||
|
@ -302,7 +302,7 @@
|
||||||
<meta itemprop="url" content="https://i.guim.co.uk/img/media/3766106f73e858d5b140ae3cdd2eef84060180cd/0_0_4800_3200/master/4800.jpg?width=700&quality=85&auto=format&fit=max&s=7dca3d798aef3526f42e281771d50f91">
|
<meta itemprop="url" content="https://i.guim.co.uk/img/media/3766106f73e858d5b140ae3cdd2eef84060180cd/0_0_4800_3200/master/4800.jpg?width=700&quality=85&auto=format&fit=max&s=7dca3d798aef3526f42e281771d50f91">
|
||||||
<meta itemprop="width" content="4800">
|
<meta itemprop="width" content="4800">
|
||||||
<meta itemprop="height" content="3200">
|
<meta itemprop="height" content="3200">
|
||||||
<a href="http://fakehost/test/base/#img-14" data-link-name="Launch Article Lightbox" data-is-ajax="" target="_blank">
|
<a href="#img-14" data-link-name="Launch Article Lightbox" data-is-ajax="">
|
||||||
<div>
|
<div>
|
||||||
<picture>
|
<picture>
|
||||||
<source media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" sizes="620px" srcset="https://i.guim.co.uk/img/media/3766106f73e858d5b140ae3cdd2eef84060180cd/0_0_4800_3200/master/4800.jpg?width=620&quality=45&auto=format&fit=max&dpr=2&s=0daf794415132fc19259f8d2f654f57f 1240w"></source> <source media="(min-width: 660px)" sizes="620px" srcset="https://i.guim.co.uk/img/media/3766106f73e858d5b140ae3cdd2eef84060180cd/0_0_4800_3200/master/4800.jpg?width=620&quality=85&auto=format&fit=max&s=98ce62f9d983fe8059c936a6c6cdff33 620w"></source> <source media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" sizes="605px" srcset="https://i.guim.co.uk/img/media/3766106f73e858d5b140ae3cdd2eef84060180cd/0_0_4800_3200/master/4800.jpg?width=605&quality=45&auto=format&fit=max&dpr=2&s=9ff4aac2a3b07867dfdfb8f470ea6977 1210w"></source> <source media="(min-width: 480px)" sizes="605px" srcset="https://i.guim.co.uk/img/media/3766106f73e858d5b140ae3cdd2eef84060180cd/0_0_4800_3200/master/4800.jpg?width=605&quality=85&auto=format&fit=max&s=10d1b71094ecf1722f593eb49bb2effe 605w"></source> <source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 0px) and (min-resolution: 120dpi)" sizes="445px" srcset="https://i.guim.co.uk/img/media/3766106f73e858d5b140ae3cdd2eef84060180cd/0_0_4800_3200/master/4800.jpg?width=445&quality=45&auto=format&fit=max&dpr=2&s=0705690fcb523f2781a5952f83528ff9 890w"></source> <source media="(min-width: 0px)" sizes="445px" srcset="https://i.guim.co.uk/img/media/3766106f73e858d5b140ae3cdd2eef84060180cd/0_0_4800_3200/master/4800.jpg?width=445&quality=85&auto=format&fit=max&s=4c748337df5f0348eb0e7d3e3ec46571 445w"></source>
|
<source media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" sizes="620px" srcset="https://i.guim.co.uk/img/media/3766106f73e858d5b140ae3cdd2eef84060180cd/0_0_4800_3200/master/4800.jpg?width=620&quality=45&auto=format&fit=max&dpr=2&s=0daf794415132fc19259f8d2f654f57f 1240w"></source> <source media="(min-width: 660px)" sizes="620px" srcset="https://i.guim.co.uk/img/media/3766106f73e858d5b140ae3cdd2eef84060180cd/0_0_4800_3200/master/4800.jpg?width=620&quality=85&auto=format&fit=max&s=98ce62f9d983fe8059c936a6c6cdff33 620w"></source> <source media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" sizes="605px" srcset="https://i.guim.co.uk/img/media/3766106f73e858d5b140ae3cdd2eef84060180cd/0_0_4800_3200/master/4800.jpg?width=605&quality=45&auto=format&fit=max&dpr=2&s=9ff4aac2a3b07867dfdfb8f470ea6977 1210w"></source> <source media="(min-width: 480px)" sizes="605px" srcset="https://i.guim.co.uk/img/media/3766106f73e858d5b140ae3cdd2eef84060180cd/0_0_4800_3200/master/4800.jpg?width=605&quality=85&auto=format&fit=max&s=10d1b71094ecf1722f593eb49bb2effe 605w"></source> <source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 0px) and (min-resolution: 120dpi)" sizes="445px" srcset="https://i.guim.co.uk/img/media/3766106f73e858d5b140ae3cdd2eef84060180cd/0_0_4800_3200/master/4800.jpg?width=445&quality=45&auto=format&fit=max&dpr=2&s=0705690fcb523f2781a5952f83528ff9 890w"></source> <source media="(min-width: 0px)" sizes="445px" srcset="https://i.guim.co.uk/img/media/3766106f73e858d5b140ae3cdd2eef84060180cd/0_0_4800_3200/master/4800.jpg?width=445&quality=85&auto=format&fit=max&s=4c748337df5f0348eb0e7d3e3ec46571 445w"></source>
|
||||||
|
|
|
@ -51,50 +51,50 @@ Copyright Notice
|
||||||
publication of this document. Please review these documents
|
publication of this document. Please review these documents
|
||||||
carefully, as they describe your rights and restrictions with respect
|
carefully, as they describe your rights and restrictions with respect
|
||||||
to this document. Code Components extracted from this document must
|
to this document. Code Components extracted from this document must
|
||||||
include Simplified BSD License text as described in <a href="http://fakehost/test/base/#section-4" target="_blank">Section 4</a>.e of
|
include Simplified BSD License text as described in <a href="#section-4">Section 4</a>.e of
|
||||||
the Trust Legal Provisions and are provided without warranty as
|
the Trust Legal Provisions and are provided without warranty as
|
||||||
described in the Simplified BSD License.
|
described in the Simplified BSD License.
|
||||||
|
|
||||||
|
|
||||||
<span>de Jong [Page 1]</span>
|
<span>de Jong [Page 1]</span>
|
||||||
</pre>
|
</pre>
|
||||||
<pre><a name="page-2" id="page-2" href="http://fakehost/test/base/#page-2" target="_blank"> </a>
|
<pre><a name="page-2" id="page-2" href="#page-2"> </a>
|
||||||
<span>Internet-Draft remoteStorage December 2014</span>
|
<span>Internet-Draft remoteStorage December 2014</span>
|
||||||
|
|
||||||
|
|
||||||
Table of Contents
|
Table of Contents
|
||||||
|
|
||||||
<a href="http://fakehost/test/base/#section-1" target="_blank">1</a>. Introduction...................................................<a href="http://fakehost/test/base/#page-2" target="_blank">2</a>
|
<a href="#section-1">1</a>. Introduction...................................................<a href="#page-2">2</a>
|
||||||
<a href="http://fakehost/test/base/#section-2" target="_blank">2</a>. Terminology....................................................<a href="http://fakehost/test/base/#page-3" target="_blank">3</a>
|
<a href="#section-2">2</a>. Terminology....................................................<a href="#page-3">3</a>
|
||||||
<a href="http://fakehost/test/base/#section-3" target="_blank">3</a>. Storage model..................................................<a href="http://fakehost/test/base/#page-3" target="_blank">3</a>
|
<a href="#section-3">3</a>. Storage model..................................................<a href="#page-3">3</a>
|
||||||
<a href="http://fakehost/test/base/#section-4" target="_blank">4</a>. Requests.......................................................<a href="http://fakehost/test/base/#page-4" target="_blank">4</a>
|
<a href="#section-4">4</a>. Requests.......................................................<a href="#page-4">4</a>
|
||||||
<a href="http://fakehost/test/base/#section-5" target="_blank">5</a>. Response codes.................................................<a href="http://fakehost/test/base/#page-7" target="_blank">7</a>
|
<a href="#section-5">5</a>. Response codes.................................................<a href="#page-7">7</a>
|
||||||
<a href="http://fakehost/test/base/#section-6" target="_blank">6</a>. Versioning.....................................................<a href="http://fakehost/test/base/#page-7" target="_blank">7</a>
|
<a href="#section-6">6</a>. Versioning.....................................................<a href="#page-7">7</a>
|
||||||
<a href="http://fakehost/test/base/#section-7" target="_blank">7</a>. CORS headers...................................................<a href="http://fakehost/test/base/#page-8" target="_blank">8</a>
|
<a href="#section-7">7</a>. CORS headers...................................................<a href="#page-8">8</a>
|
||||||
<a href="http://fakehost/test/base/#section-8" target="_blank">8</a>. Session description............................................<a href="http://fakehost/test/base/#page-8" target="_blank">8</a>
|
<a href="#section-8">8</a>. Session description............................................<a href="#page-8">8</a>
|
||||||
<a href="http://fakehost/test/base/#section-9" target="_blank">9</a>. Bearer tokens and access control...............................<a href="http://fakehost/test/base/#page-9" target="_blank">9</a>
|
<a href="#section-9">9</a>. Bearer tokens and access control...............................<a href="#page-9">9</a>
|
||||||
<a href="http://fakehost/test/base/#section-10" target="_blank">10</a>. Application-first bearer token issuance.......................<a href="http://fakehost/test/base/#page-10" target="_blank">10</a>
|
<a href="#section-10">10</a>. Application-first bearer token issuance.......................<a href="#page-10">10</a>
|
||||||
<a href="http://fakehost/test/base/#section-11" target="_blank">11</a>. Storage-first bearer token issuance...........................<a href="http://fakehost/test/base/#page-11" target="_blank">11</a>
|
<a href="#section-11">11</a>. Storage-first bearer token issuance...........................<a href="#page-11">11</a>
|
||||||
<a href="http://fakehost/test/base/#section-12" target="_blank">12</a>. Example wire transcripts......................................<a href="http://fakehost/test/base/#page-12" target="_blank">12</a>
|
<a href="#section-12">12</a>. Example wire transcripts......................................<a href="#page-12">12</a>
|
||||||
<a href="http://fakehost/test/base/#section-12.1" target="_blank">12.1</a>. WebFinger................................................<a href="http://fakehost/test/base/#page-12" target="_blank">12</a>
|
<a href="#section-12.1">12.1</a>. WebFinger................................................<a href="#page-12">12</a>
|
||||||
<a href="http://fakehost/test/base/#section-12.2" target="_blank">12.2</a>. OAuth dialog form........................................<a href="http://fakehost/test/base/#page-13" target="_blank">13</a>
|
<a href="#section-12.2">12.2</a>. OAuth dialog form........................................<a href="#page-13">13</a>
|
||||||
<a href="http://fakehost/test/base/#section-12.3" target="_blank">12.3</a>. OAuth dialog form submission.............................<a href="http://fakehost/test/base/#page-14" target="_blank">14</a>
|
<a href="#section-12.3">12.3</a>. OAuth dialog form submission.............................<a href="#page-14">14</a>
|
||||||
<a href="http://fakehost/test/base/#section-12.4" target="_blank">12.4</a>. OPTIONS preflight........................................<a href="http://fakehost/test/base/#page-15" target="_blank">15</a>
|
<a href="#section-12.4">12.4</a>. OPTIONS preflight........................................<a href="#page-15">15</a>
|
||||||
<a href="http://fakehost/test/base/#section-12.5" target="_blank">12.5</a>. Initial PUT..............................................<a href="http://fakehost/test/base/#page-15" target="_blank">15</a>
|
<a href="#section-12.5">12.5</a>. Initial PUT..............................................<a href="#page-15">15</a>
|
||||||
<a href="http://fakehost/test/base/#section-12.6" target="_blank">12.6</a>. Subsequent PUT...........................................<a href="http://fakehost/test/base/#page-16" target="_blank">16</a>
|
<a href="#section-12.6">12.6</a>. Subsequent PUT...........................................<a href="#page-16">16</a>
|
||||||
<a href="http://fakehost/test/base/#section-12.7" target="_blank">12.7</a>. GET......................................................<a href="http://fakehost/test/base/#page-16" target="_blank">16</a>
|
<a href="#section-12.7">12.7</a>. GET......................................................<a href="#page-16">16</a>
|
||||||
<a href="http://fakehost/test/base/#section-12.8" target="_blank">12.8</a>. DELETE...................................................<a href="http://fakehost/test/base/#page-17" target="_blank">17</a>
|
<a href="#section-12.8">12.8</a>. DELETE...................................................<a href="#page-17">17</a>
|
||||||
<a href="http://fakehost/test/base/#section-13" target="_blank">13</a>. Distributed versioning........................................<a href="http://fakehost/test/base/#page-17" target="_blank">17</a>
|
<a href="#section-13">13</a>. Distributed versioning........................................<a href="#page-17">17</a>
|
||||||
<a href="http://fakehost/test/base/#section-14" target="_blank">14</a>. Security Considerations.......................................<a href="http://fakehost/test/base/#page-19" target="_blank">19</a>
|
<a href="#section-14">14</a>. Security Considerations.......................................<a href="#page-19">19</a>
|
||||||
<a href="http://fakehost/test/base/#section-15" target="_blank">15</a>. IANA Considerations...........................................<a href="http://fakehost/test/base/#page-20" target="_blank">20</a>
|
<a href="#section-15">15</a>. IANA Considerations...........................................<a href="#page-20">20</a>
|
||||||
<a href="http://fakehost/test/base/#section-16" target="_blank">16</a>. Acknowledgments...............................................<a href="http://fakehost/test/base/#page-20" target="_blank">20</a>
|
<a href="#section-16">16</a>. Acknowledgments...............................................<a href="#page-20">20</a>
|
||||||
<a href="http://fakehost/test/base/#section-17" target="_blank">17</a>. References....................................................<a href="http://fakehost/test/base/#page-21" target="_blank">21</a>
|
<a href="#section-17">17</a>. References....................................................<a href="#page-21">21</a>
|
||||||
<a href="http://fakehost/test/base/#section-17.1" target="_blank">17.1</a>. Normative References.....................................<a href="http://fakehost/test/base/#page-21" target="_blank">21</a>
|
<a href="#section-17.1">17.1</a>. Normative References.....................................<a href="#page-21">21</a>
|
||||||
<a href="http://fakehost/test/base/#section-17.2" target="_blank">17.2</a>. Informative References...................................<a href="http://fakehost/test/base/#page-21" target="_blank">21</a>
|
<a href="#section-17.2">17.2</a>. Informative References...................................<a href="#page-21">21</a>
|
||||||
<a href="http://fakehost/test/base/#section-18" target="_blank">18</a>. Authors' addresses............................................<a href="http://fakehost/test/base/#page-22" target="_blank">22</a>
|
<a href="#section-18">18</a>. Authors' addresses............................................<a href="#page-22">22</a>
|
||||||
|
|
||||||
|
|
||||||
<span><a name="section-1" href="http://fakehost/test/base/#section-1" target="_blank">1</a>. Introduction</span>
|
<span><a name="section-1" href="#section-1">1</a>. Introduction</span>
|
||||||
|
|
||||||
Many services for data storage are available over the internet. This
|
Many services for data storage are available over the internet. This
|
||||||
specification describes a vendor-independent interface for such
|
specification describes a vendor-independent interface for such
|
||||||
|
@ -109,7 +109,7 @@ Table of Contents
|
||||||
|
|
||||||
<span>de Jong [Page 2]</span>
|
<span>de Jong [Page 2]</span>
|
||||||
</pre>
|
</pre>
|
||||||
<pre><a name="page-3" id="page-3" href="http://fakehost/test/base/#page-3" target="_blank"> </a>
|
<pre><a name="page-3" id="page-3" href="#page-3"> </a>
|
||||||
<span>Internet-Draft remoteStorage December 2014</span>
|
<span>Internet-Draft remoteStorage December 2014</span>
|
||||||
|
|
||||||
|
|
||||||
|
@ -128,11 +128,11 @@ Table of Contents
|
||||||
The exact details of these four actions are described in this
|
The exact details of these four actions are described in this
|
||||||
specification.
|
specification.
|
||||||
|
|
||||||
<span><a name="section-2" href="http://fakehost/test/base/#section-2" target="_blank">2</a>. Terminology</span>
|
<span><a name="section-2" href="#section-2">2</a>. Terminology</span>
|
||||||
|
|
||||||
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
|
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
|
||||||
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
|
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
|
||||||
document are to be interpreted as described in <a href="http://fakehost/test/base/rfc2119" target="_blank">RFC 2119</a> [<a href="http://fakehost/test/base/#ref-WORDS" target="_blank">WORDS</a>].
|
document are to be interpreted as described in <a href="http://fakehost/test/base/rfc2119" target="_blank">RFC 2119</a> [<a href="#ref-WORDS">WORDS</a>].
|
||||||
|
|
||||||
"SHOULD" and "SHOULD NOT" are appropriate when valid exceptions to a
|
"SHOULD" and "SHOULD NOT" are appropriate when valid exceptions to a
|
||||||
general requirement are known to exist or appear to exist, and it is
|
general requirement are known to exist or appear to exist, and it is
|
||||||
|
@ -141,7 +141,7 @@ Table of Contents
|
||||||
implement the general requirement when such failure would result in
|
implement the general requirement when such failure would result in
|
||||||
interoperability failure.
|
interoperability failure.
|
||||||
|
|
||||||
<span><a name="section-3" href="http://fakehost/test/base/#section-3" target="_blank">3</a>. Storage model</span>
|
<span><a name="section-3" href="#section-3">3</a>. Storage model</span>
|
||||||
|
|
||||||
The server stores data in nodes that form a tree structure.
|
The server stores data in nodes that form a tree structure.
|
||||||
Internal nodes are called 'folders' and leaf nodes are called
|
Internal nodes are called 'folders' and leaf nodes are called
|
||||||
|
@ -160,7 +160,7 @@ Table of Contents
|
||||||
|
|
||||||
<span>de Jong [Page 3]</span>
|
<span>de Jong [Page 3]</span>
|
||||||
</pre>
|
</pre>
|
||||||
<pre><a name="page-4" id="page-4" href="http://fakehost/test/base/#page-4" target="_blank"> </a>
|
<pre><a name="page-4" id="page-4" href="#page-4"> </a>
|
||||||
<span>Internet-Draft remoteStorage December 2014</span>
|
<span>Internet-Draft remoteStorage December 2014</span>
|
||||||
|
|
||||||
|
|
||||||
|
@ -170,12 +170,12 @@ Table of Contents
|
||||||
* content length
|
* content length
|
||||||
* content
|
* content
|
||||||
|
|
||||||
<span><a name="section-4" href="http://fakehost/test/base/#section-4" target="_blank">4</a>. Requests</span>
|
<span><a name="section-4" href="#section-4">4</a>. Requests</span>
|
||||||
|
|
||||||
Client-to-server requests SHOULD be made over https [<a href="http://fakehost/test/base/#ref-HTTPS" target="_blank">HTTPS</a>], and
|
Client-to-server requests SHOULD be made over https [<a href="#ref-HTTPS">HTTPS</a>], and
|
||||||
servers MUST comply with HTTP/1.1 [<a href="http://fakehost/test/base/#ref-HTTP" target="_blank">HTTP</a>]. Specifically, they
|
servers MUST comply with HTTP/1.1 [<a href="#ref-HTTP">HTTP</a>]. Specifically, they
|
||||||
MUST support chunked transfer coding on PUT requests. Servers MAY
|
MUST support chunked transfer coding on PUT requests. Servers MAY
|
||||||
also offer an optional switch from https to SPDY [<a href="http://fakehost/test/base/#ref-SPDY" target="_blank">SPDY</a>].
|
also offer an optional switch from https to SPDY [<a href="#ref-SPDY">SPDY</a>].
|
||||||
|
|
||||||
A request is considered successful if the HTTP response code is in
|
A request is considered successful if the HTTP response code is in
|
||||||
the 2xx range (e.g. 200 OK, 201 Created), and unsuccessful if an
|
the 2xx range (e.g. 200 OK, 201 Created), and unsuccessful if an
|
||||||
|
@ -211,14 +211,14 @@ Table of Contents
|
||||||
|
|
||||||
<span>de Jong [Page 4]</span>
|
<span>de Jong [Page 4]</span>
|
||||||
</pre>
|
</pre>
|
||||||
<pre><a name="page-5" id="page-5" href="http://fakehost/test/base/#page-5" target="_blank"> </a>
|
<pre><a name="page-5" id="page-5" href="#page-5"> </a>
|
||||||
<span>Internet-Draft remoteStorage December 2014</span>
|
<span>Internet-Draft remoteStorage December 2014</span>
|
||||||
|
|
||||||
|
|
||||||
field, representing the folder's current version.
|
field, representing the folder's current version.
|
||||||
|
|
||||||
A successful GET request to a folder MUST be responded to with a
|
A successful GET request to a folder MUST be responded to with a
|
||||||
JSON-LD [<a href="http://fakehost/test/base/#ref-JSON-LD" target="_blank">JSON-LD</a>] document (content type 'application/ld+json'),
|
JSON-LD [<a href="#ref-JSON-LD">JSON-LD</a>] document (content type 'application/ld+json'),
|
||||||
containing as its 'items' field a map in which contained documents
|
containing as its 'items' field a map in which contained documents
|
||||||
appear as entries <item_name> to a document description, and
|
appear as entries <item_name> to a document description, and
|
||||||
contained non-empty folders appear as entries <item_name> '/' to a
|
contained non-empty folders appear as entries <item_name> '/' to a
|
||||||
|
@ -262,7 +262,7 @@ Table of Contents
|
||||||
|
|
||||||
<span>de Jong [Page 5]</span>
|
<span>de Jong [Page 5]</span>
|
||||||
</pre>
|
</pre>
|
||||||
<pre><a name="page-6" id="page-6" href="http://fakehost/test/base/#page-6" target="_blank"> </a>
|
<pre><a name="page-6" id="page-6" href="#page-6"> </a>
|
||||||
<span>Internet-Draft remoteStorage December 2014</span>
|
<span>Internet-Draft remoteStorage December 2014</span>
|
||||||
|
|
||||||
|
|
||||||
|
@ -273,9 +273,9 @@ Table of Contents
|
||||||
gzipped when requested by the client, since the two bodies would not
|
gzipped when requested by the client, since the two bodies would not
|
||||||
be identical byte-for-byte.
|
be identical byte-for-byte.
|
||||||
|
|
||||||
Servers MAY support Content-Range headers [<a href="http://fakehost/test/base/#ref-RANGE" target="_blank">RANGE</a>] on GET requests,
|
Servers MAY support Content-Range headers [<a href="#ref-RANGE">RANGE</a>] on GET requests,
|
||||||
but whether or not they do SHOULD be announced through the <ranges>
|
but whether or not they do SHOULD be announced through the <ranges>
|
||||||
variable mentioned below in <a href="http://fakehost/test/base/#section-10" target="_blank">section 10</a>.
|
variable mentioned below in <a href="#section-10">section 10</a>.
|
||||||
|
|
||||||
A successful PUT request to a document MUST result in:
|
A successful PUT request to a document MUST result in:
|
||||||
|
|
||||||
|
@ -288,7 +288,7 @@ Table of Contents
|
||||||
document's new content type,
|
document's new content type,
|
||||||
* its version being updated, as well as that of its parent folder
|
* its version being updated, as well as that of its parent folder
|
||||||
and further ancestor folders, using a strong validator [HTTP,
|
and further ancestor folders, using a strong validator [HTTP,
|
||||||
<a href="http://fakehost/test/base/#section-7.2" target="_blank">section 7.2</a>].
|
<a href="#section-7.2">section 7.2</a>].
|
||||||
|
|
||||||
The response MUST contain a strong ETag header, with the document's
|
The response MUST contain a strong ETag header, with the document's
|
||||||
new version (for instance a hash of its contents) as its value.
|
new version (for instance a hash of its contents) as its value.
|
||||||
|
@ -313,14 +313,14 @@ Table of Contents
|
||||||
|
|
||||||
<span>de Jong [Page 6]</span>
|
<span>de Jong [Page 6]</span>
|
||||||
</pre>
|
</pre>
|
||||||
<pre><a name="page-7" id="page-7" href="http://fakehost/test/base/#page-7" target="_blank"> </a>
|
<pre><a name="page-7" id="page-7" href="#page-7"> </a>
|
||||||
<span>Internet-Draft remoteStorage December 2014</span>
|
<span>Internet-Draft remoteStorage December 2014</span>
|
||||||
|
|
||||||
|
|
||||||
<span><a name="section-5" href="http://fakehost/test/base/#section-5" target="_blank">5</a>. Response codes</span>
|
<span><a name="section-5" href="#section-5">5</a>. Response codes</span>
|
||||||
|
|
||||||
Response codes SHOULD be given as defined by [HTTP, <a href="http://fakehost/test/base/#section-6" target="_blank">section 6</a>] and
|
Response codes SHOULD be given as defined by [HTTP, <a href="#section-6">section 6</a>] and
|
||||||
[BEARER, <a href="http://fakehost/test/base/#section-3.1" target="_blank">section 3.1</a>]. The following is a non-normative checklist
|
[BEARER, <a href="#section-3.1">section 3.1</a>]. The following is a non-normative checklist
|
||||||
of status codes that are likely to occur in practice:
|
of status codes that are likely to occur in practice:
|
||||||
|
|
||||||
* 500 if an internal server error occurs,
|
* 500 if an internal server error occurs,
|
||||||
|
@ -350,13 +350,13 @@ Table of Contents
|
||||||
Clients SHOULD also handle the case where a response takes too long
|
Clients SHOULD also handle the case where a response takes too long
|
||||||
to arrive, or where no response is received at all.
|
to arrive, or where no response is received at all.
|
||||||
|
|
||||||
<span><a name="section-6" href="http://fakehost/test/base/#section-6" target="_blank">6</a>. Versioning</span>
|
<span><a name="section-6" href="#section-6">6</a>. Versioning</span>
|
||||||
|
|
||||||
All successful requests MUST return an 'ETag' header [<a href="http://fakehost/test/base/#ref-HTTP" target="_blank">HTTP</a>] with, in
|
All successful requests MUST return an 'ETag' header [<a href="#ref-HTTP">HTTP</a>] with, in
|
||||||
the case of GET, the current version, in the case of PUT, the new
|
the case of GET, the current version, in the case of PUT, the new
|
||||||
version, and in case of DELETE, the version that was deleted. All
|
version, and in case of DELETE, the version that was deleted. All
|
||||||
successful GET requests MUST return an 'Expires: 0' header. PUT and
|
successful GET requests MUST return an 'Expires: 0' header. PUT and
|
||||||
DELETE requests MAY have an 'If-Match' request header [<a href="http://fakehost/test/base/#ref-COND" target="_blank">COND</a>], and
|
DELETE requests MAY have an 'If-Match' request header [<a href="#ref-COND">COND</a>], and
|
||||||
MUST fail with a 412 response code if that doesn't match the
|
MUST fail with a 412 response code if that doesn't match the
|
||||||
document's current version.
|
document's current version.
|
||||||
|
|
||||||
|
@ -364,14 +364,14 @@ Table of Contents
|
||||||
|
|
||||||
<span>de Jong [Page 7]</span>
|
<span>de Jong [Page 7]</span>
|
||||||
</pre>
|
</pre>
|
||||||
<pre><a name="page-8" id="page-8" href="http://fakehost/test/base/#page-8" target="_blank"> </a>
|
<pre><a name="page-8" id="page-8" href="#page-8"> </a>
|
||||||
<span>Internet-Draft remoteStorage December 2014</span>
|
<span>Internet-Draft remoteStorage December 2014</span>
|
||||||
|
|
||||||
|
|
||||||
GET requests MAY have a comma-separated list of revisions in an
|
GET requests MAY have a comma-separated list of revisions in an
|
||||||
'If-None-Match' header [<a href="http://fakehost/test/base/#ref-COND" target="_blank">COND</a>], and SHOULD be responded to with a 304
|
'If-None-Match' header [<a href="#ref-COND">COND</a>], and SHOULD be responded to with a 304
|
||||||
response if that list includes the document or folder's current
|
response if that list includes the document or folder's current
|
||||||
version. A PUT request MAY have an 'If-None-Match: *' header [<a href="http://fakehost/test/base/#ref-COND" target="_blank">COND</a>],
|
version. A PUT request MAY have an 'If-None-Match: *' header [<a href="#ref-COND">COND</a>],
|
||||||
in which case it MUST fail with a 412 response code if the document
|
in which case it MUST fail with a 412 response code if the document
|
||||||
already exists.
|
already exists.
|
||||||
|
|
||||||
|
@ -381,14 +381,14 @@ Table of Contents
|
||||||
A provider MAY offer version rollback functionality to its users,
|
A provider MAY offer version rollback functionality to its users,
|
||||||
but this specification does not define the user interface for that.
|
but this specification does not define the user interface for that.
|
||||||
|
|
||||||
<span><a name="section-7" href="http://fakehost/test/base/#section-7" target="_blank">7</a>. CORS headers</span>
|
<span><a name="section-7" href="#section-7">7</a>. CORS headers</span>
|
||||||
|
|
||||||
All responses MUST carry CORS headers [<a href="http://fakehost/test/base/#ref-CORS" target="_blank">CORS</a>]. The server MUST also
|
All responses MUST carry CORS headers [<a href="#ref-CORS">CORS</a>]. The server MUST also
|
||||||
reply to OPTIONS requests as per CORS. For GET requests, a wildcard
|
reply to OPTIONS requests as per CORS. For GET requests, a wildcard
|
||||||
origin MAY be returned, but for PUT and DELETE requests, the
|
origin MAY be returned, but for PUT and DELETE requests, the
|
||||||
response MUST echo back the Origin header sent by the client.
|
response MUST echo back the Origin header sent by the client.
|
||||||
|
|
||||||
<span><a name="section-8" href="http://fakehost/test/base/#section-8" target="_blank">8</a>. Session description</span>
|
<span><a name="section-8" href="#section-8">8</a>. Session description</span>
|
||||||
|
|
||||||
The information that a client needs to receive in order to be able
|
The information that a client needs to receive in order to be able
|
||||||
to connect to a server SHOULD reach the client as described in the
|
to connect to a server SHOULD reach the client as described in the
|
||||||
|
@ -396,12 +396,12 @@ Table of Contents
|
||||||
|
|
||||||
* <storage_root>, consisting of 'https://' followed by a server
|
* <storage_root>, consisting of 'https://' followed by a server
|
||||||
host, and optionally a server port and a path prefix as per
|
host, and optionally a server port and a path prefix as per
|
||||||
[<a href="http://fakehost/test/base/#ref-IRI" target="_blank">IRI</a>]. Examples:
|
[<a href="#ref-IRI">IRI</a>]. Examples:
|
||||||
* 'https://example.com' (host only)
|
* 'https://example.com' (host only)
|
||||||
* 'https://example.com:8080' (host and port)
|
* 'https://example.com:8080' (host and port)
|
||||||
* 'https://example.com/path/to/storage' (host, port and
|
* 'https://example.com/path/to/storage' (host, port and
|
||||||
path prefix; note there is no trailing slash)
|
path prefix; note there is no trailing slash)
|
||||||
* <access_token> as per [<a href="http://fakehost/test/base/#ref-OAUTH" target="_blank">OAUTH</a>]. The token SHOULD be hard to
|
* <access_token> as per [<a href="#ref-OAUTH">OAUTH</a>]. The token SHOULD be hard to
|
||||||
guess and SHOULD NOT be reused from one client to another. It
|
guess and SHOULD NOT be reused from one client to another. It
|
||||||
can however be reused in subsequent interactions with the same
|
can however be reused in subsequent interactions with the same
|
||||||
client, as long as that client is still trusted. Example:
|
client, as long as that client is still trusted. Example:
|
||||||
|
@ -415,7 +415,7 @@ Table of Contents
|
||||||
|
|
||||||
<span>de Jong [Page 8]</span>
|
<span>de Jong [Page 8]</span>
|
||||||
</pre>
|
</pre>
|
||||||
<pre><a name="page-9" id="page-9" href="http://fakehost/test/base/#page-9" target="_blank"> </a>
|
<pre><a name="page-9" id="page-9" href="#page-9"> </a>
|
||||||
<span>Internet-Draft remoteStorage December 2014</span>
|
<span>Internet-Draft remoteStorage December 2014</span>
|
||||||
|
|
||||||
|
|
||||||
|
@ -430,7 +430,7 @@ Table of Contents
|
||||||
* https://storage.example.com/bob/public/documents/
|
* https://storage.example.com/bob/public/documents/
|
||||||
* https://storage.example.com/bob/public/documents/draft.txt
|
* https://storage.example.com/bob/public/documents/draft.txt
|
||||||
|
|
||||||
<span><a name="section-9" href="http://fakehost/test/base/#section-9" target="_blank">9</a>. Bearer tokens and access control</span>
|
<span><a name="section-9" href="#section-9">9</a>. Bearer tokens and access control</span>
|
||||||
|
|
||||||
A bearer token represents one or more access scopes. These access
|
A bearer token represents one or more access scopes. These access
|
||||||
scopes are represented as strings of the form <module> <level>,
|
scopes are represented as strings of the form <module> <level>,
|
||||||
|
@ -452,7 +452,7 @@ Table of Contents
|
||||||
As a special exceptions, GET requests to a document (but not a
|
As a special exceptions, GET requests to a document (but not a
|
||||||
folder) whose path starts with '/public/' are always allowed. They,
|
folder) whose path starts with '/public/' are always allowed. They,
|
||||||
as well as OPTIONS requests, can be made without a bearer token.
|
as well as OPTIONS requests, can be made without a bearer token.
|
||||||
Unless [<a href="http://fakehost/test/base/#ref-KERBEROS" target="_blank">KERBEROS</a>] is used (see <a href="http://fakehost/test/base/#section-10" target="_blank">section 10</a> below), all other requests
|
Unless [<a href="#ref-KERBEROS">KERBEROS</a>] is used (see <a href="#section-10">section 10</a> below), all other requests
|
||||||
SHOULD present a bearer token with sufficient access scope, using a
|
SHOULD present a bearer token with sufficient access scope, using a
|
||||||
header of the following form (no double quotes here):
|
header of the following form (no double quotes here):
|
||||||
|
|
||||||
|
@ -461,21 +461,21 @@ Table of Contents
|
||||||
In addition, providing the access token via a HTTP query parameter
|
In addition, providing the access token via a HTTP query parameter
|
||||||
for GET requests MAY be supported by the server, although its use
|
for GET requests MAY be supported by the server, although its use
|
||||||
is not recommended, due to its security deficiencies; see [BEARER,
|
is not recommended, due to its security deficiencies; see [BEARER,
|
||||||
<a href="http://fakehost/test/base/#section-2.3" target="_blank">section 2.3</a>].
|
<a href="#section-2.3">section 2.3</a>].
|
||||||
|
|
||||||
|
|
||||||
<span>de Jong [Page 9]</span>
|
<span>de Jong [Page 9]</span>
|
||||||
</pre>
|
</pre>
|
||||||
<pre><a name="page-10" id="page-10" href="http://fakehost/test/base/#page-10" target="_blank"> </a>
|
<pre><a name="page-10" id="page-10" href="#page-10"> </a>
|
||||||
<span>Internet-Draft remoteStorage December 2014</span>
|
<span>Internet-Draft remoteStorage December 2014</span>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<span><a name="section-10" href="http://fakehost/test/base/#section-10" target="_blank">10</a>. Application-first bearer token issuance</span>
|
<span><a name="section-10" href="#section-10">10</a>. Application-first bearer token issuance</span>
|
||||||
|
|
||||||
To make a remoteStorage server available as 'the remoteStorage of
|
To make a remoteStorage server available as 'the remoteStorage of
|
||||||
<account> at <host>', exactly one link of the following format
|
<account> at <host>', exactly one link of the following format
|
||||||
SHOULD be added to the WebFinger record [<a href="http://fakehost/test/base/#ref-WEBFINGER" target="_blank">WEBFINGER</a>] of <account> at
|
SHOULD be added to the WebFinger record [<a href="#ref-WEBFINGER">WEBFINGER</a>] of <account> at
|
||||||
<host>:
|
<host>:
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -490,7 +490,7 @@ Table of Contents
|
||||||
|
|
||||||
Here <storage_root> and <storage_api> are as per "Session
|
Here <storage_root> and <storage_api> are as per "Session
|
||||||
description" above, and <auth-dialog> SHOULD be either null or a
|
description" above, and <auth-dialog> SHOULD be either null or a
|
||||||
URL where an OAuth 2.0 implicit-grant flow dialog [<a href="http://fakehost/test/base/#ref-OAUTH" target="_blank">OAUTH</a>] is
|
URL where an OAuth 2.0 implicit-grant flow dialog [<a href="#ref-OAUTH">OAUTH</a>] is
|
||||||
presented.
|
presented.
|
||||||
|
|
||||||
If <auth-dialog> is a URL, the user can supply their credentials
|
If <auth-dialog> is a URL, the user can supply their credentials
|
||||||
|
@ -502,7 +502,7 @@ Table of Contents
|
||||||
|
|
||||||
If <auth-dialog> is null, the client will not have a way to obtain
|
If <auth-dialog> is null, the client will not have a way to obtain
|
||||||
an access token, and SHOULD send all requests without Authorization
|
an access token, and SHOULD send all requests without Authorization
|
||||||
header, and rely on Kerberos [<a href="http://fakehost/test/base/#ref-KERBEROS" target="_blank">KERBEROS</a>] instead for requests that
|
header, and rely on Kerberos [<a href="#ref-KERBEROS">KERBEROS</a>] instead for requests that
|
||||||
would normally be sent with a bearer token, but servers SHOULD NOT
|
would normally be sent with a bearer token, but servers SHOULD NOT
|
||||||
impose any such access barriers for resources that would normally
|
impose any such access barriers for resources that would normally
|
||||||
not require an access token.
|
not require an access token.
|
||||||
|
@ -511,20 +511,20 @@ Table of Contents
|
||||||
Non-breaking examples that have been proposed so far, include a
|
Non-breaking examples that have been proposed so far, include a
|
||||||
"<a href="http://tools.ietf.org/html/rfc6750#section-2.3" target="_blank">http://tools.ietf.org/html/rfc6750#section-2.3</a>" property, set to
|
"<a href="http://tools.ietf.org/html/rfc6750#section-2.3" target="_blank">http://tools.ietf.org/html/rfc6750#section-2.3</a>" property, set to
|
||||||
the string value "true" if the server supports passing the bearer
|
the string value "true" if the server supports passing the bearer
|
||||||
token in the URI query parameter as per section 2.3 of [<a href="http://fakehost/test/base/#ref-BEARER" target="_blank">BEARER</a>],
|
token in the URI query parameter as per section 2.3 of [<a href="#ref-BEARER">BEARER</a>],
|
||||||
instead of in the request header.
|
instead of in the request header.
|
||||||
|
|
||||||
|
|
||||||
<span>de Jong [Page 10]</span>
|
<span>de Jong [Page 10]</span>
|
||||||
</pre>
|
</pre>
|
||||||
<pre><a name="page-11" id="page-11" href="http://fakehost/test/base/#page-11" target="_blank"> </a>
|
<pre><a name="page-11" id="page-11" href="#page-11"> </a>
|
||||||
<span>Internet-Draft remoteStorage December 2014</span>
|
<span>Internet-Draft remoteStorage December 2014</span>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Another example is "<a href="http://tools.ietf.org/html/rfc7233" target="_blank">http://tools.ietf.org/html/rfc7233</a>" with a
|
Another example is "<a href="http://tools.ietf.org/html/rfc7233" target="_blank">http://tools.ietf.org/html/rfc7233</a>" with a
|
||||||
string value of "GET" if Content-Range headers are supported for
|
string value of "GET" if Content-Range headers are supported for
|
||||||
GET requests as per [<a href="http://fakehost/test/base/#ref-RANGE" target="_blank">RANGE</a>], "PUT" if they are supported for PUT
|
GET requests as per [<a href="#ref-RANGE">RANGE</a>], "PUT" if they are supported for PUT
|
||||||
requests, and "GET,PUT" if supported for both.
|
requests, and "GET,PUT" if supported for both.
|
||||||
|
|
||||||
Both these proposals are non-breaking extensions, since the client
|
Both these proposals are non-breaking extensions, since the client
|
||||||
|
@ -535,7 +535,7 @@ Table of Contents
|
||||||
A "<a href="http://remotestorage.io/spec/web-authoring" target="_blank">http://remotestorage.io/spec/web-authoring</a>" property has been
|
A "<a href="http://remotestorage.io/spec/web-authoring" target="_blank">http://remotestorage.io/spec/web-authoring</a>" property has been
|
||||||
proposed with a string value of the fully qualified domain name to
|
proposed with a string value of the fully qualified domain name to
|
||||||
which web authoring content is published if the server supports web
|
which web authoring content is published if the server supports web
|
||||||
authoring as per [<a href="http://fakehost/test/base/#ref-AUTHORING" target="_blank">AUTHORING</a>]. Note that this extension is a breaking
|
authoring as per [<a href="#ref-AUTHORING">AUTHORING</a>]. Note that this extension is a breaking
|
||||||
extension in the sense that it divides users into "haves", whose
|
extension in the sense that it divides users into "haves", whose
|
||||||
remoteStorage accounts allow them to author web content, and
|
remoteStorage accounts allow them to author web content, and
|
||||||
"have-nots", whose remoteStorage account does not support this
|
"have-nots", whose remoteStorage account does not support this
|
||||||
|
@ -547,10 +547,10 @@ Table of Contents
|
||||||
client_id parameter in favor of relying on the redirect_uri
|
client_id parameter in favor of relying on the redirect_uri
|
||||||
parameter for client identification.
|
parameter for client identification.
|
||||||
|
|
||||||
<span><a name="section-11" href="http://fakehost/test/base/#section-11" target="_blank">11</a>. Storage-first bearer token issuance</span>
|
<span><a name="section-11" href="#section-11">11</a>. Storage-first bearer token issuance</span>
|
||||||
|
|
||||||
The provider MAY also present a dashboard to the user, where they
|
The provider MAY also present a dashboard to the user, where they
|
||||||
have some way to add open web app manifests [<a href="http://fakehost/test/base/#ref-MANIFEST" target="_blank">MANIFEST</a>]. Adding a
|
have some way to add open web app manifests [<a href="#ref-MANIFEST">MANIFEST</a>]. Adding a
|
||||||
manifest to the dashboard is considered equivalent to clicking
|
manifest to the dashboard is considered equivalent to clicking
|
||||||
'accept' in the dialog of the application-first flow. Removing one
|
'accept' in the dialog of the application-first flow. Removing one
|
||||||
is considered equivalent to revoking its access token.
|
is considered equivalent to revoking its access token.
|
||||||
|
@ -559,7 +559,7 @@ Table of Contents
|
||||||
field SHOULD be present in the root of such an application manifest
|
field SHOULD be present in the root of such an application manifest
|
||||||
document, with entries <module> -> '{"access": "readonly"}' for
|
document, with entries <module> -> '{"access": "readonly"}' for
|
||||||
<level> 'r' or '{"access": "readwrite"}' for <level> 'rw', as
|
<level> 'r' or '{"access": "readwrite"}' for <level> 'rw', as
|
||||||
prescribed in [<a href="http://fakehost/test/base/#ref-DATASTORE" target="_blank">DATASTORE</a>].
|
prescribed in [<a href="#ref-DATASTORE">DATASTORE</a>].
|
||||||
|
|
||||||
When the user gestures they want to use a certain application whose
|
When the user gestures they want to use a certain application whose
|
||||||
manifest is present on the dashboard, the dashboard SHOULD redirect
|
manifest is present on the dashboard, the dashboard SHOULD redirect
|
||||||
|
@ -568,7 +568,7 @@ Table of Contents
|
||||||
|
|
||||||
<span>de Jong [Page 11]</span>
|
<span>de Jong [Page 11]</span>
|
||||||
</pre>
|
</pre>
|
||||||
<pre><a name="page-12" id="page-12" href="http://fakehost/test/base/#page-12" target="_blank"> </a>
|
<pre><a name="page-12" id="page-12" href="#page-12"> </a>
|
||||||
<span>Internet-Draft remoteStorage December 2014</span>
|
<span>Internet-Draft remoteStorage December 2014</span>
|
||||||
|
|
||||||
|
|
||||||
|
@ -606,12 +606,12 @@ Table of Contents
|
||||||
debug tool, thus bypassing the need for an OAuth dance. Clients
|
debug tool, thus bypassing the need for an OAuth dance. Clients
|
||||||
SHOULD NOT rely on this in production.
|
SHOULD NOT rely on this in production.
|
||||||
|
|
||||||
<span><a name="section-12" href="http://fakehost/test/base/#section-12" target="_blank">12</a>. Example wire transcripts</span>
|
<span><a name="section-12" href="#section-12">12</a>. Example wire transcripts</span>
|
||||||
|
|
||||||
The following examples are not normative ("\" indicates a line was
|
The following examples are not normative ("\" indicates a line was
|
||||||
wrapped).
|
wrapped).
|
||||||
|
|
||||||
<span><a name="section-12.1" href="http://fakehost/test/base/#section-12.1" target="_blank">12.1</a>. WebFinger</span>
|
<span><a name="section-12.1" href="#section-12.1">12.1</a>. WebFinger</span>
|
||||||
|
|
||||||
In application-first, an in-browser application might issue the
|
In application-first, an in-browser application might issue the
|
||||||
following request, using XMLHttpRequest and CORS:
|
following request, using XMLHttpRequest and CORS:
|
||||||
|
@ -619,7 +619,7 @@ Table of Contents
|
||||||
|
|
||||||
<span>de Jong [Page 12]</span>
|
<span>de Jong [Page 12]</span>
|
||||||
</pre>
|
</pre>
|
||||||
<pre><a name="page-13" id="page-13" href="http://fakehost/test/base/#page-13" target="_blank"> </a>
|
<pre><a name="page-13" id="page-13" href="#page-13"> </a>
|
||||||
<span>Internet-Draft remoteStorage December 2014</span>
|
<span>Internet-Draft remoteStorage December 2014</span>
|
||||||
|
|
||||||
|
|
||||||
|
@ -659,7 +659,7 @@ motestorage-04",
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
<span><a name="section-12.2" href="http://fakehost/test/base/#section-12.2" target="_blank">12.2</a>. OAuth dialog form</span>
|
<span><a name="section-12.2" href="#section-12.2">12.2</a>. OAuth dialog form</span>
|
||||||
|
|
||||||
Once the in-browser application has discovered the server's OAuth
|
Once the in-browser application has discovered the server's OAuth
|
||||||
end-point, it will typically redirect the user to this URL, in
|
end-point, it will typically redirect the user to this URL, in
|
||||||
|
@ -670,7 +670,7 @@ motestorage-04",
|
||||||
|
|
||||||
<span>de Jong [Page 13]</span>
|
<span>de Jong [Page 13]</span>
|
||||||
</pre>
|
</pre>
|
||||||
<pre><a name="page-14" id="page-14" href="http://fakehost/test/base/#page-14" target="_blank"> </a>
|
<pre><a name="page-14" id="page-14" href="#page-14"> </a>
|
||||||
<span>Internet-Draft remoteStorage December 2014</span>
|
<span>Internet-Draft remoteStorage December 2014</span>
|
||||||
|
|
||||||
|
|
||||||
|
@ -690,7 +690,7 @@ unhosted.5apps.com&response_type=token HTTP/1.1
|
||||||
<title>Allow access?</title>
|
<title>Allow access?</title>
|
||||||
...
|
...
|
||||||
|
|
||||||
<span><a name="section-12.3" href="http://fakehost/test/base/#section-12.3" target="_blank">12.3</a>. OAuth dialog form submission</span>
|
<span><a name="section-12.3" href="#section-12.3">12.3</a>. OAuth dialog form submission</span>
|
||||||
|
|
||||||
When the user submits the form, the request would look something
|
When the user submits the form, the request would look something
|
||||||
like this:
|
like this:
|
||||||
|
@ -715,13 +715,13 @@ low
|
||||||
Location:https://drinks-unhosted.5apps.com/#access_token=j2YnGt\
|
Location:https://drinks-unhosted.5apps.com/#access_token=j2YnGt\
|
||||||
XjzzzHNjkd1CJxoQubA1o%3D&token_type=bearer&state=
|
XjzzzHNjkd1CJxoQubA1o%3D&token_type=bearer&state=
|
||||||
|
|
||||||
<span><a name="section-12.4" href="http://fakehost/test/base/#section-12.4" target="_blank">12.4</a>. OPTIONS preflight</span>
|
<span><a name="section-12.4" href="#section-12.4">12.4</a>. OPTIONS preflight</span>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<span>de Jong [Page 14]</span>
|
<span>de Jong [Page 14]</span>
|
||||||
</pre>
|
</pre>
|
||||||
<pre><a name="page-15" id="page-15" href="http://fakehost/test/base/#page-15" target="_blank"> </a>
|
<pre><a name="page-15" id="page-15" href="#page-15"> </a>
|
||||||
<span>Internet-Draft remoteStorage December 2014</span>
|
<span>Internet-Draft remoteStorage December 2014</span>
|
||||||
|
|
||||||
|
|
||||||
|
@ -744,7 +744,7 @@ XjzzzHNjkd1CJxoQubA1o%3D&token_type=bearer&state=
|
||||||
Access-Control-Allow-Headers: Authorization, Content-Length, Co\
|
Access-Control-Allow-Headers: Authorization, Content-Length, Co\
|
||||||
ntent-Type, Origin, X-Requested-With, If-Match, If-None-Match
|
ntent-Type, Origin, X-Requested-With, If-Match, If-None-Match
|
||||||
|
|
||||||
<span><a name="section-12.5" href="http://fakehost/test/base/#section-12.5" target="_blank">12.5</a>. Initial PUT</span>
|
<span><a name="section-12.5" href="#section-12.5">12.5</a>. Initial PUT</span>
|
||||||
|
|
||||||
An initial PUT may contain an 'If-None-Match: *' header, like this:
|
An initial PUT may contain an 'If-None-Match: *' header, like this:
|
||||||
|
|
||||||
|
@ -767,12 +767,12 @@ ntent-Type, Origin, X-Requested-With, If-Match, If-None-Match
|
||||||
Access-Control-Allow-Origin: <a href="https://drinks-unhosted.5apps.com/" target="_blank">https://drinks-unhosted.5apps.com</a>
|
Access-Control-Allow-Origin: <a href="https://drinks-unhosted.5apps.com/" target="_blank">https://drinks-unhosted.5apps.com</a>
|
||||||
ETag: "1382694045000"
|
ETag: "1382694045000"
|
||||||
|
|
||||||
<span><a name="section-12.6" href="http://fakehost/test/base/#section-12.6" target="_blank">12.6</a>. Subsequent PUT</span>
|
<span><a name="section-12.6" href="#section-12.6">12.6</a>. Subsequent PUT</span>
|
||||||
|
|
||||||
|
|
||||||
<span>de Jong [Page 15]</span>
|
<span>de Jong [Page 15]</span>
|
||||||
</pre>
|
</pre>
|
||||||
<pre><a name="page-16" id="page-16" href="http://fakehost/test/base/#page-16" target="_blank"> </a>
|
<pre><a name="page-16" id="page-16" href="#page-16"> </a>
|
||||||
<span>Internet-Draft remoteStorage December 2014</span>
|
<span>Internet-Draft remoteStorage December 2014</span>
|
||||||
|
|
||||||
|
|
||||||
|
@ -798,7 +798,7 @@ e.io/spec/modules/myfavoritedrinks/drink"}
|
||||||
Access-Control-Allow-Origin: <a href="https://drinks-unhosted.5apps.com/" target="_blank">https://drinks-unhosted.5apps.com</a>
|
Access-Control-Allow-Origin: <a href="https://drinks-unhosted.5apps.com/" target="_blank">https://drinks-unhosted.5apps.com</a>
|
||||||
ETag: "1382694048000"
|
ETag: "1382694048000"
|
||||||
|
|
||||||
<span><a name="section-12.7" href="http://fakehost/test/base/#section-12.7" target="_blank">12.7</a>. GET</span>
|
<span><a name="section-12.7" href="#section-12.7">12.7</a>. GET</span>
|
||||||
|
|
||||||
A GET request would also include the bearer token, and optionally
|
A GET request would also include the bearer token, and optionally
|
||||||
an If-None-Match header:
|
an If-None-Match header:
|
||||||
|
@ -823,7 +823,7 @@ e.io/spec/modules/myfavoritedrinks/drink"}
|
||||||
|
|
||||||
<span>de Jong [Page 16]</span>
|
<span>de Jong [Page 16]</span>
|
||||||
</pre>
|
</pre>
|
||||||
<pre><a name="page-17" id="page-17" href="http://fakehost/test/base/#page-17" target="_blank"> </a>
|
<pre><a name="page-17" id="page-17" href="#page-17"> </a>
|
||||||
<span>Internet-Draft remoteStorage December 2014</span>
|
<span>Internet-Draft remoteStorage December 2014</span>
|
||||||
|
|
||||||
|
|
||||||
|
@ -858,7 +858,7 @@ charset=UTF-8","Content-Length":106}}}
|
||||||
HTTP/1.1 404 Not Found
|
HTTP/1.1 404 Not Found
|
||||||
Access-Control-Allow-Origin: <a href="https://drinks-unhosted.5apps.com/" target="_blank">https://drinks-unhosted.5apps.com</a>
|
Access-Control-Allow-Origin: <a href="https://drinks-unhosted.5apps.com/" target="_blank">https://drinks-unhosted.5apps.com</a>
|
||||||
|
|
||||||
<span><a name="section-12.8" href="http://fakehost/test/base/#section-12.8" target="_blank">12.8</a>. DELETE</span>
|
<span><a name="section-12.8" href="#section-12.8">12.8</a>. DELETE</span>
|
||||||
|
|
||||||
A DELETE request may look like this:
|
A DELETE request may look like this:
|
||||||
|
|
||||||
|
@ -874,7 +874,7 @@ charset=UTF-8","Content-Length":106}}}
|
||||||
|
|
||||||
<span>de Jong [Page 17]</span>
|
<span>de Jong [Page 17]</span>
|
||||||
</pre>
|
</pre>
|
||||||
<pre><a name="page-18" id="page-18" href="http://fakehost/test/base/#page-18" target="_blank"> </a>
|
<pre><a name="page-18" id="page-18" href="#page-18"> </a>
|
||||||
<span>Internet-Draft remoteStorage December 2014</span>
|
<span>Internet-Draft remoteStorage December 2014</span>
|
||||||
|
|
||||||
|
|
||||||
|
@ -884,7 +884,7 @@ charset=UTF-8","Content-Length":106}}}
|
||||||
Access-Control-Allow-Origin: <a href="https://drinks-unhosted.5apps.com/" target="_blank">https://drinks-unhosted.5apps.com</a>
|
Access-Control-Allow-Origin: <a href="https://drinks-unhosted.5apps.com/" target="_blank">https://drinks-unhosted.5apps.com</a>
|
||||||
ETag: "1382694048000"
|
ETag: "1382694048000"
|
||||||
|
|
||||||
<span><a name="section-13" href="http://fakehost/test/base/#section-13" target="_blank">13</a>. Distributed versioning</span>
|
<span><a name="section-13" href="#section-13">13</a>. Distributed versioning</span>
|
||||||
|
|
||||||
This section is non-normative, and is intended to explain some of
|
This section is non-normative, and is intended to explain some of
|
||||||
the design choices concerning ETags and folder listings. At the
|
the design choices concerning ETags and folder listings. At the
|
||||||
|
@ -925,7 +925,7 @@ charset=UTF-8","Content-Length":106}}}
|
||||||
|
|
||||||
<span>de Jong [Page 18]</span>
|
<span>de Jong [Page 18]</span>
|
||||||
</pre>
|
</pre>
|
||||||
<pre><a name="page-19" id="page-19" href="http://fakehost/test/base/#page-19" target="_blank"> </a>
|
<pre><a name="page-19" id="page-19" href="#page-19"> </a>
|
||||||
<span>Internet-Draft remoteStorage December 2014</span>
|
<span>Internet-Draft remoteStorage December 2014</span>
|
||||||
|
|
||||||
|
|
||||||
|
@ -947,7 +947,7 @@ charset=UTF-8","Content-Length":106}}}
|
||||||
but it is up to whichever client discovers a given version
|
but it is up to whichever client discovers a given version
|
||||||
conflict, to resolve it.
|
conflict, to resolve it.
|
||||||
|
|
||||||
<span><a name="section-14" href="http://fakehost/test/base/#section-14" target="_blank">14</a>. Security Considerations</span>
|
<span><a name="section-14" href="#section-14">14</a>. Security Considerations</span>
|
||||||
|
|
||||||
To prevent man-in-the-middle attacks, the use of https instead of
|
To prevent man-in-the-middle attacks, the use of https instead of
|
||||||
http is important for both the interface itself and all end-points
|
http is important for both the interface itself and all end-points
|
||||||
|
@ -976,7 +976,7 @@ charset=UTF-8","Content-Length":106}}}
|
||||||
|
|
||||||
<span>de Jong [Page 19]</span>
|
<span>de Jong [Page 19]</span>
|
||||||
</pre>
|
</pre>
|
||||||
<pre><a name="page-20" id="page-20" href="http://fakehost/test/base/#page-20" target="_blank"> </a>
|
<pre><a name="page-20" id="page-20" href="#page-20"> </a>
|
||||||
<span>Internet-Draft remoteStorage December 2014</span>
|
<span>Internet-Draft remoteStorage December 2014</span>
|
||||||
|
|
||||||
|
|
||||||
|
@ -993,7 +993,7 @@ charset=UTF-8","Content-Length":106}}}
|
||||||
The server SHOULD also detect and stop denial-of-service attacks
|
The server SHOULD also detect and stop denial-of-service attacks
|
||||||
that aim to overwhelm its interface with too much traffic.
|
that aim to overwhelm its interface with too much traffic.
|
||||||
|
|
||||||
<span><a name="section-15" href="http://fakehost/test/base/#section-15" target="_blank">15</a>. IANA Considerations</span>
|
<span><a name="section-15" href="#section-15">15</a>. IANA Considerations</span>
|
||||||
|
|
||||||
This document registers the 'remotestorage' link relation, as well
|
This document registers the 'remotestorage' link relation, as well
|
||||||
as the following WebFinger properties:
|
as the following WebFinger properties:
|
||||||
|
@ -1003,7 +1003,7 @@ charset=UTF-8","Content-Length":106}}}
|
||||||
* "<a href="http://tools.ietf.org/html/rfc7233" target="_blank">http://tools.ietf.org/html/rfc7233</a>"
|
* "<a href="http://tools.ietf.org/html/rfc7233" target="_blank">http://tools.ietf.org/html/rfc7233</a>"
|
||||||
* "<a href="http://remotestorage.io/spec/web-authoring" target="_blank">http://remotestorage.io/spec/web-authoring</a>"
|
* "<a href="http://remotestorage.io/spec/web-authoring" target="_blank">http://remotestorage.io/spec/web-authoring</a>"
|
||||||
|
|
||||||
<span><a name="section-16" href="http://fakehost/test/base/#section-16" target="_blank">16</a>. Acknowledgements</span>
|
<span><a name="section-16" href="#section-16">16</a>. Acknowledgements</span>
|
||||||
|
|
||||||
The authors would like to thank everybody who contributed to the
|
The authors would like to thank everybody who contributed to the
|
||||||
development of this protocol, including Kenny Bentley, Javier Diaz,
|
development of this protocol, including Kenny Bentley, Javier Diaz,
|
||||||
|
@ -1016,88 +1016,88 @@ charset=UTF-8","Content-Length":106}}}
|
||||||
Rick van Rein, Mark Nottingham, Julian Reschke, and Markus
|
Rick van Rein, Mark Nottingham, Julian Reschke, and Markus
|
||||||
Lanthaler, among many others.
|
Lanthaler, among many others.
|
||||||
|
|
||||||
<span><a name="section-17" href="http://fakehost/test/base/#section-17" target="_blank">17</a>. References</span>
|
<span><a name="section-17" href="#section-17">17</a>. References</span>
|
||||||
|
|
||||||
<span><a name="section-17.1" href="http://fakehost/test/base/#section-17.1" target="_blank">17.1</a>. Normative References</span>
|
<span><a name="section-17.1" href="#section-17.1">17.1</a>. Normative References</span>
|
||||||
|
|
||||||
[<a name="ref-WORDS" id="ref-WORDS" target="_blank">WORDS</a>]
|
[<a name="ref-WORDS" id="ref-WORDS">WORDS</a>]
|
||||||
Bradner, S., "Key words for use in RFCs to Indicate Requirement
|
Bradner, S., "Key words for use in RFCs to Indicate Requirement
|
||||||
Levels", <a href="http://fakehost/test/base/bcp14" target="_blank">BCP 14</a>, <a href="http://fakehost/test/base/rfc2119" target="_blank">RFC 2119</a>, March 1997.
|
Levels", <a href="http://fakehost/test/base/bcp14" target="_blank">BCP 14</a>, <a href="http://fakehost/test/base/rfc2119" target="_blank">RFC 2119</a>, March 1997.
|
||||||
|
|
||||||
|
|
||||||
<span>de Jong [Page 20]</span>
|
<span>de Jong [Page 20]</span>
|
||||||
</pre>
|
</pre>
|
||||||
<pre><a name="page-21" id="page-21" href="http://fakehost/test/base/#page-21" target="_blank"> </a>
|
<pre><a name="page-21" id="page-21" href="#page-21"> </a>
|
||||||
<span>Internet-Draft remoteStorage December 2014</span>
|
<span>Internet-Draft remoteStorage December 2014</span>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[<a name="ref-IRI" id="ref-IRI" target="_blank">IRI</a>]
|
[<a name="ref-IRI" id="ref-IRI">IRI</a>]
|
||||||
Duerst, M., "Internationalized Resource Identifiers (IRIs)",
|
Duerst, M., "Internationalized Resource Identifiers (IRIs)",
|
||||||
<a href="http://fakehost/test/base/rfc3987" target="_blank">RFC 3987</a>, January 2005.
|
<a href="http://fakehost/test/base/rfc3987" target="_blank">RFC 3987</a>, January 2005.
|
||||||
|
|
||||||
[<a name="ref-WEBFINGER" id="ref-WEBFINGER" target="_blank">WEBFINGER</a>]
|
[<a name="ref-WEBFINGER" id="ref-WEBFINGER">WEBFINGER</a>]
|
||||||
Jones, P., Salguerio, G., Jones, M, and Smarr, J.,
|
Jones, P., Salguerio, G., Jones, M, and Smarr, J.,
|
||||||
"WebFinger", <a href="http://fakehost/test/base/rfc7033" target="_blank">RFC7033</a>, September 2013.
|
"WebFinger", <a href="http://fakehost/test/base/rfc7033" target="_blank">RFC7033</a>, September 2013.
|
||||||
|
|
||||||
[<a name="ref-OAUTH" id="ref-OAUTH" target="_blank">OAUTH</a>]
|
[<a name="ref-OAUTH" id="ref-OAUTH">OAUTH</a>]
|
||||||
"<a href="http://fakehost/test/base/#section-4.2" target="_blank">Section 4.2</a>: Implicit Grant", in: Hardt, D. (ed), "The OAuth
|
"<a href="#section-4.2">Section 4.2</a>: Implicit Grant", in: Hardt, D. (ed), "The OAuth
|
||||||
2.0 Authorization Framework", <a href="http://fakehost/test/base/rfc6749" target="_blank">RFC6749</a>, October 2012.
|
2.0 Authorization Framework", <a href="http://fakehost/test/base/rfc6749" target="_blank">RFC6749</a>, October 2012.
|
||||||
|
|
||||||
<span><a name="section-17.2" href="http://fakehost/test/base/#section-17.2" target="_blank">17.2</a>. Informative References</span>
|
<span><a name="section-17.2" href="#section-17.2">17.2</a>. Informative References</span>
|
||||||
|
|
||||||
[<a name="ref-HTTPS" id="ref-HTTPS" target="_blank">HTTPS</a>]
|
[<a name="ref-HTTPS" id="ref-HTTPS">HTTPS</a>]
|
||||||
Rescorla, E., "HTTP Over TLS", <a href="http://fakehost/test/base/rfc2818" target="_blank">RFC2818</a>, May 2000.
|
Rescorla, E., "HTTP Over TLS", <a href="http://fakehost/test/base/rfc2818" target="_blank">RFC2818</a>, May 2000.
|
||||||
|
|
||||||
[<a name="ref-HTTP" id="ref-HTTP" target="_blank">HTTP</a>]
|
[<a name="ref-HTTP" id="ref-HTTP">HTTP</a>]
|
||||||
Fielding et al., "Hypertext Transfer Protocol (HTTP/1.1):
|
Fielding et al., "Hypertext Transfer Protocol (HTTP/1.1):
|
||||||
Semantics and Content", <a href="http://fakehost/test/base/rfc7231" target="_blank">RFC7231</a>, June 2014.
|
Semantics and Content", <a href="http://fakehost/test/base/rfc7231" target="_blank">RFC7231</a>, June 2014.
|
||||||
|
|
||||||
[<a name="ref-COND" id="ref-COND" target="_blank">COND</a>]
|
[<a name="ref-COND" id="ref-COND">COND</a>]
|
||||||
Fielding et al., "Hypertext Transfer Protocol (HTTP/1.1):
|
Fielding et al., "Hypertext Transfer Protocol (HTTP/1.1):
|
||||||
Conditional Requests", <a href="http://fakehost/test/base/rfc7232" target="_blank">RFC7232</a>, June 2014.
|
Conditional Requests", <a href="http://fakehost/test/base/rfc7232" target="_blank">RFC7232</a>, June 2014.
|
||||||
|
|
||||||
[<a name="ref-RANGE" id="ref-RANGE" target="_blank">RANGE</a>]
|
[<a name="ref-RANGE" id="ref-RANGE">RANGE</a>]
|
||||||
Fielding et al., "Hypertext Transfer Protocol (HTTP/1.1):
|
Fielding et al., "Hypertext Transfer Protocol (HTTP/1.1):
|
||||||
Conditional Requests", <a href="http://fakehost/test/base/rfc7233" target="_blank">RFC7233</a>, June 2014.
|
Conditional Requests", <a href="http://fakehost/test/base/rfc7233" target="_blank">RFC7233</a>, June 2014.
|
||||||
|
|
||||||
[<a name="ref-SPDY" id="ref-SPDY" target="_blank">SPDY</a>]
|
[<a name="ref-SPDY" id="ref-SPDY">SPDY</a>]
|
||||||
Mark Belshe, Roberto Peon, "SPDY Protocol - Draft 3.1", <a href="http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3-1" target="_blank">http://</a>
|
Mark Belshe, Roberto Peon, "SPDY Protocol - Draft 3.1", <a href="http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3-1" target="_blank">http://</a>
|
||||||
<a href="http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3-1" target="_blank">www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3-1</a>,
|
<a href="http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3-1" target="_blank">www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3-1</a>,
|
||||||
September 2013.
|
September 2013.
|
||||||
|
|
||||||
[<a name="ref-JSON-LD" id="ref-JSON-LD" target="_blank">JSON-LD</a>]
|
[<a name="ref-JSON-LD" id="ref-JSON-LD">JSON-LD</a>]
|
||||||
M. Sporny, G. Kellogg, M. Lanthaler, "JSON-LD 1.0", W3C
|
M. Sporny, G. Kellogg, M. Lanthaler, "JSON-LD 1.0", W3C
|
||||||
Proposed Recommendation,
|
Proposed Recommendation,
|
||||||
<a href="http://www.w3.org/TR/2014/REC-json-ld-20140116/" target="_blank">http://www.w3.org/TR/2014/REC-json-ld-20140116/</a>, January 2014.
|
<a href="http://www.w3.org/TR/2014/REC-json-ld-20140116/" target="_blank">http://www.w3.org/TR/2014/REC-json-ld-20140116/</a>, January 2014.
|
||||||
|
|
||||||
[<a name="ref-CORS" id="ref-CORS" target="_blank">CORS</a>]
|
[<a name="ref-CORS" id="ref-CORS">CORS</a>]
|
||||||
van Kesteren, Anne (ed), "Cross-Origin Resource Sharing --
|
van Kesteren, Anne (ed), "Cross-Origin Resource Sharing --
|
||||||
W3C Candidate Recommendation 29 January 2013",
|
W3C Candidate Recommendation 29 January 2013",
|
||||||
|
|
||||||
|
|
||||||
<span>de Jong [Page 21]</span>
|
<span>de Jong [Page 21]</span>
|
||||||
</pre>
|
</pre>
|
||||||
<pre><a name="page-22" id="page-22" href="http://fakehost/test/base/#page-22" target="_blank"> </a>
|
<pre><a name="page-22" id="page-22" href="#page-22"> </a>
|
||||||
<span>Internet-Draft remoteStorage December 2014</span>
|
<span>Internet-Draft remoteStorage December 2014</span>
|
||||||
|
|
||||||
|
|
||||||
<a href="http://www.w3.org/TR/cors/" target="_blank">http://www.w3.org/TR/cors/</a>, January 2013.
|
<a href="http://www.w3.org/TR/cors/" target="_blank">http://www.w3.org/TR/cors/</a>, January 2013.
|
||||||
|
|
||||||
[<a name="ref-MANIFEST" id="ref-MANIFEST" target="_blank">MANIFEST</a>]
|
[<a name="ref-MANIFEST" id="ref-MANIFEST">MANIFEST</a>]
|
||||||
Mozilla Developer Network (ed), "App manifest -- Revision
|
Mozilla Developer Network (ed), "App manifest -- Revision
|
||||||
330541", <a href="https://developer.mozilla.org/en-" target="_blank">https://developer.mozilla.org/en-</a>
|
330541", <a href="https://developer.mozilla.org/en-" target="_blank">https://developer.mozilla.org/en-</a>
|
||||||
US/Apps/Build/Manifest$revision/566677, April 2014.
|
US/Apps/Build/Manifest$revision/566677, April 2014.
|
||||||
|
|
||||||
[<a name="ref-DATASTORE" id="ref-DATASTORE" target="_blank">DATASTORE</a>]
|
[<a name="ref-DATASTORE" id="ref-DATASTORE">DATASTORE</a>]
|
||||||
"WebAPI/DataStore", MozillaWiki, retrieved May 2014.
|
"WebAPI/DataStore", MozillaWiki, retrieved May 2014.
|
||||||
<a href="https://wiki.mozilla.org/WebAPI/DataStore#Manifest" target="_blank">https://wiki.mozilla.org/WebAPI/DataStore#Manifest</a>
|
<a href="https://wiki.mozilla.org/WebAPI/DataStore#Manifest" target="_blank">https://wiki.mozilla.org/WebAPI/DataStore#Manifest</a>
|
||||||
|
|
||||||
[<a name="ref-KERBEROS" id="ref-KERBEROS" target="_blank">KERBEROS</a>]
|
[<a name="ref-KERBEROS" id="ref-KERBEROS">KERBEROS</a>]
|
||||||
C. Neuman et al., "The Kerberos Network Authentication Service
|
C. Neuman et al., "The Kerberos Network Authentication Service
|
||||||
(V5)", <a href="http://fakehost/test/base/rfc4120" target="_blank">RFC4120</a>, July 2005.
|
(V5)", <a href="http://fakehost/test/base/rfc4120" target="_blank">RFC4120</a>, July 2005.
|
||||||
|
|
||||||
[<a name="ref-BEARER" id="ref-BEARER" target="_blank">BEARER</a>]
|
[<a name="ref-BEARER" id="ref-BEARER">BEARER</a>]
|
||||||
M. Jones, D. Hardt, "The OAuth 2.0 Authorization Framework:
|
M. Jones, D. Hardt, "The OAuth 2.0 Authorization Framework:
|
||||||
Bearer Token Usage", <a href="http://fakehost/test/base/rfc6750" target="_blank">RFC6750</a>, October 2012.
|
Bearer Token Usage", <a href="http://fakehost/test/base/rfc6750" target="_blank">RFC6750</a>, October 2012.
|
||||||
|
|
||||||
|
@ -1106,7 +1106,7 @@ charset=UTF-8","Content-Length":106}}}
|
||||||
September 2014. <a href="https://github.com/michielbdejong/resite/wiki" target="_blank">https://github.com/michielbdejong/resite/wiki</a>
|
September 2014. <a href="https://github.com/michielbdejong/resite/wiki" target="_blank">https://github.com/michielbdejong/resite/wiki</a>
|
||||||
/Using-remoteStorage-for-web-authoring
|
/Using-remoteStorage-for-web-authoring
|
||||||
|
|
||||||
<span><a name="section-18" href="http://fakehost/test/base/#section-18" target="_blank">18</a>. Authors' addresses</span>
|
<span><a name="section-18" href="#section-18">18</a>. Authors' addresses</span>
|
||||||
|
|
||||||
Michiel B. de Jong
|
Michiel B. de Jong
|
||||||
IndieHosters
|
IndieHosters
|
||||||
|
|
738
resources/tests/readability/mercurial/expected.html
Normal file
738
resources/tests/readability/mercurial/expected.html
Normal file
|
@ -0,0 +1,738 @@
|
||||||
|
<article><div id="readability-page-1">
|
||||||
|
|
||||||
|
<div id="contents">
|
||||||
|
<p>
|
||||||
|
Contents
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="#evolve-shared-mutable-history" id="id4">Evolve: Shared Mutable History</a>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="#sharing-with-a-single-developer" id="id5">Sharing with a single developer</a>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="#publishing-and-non-publishing-repositories" id="id6">Publishing and non-publishing repositories</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#setting-up" id="id7">Setting up</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#example-1-amend-a-shared-changeset" id="id8">Example 1: Amend a shared changeset</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#example-2-amend-again-locally" id="id9">Example 2: Amend again, locally</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#sharing-with-multiple-developers-code-review" id="id10">Sharing with multiple developers: code review</a>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="#id2" id="id11">Setting up</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#example-3-alice-commits-and-amends-a-draft-fix" id="id12">Example 3: Alice commits and amends a draft fix</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#example-4-bob-implements-and-publishes-a-new-feature" id="id13">Example 4: Bob implements and publishes a new feature</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#example-5-alice-integrates-and-publishes" id="id14">Example 5: Alice integrates and publishes</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#getting-into-trouble-with-shared-mutable-history" id="id15">Getting into trouble with shared mutable history</a>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="#id3" id="id16">Setting up</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#example-6-divergent-changesets" id="id17">Example 6: Divergent changesets</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#phase-divergence-when-a-rewritten-changeset-is-made-public" id="id18">Phase-divergence: when a rewritten changeset is made public</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#conclusion" id="id19">Conclusion</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Once you have mastered the art of mutable history in a single repository (see the <a href="http://fakehost/test/base/user-guide.html" target="_blank">user guide</a>), you can move up to the next level: <em>shared</em> mutable history. <tt><span>evolve</span></tt> lets you push and pull draft changesets between repositories along with their obsolescence markers. This opens up a number of interesting possibilities.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The simplest scenario is a single developer working across two computers. Say you’re working on code that must be tested on a remote test server, probably in a rack somewhere, only accessible by SSH, and running an “enterprise-grade” (out-of-date) OS. But you probably prefer to write code locally: everything is setup the way you like it, and you can use your preferred editor, IDE, merge/diff tools, etc.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Traditionally, your options are limited: either
|
||||||
|
</p>
|
||||||
|
<blockquote>
|
||||||
|
<div>
|
||||||
|
<ul>
|
||||||
|
<li>(ab)use your source control system by committing half-working code in order to get it onto the remote test server, or
|
||||||
|
</li>
|
||||||
|
<li>go behind source control’s back by using <tt><span>rsync</span></tt> (or similar) to transfer your code back-and-forth until it is ready to commit
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</blockquote>
|
||||||
|
<p>
|
||||||
|
The former is less bad with distributed version control systems like Mercurial, but it’s still far from ideal. (One important version control “best practice” is that every commit should make things just a little bit better, i.e. you should never commit code that is worse than what came before.) The latter, avoiding version control entirely, means that you’re walking a tightrope without a safety net. One accidental <tt><span>rsync</span></tt> in the wrong direction could destroy hours of work.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Using Mercurial with <tt><span>evolve</span></tt> to share mutable history solves these problems. As with single-repository <tt><span>evolve</span></tt>, you can commit whenever the code is demonstrably better, even if all the tests aren’t passing yet—just <tt><span>hg</span> <span>amend</span></tt> when they are. And you can transfer those half-baked changesets between repositories to try things out on your test server before anything is carved in stone.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
A less common scenario is multiple developers sharing mutable history, typically for code review. We’ll cover this scenario later. First, we will cover single-user sharing.
|
||||||
|
</p>
|
||||||
|
<div id="sharing-with-a-single-developer">
|
||||||
|
<h2>
|
||||||
|
<a href="#id5">Sharing with a single developer</a><a href="#sharing-with-a-single-developer" title="Permalink to this headline">¶</a>
|
||||||
|
</h2>
|
||||||
|
<div id="publishing-and-non-publishing-repositories">
|
||||||
|
<h3>
|
||||||
|
<a href="#id6">Publishing and non-publishing repositories</a><a href="#publishing-and-non-publishing-repositories" title="Permalink to this headline">¶</a>
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
The key to shared mutable history is to keep your changesets in <em>draft</em> phase as you pass them around. Recall that by default, <tt><span>hg</span> <span>push</span></tt> promotes changesets from <em>draft</em> to <em>public</em>, and public changesets are immutable. You can change this behaviour by reconfiguring the <em>remote</em> repository so that it is non-publishing. (Short version: set <tt><span>phases.publish</span></tt> to <tt><span>false</span></tt>. Long version follows.)
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div id="setting-up">
|
||||||
|
<h3>
|
||||||
|
<a href="#id7">Setting up</a><a href="#setting-up" title="Permalink to this headline">¶</a>
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
We’ll work through an example with three local repositories, although in the real world they’d most likely be on three different computers. First, the <tt><span>public</span></tt> repository is where tested, polished changesets live, and it is where you synchronize with the rest of your team.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
We’ll need two clones where work gets done, <tt><span>test-repo</span></tt> and <tt><span>dev-repo</span></tt>:
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ hg clone public test-repo
|
||||||
|
updating to branch default
|
||||||
|
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||||||
|
$ hg clone test-repo dev-repo
|
||||||
|
updating to branch default
|
||||||
|
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
<tt><span>dev-repo</span></tt> is your local machine, with GUI merge tools and IDEs and everything configured just the way you like it. <tt><span>test-repo</span></tt> is the test server in a rack somewhere behind SSH. So for the most part, we’ll develop in <tt><span>dev-repo</span></tt>, push to <tt><span>test-repo</span></tt>, test and polish there, and push to <tt><span>public</span></tt>.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The key to shared mutable history is to make the target repository, in this case <tt><span>test-repo</span></tt>, non-publishing. And, of course, we have to enable the <tt><span>evolve</span></tt> extension in both <tt><span>test-repo</span></tt> and <tt><span>dev-repo</span></tt>.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
First, edit the configuration for <tt><span>test-repo</span></tt>:
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ hg -R test-repo config --edit --local
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
and add
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>[phases]
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[extensions]
|
||||||
|
evolve =
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Then edit the configuration for <tt><span>dev-repo</span></tt>:
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ hg -R dev-repo config --edit --local
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
and add
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Keep in mind that in real life, these repositories would probably be on separate computers, so you’d have to login to each one to configure each repository.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
To start things off, let’s make one public, immutable changeset:
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ cd test-repo
|
||||||
|
$ echo 'my new project' > file1
|
||||||
|
$ hg add file1
|
||||||
|
$ hg commit -m 'create new project'
|
||||||
|
$ hg push
|
||||||
|
[...]
|
||||||
|
added 1 changesets with 1 changes to 1 files
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
and pull that into the development repository:
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ cd ../dev-repo
|
||||||
|
$ hg pull -u
|
||||||
|
[...]
|
||||||
|
added 1 changesets with 1 changes to 1 files
|
||||||
|
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="example-2-amend-again-locally">
|
||||||
|
<h3>
|
||||||
|
<a href="#id9">Example 2: Amend again, locally</a><a href="#example-2-amend-again-locally" title="Permalink to this headline">¶</a>
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
This process can repeat. Perhaps you figure out a more elegant fix to the bug, and want to mutate history so nobody ever knows you had a less-than-perfect idea. We’ll implement it locally in <tt><span>dev-repo</span></tt> and push to <tt><span>test-repo</span></tt>:
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ echo 'Fix, fix, and fix.' > file1
|
||||||
|
$ hg amend
|
||||||
|
$ hg push
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
This time around, the temporary amend commit is in <tt><span>dev-repo</span></tt>, and it is not transferred to <tt><span>test-repo</span></tt>—the same as before, just in the opposite direction. Figure 4 shows the two repositories after amending in <tt><span>dev-repo</span></tt> and pushing to <tt><span>test-repo</span></tt>.
|
||||||
|
</p>
|
||||||
|
<blockquote>
|
||||||
|
<p>
|
||||||
|
[figure SG04: each repo has one temporary amend commit, but they’re different in each one]
|
||||||
|
</p>
|
||||||
|
</blockquote>
|
||||||
|
<p>
|
||||||
|
Let’s hop over to <tt><span>test-repo</span></tt> to test the more elegant fix:
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ cd ../test-repo
|
||||||
|
$ hg update
|
||||||
|
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
This time, all the tests pass, so no further amending is required. This bug fix is finished, so we push it to the public repository:
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ hg push
|
||||||
|
[...]
|
||||||
|
added 1 changesets with 1 changes to 1 files
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Note that only one changeset—the final version, after two amendments—was actually pushed. Again, Mercurial doesn’t transfer hidden changesets on push and pull.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
So the picture in <tt><span>public</span></tt> is much simpler than in either <tt><span>dev-repo</span></tt> or <tt><span>test-repo</span></tt>. Neither of our missteps nor our amendments are publicly visible, just the final, beautifully polished changeset:
|
||||||
|
</p>
|
||||||
|
<blockquote>
|
||||||
|
<p>
|
||||||
|
[figure SG05: public repo with rev 0:0dc9, 1:de61, both public]
|
||||||
|
</p>
|
||||||
|
</blockquote>
|
||||||
|
<p>
|
||||||
|
There is one important step left to do. Because we pushed from <tt><span>test-repo</span></tt> to <tt><span>public</span></tt>, the pushed changeset is in <em>public</em> phase in those two repositories. But <tt><span>dev-repo</span></tt> has been out-of-the-loop; changeset de61 is still <em>draft</em> there. If we’re not careful, we might mutate history in <tt><span>dev-repo</span></tt>, obsoleting a changeset that is already public. Let’s avoid that situation for now by pushing up to <tt><span>dev-repo</span></tt>:
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ hg push ../dev-repo
|
||||||
|
pushing to ../dev-repo
|
||||||
|
searching for changes
|
||||||
|
no changes found
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Even though no <em>changesets</em> were pushed, Mercurial still pushed obsolescence markers and phase changes to <tt><span>dev-repo</span></tt>.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
A final note: since this fix is now <em>public</em>, it is immutable. It’s no longer possible to amend it:
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ hg amend -m 'fix bug 37'
|
||||||
|
abort: cannot amend public changesets
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
This is, after all, the whole point of Mercurial’s phases: to prevent rewriting history that has already been published.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="sharing-with-multiple-developers-code-review">
|
||||||
|
<h2>
|
||||||
|
<a href="#id10">Sharing with multiple developers: code review</a><a href="#sharing-with-multiple-developers-code-review" title="Permalink to this headline">¶</a>
|
||||||
|
</h2>
|
||||||
|
<p>
|
||||||
|
Now that you know how to share your own mutable history across multiple computers, you might be wondering if it makes sense to share mutable history with others. It does, but you have to be careful, stay alert, and <em>communicate</em> with your peers.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Code review is a good use case for sharing mutable history across multiple developers: Alice commits a draft changeset, submits it for review, and amends her changeset until her reviewer is satisfied. Meanwhile, Bob is also committing draft changesets for review, amending until his reviewer is satisfied. Once a particular changeset passes review, the respective author (Alice or Bob) pushes it to the public (publishing) repository.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Incidentally, the reviewers here can be anyone: maybe Bob and Alice review each other’s work; maybe the same third party reviews both; or maybe they pick different experts to review their work on different parts of a large codebase. Similarly, it doesn’t matter if reviews are conducted in person, by email, or by carrier pigeon. Code review is outside of the scope of Mercurial, so all we’re looking at here is the mechanics of committing, amending, pushing, and pulling.
|
||||||
|
</p>
|
||||||
|
<div id="id2">
|
||||||
|
<h3>
|
||||||
|
<a href="#id11">Setting up</a><a href="#id2" title="Permalink to this headline">¶</a>
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
To demonstrate, let’s start with the <tt><span>public</span></tt> repository as we left it in the last example, with two immutable changesets (figure 5 above). We’ll clone a <tt><span>review</span></tt> repository from it, and then Alice and Bob will both clone from <tt><span>review</span></tt>.
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ hg clone public review
|
||||||
|
updating to branch default
|
||||||
|
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||||||
|
$ hg clone review alice
|
||||||
|
updating to branch default
|
||||||
|
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||||||
|
$ hg clone review bob
|
||||||
|
updating to branch default
|
||||||
|
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
We need to configure Alice’s and Bob’s working repositories to enable <tt><span>evolve</span></tt>. First, edit Alice’s configuration with
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ hg -R alice config --edit --local
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
and add
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Then edit Bob’s repository configuration:
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ hg -R bob config --edit --local
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
and add the same text.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div id="example-3-alice-commits-and-amends-a-draft-fix">
|
||||||
|
<h3>
|
||||||
|
<a href="#id12">Example 3: Alice commits and amends a draft fix</a><a href="#example-3-alice-commits-and-amends-a-draft-fix" title="Permalink to this headline">¶</a>
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
We’ll follow Alice working on a bug fix. We’re going to use bookmarks to make it easier to understand multiple branch heads in the <tt><span>review</span></tt> repository, so Alice starts off by creating a bookmark and committing her first attempt at a fix:
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ hg bookmark bug15
|
||||||
|
$ echo 'fix' > file2
|
||||||
|
$ hg commit -A -u alice -m 'fix bug 15 (v1)'
|
||||||
|
adding file2
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Note the unorthodox “(v1)” in the commit message. We’re just using that to make this tutorial easier to follow; it’s not something we’d recommend in real life.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Of course Alice wouldn’t commit unless her fix worked to her satisfaction, so it must be time to solicit a code review. She does this by pushing to the <tt><span>review</span></tt> repository:
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ hg push -B bug15
|
||||||
|
[...]
|
||||||
|
added 1 changesets with 1 changes to 1 files
|
||||||
|
exporting bookmark bug15
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
(The use of <tt><span>-B</span></tt> is important to ensure that we only push the bookmarked head, and that the bookmark itself is pushed. See this <a href="http://mercurial.aragost.com/kick-start/en/bookmarks/" target="_blank">guide to bookmarks</a>, especially the <a href="http://mercurial.aragost.com/kick-start/en/bookmarks/#sharing-bookmarks" target="_blank">Sharing Bookmarks</a> section, if you’re not familiar with bookmarks.)
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Some time passes, and Alice receives her code review. As a result, Alice revises her fix and submits it for a second review:
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ echo 'Fix.' > file2
|
||||||
|
$ hg amend -m 'fix bug 15 (v2)'
|
||||||
|
$ hg push
|
||||||
|
[...]
|
||||||
|
added 1 changesets with 1 changes to 1 files (+1 heads)
|
||||||
|
updating bookmark bug15
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Figure 6 shows the state of the <tt><span>review</span></tt> repository at this point.
|
||||||
|
</p>
|
||||||
|
<blockquote>
|
||||||
|
<p>
|
||||||
|
[figure SG06: rev 2:fn1e is Alice’s obsolete v1, rev 3:cbdf is her v2; both children of rev 1:de61]
|
||||||
|
</p>
|
||||||
|
</blockquote>
|
||||||
|
<p>
|
||||||
|
After a busy morning of bug fixing, Alice stops for lunch. Let’s see what Bob has been up to.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div id="example-4-bob-implements-and-publishes-a-new-feature">
|
||||||
|
<h3>
|
||||||
|
<a href="#id13">Example 4: Bob implements and publishes a new feature</a><a href="#example-4-bob-implements-and-publishes-a-new-feature" title="Permalink to this headline">¶</a>
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
Meanwhile, Bob has been working on a new feature. Like Alice, he’ll use a bookmark to track his work, and he’ll push that bookmark to the <tt><span>review</span></tt> repository, so that reviewers know which changesets to review.
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ cd ../bob
|
||||||
|
$ echo 'stuff' > file1
|
||||||
|
$ hg bookmark featureX
|
||||||
|
$ hg commit -u bob -m 'implement feature X (v1)' # rev 4:1636
|
||||||
|
$ hg push -B featureX
|
||||||
|
[...]
|
||||||
|
added 1 changesets with 1 changes to 1 files (+1 heads)
|
||||||
|
exporting bookmark featureX
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
When Bob receives his code review, he improves his implementation a bit, amends, and submits the resulting changeset for review:
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ echo 'do stuff' > file1
|
||||||
|
$ hg amend -m 'implement feature X (v2)' # rev 5:0eb7
|
||||||
|
$ hg push
|
||||||
|
[...]
|
||||||
|
added 1 changesets with 1 changes to 1 files (+1 heads)
|
||||||
|
updating bookmark featureX
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Unfortunately, that still doesn’t pass muster. Bob’s reviewer insists on proper capitalization and punctuation.
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ echo 'Do stuff.' > file1
|
||||||
|
$ hg amend -m 'implement feature X (v3)' # rev 6:540b
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
On the bright side, the second review said, “Go ahead and publish once you fix that.” So Bob immediately publishes his third attempt:
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ hg push ../public
|
||||||
|
[...]
|
||||||
|
added 1 changesets with 1 changes to 1 files
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
It’s not enough just to update <tt><span>public</span></tt>, though! Other people also use the <tt><span>review</span></tt> repository, and right now it doesn’t have Bob’s latest amendment (“v3”, revision 6:540b), nor does it know that the precursor of that changeset (“v2”, revision 5:0eb7) is obsolete. Thus, Bob pushes to <tt><span>review</span></tt> as well:
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ hg push ../review
|
||||||
|
[...]
|
||||||
|
added 1 changesets with 1 changes to 1 files (+1 heads)
|
||||||
|
updating bookmark featureX
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Figure 7 shows the result of Bob’s work in both <tt><span>review</span></tt> and <tt><span>public</span></tt>.
|
||||||
|
</p>
|
||||||
|
<blockquote>
|
||||||
|
<p>
|
||||||
|
[figure SG07: review includes Alice’s draft work on bug 15, as well as Bob’s v1, v2, and v3 changes for feature X: v1 and v2 obsolete, v3 public. public contains only the final, public implementation of feature X]
|
||||||
|
</p>
|
||||||
|
</blockquote>
|
||||||
|
<p>
|
||||||
|
Incidentally, it’s important that Bob push to <tt><span>public</span></tt> <em>before</em> <tt><span>review</span></tt>. If he pushed to <tt><span>review</span></tt> first, then revision 6:540b would still be in <em>draft</em> phase in <tt><span>review</span></tt>, but it would be <em>public</em> in both Bob’s local repository and the <tt><span>public</span></tt> repository. That could lead to confusion at some point, which is easily avoided by pushing first to <tt><span>public</span></tt>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div id="example-5-alice-integrates-and-publishes">
|
||||||
|
<h3>
|
||||||
|
<a href="#id14">Example 5: Alice integrates and publishes</a><a href="#example-5-alice-integrates-and-publishes" title="Permalink to this headline">¶</a>
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
Finally, Alice gets back from lunch and sees that the carrier pigeon with her second review has arrived (or maybe it’s in her email inbox). Alice’s reviewer approved her amended changeset, so she pushes it to <tt><span>public</span></tt>:
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ hg push ../public
|
||||||
|
[...]
|
||||||
|
remote has heads on branch 'default' that are not known locally: 540ba8f317e6
|
||||||
|
abort: push creates new remote head cbdfbd5a5db2!
|
||||||
|
(pull and merge or see "hg help push" for details about pushing new heads)
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Oops! Bob has won the race to push first to <tt><span>public</span></tt>. So Alice needs to integrate with Bob: let’s pull his changeset(s) and see what the branch heads are.
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ hg pull ../public
|
||||||
|
[...]
|
||||||
|
added 1 changesets with 1 changes to 1 files (+1 heads)
|
||||||
|
(run 'hg heads' to see heads, 'hg merge' to merge)
|
||||||
|
$ hg log -G -q -r 'head()' --template '{rev}:{node|short} ({author})\n'
|
||||||
|
o 5:540ba8f317e6 (bob)
|
||||||
|
|
|
||||||
|
| @ 4:cbdfbd5a5db2 (alice)
|
||||||
|
|/
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
We’ll assume Alice and Bob are perfectly comfortable with rebasing changesets. (After all, they’re already using mutable history in the form of <tt><span>amend</span></tt>.) So Alice rebases her changeset on top of Bob’s and publishes the result:
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ hg rebase -d 5
|
||||||
|
$ hg push ../public
|
||||||
|
[...]
|
||||||
|
added 1 changesets with 1 changes to 1 files
|
||||||
|
$ hg push ../review
|
||||||
|
[...]
|
||||||
|
added 1 changesets with 0 changes to 0 files
|
||||||
|
updating bookmark bug15
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
The result, in both <tt><span>review</span></tt> and <tt><span>public</span></tt> repositories, is shown in figure 8.
|
||||||
|
</p>
|
||||||
|
<blockquote>
|
||||||
|
<p>
|
||||||
|
[figure SG08: review shows v1 and v2 of Alice’s fix, then v1, v2, v3 of Bob’s feature, finally Alice’s fix rebased onto Bob’s. public just shows the final public version of each changeset]
|
||||||
|
</p>
|
||||||
|
</blockquote>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="getting-into-trouble-with-shared-mutable-history">
|
||||||
|
<h2>
|
||||||
|
<a href="#id15">Getting into trouble with shared mutable history</a><a href="#getting-into-trouble-with-shared-mutable-history" title="Permalink to this headline">¶</a>
|
||||||
|
</h2>
|
||||||
|
<p>
|
||||||
|
Mercurial with <tt><span>evolve</span></tt> is a powerful tool, and using powerful tools can have consequences. (You can cut yourself badly with a sharp knife, but every competent chef keeps several around. Ever try to chop onions with a spoon?)
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
In the user guide, we saw examples of <em>unstbale</em> changesets, which are the most common type of troubled changeset. (Recall that a non-obsolete changeset with obsolete ancestors is an orphan.)
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Two other types of troubles can happen: <em>divergent</em> and <em>bumped</em> changesets. Both are more likely with shared mutable history, especially mutable history shared by multiple developers.
|
||||||
|
</p>
|
||||||
|
<div id="id3">
|
||||||
|
<h3>
|
||||||
|
<a href="#id16">Setting up</a><a href="#id3" title="Permalink to this headline">¶</a>
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
For these examples, we’re going to use a slightly different workflow: as before, Alice and Bob share a <tt><span>public</span></tt> repository. But this time there is no <tt><span>review</span></tt> repository. Instead, Alice and Bob put on their cowboy hats, throw good practice to the wind, and pull directly from each other’s working repositories.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
So we throw away everything except <tt><span>public</span></tt> and reclone:
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ rm -rf review alice bob
|
||||||
|
$ hg clone public alice
|
||||||
|
updating to branch default
|
||||||
|
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||||||
|
$ hg clone public bob
|
||||||
|
updating to branch default
|
||||||
|
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Once again we have to configure their repositories: enable <tt><span>evolve</span></tt> and (since Alice and Bob will be pulling directly from each other) make their repositories non-publishing. Edit Alice’s configuration:
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ hg -R alice config --edit --local
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
and add
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>[extensions]
|
||||||
|
rebase =
|
||||||
|
evolve =
|
||||||
|
|
||||||
|
[phases]
|
||||||
|
publish = false
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Then edit Bob’s repository configuration:
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ hg -R bob config --edit --local
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
and add the same text.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div id="example-6-divergent-changesets">
|
||||||
|
<h3>
|
||||||
|
<a href="#id17">Example 6: Divergent changesets</a><a href="#example-6-divergent-changesets" title="Permalink to this headline">¶</a>
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
When an obsolete changeset has two successors, those successors are <em>divergent</em>. One way to get into such a situation is by failing to communicate with your teammates. Let’s see how that might happen.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
First, we’ll have Bob commit a bug fix that could still be improved:
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ cd bob
|
||||||
|
$ echo 'pretty good fix' >> file1
|
||||||
|
$ hg commit -u bob -m 'fix bug 24 (v1)' # rev 4:2fe6
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Since Alice and Bob are now in cowboy mode, Alice pulls Bob’s draft changeset and amends it herself.
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ cd ../alice
|
||||||
|
$ hg pull -u ../bob
|
||||||
|
[...]
|
||||||
|
added 1 changesets with 1 changes to 1 files
|
||||||
|
$ echo 'better fix (alice)' >> file1
|
||||||
|
$ hg amend -u alice -m 'fix bug 24 (v2 by alice)'
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
But Bob has no idea that Alice just did this. (See how important good communication is?) So he implements a better fix of his own:
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ cd ../bob
|
||||||
|
$ echo 'better fix (bob)' >> file1
|
||||||
|
$ hg amend -u bob -m 'fix bug 24 (v2 by bob)' # rev 6:a360
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
At this point, the divergence exists, but only in theory: Bob’s original changeset, 4:2fe6, is obsolete and has two successors. But those successors are in different repositories, so the trouble is not visible to anyone yet. It will be as soon as Bob pulls from Alice’s repository (or vice-versa).
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ hg pull ../alice
|
||||||
|
[...]
|
||||||
|
added 1 changesets with 1 changes to 2 files (+1 heads)
|
||||||
|
(run 'hg heads' to see heads, 'hg merge' to merge)
|
||||||
|
2 new divergent changesets
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Figure 9 shows the situation in Bob’s repository.
|
||||||
|
</p>
|
||||||
|
<blockquote>
|
||||||
|
<p>
|
||||||
|
[figure SG09: Bob’s repo with 2 heads for the 2 divergent changesets, 6:a360 and 7:e3f9; wc is at 6:a360; both are successors of obsolete 4:2fe6, hence divergence]
|
||||||
|
</p>
|
||||||
|
</blockquote>
|
||||||
|
<p>
|
||||||
|
Now we need to get out of trouble. As usual, the answer is to evolve history.
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ HGMERGE=internal:other hg evolve
|
||||||
|
merge:[6] fix bug 24 (v2 by bob)
|
||||||
|
with: [7] fix bug 24 (v2 by alice)
|
||||||
|
base: [4] fix bug 24 (v1)
|
||||||
|
0 files updated, 1 files merged, 0 files removed, 0 files unresolved
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Figure 10 shows how Bob’s repository looks now.
|
||||||
|
</p>
|
||||||
|
<blockquote>
|
||||||
|
<p>
|
||||||
|
[figure SG10: only one visible head, 9:5ad6, successor to hidden 6:a360 and 7:e3f9]
|
||||||
|
</p>
|
||||||
|
</blockquote>
|
||||||
|
<p>
|
||||||
|
We carefully dodged a merge conflict by specifying a merge tool (<tt><span>internal:other</span></tt>) that will take Alice’s changes over Bob’s. (You might wonder why Bob wouldn’t prefer his own changes by using <tt><span>internal:local</span></tt>. He’s avoiding a <a href="#bug">bug</a> in <tt><span>evolve</span></tt> that occurs when evolving divergent changesets using <tt><span>internal:local</span></tt>.)
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
# XXX this link does not work .. <span id="bug">bug</span>: <a href="https://bitbucket.org/marmoute/mutable-history/issue/48/" target="_blank">https://bitbucket.org/marmoute/mutable-history/issue/48/</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
** STOP HERE: WORK IN PROGRESS **
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div id="phase-divergence-when-a-rewritten-changeset-is-made-public">
|
||||||
|
<h3>
|
||||||
|
<a href="#id18">Phase-divergence: when a rewritten changeset is made public</a><a href="#phase-divergence-when-a-rewritten-changeset-is-made-public" title="Permalink to this headline">¶</a>
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
If Alice and Bob are collaborating on some mutable changesets, it’s possible to get into a situation where an otherwise worthwhile changeset cannot be pushed to the public repository; it is <em>phase-divergent</em> with another changeset that was made public first. Let’s demonstrate one way this could happen.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
It starts with Alice committing a bug fix. Right now, we don’t yet know if this bug fix is good enough to push to the public repository, but it’s good enough for Alice to commit.
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ cd alice
|
||||||
|
$ echo 'fix' > file2
|
||||||
|
$ hg commit -A -m 'fix bug 15'
|
||||||
|
adding file2
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Now Bob has a bad idea: he decides to pull whatever Alice is working on and tweak her bug fix to his taste:
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ cd ../bob
|
||||||
|
$ hg pull -u ../alice
|
||||||
|
[...]
|
||||||
|
added 1 changesets with 1 changes to 1 files
|
||||||
|
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||||||
|
$ echo 'Fix.' > file2
|
||||||
|
$ hg amend -A -m 'fix bug 15 (amended)'
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
(Note the lack of communication between Alice and Bob. Failing to communicate with your colleagues is a good way to get into trouble. Nevertheless, <tt><span>evolve</span></tt> can usually sort things out, as we will see.)
|
||||||
|
</p>
|
||||||
|
<blockquote>
|
||||||
|
<p>
|
||||||
|
[figure SG06: Bob’s repo with one amendment]
|
||||||
|
</p>
|
||||||
|
</blockquote>
|
||||||
|
<p>
|
||||||
|
After some testing, Alice realizes her bug fix is just fine as it is: no need for further polishing and amending, this changeset is ready to publish.
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ cd ../alice
|
||||||
|
$ hg push
|
||||||
|
[...]
|
||||||
|
added 1 changesets with 1 changes to 1 files
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
This introduces a contradiction: in Bob’s repository, changeset 2:e011 (his copy of Alice’s fix) is obsolete, since Bob amended it. But in Alice’s repository (and the <tt><span>public</span></tt> repository), that changeset is public: it is immutable, carved in stone for all eternity. No changeset can be both obsolete and public, so Bob is in for a surprise the next time he pulls from <tt><span>public</span></tt>:
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<pre>$ cd ../bob
|
||||||
|
$ hg pull -q -u
|
||||||
|
1 new phase-divergent changesets
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Figure 7 shows what just happened to Bob’s repository: changeset 2:e011 is now public, so it can’t be obsolete. When that changeset was obsolete, it made perfect sense for it to have a successor, namely Bob’s amendment of Alice’s fix (changeset 4:fe88). But it’s illogical for a public changeset to have a successor, so 4:fe88 is troubled: it has become <em>bumped</em>.
|
||||||
|
</p>
|
||||||
|
<blockquote>
|
||||||
|
<p>
|
||||||
|
[figure SG07: 2:e011 now public not obsolete, 4:fe88 now bumped]
|
||||||
|
</p>
|
||||||
|
</blockquote>
|
||||||
|
<p>
|
||||||
|
As usual when there’s trouble in your repository, the solution is to evolve it:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Figure 8 illustrates Bob’s repository after evolving away the bumped changeset. Ignoring the obsolete changesets, Bob now has a nice, clean, simple history. His amendment of Alice’s bug fix lives on, as changeset 5:227d—albeit with a software-generated commit message. (Bob should probably amend that changeset to improve the commit message.) But the important thing is that his repository no longer has any troubled changesets, thanks to <tt><span>evolve</span></tt>.
|
||||||
|
</p>
|
||||||
|
<blockquote>
|
||||||
|
<p>
|
||||||
|
[figure SG08: 5:227d is new, formerly bumped changeset 4:fe88 now hidden]
|
||||||
|
</p>
|
||||||
|
</blockquote>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="conclusion">
|
||||||
|
<h2>
|
||||||
|
<a href="#id19">Conclusion</a><a href="#conclusion" title="Permalink to this headline">¶</a>
|
||||||
|
</h2>
|
||||||
|
<p>
|
||||||
|
Mutable history is a powerful tool. Like a sharp knife, an experienced user can do wonderful things with it, much more wonderful than with a dull knife (never mind a rusty spoon). At the same time, an inattentive or careless user can do harm to himself or others. Mercurial with <tt><span>evolve</span></tt> goes to great lengths to limit the harm you can do by trying to handle all possible types of “troubled” changesets. Nevertheless, having a first-aid kit nearby does not mean you should stop being careful with sharp knives.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Mutable history shared across multiple repositories by a single developer is a natural extension of this model. Once you are used to using a single sharp knife on its own, it’s pretty straightforward to chop onions and mushrooms using the same knife, or to alternate between two chopping boards with different knives.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Mutable history shared by multiple developers is a scary place to go. Imagine a professional kitchen full of expert chefs tossing their favourite knives back and forth, with the occasional axe or chainsaw thrown in to spice things up. If you’re confident that you <em>and your colleagues</em> can do it without losing a limb, go for it. But be sure to practice a lot first before you rely on it!
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div></article>
|
|
@ -49,7 +49,7 @@ pub static OKAY_MAYBE_ITS_A_CANDIDATE: Lazy<Regex> = Lazy::new(|| {
|
||||||
});
|
});
|
||||||
pub static HAS_CONTENT: Lazy<Regex> =
|
pub static HAS_CONTENT: Lazy<Regex> =
|
||||||
Lazy::new(|| Regex::new(r#"/\S$/"#).expect("HAS_CONTENT regex"));
|
Lazy::new(|| Regex::new(r#"/\S$/"#).expect("HAS_CONTENT regex"));
|
||||||
pub static HASH_URL: Lazy<Regex> = Lazy::new(|| Regex::new(r#"/^#.+/"#).expect("HASH_URL regex"));
|
pub static HASH_URL: Lazy<Regex> = Lazy::new(|| Regex::new(r#"^#.+"#).expect("HASH_URL regex"));
|
||||||
pub static POSITIVE: Lazy<Regex> =
|
pub static POSITIVE: Lazy<Regex> =
|
||||||
Lazy::new(|| {
|
Lazy::new(|| {
|
||||||
RegexBuilder::new(
|
RegexBuilder::new(
|
||||||
|
|
|
@ -551,24 +551,6 @@ impl FullTextParser {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_attribute(
|
|
||||||
context: &Context,
|
|
||||||
tag: Option<&str>,
|
|
||||||
attribute: &str,
|
|
||||||
value: &str,
|
|
||||||
) -> Result<(), FullTextParserError> {
|
|
||||||
let xpath_tag = tag.unwrap_or("*");
|
|
||||||
|
|
||||||
let xpath = &format!("//{}", xpath_tag);
|
|
||||||
let node_vec = Util::evaluate_xpath(context, xpath, false)?;
|
|
||||||
for mut node in node_vec {
|
|
||||||
if let Err(err) = node.set_attribute(attribute, value) {
|
|
||||||
log::warn!("Failed to set attribute '{}' on node: {}", attribute, err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn repair_urls(
|
fn repair_urls(
|
||||||
context: &Context,
|
context: &Context,
|
||||||
xpath: &str,
|
xpath: &str,
|
||||||
|
@ -580,13 +562,21 @@ impl FullTextParser {
|
||||||
for mut node in node_vec {
|
for mut node in node_vec {
|
||||||
if let Some(url) = node.get_attribute(attribute) {
|
if let Some(url) = node.get_attribute(attribute) {
|
||||||
let trimmed_url = url.trim();
|
let trimmed_url = url.trim();
|
||||||
|
|
||||||
|
let is_hash_url = url.starts_with('#');
|
||||||
let is_relative_url = url::Url::parse(&url)
|
let is_relative_url = url::Url::parse(&url)
|
||||||
.err()
|
.err()
|
||||||
.map(|err| err == url::ParseError::RelativeUrlWithoutBase)
|
.map(|err| err == url::ParseError::RelativeUrlWithoutBase)
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
let is_javascript = trimmed_url.contains("javascript:");
|
let is_javascript = trimmed_url.contains("javascript:");
|
||||||
|
|
||||||
if is_relative_url {
|
if !is_hash_url && node.get_name().to_uppercase() == "A" {
|
||||||
|
_ = node.set_attribute("target", "_blank");
|
||||||
|
}
|
||||||
|
|
||||||
|
if is_hash_url {
|
||||||
|
_ = node.set_attribute(attribute, trimmed_url);
|
||||||
|
} else if is_relative_url {
|
||||||
let completed_url = match article_url.join(trimmed_url) {
|
let completed_url = match article_url.join(trimmed_url) {
|
||||||
Ok(joined_url) => joined_url,
|
Ok(joined_url) => joined_url,
|
||||||
Err(_) => continue,
|
Err(_) => continue,
|
||||||
|
@ -697,7 +687,6 @@ impl FullTextParser {
|
||||||
_ = Self::fix_lazy_images(context, document);
|
_ = Self::fix_lazy_images(context, document);
|
||||||
_ = Self::fix_iframe_size(context, "youtube.com");
|
_ = Self::fix_iframe_size(context, "youtube.com");
|
||||||
_ = Self::remove_attribute(context, Some("a"), "onclick");
|
_ = Self::remove_attribute(context, Some("a"), "onclick");
|
||||||
_ = Self::add_attribute(context, Some("a"), "target", "_blank");
|
|
||||||
|
|
||||||
// strip elements using Readability.com and Instapaper.com ignore class names
|
// strip elements using Readability.com and Instapaper.com ignore class names
|
||||||
// .entry-unrelated and .instapaper_ignore
|
// .entry-unrelated and .instapaper_ignore
|
||||||
|
|
|
@ -578,8 +578,6 @@ impl Readability {
|
||||||
let text = Util::get_inner_text(&article_content, true);
|
let text = Util::get_inner_text(&article_content, true);
|
||||||
let text_length = text.len();
|
let text_length = text.len();
|
||||||
|
|
||||||
//Util::serialize_node(&article_content, "dbg.html");
|
|
||||||
|
|
||||||
if text_length < constants::DEFAULT_CHAR_THRESHOLD {
|
if text_length < constants::DEFAULT_CHAR_THRESHOLD {
|
||||||
parse_successful = false;
|
parse_successful = false;
|
||||||
|
|
||||||
|
|
|
@ -337,10 +337,10 @@ async fn medium_3() {
|
||||||
run_test("medium-3").await
|
run_test("medium-3").await
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[tokio::test]
|
#[tokio::test]
|
||||||
// async fn mercurial() {
|
async fn mercurial() {
|
||||||
// run_test("mercurial").await
|
run_test("mercurial").await
|
||||||
// }
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn metadata_content_missing() {
|
async fn metadata_content_missing() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue