Skip to content

Commit 62c8c91

Browse files
shagamemnonGregBrimble
authored andcommitted
Frank/#165 fix (#166)
* defined response status on cached responses. fixes 165 * updated mocks and added tests for range requests * fixed range request test
1 parent 0423a3f commit 62c8c91

File tree

3 files changed

+65
-8
lines changed

3 files changed

+65
-8
lines changed

packages/kv-asset-handler/src/index.ts

+18-2
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,24 @@ const getAssetFromKV = async (event: FetchEvent, options?: Partial<Options>): Pr
211211
}
212212
response = new Response(null, response)
213213
} else {
214-
response = new Response(response.body, response)
215-
response.headers.set('cf-cache-status', 'HIT')
214+
headers.set('CF-Cache-Status', 'HIT')
215+
// fixes #165
216+
let opts = {
217+
headers,
218+
status: 0,
219+
statusText: ''
220+
}
221+
if (response.status) {
222+
opts.status = response.status
223+
opts.statusText = response.statusText
224+
} else if (headers.has('Content-Range')) {
225+
opts.status = 206
226+
opts.statusText = 'Partial Content'
227+
} else {
228+
opts.status = 200
229+
opts.statusText = 'OK'
230+
}
231+
response = new Response(response.body, opts)
216232
}
217233

218234
} else {

packages/kv-asset-handler/src/mocks.ts

+32-6
Original file line numberDiff line numberDiff line change
@@ -66,17 +66,43 @@ export const mockCaches = () => {
6666
url: key.url,
6767
headers: {}
6868
}
69+
let response
6970
if (key.headers.has('if-none-match')) {
70-
let makeStrongEtag = key.headers.get('if-none-match').replace('W/', '')
71-
Reflect.set(cacheKey.headers, 'etag', makeStrongEtag)
71+
cacheKey.headers = {
72+
'etag': key.headers.get('if-none-match')
73+
}
74+
response = cacheStore.get(JSON.stringify(cacheKey))
75+
} else {
76+
// if client doesn't send if-none-match, we need to iterate through these keys
77+
// and just test the URL
78+
const activeCacheKeys: Array<string> = Array.from(cacheStore.keys())
79+
for (const cacheStoreKey of activeCacheKeys) {
80+
if (JSON.parse(cacheStoreKey).url === key.url) {
81+
response = cacheStore.get(cacheStoreKey)
82+
}
83+
}
84+
}
85+
if (response) {
86+
// this appears overly verbose, but is necessary to document edge cache behavior
87+
// The Range request header triggers the response header Content-Range ...
88+
const range = key.headers.get('range')
89+
if (range) {
90+
response.headers.set('content-range', `bytes ${range.split('=').pop()}/${response.headers.get('content-length')}`)
91+
}
92+
// ... which we are using in this repository to set status 206
93+
if (response.headers.has('content-range')) {
94+
response.status = 206
95+
} else {
96+
response.status = 200
97+
}
7298
}
73-
return cacheStore.get(JSON.stringify(cacheKey))
99+
return response
74100
},
75101
async put (key: any, val: Response) {
76102
let headers = new Headers(val.headers)
77-
let url = new URL(key.url)
78-
let resWithBody = new Response(val.body, { headers, status: 200 })
79-
let resNoBody = new Response(null, { headers, status: 304 })
103+
let body = await val.text()
104+
let resp = new Response(body, { headers })
105+
headers.set('content-length', (body.length).toString())
80106
let cacheKey: CacheKey = {
81107
url: key.url,
82108
headers: {

packages/kv-asset-handler/src/test/getAssetFromKV.ts

+15
Original file line numberDiff line numberDiff line change
@@ -439,4 +439,19 @@ test('getAssetFromKV if-none-match not sent but resource in cache, should return
439439
}
440440
})
441441

442+
test('getAssetFromKV if range request submitted and resource in cache, request fulfilled', async t => {
443+
const resourceKey = 'cache.html'
444+
const event1 = getEvent(new Request(`https://blah.com/${resourceKey}`))
445+
const event2 = getEvent(new Request(`https://blah.com/${resourceKey}`, { headers: { 'range': 'bytes=0-10'}}))
446+
const res1 = await getAssetFromKV(event1, { cacheControl: { edgeTTL: 720 } })
447+
await res1
448+
await sleep(2)
449+
const res2 = await getAssetFromKV(event2)
450+
if (res2.headers.has('content-range')) {
451+
t.is(res2.status, 206)
452+
} else {
453+
t.fail('Response was undefined')
454+
}
455+
})
456+
442457
test.todo('getAssetFromKV when body not empty, should invoke .cancel()')

0 commit comments

Comments
 (0)