diff --git a/src/Package/Fetch.zig b/src/Package/Fetch.zig index 2a11e1ea6e..6fd5a5989c 100644 --- a/src/Package/Fetch.zig +++ b/src/Package/Fetch.zig @@ -400,7 +400,8 @@ pub fn run(f: *Fetch) RunError!void { .{ path_or_url, file_err, uri_err }, )); }; - var resource = try f.initResource(uri, &server_header_buffer); + var resource: Resource = undefined; + try f.initResource(uri, &resource, &server_header_buffer); return f.runResource(try uri.path.toRawMaybeAlloc(arena), &resource, null); } }, @@ -466,7 +467,8 @@ pub fn run(f: *Fetch) RunError!void { try eb.printString("invalid URI: {s}", .{@errorName(err)}), ); var buffer: [init_resource_buffer_size]u8 = undefined; - var resource = try f.initResource(uri, &buffer); + var resource: Resource = undefined; + try f.initResource(uri, &resource, &buffer); return f.runResource(try uri.path.toRawMaybeAlloc(arena), &resource, remote.hash); } @@ -880,7 +882,7 @@ const Resource = union(enum) { const HttpRequest = struct { request: std.http.Client.Request, - head: std.http.Client.Response.Head, + response: std.http.Client.Response, buffer: []u8, }; @@ -900,13 +902,7 @@ const Resource = union(enum) { fn reader(resource: *Resource) *std.Io.Reader { return switch (resource.*) { .file => |*file_reader| return &file_reader.interface, - .http_request => |*http_request| { - const response: std.http.Client.Response = .{ - .request = &http_request.request, - .head = http_request.head, - }; - return response.reader(http_request.buffer); - }, + .http_request => |*http_request| return http_request.response.reader(http_request.buffer), .git => |*g| return &g.fetch_stream.reader, .dir => unreachable, }; @@ -974,7 +970,7 @@ const FileType = enum { const init_resource_buffer_size = git.Packet.max_data_length; -fn initResource(f: *Fetch, uri: std.Uri, reader_buffer: []u8) RunError!Resource { +fn initResource(f: *Fetch, uri: std.Uri, resource: *Resource, reader_buffer: []u8) RunError!void { const gpa = f.arena.child_allocator; const arena = f.arena.allocator(); const eb = &f.error_bundle; @@ -986,7 +982,8 @@ fn initResource(f: *Fetch, uri: std.Uri, reader_buffer: []u8) RunError!Resource f.parent_package_root, path, err, })); }; - return .{ .file = file.reader(reader_buffer) }; + resource.* = .{ .file = file.reader(reader_buffer) }; + return; } const http_client = f.job_queue.http_client; @@ -994,15 +991,21 @@ fn initResource(f: *Fetch, uri: std.Uri, reader_buffer: []u8) RunError!Resource if (ascii.eqlIgnoreCase(uri.scheme, "http") or ascii.eqlIgnoreCase(uri.scheme, "https")) { - var request = http_client.request(.GET, uri, .{}) catch |err| - return f.fail(f.location_tok, try eb.printString("unable to connect to server: {t}", .{err})); + resource.* = .{ .http_request = .{ + .request = http_client.request(.GET, uri, .{}) catch |err| + return f.fail(f.location_tok, try eb.printString("unable to connect to server: {t}", .{err})), + .response = undefined, + .buffer = reader_buffer, + } }; + const request = &resource.http_request.request; defer request.deinit(); request.sendBodiless() catch |err| return f.fail(f.location_tok, try eb.printString("HTTP request failed: {t}", .{err})); var redirect_buffer: [1024]u8 = undefined; - const response = request.receiveHead(&redirect_buffer) catch |err| + const response = &resource.http_request.response; + response.* = request.receiveHead(&redirect_buffer) catch |err| return f.fail(f.location_tok, try eb.printString("invalid HTTP response: {t}", .{err})); if (response.head.status != .ok) return f.fail(f.location_tok, try eb.printString( @@ -1010,11 +1013,7 @@ fn initResource(f: *Fetch, uri: std.Uri, reader_buffer: []u8) RunError!Resource .{ response.head.status, response.head.status.phrase() orelse "" }, )); - return .{ .http_request = .{ - .request = request, - .head = response.head, - .buffer = reader_buffer, - } }; + return; } if (ascii.eqlIgnoreCase(uri.scheme, "git+http") or @@ -1087,13 +1086,12 @@ fn initResource(f: *Fetch, uri: std.Uri, reader_buffer: []u8) RunError!Resource }; errdefer fetch_stream.deinit(); - if (true) @panic("TODO this moves fetch_stream, invalidating its reader"); - - return .{ .git = .{ + resource.* = .{ .git = .{ .session = session, .fetch_stream = fetch_stream, .want_oid = want_oid, } }; + return; } return f.fail(f.location_tok, try eb.printString("unsupported URL scheme: {s}", .{uri.scheme})); @@ -1111,7 +1109,7 @@ fn unpackResource( return f.fail(f.location_tok, try eb.printString("unknown file type: '{s}'", .{uri_path})), .http_request => |*http_request| ft: { - const head = &http_request.head; + const head = &http_request.response.head; // Content-Type takes first precedence. const content_type = head.content_type orelse diff --git a/src/Package/Fetch/git.zig b/src/Package/Fetch/git.zig index 88652343f5..390b977c3a 100644 --- a/src/Package/Fetch/git.zig +++ b/src/Package/Fetch/git.zig @@ -773,7 +773,7 @@ pub const Session = struct { try request.sendBodiless(); var redirect_buffer: [1024]u8 = undefined; - const response = try request.receiveHead(&redirect_buffer); + var response = try request.receiveHead(&redirect_buffer); if (response.head.status != .ok) return error.ProtocolError; const any_redirects_occurred = request.redirect_behavior.remaining() < max_redirects; if (any_redirects_occurred) { @@ -918,7 +918,7 @@ pub const Session = struct { errdefer request.deinit(); try request.sendBodyComplete(body.buffered()); - const response = try request.receiveHead(options.buffer); + var response = try request.receiveHead(options.buffer); if (response.head.status != .ok) return error.ProtocolError; it.reader = response.reader(options.buffer); } @@ -1037,7 +1037,7 @@ pub const Session = struct { try request.sendBodyComplete(body.buffered()); - const response = try request.receiveHead(&.{}); + var response = try request.receiveHead(&.{}); if (response.head.status != .ok) return error.ProtocolError; const reader = response.reader(response_buffer);