| ... | @@ -400,7 +400,8 @@ pub fn run(f: *Fetch) RunError!void { | ... | @@ -400,7 +400,8 @@ pub fn run(f: *Fetch) RunError!void { |
| 400 | .{ path_or_url, file_err, uri_err }, | 400 | .{ path_or_url, file_err, uri_err }, |
| 401 | )); | 401 | )); |
| 402 | }; | 402 | }; |
| 403 | var resource = try f.initResource(uri, &server_header_buffer); | 403 | var resource: Resource = undefined; |
| | 404 | try f.initResource(uri, &resource, &server_header_buffer); |
| 404 | return f.runResource(try uri.path.toRawMaybeAlloc(arena), &resource, null); | 405 | return f.runResource(try uri.path.toRawMaybeAlloc(arena), &resource, null); |
| 405 | } | 406 | } |
| 406 | }, | 407 | }, |
| ... | @@ -466,7 +467,8 @@ pub fn run(f: *Fetch) RunError!void { | ... | @@ -466,7 +467,8 @@ pub fn run(f: *Fetch) RunError!void { |
| 466 | try eb.printString("invalid URI: {s}", .{@errorName(err)}), | 467 | try eb.printString("invalid URI: {s}", .{@errorName(err)}), |
| 467 | ); | 468 | ); |
| 468 | var buffer: [init_resource_buffer_size]u8 = undefined; | 469 | var buffer: [init_resource_buffer_size]u8 = undefined; |
| 469 | var resource = try f.initResource(uri, &buffer); | 470 | var resource: Resource = undefined; |
| | 471 | try f.initResource(uri, &resource, &buffer); |
| 470 | return f.runResource(try uri.path.toRawMaybeAlloc(arena), &resource, remote.hash); | 472 | return f.runResource(try uri.path.toRawMaybeAlloc(arena), &resource, remote.hash); |
| 471 | } | 473 | } |
| 472 | | 474 | |
| ... | @@ -880,7 +882,7 @@ const Resource = union(enum) { | ... | @@ -880,7 +882,7 @@ const Resource = union(enum) { |
| 880 | | 882 | |
| 881 | const HttpRequest = struct { | 883 | const HttpRequest = struct { |
| 882 | request: std.http.Client.Request, | 884 | request: std.http.Client.Request, |
| 883 | head: std.http.Client.Response.Head, | 885 | response: std.http.Client.Response, |
| 884 | buffer: []u8, | 886 | buffer: []u8, |
| 885 | }; | 887 | }; |
| 886 | | 888 | |
| ... | @@ -900,13 +902,7 @@ const Resource = union(enum) { | ... | @@ -900,13 +902,7 @@ const Resource = union(enum) { |
| 900 | fn reader(resource: *Resource) *std.Io.Reader { | 902 | fn reader(resource: *Resource) *std.Io.Reader { |
| 901 | return switch (resource.*) { | 903 | return switch (resource.*) { |
| 902 | .file => |*file_reader| return &file_reader.interface, | 904 | .file => |*file_reader| return &file_reader.interface, |
| 903 | .http_request => |*http_request| { | 905 | .http_request => |*http_request| return http_request.response.reader(http_request.buffer), |
| 904 | const response: std.http.Client.Response = .{ | | |
| 905 | .request = &http_request.request, | | |
| 906 | .head = http_request.head, | | |
| 907 | }; | | |
| 908 | return response.reader(http_request.buffer); | | |
| 909 | }, | | |
| 910 | .git => |*g| return &g.fetch_stream.reader, | 906 | .git => |*g| return &g.fetch_stream.reader, |
| 911 | .dir => unreachable, | 907 | .dir => unreachable, |
| 912 | }; | 908 | }; |
| ... | @@ -974,7 +970,7 @@ const FileType = enum { | ... | @@ -974,7 +970,7 @@ const FileType = enum { |
| 974 | | 970 | |
| 975 | const init_resource_buffer_size = git.Packet.max_data_length; | 971 | const init_resource_buffer_size = git.Packet.max_data_length; |
| 976 | | 972 | |
| 977 | fn initResource(f: *Fetch, uri: std.Uri, reader_buffer: []u8) RunError!Resource { | 973 | fn initResource(f: *Fetch, uri: std.Uri, resource: *Resource, reader_buffer: []u8) RunError!void { |
| 978 | const gpa = f.arena.child_allocator; | 974 | const gpa = f.arena.child_allocator; |
| 979 | const arena = f.arena.allocator(); | 975 | const arena = f.arena.allocator(); |
| 980 | const eb = &f.error_bundle; | 976 | const eb = &f.error_bundle; |
| ... | @@ -986,7 +982,8 @@ fn initResource(f: *Fetch, uri: std.Uri, reader_buffer: []u8) RunError!Resource | ... | @@ -986,7 +982,8 @@ fn initResource(f: *Fetch, uri: std.Uri, reader_buffer: []u8) RunError!Resource |
| 986 | f.parent_package_root, path, err, | 982 | f.parent_package_root, path, err, |
| 987 | })); | 983 | })); |
| 988 | }; | 984 | }; |
| 989 | return .{ .file = file.reader(reader_buffer) }; | 985 | resource.* = .{ .file = file.reader(reader_buffer) }; |
| | 986 | return; |
| 990 | } | 987 | } |
| 991 | | 988 | |
| 992 | const http_client = f.job_queue.http_client; | 989 | const http_client = f.job_queue.http_client; |
| ... | @@ -994,15 +991,21 @@ fn initResource(f: *Fetch, uri: std.Uri, reader_buffer: []u8) RunError!Resource | ... | @@ -994,15 +991,21 @@ fn initResource(f: *Fetch, uri: std.Uri, reader_buffer: []u8) RunError!Resource |
| 994 | if (ascii.eqlIgnoreCase(uri.scheme, "http") or | 991 | if (ascii.eqlIgnoreCase(uri.scheme, "http") or |
| 995 | ascii.eqlIgnoreCase(uri.scheme, "https")) | 992 | ascii.eqlIgnoreCase(uri.scheme, "https")) |
| 996 | { | 993 | { |
| 997 | var request = http_client.request(.GET, uri, .{}) catch |err| | 994 | resource.* = .{ .http_request = .{ |
| 998 | return f.fail(f.location_tok, try eb.printString("unable to connect to server: {t}", .{err})); | 995 | .request = http_client.request(.GET, uri, .{}) catch |err| |
| | 996 | return f.fail(f.location_tok, try eb.printString("unable to connect to server: {t}", .{err})), |
| | 997 | .response = undefined, |
| | 998 | .buffer = reader_buffer, |
| | 999 | } }; |
| | 1000 | const request = &resource.http_request.request; |
| 999 | defer request.deinit(); | 1001 | defer request.deinit(); |
| 1000 | | 1002 | |
| 1001 | request.sendBodiless() catch |err| | 1003 | request.sendBodiless() catch |err| |
| 1002 | return f.fail(f.location_tok, try eb.printString("HTTP request failed: {t}", .{err})); | 1004 | return f.fail(f.location_tok, try eb.printString("HTTP request failed: {t}", .{err})); |
| 1003 | | 1005 | |
| 1004 | var redirect_buffer: [1024]u8 = undefined; | 1006 | var redirect_buffer: [1024]u8 = undefined; |
| 1005 | const response = request.receiveHead(&redirect_buffer) catch |err| | 1007 | const response = &resource.http_request.response; |
| | 1008 | response.* = request.receiveHead(&redirect_buffer) catch |err| |
| 1006 | return f.fail(f.location_tok, try eb.printString("invalid HTTP response: {t}", .{err})); | 1009 | return f.fail(f.location_tok, try eb.printString("invalid HTTP response: {t}", .{err})); |
| 1007 | | 1010 | |
| 1008 | if (response.head.status != .ok) return f.fail(f.location_tok, try eb.printString( | 1011 | 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 | ... | @@ -1010,11 +1013,7 @@ fn initResource(f: *Fetch, uri: std.Uri, reader_buffer: []u8) RunError!Resource |
| 1010 | .{ response.head.status, response.head.status.phrase() orelse "" }, | 1013 | .{ response.head.status, response.head.status.phrase() orelse "" }, |
| 1011 | )); | 1014 | )); |
| 1012 | | 1015 | |
| 1013 | return .{ .http_request = .{ | 1016 | return; |
| 1014 | .request = request, | | |
| 1015 | .head = response.head, | | |
| 1016 | .buffer = reader_buffer, | | |
| 1017 | } }; | | |
| 1018 | } | 1017 | } |
| 1019 | | 1018 | |
| 1020 | if (ascii.eqlIgnoreCase(uri.scheme, "git+http") or | 1019 | if (ascii.eqlIgnoreCase(uri.scheme, "git+http") or |
| ... | @@ -1087,13 +1086,12 @@ fn initResource(f: *Fetch, uri: std.Uri, reader_buffer: []u8) RunError!Resource | ... | @@ -1087,13 +1086,12 @@ fn initResource(f: *Fetch, uri: std.Uri, reader_buffer: []u8) RunError!Resource |
| 1087 | }; | 1086 | }; |
| 1088 | errdefer fetch_stream.deinit(); | 1087 | errdefer fetch_stream.deinit(); |
| 1089 | | 1088 | |
| 1090 | if (true) @panic("TODO this moves fetch_stream, invalidating its reader"); | 1089 | resource.* = .{ .git = .{ |
| 1091 | | | |
| 1092 | return .{ .git = .{ | | |
| 1093 | .session = session, | 1090 | .session = session, |
| 1094 | .fetch_stream = fetch_stream, | 1091 | .fetch_stream = fetch_stream, |
| 1095 | .want_oid = want_oid, | 1092 | .want_oid = want_oid, |
| 1096 | } }; | 1093 | } }; |
| | 1094 | return; |
| 1097 | } | 1095 | } |
| 1098 | | 1096 | |
| 1099 | return f.fail(f.location_tok, try eb.printString("unsupported URL scheme: {s}", .{uri.scheme})); | 1097 | return f.fail(f.location_tok, try eb.printString("unsupported URL scheme: {s}", .{uri.scheme})); |
| ... | @@ -1111,7 +1109,7 @@ fn unpackResource( | ... | @@ -1111,7 +1109,7 @@ fn unpackResource( |
| 1111 | return f.fail(f.location_tok, try eb.printString("unknown file type: '{s}'", .{uri_path})), | 1109 | return f.fail(f.location_tok, try eb.printString("unknown file type: '{s}'", .{uri_path})), |
| 1112 | | 1110 | |
| 1113 | .http_request => |*http_request| ft: { | 1111 | .http_request => |*http_request| ft: { |
| 1114 | const head = &http_request.head; | 1112 | const head = &http_request.response.head; |
| 1115 | | 1113 | |
| 1116 | // Content-Type takes first precedence. | 1114 | // Content-Type takes first precedence. |
| 1117 | const content_type = head.content_type orelse | 1115 | const content_type = head.content_type orelse |