-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathHttpSource.js
More file actions
77 lines (69 loc) · 2.34 KB
/
Copy pathHttpSource.js
File metadata and controls
77 lines (69 loc) · 2.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
const path = require("path")
const Source = require("./Source")
const downloadWithCache = require("../lib/downloadWithCache")
const { REMOTE_FETCH_FAILED } = require("../errors/codes")
const RemoteFileNotFoundError = require("../errors/RemoteFileNotFoundError")
class HttpSource extends Source {
constructor({ url, defaultExtension = ".dockerfile" }) {
super()
this._defaultExtension = defaultExtension
this._originalUrl = url
// Eagerly append default extension when the pathname lacks any — saves a
// guaranteed 404 round-trip for the common `INCLUDE https://x/y/z` case.
// Mutate `pathname` (not raw URL) so `?query` and `#fragment` survive.
if (defaultExtension) {
const parsed = new URL(url)
if (!path.extname(parsed.pathname)) {
parsed.pathname += defaultExtension
url = parsed.toString()
}
}
this._url = url
}
async read() {
try {
return await downloadWithCache(this._url)
} catch (err) {
// 404 is an authoritative "not found" — surface it as the typed
// RemoteFileNotFoundError so callers can branch on the same code that
// GitSource and OciSource emit for the equivalent miss.
if (err.response?.status === 404) {
throw new RemoteFileNotFoundError(this._url, err)
}
const original = this._originalUrl
const suffix = original && original !== this._url ? ` (from ${original})` : ""
const wrapped = new Error(
`Failed to fetch ${this._url}${suffix}: ${err.message}`,
)
wrapped.code = REMOTE_FETCH_FAILED
wrapped.url = this._url
wrapped.originalUrl = original
wrapped.cause = err
throw wrapped
}
}
joinRelative(relPath) {
// Defense-in-depth: resolveSource already rejects scheme-bearing relative
// paths, but `new URL(absUrl, base)` would silently drop the base if the
// guard ever regressed. Reject here too.
if (/^[a-z][a-z0-9+.-]*:/i.test(relPath)) {
throw new Error(
`HttpSource.joinRelative rejected scheme-bearing path: ${relPath}`,
)
}
return new HttpSource({
url: new URL(relPath, this._url).toString(),
defaultExtension: this._defaultExtension,
})
}
key() {
return this._url
}
displayPath() {
return this._url
}
stageAliasBase() {
return this._url
}
}
module.exports = HttpSource