Skip to content

Commit 6600626

Browse files
committed
Reset CURLOPT_CUSTOMREQUEST for each request
1 parent 2522e7f commit 6600626

File tree

2 files changed

+31
-12
lines changed

2 files changed

+31
-12
lines changed

src/http/Client.zig

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -345,10 +345,8 @@ fn makeRequest(self: *Client, handle: *Handle, transfer: *Transfer) !void {
345345
try conn.setMethod(req.method);
346346
if (req.body) |b| {
347347
try conn.setBody(b);
348-
} else if (req.method == .POST) {
349-
// libcurl will crash if the method is POST but there's no body
350-
// TODO: is there a setting for that..seems weird.
351-
try conn.setBody("");
348+
} else {
349+
try errorCheck(c.curl_easy_setopt(easy, c.CURLOPT_HTTPGET, @as(c_long, 1)));
352350
}
353351

354352
var header_list = req.headers;

src/http/Http.zig

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -181,20 +181,41 @@ pub const Connection = struct {
181181
try errorCheck(c.curl_easy_setopt(self.easy, c.CURLOPT_URL, url.ptr));
182182
}
183183

184+
// a libcurl request has 2 methods. The first is the method that
185+
// controls how libcurl behaves. This specifically influences how redirects
186+
// are handled. For example, if you do a POST and get a 301, libcurl will
187+
// change that to a GET. But if you do a POST and get a 308, libcurl will
188+
// keep the POST (and re-send the body).
189+
// The second method is the actual string that's included in the request
190+
// headers.
191+
// These two methods can be different - you can tell curl to behave as though
192+
// you made a GET, but include "POST" in the request header.
193+
//
194+
// Here, we're only concerned about the 2nd method. If we want, we'll set
195+
// the first one based on whether or not we have a body.
196+
//
197+
// It's important that, for each use of this connection, we set the 2nd
198+
// method. Else, if we make a HEAD request and re-use the connection, but
199+
// DON'T reset this, it'll keep making HEAD requests.
200+
// (I don't know if it's as important to reset the 1st method, or if libcurl
201+
// can infer that based on the presence of the body, but we also reset it
202+
// to be safe);
184203
pub fn setMethod(self: *const Connection, method: Method) !void {
185204
const easy = self.easy;
186-
switch (method) {
187-
.GET => try errorCheck(c.curl_easy_setopt(easy, c.CURLOPT_HTTPGET, @as(c_long, 1))),
188-
.POST => try errorCheck(c.curl_easy_setopt(easy, c.CURLOPT_HTTPPOST, @as(c_long, 1))),
189-
.PUT => try errorCheck(c.curl_easy_setopt(easy, c.CURLOPT_CUSTOMREQUEST, "put")),
190-
.DELETE => try errorCheck(c.curl_easy_setopt(easy, c.CURLOPT_CUSTOMREQUEST, "delete")),
191-
.HEAD => try errorCheck(c.curl_easy_setopt(easy, c.CURLOPT_CUSTOMREQUEST, "head")),
192-
.OPTIONS => try errorCheck(c.curl_easy_setopt(easy, c.CURLOPT_CUSTOMREQUEST, "options")),
193-
}
205+
const m: [:0]const u8 = switch (method) {
206+
.GET => "GET",
207+
.POST => "POST",
208+
.PUT => "PUT",
209+
.DELETE => "DELETE",
210+
.HEAD => "HEAD",
211+
.OPTIONS => "OPTIONS",
212+
};
213+
try errorCheck(c.curl_easy_setopt(easy, c.CURLOPT_CUSTOMREQUEST, m.ptr));
194214
}
195215

196216
pub fn setBody(self: *const Connection, body: []const u8) !void {
197217
const easy = self.easy;
218+
try errorCheck(c.curl_easy_setopt(easy, c.CURLOPT_HTTPPOST, @as(c_long, 1)));
198219
try errorCheck(c.curl_easy_setopt(easy, c.CURLOPT_POSTFIELDSIZE, @as(c_long, @intCast(body.len))));
199220
try errorCheck(c.curl_easy_setopt(easy, c.CURLOPT_POSTFIELDS, body.ptr));
200221
}

0 commit comments

Comments
 (0)