Skip to content

Commit bc59417

Browse files
authored
Merge pull request #31 from bradcypert/bradcypert/#29-parse-http-version
parse HTTP version and use it in curl requests
2 parents 0785c2d + 466d8d0 commit bc59417

4 files changed

Lines changed: 38 additions & 3 deletions

File tree

build.zig.zon

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@
4545
.hash = "regex-0.1.2-axC350bnAQCyrPkH2IEfri8hebJO6IujGY1rhcgZBXpL",
4646
},
4747
.curl = .{
48-
.url = "git+https://github.com/jiacai2050/zig-curl/?ref=HEAD#df369a2925a57446cb3147def4e11e6782452dbd",
49-
.hash = "curl-0.3.1-P4tT4X_LAAB-rzh6tsg_j9OSokOCTt6pK4DxFUYUwC7K",
48+
.url = "git+https://github.com/jiacai2050/zig-curl/?ref=HEAD#1a23d311582c1e72bdb9ec3020f82b8e2a4b8c8a",
49+
.hash = "curl-0.3.1-P4tT4cPNAAAZsLz5AsgitsBp3W0uVpoFT7IeNX2qOQlP",
5050
},
5151
},
5252
.paths = .{

src/httpfile/assertion_checker.zig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,7 @@ test "Assertion checker with diagnostics - all pass" {
327327
.headers = .empty,
328328
.assertions = assertions,
329329
.body = null,
330+
.version = .@"HTTP/1.1",
330331
};
331332

332333
var response_headers = std.StringHashMap([]const u8).init(allocator);
@@ -381,6 +382,7 @@ test "Assertion checker with not_equal - all pass" {
381382
.headers = .empty,
382383
.assertions = assertions,
383384
.body = null,
385+
.version = .@"HTTP/1.1",
384386
};
385387

386388
var response_headers = std.StringHashMap([]const u8).init(allocator);
@@ -435,6 +437,7 @@ test "Assertion checker with failures - collects all failures" {
435437
.headers = .empty,
436438
.assertions = assertions,
437439
.body = null,
440+
.version = .@"HTTP/1.1",
438441
};
439442

440443
var response_headers = std.StringHashMap([]const u8).init(allocator);
@@ -493,6 +496,7 @@ test "HttpParser supports starts_with for status, body, and header" {
493496
.headers = .empty,
494497
.assertions = assertions,
495498
.body = null,
499+
.version = .@"HTTP/1.1",
496500
};
497501

498502
var response_headers = std.StringHashMap([]const u8).init(allocator);
@@ -556,6 +560,7 @@ test "HttpParser supports matches_regex and not_matches_regex for status, body,
556560
.headers = .empty,
557561
.assertions = assertions,
558562
.body = null,
563+
.version = .@"HTTP/1.1",
559564
};
560565

561566
var response_headers = std.StringHashMap([]const u8).init(allocator);
@@ -605,6 +610,7 @@ test "HttpParser supports contains and not_contains for headers" {
605610
.headers = .empty,
606611
.assertions = assertions,
607612
.body = null,
613+
.version = .@"HTTP/1.1",
608614
};
609615

610616
var response_headers = std.StringHashMap([]const u8).init(allocator);

src/httpfile/http_client.zig

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ pub const HttpClient = struct {
7070
const easy = try curl.Easy.init(.{
7171
.ca_bundle = ca_bundle,
7272
});
73+
7374
defer easy.deinit();
7475

7576
var writer = std.Io.Writer.Allocating.init(self.allocator);
@@ -90,6 +91,20 @@ pub const HttpClient = struct {
9091

9192
const url = try self.allocator.dupeZ(u8, request.url);
9293
defer self.allocator.free(url);
94+
switch (request.version) {
95+
.@"HTTP/1.0" => {
96+
try easy.setHttpVersion(.http1_0);
97+
},
98+
.@"HTTP/1.1" => {
99+
try easy.setHttpVersion(.http1_1);
100+
},
101+
.@"HTTP/2" => {
102+
try easy.setHttpVersion(.http2);
103+
},
104+
.@"HTTP/3" => {
105+
try easy.setHttpVersion(.http3);
106+
},
107+
}
93108
const resp = try easy.fetch(url, .{
94109
.method = try map_method_for_curl(request.method orelse return error.RequestMethodNotSet),
95110
// TODO: Is it possible to remove the ptrCast?

src/httpfile/parser.zig

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,21 @@ pub const Assertion = struct {
3636
assertion_type: AssertionType,
3737
};
3838

39+
pub const HttpVersion = enum {
40+
@"HTTP/1.0",
41+
@"HTTP/1.1",
42+
@"HTTP/2",
43+
@"HTTP/3",
44+
};
45+
3946
pub const HttpRequest = struct {
4047
// TODO: Null HTTP METHOD SHOULD NOT BE CRITICAL TO PROPERLY PARSING
4148
method: ?http.Method,
4249
url: []const u8,
4350
headers: ArrayList(http.Header),
4451
body: ?[]u8,
4552
assertions: ArrayList(Assertion),
53+
version: HttpVersion,
4654
// TODO: Add a name for the request if needed.
4755

4856
pub fn init() HttpRequest {
@@ -52,6 +60,7 @@ pub const HttpRequest = struct {
5260
.headers = .empty,
5361
.body = null,
5462
.assertions = .empty,
63+
.version = .@"HTTP/1.1",
5564
};
5665
}
5766

@@ -136,8 +145,12 @@ pub fn parseContent(allocator: Allocator, content: []const u8) !ArrayList(HttpRe
136145
var tokens = std.mem.tokenizeScalar(u8, trimmed_line, ' ');
137146
const method_str = tokens.next() orelse return error.InvalidRequestMissingMethod;
138147
const url = tokens.next() orelse return error.InvalidRequestMissingURL;
148+
const version = tokens.next();
139149
current_request.method = std.meta.stringToEnum(http.Method, method_str) orelse null;
140150
current_request.url = try allocator.dupe(u8, url);
151+
if (version) |v| {
152+
current_request.version = std.meta.stringToEnum(HttpVersion, v) orelse return error.InvalidHttpVersion;
153+
}
141154
state = .headers;
142155
continue;
143156
}
@@ -171,7 +184,7 @@ pub fn parseContent(allocator: Allocator, content: []const u8) !ArrayList(HttpRe
171184

172185
test "HttpParser from String Contents" {
173186
const test_http_contents =
174-
\\GET https://api.example.com
187+
\\GET https://api.example.com HTTP/3
175188
\\Accept: */*
176189
\\Authorization: Bearer ABC123
177190
\\
@@ -199,6 +212,7 @@ test "HttpParser from String Contents" {
199212
try std.testing.expectEqual(http.Method.POST, requests.items[1].method);
200213
try std.testing.expectEqualStrings("https://api.example.com", requests.items[0].url);
201214
try std.testing.expectEqualStrings("https://api.example.com/users", requests.items[1].url);
215+
try std.testing.expectEqual(HttpVersion.@"HTTP/3", requests.items[0].version);
202216
try std.testing.expectEqualStrings("Authorization", requests.items[0].headers.items[1].name);
203217
try std.testing.expectEqualStrings("Bearer ABC123", requests.items[0].headers.items[1].value);
204218
try std.testing.expectEqualStrings("Authorization", requests.items[1].headers.items[1].name);

0 commit comments

Comments
 (0)