mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
fetch: avoid copying Resource
This commit is contained in:
parent
59ba197308
commit
1596aed1fd
2 changed files with 25 additions and 27 deletions
|
|
@ -400,7 +400,8 @@ pub fn run(f: *Fetch) RunError!void {
|
||||||
.{ path_or_url, file_err, uri_err },
|
.{ 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);
|
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)}),
|
try eb.printString("invalid URI: {s}", .{@errorName(err)}),
|
||||||
);
|
);
|
||||||
var buffer: [init_resource_buffer_size]u8 = undefined;
|
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);
|
return f.runResource(try uri.path.toRawMaybeAlloc(arena), &resource, remote.hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -880,7 +882,7 @@ const Resource = union(enum) {
|
||||||
|
|
||||||
const HttpRequest = struct {
|
const HttpRequest = struct {
|
||||||
request: std.http.Client.Request,
|
request: std.http.Client.Request,
|
||||||
head: std.http.Client.Response.Head,
|
response: std.http.Client.Response,
|
||||||
buffer: []u8,
|
buffer: []u8,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -900,13 +902,7 @@ const Resource = union(enum) {
|
||||||
fn reader(resource: *Resource) *std.Io.Reader {
|
fn reader(resource: *Resource) *std.Io.Reader {
|
||||||
return switch (resource.*) {
|
return switch (resource.*) {
|
||||||
.file => |*file_reader| return &file_reader.interface,
|
.file => |*file_reader| return &file_reader.interface,
|
||||||
.http_request => |*http_request| {
|
.http_request => |*http_request| return http_request.response.reader(http_request.buffer),
|
||||||
const response: std.http.Client.Response = .{
|
|
||||||
.request = &http_request.request,
|
|
||||||
.head = http_request.head,
|
|
||||||
};
|
|
||||||
return response.reader(http_request.buffer);
|
|
||||||
},
|
|
||||||
.git => |*g| return &g.fetch_stream.reader,
|
.git => |*g| return &g.fetch_stream.reader,
|
||||||
.dir => unreachable,
|
.dir => unreachable,
|
||||||
};
|
};
|
||||||
|
|
@ -974,7 +970,7 @@ const FileType = enum {
|
||||||
|
|
||||||
const init_resource_buffer_size = git.Packet.max_data_length;
|
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 gpa = f.arena.child_allocator;
|
||||||
const arena = f.arena.allocator();
|
const arena = f.arena.allocator();
|
||||||
const eb = &f.error_bundle;
|
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,
|
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;
|
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
|
if (ascii.eqlIgnoreCase(uri.scheme, "http") or
|
||||||
ascii.eqlIgnoreCase(uri.scheme, "https"))
|
ascii.eqlIgnoreCase(uri.scheme, "https"))
|
||||||
{
|
{
|
||||||
var request = http_client.request(.GET, uri, .{}) catch |err|
|
resource.* = .{ .http_request = .{
|
||||||
return f.fail(f.location_tok, try eb.printString("unable to connect to server: {t}", .{err}));
|
.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();
|
defer request.deinit();
|
||||||
|
|
||||||
request.sendBodiless() catch |err|
|
request.sendBodiless() catch |err|
|
||||||
return f.fail(f.location_tok, try eb.printString("HTTP request failed: {t}", .{err}));
|
return f.fail(f.location_tok, try eb.printString("HTTP request failed: {t}", .{err}));
|
||||||
|
|
||||||
var redirect_buffer: [1024]u8 = undefined;
|
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}));
|
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(
|
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 "" },
|
.{ response.head.status, response.head.status.phrase() orelse "" },
|
||||||
));
|
));
|
||||||
|
|
||||||
return .{ .http_request = .{
|
return;
|
||||||
.request = request,
|
|
||||||
.head = response.head,
|
|
||||||
.buffer = reader_buffer,
|
|
||||||
} };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ascii.eqlIgnoreCase(uri.scheme, "git+http") or
|
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();
|
errdefer fetch_stream.deinit();
|
||||||
|
|
||||||
if (true) @panic("TODO this moves fetch_stream, invalidating its reader");
|
resource.* = .{ .git = .{
|
||||||
|
|
||||||
return .{ .git = .{
|
|
||||||
.session = session,
|
.session = session,
|
||||||
.fetch_stream = fetch_stream,
|
.fetch_stream = fetch_stream,
|
||||||
.want_oid = want_oid,
|
.want_oid = want_oid,
|
||||||
} };
|
} };
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return f.fail(f.location_tok, try eb.printString("unsupported URL scheme: {s}", .{uri.scheme}));
|
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})),
|
return f.fail(f.location_tok, try eb.printString("unknown file type: '{s}'", .{uri_path})),
|
||||||
|
|
||||||
.http_request => |*http_request| ft: {
|
.http_request => |*http_request| ft: {
|
||||||
const head = &http_request.head;
|
const head = &http_request.response.head;
|
||||||
|
|
||||||
// Content-Type takes first precedence.
|
// Content-Type takes first precedence.
|
||||||
const content_type = head.content_type orelse
|
const content_type = head.content_type orelse
|
||||||
|
|
|
||||||
|
|
@ -773,7 +773,7 @@ pub const Session = struct {
|
||||||
try request.sendBodiless();
|
try request.sendBodiless();
|
||||||
|
|
||||||
var redirect_buffer: [1024]u8 = undefined;
|
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;
|
if (response.head.status != .ok) return error.ProtocolError;
|
||||||
const any_redirects_occurred = request.redirect_behavior.remaining() < max_redirects;
|
const any_redirects_occurred = request.redirect_behavior.remaining() < max_redirects;
|
||||||
if (any_redirects_occurred) {
|
if (any_redirects_occurred) {
|
||||||
|
|
@ -918,7 +918,7 @@ pub const Session = struct {
|
||||||
errdefer request.deinit();
|
errdefer request.deinit();
|
||||||
try request.sendBodyComplete(body.buffered());
|
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;
|
if (response.head.status != .ok) return error.ProtocolError;
|
||||||
it.reader = response.reader(options.buffer);
|
it.reader = response.reader(options.buffer);
|
||||||
}
|
}
|
||||||
|
|
@ -1037,7 +1037,7 @@ pub const Session = struct {
|
||||||
|
|
||||||
try request.sendBodyComplete(body.buffered());
|
try request.sendBodyComplete(body.buffered());
|
||||||
|
|
||||||
const response = try request.receiveHead(&.{});
|
var response = try request.receiveHead(&.{});
|
||||||
if (response.head.status != .ok) return error.ProtocolError;
|
if (response.head.status != .ok) return error.ProtocolError;
|
||||||
|
|
||||||
const reader = response.reader(response_buffer);
|
const reader = response.reader(response_buffer);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue