Skip to content

Commit 034f776

Browse files
authored
WIP: S3 improvements (#16167)
1 parent 8a469cc commit 034f776

21 files changed

+2974
-2673
lines changed

Diff for: src/bun.js/api/server.zig

+3-3
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ const linux = std.os.linux;
9090
const Async = bun.Async;
9191
const httplog = Output.scoped(.Server, false);
9292
const ctxLog = Output.scoped(.RequestContext, false);
93-
const AWS = @import("../../s3.zig").AWSCredentials;
93+
const S3 = bun.S3;
9494
const BlobFileContentResult = struct {
9595
data: [:0]const u8,
9696

@@ -3182,7 +3182,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
31823182
this.endWithoutBody(this.shouldCloseConnection());
31833183
this.deref();
31843184
}
3185-
pub fn onS3SizeResolved(result: AWS.S3StatResult, this: *RequestContext) void {
3185+
pub fn onS3SizeResolved(result: S3.S3StatResult, this: *RequestContext) void {
31863186
defer {
31873187
this.deref();
31883188
}
@@ -3254,7 +3254,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
32543254
const path = blob.store.?.data.s3.path();
32553255
const env = globalThis.bunVM().transpiler.env;
32563256

3257-
credentials.s3Stat(path, @ptrCast(&onS3SizeResolved), this, if (env.getHttpProxy(true, null)) |proxy| proxy.href else null);
3257+
S3.stat(credentials, path, @ptrCast(&onS3SizeResolved), this, if (env.getHttpProxy(true, null)) |proxy| proxy.href else null);
32583258

32593259
return;
32603260
}

Diff for: src/bun.js/bindings/JSS3Bucket.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ JSC_DECLARE_HOST_FUNCTION(functionS3Bucket_size);
3737

3838
static const HashTableValue JSS3BucketPrototypeTableValues[] = {
3939
{ "unlink"_s, static_cast<unsigned>(PropertyAttribute::Function | PropertyAttribute::ReadOnly), NoIntrinsic, { HashTableValue::NativeFunctionType, functionS3Bucket_unlink, 0 } },
40+
{ "delete"_s, static_cast<unsigned>(PropertyAttribute::Function | PropertyAttribute::ReadOnly), NoIntrinsic, { HashTableValue::NativeFunctionType, functionS3Bucket_unlink, 0 } },
4041
{ "write"_s, static_cast<unsigned>(PropertyAttribute::Function | PropertyAttribute::ReadOnly), NoIntrinsic, { HashTableValue::NativeFunctionType, functionS3Bucket_write, 1 } },
4142
{ "presign"_s, static_cast<unsigned>(PropertyAttribute::Function | PropertyAttribute::ReadOnly), NoIntrinsic, { HashTableValue::NativeFunctionType, functionS3Bucket_presign, 1 } },
4243
{ "exists"_s, static_cast<unsigned>(PropertyAttribute::Function | PropertyAttribute::ReadOnly), NoIntrinsic, { HashTableValue::NativeFunctionType, functionS3Bucket_exists, 1 } },

Diff for: src/bun.js/event_loop.zig

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ const ReadFileTask = WebCore.Blob.ReadFile.ReadFileTask;
1818
const WriteFileTask = WebCore.Blob.WriteFile.WriteFileTask;
1919
const napi_async_work = JSC.napi.napi_async_work;
2020
const FetchTasklet = Fetch.FetchTasklet;
21-
const AWS = @import("../s3.zig").AWSCredentials;
22-
const S3HttpSimpleTask = AWS.S3HttpSimpleTask;
23-
const S3HttpDownloadStreamingTask = AWS.S3HttpDownloadStreamingTask;
21+
const S3 = bun.S3;
22+
const S3HttpSimpleTask = S3.S3HttpSimpleTask;
23+
const S3HttpDownloadStreamingTask = S3.S3HttpDownloadStreamingTask;
2424

2525
const JSValue = JSC.JSValue;
2626
const js = JSC.C;

Diff for: src/bun.js/webcore/S3Bucket.zig

+12-12
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ const PathOrBlob = JSC.Node.PathOrBlob;
66
const ZigString = JSC.ZigString;
77
const Method = bun.http.Method;
88
const S3File = @import("./S3File.zig");
9-
const AWSCredentials = bun.AWSCredentials;
9+
const S3Credentials = bun.S3.S3Credentials;
1010

1111
const S3BucketOptions = struct {
12-
credentials: *AWSCredentials,
13-
options: bun.S3.MultiPartUpload.MultiPartUploadOptions = .{},
12+
credentials: *S3Credentials,
13+
options: bun.S3.MultiPartUploadOptions = .{},
1414
acl: ?bun.S3.ACL = null,
1515
pub usingnamespace bun.New(@This());
1616

@@ -20,7 +20,7 @@ const S3BucketOptions = struct {
2020
}
2121
};
2222

23-
pub fn writeFormatCredentials(credentials: *AWSCredentials, options: bun.S3.MultiPartUpload.MultiPartUploadOptions, acl: ?bun.S3.ACL, comptime Formatter: type, formatter: *Formatter, writer: anytype, comptime enable_ansi_colors: bool) !void {
23+
pub fn writeFormatCredentials(credentials: *S3Credentials, options: bun.S3.MultiPartUploadOptions, acl: ?bun.S3.ACL, comptime Formatter: type, formatter: *Formatter, writer: anytype, comptime enable_ansi_colors: bool) !void {
2424
try writer.writeAll("\n");
2525

2626
{
@@ -37,7 +37,7 @@ pub fn writeFormatCredentials(credentials: *AWSCredentials, options: bun.S3.Mult
3737
formatter.printComma(Writer, writer, enable_ansi_colors) catch bun.outOfMemory();
3838
try writer.writeAll("\n");
3939

40-
const region = if (credentials.region.len > 0) credentials.region else AWSCredentials.guessRegion(credentials.endpoint);
40+
const region = if (credentials.region.len > 0) credentials.region else S3Credentials.guessRegion(credentials.endpoint);
4141
try formatter.writeIndent(Writer, writer);
4242
try writer.writeAll(comptime bun.Output.prettyFmt("<r>region<d>:<r> \"", enable_ansi_colors));
4343
try writer.print(comptime bun.Output.prettyFmt("<r><b>{s}<r>\"", enable_ansi_colors), .{region});
@@ -133,7 +133,7 @@ pub fn call(ptr: *S3BucketOptions, globalThis: *JSC.JSGlobalObject, callframe: *
133133
};
134134
errdefer path.deinit();
135135
const options = args.nextEat();
136-
var blob = Blob.new(try S3File.constructS3FileWithAWSCredentialsAndOptions(globalThis, path, options, ptr.credentials, ptr.options, ptr.acl));
136+
var blob = Blob.new(try S3File.constructS3FileWithS3CredentialsAndOptions(globalThis, path, options, ptr.credentials, ptr.options, ptr.acl));
137137
blob.allocator = bun.default_allocator;
138138
return blob.toJS(globalThis);
139139
}
@@ -151,7 +151,7 @@ pub fn presign(ptr: *S3BucketOptions, globalThis: *JSC.JSGlobalObject, callframe
151151
errdefer path.deinit();
152152

153153
const options = args.nextEat();
154-
var blob = try S3File.constructS3FileWithAWSCredentialsAndOptions(globalThis, path, options, ptr.credentials, ptr.options, ptr.acl);
154+
var blob = try S3File.constructS3FileWithS3CredentialsAndOptions(globalThis, path, options, ptr.credentials, ptr.options, ptr.acl);
155155
defer blob.detach();
156156
return S3File.getPresignUrlFrom(&blob, globalThis, options);
157157
}
@@ -168,7 +168,7 @@ pub fn exists(ptr: *S3BucketOptions, globalThis: *JSC.JSGlobalObject, callframe:
168168
};
169169
errdefer path.deinit();
170170
const options = args.nextEat();
171-
var blob = try S3File.constructS3FileWithAWSCredentialsAndOptions(globalThis, path, options, ptr.credentials, ptr.options, ptr.acl);
171+
var blob = try S3File.constructS3FileWithS3CredentialsAndOptions(globalThis, path, options, ptr.credentials, ptr.options, ptr.acl);
172172
defer blob.detach();
173173
return S3File.S3BlobStatTask.exists(globalThis, &blob);
174174
}
@@ -185,7 +185,7 @@ pub fn size(ptr: *S3BucketOptions, globalThis: *JSC.JSGlobalObject, callframe: *
185185
};
186186
errdefer path.deinit();
187187
const options = args.nextEat();
188-
var blob = try S3File.constructS3FileWithAWSCredentialsAndOptions(globalThis, path, options, ptr.credentials, ptr.options, ptr.acl);
188+
var blob = try S3File.constructS3FileWithS3CredentialsAndOptions(globalThis, path, options, ptr.credentials, ptr.options, ptr.acl);
189189
defer blob.detach();
190190
return S3File.S3BlobStatTask.size(globalThis, &blob);
191191
}
@@ -203,7 +203,7 @@ pub fn write(ptr: *S3BucketOptions, globalThis: *JSC.JSGlobalObject, callframe:
203203
};
204204

205205
const options = args.nextEat();
206-
var blob = try S3File.constructS3FileWithAWSCredentialsAndOptions(globalThis, path, options, ptr.credentials, ptr.options, ptr.acl);
206+
var blob = try S3File.constructS3FileWithS3CredentialsAndOptions(globalThis, path, options, ptr.credentials, ptr.options, ptr.acl);
207207
defer blob.detach();
208208
var blob_internal: PathOrBlob = .{ .blob = blob };
209209
return Blob.writeFileInternal(globalThis, &blob_internal, data, .{
@@ -221,7 +221,7 @@ pub fn unlink(ptr: *S3BucketOptions, globalThis: *JSC.JSGlobalObject, callframe:
221221
};
222222
errdefer path.deinit();
223223
const options = args.nextEat();
224-
var blob = try S3File.constructS3FileWithAWSCredentialsAndOptions(globalThis, path, options, ptr.credentials, ptr.options, ptr.acl);
224+
var blob = try S3File.constructS3FileWithS3CredentialsAndOptions(globalThis, path, options, ptr.credentials, ptr.options, ptr.acl);
225225
defer blob.detach();
226226
return blob.store.?.data.s3.unlink(blob.store.?, globalThis, options);
227227
}
@@ -235,7 +235,7 @@ pub fn construct(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) cal
235235
if (options.isEmptyOrUndefinedOrNull() or !options.isObject()) {
236236
globalThis.throwInvalidArguments("Expected S3 options to be passed", .{}) catch return null;
237237
}
238-
var aws_options = AWSCredentials.getCredentialsWithOptions(globalThis.bunVM().transpiler.env.getAWSCredentials(), .{}, options, null, globalThis) catch return null;
238+
var aws_options = S3Credentials.getCredentialsWithOptions(globalThis.bunVM().transpiler.env.getS3Credentials(), .{}, options, null, globalThis) catch return null;
239239
defer aws_options.deinit();
240240
return S3BucketOptions.new(.{
241241
.credentials = aws_options.credentials.dupe(),

Diff for: src/bun.js/webcore/S3File.zig

+16-17
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const Method = bun.http.Method;
88
const strings = bun.strings;
99
const Output = bun.Output;
1010
const S3Bucket = @import("./S3Bucket.zig");
11+
const S3 = bun.S3;
1112

1213
pub fn writeFormat(s3: *Blob.S3Store, comptime Formatter: type, formatter: *Formatter, writer: anytype, comptime enable_ansi_colors: bool) !void {
1314
try writer.writeAll(comptime Output.prettyFmt("<r>S3Ref<r>", enable_ansi_colors));
@@ -214,19 +215,19 @@ fn constructS3FileInternalStore(
214215
options: ?JSC.JSValue,
215216
) bun.JSError!Blob {
216217
// get credentials from env
217-
const existing_credentials = globalObject.bunVM().transpiler.env.getAWSCredentials();
218-
return constructS3FileWithAWSCredentials(globalObject, path, options, existing_credentials);
218+
const existing_credentials = globalObject.bunVM().transpiler.env.getS3Credentials();
219+
return constructS3FileWithS3Credentials(globalObject, path, options, existing_credentials);
219220
}
220221
/// if the credentials have changed, we need to clone it, if not we can just ref/deref it
221-
pub fn constructS3FileWithAWSCredentialsAndOptions(
222+
pub fn constructS3FileWithS3CredentialsAndOptions(
222223
globalObject: *JSC.JSGlobalObject,
223224
path: JSC.Node.PathLike,
224225
options: ?JSC.JSValue,
225-
default_credentials: *AWS,
226-
default_options: bun.S3.MultiPartUpload.MultiPartUploadOptions,
226+
default_credentials: *S3.S3Credentials,
227+
default_options: bun.S3.MultiPartUploadOptions,
227228
default_acl: ?bun.S3.ACL,
228229
) bun.JSError!Blob {
229-
var aws_options = try AWS.getCredentialsWithOptions(default_credentials.*, default_options, options, default_acl, globalObject);
230+
var aws_options = try S3.S3Credentials.getCredentialsWithOptions(default_credentials.*, default_options, options, default_acl, globalObject);
230231
defer aws_options.deinit();
231232

232233
const store = brk: {
@@ -268,13 +269,13 @@ pub fn constructS3FileWithAWSCredentialsAndOptions(
268269
return blob;
269270
}
270271

271-
pub fn constructS3FileWithAWSCredentials(
272+
pub fn constructS3FileWithS3Credentials(
272273
globalObject: *JSC.JSGlobalObject,
273274
path: JSC.Node.PathLike,
274275
options: ?JSC.JSValue,
275-
existing_credentials: AWS,
276+
existing_credentials: S3.S3Credentials,
276277
) bun.JSError!Blob {
277-
var aws_options = try AWS.getCredentialsWithOptions(existing_credentials, .{}, options, null, globalObject);
278+
var aws_options = try S3.S3Credentials.getCredentialsWithOptions(existing_credentials, .{}, options, null, globalObject);
278279
defer aws_options.deinit();
279280
const store = Blob.Store.initS3(path, null, aws_options.credentials, bun.default_allocator) catch bun.outOfMemory();
280281
errdefer store.deinit();
@@ -318,14 +319,12 @@ fn constructS3FileInternal(
318319
return ptr;
319320
}
320321

321-
const AWS = bun.S3.AWSCredentials;
322-
323322
pub const S3BlobStatTask = struct {
324323
promise: JSC.JSPromise.Strong,
325324
store: *Blob.Store,
326325
usingnamespace bun.New(S3BlobStatTask);
327326

328-
pub fn onS3ExistsResolved(result: AWS.S3StatResult, this: *S3BlobStatTask) void {
327+
pub fn onS3ExistsResolved(result: S3.S3StatResult, this: *S3BlobStatTask) void {
329328
defer this.deinit();
330329
const globalThis = this.promise.globalObject().?;
331330
switch (result) {
@@ -346,7 +345,7 @@ pub const S3BlobStatTask = struct {
346345
}
347346
}
348347

349-
pub fn onS3SizeResolved(result: AWS.S3StatResult, this: *S3BlobStatTask) void {
348+
pub fn onS3SizeResolved(result: S3.S3StatResult, this: *S3BlobStatTask) void {
350349
defer this.deinit();
351350
const globalThis = this.promise.globalObject().?;
352351

@@ -371,7 +370,7 @@ pub const S3BlobStatTask = struct {
371370
const path = blob.store.?.data.s3.path();
372371
const env = globalThis.bunVM().transpiler.env;
373372

374-
credentials.s3Stat(path, @ptrCast(&S3BlobStatTask.onS3ExistsResolved), this, if (env.getHttpProxy(true, null)) |proxy| proxy.href else null);
373+
S3.stat(credentials, path, @ptrCast(&S3BlobStatTask.onS3ExistsResolved), this, if (env.getHttpProxy(true, null)) |proxy| proxy.href else null);
375374
return promise;
376375
}
377376

@@ -386,7 +385,7 @@ pub const S3BlobStatTask = struct {
386385
const path = blob.store.?.data.s3.path();
387386
const env = globalThis.bunVM().transpiler.env;
388387

389-
credentials.s3Stat(path, @ptrCast(&S3BlobStatTask.onS3SizeResolved), this, if (env.getHttpProxy(true, null)) |proxy| proxy.href else null);
388+
S3.stat(credentials, path, @ptrCast(&S3BlobStatTask.onS3SizeResolved), this, if (env.getHttpProxy(true, null)) |proxy| proxy.href else null);
390389
return promise;
391390
}
392391

@@ -405,7 +404,7 @@ pub fn getPresignUrlFrom(this: *Blob, globalThis: *JSC.JSGlobalObject, extra_opt
405404
var method: bun.http.Method = .GET;
406405
var expires: usize = 86400; // 1 day default
407406

408-
var credentialsWithOptions: AWS.AWSCredentialsWithOptions = .{
407+
var credentialsWithOptions: S3.S3CredentialsWithOptions = .{
409408
.credentials = this.store.?.data.s3.getCredentials().*,
410409
};
411410
defer {
@@ -434,7 +433,7 @@ pub fn getPresignUrlFrom(this: *Blob, globalThis: *JSC.JSGlobalObject, extra_opt
434433
.method = method,
435434
.acl = credentialsWithOptions.acl,
436435
}, .{ .expires = expires }) catch |sign_err| {
437-
return AWS.throwSignError(sign_err, globalThis);
436+
return S3.throwSignError(sign_err, globalThis);
438437
};
439438
defer result.deinit();
440439
var str = bun.String.fromUTF8(result.url);

0 commit comments

Comments
 (0)