Commit fcca3cd1a3
Changed files (4)
lib/std/http/Client.zig
@@ -538,8 +538,13 @@ pub const Request = struct {
pub const StartError = Connection.WriteError || error{ InvalidContentLength, UnsupportedTransferEncoding };
+ pub const StartOptions = struct {
+ /// Specifies that the uri should be used as is
+ raw_uri: bool = false,
+ };
+
/// Send the request to the server.
- pub fn start(req: *Request) StartError!void {
+ pub fn start(req: *Request, options: StartOptions) StartError!void {
if (!req.method.requestHasBody() and req.transfer_encoding != .none) return error.UnsupportedTransferEncoding;
var buffered = std.io.bufferedWriter(req.connection.?.data.writer());
@@ -552,13 +557,22 @@ pub const Request = struct {
try w.writeAll(req.uri.host.?);
try w.writeByte(':');
try w.print("{}", .{req.uri.port.?});
- } else if (req.connection.?.data.proxied) {
- // proxied connections require the full uri
- try w.print("{+/}", .{req.uri});
} else {
- try w.print("{/}", .{req.uri});
+ if (req.connection.?.data.proxied) {
+ // proxied connections require the full uri
+ if (options.raw_uri) {
+ try w.print("{+/r}", .{req.uri});
+ } else {
+ try w.print("{+/}", .{req.uri});
+ }
+ } else {
+ if (options.raw_uri) {
+ try w.print("{/r}", .{req.uri});
+ } else {
+ try w.print("{/}", .{req.uri});
+ }
+ }
}
-
try w.writeByte(' ');
try w.writeAll(@tagName(req.version));
try w.writeAll("\r\n");
@@ -757,7 +771,7 @@ pub const Request = struct {
try req.redirect(resolved_url);
- try req.start();
+ try req.start(.{});
} else {
req.response.skip = false;
if (!req.response.parser.done) {
@@ -1141,6 +1155,7 @@ pub const FetchOptions = struct {
method: http.Method = .GET,
headers: http.Headers = http.Headers{ .allocator = std.heap.page_allocator, .owned = false },
payload: Payload = .none,
+ raw_uri: bool = false,
};
pub const FetchResult = struct {
@@ -1188,7 +1203,7 @@ pub fn fetch(client: *Client, allocator: Allocator, options: FetchOptions) !Fetc
.none => {},
}
- try req.start();
+ try req.start(.{ .raw_uri = options.raw_uri });
switch (options.payload) {
.string => |str| try req.writeAll(str),
lib/std/Uri.zig
@@ -216,6 +216,7 @@ pub fn format(
const needs_absolute = comptime std.mem.indexOf(u8, fmt, "+") != null;
const needs_path = comptime std.mem.indexOf(u8, fmt, "/") != null or fmt.len == 0;
+ const raw_uri = comptime std.mem.indexOf(u8, fmt, "r") != null;
const needs_fragment = comptime std.mem.indexOf(u8, fmt, "#") != null;
if (needs_absolute) {
@@ -246,18 +247,30 @@ pub fn format(
if (uri.path.len == 0) {
try writer.writeAll("/");
} else {
- try Uri.writeEscapedPath(writer, uri.path);
+ if (raw_uri) {
+ try writer.writeAll(uri.path);
+ } else {
+ try Uri.writeEscapedPath(writer, uri.path);
+ }
}
if (uri.query) |q| {
try writer.writeAll("?");
- try Uri.writeEscapedQuery(writer, q);
+ if (raw_uri) {
+ try writer.writeAll(q);
+ } else {
+ try Uri.writeEscapedQuery(writer, q);
+ }
}
if (needs_fragment) {
if (uri.fragment) |f| {
try writer.writeAll("#");
- try Uri.writeEscapedQuery(writer, f);
+ if (raw_uri) {
+ try writer.writeAll(f);
+ } else {
+ try Uri.writeEscapedQuery(writer, f);
+ }
}
}
}
src/Package.zig
@@ -653,7 +653,7 @@ fn fetchAndUnpack(
var req = try http_client.request(.GET, uri, h, .{});
defer req.deinit();
- try req.start();
+ try req.start(.{});
try req.wait();
if (req.response.status != .ok) {
test/standalone/http.zig
@@ -240,7 +240,7 @@ pub fn main() !void {
var req = try client.request(.GET, uri, h, .{});
defer req.deinit();
- try req.start();
+ try req.start(.{});
try req.wait();
const body = try req.reader().readAllAlloc(calloc, 8192);
@@ -265,7 +265,7 @@ pub fn main() !void {
var req = try client.request(.GET, uri, h, .{});
defer req.deinit();
- try req.start();
+ try req.start(.{});
try req.wait();
const body = try req.reader().readAllAlloc(calloc, 8192 * 1024);
@@ -289,7 +289,7 @@ pub fn main() !void {
var req = try client.request(.HEAD, uri, h, .{});
defer req.deinit();
- try req.start();
+ try req.start(.{});
try req.wait();
const body = try req.reader().readAllAlloc(calloc, 8192);
@@ -315,7 +315,7 @@ pub fn main() !void {
var req = try client.request(.GET, uri, h, .{});
defer req.deinit();
- try req.start();
+ try req.start(.{});
try req.wait();
const body = try req.reader().readAllAlloc(calloc, 8192);
@@ -340,7 +340,7 @@ pub fn main() !void {
var req = try client.request(.HEAD, uri, h, .{});
defer req.deinit();
- try req.start();
+ try req.start(.{});
try req.wait();
const body = try req.reader().readAllAlloc(calloc, 8192);
@@ -366,7 +366,7 @@ pub fn main() !void {
var req = try client.request(.GET, uri, h, .{});
defer req.deinit();
- try req.start();
+ try req.start(.{});
try req.wait();
const body = try req.reader().readAllAlloc(calloc, 8192);
@@ -395,7 +395,7 @@ pub fn main() !void {
req.transfer_encoding = .{ .content_length = 14 };
- try req.start();
+ try req.start(.{});
try req.writeAll("Hello, ");
try req.writeAll("World!\n");
try req.finish();
@@ -425,7 +425,7 @@ pub fn main() !void {
var req = try client.request(.GET, uri, h, .{});
defer req.deinit();
- try req.start();
+ try req.start(.{});
try req.wait();
const body = try req.reader().readAllAlloc(calloc, 8192);
@@ -454,7 +454,7 @@ pub fn main() !void {
req.transfer_encoding = .chunked;
- try req.start();
+ try req.start(.{});
try req.writeAll("Hello, ");
try req.writeAll("World!\n");
try req.finish();
@@ -482,7 +482,7 @@ pub fn main() !void {
var req = try client.request(.GET, uri, h, .{});
defer req.deinit();
- try req.start();
+ try req.start(.{});
try req.wait();
const body = try req.reader().readAllAlloc(calloc, 8192);
@@ -506,7 +506,7 @@ pub fn main() !void {
var req = try client.request(.GET, uri, h, .{});
defer req.deinit();
- try req.start();
+ try req.start(.{});
try req.wait();
const body = try req.reader().readAllAlloc(calloc, 8192);
@@ -530,7 +530,7 @@ pub fn main() !void {
var req = try client.request(.GET, uri, h, .{});
defer req.deinit();
- try req.start();
+ try req.start(.{});
try req.wait();
const body = try req.reader().readAllAlloc(calloc, 8192);
@@ -554,7 +554,7 @@ pub fn main() !void {
var req = try client.request(.GET, uri, h, .{});
defer req.deinit();
- try req.start();
+ try req.start(.{});
req.wait() catch |err| switch (err) {
error.TooManyHttpRedirects => {},
else => return err,
@@ -576,7 +576,7 @@ pub fn main() !void {
var req = try client.request(.GET, uri, h, .{});
defer req.deinit();
- try req.start();
+ try req.start(.{});
const result = req.wait();
try testing.expectError(error.ConnectionRefused, result); // expects not segfault but the regular error
@@ -623,7 +623,7 @@ pub fn main() !void {
req.transfer_encoding = .chunked;
- try req.start();
+ try req.start(.{});
try req.wait();
try testing.expectEqual(http.Status.@"continue", req.response.status);
@@ -657,7 +657,7 @@ pub fn main() !void {
req.transfer_encoding = .chunked;
- try req.start();
+ try req.start(.{});
try req.wait();
try testing.expectEqual(http.Status.expectation_failed, req.response.status);
}