diff options
author | 2023-02-15 19:20:40 -0300 | |
---|---|---|
committer | 2023-02-15 14:20:40 -0800 | |
commit | 597053ea91a83ed0ce98bf1b8bb59fbf282c3619 (patch) | |
tree | 51141e81e587d8ce747fe81fb6064f5740d5bc40 /src | |
parent | 1c221d33b0def3810c262bd19a4bf8060389dae0 (diff) | |
download | bun-597053ea91a83ed0ce98bf1b8bb59fbf282c3619.tar.gz bun-597053ea91a83ed0ce98bf1b8bb59fbf282c3619.tar.zst bun-597053ea91a83ed0ce98bf1b8bb59fbf282c3619.zip |
feat(fetch) AbortSignal (#2019)
* add fetch abort signal
* get aborted (still segfaults)
* bidings.zig u0 error
* still GC/memory error
* fix start crash
* fix AbortSignal fromJS
* change fromJS to obj.as
* addAbortSignalEventListenner
* handle abort types, and add tests
* fix tests
* add custom reason test
* merge 2 substring methods, use MAKE_STATIC_STRING_IMPL
* fix create AbortError and TimeoutError, move globalThis and exception creation to main thread
* fix tests and rebuild headers
* no need to check with substring reason is already an exception
* no need to check with substring reason is already an exception
* fix dumb error inverting conditions for check reason
* fix custom reason behavior
Diffstat (limited to 'src')
-rw-r--r-- | src/bun.js/bindings/ZigGlobalObject.cpp | 2 | ||||
-rw-r--r-- | src/bun.js/bindings/bindings.cpp | 97 | ||||
-rw-r--r-- | src/bun.js/bindings/bindings.zig | 79 | ||||
-rw-r--r-- | src/bun.js/bindings/headers-cpp.h | 16 | ||||
-rw-r--r-- | src/bun.js/bindings/headers.h | 17 | ||||
-rw-r--r-- | src/bun.js/bindings/headers.zig | 9 | ||||
-rw-r--r-- | src/bun.js/bindings/sizes.zig | 2 | ||||
-rw-r--r-- | src/bun.js/bindings/webcore/AbortSignal.cpp | 6 | ||||
-rw-r--r-- | src/bun.js/bindings/webcore/AbortSignal.h | 2 | ||||
-rw-r--r-- | src/bun.js/event_loop.zig | 1 | ||||
-rw-r--r-- | src/bun.js/javascript.zig | 2 | ||||
-rw-r--r-- | src/bun.js/webcore/response.zig | 45 | ||||
-rw-r--r-- | src/bundler.zig | 2 | ||||
-rw-r--r-- | src/http_client_async.zig | 156 | ||||
-rw-r--r-- | src/install/install.zig | 4 | ||||
-rw-r--r-- | src/string_immutable.zig | 1 |
16 files changed, 383 insertions, 58 deletions
diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp index 0f4fe92e2..8fd9f366a 100644 --- a/src/bun.js/bindings/ZigGlobalObject.cpp +++ b/src/bun.js/bindings/ZigGlobalObject.cpp @@ -1533,7 +1533,7 @@ JSC_DEFINE_HOST_FUNCTION(whenSignalAborted, (JSGlobalObject * globalObject, Call Ref<AbortAlgorithm> abortAlgorithm = JSAbortAlgorithm::create(vm, callFrame->uncheckedArgument(1).getObject()); - bool result = AbortSignal::whenSignalAborted(abortSignal->wrapped(), WTFMove(abortAlgorithm)); + bool result = WebCore::AbortSignal::whenSignalAborted(abortSignal->wrapped(), WTFMove(abortAlgorithm)); return JSValue::encode(result ? JSValue(JSC::JSValue::JSTrue) : JSValue(JSC::JSValue::JSFalse)); } diff --git a/src/bun.js/bindings/bindings.cpp b/src/bun.js/bindings/bindings.cpp index aa8a28601..4b614788d 100644 --- a/src/bun.js/bindings/bindings.cpp +++ b/src/bun.js/bindings/bindings.cpp @@ -84,6 +84,8 @@ #include "JavaScriptCore/PropertyNameArray.h" #include "JavaScriptCore/HashMapImpl.h" #include "JavaScriptCore/HashMapImplInlines.h" +#include "webcore/JSAbortSignal.h" +#include "JSAbortAlgorithm.h" #include "DOMFormData.h" #include "JSDOMFormData.h" @@ -3732,6 +3734,101 @@ extern "C" void JSC__JSGlobalObject__queueMicrotaskJob(JSC__JSGlobalObject* arg0 JSC::JSValue::decode(JSValue4)); } +extern "C" JSC__AbortSignal* JSC__AbortSignal__signal(JSC__AbortSignal* arg0, JSC__JSValue JSValue1) { + WebCore::AbortSignal* abortSignal = reinterpret_cast<WebCore::AbortSignal*>(arg0); + abortSignal->signalAbort(JSC::JSValue::decode(JSValue1)); + return arg0; +} + +extern "C" bool JSC__AbortSignal__aborted(JSC__AbortSignal* arg0) { + WebCore::AbortSignal* abortSignal = reinterpret_cast<WebCore::AbortSignal*>(arg0); + return abortSignal->aborted(); +} + +extern "C" JSC__JSValue JSC__AbortSignal__abortReason(JSC__AbortSignal* arg0) { + WebCore::AbortSignal* abortSignal = reinterpret_cast<WebCore::AbortSignal*>(arg0); + return JSC::JSValue::encode(abortSignal->reason().getValue()); +} + + +extern "C" JSC__AbortSignal* JSC__AbortSignal__ref(JSC__AbortSignal* arg0) { + WebCore::AbortSignal* abortSignal = reinterpret_cast<WebCore::AbortSignal*>(arg0); + abortSignal->ref(); + return arg0; +} + +extern "C" JSC__AbortSignal* JSC__AbortSignal__unref(JSC__AbortSignal* arg0) { + WebCore::AbortSignal* abortSignal = reinterpret_cast<WebCore::AbortSignal*>(arg0); + abortSignal->deref(); + return arg0; +} + +extern "C" JSC__AbortSignal* JSC__AbortSignal__addListener(JSC__AbortSignal* arg0, void* ctx, void (*callback)(void* ctx, JSC__JSValue reason)) { + WebCore::AbortSignal* abortSignal = reinterpret_cast<WebCore::AbortSignal*>(arg0); + + if(abortSignal->aborted()){ + callback(ctx, JSC::JSValue::encode(abortSignal->reason().getValue())); + return arg0; + } + + abortSignal->addNativeCallback(std::make_tuple(ctx, callback)); + + return arg0; +} +extern "C" JSC__AbortSignal* JSC__AbortSignal__fromJS(JSC__JSValue value) +{ + JSC::JSValue decodedValue = JSC::JSValue::decode(value); + if (decodedValue.isEmpty()) + return nullptr; + WebCore::JSAbortSignal* object = JSC::jsDynamicCast<WebCore::JSAbortSignal*>(decodedValue); + if (!object) + return nullptr; + + return reinterpret_cast<JSC__AbortSignal*>(&object->wrapped()); +} +static auto ABORT_ERROR_NAME = MAKE_STATIC_STRING_IMPL("AbortError"); +extern "C" JSC__JSValue JSC__AbortSignal__createAbortError(const ZigString* message, const ZigString* arg1, + JSC__JSGlobalObject* globalObject) +{ + JSC::VM& vm = globalObject->vm(); + ZigString code = *arg1; + JSC::JSObject* error = Zig::getErrorInstance(message, globalObject).asCell()->getObject(); + + error->putDirect( + vm, vm.propertyNames->name, + JSC::JSValue(JSC::jsOwnedString(vm, ABORT_ERROR_NAME)), + 0); + + if (code.len > 0) { + auto clientData = WebCore::clientData(vm); + JSC::JSValue codeValue = Zig::toJSStringValue(code, globalObject); + error->putDirect(vm, clientData->builtinNames().codePublicName(), codeValue, 0); + } + + return JSC::JSValue::encode(error); +} + +static auto TIMEOUT_ERROR_NAME = MAKE_STATIC_STRING_IMPL("TimeoutError"); +extern "C" JSC__JSValue JSC__AbortSignal__createTimeoutError(const ZigString* message, const ZigString* arg1, + JSC__JSGlobalObject* globalObject) +{ + JSC::VM& vm = globalObject->vm(); + ZigString code = *arg1; + JSC::JSObject* error = Zig::getErrorInstance(message, globalObject).asCell()->getObject(); + + error->putDirect( + vm, vm.propertyNames->name, + JSC::JSValue(JSC::jsOwnedString(vm, TIMEOUT_ERROR_NAME)), + 0); + + if (code.len > 0) { + auto clientData = WebCore::clientData(vm); + JSC::JSValue codeValue = Zig::toJSStringValue(code, globalObject); + error->putDirect(vm, clientData->builtinNames().codePublicName(), codeValue, 0); + } + + return JSC::JSValue::encode(error); +} #pragma mark - WebCore::DOMFormData CPP_DECL void WebCore__DOMFormData__append(WebCore__DOMFormData* arg0, ZigString* arg1, ZigString* arg2) diff --git a/src/bun.js/bindings/bindings.zig b/src/bun.js/bindings/bindings.zig index 4c1469564..6b5386a68 100644 --- a/src/bun.js/bindings/bindings.zig +++ b/src/bun.js/bindings/bindings.zig @@ -209,12 +209,19 @@ pub const ZigString = extern struct { return ZigString__toJSONObject(&this, globalThis); } - pub fn substring(this: ZigString, offset: usize) ZigString { + pub fn substring(this: ZigString, offset: usize, maxlen: usize) ZigString { + var len: usize = undefined; + if(maxlen == 0){ + len = this.len; + }else { + len = @max(this.len, maxlen); + } + if (this.is16Bit()) { - return ZigString.from16Slice(this.utf16SliceAligned()[@min(this.len, offset)..]); + return ZigString.from16Slice(this.utf16SliceAligned()[@min(this.len, offset)..len]); } - var out = ZigString.init(this.slice()[@min(this.len, offset)..]); + var out = ZigString.init(this.slice()[@min(this.len, offset)..len]); if (this.isUTF8()) { out.markUTF8(); } @@ -1662,6 +1669,72 @@ pub fn PromiseCallback(comptime Type: type, comptime CallbackFunction: fn (*Type }.callback; } +pub const AbortSignal = extern opaque { + pub const shim = Shimmer("JSC", "AbortSignal", @This()); + const cppFn = shim.cppFn; + pub const include = "WebCore/AbortSignal.h"; + pub const name = "JSC::AbortSignal"; + pub const namespace = "JSC"; + + pub fn addListener( + this: *AbortSignal, + ctx: ?*anyopaque, + callback: *const fn (?*anyopaque, JSValue) callconv(.C) void, + ) *AbortSignal { + return cppFn("addListener", .{ this, ctx, callback }); + } + pub fn signal( + this: *AbortSignal, + reason: JSValue, + ) *AbortSignal { + return cppFn("signal", .{ this, reason }); + } + + pub fn aborted(this: *AbortSignal) bool { + return cppFn("aborted", .{this}); + } + + pub fn abortReason(this: *AbortSignal) JSValue { + return cppFn("abortReason", .{this}); + } + + pub fn ref( + this: *AbortSignal, + ) *AbortSignal { + return cppFn("ref", .{this}); + } + + pub fn unref( + this: *AbortSignal, + ) *AbortSignal { + return cppFn("unref", .{this}); + } + + pub fn fromJS(value: JSValue) ?*AbortSignal { + return cppFn("fromJS", .{value}); + } + + pub fn createAbortError(message: *const ZigString, code: *const ZigString, global: *JSGlobalObject) JSValue { + return cppFn("createAbortError", .{ message, code, global }); + } + + pub fn createTimeoutError(message: *const ZigString, code: *const ZigString, global: *JSGlobalObject) JSValue { + return cppFn("createTimeoutError", .{ message, code, global }); + } + + pub const Extern = [_][]const u8{ + "createAbortError", + "createTimeoutError", + "ref", + "unref", + "signal", + "abortReason", + "aborted", + "addListener", + "fromJS", + }; +}; + pub const JSPromise = extern struct { pub const shim = Shimmer("JSC", "JSPromise", @This()); bytes: shim.Bytes, diff --git a/src/bun.js/bindings/headers-cpp.h b/src/bun.js/bindings/headers-cpp.h index 4dc7a2143..d0abc7db0 100644 --- a/src/bun.js/bindings/headers-cpp.h +++ b/src/bun.js/bindings/headers-cpp.h @@ -1,4 +1,4 @@ -//-- AUTOGENERATED FILE -- 1676266700 +//-- AUTOGENERATED FILE -- 1676470760 // clang-format off #pragma once @@ -56,6 +56,14 @@ extern "C" const size_t JSC__JSString_object_align_ = alignof(JSC::JSString); extern "C" const size_t JSC__JSModuleLoader_object_size_ = sizeof(JSC::JSModuleLoader); extern "C" const size_t JSC__JSModuleLoader_object_align_ = alignof(JSC::JSModuleLoader); +#ifndef INCLUDED_WebCore_AbortSignal_h +#define INCLUDED_WebCore_AbortSignal_h +#include "WebCore/AbortSignal.h" +#endif + +extern "C" const size_t JSC__AbortSignal_object_size_ = sizeof(JSC::AbortSignal); +extern "C" const size_t JSC__AbortSignal_object_align_ = alignof(JSC::AbortSignal); + #ifndef INCLUDED_JavaScriptCore_JSPromise_h #define INCLUDED_JavaScriptCore_JSPromise_h #include "JavaScriptCore/JSPromise.h" @@ -160,8 +168,8 @@ extern "C" const size_t Zig__ConsoleClient_object_align_ = alignof(Zig::ConsoleC extern "C" const size_t Bun__Timer_object_size_ = sizeof(Bun__Timer); extern "C" const size_t Bun__Timer_object_align_ = alignof(Bun__Timer); -const size_t sizes[39] = {sizeof(JSC::JSObject), sizeof(WebCore::DOMURL), sizeof(WebCore::DOMFormData), sizeof(WebCore::FetchHeaders), sizeof(SystemError), sizeof(JSC::JSCell), sizeof(JSC::JSString), sizeof(JSC::JSModuleLoader), sizeof(JSC::JSPromise), sizeof(JSC::JSInternalPromise), sizeof(JSC::JSFunction), sizeof(JSC::JSGlobalObject), sizeof(JSC::JSValue), sizeof(JSC::Exception), sizeof(JSC::VM), sizeof(JSC::ThrowScope), sizeof(JSC::CatchScope), sizeof(FFI__ptr), sizeof(Reader__u8), sizeof(Reader__u16), sizeof(Reader__u32), sizeof(Reader__ptr), sizeof(Reader__i8), sizeof(Reader__i16), sizeof(Reader__i32), sizeof(Reader__f32), sizeof(Reader__f64), sizeof(Reader__i64), sizeof(Reader__u64), sizeof(Reader__intptr), sizeof(Crypto__getRandomValues), sizeof(Crypto__randomUUID), sizeof(Crypto__timingSafeEqual), sizeof(Zig::GlobalObject), sizeof(Bun__Path), sizeof(ArrayBufferSink), sizeof(HTTPSResponseSink), sizeof(HTTPResponseSink), sizeof(FileSink)}; +const size_t sizes[40] = {sizeof(JSC::JSObject), sizeof(WebCore::DOMURL), sizeof(WebCore::DOMFormData), sizeof(WebCore::FetchHeaders), sizeof(SystemError), sizeof(JSC::JSCell), sizeof(JSC::JSString), sizeof(JSC::JSModuleLoader), sizeof(JSC::AbortSignal), sizeof(JSC::JSPromise), sizeof(JSC::JSInternalPromise), sizeof(JSC::JSFunction), sizeof(JSC::JSGlobalObject), sizeof(JSC::JSValue), sizeof(JSC::Exception), sizeof(JSC::VM), sizeof(JSC::ThrowScope), sizeof(JSC::CatchScope), sizeof(FFI__ptr), sizeof(Reader__u8), sizeof(Reader__u16), sizeof(Reader__u32), sizeof(Reader__ptr), sizeof(Reader__i8), sizeof(Reader__i16), sizeof(Reader__i32), sizeof(Reader__f32), sizeof(Reader__f64), sizeof(Reader__i64), sizeof(Reader__u64), sizeof(Reader__intptr), sizeof(Crypto__getRandomValues), sizeof(Crypto__randomUUID), sizeof(Crypto__timingSafeEqual), sizeof(Zig::GlobalObject), sizeof(Bun__Path), sizeof(ArrayBufferSink), sizeof(HTTPSResponseSink), sizeof(HTTPResponseSink), sizeof(FileSink)}; -const char* names[39] = {"JSC__JSObject", "WebCore__DOMURL", "WebCore__DOMFormData", "WebCore__FetchHeaders", "SystemError", "JSC__JSCell", "JSC__JSString", "JSC__JSModuleLoader", "JSC__JSPromise", "JSC__JSInternalPromise", "JSC__JSFunction", "JSC__JSGlobalObject", "JSC__JSValue", "JSC__Exception", "JSC__VM", "JSC__ThrowScope", "JSC__CatchScope", "FFI__ptr", "Reader__u8", "Reader__u16", "Reader__u32", "Reader__ptr", "Reader__i8", "Reader__i16", "Reader__i32", "Reader__f32", "Reader__f64", "Reader__i64", "Reader__u64", "Reader__intptr", "Crypto__getRandomValues", "Crypto__randomUUID", "Crypto__timingSafeEqual", "Zig__GlobalObject", "Bun__Path", "ArrayBufferSink", "HTTPSResponseSink", "HTTPResponseSink", "FileSink"}; +const char* names[40] = {"JSC__JSObject", "WebCore__DOMURL", "WebCore__DOMFormData", "WebCore__FetchHeaders", "SystemError", "JSC__JSCell", "JSC__JSString", "JSC__JSModuleLoader", "JSC__AbortSignal", "JSC__JSPromise", "JSC__JSInternalPromise", "JSC__JSFunction", "JSC__JSGlobalObject", "JSC__JSValue", "JSC__Exception", "JSC__VM", "JSC__ThrowScope", "JSC__CatchScope", "FFI__ptr", "Reader__u8", "Reader__u16", "Reader__u32", "Reader__ptr", "Reader__i8", "Reader__i16", "Reader__i32", "Reader__f32", "Reader__f64", "Reader__i64", "Reader__u64", "Reader__intptr", "Crypto__getRandomValues", "Crypto__randomUUID", "Crypto__timingSafeEqual", "Zig__GlobalObject", "Bun__Path", "ArrayBufferSink", "HTTPSResponseSink", "HTTPResponseSink", "FileSink"}; -const size_t aligns[39] = {alignof(JSC::JSObject), alignof(WebCore::DOMURL), alignof(WebCore::DOMFormData), alignof(WebCore::FetchHeaders), alignof(SystemError), alignof(JSC::JSCell), alignof(JSC::JSString), alignof(JSC::JSModuleLoader), alignof(JSC::JSPromise), alignof(JSC::JSInternalPromise), alignof(JSC::JSFunction), alignof(JSC::JSGlobalObject), alignof(JSC::JSValue), alignof(JSC::Exception), alignof(JSC::VM), alignof(JSC::ThrowScope), alignof(JSC::CatchScope), alignof(FFI__ptr), alignof(Reader__u8), alignof(Reader__u16), alignof(Reader__u32), alignof(Reader__ptr), alignof(Reader__i8), alignof(Reader__i16), alignof(Reader__i32), alignof(Reader__f32), alignof(Reader__f64), alignof(Reader__i64), alignof(Reader__u64), alignof(Reader__intptr), alignof(Crypto__getRandomValues), alignof(Crypto__randomUUID), alignof(Crypto__timingSafeEqual), alignof(Zig::GlobalObject), alignof(Bun__Path), alignof(ArrayBufferSink), alignof(HTTPSResponseSink), alignof(HTTPResponseSink), alignof(FileSink)}; +const size_t aligns[40] = {alignof(JSC::JSObject), alignof(WebCore::DOMURL), alignof(WebCore::DOMFormData), alignof(WebCore::FetchHeaders), alignof(SystemError), alignof(JSC::JSCell), alignof(JSC::JSString), alignof(JSC::JSModuleLoader), alignof(JSC::AbortSignal), alignof(JSC::JSPromise), alignof(JSC::JSInternalPromise), alignof(JSC::JSFunction), alignof(JSC::JSGlobalObject), alignof(JSC::JSValue), alignof(JSC::Exception), alignof(JSC::VM), alignof(JSC::ThrowScope), alignof(JSC::CatchScope), alignof(FFI__ptr), alignof(Reader__u8), alignof(Reader__u16), alignof(Reader__u32), alignof(Reader__ptr), alignof(Reader__i8), alignof(Reader__i16), alignof(Reader__i32), alignof(Reader__f32), alignof(Reader__f64), alignof(Reader__i64), alignof(Reader__u64), alignof(Reader__intptr), alignof(Crypto__getRandomValues), alignof(Crypto__randomUUID), alignof(Crypto__timingSafeEqual), alignof(Zig::GlobalObject), alignof(Bun__Path), alignof(ArrayBufferSink), alignof(HTTPSResponseSink), alignof(HTTPResponseSink), alignof(FileSink)}; diff --git a/src/bun.js/bindings/headers.h b/src/bun.js/bindings/headers.h index 159a7acbd..59450ecf1 100644 --- a/src/bun.js/bindings/headers.h +++ b/src/bun.js/bindings/headers.h @@ -1,5 +1,5 @@ // clang-format off -//-- AUTOGENERATED FILE -- 1676266700 +//-- AUTOGENERATED FILE -- 1676470760 #pragma once #include <stddef.h> @@ -55,6 +55,7 @@ typedef void* JSClassRef; typedef bJSC__JSObject JSC__JSObject; // JSC::JSObject typedef WebSocketClient WebSocketClient; typedef WebSocketHTTPSClient WebSocketHTTPSClient; + typedef struct JSC__AbortSignal JSC__AbortSignal; // JSC::AbortSignal typedef JSClassRef JSClassRef; typedef bJSC__VM JSC__VM; // JSC::VM typedef Bun__ArrayBuffer Bun__ArrayBuffer; @@ -85,6 +86,7 @@ typedef void* JSClassRef; class JSGlobalObject; class JSPromise; class Exception; + class AbortSignal; class JSString; class JSInternalPromise; class CatchScope; @@ -116,6 +118,7 @@ typedef void* JSClassRef; using JSC__JSGlobalObject = JSC::JSGlobalObject; using JSC__JSPromise = JSC::JSPromise; using JSC__Exception = JSC::Exception; + using JSC__AbortSignal = JSC::AbortSignal; using JSC__JSString = JSC::JSString; using JSC__JSInternalPromise = JSC::JSInternalPromise; using JSC__CatchScope = JSC::CatchScope; @@ -202,6 +205,18 @@ CPP_DECL void JSC__JSString__toZigString(JSC__JSString* arg0, JSC__JSGlobalObjec CPP_DECL JSC__JSValue JSC__JSModuleLoader__evaluate(JSC__JSGlobalObject* arg0, const unsigned char* arg1, size_t arg2, const unsigned char* arg3, size_t arg4, const unsigned char* arg5, size_t arg6, JSC__JSValue JSValue7, JSC__JSValue* arg8); CPP_DECL JSC__JSInternalPromise* JSC__JSModuleLoader__loadAndEvaluateModule(JSC__JSGlobalObject* arg0, const ZigString* arg1); +#pragma mark - JSC::AbortSignal + +CPP_DECL bool JSC__AbortSignal__aborted(JSC__AbortSignal* arg0); +CPP_DECL JSC__JSValue JSC__AbortSignal__abortReason(JSC__AbortSignal* arg0); +CPP_DECL JSC__AbortSignal* JSC__AbortSignal__addListener(JSC__AbortSignal* arg0, void* arg1, void(* ArgFn2)(void* arg0, JSC__JSValue JSValue1)) __attribute__((nonnull (2))); +CPP_DECL JSC__JSValue JSC__AbortSignal__createAbortError(const ZigString* arg0, const ZigString* arg1, JSC__JSGlobalObject* arg2); +CPP_DECL JSC__JSValue JSC__AbortSignal__createTimeoutError(const ZigString* arg0, const ZigString* arg1, JSC__JSGlobalObject* arg2); +CPP_DECL JSC__AbortSignal* JSC__AbortSignal__fromJS(JSC__JSValue JSValue0); +CPP_DECL JSC__AbortSignal* JSC__AbortSignal__ref(JSC__AbortSignal* arg0); +CPP_DECL JSC__AbortSignal* JSC__AbortSignal__signal(JSC__AbortSignal* arg0, JSC__JSValue JSValue1); +CPP_DECL JSC__AbortSignal* JSC__AbortSignal__unref(JSC__AbortSignal* arg0); + #pragma mark - JSC::JSPromise CPP_DECL JSC__JSValue JSC__JSPromise__asValue(JSC__JSPromise* arg0, JSC__JSGlobalObject* arg1); diff --git a/src/bun.js/bindings/headers.zig b/src/bun.js/bindings/headers.zig index 756a08bcc..9f2e1580d 100644 --- a/src/bun.js/bindings/headers.zig +++ b/src/bun.js/bindings/headers.zig @@ -135,6 +135,15 @@ pub extern fn JSC__JSString__toObject(arg0: [*c]bindings.JSString, arg1: *bindin pub extern fn JSC__JSString__toZigString(arg0: [*c]bindings.JSString, arg1: *bindings.JSGlobalObject, arg2: [*c]ZigString) void; pub extern fn JSC__JSModuleLoader__evaluate(arg0: *bindings.JSGlobalObject, arg1: [*c]const u8, arg2: usize, arg3: [*c]const u8, arg4: usize, arg5: [*c]const u8, arg6: usize, JSValue7: JSC__JSValue, arg8: [*c]bindings.JSValue) JSC__JSValue; pub extern fn JSC__JSModuleLoader__loadAndEvaluateModule(arg0: *bindings.JSGlobalObject, arg1: [*c]const ZigString) [*c]bindings.JSInternalPromise; +pub extern fn JSC__AbortSignal__aborted(arg0: ?*bindings.AbortSignal) bool; +pub extern fn JSC__AbortSignal__abortReason(arg0: ?*bindings.AbortSignal) JSC__JSValue; +pub extern fn JSC__AbortSignal__addListener(arg0: ?*bindings.AbortSignal, arg1: ?*anyopaque, ArgFn2: ?*const fn (?*anyopaque, JSC__JSValue) callconv(.C) void) ?*bindings.AbortSignal; +pub extern fn JSC__AbortSignal__createAbortError(arg0: [*c]const ZigString, arg1: [*c]const ZigString, arg2: *bindings.JSGlobalObject) JSC__JSValue; +pub extern fn JSC__AbortSignal__createTimeoutError(arg0: [*c]const ZigString, arg1: [*c]const ZigString, arg2: *bindings.JSGlobalObject) JSC__JSValue; +pub extern fn JSC__AbortSignal__fromJS(JSValue0: JSC__JSValue) ?*bindings.AbortSignal; +pub extern fn JSC__AbortSignal__ref(arg0: ?*bindings.AbortSignal) ?*bindings.AbortSignal; +pub extern fn JSC__AbortSignal__signal(arg0: ?*bindings.AbortSignal, JSValue1: JSC__JSValue) ?*bindings.AbortSignal; +pub extern fn JSC__AbortSignal__unref(arg0: ?*bindings.AbortSignal) ?*bindings.AbortSignal; pub extern fn JSC__JSPromise__asValue(arg0: ?*bindings.JSPromise, arg1: *bindings.JSGlobalObject) JSC__JSValue; pub extern fn JSC__JSPromise__create(arg0: *bindings.JSGlobalObject) ?*bindings.JSPromise; pub extern fn JSC__JSPromise__isHandled(arg0: [*c]const JSC__JSPromise, arg1: *bindings.VM) bool; diff --git a/src/bun.js/bindings/sizes.zig b/src/bun.js/bindings/sizes.zig index 795159e49..b1b9c1679 100644 --- a/src/bun.js/bindings/sizes.zig +++ b/src/bun.js/bindings/sizes.zig @@ -78,4 +78,4 @@ pub const Bun_CallFrame__argumentCountIncludingThis = 4; pub const Bun_CallFrame__thisArgument = 5; pub const Bun_CallFrame__firstArgument = 6; pub const Bun_CallFrame__size = 8; -pub const Bun_CallFrame__align = 8; +pub const Bun_CallFrame__align = 8;
\ No newline at end of file diff --git a/src/bun.js/bindings/webcore/AbortSignal.cpp b/src/bun.js/bindings/webcore/AbortSignal.cpp index aa4143ebd..132ecefca 100644 --- a/src/bun.js/bindings/webcore/AbortSignal.cpp +++ b/src/bun.js/bindings/webcore/AbortSignal.cpp @@ -105,6 +105,12 @@ void AbortSignal::signalAbort(JSC::JSValue reason) for (auto& algorithm : algorithms) algorithm(reason); + auto callbacks = std::exchange(m_native_callbacks, {}); + for (auto callback : callbacks) { + const auto [ ctx, func ] = callback; + func(ctx, JSC::JSValue::encode(reason)); + } + // 5. Fire an event named abort at signal. dispatchEvent(Event::create(eventNames().abortEvent, Event::CanBubble::No, Event::IsCancelable::No)); } diff --git a/src/bun.js/bindings/webcore/AbortSignal.h b/src/bun.js/bindings/webcore/AbortSignal.h index 05e64ca82..b0c59daae 100644 --- a/src/bun.js/bindings/webcore/AbortSignal.h +++ b/src/bun.js/bindings/webcore/AbortSignal.h @@ -65,6 +65,7 @@ public: using Algorithm = Function<void(JSValue)>; void addAlgorithm(Algorithm&& algorithm) { m_algorithms.append(WTFMove(algorithm)); } + void addNativeCallback(std::tuple<void*, void (*)(void*, JSC::EncodedJSValue)> callback) { m_native_callbacks.append(callback); } bool isFollowingSignal() const { return !!m_followingSignal; } @@ -86,6 +87,7 @@ private: bool m_aborted { false }; Vector<Algorithm> m_algorithms; + Vector<std::tuple<void*, void (*)(void*, JSC::EncodedJSValue)>> m_native_callbacks; WeakPtr<AbortSignal> m_followingSignal; JSValueInWrappedObject m_reason; bool m_hasActiveTimeoutTimer { false }; diff --git a/src/bun.js/event_loop.zig b/src/bun.js/event_loop.zig index 8dbf5abfd..9c2627fda 100644 --- a/src/bun.js/event_loop.zig +++ b/src/bun.js/event_loop.zig @@ -173,6 +173,7 @@ pub const AnyTask = struct { } }; + pub const CppTask = opaque { extern fn Bun__performTask(globalObject: *JSGlobalObject, task: *CppTask) void; pub fn run(this: *CppTask, global: *JSGlobalObject) void { diff --git a/src/bun.js/javascript.zig b/src/bun.js/javascript.zig index b926c4ee9..a5ef4a44a 100644 --- a/src/bun.js/javascript.zig +++ b/src/bun.js/javascript.zig @@ -1150,7 +1150,7 @@ pub const VirtualMachine = struct { const after_namespace = if (namespace.len == 0) specifier else - specifier.substring(namespace.len + 1); + specifier.substring(namespace.len + 1, specifier.len); if (plugin_runner.onResolveJSC(ZigString.init(namespace), after_namespace, source, .bun)) |resolved_path| { res.* = resolved_path; diff --git a/src/bun.js/webcore/response.zig b/src/bun.js/webcore/response.zig index 2c3b1ee31..725a4e64c 100644 --- a/src/bun.js/webcore/response.zig +++ b/src/bun.js/webcore/response.zig @@ -688,6 +688,31 @@ pub const Fetch = struct { } pub fn onReject(this: *FetchTasklet) JSValue { + if (this.result.isTimeout()) { + //Timeout with reason + if (this.result.reason) |exception| { + if (!exception.isEmptyOrUndefinedOrNull()) { + return exception; + } + } + //Timeout without reason + const exception = JSC.AbortSignal.createTimeoutError(JSC.ZigString.static("The operation timed out"), &JSC.ZigString.Empty, this.global_this); + return exception; + } + + if (this.result.isAbort()) { + //Abort can be TimeoutError (AbortSignal.timeout(ms)) or AbortError so we need to detect + if (this.result.reason) |exception| { + if (!exception.isEmptyOrUndefinedOrNull()) { + return exception; + } + } + + //Abort without reason + const exception = JSC.AbortSignal.createAbortError(JSC.ZigString.static("The user aborted a request"), &JSC.ZigString.Empty, this.global_this); + return exception; + } + const fetch_error = JSC.SystemError{ .code = ZigString.init(@errorName(this.result.fail)), .message = ZigString.init("fetch() failed"), @@ -788,7 +813,7 @@ pub const Fetch = struct { FetchTasklet.callback, ).init( fetch_tasklet, - ), proxy); + ), proxy, fetch_options.signal); if (!fetch_options.follow_redirects) { fetch_tasklet.http.?.client.remaining_redirect_count = 0; @@ -800,7 +825,7 @@ pub const Fetch = struct { return fetch_tasklet; } - const FetchOptions = struct { method: Method, headers: Headers, body: AnyBlob, timeout: usize, disable_timeout: bool, disable_keepalive: bool, url: ZigURL, verbose: bool = false, follow_redirects: bool = true, proxy: ?ZigURL = null, url_proxy_buffer: []const u8 = "" }; + const FetchOptions = struct { method: Method, headers: Headers, body: AnyBlob, timeout: usize, disable_timeout: bool, disable_keepalive: bool, url: ZigURL, verbose: bool = false, follow_redirects: bool = true, proxy: ?ZigURL = null, url_proxy_buffer: []const u8 = "", signal: ?*JSC.AbortSignal = null, globalThis: ?*JSGlobalObject }; pub fn queue( allocator: std.mem.Allocator, @@ -862,6 +887,8 @@ pub const Fetch = struct { var verbose = false; var proxy: ?ZigURL = null; var follow_redirects = true; + var signal: ?*JSC.AbortSignal = null; + var url_proxy_buffer: []const u8 = undefined; if (first_arg.as(Request)) |request| { @@ -929,6 +956,12 @@ pub const Fetch = struct { if (options.get(globalThis, "verbose")) |verb| { verbose = verb.toBoolean(); } + if (options.get(globalThis, "signal")) |signal_arg| { + if (signal_arg.as(JSC.AbortSignal)) |signal_| { + _ = signal_.ref(); + signal = signal_; + } + } if (options.get(globalThis, "proxy")) |proxy_arg| { if (!proxy_arg.isUndefined()) { if (proxy_arg.isNull()) { @@ -1040,6 +1073,12 @@ pub const Fetch = struct { if (options.get(globalThis, "verbose")) |verb| { verbose = verb.toBoolean(); } + if (options.get(globalThis, "signal")) |signal_arg| { + if (signal_arg.as(JSC.AbortSignal)) |signal_| { + _ = signal_.ref(); + signal = signal_; + } + } if (options.get(globalThis, "proxy")) |proxy_arg| { if (!proxy_arg.isUndefined()) { var proxy_str = proxy_arg.toStringOrNull(globalThis) orelse return null; @@ -1159,7 +1198,7 @@ pub const Fetch = struct { globalThis, .{ .method = method, .url = url, .headers = headers orelse Headers{ .allocator = bun.default_allocator, - }, .body = body, .timeout = std.time.ns_per_hour, .disable_keepalive = disable_keepalive, .disable_timeout = disable_timeout, .follow_redirects = follow_redirects, .verbose = verbose, .proxy = proxy, .url_proxy_buffer = url_proxy_buffer }, + }, .body = body, .timeout = std.time.ns_per_hour, .disable_keepalive = disable_keepalive, .disable_timeout = disable_timeout, .follow_redirects = follow_redirects, .verbose = verbose, .proxy = proxy, .url_proxy_buffer = url_proxy_buffer, .signal = signal, .globalThis = globalThis }, JSC.JSValue.fromRef(deferred_promise), ) catch unreachable; return deferred_promise; diff --git a/src/bundler.zig b/src/bundler.zig index f540436b0..26a75ec43 100644 --- a/src/bundler.zig +++ b/src/bundler.zig @@ -180,7 +180,7 @@ pub const PluginRunner = struct { JSC.ZigString.init(""); const on_resolve_plugin = global.runOnResolvePlugins( namespace, - JSC.ZigString.init(specifier).substring(if (namespace.len > 0) namespace.len + 1 else 0), + JSC.ZigString.init(specifier).substring(if (namespace.len > 0) namespace.len + 1 else 0, 0), JSC.ZigString.init(importer), target, ) orelse return null; diff --git a/src/http_client_async.zig b/src/http_client_async.zig index 853ab8f3d..b6dd0e828 100644 --- a/src/http_client_async.zig +++ b/src/http_client_async.zig @@ -1,5 +1,6 @@ const picohttp = @import("bun").picohttp; const bun = @import("bun"); +const JSC = bun.JSC; const string = bun.string; const Output = bun.Output; const Global = bun.Global; @@ -658,6 +659,7 @@ pub fn onOpen( ssl.configureHTTPClient(hostname); } } + client.addAbortSignalEventListenner(is_ssl, socket); if (client.state.request_stage == .pending) { client.onWritable(true, comptime is_ssl, socket); } @@ -691,7 +693,7 @@ pub fn onClose( } if (in_progress) { - client.fail(error.ConnectionClosed); + client.fail(error.ConnectionClosed, null); } } pub fn onTimeout( @@ -702,8 +704,9 @@ pub fn onTimeout( _ = socket; log("Timeout {s}\n", .{client.url.href}); - if (client.state.stage != .done and client.state.stage != .fail) - client.fail(error.Timeout); + if (client.state.stage != .done and client.state.stage != .fail) { + client.fail(error.Timeout, null); + } } pub fn onConnectError( client: *HTTPClient, @@ -714,7 +717,7 @@ pub fn onConnectError( log("onConnectError {s}\n", .{client.url.href}); if (client.state.stage != .done and client.state.stage != .fail) - client.fail(error.ConnectionRefused); + client.fail(error.ConnectionRefused, null); } pub fn onEnd( client: *HTTPClient, @@ -724,7 +727,7 @@ pub fn onEnd( log("onEnd {s}\n", .{client.url.href}); if (client.state.stage != .done and client.state.stage != .fail) - client.fail(error.ConnectionClosed); + client.fail(error.ConnectionClosed, null); } pub inline fn getAllocator() std.mem.Allocator { @@ -989,23 +992,68 @@ http_proxy: ?URL = null, proxy_authorization: ?[]u8 = null, proxy_tunneling: bool = false, proxy_tunnel: ?ProxyTunnel = null, +signal: ?*JSC.AbortSignal = null, +abort_handler: ?*anyopaque = null, +abort_handler_deinit: ?*const fn (?*anyopaque) void = null, +pub fn init(allocator: std.mem.Allocator, method: Method, url: URL, header_entries: Headers.Entries, header_buf: string, signal: ?*JSC.AbortSignal) HTTPClient { + return HTTPClient{ .allocator = allocator, .method = method, .url = url, .header_entries = header_entries, .header_buf = header_buf, .signal = signal, .abort_handler = null, .abort_handler_deinit = null }; +} -pub fn init( - allocator: std.mem.Allocator, - method: Method, - url: URL, - header_entries: Headers.Entries, - header_buf: string, -) HTTPClient { - return HTTPClient{ - .allocator = allocator, - .method = method, - .url = url, - .header_entries = header_entries, - .header_buf = header_buf, +pub fn ClientSocketAbortHandler(comptime is_ssl: bool) type { + return struct { + client: *HTTPClient, + socket: NewHTTPContext(is_ssl).HTTPSocket, + + pub fn init(client: *HTTPClient, socket: NewHTTPContext(is_ssl).HTTPSocket) !*@This() { + var ctx = try client.allocator.create(@This()); + ctx.client = client; + ctx.socket = socket; + return ctx; + } + + pub fn onAborted(this: ?*anyopaque, reason: JSC.JSValue) callconv(.C) void { + log("onAborted", .{}); + if (this) |this_| { + const self = bun.cast(*@This(), this_); + self.client.closeAndAbort(reason, is_ssl, self.socket); + } + } + + pub fn deinit(this: ?*anyopaque) void { + if (this) |this_| { + var self = bun.cast(*@This(), this_); + const allocator = self.client.allocator; + allocator.destroy(self); + } + } }; } +pub fn addAbortSignalEventListenner(this: *HTTPClient, comptime is_ssl: bool, socket: NewHTTPContext(is_ssl).HTTPSocket) void { + if (this.signal) |signal| { + const handler = ClientSocketAbortHandler(is_ssl).init(this, socket) catch unreachable; + this.abort_handler = bun.cast(*anyopaque, handler); + this.abort_handler_deinit = ClientSocketAbortHandler(is_ssl).deinit; + _ = signal.addListener(this.abort_handler.?, ClientSocketAbortHandler(is_ssl).onAborted); + log("addAbortSignalEventListenner added!", .{}); + return; + } + log("addAbortSignalEventListenner (signal == null)", .{}); +} + +pub fn hasSignalAborted(this: *HTTPClient) ?JSC.JSValue { + if (this.signal) |signal| { + const aborted = signal.aborted(); + log("hasSignalAborted {any}", .{aborted}); + if (aborted) { + return signal.abortReason(); + } + return null; + } + log("hasSignalAborted (signal == null)", .{}); + return null; +} + pub fn deinit(this: *HTTPClient) void { if (this.redirect) |redirect| { redirect.release(); @@ -1019,6 +1067,17 @@ pub fn deinit(this: *HTTPClient) void { tunnel.deinit(); this.proxy_tunnel = null; } + + if (this.signal != null) { + var signal = this.signal.?; + _ = signal.unref(); + this.signal = null; + } + if (this.abort_handler != null and this.abort_handler_deinit != null) { + this.abort_handler_deinit.?(this.abort_handler.?); + this.abort_handler = null; + this.abort_handler_deinit = null; + } this.state.compressed_body.deinit(); this.state.response_message_buffer.deinit(); } @@ -1178,20 +1237,9 @@ pub const AsyncHTTP = struct { }; const AtomicState = std.atomic.Atomic(State); - pub fn init( - allocator: std.mem.Allocator, - method: Method, - url: URL, - headers: Headers.Entries, - headers_buf: string, - response_buffer: *MutableString, - request_body: []const u8, - timeout: usize, - callback: HTTPClientResult.Callback, - http_proxy: ?URL, - ) AsyncHTTP { + pub fn init(allocator: std.mem.Allocator, method: Method, url: URL, headers: Headers.Entries, headers_buf: string, response_buffer: *MutableString, request_body: []const u8, timeout: usize, callback: HTTPClientResult.Callback, http_proxy: ?URL, signal: ?*JSC.AbortSignal) AsyncHTTP { var this = AsyncHTTP{ .allocator = allocator, .url = url, .method = method, .request_headers = headers, .request_header_buf = headers_buf, .request_body = request_body, .response_buffer = response_buffer, .completion_callback = callback, .http_proxy = http_proxy }; - this.client = HTTPClient.init(allocator, method, url, headers, headers_buf); + this.client = HTTPClient.init(allocator, method, url, headers, headers_buf, signal); this.client.timeout = timeout; this.client.http_proxy = this.http_proxy; if (http_proxy) |proxy| { @@ -1222,7 +1270,7 @@ pub const AsyncHTTP = struct { } pub fn initSync(allocator: std.mem.Allocator, method: Method, url: URL, headers: Headers.Entries, headers_buf: string, response_buffer: *MutableString, request_body: []const u8, timeout: usize, http_proxy: ?URL) AsyncHTTP { - return @This().init(allocator, method, url, headers, headers_buf, response_buffer, request_body, timeout, undefined, http_proxy); + return @This().init(allocator, method, url, headers, headers_buf, response_buffer, request_body, timeout, undefined, http_proxy, null); } fn reset(this: *AsyncHTTP) !void { @@ -1454,7 +1502,7 @@ pub fn doRedirect(this: *HTTPClient) void { std.debug.assert(this.follow_redirects); if (this.remaining_redirect_count == 0) { - this.fail(error.TooManyRedirects); + this.fail(error.TooManyRedirects, null); return; } this.state.reset(); @@ -1491,12 +1539,12 @@ pub fn start(this: *HTTPClient, body: []const u8, body_out_str: *MutableString) fn start_(this: *HTTPClient, comptime is_ssl: bool) void { var socket = http_thread.connect(this, is_ssl) catch |err| { - this.fail(err); + this.fail(err, null); return; }; if (socket.isClosed() and (this.state.response_stage != .done and this.state.response_stage != .fail)) { - this.fail(error.ConnectionClosed); + this.fail(error.ConnectionClosed, null); std.debug.assert(this.state.fail != error.NoError); } } @@ -1522,6 +1570,11 @@ fn printResponse(response: picohttp.Response) void { } pub fn onWritable(this: *HTTPClient, comptime is_first_call: bool, comptime is_ssl: bool, socket: NewHTTPContext(is_ssl).HTTPSocket) void { + if (this.hasSignalAborted()) |reason| { + this.closeAndAbort(reason, is_ssl, socket); + return; + } + switch (this.state.request_stage) { .pending, .headers => { var stack_fallback = std.heap.stackFallback(16384, default_allocator); @@ -1766,8 +1819,8 @@ pub fn closeAndFail(this: *HTTPClient, err: anyerror, comptime is_ssl: bool, soc **anyopaque, NewHTTPContext(is_ssl).ActiveSocket.init(&dead_socket).ptr(), ); - this.fail(err); socket.close(0, null); + this.fail(err, null); } fn startProxySendHeaders(this: *HTTPClient, comptime is_ssl: bool, socket: NewHTTPContext(is_ssl).HTTPSocket) void { @@ -1821,6 +1874,10 @@ fn startProxyHandshake(this: *HTTPClient, comptime is_ssl: bool, socket: NewHTTP } pub fn onData(this: *HTTPClient, comptime is_ssl: bool, incoming_data: []const u8, ctx: *NewHTTPContext(is_ssl), socket: NewHTTPContext(is_ssl).HTTPSocket) void { + if (this.hasSignalAborted()) |reason| { + this.closeAndAbort(reason, is_ssl, socket); + return; + } switch (this.state.response_stage) { .pending, .headers, .proxy_decoded_headers => { var to_read = incoming_data; @@ -2054,14 +2111,23 @@ pub fn onData(this: *HTTPClient, comptime is_ssl: bool, incoming_data: []const u } } -fn fail(this: *HTTPClient, err: anyerror) void { +pub fn closeAndAbort(this: *HTTPClient, reason: JSC.JSValue, comptime is_ssl: bool, socket: NewHTTPContext(is_ssl).HTTPSocket) void { + socket.ext(**anyopaque).?.* = bun.cast( + **anyopaque, + NewHTTPContext(is_ssl).ActiveSocket.init(&dead_socket).ptr(), + ); + socket.close(0, null); + this.fail(error.Aborted, reason); +} + +fn fail(this: *HTTPClient, err: anyerror, reason: ?JSC.JSValue) void { this.state.request_stage = .fail; this.state.response_stage = .fail; this.state.fail = err; this.state.stage = .fail; const callback = this.completion_callback; - const result = this.toResult(this.cloned_metadata); + const result = this.toResult(this.cloned_metadata, reason); this.state.reset(); this.proxy_tunneling = false; @@ -2101,7 +2167,7 @@ pub fn done(this: *HTTPClient, comptime is_ssl: bool, ctx: *NewHTTPContext(is_ss var out_str = this.state.body_out_str.?; var body = out_str.*; this.cloned_metadata.response = this.state.pending_response; - const result = this.toResult(this.cloned_metadata); + const result = this.toResult(this.cloned_metadata, null); const callback = this.completion_callback; this.state.response_stage = .done; @@ -2147,11 +2213,20 @@ pub const HTTPClientResult = struct { fail: anyerror = error.NoError, redirected: bool = false, headers_buf: []picohttp.Header = &.{}, + reason: ?JSC.JSValue = null, pub fn isSuccess(this: *const HTTPClientResult) bool { return this.fail == error.NoError; } + pub fn isTimeout(this: *const HTTPClientResult) bool { + return this.fail == error.Timeout; + } + + pub fn isAbort(this: *const HTTPClientResult) bool { + return this.fail == error.Aborted; + } + pub fn deinitMetadata(this: *HTTPClientResult) void { if (this.metadata_buf.len > 0) bun.default_allocator.free(this.metadata_buf); if (this.headers_buf.len > 0) bun.default_allocator.free(this.headers_buf); @@ -2191,7 +2266,7 @@ pub const HTTPClientResult = struct { }; }; -pub fn toResult(this: *HTTPClient, metadata: HTTPResponseMetadata) HTTPClientResult { +pub fn toResult(this: *HTTPClient, metadata: HTTPResponseMetadata, reason: ?JSC.JSValue) HTTPClientResult { return HTTPClientResult{ .body = this.state.body_out_str, .response = metadata.response, @@ -2199,6 +2274,7 @@ pub fn toResult(this: *HTTPClient, metadata: HTTPResponseMetadata) HTTPClientRes .redirected = this.remaining_redirect_count != default_redirect_count, .href = metadata.url, .fail = this.state.fail, + .reason = reason, .headers_buf = metadata.response.headers, }; } diff --git a/src/install/install.zig b/src/install/install.zig index 7bc79b015..5b5346294 100644 --- a/src/install/install.zig +++ b/src/install/install.zig @@ -329,7 +329,7 @@ const NetworkTask = struct { var url = URL.parse(this.url_buf); var http_proxy: ?URL = env_loader.getHttpProxy(url); - this.http = AsyncHTTP.init(allocator, .GET, url, header_builder.entries, header_builder.content.ptr.?[0..header_builder.content.len], &this.response_buffer, "", 0, this.getCompletionCallback(), http_proxy); + this.http = AsyncHTTP.init(allocator, .GET, url, header_builder.entries, header_builder.content.ptr.?[0..header_builder.content.len], &this.response_buffer, "", 0, this.getCompletionCallback(), http_proxy, null); this.http.max_retry_count = this.package_manager.options.max_retry_count; this.callback = .{ .package_manifest = .{ @@ -396,7 +396,7 @@ const NetworkTask = struct { var url = URL.parse(this.url_buf); var http_proxy: ?URL = env_loader.getHttpProxy(url); - this.http = AsyncHTTP.init(allocator, .GET, url, header_builder.entries, header_buf, &this.response_buffer, "", 0, this.getCompletionCallback(), http_proxy); + this.http = AsyncHTTP.init(allocator, .GET, url, header_builder.entries, header_buf, &this.response_buffer, "", 0, this.getCompletionCallback(), http_proxy, null); this.http.max_retry_count = this.package_manager.options.max_retry_count; this.callback = .{ .extract = tarball }; } diff --git a/src/string_immutable.zig b/src/string_immutable.zig index 9d36d0c78..e012b6e5a 100644 --- a/src/string_immutable.zig +++ b/src/string_immutable.zig @@ -1133,7 +1133,6 @@ pub fn toUTF16Alloc(allocator: std.mem.Allocator, bytes: []const u8, comptime fa else => return out, } } else null; - var output = output_ orelse fallback: { var list = try std.ArrayList(u16).initCapacity(allocator, i + 2); list.items.len = i; |