authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-02-16 18:50:38-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-02-23 02:37:11-07:00
logf9dff2fcf1d5c6df1d6b935c4eb536793148a9d9
treec48b4e45e64d6cf72e802815491ffaa1607c4fb1
parent78192637fba21c1cc6fca364be716795e4e44020

std.http: fields at the top of the struct

Perhaps the language should enforce this.

2 files changed, 77 insertions(+), 77 deletions(-)

lib/std/http/Client.zig+62-62
...@@ -44,6 +44,14 @@ https_proxy: ?*Proxy = null,...@@ -44,6 +44,14 @@ https_proxy: ?*Proxy = null,
4444
45/// A set of linked lists of connections that can be reused.45/// A set of linked lists of connections that can be reused.
46pub const ConnectionPool = struct {46pub const ConnectionPool = struct {
47 mutex: std.Thread.Mutex = .{},
48 /// Open connections that are currently in use.
49 used: Queue = .{},
50 /// Open connections that are not currently in use.
51 free: Queue = .{},
52 free_len: usize = 0,
53 free_size: usize = 32,
54
47 /// The criteria for a connection to be considered a match.55 /// The criteria for a connection to be considered a match.
48 pub const Criteria = struct {56 pub const Criteria = struct {
49 host: []const u8,57 host: []const u8,
...@@ -54,14 +62,6 @@ pub const ConnectionPool = struct {...@@ -54,14 +62,6 @@ pub const ConnectionPool = struct {
54 const Queue = std.DoublyLinkedList(Connection);62 const Queue = std.DoublyLinkedList(Connection);
55 pub const Node = Queue.Node;63 pub const Node = Queue.Node;
5664
57 mutex: std.Thread.Mutex = .{},
58 /// Open connections that are currently in use.
59 used: Queue = .{},
60 /// Open connections that are not currently in use.
61 free: Queue = .{},
62 free_len: usize = 0,
63 free_size: usize = 32,
64
65 /// Finds and acquires a connection from the connection pool matching the criteria. This function is threadsafe.65 /// Finds and acquires a connection from the connection pool matching the criteria. This function is threadsafe.
66 /// If no connection is found, null is returned.66 /// If no connection is found, null is returned.
67 pub fn findConnection(pool: *ConnectionPool, criteria: Criteria) ?*Connection {67 pub fn findConnection(pool: *ConnectionPool, criteria: Criteria) ?*Connection {
...@@ -190,11 +190,6 @@ pub const ConnectionPool = struct {...@@ -190,11 +190,6 @@ pub const ConnectionPool = struct {
190190
191/// An interface to either a plain or TLS connection.191/// An interface to either a plain or TLS connection.
192pub const Connection = struct {192pub const Connection = struct {
193 pub const buffer_size = std.crypto.tls.max_ciphertext_record_len;
194 const BufferSize = std.math.IntFittingRange(0, buffer_size);
195
196 pub const Protocol = enum { plain, tls };
197
198 stream: net.Stream,193 stream: net.Stream,
199 /// undefined unless protocol is tls.194 /// undefined unless protocol is tls.
200 tls_client: if (!disable_tls) *std.crypto.tls.Client else void,195 tls_client: if (!disable_tls) *std.crypto.tls.Client else void,
...@@ -220,6 +215,11 @@ pub const Connection = struct {...@@ -220,6 +215,11 @@ pub const Connection = struct {
220 read_buf: [buffer_size]u8 = undefined,215 read_buf: [buffer_size]u8 = undefined,
221 write_buf: [buffer_size]u8 = undefined,216 write_buf: [buffer_size]u8 = undefined,
222217
218 pub const buffer_size = std.crypto.tls.max_ciphertext_record_len;
219 const BufferSize = std.math.IntFittingRange(0, buffer_size);
220
221 pub const Protocol = enum { plain, tls };
222
223 pub fn readvDirectTls(conn: *Connection, buffers: []std.os.iovec) ReadError!usize {223 pub fn readvDirectTls(conn: *Connection, buffers: []std.os.iovec) ReadError!usize {
224 return conn.tls_client.readv(conn.stream, buffers) catch |err| {224 return conn.tls_client.readv(conn.stream, buffers) catch |err| {
225 // https://github.com/ziglang/zig/issues/2473225 // https://github.com/ziglang/zig/issues/2473
...@@ -419,6 +419,35 @@ pub const Compression = union(enum) {...@@ -419,6 +419,35 @@ pub const Compression = union(enum) {
419419
420/// A HTTP response originating from a server.420/// A HTTP response originating from a server.
421pub const Response = struct {421pub const Response = struct {
422 version: http.Version,
423 status: http.Status,
424 reason: []const u8,
425
426 /// Points into the user-provided `server_header_buffer`.
427 location: ?[]const u8 = null,
428 /// Points into the user-provided `server_header_buffer`.
429 content_type: ?[]const u8 = null,
430 /// Points into the user-provided `server_header_buffer`.
431 content_disposition: ?[]const u8 = null,
432
433 keep_alive: bool = false,
434
435 /// If present, the number of bytes in the response body.
436 content_length: ?u64 = null,
437
438 /// If present, the transfer encoding of the response body, otherwise none.
439 transfer_encoding: http.TransferEncoding = .none,
440
441 /// If present, the compression of the response body, otherwise identity (no compression).
442 transfer_compression: http.ContentEncoding = .identity,
443
444 parser: proto.HeadersParser,
445 compression: Compression = .none,
446
447 /// Whether the response body should be skipped. Any data read from the
448 /// response body will be discarded.
449 skip: bool = false,
450
422 pub const ParseError = error{451 pub const ParseError = error{
423 HttpHeadersInvalid,452 HttpHeadersInvalid,
424 HttpHeaderContinuationsUnsupported,453 HttpHeaderContinuationsUnsupported,
...@@ -542,35 +571,6 @@ pub const Response = struct {...@@ -542,35 +571,6 @@ pub const Response = struct {
542 pub fn iterateHeaders(r: Response) proto.HeaderIterator {571 pub fn iterateHeaders(r: Response) proto.HeaderIterator {
543 return proto.HeaderIterator.init(r.parser.get());572 return proto.HeaderIterator.init(r.parser.get());
544 }573 }
545
546 version: http.Version,
547 status: http.Status,
548 reason: []const u8,
549
550 /// Points into the user-provided `server_header_buffer`.
551 location: ?[]const u8 = null,
552 /// Points into the user-provided `server_header_buffer`.
553 content_type: ?[]const u8 = null,
554 /// Points into the user-provided `server_header_buffer`.
555 content_disposition: ?[]const u8 = null,
556
557 keep_alive: bool = false,
558
559 /// If present, the number of bytes in the response body.
560 content_length: ?u64 = null,
561
562 /// If present, the transfer encoding of the response body, otherwise none.
563 transfer_encoding: http.TransferEncoding = .none,
564
565 /// If present, the compression of the response body, otherwise identity (no compression).
566 transfer_compression: http.ContentEncoding = .identity,
567
568 parser: proto.HeadersParser,
569 compression: Compression = .none,
570
571 /// Whether the response body should be skipped. Any data read from the
572 /// response body will be discarded.
573 skip: bool = false,
574};574};
575575
576/// A HTTP request that has been sent.576/// A HTTP request that has been sent.
...@@ -1558,6 +1558,26 @@ pub fn open(...@@ -1558,6 +1558,26 @@ pub fn open(
1558}1558}
15591559
1560pub const FetchOptions = struct {1560pub const FetchOptions = struct {
1561 server_header_buffer: ?[]u8 = null,
1562 response_strategy: ResponseStrategy = .{ .storage = .{ .dynamic = 16 * 1024 * 1024 } },
1563 redirect_behavior: ?Request.RedirectBehavior = null,
1564
1565 location: Location,
1566 method: http.Method = .GET,
1567 payload: Payload = .none,
1568 raw_uri: bool = false,
1569
1570 /// Standard headers that have default, but overridable, behavior.
1571 headers: Request.Headers = .{},
1572 /// These headers are kept including when following a redirect to a
1573 /// different domain.
1574 /// Externally-owned; must outlive the Request.
1575 extra_headers: []const http.Header = &.{},
1576 /// These headers are stripped when following a redirect to a different
1577 /// domain.
1578 /// Externally-owned; must outlive the Request.
1579 privileged_headers: []const http.Header = &.{},
1580
1561 pub const Location = union(enum) {1581 pub const Location = union(enum) {
1562 url: []const u8,1582 url: []const u8,
1563 uri: Uri,1583 uri: Uri,
...@@ -1587,26 +1607,6 @@ pub const FetchOptions = struct {...@@ -1587,26 +1607,6 @@ pub const FetchOptions = struct {
1587 /// cannot be returned from `read()`.1607 /// cannot be returned from `read()`.
1588 static: []u8,1608 static: []u8,
1589 };1609 };
1590
1591 server_header_buffer: ?[]u8 = null,
1592 response_strategy: ResponseStrategy = .{ .storage = .{ .dynamic = 16 * 1024 * 1024 } },
1593 redirect_behavior: ?Request.RedirectBehavior = null,
1594
1595 location: Location,
1596 method: http.Method = .GET,
1597 payload: Payload = .none,
1598 raw_uri: bool = false,
1599
1600 /// Standard headers that have default, but overridable, behavior.
1601 headers: Request.Headers = .{},
1602 /// These headers are kept including when following a redirect to a
1603 /// different domain.
1604 /// Externally-owned; must outlive the Request.
1605 extra_headers: []const http.Header = &.{},
1606 /// These headers are stripped when following a redirect to a different
1607 /// domain.
1608 /// Externally-owned; must outlive the Request.
1609 privileged_headers: []const http.Header = &.{},
1610};1610};
16111611
1612pub const FetchResult = struct {1612pub const FetchResult = struct {
lib/std/http/Server.zig+15-15
...@@ -21,9 +21,6 @@ socket: net.StreamServer,...@@ -21,9 +21,6 @@ socket: net.StreamServer,
2121
22/// An interface to a plain connection.22/// An interface to a plain connection.
23pub const Connection = struct {23pub const Connection = struct {
24 pub const buffer_size = std.crypto.tls.max_ciphertext_record_len;
25 pub const Protocol = enum { plain };
26
27 stream: net.Stream,24 stream: net.Stream,
28 protocol: Protocol,25 protocol: Protocol,
2926
...@@ -33,6 +30,9 @@ pub const Connection = struct {...@@ -33,6 +30,9 @@ pub const Connection = struct {
33 read_start: u16 = 0,30 read_start: u16 = 0,
34 read_end: u16 = 0,31 read_end: u16 = 0,
3532
33 pub const buffer_size = std.crypto.tls.max_ciphertext_record_len;
34 pub const Protocol = enum { plain };
35
36 pub fn rawReadAtLeast(conn: *Connection, buffer: []u8, len: usize) ReadError!usize {36 pub fn rawReadAtLeast(conn: *Connection, buffer: []u8, len: usize) ReadError!usize {
37 return switch (conn.protocol) {37 return switch (conn.protocol) {
38 .plain => conn.stream.readAtLeast(buffer, len),38 .plain => conn.stream.readAtLeast(buffer, len),
...@@ -174,6 +174,18 @@ pub const Compression = union(enum) {...@@ -174,6 +174,18 @@ pub const Compression = union(enum) {
174174
175/// A HTTP request originating from a client.175/// A HTTP request originating from a client.
176pub const Request = struct {176pub const Request = struct {
177 method: http.Method,
178 target: []const u8,
179 version: http.Version,
180 expect: ?[]const u8 = null,
181 content_type: ?[]const u8 = null,
182 content_length: ?u64 = null,
183 transfer_encoding: http.TransferEncoding = .none,
184 transfer_compression: http.ContentEncoding = .identity,
185 keep_alive: bool = false,
186 parser: proto.HeadersParser,
187 compression: Compression = .none,
188
177 pub const ParseError = Allocator.Error || error{189 pub const ParseError = Allocator.Error || error{
178 UnknownHttpMethod,190 UnknownHttpMethod,
179 HttpHeadersInvalid,191 HttpHeadersInvalid,
...@@ -284,18 +296,6 @@ pub const Request = struct {...@@ -284,18 +296,6 @@ pub const Request = struct {
284 inline fn int64(array: *const [8]u8) u64 {296 inline fn int64(array: *const [8]u8) u64 {
285 return @bitCast(array.*);297 return @bitCast(array.*);
286 }298 }
287
288 method: http.Method,
289 target: []const u8,
290 version: http.Version,
291 expect: ?[]const u8 = null,
292 content_type: ?[]const u8 = null,
293 content_length: ?u64 = null,
294 transfer_encoding: http.TransferEncoding = .none,
295 transfer_compression: http.ContentEncoding = .identity,
296 keep_alive: bool = false,
297 parser: proto.HeadersParser,
298 compression: Compression = .none,
299};299};
300300
301/// A HTTP response waiting to be sent.301/// A HTTP response waiting to be sent.