@@ -9,9 +9,8 @@ const net = std.net;
99const Client = @This ();
1010const Url = std .Url ;
1111
12+ /// TODO: remove this field (currently required due to tcpConnectToHost)
1213allocator : std.mem.Allocator ,
13- headers : std .ArrayListUnmanaged (u8 ) = .{},
14- active_requests : usize = 0 ,
1514ca_bundle : std.crypto.Certificate.Bundle = .{},
1615
1716/// TODO: emit error.UnexpectedEndOfStream or something like that when the read
@@ -20,44 +19,23 @@ ca_bundle: std.crypto.Certificate.Bundle = .{},
2019pub const Request = struct {
2120 client : * Client ,
2221 stream : net.Stream ,
23- headers : std .ArrayListUnmanaged (u8 ) = .{},
2422 tls_client : std.crypto.tls.Client ,
2523 protocol : Protocol ,
2624 response_headers : http.Headers = .{},
2725
28- pub const Protocol = enum { http , https };
29-
30- pub const Options = struct {
26+ pub const Headers = struct {
3127 method : http.Method = .GET ,
32- };
28+ connection : Connection ,
3329
34- pub fn deinit ( req : * Request ) void {
35- req . client . active_requests -= 1 ;
36- req . headers . deinit ( req . client . allocator );
37- req .* = undefined ;
38- }
30+ pub const Connection = enum {
31+ close ,
32+ @ "keep-alive" ,
33+ } ;
34+ };
3935
40- pub fn addHeader (req : * Request , name : []const u8 , value : []const u8 ) ! void {
41- const gpa = req .client .allocator ;
42- // Ensure an extra +2 for the \r\n in end()
43- try req .headers .ensureUnusedCapacity (gpa , name .len + value .len + 6 );
44- req .headers .appendSliceAssumeCapacity (name );
45- req .headers .appendSliceAssumeCapacity (": " );
46- req .headers .appendSliceAssumeCapacity (value );
47- req .headers .appendSliceAssumeCapacity ("\r \n " );
48- }
36+ pub const Protocol = enum { http , https };
4937
50- pub fn end (req : * Request ) ! void {
51- req .headers .appendSliceAssumeCapacity ("\r \n " );
52- switch (req .protocol ) {
53- .http = > {
54- try req .stream .writeAll (req .headers .items );
55- },
56- .https = > {
57- try req .tls_client .writeAll (req .stream , req .headers .items );
58- },
59- }
60- }
38+ pub const Options = struct {};
6139
6240 pub fn readAll (req : * Request , buffer : []u8 ) ! usize {
6341 return readAtLeast (req , buffer , buffer .len );
@@ -113,13 +91,14 @@ pub const Request = struct {
11391 }
11492};
11593
116- pub fn deinit (client : * Client ) void {
117- assert (client .active_requests == 0 );
118- client .headers .deinit (client .allocator );
94+ pub fn deinit (client : * Client , gpa : std.mem.Allocator ) void {
95+ client .ca_bundle .deinit (gpa );
11996 client .* = undefined ;
12097}
12198
122- pub fn request (client : * Client , url : Url , options : Request.Options ) ! Request {
99+ pub fn request (client : * Client , url : Url , headers : Request.Headers , options : Request.Options ) ! Request {
100+ _ = options ; // we have no options yet
101+
123102 const protocol = std .meta .stringToEnum (Request .Protocol , url .scheme ) orelse
124103 return error .UnsupportedUrlScheme ;
125104 const port : u16 = url .port orelse switch (protocol ) {
@@ -133,8 +112,6 @@ pub fn request(client: *Client, url: Url, options: Request.Options) !Request {
133112 .protocol = protocol ,
134113 .tls_client = undefined ,
135114 };
136- client .active_requests += 1 ;
137- errdefer req .deinit ();
138115
139116 switch (protocol ) {
140117 .http = > {},
@@ -146,36 +123,30 @@ pub fn request(client: *Client, url: Url, options: Request.Options) !Request {
146123 },
147124 }
148125
149- try req .headers .ensureUnusedCapacity (
150- client .allocator ,
151- @tagName (options .method ).len +
152- 1 +
153- url .path .len +
154- " HTTP/1.1\r \n Host: " .len +
155- url .host .len +
156- "\r \n Upgrade-Insecure-Requests: 1\r \n " .len +
157- client .headers .items .len +
158- 2 , // for the \r\n at the end of headers
159- );
160- req .headers .appendSliceAssumeCapacity (@tagName (options .method ));
161- req .headers .appendSliceAssumeCapacity (" " );
162- req .headers .appendSliceAssumeCapacity (url .path );
163- req .headers .appendSliceAssumeCapacity (" HTTP/1.1\r \n Host: " );
164- req .headers .appendSliceAssumeCapacity (url .host );
165- switch (protocol ) {
166- .https = > req .headers .appendSliceAssumeCapacity ("\r \n Upgrade-Insecure-Requests: 1\r \n " ),
167- .http = > req .headers .appendSliceAssumeCapacity ("\r \n " ),
126+ {
127+ var h = try std .BoundedArray (u8 , 1000 ).init (0 );
128+ try h .appendSlice (@tagName (headers .method ));
129+ try h .appendSlice (" " );
130+ try h .appendSlice (url .path );
131+ try h .appendSlice (" HTTP/1.1\r \n Host: " );
132+ try h .appendSlice (url .host );
133+ switch (protocol ) {
134+ .https = > try h .appendSlice ("\r \n Upgrade-Insecure-Requests: 1\r \n " ),
135+ .http = > try h .appendSlice ("\r \n " ),
136+ }
137+ try h .writer ().print ("Connection: {s}\r \n " , .{@tagName (headers .connection )});
138+ try h .appendSlice ("\r \n " );
139+
140+ const header_bytes = h .slice ();
141+ switch (req .protocol ) {
142+ .http = > {
143+ try req .stream .writeAll (header_bytes );
144+ },
145+ .https = > {
146+ try req .tls_client .writeAll (req .stream , header_bytes );
147+ },
148+ }
168149 }
169- req .headers .appendSliceAssumeCapacity (client .headers .items );
170150
171151 return req ;
172152}
173-
174- pub fn addHeader (client : * Client , name : []const u8 , value : []const u8 ) ! void {
175- const gpa = client .allocator ;
176- try client .headers .ensureUnusedCapacity (gpa , name .len + value .len + 4 );
177- client .headers .appendSliceAssumeCapacity (name );
178- client .headers .appendSliceAssumeCapacity (": " );
179- client .headers .appendSliceAssumeCapacity (value );
180- client .headers .appendSliceAssumeCapacity ("\r \n " );
181- }
0 commit comments