doc.go 4.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /*
  2. Package amp provides functions for working with the AMP (Accelerated Mobile
  3. Pages) subset of HTML, and conveying binary data through an AMP cache.
  4. # AMP cache
  5. The CacheURL function takes a plain URL and converts it to be accessed through a
  6. given AMP cache.
  7. The EncodePath and DecodePath functions provide a way to encode data into the
  8. suffix of a URL path. AMP caches do not support HTTP POST, but encoding data
  9. into a URL path with GET is an alternative means of sending data to the server.
  10. The format of an encoded path is:
  11. 0<0 or more bytes, including slash>/<base64 of data>
  12. That is:
  13. * "0", a format version number, which controls the interpretation of the rest of
  14. the path. Only the first byte matters as a version indicator (not the whole
  15. first path component).
  16. * Any number of slash or non-slash bytes. These may be used as padding or to
  17. prevent cache collisions in the AMP cache.
  18. * A final slash.
  19. * base64 encoding of the data, using the URL-safe alphabet (which does not
  20. include slash).
  21. For example, an encoding of the string "This is path-encoded data." is the
  22. following. The "lgWHcwhXFjUm" following the format version number is random
  23. padding that will be ignored on decoding.
  24. 0lgWHcwhXFjUm/VGhpcyBpcyBwYXRoLWVuY29kZWQgZGF0YS4
  25. It is the caller's responsibility to add or remove any directory path prefix
  26. before calling EncodePath or DecodePath.
  27. # AMP armor
  28. AMP armor is a data encoding scheme that that satisfies the requirements of the
  29. AMP (Accelerated Mobile Pages) subset of HTML, and survives modification by an
  30. AMP cache. For the requirements of AMP HTML, see
  31. https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/.
  32. For modifications that may be made by an AMP cache, see
  33. https://github.com/ampproject/amphtml/blob/main/docs/spec/amp-cache-modifications.md.
  34. The encoding is based on ones created by Ivan Markin. See codec/amp/ in
  35. https://github.com/nogoegst/amper and discussion at
  36. https://bugs.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/25985.
  37. The encoding algorithm works as follows. Base64-encode the input. Prepend the
  38. input with the byte '0'; this is a protocol version indicator that the decoder
  39. can use to determine how to interpret the bytes that follow. Split the base64
  40. into fixed-size chunks separated by whitespace. Take up to 1024 chunks at a
  41. time, and wrap them in a pre element. Then, situate the markup so far within the
  42. body of the AMP HTML boilerplate. The decoding algorithm is to scan the HTML for
  43. pre elements, split their text contents on whitespace and concatenate, then
  44. base64 decode. The base64 encoding uses the standard alphabet, with normal "="
  45. padding (https://tools.ietf.org/html/rfc4648#section-4).
  46. The reason for splitting the base64 into chunks is that AMP caches reportedly
  47. truncate long strings that are not broken by whitespace:
  48. https://bugs.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/25985#note_2592348.
  49. The characters that may separate the chunks are the ASCII whitespace characters
  50. (https://infra.spec.whatwg.org/#ascii-whitespace) "\x09", "\x0a", "\x0c",
  51. "\x0d", and "\x20". The reason for separating the chunks into pre elements is to
  52. limit the amount of text a decoder may have to buffer while parsing the HTML.
  53. Each pre element may contain at most 64 KB of text. pre elements may not be
  54. nested.
  55. # Example
  56. The following is the result of encoding the string
  57. "This was encoded with AMP armor.":
  58. <!doctype html>
  59. <html amp>
  60. <head>
  61. <meta charset="utf-8">
  62. <script async src="https://cdn.ampproject.org/v0.js"></script>
  63. <link rel="canonical" href="#">
  64. <meta name="viewport" content="width=device-width">
  65. <style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
  66. </head>
  67. <body>
  68. <pre>
  69. 0VGhpcyB3YXMgZW5jb2RlZCB3aXRoIEF
  70. NUCBhcm1vci4=
  71. </pre>
  72. </body>
  73. </html>
  74. */
  75. package amp