@helia/verified-fetch 4.1.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. package/README.md +6 -40
  2. package/dist/index.min.js +73 -534
  3. package/dist/index.min.js.map +4 -4
  4. package/dist/src/constants.d.ts +2 -0
  5. package/dist/src/constants.d.ts.map +1 -1
  6. package/dist/src/constants.js +2 -0
  7. package/dist/src/constants.js.map +1 -1
  8. package/dist/src/index.d.ts +162 -68
  9. package/dist/src/index.d.ts.map +1 -1
  10. package/dist/src/index.js +11 -43
  11. package/dist/src/index.js.map +1 -1
  12. package/dist/src/plugins/index.d.ts +0 -5
  13. package/dist/src/plugins/index.d.ts.map +1 -1
  14. package/dist/src/plugins/index.js +0 -4
  15. package/dist/src/plugins/index.js.map +1 -1
  16. package/dist/src/plugins/plugin-base.d.ts +8 -9
  17. package/dist/src/plugins/plugin-base.d.ts.map +1 -1
  18. package/dist/src/plugins/plugin-base.js +5 -6
  19. package/dist/src/plugins/plugin-base.js.map +1 -1
  20. package/dist/src/plugins/plugin-handle-car.d.ts +3 -3
  21. package/dist/src/plugins/plugin-handle-car.d.ts.map +1 -1
  22. package/dist/src/plugins/plugin-handle-car.js +38 -39
  23. package/dist/src/plugins/plugin-handle-car.js.map +1 -1
  24. package/dist/src/plugins/plugin-handle-ipld.d.ts +12 -0
  25. package/dist/src/plugins/plugin-handle-ipld.d.ts.map +1 -0
  26. package/dist/src/plugins/plugin-handle-ipld.js +83 -0
  27. package/dist/src/plugins/plugin-handle-ipld.js.map +1 -0
  28. package/dist/src/plugins/plugin-handle-ipns-record.d.ts +3 -3
  29. package/dist/src/plugins/plugin-handle-ipns-record.d.ts.map +1 -1
  30. package/dist/src/plugins/plugin-handle-ipns-record.js +25 -34
  31. package/dist/src/plugins/plugin-handle-ipns-record.js.map +1 -1
  32. package/dist/src/plugins/plugin-handle-tar.d.ts +3 -3
  33. package/dist/src/plugins/plugin-handle-tar.d.ts.map +1 -1
  34. package/dist/src/plugins/plugin-handle-tar.js +20 -22
  35. package/dist/src/plugins/plugin-handle-tar.js.map +1 -1
  36. package/dist/src/plugins/plugin-handle-unixfs.d.ts +14 -0
  37. package/dist/src/plugins/plugin-handle-unixfs.d.ts.map +1 -0
  38. package/dist/src/plugins/plugin-handle-unixfs.js +180 -0
  39. package/dist/src/plugins/plugin-handle-unixfs.js.map +1 -0
  40. package/dist/src/plugins/types.d.ts +1 -77
  41. package/dist/src/plugins/types.d.ts.map +1 -1
  42. package/dist/src/url-resolver.d.ts +29 -11
  43. package/dist/src/url-resolver.d.ts.map +1 -1
  44. package/dist/src/url-resolver.js +152 -74
  45. package/dist/src/url-resolver.js.map +1 -1
  46. package/dist/src/utils/content-type-parser.d.ts.map +1 -1
  47. package/dist/src/utils/content-type-parser.js +4 -3
  48. package/dist/src/utils/content-type-parser.js.map +1 -1
  49. package/dist/src/utils/content-types.d.ts +26 -0
  50. package/dist/src/utils/content-types.d.ts.map +1 -0
  51. package/dist/src/utils/content-types.js +137 -0
  52. package/dist/src/utils/content-types.js.map +1 -0
  53. package/dist/src/utils/convert-output.d.ts +17 -0
  54. package/dist/src/utils/convert-output.d.ts.map +1 -0
  55. package/dist/src/utils/convert-output.js +176 -0
  56. package/dist/src/utils/convert-output.js.map +1 -0
  57. package/dist/src/utils/error-to-response.d.ts +3 -0
  58. package/dist/src/utils/error-to-response.d.ts.map +1 -0
  59. package/dist/src/utils/error-to-response.js +40 -0
  60. package/dist/src/utils/error-to-response.js.map +1 -0
  61. package/dist/src/utils/get-content-disposition-filename.d.ts +1 -1
  62. package/dist/src/utils/get-content-disposition-filename.d.ts.map +1 -1
  63. package/dist/src/utils/get-content-disposition-filename.js +4 -0
  64. package/dist/src/utils/get-content-disposition-filename.js.map +1 -1
  65. package/dist/src/utils/get-e-tag.d.ts +20 -15
  66. package/dist/src/utils/get-e-tag.d.ts.map +1 -1
  67. package/dist/src/utils/get-e-tag.js +8 -22
  68. package/dist/src/utils/get-e-tag.js.map +1 -1
  69. package/dist/src/utils/get-offset-and-length.d.ts +12 -2
  70. package/dist/src/utils/get-offset-and-length.d.ts.map +1 -1
  71. package/dist/src/utils/get-offset-and-length.js +63 -21
  72. package/dist/src/utils/get-offset-and-length.js.map +1 -1
  73. package/dist/src/utils/get-range-header.d.ts +22 -0
  74. package/dist/src/utils/get-range-header.d.ts.map +1 -0
  75. package/dist/src/utils/get-range-header.js +69 -0
  76. package/dist/src/utils/get-range-header.js.map +1 -0
  77. package/dist/src/utils/parse-url-string.d.ts +2 -1
  78. package/dist/src/utils/parse-url-string.d.ts.map +1 -1
  79. package/dist/src/utils/parse-url-string.js +46 -71
  80. package/dist/src/utils/parse-url-string.js.map +1 -1
  81. package/dist/src/utils/resource-to-cache-key.d.ts +3 -3
  82. package/dist/src/utils/resource-to-cache-key.js +5 -5
  83. package/dist/src/utils/resource-to-cache-key.js.map +1 -1
  84. package/dist/src/utils/response-headers.d.ts +4 -14
  85. package/dist/src/utils/response-headers.d.ts.map +1 -1
  86. package/dist/src/utils/response-headers.js +36 -36
  87. package/dist/src/utils/response-headers.js.map +1 -1
  88. package/dist/src/utils/responses.d.ts +30 -11
  89. package/dist/src/utils/responses.d.ts.map +1 -1
  90. package/dist/src/utils/responses.js +146 -39
  91. package/dist/src/utils/responses.js.map +1 -1
  92. package/dist/src/verified-fetch.d.ts +16 -15
  93. package/dist/src/verified-fetch.d.ts.map +1 -1
  94. package/dist/src/verified-fetch.js +307 -236
  95. package/dist/src/verified-fetch.js.map +1 -1
  96. package/dist/typedoc-urls.json +64 -45
  97. package/package.json +4 -3
  98. package/src/constants.ts +3 -0
  99. package/src/index.ts +203 -71
  100. package/src/plugins/index.ts +0 -6
  101. package/src/plugins/plugin-base.ts +8 -10
  102. package/src/plugins/plugin-handle-car.ts +48 -46
  103. package/src/plugins/plugin-handle-ipld.ts +93 -0
  104. package/src/plugins/plugin-handle-ipns-record.ts +31 -41
  105. package/src/plugins/plugin-handle-tar.ts +25 -29
  106. package/src/plugins/plugin-handle-unixfs.ts +217 -0
  107. package/src/plugins/types.ts +0 -86
  108. package/src/url-resolver.ts +197 -83
  109. package/src/utils/content-type-parser.ts +4 -3
  110. package/src/utils/content-types.ts +159 -0
  111. package/src/utils/convert-output.ts +187 -0
  112. package/src/utils/error-to-response.ts +49 -0
  113. package/src/utils/get-content-disposition-filename.ts +7 -1
  114. package/src/utils/get-e-tag.ts +26 -35
  115. package/src/utils/get-offset-and-length.ts +75 -21
  116. package/src/utils/get-range-header.ts +107 -0
  117. package/src/utils/parse-url-string.ts +51 -80
  118. package/src/utils/resource-to-cache-key.ts +5 -5
  119. package/src/utils/response-headers.ts +40 -41
  120. package/src/utils/responses.ts +186 -45
  121. package/src/verified-fetch.ts +359 -267
  122. package/dist/src/plugins/plugin-handle-byte-range-context.d.ts +0 -14
  123. package/dist/src/plugins/plugin-handle-byte-range-context.d.ts.map +0 -1
  124. package/dist/src/plugins/plugin-handle-byte-range-context.js +0 -25
  125. package/dist/src/plugins/plugin-handle-byte-range-context.js.map +0 -1
  126. package/dist/src/plugins/plugin-handle-cbor.d.ts +0 -17
  127. package/dist/src/plugins/plugin-handle-cbor.d.ts.map +0 -1
  128. package/dist/src/plugins/plugin-handle-cbor.js +0 -94
  129. package/dist/src/plugins/plugin-handle-cbor.js.map +0 -1
  130. package/dist/src/plugins/plugin-handle-dag-cbor-html-preview.d.ts +0 -27
  131. package/dist/src/plugins/plugin-handle-dag-cbor-html-preview.d.ts.map +0 -1
  132. package/dist/src/plugins/plugin-handle-dag-cbor-html-preview.js +0 -279
  133. package/dist/src/plugins/plugin-handle-dag-cbor-html-preview.js.map +0 -1
  134. package/dist/src/plugins/plugin-handle-dag-cbor.d.ts +0 -17
  135. package/dist/src/plugins/plugin-handle-dag-cbor.d.ts.map +0 -1
  136. package/dist/src/plugins/plugin-handle-dag-cbor.js +0 -66
  137. package/dist/src/plugins/plugin-handle-dag-cbor.js.map +0 -1
  138. package/dist/src/plugins/plugin-handle-dag-pb.d.ts +0 -17
  139. package/dist/src/plugins/plugin-handle-dag-pb.d.ts.map +0 -1
  140. package/dist/src/plugins/plugin-handle-dag-pb.js +0 -209
  141. package/dist/src/plugins/plugin-handle-dag-pb.js.map +0 -1
  142. package/dist/src/plugins/plugin-handle-dag-walk.d.ts +0 -21
  143. package/dist/src/plugins/plugin-handle-dag-walk.d.ts.map +0 -1
  144. package/dist/src/plugins/plugin-handle-dag-walk.js +0 -95
  145. package/dist/src/plugins/plugin-handle-dag-walk.js.map +0 -1
  146. package/dist/src/plugins/plugin-handle-dir-index-html.d.ts +0 -10
  147. package/dist/src/plugins/plugin-handle-dir-index-html.d.ts.map +0 -1
  148. package/dist/src/plugins/plugin-handle-dir-index-html.js +0 -59
  149. package/dist/src/plugins/plugin-handle-dir-index-html.js.map +0 -1
  150. package/dist/src/plugins/plugin-handle-json.d.ts +0 -12
  151. package/dist/src/plugins/plugin-handle-json.d.ts.map +0 -1
  152. package/dist/src/plugins/plugin-handle-json.js +0 -73
  153. package/dist/src/plugins/plugin-handle-json.js.map +0 -1
  154. package/dist/src/plugins/plugin-handle-raw.d.ts +0 -9
  155. package/dist/src/plugins/plugin-handle-raw.d.ts.map +0 -1
  156. package/dist/src/plugins/plugin-handle-raw.js +0 -92
  157. package/dist/src/plugins/plugin-handle-raw.js.map +0 -1
  158. package/dist/src/plugins/plugins.d.ts +0 -6
  159. package/dist/src/plugins/plugins.d.ts.map +0 -1
  160. package/dist/src/plugins/plugins.js +0 -6
  161. package/dist/src/plugins/plugins.js.map +0 -1
  162. package/dist/src/utils/byte-range-context.d.ts +0 -103
  163. package/dist/src/utils/byte-range-context.d.ts.map +0 -1
  164. package/dist/src/utils/byte-range-context.js +0 -504
  165. package/dist/src/utils/byte-range-context.js.map +0 -1
  166. package/dist/src/utils/dag-cbor-to-safe-json.d.ts +0 -15
  167. package/dist/src/utils/dag-cbor-to-safe-json.d.ts.map +0 -1
  168. package/dist/src/utils/dag-cbor-to-safe-json.js +0 -54
  169. package/dist/src/utils/dag-cbor-to-safe-json.js.map +0 -1
  170. package/dist/src/utils/dir-index-html.d.ts +0 -19
  171. package/dist/src/utils/dir-index-html.d.ts.map +0 -1
  172. package/dist/src/utils/dir-index-html.js +0 -438
  173. package/dist/src/utils/dir-index-html.js.map +0 -1
  174. package/dist/src/utils/get-peer-id-from-string.d.ts +0 -3
  175. package/dist/src/utils/get-peer-id-from-string.d.ts.map +0 -1
  176. package/dist/src/utils/get-peer-id-from-string.js +0 -10
  177. package/dist/src/utils/get-peer-id-from-string.js.map +0 -1
  178. package/dist/src/utils/get-resolved-accept-header.d.ts +0 -9
  179. package/dist/src/utils/get-resolved-accept-header.d.ts.map +0 -1
  180. package/dist/src/utils/get-resolved-accept-header.js +0 -27
  181. package/dist/src/utils/get-resolved-accept-header.js.map +0 -1
  182. package/dist/src/utils/get-stream-from-async-iterable.d.ts +0 -9
  183. package/dist/src/utils/get-stream-from-async-iterable.d.ts.map +0 -1
  184. package/dist/src/utils/get-stream-from-async-iterable.js +0 -43
  185. package/dist/src/utils/get-stream-from-async-iterable.js.map +0 -1
  186. package/dist/src/utils/handle-redirects.d.ts +0 -16
  187. package/dist/src/utils/handle-redirects.d.ts.map +0 -1
  188. package/dist/src/utils/handle-redirects.js +0 -84
  189. package/dist/src/utils/handle-redirects.js.map +0 -1
  190. package/dist/src/utils/is-accept-explicit.d.ts +0 -15
  191. package/dist/src/utils/is-accept-explicit.d.ts.map +0 -1
  192. package/dist/src/utils/is-accept-explicit.js +0 -26
  193. package/dist/src/utils/is-accept-explicit.js.map +0 -1
  194. package/dist/src/utils/request-headers.d.ts +0 -13
  195. package/dist/src/utils/request-headers.d.ts.map +0 -1
  196. package/dist/src/utils/request-headers.js +0 -63
  197. package/dist/src/utils/request-headers.js.map +0 -1
  198. package/dist/src/utils/select-output-type.d.ts +0 -17
  199. package/dist/src/utils/select-output-type.d.ts.map +0 -1
  200. package/dist/src/utils/select-output-type.js +0 -153
  201. package/dist/src/utils/select-output-type.js.map +0 -1
  202. package/dist/src/utils/tlru.d.ts +0 -15
  203. package/dist/src/utils/tlru.d.ts.map +0 -1
  204. package/dist/src/utils/tlru.js +0 -34
  205. package/dist/src/utils/tlru.js.map +0 -1
  206. package/dist/src/utils/walk-path.d.ts +0 -27
  207. package/dist/src/utils/walk-path.d.ts.map +0 -1
  208. package/dist/src/utils/walk-path.js +0 -45
  209. package/dist/src/utils/walk-path.js.map +0 -1
  210. package/src/plugins/plugin-handle-byte-range-context.ts +0 -30
  211. package/src/plugins/plugin-handle-cbor.ts +0 -107
  212. package/src/plugins/plugin-handle-dag-cbor-html-preview.ts +0 -295
  213. package/src/plugins/plugin-handle-dag-cbor.ts +0 -83
  214. package/src/plugins/plugin-handle-dag-pb.ts +0 -248
  215. package/src/plugins/plugin-handle-dag-walk.ts +0 -110
  216. package/src/plugins/plugin-handle-dir-index-html.ts +0 -72
  217. package/src/plugins/plugin-handle-json.ts +0 -80
  218. package/src/plugins/plugin-handle-raw.ts +0 -110
  219. package/src/plugins/plugins.ts +0 -5
  220. package/src/utils/byte-range-context.ts +0 -597
  221. package/src/utils/dag-cbor-to-safe-json.ts +0 -63
  222. package/src/utils/dir-index-html.ts +0 -505
  223. package/src/utils/get-peer-id-from-string.ts +0 -12
  224. package/src/utils/get-resolved-accept-header.ts +0 -42
  225. package/src/utils/get-stream-from-async-iterable.ts +0 -49
  226. package/src/utils/handle-redirects.ts +0 -109
  227. package/src/utils/is-accept-explicit.ts +0 -38
  228. package/src/utils/request-headers.ts +0 -65
  229. package/src/utils/select-output-type.ts +0 -175
  230. package/src/utils/tlru.ts +0 -42
  231. package/src/utils/walk-path.ts +0 -68
@@ -1,209 +0,0 @@
1
- import { unixfs } from '@helia/unixfs';
2
- import { code as dagPbCode } from '@ipld/dag-pb';
3
- import { AbortError } from '@libp2p/interface';
4
- import { exporter } from 'ipfs-unixfs-exporter';
5
- import { CustomProgressEvent } from 'progress-events';
6
- import { getContentType } from '../utils/get-content-type.js';
7
- import { getStreamFromAsyncIterable } from '../utils/get-stream-from-async-iterable.js';
8
- import { setIpfsRoots } from '../utils/response-headers.js';
9
- import { badGatewayResponse, badRangeResponse, movedPermanentlyResponse, okRangeResponse } from '../utils/responses.js';
10
- import { BasePlugin } from './plugin-base.js';
11
- /**
12
- * Handles UnixFS and dag-pb content.
13
- */
14
- export class DagPbPlugin extends BasePlugin {
15
- id = 'dag-pb-plugin';
16
- codes = [dagPbCode];
17
- canHandle({ cid, accept, pathDetails, byteRangeContext }) {
18
- if (pathDetails == null) {
19
- return false;
20
- }
21
- if (byteRangeContext == null) {
22
- return false;
23
- }
24
- // TODO: this may be too restrictive?
25
- if (accept != null && accept.mimeType !== 'application/octet-stream') {
26
- return false;
27
- }
28
- return cid.code === dagPbCode;
29
- }
30
- /**
31
- * @see https://specs.ipfs.tech/http-gateways/path-gateway/#use-in-directory-url-normalization
32
- */
33
- getRedirectUrl(context) {
34
- const { resource, url, isDirectory } = context;
35
- let uri;
36
- try {
37
- // try the requested resource
38
- uri = new URL(resource);
39
- }
40
- catch {
41
- // fall back to the canonical URL
42
- uri = url;
43
- }
44
- // directories must be requested with a trailing slash
45
- if (isDirectory && !uri.pathname.endsWith('/')) {
46
- // make sure we append slash to end of the path
47
- uri.pathname += '/';
48
- return uri.toString();
49
- }
50
- return null;
51
- }
52
- async handle(context) {
53
- const { cid, options, pathDetails, query } = context;
54
- const { contentTypeParser, helia, getBlockstore } = this.pluginOptions;
55
- const log = this.log;
56
- let resource = context.resource;
57
- const path = context.path;
58
- let filename = query?.filename;
59
- let redirected = false;
60
- const byteRangeContext = context.byteRangeContext;
61
- const ipfsRoots = pathDetails.ipfsRoots;
62
- const terminalElement = pathDetails.terminalElement;
63
- let resolvedCID = terminalElement.cid;
64
- const fs = unixfs({ ...helia, blockstore: getBlockstore(context.cid, context.resource, options?.session ?? true, options) });
65
- context.isDirectory = terminalElement?.type === 'directory';
66
- if (terminalElement?.type === 'directory') {
67
- const redirectUrl = this.getRedirectUrl(context);
68
- if (redirectUrl != null) {
69
- log.trace('directory url normalization spec requires redirect...');
70
- if (options?.redirect === 'error') {
71
- log('could not redirect to %s as redirect option was set to "error"', redirectUrl);
72
- throw new TypeError('Failed to fetch');
73
- }
74
- else if (options?.redirect === 'manual') {
75
- log('returning 301 permanent redirect to %s', redirectUrl);
76
- return movedPermanentlyResponse(resource, redirectUrl);
77
- }
78
- log('following redirect to %s', redirectUrl);
79
- // fall-through simulates following the redirect?
80
- resource = redirectUrl;
81
- redirected = true;
82
- }
83
- const dirCid = terminalElement.cid;
84
- const rootFilePath = 'index.html';
85
- try {
86
- log.trace('found directory at %c/%s, looking for index.html', cid, path);
87
- const entry = await context.serverTiming.time('exporter-dir', '', exporter(`/ipfs/${dirCid}/${rootFilePath}`, helia.blockstore, {
88
- signal: options?.signal,
89
- onProgress: options?.onProgress
90
- }));
91
- log.trace('found root file at %c/%s with cid %c', dirCid, rootFilePath, entry.cid);
92
- resolvedCID = entry.cid;
93
- // use `index.html` as the file name to help with content types
94
- filename = rootFilePath;
95
- }
96
- catch (err) {
97
- if (options?.signal?.aborted) {
98
- throw new AbortError(options?.signal?.reason);
99
- }
100
- this.log.error('error loading path %c/%s - %e', dirCid, rootFilePath, err);
101
- context.isDirectory = true;
102
- context.directoryEntries = [];
103
- context.modified++;
104
- this.log.trace('attempting to get directory entries because index.html was not found');
105
- for await (const dirItem of fs.ls(dirCid, { signal: options?.signal, onProgress: options?.onProgress, extended: false })) {
106
- context.directoryEntries.push(dirItem);
107
- }
108
- // dir-index-html plugin or dir-index-json (future idea?) plugin should handle this
109
- return null;
110
- }
111
- finally {
112
- options?.onProgress?.(new CustomProgressEvent('verified-fetch:request:end', { cid: dirCid, path: [rootFilePath] }));
113
- }
114
- }
115
- try {
116
- // attempt to get the exact file size, but timeout quickly.
117
- const stat = await fs.stat(resolvedCID, {
118
- extended: true,
119
- signal: AbortSignal.timeout(500)
120
- });
121
- byteRangeContext.setFileSize(stat.size);
122
- }
123
- catch (err) {
124
- log.error('error getting exact file size for %c/%s - %e', cid, path, err);
125
- byteRangeContext.setFileSize(pathDetails.terminalElement.size);
126
- log.trace('using terminal element size of %d for %c/%s', pathDetails.terminalElement.size, cid, path);
127
- }
128
- try {
129
- const entry = await context.serverTiming.time('exporter-file', '', exporter(resolvedCID, helia.blockstore, {
130
- signal: options?.signal,
131
- onProgress: options?.onProgress
132
- }));
133
- let firstChunk;
134
- let contentType;
135
- if (byteRangeContext.isValidRangeRequest) {
136
- contentType = await this.handleRangeRequest(context, entry);
137
- }
138
- else {
139
- const asyncIter = entry.content({
140
- signal: options?.signal,
141
- onProgress: options?.onProgress
142
- });
143
- log('got async iterator for %c/%s', cid, path);
144
- const streamAndFirstChunk = await context.serverTiming.time('stream-and-chunk', '', getStreamFromAsyncIterable(asyncIter, {
145
- onProgress: options?.onProgress,
146
- signal: options?.signal
147
- }));
148
- const stream = streamAndFirstChunk.stream;
149
- firstChunk = streamAndFirstChunk.firstChunk;
150
- contentType = await context.serverTiming.time('get-content-type', '', getContentType({
151
- path,
152
- filename,
153
- bytes: firstChunk,
154
- contentTypeParser,
155
- log
156
- }));
157
- byteRangeContext.setBody(stream);
158
- }
159
- // if not a valid range request, okRangeRequest will call okResponse
160
- const response = okRangeResponse(resource, byteRangeContext.getBody(contentType), { byteRangeContext, log }, {
161
- redirected
162
- });
163
- response.headers.set('Content-Type', byteRangeContext.getContentType() ?? contentType);
164
- setIpfsRoots(response, ipfsRoots);
165
- return response;
166
- }
167
- catch (err) {
168
- if (options?.signal?.aborted) {
169
- throw new AbortError(options?.signal?.reason);
170
- }
171
- log.error('error streaming %c/%s - %e', cid, path, err);
172
- if (byteRangeContext.isRangeRequest && err.code === 'ERR_INVALID_PARAMS') {
173
- return badRangeResponse(resource);
174
- }
175
- return badGatewayResponse(resource, 'Unable to stream content');
176
- }
177
- }
178
- async handleRangeRequest(context, entry) {
179
- const { path, byteRangeContext, options } = context;
180
- const { contentTypeParser } = this.pluginOptions;
181
- const log = this.log;
182
- // get the first chunk in order to determine the content type
183
- const asyncIter = entry.content({
184
- signal: options?.signal,
185
- onProgress: options?.onProgress,
186
- offset: 0,
187
- // 8kb in order to determine the content type
188
- length: 8192
189
- });
190
- const { firstChunk } = await getStreamFromAsyncIterable(asyncIter, {
191
- onProgress: options?.onProgress,
192
- signal: options?.signal
193
- });
194
- const contentType = await context.serverTiming.time('get-content-type', '', getContentType({ bytes: firstChunk, path, contentTypeParser, log }));
195
- byteRangeContext?.setBody((range) => {
196
- if (options?.signal?.aborted) {
197
- throw new AbortError(options?.signal?.reason ?? 'aborted while streaming');
198
- }
199
- return entry.content({
200
- signal: options?.signal,
201
- onProgress: options?.onProgress,
202
- offset: range.start ?? 0,
203
- length: byteRangeContext.getLength(range)
204
- });
205
- }, contentType);
206
- return contentType;
207
- }
208
- }
209
- //# sourceMappingURL=plugin-handle-dag-pb.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugin-handle-dag-pb.js","sourceRoot":"","sources":["../../../src/plugins/plugin-handle-dag-pb.ts"],"names":[],"mappings":"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"}
@@ -1,21 +0,0 @@
1
- import { BasePlugin } from './plugin-base.js';
2
- import type { PluginContext } from './types.js';
3
- /**
4
- * This plugin should almost always run first because it's going to handle path
5
- * walking if needed, and will only say it can handle the request if path
6
- * walking is possible (path is not empty, terminalCid is unknown, and the path
7
- * has not been walked yet).
8
- *
9
- * Once this plugin has run, the PluginContext will be updated and then this
10
- * plugin will return false for canHandle, so it won't run again.
11
- */
12
- export declare class DagWalkPlugin extends BasePlugin {
13
- readonly id = "dag-walk-plugin";
14
- /**
15
- * Return false if the path has already been walked, otherwise return true if
16
- * the CID is encoded with a codec that supports pathing.
17
- */
18
- canHandle(context: PluginContext): boolean;
19
- handle(context: PluginContext): Promise<Response | null>;
20
- }
21
- //# sourceMappingURL=plugin-handle-dag-walk.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugin-handle-dag-walk.d.ts","sourceRoot":"","sources":["../../../src/plugins/plugin-handle-dag-walk.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAgB/C;;;;;;;;GAQG;AACH,qBAAa,aAAc,SAAQ,UAAU;IAC3C,QAAQ,CAAC,EAAE,qBAAoB;IAE/B;;;OAGG;IACH,SAAS,CAAE,OAAO,EAAE,aAAa,GAAG,OAAO;IAWrC,MAAM,CAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;CAyDhE"}
@@ -1,95 +0,0 @@
1
- import * as dagCbor from '@ipld/dag-cbor';
2
- import * as dagJson from '@ipld/dag-json';
3
- import * as dagPb from '@ipld/dag-pb';
4
- import toBuffer from 'it-to-buffer';
5
- import * as json from 'multiformats/codecs/json';
6
- import * as raw from 'multiformats/codecs/raw';
7
- import { CODEC_CBOR, CODEC_IDENTITY } from "../constants.js";
8
- import { handlePathWalking } from '../utils/walk-path.js';
9
- import { BasePlugin } from './plugin-base.js';
10
- const ENTITY_CODECS = [
11
- CODEC_CBOR,
12
- json.code,
13
- raw.code
14
- ];
15
- const WALKABLE_CODECS = [
16
- dagPb.code,
17
- dagCbor.code,
18
- dagJson.code,
19
- ...ENTITY_CODECS
20
- ];
21
- /**
22
- * This plugin should almost always run first because it's going to handle path
23
- * walking if needed, and will only say it can handle the request if path
24
- * walking is possible (path is not empty, terminalCid is unknown, and the path
25
- * has not been walked yet).
26
- *
27
- * Once this plugin has run, the PluginContext will be updated and then this
28
- * plugin will return false for canHandle, so it won't run again.
29
- */
30
- export class DagWalkPlugin extends BasePlugin {
31
- id = 'dag-walk-plugin';
32
- /**
33
- * Return false if the path has already been walked, otherwise return true if
34
- * the CID is encoded with a codec that supports pathing.
35
- */
36
- canHandle(context) {
37
- const { pathDetails, cid } = context;
38
- if (pathDetails != null) {
39
- // path has already been walked
40
- return false;
41
- }
42
- return WALKABLE_CODECS.includes(cid.code);
43
- }
44
- async handle(context) {
45
- const { cid, resource, options } = context;
46
- const { getBlockstore } = this.pluginOptions;
47
- const blockstore = getBlockstore(cid, resource, options?.session ?? true, options);
48
- let pathDetails;
49
- // entity codecs contain all the bytes for an entity in one block and no
50
- // path walking outside of that block is possible
51
- if (ENTITY_CODECS.includes(cid.code)) {
52
- let bytes;
53
- if (cid.multihash.code === CODEC_IDENTITY) {
54
- bytes = cid.multihash.digest;
55
- }
56
- else {
57
- bytes = await toBuffer(blockstore.get(cid, context.options));
58
- }
59
- pathDetails = {
60
- ipfsRoots: [cid],
61
- terminalElement: {
62
- name: cid.toString(),
63
- path: cid.toString(),
64
- depth: 0,
65
- type: 'object',
66
- node: bytes,
67
- cid,
68
- size: BigInt(bytes.byteLength),
69
- content: async function* () {
70
- yield bytes;
71
- }
72
- }
73
- };
74
- }
75
- else {
76
- // TODO: migrate handlePathWalking into this plugin
77
- pathDetails = await context.serverTiming.time('path-walking', '', handlePathWalking({ ...context, blockstore, log: this.log }));
78
- }
79
- if (pathDetails instanceof Response) {
80
- this.log.trace('path walking failed');
81
- if (pathDetails.status === 404) {
82
- // invalid or incorrect path.. we walked the path but nothing is there
83
- // send the 404 response
84
- return pathDetails;
85
- }
86
- // some other error walking the path (codec doesn't support pathing,
87
- // etc..), let the next plugin try to handle it
88
- return null;
89
- }
90
- context.modified++;
91
- context.pathDetails = pathDetails;
92
- return null;
93
- }
94
- }
95
- //# sourceMappingURL=plugin-handle-dag-walk.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugin-handle-dag-walk.js","sourceRoot":"","sources":["../../../src/plugins/plugin-handle-dag-walk.ts"],"names":[],"mappings":"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"}
@@ -1,10 +0,0 @@
1
- import { BasePlugin } from './plugin-base.js';
2
- import type { PluginContext, VerifiedFetchPluginFactory } from './types.js';
3
- export declare class DirIndexHtmlPlugin extends BasePlugin {
4
- readonly id = "dir-index-html-plugin";
5
- readonly codes: 112[];
6
- canHandle(context: PluginContext): boolean;
7
- handle(context: PluginContext & Required<Pick<PluginContext, 'byteRangeContext' | 'pathDetails' | 'directoryEntries'>>): Promise<Response>;
8
- }
9
- export declare const dirIndexHtmlPluginFactory: VerifiedFetchPluginFactory;
10
- //# sourceMappingURL=plugin-handle-dir-index-html.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugin-handle-dir-index-html.d.ts","sourceRoot":"","sources":["../../../src/plugins/plugin-handle-dir-index-html.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAA;AAiB3E,qBAAa,kBAAmB,SAAQ,UAAU;IAChD,QAAQ,CAAC,EAAE,2BAA0B;IACrC,QAAQ,CAAC,KAAK,QAAc;IAC5B,SAAS,CAAE,OAAO,EAAE,aAAa,GAAG,OAAO;IAgBrC,MAAM,CAAE,OAAO,EAAE,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,kBAAkB,GAAG,aAAa,GAAG,kBAAkB,CAAC,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC;CAyBlJ;AAED,eAAO,MAAM,yBAAyB,EAAE,0BAAmE,CAAA"}
@@ -1,59 +0,0 @@
1
- import { code as dagPbCode } from '@ipld/dag-pb';
2
- import { base32 } from 'multiformats/bases/base32';
3
- import { sha256 } from 'multiformats/hashes/sha2';
4
- import { dirIndexHtml } from '../utils/dir-index-html.js';
5
- import { getETag } from '../utils/get-e-tag.js';
6
- import { getIpfsRoots } from '../utils/response-headers.js';
7
- import { okRangeResponse } from '../utils/responses.js';
8
- import { BasePlugin } from './plugin-base.js';
9
- /**
10
- * Converts a list of directory entries into a small hash that can be used in the etag header.
11
- *
12
- * @see https://github.com/ipfs/boxo/blob/dc60fe747c375c631a92fcfd6c7456f44a760d24/gateway/assets/assets.go#L84
13
- * @see https://github.com/ipfs/boxo/blob/dc60fe747c375c631a92fcfd6c7456f44a760d24/gateway/handler_unixfs_dir.go#L233-L235
14
- */
15
- async function getAssetHash(directoryEntries) {
16
- const entryDetails = directoryEntries.reduce((acc, entry) => {
17
- return `${acc}${entry.name}${entry.cid.toString()}`;
18
- }, '');
19
- const hashBytes = await sha256.encode(new TextEncoder().encode(entryDetails));
20
- return base32.encode(hashBytes);
21
- }
22
- export class DirIndexHtmlPlugin extends BasePlugin {
23
- id = 'dir-index-html-plugin';
24
- codes = [dagPbCode];
25
- canHandle(context) {
26
- const { cid, pathDetails, directoryEntries } = context;
27
- if (pathDetails == null) {
28
- return false;
29
- }
30
- if (pathDetails.terminalElement?.type !== 'directory') {
31
- return false;
32
- }
33
- if (directoryEntries == null || directoryEntries.length === 0) {
34
- return false;
35
- }
36
- return cid.code === dagPbCode;
37
- }
38
- async handle(context) {
39
- const { resource, pathDetails, directoryEntries } = context;
40
- const { terminalElement, ipfsRoots } = pathDetails;
41
- const gatewayURL = resource;
42
- const htmlResponse = dirIndexHtml(terminalElement, directoryEntries, { gatewayURL, log: this.log });
43
- context.byteRangeContext.setBody(htmlResponse);
44
- const etagPrefix = `DirIndex-${await getAssetHash(directoryEntries)}_CID-`;
45
- const response = okRangeResponse(resource, context.byteRangeContext.getBody('text/html'), { byteRangeContext: context.byteRangeContext, log: this.log }, {
46
- headers: {
47
- 'Content-Type': context.byteRangeContext.getContentType() ?? 'text/html',
48
- // see https://github.com/ipfs/gateway-conformance/pull/219
49
- 'Cache-Control': 'public, max-age=604800, stale-while-revalidate=2678400',
50
- 'X-Ipfs-Roots': getIpfsRoots(ipfsRoots),
51
- // e.g. DirIndex-<asset_hash>_CID-<cid>
52
- Etag: getETag({ cid: terminalElement.cid, reqFormat: context.reqFormat, contentPrefix: etagPrefix })
53
- }
54
- });
55
- return response;
56
- }
57
- }
58
- export const dirIndexHtmlPluginFactory = (opts) => new DirIndexHtmlPlugin(opts);
59
- //# sourceMappingURL=plugin-handle-dir-index-html.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugin-handle-dir-index-html.js","sourceRoot":"","sources":["../../../src/plugins/plugin-handle-dir-index-html.ts"],"names":[],"mappings":"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"}
@@ -1,12 +0,0 @@
1
- import { BasePlugin } from './plugin-base.js';
2
- import type { PluginContext } from './types.js';
3
- /**
4
- * Handles `dag-json` content, including requests with Accept: `application/vnd.ipld.dag-cbor` and `application/cbor`.
5
- */
6
- export declare class JsonPlugin extends BasePlugin {
7
- readonly id = "json-plugin";
8
- readonly codes: number[];
9
- canHandle({ cid, accept, byteRangeContext }: PluginContext): boolean;
10
- handle(context: PluginContext & Required<Pick<PluginContext, 'byteRangeContext'>>): Promise<Response>;
11
- }
12
- //# sourceMappingURL=plugin-handle-json.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugin-handle-json.d.ts","sourceRoot":"","sources":["../../../src/plugins/plugin-handle-json.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/C;;GAEG;AACH,qBAAa,UAAW,SAAQ,UAAU;IACxC,QAAQ,CAAC,EAAE,iBAAgB;IAC3B,QAAQ,CAAC,KAAK,WAA+B;IAE7C,SAAS,CAAE,EAAE,GAAG,EAAE,MAAM,EAAE,gBAAgB,EAAE,EAAE,aAAa,GAAG,OAAO;IAe/D,MAAM,CAAE,OAAO,EAAE,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,kBAAkB,CAAC,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC;CAgD7G"}
@@ -1,73 +0,0 @@
1
- import * as ipldDagCbor from '@ipld/dag-cbor';
2
- import * as ipldDagJson from '@ipld/dag-json';
3
- import toBuffer from 'it-to-buffer';
4
- import { code as jsonCode } from 'multiformats/codecs/json';
5
- import { CODEC_CBOR } from "../constants.js";
6
- import { notAcceptableResponse, okRangeResponse } from '../utils/responses.js';
7
- import { BasePlugin } from './plugin-base.js';
8
- /**
9
- * Handles `dag-json` content, including requests with Accept: `application/vnd.ipld.dag-cbor` and `application/cbor`.
10
- */
11
- export class JsonPlugin extends BasePlugin {
12
- id = 'json-plugin';
13
- codes = [ipldDagJson.code, jsonCode];
14
- canHandle({ cid, accept, byteRangeContext }) {
15
- if (byteRangeContext == null) {
16
- return false;
17
- }
18
- if (accept?.mimeType === 'application/vnd.ipld.dag-json' && cid.code !== ipldDagCbor.code && cid.code !== CODEC_CBOR) {
19
- // we can handle application/vnd.ipld.dag-json, but if the CID codec is
20
- // cbor related, cbor related plugins will handle it
21
- // TODO: remove the need for deny-listing cases in plugins
22
- return true;
23
- }
24
- return ipldDagJson.code === cid.code || jsonCode === cid.code;
25
- }
26
- async handle(context) {
27
- const { path, resource, cid, accept, options } = context;
28
- const { getBlockstore } = this.pluginOptions;
29
- const session = options?.session ?? true;
30
- this.log.trace('fetching %c/%s', cid, path);
31
- const terminalCid = context.pathDetails?.terminalElement.cid ?? context.cid;
32
- const blockstore = getBlockstore(terminalCid, resource, session, options);
33
- const block = await toBuffer(blockstore.get(terminalCid, options));
34
- let body;
35
- if (accept?.mimeType === 'application/vnd.ipld.dag-cbor' || accept?.mimeType === 'application/cbor') {
36
- try {
37
- // if vnd.ipld.dag-cbor has been specified, convert to the format - note
38
- // that this supports more data types than regular JSON, the content-type
39
- // response header is set so the user knows to process it differently
40
- const obj = ipldDagJson.decode(block);
41
- body = ipldDagCbor.encode(obj);
42
- }
43
- catch (err) {
44
- this.log.error('could not transform %c to application/vnd.ipld.dag-cbor - %e', err);
45
- return notAcceptableResponse(resource);
46
- }
47
- }
48
- else {
49
- // skip decoding
50
- body = block;
51
- }
52
- let contentType;
53
- if (accept == null) {
54
- if (ipldDagJson.code === cid.code) {
55
- contentType = 'application/vnd.ipld.dag-json';
56
- }
57
- else {
58
- contentType = 'application/json';
59
- }
60
- }
61
- else {
62
- contentType = accept?.mimeType.split(';')[0];
63
- }
64
- context.byteRangeContext.setBody(body);
65
- const response = okRangeResponse(resource, context.byteRangeContext.getBody(contentType), { byteRangeContext: context.byteRangeContext, log: this.log });
66
- response.headers.set('content-type', context.byteRangeContext.getContentType() ?? contentType);
67
- if (!context.byteRangeContext.isValidRangeRequest) {
68
- response.headers.set('content-length', body.length.toString());
69
- }
70
- return response;
71
- }
72
- }
73
- //# sourceMappingURL=plugin-handle-json.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugin-handle-json.js","sourceRoot":"","sources":["../../../src/plugins/plugin-handle-json.ts"],"names":[],"mappings":"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"}
@@ -1,9 +0,0 @@
1
- import { BasePlugin } from './plugin-base.js';
2
- import type { PluginContext } from './types.js';
3
- export declare class RawPlugin extends BasePlugin {
4
- readonly id = "raw-plugin";
5
- codes: number[];
6
- canHandle({ cid, accept, query, byteRangeContext }: PluginContext): boolean;
7
- handle(context: PluginContext & Required<Pick<PluginContext, 'byteRangeContext'>>): Promise<Response>;
8
- }
9
- //# sourceMappingURL=plugin-handle-raw.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugin-handle-raw.d.ts","sourceRoot":"","sources":["../../../src/plugins/plugin-handle-raw.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAuC/C,qBAAa,SAAU,SAAQ,UAAU;IACvC,QAAQ,CAAC,EAAE,gBAAe;IAC1B,KAAK,EAAE,MAAM,EAAE,CAA2B;IAE1C,SAAS,CAAE,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,EAAE,EAAE,aAAa,GAAG,OAAO;IAQtE,MAAM,CAAE,OAAO,EAAE,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,kBAAkB,CAAC,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC;CAoD7G"}
@@ -1,92 +0,0 @@
1
- import toBuffer from 'it-to-buffer';
2
- import { code as rawCode } from 'multiformats/codecs/raw';
3
- import { identity } from 'multiformats/hashes/identity';
4
- import { getContentType } from '../utils/get-content-type.js';
5
- import { notFoundResponse, okRangeResponse } from '../utils/responses.js';
6
- import { BasePlugin } from './plugin-base.js';
7
- /**
8
- * These are Accept header values that will cause content type sniffing to be
9
- * skipped and set to these values.
10
- */
11
- const RAW_HEADERS = [
12
- 'application/vnd.ipld.dag-json',
13
- 'application/vnd.ipld.raw',
14
- 'application/octet-stream'
15
- ];
16
- /**
17
- * if the user has specified an `Accept` header, and it's in our list of
18
- * allowable "raw" format headers, use that instead of detecting the content
19
- * type. This avoids the user from receiving something different when they
20
- * signal that they want to `Accept` a specific mime type.
21
- */
22
- function getOverriddenRawContentType({ headers, accept }) {
23
- // accept has already been resolved by getResolvedAcceptHeader, if we have it, use it.
24
- const acceptHeader = accept?.mimeType ?? new Headers(headers).get('accept') ?? '';
25
- // e.g. "Accept: text/html, application/xhtml+xml, application/xml;q=0.9, image/webp, */*;q=0.8"
26
- const acceptHeaders = acceptHeader.split(',')
27
- .map(s => s.split(';')[0])
28
- .map(s => s.trim());
29
- for (const mimeType of acceptHeaders) {
30
- if (mimeType === '*/*') {
31
- return;
32
- }
33
- if (RAW_HEADERS.includes(mimeType ?? '')) {
34
- return mimeType;
35
- }
36
- }
37
- }
38
- export class RawPlugin extends BasePlugin {
39
- id = 'raw-plugin';
40
- codes = [rawCode, identity.code];
41
- canHandle({ cid, accept, query, byteRangeContext }) {
42
- if (byteRangeContext == null) {
43
- return false;
44
- }
45
- return accept?.mimeType === 'application/vnd.ipld.raw' || query.format === 'raw';
46
- }
47
- async handle(context) {
48
- const { path, resource, cid, accept, query, options } = context;
49
- const { getBlockstore, contentTypeParser } = this.pluginOptions;
50
- const session = options?.session ?? true;
51
- const log = this.log;
52
- if (accept?.mimeType === 'application/vnd.ipld.raw' || query.format === 'raw') {
53
- context.reqFormat = 'raw';
54
- context.query.download = true;
55
- context.query.filename = context.query.filename ?? `${cid.toString()}.bin`;
56
- log.trace('set content disposition to force download');
57
- }
58
- else {
59
- log.trace('did not set content disposition, raw block will display inline');
60
- }
61
- if (path.length > 0 && cid.code === rawCode) {
62
- log.trace('404-ing raw codec request for %c/%s', cid, path);
63
- return notFoundResponse(resource);
64
- }
65
- const terminalCid = context.pathDetails?.terminalElement.cid ?? context.cid;
66
- const blockstore = getBlockstore(terminalCid, resource, session, options);
67
- const result = await toBuffer(blockstore.get(terminalCid, options));
68
- context.byteRangeContext.setBody(result);
69
- // if the user has specified an `Accept` header that corresponds to a raw
70
- // type, honour that header, so for example they don't request
71
- // `application/vnd.ipld.raw` but get `application/octet-stream`
72
- const contentType = await getContentType({
73
- filename: query.filename,
74
- bytes: result,
75
- path,
76
- defaultContentType: getOverriddenRawContentType({ headers: options?.headers, accept }),
77
- contentTypeParser,
78
- log
79
- });
80
- const response = okRangeResponse(resource, context.byteRangeContext.getBody(contentType), { byteRangeContext: context.byteRangeContext, log }, {
81
- redirected: false
82
- });
83
- response.headers.set('content-type', context.byteRangeContext.getContentType() ?? contentType);
84
- response.headers.set('x-ipfs-roots', terminalCid.toV1().toString());
85
- // only set content-length if it is not a range request
86
- if (!context.byteRangeContext.isRangeRequest) {
87
- response.headers.set('content-length', result.byteLength.toString());
88
- }
89
- return response;
90
- }
91
- }
92
- //# sourceMappingURL=plugin-handle-raw.js.map