mirror of
https://github.com/protomaps/PMTiles.git
synced 2026-02-04 10:51:07 +00:00
@@ -5,6 +5,7 @@ import {
|
|||||||
} from "aws-lambda";
|
} from "aws-lambda";
|
||||||
import {
|
import {
|
||||||
Compression,
|
Compression,
|
||||||
|
EtagMismatch,
|
||||||
PMTiles,
|
PMTiles,
|
||||||
RangeResponse,
|
RangeResponse,
|
||||||
ResolvedValueCache,
|
ResolvedValueCache,
|
||||||
@@ -16,7 +17,11 @@ import { pmtiles_path, tileJSON, tile_path } from "../../shared/index";
|
|||||||
import { createHash } from "crypto";
|
import { createHash } from "crypto";
|
||||||
import zlib from "zlib";
|
import zlib from "zlib";
|
||||||
|
|
||||||
import { GetObjectCommand, S3Client } from "@aws-sdk/client-s3";
|
import {
|
||||||
|
GetObjectCommand,
|
||||||
|
GetObjectCommandOutput,
|
||||||
|
S3Client,
|
||||||
|
} from "@aws-sdk/client-s3";
|
||||||
import { NodeHttpHandler } from "@aws-sdk/node-http-handler";
|
import { NodeHttpHandler } from "@aws-sdk/node-http-handler";
|
||||||
|
|
||||||
// the region should default to the same one as the function
|
// the region should default to the same one as the function
|
||||||
@@ -60,7 +65,9 @@ class S3Source implements Source {
|
|||||||
signal?: AbortSignal,
|
signal?: AbortSignal,
|
||||||
etag?: string
|
etag?: string
|
||||||
): Promise<RangeResponse> {
|
): Promise<RangeResponse> {
|
||||||
const resp = await s3client.send(
|
let resp: GetObjectCommandOutput;
|
||||||
|
try {
|
||||||
|
resp = await s3client.send(
|
||||||
new GetObjectCommand({
|
new GetObjectCommand({
|
||||||
// biome-ignore lint: aws api
|
// biome-ignore lint: aws api
|
||||||
Bucket: process.env.BUCKET!,
|
Bucket: process.env.BUCKET!,
|
||||||
@@ -68,8 +75,16 @@ class S3Source implements Source {
|
|||||||
Key: pmtiles_path(this.archiveName, process.env.PMTILES_PATH),
|
Key: pmtiles_path(this.archiveName, process.env.PMTILES_PATH),
|
||||||
// biome-ignore lint: aws api
|
// biome-ignore lint: aws api
|
||||||
Range: "bytes=" + offset + "-" + (offset + length - 1),
|
Range: "bytes=" + offset + "-" + (offset + length - 1),
|
||||||
|
// biome-ignore lint: aws api
|
||||||
|
IfMatch: etag,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
} catch (e: unknown) {
|
||||||
|
if (e instanceof Error && (e as Error).name === "PreconditionFailed") {
|
||||||
|
throw new EtagMismatch();
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
const arr = await resp.Body?.transformToByteArray();
|
const arr = await resp.Body?.transformToByteArray();
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
Compression,
|
Compression,
|
||||||
|
EtagMismatch,
|
||||||
PMTiles,
|
PMTiles,
|
||||||
RangeResponse,
|
RangeResponse,
|
||||||
ResolvedValueCache,
|
ResolvedValueCache,
|
||||||
@@ -63,12 +64,19 @@ class R2Source implements Source {
|
|||||||
pmtiles_path(this.archiveName, this.env.PMTILES_PATH),
|
pmtiles_path(this.archiveName, this.env.PMTILES_PATH),
|
||||||
{
|
{
|
||||||
range: { offset: offset, length: length },
|
range: { offset: offset, length: length },
|
||||||
|
onlyIf: { etagMatches: etag },
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
if (!resp) {
|
if (!resp) {
|
||||||
throw new KeyNotFoundError("Archive not found");
|
throw new KeyNotFoundError("Archive not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
const o = resp as R2ObjectBody;
|
const o = resp as R2ObjectBody;
|
||||||
|
|
||||||
|
if (!o.body) {
|
||||||
|
throw new EtagMismatch();
|
||||||
|
}
|
||||||
|
|
||||||
const a = await o.arrayBuffer();
|
const a = await o.arrayBuffer();
|
||||||
return {
|
return {
|
||||||
data: a,
|
data: a,
|
||||||
|
|||||||
Reference in New Issue
Block a user