diff --git a/src/lib/buzz_http.zig b/src/lib/buzz_http.zig index 01311f4c..b4a4861a 100644 --- a/src/lib/buzz_http.zig +++ b/src/lib/buzz_http.zig @@ -25,6 +25,7 @@ pub export fn HttpClientDeinit(ctx: *api.NativeCtx) c_int { const client = @as(*http.Client, @ptrCast(@alignCast(@as(*anyopaque, @ptrFromInt(userdata))))); client.deinit(); + api.VM.allocator.destroy(client); return 0; } @@ -66,7 +67,7 @@ pub export fn HttpClientSend(ctx: *api.NativeCtx) c_int { } const request = api.VM.allocator.create(http.Client.Request) catch @panic("Out of memory"); - const server_header_buffer = api.VM.allocator.alloc(u8, 1024) catch @panic("Out of memory"); // FIXME: what do i do we this?? + const server_header_buffer = api.VM.allocator.alloc(u8, 16 * 1024) catch @panic("Out of memory"); request.* = client.open( method, @@ -103,7 +104,14 @@ pub export fn HttpClientSend(ctx: *api.NativeCtx) c_int { pub export fn HttpRequestWait(ctx: *api.NativeCtx) c_int { const userdata_value = ctx.vm.bz_peek(0); const userdata = userdata_value.bz_valueToUserData(); - const request = @as(*http.Client.Request, @ptrCast(@alignCast(@as(*anyopaque, @ptrFromInt(userdata))))); + const request = @as( + *http.Client.Request, + @ptrCast( + @alignCast( + @as(*anyopaque, @ptrFromInt(userdata)), + ), + ), + ); request.wait() catch |err| { handleWaitError(ctx, err); @@ -116,10 +124,36 @@ pub export fn HttpRequestWait(ctx: *api.NativeCtx) c_int { return 1; } +pub export fn HttpRequestDeinit(ctx: *api.NativeCtx) c_int { + const userdata_value = ctx.vm.bz_peek(0); + const userdata = userdata_value.bz_valueToUserData(); + const request = @as( + *http.Client.Request, + @ptrCast( + @alignCast( + @as(*anyopaque, @ptrFromInt(userdata)), + ), + ), + ); + + api.VM.allocator.free(request.response.parser.header_bytes_buffer); + request.deinit(); + api.VM.allocator.destroy(request); + + return 0; +} + pub export fn HttpRequestRead(ctx: *api.NativeCtx) c_int { const userdata_value = ctx.vm.bz_peek(0); const userdata = userdata_value.bz_valueToUserData(); - const request = @as(*http.Client.Request, @ptrCast(@alignCast(@as(*anyopaque, @ptrFromInt(userdata))))); + const request = @as( + *http.Client.Request, + @ptrCast( + @alignCast( + @as(*anyopaque, @ptrFromInt(userdata)), + ), + ), + ); var body_raw = std.ArrayList(u8).init(api.VM.allocator); defer body_raw.deinit(); diff --git a/src/lib/http.buzz b/src/lib/http.buzz index 20876346..84fedf20 100644 --- a/src/lib/http.buzz +++ b/src/lib/http.buzz @@ -18,7 +18,7 @@ export enum HttpError { HttpConnectionHeaderUnsupported, HttpHeaderContinuationsUnsupported, HttpHeadersInvalid, - HttpHeadersOversize + HttpHeadersOversize, HttpRedirectLocationInvalid, HttpRedirectLocationMissing, HttpTransferEncodingUnsupported, @@ -72,6 +72,8 @@ extern fun HttpClientSend(ud client, Method method, str uri, {str: str} headers) extern fun HttpRequestWait(ud request) > void !> HttpError; || @private extern fun HttpRequestRead(ud request) > Response !> HttpError; +|| @private +extern fun HttpRequestDeinit(ud request) > void; const {int: str} reasons = { 100: "Continue", @@ -155,6 +157,7 @@ object Connection { export object Client { || @private ud client, + bool collected = false, static fun init() > Client { return Client{ @@ -184,7 +187,9 @@ export object Client { } fun collect() > void { - HttpClientDeinit(this.client); + if (!this.collected) { + HttpClientDeinit(this.client); + } } } @@ -195,6 +200,7 @@ export object Request { {str: str} headers = {}, str uri = "/", str? body = null, + bool collected = false, fun wait() > Response !> HttpError, InvalidArgumentError, HttpParseError { if (this.response != null) { @@ -228,6 +234,16 @@ export object Request { return ""; } + + fun collect() > void { + if (this.collected) { + return; + } + + if (this.request -> request) { + HttpRequestDeinit(request); + } + } } export object Response {