authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-05-22 16:41:20 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-05-22 16:41:20 -07:00
log9ccbbac07fbd2b1a809bfb0efee976fb32cd6827
tree94bf34a9b44036861f5263ff6ff23e6b2c1ea1da
parent66d9d679be21986327733d0b3915d6ea42eede84
signaturebadge-check Signed by SSH key SHA256:4hHJbtBRU58AYXwjL7fkz2fnQHdiye8x1QpTCQ0sHNw

use the stdlib http client


3 files changed, 42 insertions(+), 27 deletions(-)

licenses.txt-3
......@@ -1,14 +1,11 @@
11MIT:
22= https://spdx.org/licenses/MIT
33- This
4- git https://github.com/nektro/iguanaTLS
5- git https://github.com/nektro/zfetch
64- git https://github.com/nektro/zig-extras
75- git https://github.com/nektro/zig-sys-linux
86- git https://github.com/nektro/zig-time
97- git https://github.com/nektro/zig-tracer
108- git https://github.com/nektro/zig-unicode-ucd
11- git https://github.com/truemedian/hzzp
129- git https://github.com/kivikakk/htmlentities.zig
1310
1411MPL-2.0:
oauth2.zig+42-23
......@@ -4,7 +4,6 @@ const std = @import("std");
44const string = []const u8;
55const files = @import("./files.zig");
66const pek = @import("pek");
7const zfetch = @import("zfetch");
87const extras = @import("extras");
98const url = @import("url");
109const http = @import("http");
......@@ -299,6 +298,10 @@ pub fn Handlers(comptime T: type) type {
299298 const client = clientByProviderId(Self.clients, state) orelse return try fail(response_status, body_writer, "error: No handler found for provider: {s}\n", .{state});
300299 const code = query.get("code") orelse return try fail(response_status, body_writer, "", .{});
301300
301 var buf: [4096]u8 = @splat(0);
302 var http_client: std.http.Client = .{ .allocator = alloc };
303 defer http_client.deinit();
304
302305 var params = url.SearchParams.init(alloc);
303306 try params.append("client_id", client.id);
304307 try params.append("client_secret", client.secret);
......@@ -306,19 +309,28 @@ pub fn Handlers(comptime T: type) type {
306309 try params.append("code", code);
307310 try params.append("redirect_uri", try redirectUri(request_headers, alloc, T.callbackPath));
308311 try params.append("state", "none");
312 const req_body = try params.encode();
309313
310 const req = try zfetch.Request.init(alloc, client.provider.token_url, null);
311
312 var headers = zfetch.Headers.init(alloc);
313 try headers.appendValue("Content-Type", "application/x-www-form-urlencoded");
314 try headers.appendValue("Authorization", try std.fmt.allocPrint(alloc, "Basic {s}", .{try extras.base64EncodeAlloc(alloc, try std.mem.join(alloc, ":", &.{ client.id, client.secret }))}));
315 try headers.appendValue("Accept", "application/json");
316
317 try req.do(.POST, headers, try params.encode());
318 const r = req.reader();
319 const body_content = try r.readAllAlloc(alloc, 1024 * 1024 * 5);
320 if (req.status != .ok) std.log.scoped(.oauth).debug("{s}: {s}", .{ @tagName(req.status), body_content });
321 if (req.status != .ok) return error.OauthBadToken;
314 var req = try http_client.open(.POST, try std.Uri.parse(client.provider.token_url), .{
315 .server_header_buffer = &buf,
316 .headers = .{
317 .authorization = .{ .override = try std.fmt.allocPrint(alloc, "Basic {s}", .{try extras.base64EncodeAlloc(alloc, try std.mem.join(alloc, ":", &.{ client.id, client.secret }))}) },
318 .content_type = .{ .override = "application/x-www-form-urlencoded" },
319 },
320 .extra_headers = &.{
321 .{ .name = "Accept", .value = "application/json" },
322 },
323 .redirect_behavior = .not_allowed,
324 });
325 defer req.deinit();
326 req.transfer_encoding = .{ .content_length = req_body.len };
327 try req.send();
328 try req.writer().writeAll(req_body);
329 try req.finish();
330 try req.wait();
331 const body_content = try req.reader().readAllAlloc(alloc, 1024 * 1024 * 5);
332 if (req.response.status != .ok) std.log.scoped(.oauth).debug("{s}: {s}", .{ @tagName(req.response.status), body_content });
333 if (req.response.status != .ok) return error.OauthBadToken;
322334 const val = try extras.parse_json(alloc, body_content);
323335
324336 const tt = val.value.object.get("token_type").?.string;
......@@ -326,16 +338,23 @@ pub fn Handlers(comptime T: type) type {
326338
327339 const at = val.value.object.get("access_token") orelse return try fail(response_status, body_writer, "Identity Provider Login Error!\n{s}", .{body_content});
328340
329 const req2 = try zfetch.Request.init(alloc, client.provider.me_url, null);
330 var headers2 = zfetch.Headers.init(alloc);
331 try headers2.appendValue("Authorization", try std.fmt.allocPrint(alloc, "Bearer {s}", .{at.string}));
332 try headers2.appendValue("Accept", "application/json");
333
334 try req2.do(.GET, headers2, null);
335 const r2 = req2.reader();
336 const body_content2 = try r2.readAllAlloc(alloc, 1024 * 1024 * 5);
337 if (req2.status != .ok) std.log.scoped(.oauth).debug("{s}: {s}", .{ @tagName(req2.status), body_content2 });
338 if (req2.status != .ok) return error.OauthBadUserinfo;
341 var req2 = try http_client.open(.GET, try std.Uri.parse(client.provider.me_url), .{
342 .server_header_buffer = &buf,
343 .headers = .{
344 .authorization = .{ .override = try std.fmt.allocPrint(alloc, "Bearer {s}", .{at.string}) },
345 },
346 .extra_headers = &.{
347 .{ .name = "Accept", .value = "application/json" },
348 },
349 .redirect_behavior = .not_allowed,
350 });
351 defer req2.deinit();
352 try req2.send();
353 try req2.finish();
354 try req2.wait();
355 const body_content2 = try req2.reader().readAllAlloc(alloc, 1024 * 1024 * 5);
356 if (req2.response.status != .ok) std.log.scoped(.oauth).debug("{s}: {s}", .{ @tagName(req2.response.status), body_content2 });
357 if (req2.response.status != .ok) return error.OauthBadUserinfo;
339358 const val2 = try extras.parse_json(alloc, body_content2);
340359
341360 const id = try fixId(alloc, val2.value.object.get(client.provider.id_prop).?);
zig.mod-1
......@@ -7,7 +7,6 @@ files:
77 - www
88dependencies:
99 - src: git https://github.com/nektro/zig-pek
10 - src: git https://github.com/nektro/zfetch
1110 - src: git https://github.com/nektro/zig-extras
1211 - src: git https://github.com/nektro/zig-whatwg-url
1312 - src: git https://github.com/nektro/zig-net-http