mirror of
https://github.com/zigzap/zap.git
synced 2025-10-20 15:14:08 +00:00
latest docs
This commit is contained in:
parent
b718bc3f5a
commit
14fbe5849d
28 changed files with 1 additions and 18125 deletions
|
@ -33,7 +33,7 @@ pub fn build(b: *std.Build) !void {
|
|||
|
||||
// -- Docs
|
||||
const docs_obj = b.addObject(.{
|
||||
.name = "docs",
|
||||
.name = "zap",
|
||||
.root_source_file = .{ .path = "src/zap.zig" },
|
||||
.target = target,
|
||||
.optimize = .Debug,
|
||||
|
|
10270
docs/commonmark.js
10270
docs/commonmark.js
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
var guideSections =[{"name":"","guides":[]}];
|
|
@ -1 +0,0 @@
|
|||
var modules =[{"name":"zap","file":0,"main":66,"table":{"zap":0}},{"name":"builtin","file":0,"main":463,"table":{}}];
|
|
@ -1 +0,0 @@
|
|||
var rootMod =0;
|
|
@ -1 +0,0 @@
|
|||
var typeKinds =["Unanalyzed","Type","Void","Bool","NoReturn","Int","Float","Pointer","Array","Struct","ComptimeExpr","ComptimeFloat","ComptimeInt","Undefined","Null","Optional","ErrorUnion","InferredErrorUnion","ErrorSet","Enum","Union","Fn","Opaque","Frame","AnyFrame","Vector","EnumLiteral"];
|
File diff suppressed because one or more lines are too long
|
@ -1,177 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>builtin.zig - source view</title>
|
||||
<link rel="icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAgklEQVR4AWMYWuD7EllJIM4G4g4g5oIJ/odhOJ8wToOxSTXgNxDHoeiBMfA4+wGShjyYOCkG/IGqWQziEzYAoUAeiF9D5U+DxEg14DRU7jWIT5IBIOdCxf+A+CQZAAoopEB7QJwBCBwHiip8UYmRdrAlDpIMgApwQZNnNii5Dq0MBgCxxycBnwEd+wAAAABJRU5ErkJggg==">
|
||||
<link rel="icon" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNTMgMTQwIj48ZyBmaWxsPSIjRjdBNDFEIj48Zz48cG9seWdvbiBwb2ludHM9IjQ2LDIyIDI4LDQ0IDE5LDMwIi8+PHBvbHlnb24gcG9pbnRzPSI0NiwyMiAzMywzMyAyOCw0NCAyMiw0NCAyMiw5NSAzMSw5NSAyMCwxMDAgMTIsMTE3IDAsMTE3IDAsMjIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMzEsOTUgMTIsMTE3IDQsMTA2Ii8+PC9nPjxnPjxwb2x5Z29uIHBvaW50cz0iNTYsMjIgNjIsMzYgMzcsNDQiLz48cG9seWdvbiBwb2ludHM9IjU2LDIyIDExMSwyMiAxMTEsNDQgMzcsNDQgNTYsMzIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTE2LDk1IDk3LDExNyA5MCwxMDQiLz48cG9seWdvbiBwb2ludHM9IjExNiw5NSAxMDAsMTA0IDk3LDExNyA0MiwxMTcgNDIsOTUiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTUwLDAgNTIsMTE3IDMsMTQwIDEwMSwyMiIvPjwvZz48Zz48cG9seWdvbiBwb2ludHM9IjE0MSwyMiAxNDAsNDAgMTIyLDQ1Ii8+PHBvbHlnb24gcG9pbnRzPSIxNTMsMjIgMTUzLDExNyAxMDYsMTE3IDEyMCwxMDUgMTI1LDk1IDEzMSw5NSAxMzEsNDUgMTIyLDQ1IDEzMiwzNiAxNDEsMjIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTI1LDk1IDEzMCwxMTAgMTA2LDExNyIvPjwvZz48L2c+PC9zdmc+">
|
||||
<style>
|
||||
body{
|
||||
font-family: system-ui, -apple-system, Roboto, "Segoe UI", sans-serif;
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
pre > code {
|
||||
display: block;
|
||||
overflow: auto;
|
||||
line-height: normal;
|
||||
margin: 0em;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-str {
|
||||
color: #d14;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #005C7A;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #545454;
|
||||
font-style: italic;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #900;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-null {
|
||||
color: #005C5C;
|
||||
}
|
||||
.tok-number {
|
||||
color: #005C5C;
|
||||
}
|
||||
.tok-type {
|
||||
color: #458;
|
||||
font-weight: bold;
|
||||
}
|
||||
pre {
|
||||
counter-reset: line;
|
||||
}
|
||||
pre .line:before {
|
||||
counter-increment: line;
|
||||
content: counter(line);
|
||||
display: inline-block;
|
||||
padding-right: 1em;
|
||||
width: 2em;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.line {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
.line:target {
|
||||
border-top: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ccc;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body{
|
||||
background:#222;
|
||||
color: #ccc;
|
||||
}
|
||||
pre > code {
|
||||
color: #ccc;
|
||||
background: #222;
|
||||
border: unset;
|
||||
}
|
||||
.line:target {
|
||||
border-top: 1px solid #444;
|
||||
border-bottom: 1px solid #444;
|
||||
background: #333;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #eee;
|
||||
}
|
||||
.tok-str {
|
||||
color: #2e5;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #ff894c;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #aa7;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #B1A0F8;
|
||||
}
|
||||
.tok-null {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-number {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-type {
|
||||
color: #68f;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre><code><span class="line" id="L1"><span class="tok-kw">const</span> std = <span class="tok-builtin">@import</span>(<span class="tok-str">"std"</span>);</span>
|
||||
<span class="line" id="L2"><span class="tok-comment">/// Zig version. When writing code that supports multiple versions of Zig, prefer</span></span>
|
||||
<span class="line" id="L3"><span class="tok-comment">/// feature detection (i.e. with `@hasDecl` or `@hasField`) over version checks.</span></span>
|
||||
<span class="line" id="L4"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> zig_version = std.SemanticVersion.parse(zig_version_string) <span class="tok-kw">catch</span> <span class="tok-kw">unreachable</span>;</span>
|
||||
<span class="line" id="L5"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> zig_version_string = <span class="tok-str">"0.12.0-dev.2858+7230b68b3"</span>;</span>
|
||||
<span class="line" id="L6"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> zig_backend = std.builtin.CompilerBackend.stage2_llvm;</span>
|
||||
<span class="line" id="L7"></span>
|
||||
<span class="line" id="L8"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> output_mode = std.builtin.OutputMode.Obj;</span>
|
||||
<span class="line" id="L9"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> link_mode = std.builtin.LinkMode.Static;</span>
|
||||
<span class="line" id="L10"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> is_test = <span class="tok-null">false</span>;</span>
|
||||
<span class="line" id="L11"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> single_threaded = <span class="tok-null">false</span>;</span>
|
||||
<span class="line" id="L12"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> abi = std.Target.Abi.none;</span>
|
||||
<span class="line" id="L13"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> cpu: std.Target.Cpu = .{</span>
|
||||
<span class="line" id="L14"> .arch = .aarch64,</span>
|
||||
<span class="line" id="L15"> .model = &std.Target.aarch64.cpu.generic,</span>
|
||||
<span class="line" id="L16"> .features = std.Target.aarch64.featureSet(&[_]std.Target.aarch64.Feature{</span>
|
||||
<span class="line" id="L17"> .enable_select_opt,</span>
|
||||
<span class="line" id="L18"> .ete,</span>
|
||||
<span class="line" id="L19"> .fp_armv8,</span>
|
||||
<span class="line" id="L20"> .fuse_adrp_add,</span>
|
||||
<span class="line" id="L21"> .fuse_aes,</span>
|
||||
<span class="line" id="L22"> .neon,</span>
|
||||
<span class="line" id="L23"> .trbe,</span>
|
||||
<span class="line" id="L24"> .use_postra_scheduler,</span>
|
||||
<span class="line" id="L25"> }),</span>
|
||||
<span class="line" id="L26">};</span>
|
||||
<span class="line" id="L27"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> os = std.Target.Os{</span>
|
||||
<span class="line" id="L28"> .tag = .macos,</span>
|
||||
<span class="line" id="L29"> .version_range = .{ .semver = .{</span>
|
||||
<span class="line" id="L30"> .min = .{</span>
|
||||
<span class="line" id="L31"> .major = <span class="tok-number">14</span>,</span>
|
||||
<span class="line" id="L32"> .minor = <span class="tok-number">3</span>,</span>
|
||||
<span class="line" id="L33"> .patch = <span class="tok-number">1</span>,</span>
|
||||
<span class="line" id="L34"> },</span>
|
||||
<span class="line" id="L35"> .max = .{</span>
|
||||
<span class="line" id="L36"> .major = <span class="tok-number">14</span>,</span>
|
||||
<span class="line" id="L37"> .minor = <span class="tok-number">3</span>,</span>
|
||||
<span class="line" id="L38"> .patch = <span class="tok-number">1</span>,</span>
|
||||
<span class="line" id="L39"> },</span>
|
||||
<span class="line" id="L40"> }},</span>
|
||||
<span class="line" id="L41">};</span>
|
||||
<span class="line" id="L42"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> target: std.Target = .{</span>
|
||||
<span class="line" id="L43"> .cpu = cpu,</span>
|
||||
<span class="line" id="L44"> .os = os,</span>
|
||||
<span class="line" id="L45"> .abi = abi,</span>
|
||||
<span class="line" id="L46"> .ofmt = object_format,</span>
|
||||
<span class="line" id="L47"> .dynamic_linker = std.Target.DynamicLinker.init(<span class="tok-str">"/usr/lib/dyld"</span>),</span>
|
||||
<span class="line" id="L48">};</span>
|
||||
<span class="line" id="L49"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> object_format = std.Target.ObjectFormat.macho;</span>
|
||||
<span class="line" id="L50"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> mode = std.builtin.OptimizeMode.Debug;</span>
|
||||
<span class="line" id="L51"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> link_libc = <span class="tok-null">true</span>;</span>
|
||||
<span class="line" id="L52"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> link_libcpp = <span class="tok-null">false</span>;</span>
|
||||
<span class="line" id="L53"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> have_error_return_tracing = <span class="tok-null">true</span>;</span>
|
||||
<span class="line" id="L54"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> valgrind_support = <span class="tok-null">false</span>;</span>
|
||||
<span class="line" id="L55"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> sanitize_thread = <span class="tok-null">false</span>;</span>
|
||||
<span class="line" id="L56"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> position_independent_code = <span class="tok-null">true</span>;</span>
|
||||
<span class="line" id="L57"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> position_independent_executable = <span class="tok-null">true</span>;</span>
|
||||
<span class="line" id="L58"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> strip_debug_info = <span class="tok-null">false</span>;</span>
|
||||
<span class="line" id="L59"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> code_model = std.builtin.CodeModel.default;</span>
|
||||
<span class="line" id="L60"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> omit_frame_pointer = <span class="tok-null">false</span>;</span>
|
||||
<span class="line" id="L61"></span>
|
||||
</code></pre></body>
|
||||
</html>
|
|
@ -1,456 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>endpoint.zig - source view</title>
|
||||
<link rel="icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAgklEQVR4AWMYWuD7EllJIM4G4g4g5oIJ/odhOJ8wToOxSTXgNxDHoeiBMfA4+wGShjyYOCkG/IGqWQziEzYAoUAeiF9D5U+DxEg14DRU7jWIT5IBIOdCxf+A+CQZAAoopEB7QJwBCBwHiip8UYmRdrAlDpIMgApwQZNnNii5Dq0MBgCxxycBnwEd+wAAAABJRU5ErkJggg==">
|
||||
<link rel="icon" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNTMgMTQwIj48ZyBmaWxsPSIjRjdBNDFEIj48Zz48cG9seWdvbiBwb2ludHM9IjQ2LDIyIDI4LDQ0IDE5LDMwIi8+PHBvbHlnb24gcG9pbnRzPSI0NiwyMiAzMywzMyAyOCw0NCAyMiw0NCAyMiw5NSAzMSw5NSAyMCwxMDAgMTIsMTE3IDAsMTE3IDAsMjIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMzEsOTUgMTIsMTE3IDQsMTA2Ii8+PC9nPjxnPjxwb2x5Z29uIHBvaW50cz0iNTYsMjIgNjIsMzYgMzcsNDQiLz48cG9seWdvbiBwb2ludHM9IjU2LDIyIDExMSwyMiAxMTEsNDQgMzcsNDQgNTYsMzIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTE2LDk1IDk3LDExNyA5MCwxMDQiLz48cG9seWdvbiBwb2ludHM9IjExNiw5NSAxMDAsMTA0IDk3LDExNyA0MiwxMTcgNDIsOTUiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTUwLDAgNTIsMTE3IDMsMTQwIDEwMSwyMiIvPjwvZz48Zz48cG9seWdvbiBwb2ludHM9IjE0MSwyMiAxNDAsNDAgMTIyLDQ1Ii8+PHBvbHlnb24gcG9pbnRzPSIxNTMsMjIgMTUzLDExNyAxMDYsMTE3IDEyMCwxMDUgMTI1LDk1IDEzMSw5NSAxMzEsNDUgMTIyLDQ1IDEzMiwzNiAxNDEsMjIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTI1LDk1IDEzMCwxMTAgMTA2LDExNyIvPjwvZz48L2c+PC9zdmc+">
|
||||
<style>
|
||||
body{
|
||||
font-family: system-ui, -apple-system, Roboto, "Segoe UI", sans-serif;
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
pre > code {
|
||||
display: block;
|
||||
overflow: auto;
|
||||
line-height: normal;
|
||||
margin: 0em;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-str {
|
||||
color: #d14;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #005C7A;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #545454;
|
||||
font-style: italic;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #900;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-null {
|
||||
color: #005C5C;
|
||||
}
|
||||
.tok-number {
|
||||
color: #005C5C;
|
||||
}
|
||||
.tok-type {
|
||||
color: #458;
|
||||
font-weight: bold;
|
||||
}
|
||||
pre {
|
||||
counter-reset: line;
|
||||
}
|
||||
pre .line:before {
|
||||
counter-increment: line;
|
||||
content: counter(line);
|
||||
display: inline-block;
|
||||
padding-right: 1em;
|
||||
width: 2em;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.line {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
.line:target {
|
||||
border-top: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ccc;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body{
|
||||
background:#222;
|
||||
color: #ccc;
|
||||
}
|
||||
pre > code {
|
||||
color: #ccc;
|
||||
background: #222;
|
||||
border: unset;
|
||||
}
|
||||
.line:target {
|
||||
border-top: 1px solid #444;
|
||||
border-bottom: 1px solid #444;
|
||||
background: #333;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #eee;
|
||||
}
|
||||
.tok-str {
|
||||
color: #2e5;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #ff894c;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #aa7;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #B1A0F8;
|
||||
}
|
||||
.tok-null {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-number {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-type {
|
||||
color: #68f;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre><code><span class="line" id="L1"><span class="tok-kw">const</span> std = <span class="tok-builtin">@import</span>(<span class="tok-str">"std"</span>);</span>
|
||||
<span class="line" id="L2"><span class="tok-kw">const</span> zap = <span class="tok-builtin">@import</span>(<span class="tok-str">"zap.zig"</span>);</span>
|
||||
<span class="line" id="L3"><span class="tok-kw">const</span> auth = <span class="tok-builtin">@import</span>(<span class="tok-str">"http_auth.zig"</span>);</span>
|
||||
<span class="line" id="L4"></span>
|
||||
<span class="line" id="L5"><span class="tok-kw">const</span> Endpoint = <span class="tok-builtin">@This</span>();</span>
|
||||
<span class="line" id="L6"></span>
|
||||
<span class="line" id="L7"><span class="tok-comment">// zap types</span>
|
||||
</span>
|
||||
<span class="line" id="L8"><span class="tok-kw">const</span> Request = zap.Request;</span>
|
||||
<span class="line" id="L9"><span class="tok-kw">const</span> ListenerSettings = zap.HttpListenerSettings;</span>
|
||||
<span class="line" id="L10"><span class="tok-kw">const</span> HttpListener = zap.HttpListener;</span>
|
||||
<span class="line" id="L11"></span>
|
||||
<span class="line" id="L12"><span class="tok-comment">/// Type of the request function callbacks.</span></span>
|
||||
<span class="line" id="L13"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> RequestFn = *<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (self: *Endpoint, r: Request) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L14"></span>
|
||||
<span class="line" id="L15"><span class="tok-comment">/// Settings to initialize an Endpoint</span></span>
|
||||
<span class="line" id="L16"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> Settings = <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L17"> <span class="tok-comment">/// path / slug of the endpoint</span></span>
|
||||
<span class="line" id="L18"> path: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L19"> <span class="tok-comment">/// callback to GET request handler</span></span>
|
||||
<span class="line" id="L20"> get: ?RequestFn = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L21"> <span class="tok-comment">/// callback to POST request handler</span></span>
|
||||
<span class="line" id="L22"> post: ?RequestFn = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L23"> <span class="tok-comment">/// callback to PUT request handler</span></span>
|
||||
<span class="line" id="L24"> put: ?RequestFn = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L25"> <span class="tok-comment">/// callback to DELETE request handler</span></span>
|
||||
<span class="line" id="L26"> delete: ?RequestFn = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L27"> <span class="tok-comment">/// callback to PATCH request handler</span></span>
|
||||
<span class="line" id="L28"> patch: ?RequestFn = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L29"> <span class="tok-comment">/// callback to OPTIONS request handler</span></span>
|
||||
<span class="line" id="L30"> options: ?RequestFn = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L31"> <span class="tok-comment">/// Only applicable to Authenticating Endpoint: handler for unauthorized requests</span></span>
|
||||
<span class="line" id="L32"> unauthorized: ?RequestFn = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L33">};</span>
|
||||
<span class="line" id="L34"></span>
|
||||
<span class="line" id="L35">settings: Settings,</span>
|
||||
<span class="line" id="L36"></span>
|
||||
<span class="line" id="L37"><span class="tok-comment">/// Initialize the endpoint.</span></span>
|
||||
<span class="line" id="L38"><span class="tok-comment">/// Set only the callbacks you need. Requests of HTTP methods without a</span></span>
|
||||
<span class="line" id="L39"><span class="tok-comment">/// provided callback will be ignored.</span></span>
|
||||
<span class="line" id="L40"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">init</span>(s: Settings) Endpoint {</span>
|
||||
<span class="line" id="L41"> <span class="tok-kw">return</span> .{</span>
|
||||
<span class="line" id="L42"> .settings = .{</span>
|
||||
<span class="line" id="L43"> .path = s.path,</span>
|
||||
<span class="line" id="L44"> .get = s.get <span class="tok-kw">orelse</span> &nop,</span>
|
||||
<span class="line" id="L45"> .post = s.post <span class="tok-kw">orelse</span> &nop,</span>
|
||||
<span class="line" id="L46"> .put = s.put <span class="tok-kw">orelse</span> &nop,</span>
|
||||
<span class="line" id="L47"> .delete = s.delete <span class="tok-kw">orelse</span> &nop,</span>
|
||||
<span class="line" id="L48"> .patch = s.patch <span class="tok-kw">orelse</span> &nop,</span>
|
||||
<span class="line" id="L49"> .options = s.options <span class="tok-kw">orelse</span> &nop,</span>
|
||||
<span class="line" id="L50"> .unauthorized = s.unauthorized <span class="tok-kw">orelse</span> &nop,</span>
|
||||
<span class="line" id="L51"> },</span>
|
||||
<span class="line" id="L52"> };</span>
|
||||
<span class="line" id="L53">}</span>
|
||||
<span class="line" id="L54"></span>
|
||||
<span class="line" id="L55"><span class="tok-comment">// no operation. Dummy handler function for ignoring unset request types.</span>
|
||||
</span>
|
||||
<span class="line" id="L56"><span class="tok-kw">fn</span> <span class="tok-fn">nop</span>(self: *Endpoint, r: Request) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L57"> _ = self;</span>
|
||||
<span class="line" id="L58"> _ = r;</span>
|
||||
<span class="line" id="L59">}</span>
|
||||
<span class="line" id="L60"></span>
|
||||
<span class="line" id="L61"><span class="tok-comment">/// The global request handler for this Endpoint, called by the listener.</span></span>
|
||||
<span class="line" id="L62"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">onRequest</span>(self: *Endpoint, r: zap.Request) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L63"> <span class="tok-kw">switch</span> (r.methodAsEnum()) {</span>
|
||||
<span class="line" id="L64"> .GET => self.settings.get.?(self, r),</span>
|
||||
<span class="line" id="L65"> .POST => self.settings.post.?(self, r),</span>
|
||||
<span class="line" id="L66"> .PUT => self.settings.put.?(self, r),</span>
|
||||
<span class="line" id="L67"> .DELETE => self.settings.delete.?(self, r),</span>
|
||||
<span class="line" id="L68"> .PATCH => self.settings.patch.?(self, r),</span>
|
||||
<span class="line" id="L69"> .OPTIONS => self.settings.options.?(self, r),</span>
|
||||
<span class="line" id="L70"> <span class="tok-kw">else</span> => <span class="tok-kw">return</span>,</span>
|
||||
<span class="line" id="L71"> }</span>
|
||||
<span class="line" id="L72">}</span>
|
||||
<span class="line" id="L73"></span>
|
||||
<span class="line" id="L74"><span class="tok-comment">/// Wrap an endpoint with an Authenticator -> new Endpoint of type Endpoint</span></span>
|
||||
<span class="line" id="L75"><span class="tok-comment">/// is available via the `endpoint()` function.</span></span>
|
||||
<span class="line" id="L76"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">Authenticating</span>(<span class="tok-kw">comptime</span> Authenticator: <span class="tok-type">type</span>) <span class="tok-type">type</span> {</span>
|
||||
<span class="line" id="L77"> <span class="tok-kw">return</span> <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L78"> authenticator: *Authenticator,</span>
|
||||
<span class="line" id="L79"> ep: *Endpoint,</span>
|
||||
<span class="line" id="L80"> auth_endpoint: Endpoint,</span>
|
||||
<span class="line" id="L81"> <span class="tok-kw">const</span> Self = <span class="tok-builtin">@This</span>();</span>
|
||||
<span class="line" id="L82"></span>
|
||||
<span class="line" id="L83"> <span class="tok-comment">/// Init the authenticating endpoint. Pass in a pointer to the endpoint</span></span>
|
||||
<span class="line" id="L84"> <span class="tok-comment">/// you want to wrap, and the Authenticator that takes care of authenticating</span></span>
|
||||
<span class="line" id="L85"> <span class="tok-comment">/// requests.</span></span>
|
||||
<span class="line" id="L86"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">init</span>(e: *Endpoint, authenticator: *Authenticator) Self {</span>
|
||||
<span class="line" id="L87"> <span class="tok-kw">return</span> .{</span>
|
||||
<span class="line" id="L88"> .authenticator = authenticator,</span>
|
||||
<span class="line" id="L89"> .ep = e,</span>
|
||||
<span class="line" id="L90"> .auth_endpoint = Endpoint.init(.{</span>
|
||||
<span class="line" id="L91"> .path = e.settings.path,</span>
|
||||
<span class="line" id="L92"> <span class="tok-comment">// we override only the set ones. the other ones</span>
|
||||
</span>
|
||||
<span class="line" id="L93"> <span class="tok-comment">// are set to null anyway -> will be nopped out</span>
|
||||
</span>
|
||||
<span class="line" id="L94"> .get = <span class="tok-kw">if</span> (e.settings.get != <span class="tok-null">null</span>) get <span class="tok-kw">else</span> <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L95"> .post = <span class="tok-kw">if</span> (e.settings.post != <span class="tok-null">null</span>) post <span class="tok-kw">else</span> <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L96"> .put = <span class="tok-kw">if</span> (e.settings.put != <span class="tok-null">null</span>) put <span class="tok-kw">else</span> <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L97"> .delete = <span class="tok-kw">if</span> (e.settings.delete != <span class="tok-null">null</span>) delete <span class="tok-kw">else</span> <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L98"> .patch = <span class="tok-kw">if</span> (e.settings.patch != <span class="tok-null">null</span>) patch <span class="tok-kw">else</span> <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L99"> .options = <span class="tok-kw">if</span> (e.settings.options != <span class="tok-null">null</span>) options <span class="tok-kw">else</span> <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L100"> .unauthorized = e.settings.unauthorized,</span>
|
||||
<span class="line" id="L101"> }),</span>
|
||||
<span class="line" id="L102"> };</span>
|
||||
<span class="line" id="L103"> }</span>
|
||||
<span class="line" id="L104"></span>
|
||||
<span class="line" id="L105"> <span class="tok-comment">/// Get the auth endpoint struct of type Endpoint so it can be stored in the listener.</span></span>
|
||||
<span class="line" id="L106"> <span class="tok-comment">/// When the listener calls the auth_endpoint, onRequest will have</span></span>
|
||||
<span class="line" id="L107"> <span class="tok-comment">/// access to all of this via fieldParentPtr</span></span>
|
||||
<span class="line" id="L108"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">endpoint</span>(self: *Self) *Endpoint {</span>
|
||||
<span class="line" id="L109"> <span class="tok-kw">return</span> &self.auth_endpoint;</span>
|
||||
<span class="line" id="L110"> }</span>
|
||||
<span class="line" id="L111"></span>
|
||||
<span class="line" id="L112"> <span class="tok-comment">/// GET: here, the auth_endpoint will be passed in as endpoint.</span></span>
|
||||
<span class="line" id="L113"> <span class="tok-comment">/// Authenticates GET requests using the Authenticator.</span></span>
|
||||
<span class="line" id="L114"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">get</span>(e: *Endpoint, r: zap.Request) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L115"> <span class="tok-kw">const</span> authEp: *Self = <span class="tok-builtin">@fieldParentPtr</span>(Self, <span class="tok-str">"auth_endpoint"</span>, e);</span>
|
||||
<span class="line" id="L116"> <span class="tok-kw">switch</span> (authEp.authenticator.authenticateRequest(&r)) {</span>
|
||||
<span class="line" id="L117"> .AuthFailed => {</span>
|
||||
<span class="line" id="L118"> <span class="tok-kw">if</span> (e.settings.unauthorized) |unauthorized| {</span>
|
||||
<span class="line" id="L119"> unauthorized(authEp.ep, r);</span>
|
||||
<span class="line" id="L120"> <span class="tok-kw">return</span>;</span>
|
||||
<span class="line" id="L121"> } <span class="tok-kw">else</span> {</span>
|
||||
<span class="line" id="L122"> r.setStatus(.unauthorized);</span>
|
||||
<span class="line" id="L123"> r.sendBody(<span class="tok-str">"UNAUTHORIZED"</span>) <span class="tok-kw">catch</span> <span class="tok-kw">return</span>;</span>
|
||||
<span class="line" id="L124"> <span class="tok-kw">return</span>;</span>
|
||||
<span class="line" id="L125"> }</span>
|
||||
<span class="line" id="L126"> },</span>
|
||||
<span class="line" id="L127"> .AuthOK => authEp.ep.settings.get.?(authEp.ep, r),</span>
|
||||
<span class="line" id="L128"> .Handled => {},</span>
|
||||
<span class="line" id="L129"> }</span>
|
||||
<span class="line" id="L130"> }</span>
|
||||
<span class="line" id="L131"></span>
|
||||
<span class="line" id="L132"> <span class="tok-comment">/// POST: here, the auth_endpoint will be passed in as endpoint.</span></span>
|
||||
<span class="line" id="L133"> <span class="tok-comment">/// Authenticates POST requests using the Authenticator.</span></span>
|
||||
<span class="line" id="L134"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">post</span>(e: *Endpoint, r: zap.Request) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L135"> <span class="tok-kw">const</span> authEp: *Self = <span class="tok-builtin">@fieldParentPtr</span>(Self, <span class="tok-str">"auth_endpoint"</span>, e);</span>
|
||||
<span class="line" id="L136"> <span class="tok-kw">switch</span> (authEp.authenticator.authenticateRequest(&r)) {</span>
|
||||
<span class="line" id="L137"> .AuthFailed => {</span>
|
||||
<span class="line" id="L138"> <span class="tok-kw">if</span> (e.settings.unauthorized) |unauthorized| {</span>
|
||||
<span class="line" id="L139"> unauthorized(authEp.ep, r);</span>
|
||||
<span class="line" id="L140"> <span class="tok-kw">return</span>;</span>
|
||||
<span class="line" id="L141"> } <span class="tok-kw">else</span> {</span>
|
||||
<span class="line" id="L142"> r.setStatus(.unauthorized);</span>
|
||||
<span class="line" id="L143"> r.sendBody(<span class="tok-str">"UNAUTHORIZED"</span>) <span class="tok-kw">catch</span> <span class="tok-kw">return</span>;</span>
|
||||
<span class="line" id="L144"> <span class="tok-kw">return</span>;</span>
|
||||
<span class="line" id="L145"> }</span>
|
||||
<span class="line" id="L146"> },</span>
|
||||
<span class="line" id="L147"> .AuthOK => authEp.ep.settings.post.?(authEp.ep, r),</span>
|
||||
<span class="line" id="L148"> .Handled => {},</span>
|
||||
<span class="line" id="L149"> }</span>
|
||||
<span class="line" id="L150"> }</span>
|
||||
<span class="line" id="L151"></span>
|
||||
<span class="line" id="L152"> <span class="tok-comment">/// PUT: here, the auth_endpoint will be passed in as endpoint.</span></span>
|
||||
<span class="line" id="L153"> <span class="tok-comment">/// Authenticates PUT requests using the Authenticator.</span></span>
|
||||
<span class="line" id="L154"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">put</span>(e: *Endpoint, r: zap.Request) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L155"> <span class="tok-kw">const</span> authEp: *Self = <span class="tok-builtin">@fieldParentPtr</span>(Self, <span class="tok-str">"auth_endpoint"</span>, e);</span>
|
||||
<span class="line" id="L156"> <span class="tok-kw">switch</span> (authEp.authenticator.authenticateRequest(&r)) {</span>
|
||||
<span class="line" id="L157"> .AuthFailed => {</span>
|
||||
<span class="line" id="L158"> <span class="tok-kw">if</span> (e.settings.unauthorized) |unauthorized| {</span>
|
||||
<span class="line" id="L159"> unauthorized(authEp.ep, r);</span>
|
||||
<span class="line" id="L160"> <span class="tok-kw">return</span>;</span>
|
||||
<span class="line" id="L161"> } <span class="tok-kw">else</span> {</span>
|
||||
<span class="line" id="L162"> r.setStatus(.unauthorized);</span>
|
||||
<span class="line" id="L163"> r.sendBody(<span class="tok-str">"UNAUTHORIZED"</span>) <span class="tok-kw">catch</span> <span class="tok-kw">return</span>;</span>
|
||||
<span class="line" id="L164"> <span class="tok-kw">return</span>;</span>
|
||||
<span class="line" id="L165"> }</span>
|
||||
<span class="line" id="L166"> },</span>
|
||||
<span class="line" id="L167"> .AuthOK => authEp.ep.settings.put.?(authEp.ep, r),</span>
|
||||
<span class="line" id="L168"> .Handled => {},</span>
|
||||
<span class="line" id="L169"> }</span>
|
||||
<span class="line" id="L170"> }</span>
|
||||
<span class="line" id="L171"></span>
|
||||
<span class="line" id="L172"> <span class="tok-comment">/// DELETE: here, the auth_endpoint will be passed in as endpoint.</span></span>
|
||||
<span class="line" id="L173"> <span class="tok-comment">/// Authenticates DELETE requests using the Authenticator.</span></span>
|
||||
<span class="line" id="L174"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">delete</span>(e: *Endpoint, r: zap.Request) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L175"> <span class="tok-kw">const</span> authEp: *Self = <span class="tok-builtin">@fieldParentPtr</span>(Self, <span class="tok-str">"auth_endpoint"</span>, e);</span>
|
||||
<span class="line" id="L176"> <span class="tok-kw">switch</span> (authEp.authenticator.authenticateRequest(&r)) {</span>
|
||||
<span class="line" id="L177"> .AuthFailed => {</span>
|
||||
<span class="line" id="L178"> <span class="tok-kw">if</span> (e.settings.unauthorized) |unauthorized| {</span>
|
||||
<span class="line" id="L179"> unauthorized(authEp.ep, r);</span>
|
||||
<span class="line" id="L180"> <span class="tok-kw">return</span>;</span>
|
||||
<span class="line" id="L181"> } <span class="tok-kw">else</span> {</span>
|
||||
<span class="line" id="L182"> r.setStatus(.unauthorized);</span>
|
||||
<span class="line" id="L183"> r.sendBody(<span class="tok-str">"UNAUTHORIZED"</span>) <span class="tok-kw">catch</span> <span class="tok-kw">return</span>;</span>
|
||||
<span class="line" id="L184"> <span class="tok-kw">return</span>;</span>
|
||||
<span class="line" id="L185"> }</span>
|
||||
<span class="line" id="L186"> },</span>
|
||||
<span class="line" id="L187"> .AuthOK => authEp.ep.settings.delete.?(authEp.ep, r),</span>
|
||||
<span class="line" id="L188"> .Handled => {},</span>
|
||||
<span class="line" id="L189"> }</span>
|
||||
<span class="line" id="L190"> }</span>
|
||||
<span class="line" id="L191"></span>
|
||||
<span class="line" id="L192"> <span class="tok-comment">/// PATCH: here, the auth_endpoint will be passed in as endpoint.</span></span>
|
||||
<span class="line" id="L193"> <span class="tok-comment">/// Authenticates PATCH requests using the Authenticator.</span></span>
|
||||
<span class="line" id="L194"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">patch</span>(e: *Endpoint, r: zap.Request) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L195"> <span class="tok-kw">const</span> authEp: *Self = <span class="tok-builtin">@fieldParentPtr</span>(Self, <span class="tok-str">"auth_endpoint"</span>, e);</span>
|
||||
<span class="line" id="L196"> <span class="tok-kw">switch</span> (authEp.authenticator.authenticateRequest(&r)) {</span>
|
||||
<span class="line" id="L197"> .AuthFailed => {</span>
|
||||
<span class="line" id="L198"> <span class="tok-kw">if</span> (e.settings.unauthorized) |unauthorized| {</span>
|
||||
<span class="line" id="L199"> unauthorized(authEp.ep, r);</span>
|
||||
<span class="line" id="L200"> <span class="tok-kw">return</span>;</span>
|
||||
<span class="line" id="L201"> } <span class="tok-kw">else</span> {</span>
|
||||
<span class="line" id="L202"> r.setStatus(.unauthorized);</span>
|
||||
<span class="line" id="L203"> r.sendBody(<span class="tok-str">"UNAUTHORIZED"</span>) <span class="tok-kw">catch</span> <span class="tok-kw">return</span>;</span>
|
||||
<span class="line" id="L204"> <span class="tok-kw">return</span>;</span>
|
||||
<span class="line" id="L205"> }</span>
|
||||
<span class="line" id="L206"> },</span>
|
||||
<span class="line" id="L207"> .AuthOK => authEp.ep.settings.patch.?(authEp.ep, r),</span>
|
||||
<span class="line" id="L208"> .Handled => {},</span>
|
||||
<span class="line" id="L209"> }</span>
|
||||
<span class="line" id="L210"> }</span>
|
||||
<span class="line" id="L211"></span>
|
||||
<span class="line" id="L212"> <span class="tok-comment">/// OPTIONS: here, the auth_endpoint will be passed in as endpoint.</span></span>
|
||||
<span class="line" id="L213"> <span class="tok-comment">/// Authenticates OPTIONS requests using the Authenticator.</span></span>
|
||||
<span class="line" id="L214"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">options</span>(e: *Endpoint, r: zap.Request) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L215"> <span class="tok-kw">const</span> authEp: *Self = <span class="tok-builtin">@fieldParentPtr</span>(Self, <span class="tok-str">"auth_endpoint"</span>, e);</span>
|
||||
<span class="line" id="L216"> <span class="tok-kw">switch</span> (authEp.authenticator.authenticateRequest(&r)) {</span>
|
||||
<span class="line" id="L217"> .AuthFailed => {</span>
|
||||
<span class="line" id="L218"> <span class="tok-kw">if</span> (e.settings.unauthorized) |unauthorized| {</span>
|
||||
<span class="line" id="L219"> unauthorized(authEp.ep, r);</span>
|
||||
<span class="line" id="L220"> <span class="tok-kw">return</span>;</span>
|
||||
<span class="line" id="L221"> } <span class="tok-kw">else</span> {</span>
|
||||
<span class="line" id="L222"> r.setStatus(.unauthorized);</span>
|
||||
<span class="line" id="L223"> r.sendBody(<span class="tok-str">"UNAUTHORIZED"</span>) <span class="tok-kw">catch</span> <span class="tok-kw">return</span>;</span>
|
||||
<span class="line" id="L224"> <span class="tok-kw">return</span>;</span>
|
||||
<span class="line" id="L225"> }</span>
|
||||
<span class="line" id="L226"> },</span>
|
||||
<span class="line" id="L227"> .AuthOK => authEp.ep.settings.put.?(authEp.ep, r),</span>
|
||||
<span class="line" id="L228"> .Handled => {},</span>
|
||||
<span class="line" id="L229"> }</span>
|
||||
<span class="line" id="L230"> }</span>
|
||||
<span class="line" id="L231"> };</span>
|
||||
<span class="line" id="L232">}</span>
|
||||
<span class="line" id="L233"></span>
|
||||
<span class="line" id="L234"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> EndpointListenerError = <span class="tok-kw">error</span>{</span>
|
||||
<span class="line" id="L235"> <span class="tok-comment">/// Since we use .startsWith to check for matching paths, you cannot use</span></span>
|
||||
<span class="line" id="L236"> <span class="tok-comment">/// endpoint paths that overlap at the beginning. --> When trying to register</span></span>
|
||||
<span class="line" id="L237"> <span class="tok-comment">/// an endpoint whose path would shadow an already registered one, you will</span></span>
|
||||
<span class="line" id="L238"> <span class="tok-comment">/// receive this error.</span></span>
|
||||
<span class="line" id="L239"> EndpointPathShadowError,</span>
|
||||
<span class="line" id="L240">};</span>
|
||||
<span class="line" id="L241"></span>
|
||||
<span class="line" id="L242"><span class="tok-comment">/// The listener with endpoint support</span></span>
|
||||
<span class="line" id="L243"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L244"><span class="tok-comment">/// NOTE: It switches on path.startsWith -> so use endpoints with distinctly starting names!!</span></span>
|
||||
<span class="line" id="L245"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> Listener = <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L246"> listener: HttpListener,</span>
|
||||
<span class="line" id="L247"> allocator: std.mem.Allocator,</span>
|
||||
<span class="line" id="L248"></span>
|
||||
<span class="line" id="L249"> <span class="tok-kw">const</span> Self = <span class="tok-builtin">@This</span>();</span>
|
||||
<span class="line" id="L250"></span>
|
||||
<span class="line" id="L251"> <span class="tok-comment">/// Internal static struct of member endpoints</span></span>
|
||||
<span class="line" id="L252"> <span class="tok-kw">var</span> endpoints: std.ArrayList(*Endpoint) = <span class="tok-null">undefined</span>;</span>
|
||||
<span class="line" id="L253"></span>
|
||||
<span class="line" id="L254"> <span class="tok-comment">/// Internal, static request handler callback. Will be set to the optional,</span></span>
|
||||
<span class="line" id="L255"> <span class="tok-comment">/// user-defined request callback that only gets called if no endpoints match</span></span>
|
||||
<span class="line" id="L256"> <span class="tok-comment">/// a request.</span></span>
|
||||
<span class="line" id="L257"> <span class="tok-kw">var</span> on_request: ?zap.HttpRequestFn = <span class="tok-null">null</span>;</span>
|
||||
<span class="line" id="L258"></span>
|
||||
<span class="line" id="L259"> <span class="tok-comment">/// Initialize a new endpoint listener. Note, if you pass an `on_request`</span></span>
|
||||
<span class="line" id="L260"> <span class="tok-comment">/// callback in the provided ListenerSettings, this request callback will be</span></span>
|
||||
<span class="line" id="L261"> <span class="tok-comment">/// called every time a request arrives that no endpoint matches.</span></span>
|
||||
<span class="line" id="L262"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">init</span>(a: std.mem.Allocator, l: ListenerSettings) Self {</span>
|
||||
<span class="line" id="L263"> endpoints = std.ArrayList(*Endpoint).init(a);</span>
|
||||
<span class="line" id="L264"></span>
|
||||
<span class="line" id="L265"> <span class="tok-comment">// take copy of listener settings before modifying the callback field</span>
|
||||
</span>
|
||||
<span class="line" id="L266"> <span class="tok-kw">var</span> ls = l;</span>
|
||||
<span class="line" id="L267"></span>
|
||||
<span class="line" id="L268"> <span class="tok-comment">// override the settings with our internal, actul callback function</span>
|
||||
</span>
|
||||
<span class="line" id="L269"> <span class="tok-comment">// so that "we" will be called on request</span>
|
||||
</span>
|
||||
<span class="line" id="L270"> ls.on_request = Listener.onRequest;</span>
|
||||
<span class="line" id="L271"></span>
|
||||
<span class="line" id="L272"> <span class="tok-comment">// store the settings-provided request callback for later use</span>
|
||||
</span>
|
||||
<span class="line" id="L273"> on_request = l.on_request;</span>
|
||||
<span class="line" id="L274"> <span class="tok-kw">return</span> .{</span>
|
||||
<span class="line" id="L275"> .listener = HttpListener.init(ls),</span>
|
||||
<span class="line" id="L276"> .allocator = a,</span>
|
||||
<span class="line" id="L277"> };</span>
|
||||
<span class="line" id="L278"> }</span>
|
||||
<span class="line" id="L279"></span>
|
||||
<span class="line" id="L280"> <span class="tok-comment">/// De-init the listener and free its resources.</span></span>
|
||||
<span class="line" id="L281"> <span class="tok-comment">/// Registered endpoints will not be de-initialized automatically; just removed</span></span>
|
||||
<span class="line" id="L282"> <span class="tok-comment">/// from the internal map.</span></span>
|
||||
<span class="line" id="L283"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">deinit</span>(self: *Self) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L284"> _ = self;</span>
|
||||
<span class="line" id="L285"> endpoints.deinit();</span>
|
||||
<span class="line" id="L286"> }</span>
|
||||
<span class="line" id="L287"></span>
|
||||
<span class="line" id="L288"> <span class="tok-comment">/// Call this to start listening. After this, no more endpoints can be</span></span>
|
||||
<span class="line" id="L289"> <span class="tok-comment">/// registered.</span></span>
|
||||
<span class="line" id="L290"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">listen</span>(self: *Self) !<span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L291"> <span class="tok-kw">try</span> self.listener.listen();</span>
|
||||
<span class="line" id="L292"> }</span>
|
||||
<span class="line" id="L293"></span>
|
||||
<span class="line" id="L294"> <span class="tok-comment">/// Register an endpoint with this listener.</span></span>
|
||||
<span class="line" id="L295"> <span class="tok-comment">/// NOTE: endpoint paths are matched with startsWith -> so use endpoints with distinctly starting names!!</span></span>
|
||||
<span class="line" id="L296"> <span class="tok-comment">/// If you try to register an endpoint whose path would shadow an already registered one, you will</span></span>
|
||||
<span class="line" id="L297"> <span class="tok-comment">/// receive an EndpointPathShadowError.</span></span>
|
||||
<span class="line" id="L298"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">register</span>(self: *Self, e: *Endpoint) !<span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L299"> _ = self;</span>
|
||||
<span class="line" id="L300"> <span class="tok-kw">for</span> (endpoints.items) |other| {</span>
|
||||
<span class="line" id="L301"> <span class="tok-kw">if</span> (std.mem.startsWith(</span>
|
||||
<span class="line" id="L302"> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L303"> other.settings.path,</span>
|
||||
<span class="line" id="L304"> e.settings.path,</span>
|
||||
<span class="line" id="L305"> ) <span class="tok-kw">or</span> std.mem.startsWith(</span>
|
||||
<span class="line" id="L306"> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L307"> e.settings.path,</span>
|
||||
<span class="line" id="L308"> other.settings.path,</span>
|
||||
<span class="line" id="L309"> )) {</span>
|
||||
<span class="line" id="L310"> <span class="tok-kw">return</span> EndpointListenerError.EndpointPathShadowError;</span>
|
||||
<span class="line" id="L311"> }</span>
|
||||
<span class="line" id="L312"> }</span>
|
||||
<span class="line" id="L313"> <span class="tok-kw">try</span> endpoints.append(e);</span>
|
||||
<span class="line" id="L314"> }</span>
|
||||
<span class="line" id="L315"></span>
|
||||
<span class="line" id="L316"> <span class="tok-kw">fn</span> <span class="tok-fn">onRequest</span>(r: Request) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L317"> <span class="tok-kw">if</span> (r.path) |p| {</span>
|
||||
<span class="line" id="L318"> <span class="tok-kw">for</span> (endpoints.items) |e| {</span>
|
||||
<span class="line" id="L319"> <span class="tok-kw">if</span> (std.mem.startsWith(<span class="tok-type">u8</span>, p, e.settings.path)) {</span>
|
||||
<span class="line" id="L320"> e.onRequest(r);</span>
|
||||
<span class="line" id="L321"> <span class="tok-kw">return</span>;</span>
|
||||
<span class="line" id="L322"> }</span>
|
||||
<span class="line" id="L323"> }</span>
|
||||
<span class="line" id="L324"> }</span>
|
||||
<span class="line" id="L325"> <span class="tok-comment">// if set, call the user-provided default callback</span>
|
||||
</span>
|
||||
<span class="line" id="L326"> <span class="tok-kw">if</span> (on_request) |foo| {</span>
|
||||
<span class="line" id="L327"> foo(r);</span>
|
||||
<span class="line" id="L328"> }</span>
|
||||
<span class="line" id="L329"> }</span>
|
||||
<span class="line" id="L330">};</span>
|
||||
<span class="line" id="L331"></span>
|
||||
</code></pre></body>
|
||||
</html>
|
|
@ -1,740 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>fio.zig - source view</title>
|
||||
<link rel="icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAgklEQVR4AWMYWuD7EllJIM4G4g4g5oIJ/odhOJ8wToOxSTXgNxDHoeiBMfA4+wGShjyYOCkG/IGqWQziEzYAoUAeiF9D5U+DxEg14DRU7jWIT5IBIOdCxf+A+CQZAAoopEB7QJwBCBwHiip8UYmRdrAlDpIMgApwQZNnNii5Dq0MBgCxxycBnwEd+wAAAABJRU5ErkJggg==">
|
||||
<link rel="icon" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNTMgMTQwIj48ZyBmaWxsPSIjRjdBNDFEIj48Zz48cG9seWdvbiBwb2ludHM9IjQ2LDIyIDI4LDQ0IDE5LDMwIi8+PHBvbHlnb24gcG9pbnRzPSI0NiwyMiAzMywzMyAyOCw0NCAyMiw0NCAyMiw5NSAzMSw5NSAyMCwxMDAgMTIsMTE3IDAsMTE3IDAsMjIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMzEsOTUgMTIsMTE3IDQsMTA2Ii8+PC9nPjxnPjxwb2x5Z29uIHBvaW50cz0iNTYsMjIgNjIsMzYgMzcsNDQiLz48cG9seWdvbiBwb2ludHM9IjU2LDIyIDExMSwyMiAxMTEsNDQgMzcsNDQgNTYsMzIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTE2LDk1IDk3LDExNyA5MCwxMDQiLz48cG9seWdvbiBwb2ludHM9IjExNiw5NSAxMDAsMTA0IDk3LDExNyA0MiwxMTcgNDIsOTUiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTUwLDAgNTIsMTE3IDMsMTQwIDEwMSwyMiIvPjwvZz48Zz48cG9seWdvbiBwb2ludHM9IjE0MSwyMiAxNDAsNDAgMTIyLDQ1Ii8+PHBvbHlnb24gcG9pbnRzPSIxNTMsMjIgMTUzLDExNyAxMDYsMTE3IDEyMCwxMDUgMTI1LDk1IDEzMSw5NSAxMzEsNDUgMTIyLDQ1IDEzMiwzNiAxNDEsMjIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTI1LDk1IDEzMCwxMTAgMTA2LDExNyIvPjwvZz48L2c+PC9zdmc+">
|
||||
<style>
|
||||
body{
|
||||
font-family: system-ui, -apple-system, Roboto, "Segoe UI", sans-serif;
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
pre > code {
|
||||
display: block;
|
||||
overflow: auto;
|
||||
line-height: normal;
|
||||
margin: 0em;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-str {
|
||||
color: #d14;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #005C7A;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #545454;
|
||||
font-style: italic;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #900;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-null {
|
||||
color: #005C5C;
|
||||
}
|
||||
.tok-number {
|
||||
color: #005C5C;
|
||||
}
|
||||
.tok-type {
|
||||
color: #458;
|
||||
font-weight: bold;
|
||||
}
|
||||
pre {
|
||||
counter-reset: line;
|
||||
}
|
||||
pre .line:before {
|
||||
counter-increment: line;
|
||||
content: counter(line);
|
||||
display: inline-block;
|
||||
padding-right: 1em;
|
||||
width: 2em;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.line {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
.line:target {
|
||||
border-top: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ccc;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body{
|
||||
background:#222;
|
||||
color: #ccc;
|
||||
}
|
||||
pre > code {
|
||||
color: #ccc;
|
||||
background: #222;
|
||||
border: unset;
|
||||
}
|
||||
.line:target {
|
||||
border-top: 1px solid #444;
|
||||
border-bottom: 1px solid #444;
|
||||
background: #333;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #eee;
|
||||
}
|
||||
.tok-str {
|
||||
color: #2e5;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #ff894c;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #aa7;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #B1A0F8;
|
||||
}
|
||||
.tok-null {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-number {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-type {
|
||||
color: #68f;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre><code><span class="line" id="L1"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> FIOBJ = <span class="tok-type">usize</span>;</span>
|
||||
<span class="line" id="L2"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">is_invalid</span>(o: FIOBJ) <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L3"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> fio_url_s = <span class="tok-kw">extern</span> <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L4"> scheme: fio_str_info_s,</span>
|
||||
<span class="line" id="L5"> user: fio_str_info_s,</span>
|
||||
<span class="line" id="L6"> password: fio_str_info_s,</span>
|
||||
<span class="line" id="L7"> host: fio_str_info_s,</span>
|
||||
<span class="line" id="L8"> port: fio_str_info_s,</span>
|
||||
<span class="line" id="L9"> path: fio_str_info_s,</span>
|
||||
<span class="line" id="L10"> query: fio_str_info_s,</span>
|
||||
<span class="line" id="L11"> target: fio_str_info_s,</span>
|
||||
<span class="line" id="L12">};</span>
|
||||
<span class="line" id="L13"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fio_url_parse</span>(url: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span>, length: <span class="tok-type">usize</span>) fio_url_s;</span>
|
||||
<span class="line" id="L14"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> struct_fio_start_args = <span class="tok-kw">extern</span> <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L15"> threads: <span class="tok-type">i16</span>,</span>
|
||||
<span class="line" id="L16"> workers: <span class="tok-type">i16</span>,</span>
|
||||
<span class="line" id="L17">};</span>
|
||||
<span class="line" id="L18"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> fio_start_args = struct_fio_start_args;</span>
|
||||
<span class="line" id="L19"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fio_start</span>(args: struct_fio_start_args) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L20"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fio_stop</span>() <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L21"><span class="tok-kw">const</span> struct_unnamed_37 = <span class="tok-kw">extern</span> <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L22"> vtbl: ?*<span class="tok-type">anyopaque</span>,</span>
|
||||
<span class="line" id="L23"> flag: <span class="tok-type">usize</span>,</span>
|
||||
<span class="line" id="L24"> out_headers: FIOBJ,</span>
|
||||
<span class="line" id="L25">};</span>
|
||||
<span class="line" id="L26"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> __time_t = <span class="tok-type">c_long</span>;</span>
|
||||
<span class="line" id="L27"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> time_t = __time_t;</span>
|
||||
<span class="line" id="L28"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> __syscall_slong_t = <span class="tok-type">c_long</span>;</span>
|
||||
<span class="line" id="L29"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> struct_timespec = <span class="tok-kw">extern</span> <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L30"> tv_sec: __time_t,</span>
|
||||
<span class="line" id="L31"> tv_nsec: __syscall_slong_t,</span>
|
||||
<span class="line" id="L32">};</span>
|
||||
<span class="line" id="L33"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> struct_http_settings_s = <span class="tok-kw">extern</span> <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L34"> on_request: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> ([*c]http_s) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span>,</span>
|
||||
<span class="line" id="L35"> on_upgrade: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> ([*c]http_s, [*c]<span class="tok-type">u8</span>, <span class="tok-type">usize</span>) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span>,</span>
|
||||
<span class="line" id="L36"> on_response: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> ([*c]http_s) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span>,</span>
|
||||
<span class="line" id="L37"> on_finish: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> ([*c]struct_http_settings_s) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span>,</span>
|
||||
<span class="line" id="L38"> udata: ?*<span class="tok-type">anyopaque</span>,</span>
|
||||
<span class="line" id="L39"> public_folder: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L40"> public_folder_length: <span class="tok-type">usize</span>,</span>
|
||||
<span class="line" id="L41"> max_header_size: <span class="tok-type">usize</span>,</span>
|
||||
<span class="line" id="L42"> max_body_size: <span class="tok-type">usize</span>,</span>
|
||||
<span class="line" id="L43"> max_clients: <span class="tok-type">isize</span>,</span>
|
||||
<span class="line" id="L44"> tls: ?*<span class="tok-type">anyopaque</span>,</span>
|
||||
<span class="line" id="L45"> reserved1: <span class="tok-type">isize</span>,</span>
|
||||
<span class="line" id="L46"> reserved2: <span class="tok-type">isize</span>,</span>
|
||||
<span class="line" id="L47"> reserved3: <span class="tok-type">isize</span>,</span>
|
||||
<span class="line" id="L48"> ws_max_msg_size: <span class="tok-type">usize</span>,</span>
|
||||
<span class="line" id="L49"> timeout: <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L50"> ws_timeout: <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L51"> log: <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L52"> is_client: <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L53">};</span>
|
||||
<span class="line" id="L54"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> http_settings_s = struct_http_settings_s;</span>
|
||||
<span class="line" id="L55"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> http_s = <span class="tok-kw">extern</span> <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L56"> private_data: struct_unnamed_37,</span>
|
||||
<span class="line" id="L57"> received_at: struct_timespec,</span>
|
||||
<span class="line" id="L58"> method: FIOBJ,</span>
|
||||
<span class="line" id="L59"> status_str: FIOBJ,</span>
|
||||
<span class="line" id="L60"> version: FIOBJ,</span>
|
||||
<span class="line" id="L61"> status: <span class="tok-type">usize</span>,</span>
|
||||
<span class="line" id="L62"> path: FIOBJ,</span>
|
||||
<span class="line" id="L63"> query: FIOBJ,</span>
|
||||
<span class="line" id="L64"> headers: FIOBJ,</span>
|
||||
<span class="line" id="L65"> cookies: FIOBJ,</span>
|
||||
<span class="line" id="L66"> params: FIOBJ,</span>
|
||||
<span class="line" id="L67"> body: FIOBJ,</span>
|
||||
<span class="line" id="L68"> udata: ?*<span class="tok-type">anyopaque</span>,</span>
|
||||
<span class="line" id="L69">};</span>
|
||||
<span class="line" id="L70"></span>
|
||||
<span class="line" id="L71"><span class="tok-comment">// zig-cache/i/e0c8a6e617497ade13de512cbe191f23/include/http.h:153:12: warning: struct demoted to opaque type - has bitfield</span>
|
||||
</span>
|
||||
<span class="line" id="L72"></span>
|
||||
<span class="line" id="L73"><span class="tok-comment">// typedef struct {</span>
|
||||
</span>
|
||||
<span class="line" id="L74"><span class="tok-comment">// /** The cookie's name (Symbol). */</span>
|
||||
</span>
|
||||
<span class="line" id="L75"><span class="tok-comment">// const char *name;</span>
|
||||
</span>
|
||||
<span class="line" id="L76"><span class="tok-comment">// /** The cookie's value (leave blank to delete cookie). */</span>
|
||||
</span>
|
||||
<span class="line" id="L77"><span class="tok-comment">// const char *value;</span>
|
||||
</span>
|
||||
<span class="line" id="L78"><span class="tok-comment">// /** The cookie's domain (optional). */</span>
|
||||
</span>
|
||||
<span class="line" id="L79"><span class="tok-comment">// const char *domain;</span>
|
||||
</span>
|
||||
<span class="line" id="L80"><span class="tok-comment">// /** The cookie's path (optional). */</span>
|
||||
</span>
|
||||
<span class="line" id="L81"><span class="tok-comment">// const char *path;</span>
|
||||
</span>
|
||||
<span class="line" id="L82"><span class="tok-comment">// /** The cookie name's size in bytes or a terminating NUL will be assumed.*/</span>
|
||||
</span>
|
||||
<span class="line" id="L83"><span class="tok-comment">// size_t name_len;</span>
|
||||
</span>
|
||||
<span class="line" id="L84"><span class="tok-comment">// /** The cookie value's size in bytes or a terminating NUL will be assumed.*/</span>
|
||||
</span>
|
||||
<span class="line" id="L85"><span class="tok-comment">// size_t value_len;</span>
|
||||
</span>
|
||||
<span class="line" id="L86"><span class="tok-comment">// /** The cookie domain's size in bytes or a terminating NUL will be assumed.*/</span>
|
||||
</span>
|
||||
<span class="line" id="L87"><span class="tok-comment">// size_t domain_len;</span>
|
||||
</span>
|
||||
<span class="line" id="L88"><span class="tok-comment">// /** The cookie path's size in bytes or a terminating NULL will be assumed.*/</span>
|
||||
</span>
|
||||
<span class="line" id="L89"><span class="tok-comment">// size_t path_len;</span>
|
||||
</span>
|
||||
<span class="line" id="L90"><span class="tok-comment">// /** Max Age (how long should the cookie persist), in seconds (0 == session).*/</span>
|
||||
</span>
|
||||
<span class="line" id="L91"><span class="tok-comment">// int max_age;</span>
|
||||
</span>
|
||||
<span class="line" id="L92"><span class="tok-comment">// /** Limit cookie to secure connections.*/</span>
|
||||
</span>
|
||||
<span class="line" id="L93"><span class="tok-comment">// unsigned secure : 1;</span>
|
||||
</span>
|
||||
<span class="line" id="L94"><span class="tok-comment">// /** Limit cookie to HTTP (intended to prevent javascript access/hijacking).*/</span>
|
||||
</span>
|
||||
<span class="line" id="L95"><span class="tok-comment">// unsigned http_only : 1;</span>
|
||||
</span>
|
||||
<span class="line" id="L96"><span class="tok-comment">// } http_cookie_args_s;</span>
|
||||
</span>
|
||||
<span class="line" id="L97"></span>
|
||||
<span class="line" id="L98"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> http_cookie_args_s = <span class="tok-kw">extern</span> <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L99"> name: [*c]<span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L100"> value: [*c]<span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L101"> domain: [*c]<span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L102"> path: [*c]<span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L103"> name_len: <span class="tok-type">isize</span>,</span>
|
||||
<span class="line" id="L104"> value_len: <span class="tok-type">isize</span>,</span>
|
||||
<span class="line" id="L105"> domain_len: <span class="tok-type">isize</span>,</span>
|
||||
<span class="line" id="L106"> path_len: <span class="tok-type">isize</span>,</span>
|
||||
<span class="line" id="L107"> <span class="tok-comment">/// in seconds</span></span>
|
||||
<span class="line" id="L108"> max_age: <span class="tok-type">c_int</span>,</span>
|
||||
<span class="line" id="L109"> secure: <span class="tok-type">c_uint</span>,</span>
|
||||
<span class="line" id="L110"> http_only: <span class="tok-type">c_uint</span>,</span>
|
||||
<span class="line" id="L111">};</span>
|
||||
<span class="line" id="L112"></span>
|
||||
<span class="line" id="L113"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> struct_fio_str_info_s = <span class="tok-kw">extern</span> <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L114"> capa: <span class="tok-type">usize</span>,</span>
|
||||
<span class="line" id="L115"> len: <span class="tok-type">usize</span>,</span>
|
||||
<span class="line" id="L116"> data: [*c]<span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L117">};</span>
|
||||
<span class="line" id="L118"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> fio_str_info_s = struct_fio_str_info_s;</span>
|
||||
<span class="line" id="L119"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_send_body</span>(h: [*c]http_s, data: ?*<span class="tok-type">anyopaque</span>, length: <span class="tok-type">usize</span>) <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L120"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_each1</span>(arg_o: FIOBJ, arg_start_at: <span class="tok-type">usize</span>, arg_task: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (FIOBJ, ?*<span class="tok-type">anyopaque</span>) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">c_int</span>, arg_arg: ?*<span class="tok-type">anyopaque</span>) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">usize</span> {</span>
|
||||
<span class="line" id="L121"> <span class="tok-kw">const</span> o = arg_o;</span>
|
||||
<span class="line" id="L122"> <span class="tok-kw">const</span> start_at = arg_start_at;</span>
|
||||
<span class="line" id="L123"> <span class="tok-kw">const</span> task = arg_task;</span>
|
||||
<span class="line" id="L124"> <span class="tok-kw">const</span> arg = arg_arg;</span>
|
||||
<span class="line" id="L125"> <span class="tok-kw">if</span> ((((o != <span class="tok-number">0</span>) <span class="tok-kw">and</span> ((o & <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">1</span>))))) == <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">0</span>)))))) <span class="tok-kw">and</span> ((o & <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">6</span>))))) != <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">6</span>)))))) <span class="tok-kw">and</span> (fiobj_type_vtable(o).*.each != <span class="tok-null">null</span>)) <span class="tok-kw">return</span> fiobj_type_vtable(o).*.each.?(o, start_at, task, arg);</span>
|
||||
<span class="line" id="L126"> <span class="tok-kw">return</span> <span class="tok-number">0</span>;</span>
|
||||
<span class="line" id="L127">}</span>
|
||||
<span class="line" id="L128"></span>
|
||||
<span class="line" id="L129"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_hash_new</span>() FIOBJ;</span>
|
||||
<span class="line" id="L130"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_hash_set</span>(hash: FIOBJ, key: FIOBJ, obj: FIOBJ) <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L131"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_hash_get</span>(hash: FIOBJ, key: FIOBJ) FIOBJ;</span>
|
||||
<span class="line" id="L132"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_hash_pop</span>(hash: FIOBJ, key: [*c]FIOBJ) FIOBJ;</span>
|
||||
<span class="line" id="L133"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_hash_count</span>(hash: FIOBJ) <span class="tok-type">usize</span>;</span>
|
||||
<span class="line" id="L134"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_hash_key_in_loop</span>() FIOBJ;</span>
|
||||
<span class="line" id="L135"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_hash_haskey</span>(hash: FIOBJ, key: FIOBJ) <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L136"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_ary_new</span>() FIOBJ;</span>
|
||||
<span class="line" id="L137"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_ary_new2</span>(capa: <span class="tok-type">usize</span>) FIOBJ;</span>
|
||||
<span class="line" id="L138"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_ary_count</span>(ary: FIOBJ) <span class="tok-type">usize</span>;</span>
|
||||
<span class="line" id="L139"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_ary_capa</span>(ary: FIOBJ) <span class="tok-type">usize</span>;</span>
|
||||
<span class="line" id="L140"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_ary2ptr</span>(ary: FIOBJ) [*c]FIOBJ;</span>
|
||||
<span class="line" id="L141"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_ary_index</span>(ary: FIOBJ, pos: <span class="tok-type">i64</span>) FIOBJ;</span>
|
||||
<span class="line" id="L142"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_ary_set</span>(ary: FIOBJ, obj: FIOBJ, pos: <span class="tok-type">i64</span>) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L143"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_ary_push</span>(ary: FIOBJ, obj: FIOBJ) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L144"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_ary_pop</span>(ary: FIOBJ) FIOBJ;</span>
|
||||
<span class="line" id="L145"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_ary_unshift</span>(ary: FIOBJ, obj: FIOBJ) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L146"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_ary_shift</span>(ary: FIOBJ) FIOBJ;</span>
|
||||
<span class="line" id="L147"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_ary_replace</span>(ary: FIOBJ, obj: FIOBJ, pos: <span class="tok-type">i64</span>) FIOBJ;</span>
|
||||
<span class="line" id="L148"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_ary_find</span>(ary: FIOBJ, data: FIOBJ) <span class="tok-type">i64</span>;</span>
|
||||
<span class="line" id="L149"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_ary_remove</span>(ary: FIOBJ, pos: <span class="tok-type">i64</span>) <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L150"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_ary_remove2</span>(ary: FIOBJ, data: FIOBJ) <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L151"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_ary_compact</span>(ary: FIOBJ) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L152"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_float_new</span>(num: <span class="tok-type">f64</span>) FIOBJ;</span>
|
||||
<span class="line" id="L153"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_num_new_bignum</span>(num: <span class="tok-type">isize</span>) FIOBJ;</span>
|
||||
<span class="line" id="L154"></span>
|
||||
<span class="line" id="L155"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_data_newstr</span>() FIOBJ;</span>
|
||||
<span class="line" id="L156"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_data_newstr2</span>(buffer: ?*<span class="tok-type">anyopaque</span>, length: <span class="tok-type">usize</span>, dealloc: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (?*<span class="tok-type">anyopaque</span>) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span>) FIOBJ;</span>
|
||||
<span class="line" id="L157"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_data_newtmpfile</span>() FIOBJ;</span>
|
||||
<span class="line" id="L158"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_data_newfd</span>(fd: <span class="tok-type">c_int</span>) FIOBJ;</span>
|
||||
<span class="line" id="L159"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_data_slice</span>(parent: FIOBJ, offset: <span class="tok-type">isize</span>, length: <span class="tok-type">usize</span>) FIOBJ;</span>
|
||||
<span class="line" id="L160"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_data_save</span>(io: FIOBJ, filename: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span>) <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L161"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_data_read</span>(io: FIOBJ, length: <span class="tok-type">isize</span>) fio_str_info_s;</span>
|
||||
<span class="line" id="L162"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_data_read2ch</span>(io: FIOBJ, token: <span class="tok-type">u8</span>) fio_str_info_s;</span>
|
||||
<span class="line" id="L163"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_data_pos</span>(io: FIOBJ) <span class="tok-type">isize</span>;</span>
|
||||
<span class="line" id="L164"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_data_len</span>(io: FIOBJ) <span class="tok-type">isize</span>;</span>
|
||||
<span class="line" id="L165"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_data_seek</span>(io: FIOBJ, position: <span class="tok-type">isize</span>) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L166"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_data_pread</span>(io: FIOBJ, start_at: <span class="tok-type">isize</span>, length: <span class="tok-type">usize</span>) fio_str_info_s;</span>
|
||||
<span class="line" id="L167"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_data_write</span>(io: FIOBJ, buffer: ?*<span class="tok-type">anyopaque</span>, length: <span class="tok-type">usize</span>) <span class="tok-type">isize</span>;</span>
|
||||
<span class="line" id="L168"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_data_puts</span>(io: FIOBJ, buffer: ?*<span class="tok-type">anyopaque</span>, length: <span class="tok-type">usize</span>) <span class="tok-type">isize</span>;</span>
|
||||
<span class="line" id="L169"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_data_assert_dynamic</span>(io: FIOBJ) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L170"></span>
|
||||
<span class="line" id="L171"><span class="tok-comment">/// Creates a new SSL/TLS context / settings object with a default certificate (if any).</span></span>
|
||||
<span class="line" id="L172"><span class="tok-comment">/// If a server name is provided, than NULL values can be used to create an anonymous (unverified)</span></span>
|
||||
<span class="line" id="L173"><span class="tok-comment">/// context / settings object. If all values are NULL, a TLS object will be created without a</span></span>
|
||||
<span class="line" id="L174"><span class="tok-comment">/// certificate. This could be used for clients together with fio_tls_trust. fio_tls_s * is an</span></span>
|
||||
<span class="line" id="L175"><span class="tok-comment">/// opaque type used as a handle for the SSL/TLS functions. It shouldn't be directly accessed.</span></span>
|
||||
<span class="line" id="L176"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fio_tls_new</span>(</span>
|
||||
<span class="line" id="L177"> server_name: ?[*:<span class="tok-number">0</span>]<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L178"> public_certificate_file: ?[*:<span class="tok-number">0</span>]<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L179"> private_key_file: ?[*:<span class="tok-number">0</span>]<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L180"> private_key_password: ?[*:<span class="tok-number">0</span>]<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L181">) ?*<span class="tok-type">anyopaque</span>;</span>
|
||||
<span class="line" id="L182"></span>
|
||||
<span class="line" id="L183"><span class="tok-comment">/// Increase the reference count for the TLS object.</span></span>
|
||||
<span class="line" id="L184"><span class="tok-comment">/// Decrease / free with fio_tls_destroy.</span></span>
|
||||
<span class="line" id="L185"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fio_tls_dup</span>(tls: ?*<span class="tok-type">anyopaque</span>) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L186"></span>
|
||||
<span class="line" id="L187"><span class="tok-comment">/// Destroys the SSL/TLS context / settings object and frees any related resources / memory.</span></span>
|
||||
<span class="line" id="L188"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fio_tls_destroy</span>(tls: ?*<span class="tok-type">anyopaque</span>) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L189"></span>
|
||||
<span class="line" id="L190"><span class="tok-comment">/// Adds a certificate a new SSL/TLS context / settings object (SNI support).</span></span>
|
||||
<span class="line" id="L191"><span class="tok-comment">/// The private_key_password can be NULL if the private key PEM file isn't password protected.</span></span>
|
||||
<span class="line" id="L192"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fio_tls_cert_add</span>(</span>
|
||||
<span class="line" id="L193"> tls: ?*<span class="tok-type">anyopaque</span>,</span>
|
||||
<span class="line" id="L194"> server_name: ?[*:<span class="tok-number">0</span>]<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L195"> public_certificate_file: ?[*:<span class="tok-number">0</span>]<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L196"> private_key_file: ?[*:<span class="tok-number">0</span>]<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L197"> private_key_password: ?[*:<span class="tok-number">0</span>]<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L198">) <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L199"></span>
|
||||
<span class="line" id="L200"><span class="tok-comment">/// Adds a certificate to the "trust" list, which automatically adds a peer verification requirement.</span></span>
|
||||
<span class="line" id="L201"><span class="tok-comment">/// Note: when the fio_tls_s object is used for server connections, this will limit connections to</span></span>
|
||||
<span class="line" id="L202"><span class="tok-comment">/// clients that connect using a trusted certificate.</span></span>
|
||||
<span class="line" id="L203"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fio_tls_trust</span>(tls: ?*<span class="tok-type">anyopaque</span>, public_cert_file: ?[*:<span class="tok-number">0</span>]<span class="tok-kw">const</span> <span class="tok-type">u8</span>) <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L204"></span>
|
||||
<span class="line" id="L205"><span class="tok-comment">/// Establishes an SSL/TLS connection as an SSL/TLS Server, using the specified context / settings object.</span></span>
|
||||
<span class="line" id="L206"><span class="tok-comment">/// The uuid should be a socket UUID that is already connected to a peer (i.e., the result of fio_accept).</span></span>
|
||||
<span class="line" id="L207"><span class="tok-comment">/// The udata is an opaque user data pointer that is passed along to the protocol selected (if any protocols</span></span>
|
||||
<span class="line" id="L208"><span class="tok-comment">/// were added using fio_tls_alpn_add).</span></span>
|
||||
<span class="line" id="L209"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fio_tls_accept</span>(uuid: *<span class="tok-type">u32</span>, tls: ?*<span class="tok-type">anyopaque</span>, udata: ?*<span class="tok-type">anyopaque</span>) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L210"></span>
|
||||
<span class="line" id="L211"><span class="tok-comment">/// Establishes an SSL/TLS connection as an SSL/TLS Client, using the specified context / settings object.</span></span>
|
||||
<span class="line" id="L212"><span class="tok-comment">/// The uuid should be a socket UUID that is already connected to a peer (i.e., one received by a fio_connect</span></span>
|
||||
<span class="line" id="L213"><span class="tok-comment">/// specified callback on_connect).</span></span>
|
||||
<span class="line" id="L214"><span class="tok-comment">/// The udata is an opaque user data pointer that is passed along to the protocol selected (if any protocols</span></span>
|
||||
<span class="line" id="L215"><span class="tok-comment">/// were added using fio_tls_alpn_add).</span></span>
|
||||
<span class="line" id="L216"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fio_tls_connect</span>(uuid: *<span class="tok-type">u32</span>, tls: ?*<span class="tok-type">anyopaque</span>, udata: ?*<span class="tok-type">anyopaque</span>) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L217"></span>
|
||||
<span class="line" id="L218"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_free_wrapped</span>(o: FIOBJ) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L219"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_null</span>() <span class="tok-kw">callconv</span>(.C) FIOBJ {</span>
|
||||
<span class="line" id="L220"> <span class="tok-kw">return</span> <span class="tok-builtin">@as</span>(FIOBJ, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, FIOBJ_T_NULL)));</span>
|
||||
<span class="line" id="L221">}</span>
|
||||
<span class="line" id="L222"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_true</span>() <span class="tok-kw">callconv</span>(.C) FIOBJ {</span>
|
||||
<span class="line" id="L223"> <span class="tok-kw">return</span> <span class="tok-builtin">@as</span>(FIOBJ, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, FIOBJ_T_TRUE)));</span>
|
||||
<span class="line" id="L224">}</span>
|
||||
<span class="line" id="L225"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_false</span>() <span class="tok-kw">callconv</span>(.C) FIOBJ {</span>
|
||||
<span class="line" id="L226"> <span class="tok-kw">return</span> <span class="tok-builtin">@as</span>(FIOBJ, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, FIOBJ_T_FALSE)));</span>
|
||||
<span class="line" id="L227">}</span>
|
||||
<span class="line" id="L228"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_str_new</span>(str: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span>, len: <span class="tok-type">usize</span>) FIOBJ;</span>
|
||||
<span class="line" id="L229"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_str_buf</span>(capa: <span class="tok-type">usize</span>) FIOBJ;</span>
|
||||
<span class="line" id="L230"></span>
|
||||
<span class="line" id="L231"><span class="tok-kw">pub</span> <span class="tok-kw">inline</span> <span class="tok-kw">fn</span> <span class="tok-fn">FIOBJ_TYPE</span>(obj: <span class="tok-kw">anytype</span>) <span class="tok-builtin">@TypeOf</span>(fiobj_type(obj)) {</span>
|
||||
<span class="line" id="L232"> <span class="tok-kw">return</span> fiobj_type(obj);</span>
|
||||
<span class="line" id="L233">}</span>
|
||||
<span class="line" id="L234"><span class="tok-kw">pub</span> <span class="tok-kw">inline</span> <span class="tok-kw">fn</span> <span class="tok-fn">FIOBJ_TYPE_IS</span>(obj: <span class="tok-kw">anytype</span>, @"type": <span class="tok-kw">anytype</span>) <span class="tok-builtin">@TypeOf</span>(fiobj_type_is(obj, @"type")) {</span>
|
||||
<span class="line" id="L235"> <span class="tok-kw">return</span> fiobj_type_is(obj, @"type");</span>
|
||||
<span class="line" id="L236">}</span>
|
||||
<span class="line" id="L237"><span class="tok-kw">pub</span> <span class="tok-kw">inline</span> <span class="tok-kw">fn</span> <span class="tok-fn">FIOBJ_IS_NULL</span>(obj: <span class="tok-kw">anytype</span>) <span class="tok-builtin">@TypeOf</span>(!(obj != <span class="tok-number">0</span>) <span class="tok-kw">or</span> (obj == <span class="tok-builtin">@import</span>(<span class="tok-str">"std"</span>).zig.c_translation.cast(FIOBJ, FIOBJ_T_NULL))) {</span>
|
||||
<span class="line" id="L238"> <span class="tok-kw">return</span> !(obj != <span class="tok-number">0</span>) <span class="tok-kw">or</span> (obj == <span class="tok-builtin">@import</span>(<span class="tok-str">"std"</span>).zig.c_translation.cast(FIOBJ, FIOBJ_T_NULL));</span>
|
||||
<span class="line" id="L239">}</span>
|
||||
<span class="line" id="L240"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> FIOBJ_INVALID = <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">0</span>);</span>
|
||||
<span class="line" id="L241"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> FIOBJECT_NUMBER_FLAG = <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">1</span>);</span>
|
||||
<span class="line" id="L242"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> FIOBJECT_PRIMITIVE_FLAG = <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">6</span>);</span>
|
||||
<span class="line" id="L243"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> FIOBJECT_STRING_FLAG = <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">2</span>);</span>
|
||||
<span class="line" id="L244"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> FIOBJECT_HASH_FLAG = <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">4</span>);</span>
|
||||
<span class="line" id="L245"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> FIOBJECT_TYPE_MASK = ~<span class="tok-builtin">@import</span>(<span class="tok-str">"std"</span>).zig.c_translation.cast(<span class="tok-type">usize</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">7</span>));</span>
|
||||
<span class="line" id="L246"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> FIOBJ_NUMBER_SIGN_MASK = ~<span class="tok-builtin">@import</span>(<span class="tok-str">"std"</span>).zig.c_translation.cast(<span class="tok-type">usize</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">0</span>)) >> <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">1</span>);</span>
|
||||
<span class="line" id="L247"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> FIOBJ_NUMBER_SIGN_BIT = ~FIOBJ_NUMBER_SIGN_MASK;</span>
|
||||
<span class="line" id="L248"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> FIOBJ_NUMBER_SIGN_EXCLUDE_BIT = FIOBJ_NUMBER_SIGN_BIT >> <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">1</span>);</span>
|
||||
<span class="line" id="L249"><span class="tok-kw">pub</span> <span class="tok-kw">inline</span> <span class="tok-kw">fn</span> <span class="tok-fn">FIOBJ_IS_ALLOCATED</span>(o: <span class="tok-kw">anytype</span>) <span class="tok-builtin">@TypeOf</span>(((o != <span class="tok-number">0</span>) <span class="tok-kw">and</span> ((o & FIOBJECT_NUMBER_FLAG) == <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">0</span>))) <span class="tok-kw">and</span> ((o & FIOBJECT_PRIMITIVE_FLAG) != FIOBJECT_PRIMITIVE_FLAG)) {</span>
|
||||
<span class="line" id="L250"> <span class="tok-kw">return</span> ((o != <span class="tok-number">0</span>) <span class="tok-kw">and</span> ((o & FIOBJECT_NUMBER_FLAG) == <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">0</span>))) <span class="tok-kw">and</span> ((o & FIOBJECT_PRIMITIVE_FLAG) != FIOBJECT_PRIMITIVE_FLAG);</span>
|
||||
<span class="line" id="L251">}</span>
|
||||
<span class="line" id="L252"><span class="tok-kw">pub</span> <span class="tok-kw">inline</span> <span class="tok-kw">fn</span> <span class="tok-fn">FIOBJ2PTR</span>(o: <span class="tok-kw">anytype</span>) ?*<span class="tok-type">anyopaque</span> {</span>
|
||||
<span class="line" id="L253"> <span class="tok-kw">return</span> <span class="tok-builtin">@import</span>(<span class="tok-str">"std"</span>).zig.c_translation.cast(?*<span class="tok-type">anyopaque</span>, o & FIOBJECT_TYPE_MASK);</span>
|
||||
<span class="line" id="L254">}</span>
|
||||
<span class="line" id="L255"><span class="tok-kw">pub</span> <span class="tok-kw">inline</span> <span class="tok-kw">fn</span> <span class="tok-fn">FIOBJECT2VTBL</span>(o: <span class="tok-kw">anytype</span>) <span class="tok-builtin">@TypeOf</span>(fiobj_type_vtable(o)) {</span>
|
||||
<span class="line" id="L256"> <span class="tok-kw">return</span> fiobj_type_vtable(o);</span>
|
||||
<span class="line" id="L257">}</span>
|
||||
<span class="line" id="L258"><span class="tok-kw">pub</span> <span class="tok-kw">inline</span> <span class="tok-kw">fn</span> <span class="tok-fn">FIOBJECT2HEAD</span>(o: <span class="tok-kw">anytype</span>) [*c]fiobj_object_header_s {</span>
|
||||
<span class="line" id="L259"> <span class="tok-kw">return</span> <span class="tok-builtin">@import</span>(<span class="tok-str">"std"</span>).zig.c_translation.cast([*c]fiobj_object_header_s, FIOBJ2PTR(o));</span>
|
||||
<span class="line" id="L260">}</span>
|
||||
<span class="line" id="L261"><span class="tok-kw">pub</span> <span class="tok-kw">inline</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_ary_entry</span>(a: <span class="tok-kw">anytype</span>, p: <span class="tok-kw">anytype</span>) <span class="tok-builtin">@TypeOf</span>(fiobj_ary_index(a, p)) {</span>
|
||||
<span class="line" id="L262"> <span class="tok-kw">return</span> fiobj_ary_index(a, p);</span>
|
||||
<span class="line" id="L263">}</span>
|
||||
<span class="line" id="L264"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> FIOBJ_T_NUMBER: <span class="tok-type">c_int</span> = <span class="tok-number">1</span>;</span>
|
||||
<span class="line" id="L265"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> FIOBJ_T_NULL: <span class="tok-type">c_int</span> = <span class="tok-number">6</span>;</span>
|
||||
<span class="line" id="L266"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> FIOBJ_T_TRUE: <span class="tok-type">c_int</span> = <span class="tok-number">22</span>;</span>
|
||||
<span class="line" id="L267"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> FIOBJ_T_FALSE: <span class="tok-type">c_int</span> = <span class="tok-number">38</span>;</span>
|
||||
<span class="line" id="L268"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> FIOBJ_T_FLOAT: <span class="tok-type">c_int</span> = <span class="tok-number">39</span>;</span>
|
||||
<span class="line" id="L269"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> FIOBJ_T_STRING: <span class="tok-type">c_int</span> = <span class="tok-number">40</span>;</span>
|
||||
<span class="line" id="L270"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> FIOBJ_T_ARRAY: <span class="tok-type">c_int</span> = <span class="tok-number">41</span>;</span>
|
||||
<span class="line" id="L271"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> FIOBJ_T_HASH: <span class="tok-type">c_int</span> = <span class="tok-number">42</span>;</span>
|
||||
<span class="line" id="L272"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> FIOBJ_T_DATA: <span class="tok-type">c_int</span> = <span class="tok-number">43</span>;</span>
|
||||
<span class="line" id="L273"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> FIOBJ_T_UNKNOWN: <span class="tok-type">c_int</span> = <span class="tok-number">44</span>;</span>
|
||||
<span class="line" id="L274"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> fiobj_type_enum = <span class="tok-type">u8</span>;</span>
|
||||
<span class="line" id="L275"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> fiobj_object_vtable_s = <span class="tok-kw">extern</span> <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L276"> class_name: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L277"> dealloc: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (FIOBJ, ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (FIOBJ, ?*<span class="tok-type">anyopaque</span>) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span>, ?*<span class="tok-type">anyopaque</span>) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span>,</span>
|
||||
<span class="line" id="L278"> count: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (FIOBJ) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">usize</span>,</span>
|
||||
<span class="line" id="L279"> is_true: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (FIOBJ) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">usize</span>,</span>
|
||||
<span class="line" id="L280"> is_eq: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (FIOBJ, FIOBJ) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">usize</span>,</span>
|
||||
<span class="line" id="L281"> each: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (FIOBJ, <span class="tok-type">usize</span>, ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (FIOBJ, ?*<span class="tok-type">anyopaque</span>) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">c_int</span>, ?*<span class="tok-type">anyopaque</span>) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">usize</span>,</span>
|
||||
<span class="line" id="L282"> to_str: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (FIOBJ) <span class="tok-kw">callconv</span>(.C) fio_str_info_s,</span>
|
||||
<span class="line" id="L283"> to_i: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (FIOBJ) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">isize</span>,</span>
|
||||
<span class="line" id="L284"> to_f: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (FIOBJ) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">f64</span>,</span>
|
||||
<span class="line" id="L285">};</span>
|
||||
<span class="line" id="L286"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> fiobj_object_header_s = <span class="tok-kw">extern</span> <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L287"> <span class="tok-type">type</span>: fiobj_type_enum,</span>
|
||||
<span class="line" id="L288"> ref: <span class="tok-type">u32</span>,</span>
|
||||
<span class="line" id="L289">};</span>
|
||||
<span class="line" id="L290"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_type_is</span>(arg_o: FIOBJ, arg_type: fiobj_type_enum) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">usize</span> {</span>
|
||||
<span class="line" id="L291"> <span class="tok-kw">const</span> o = arg_o;</span>
|
||||
<span class="line" id="L292"> <span class="tok-kw">const</span> @"type" = arg_type;</span>
|
||||
<span class="line" id="L293"> <span class="tok-kw">while</span> (<span class="tok-null">true</span>) {</span>
|
||||
<span class="line" id="L294"> <span class="tok-kw">switch</span> (<span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_uint</span>, @"type")))) {</span>
|
||||
<span class="line" id="L295"> <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">1</span>) => <span class="tok-kw">return</span> <span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@intFromBool</span>(((o & <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">1</span>))))) != <span class="tok-number">0</span>) <span class="tok-kw">or</span> (<span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_uint</span>, <span class="tok-builtin">@as</span>([*c]fiobj_type_enum, <span class="tok-builtin">@ptrFromInt</span>(o))[<span class="tok-builtin">@as</span>(<span class="tok-type">c_uint</span>, <span class="tok-builtin">@intCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">0</span>)))]))) == FIOBJ_T_NUMBER))))),</span>
|
||||
<span class="line" id="L296"> <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">6</span>) => <span class="tok-kw">return</span> <span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@intFromBool</span>(!(o != <span class="tok-number">0</span>) <span class="tok-kw">or</span> (o == fiobj_null()))))),</span>
|
||||
<span class="line" id="L297"> <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">22</span>) => <span class="tok-kw">return</span> <span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@intFromBool</span>(o == fiobj_true())))),</span>
|
||||
<span class="line" id="L298"> <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">38</span>) => <span class="tok-kw">return</span> <span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@intFromBool</span>(o == fiobj_false())))),</span>
|
||||
<span class="line" id="L299"> <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">40</span>) => <span class="tok-kw">return</span> <span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@intFromBool</span>(((<span class="tok-null">true</span> <span class="tok-kw">and</span> ((o & <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">1</span>))))) == <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">0</span>)))))) <span class="tok-kw">and</span> ((o & <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">6</span>))))) == <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">2</span>)))))) <span class="tok-kw">or</span> (((<span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">2</span>) == <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">0</span>)) <span class="tok-kw">and</span> (((o != <span class="tok-number">0</span>) <span class="tok-kw">and</span> ((o & <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">1</span>))))) == <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">0</span>)))))) <span class="tok-kw">and</span> ((o & <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">6</span>))))) != <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">6</span>))))))) <span class="tok-kw">and</span> (<span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_uint</span>, <span class="tok-builtin">@as</span>([*c]fiobj_type_enum, <span class="tok-builtin">@ptrCast</span>(<span class="tok-builtin">@alignCast</span>(<span class="tok-builtin">@as</span>(?*<span class="tok-type">anyopaque</span>, <span class="tok-builtin">@ptrFromInt</span>(o & ~<span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">7</span>)))))))))[<span class="tok-builtin">@as</span>(<span class="tok-type">c_uint</span>, <span class="tok-builtin">@intCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">0</span>)))]))) == FIOBJ_T_STRING)))))),</span>
|
||||
<span class="line" id="L300"> <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">42</span>) => {</span>
|
||||
<span class="line" id="L301"> <span class="tok-kw">if</span> (<span class="tok-null">true</span>) {</span>
|
||||
<span class="line" id="L302"> <span class="tok-kw">return</span> <span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@intFromBool</span>(((o & <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">1</span>))))) == <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">0</span>))))) <span class="tok-kw">and</span> ((o & <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">6</span>))))) == <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">4</span>)))))))));</span>
|
||||
<span class="line" id="L303"> }</span>
|
||||
<span class="line" id="L304"> <span class="tok-kw">return</span> <span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@intFromBool</span>((((o != <span class="tok-number">0</span>) <span class="tok-kw">and</span> ((o & <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">1</span>))))) == <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">0</span>)))))) <span class="tok-kw">and</span> ((o & <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">6</span>))))) != <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">6</span>)))))) <span class="tok-kw">and</span> (<span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_uint</span>, <span class="tok-builtin">@as</span>([*c]fiobj_type_enum, <span class="tok-builtin">@ptrCast</span>(<span class="tok-builtin">@alignCast</span>(<span class="tok-builtin">@as</span>(?*<span class="tok-type">anyopaque</span>, <span class="tok-builtin">@ptrFromInt</span>(o & ~<span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">7</span>)))))))))[<span class="tok-builtin">@as</span>(<span class="tok-type">c_uint</span>, <span class="tok-builtin">@intCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">0</span>)))]))) == <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_uint</span>, @"type"))))))));</span>
|
||||
<span class="line" id="L305"> },</span>
|
||||
<span class="line" id="L306"> <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">39</span>), <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">41</span>), <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">43</span>), <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">44</span>) => <span class="tok-kw">return</span> <span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@intFromBool</span>((((o != <span class="tok-number">0</span>) <span class="tok-kw">and</span> ((o & <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">1</span>))))) == <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">0</span>)))))) <span class="tok-kw">and</span> ((o & <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">6</span>))))) != <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">6</span>)))))) <span class="tok-kw">and</span> (<span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_uint</span>, <span class="tok-builtin">@as</span>([*c]fiobj_type_enum, <span class="tok-builtin">@ptrCast</span>(<span class="tok-builtin">@alignCast</span>(<span class="tok-builtin">@as</span>(?*<span class="tok-type">anyopaque</span>, <span class="tok-builtin">@ptrFromInt</span>(o & ~<span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">7</span>)))))))))[<span class="tok-builtin">@as</span>(<span class="tok-type">c_uint</span>, <span class="tok-builtin">@intCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">0</span>)))]))) == <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_uint</span>, @"type")))))))),</span>
|
||||
<span class="line" id="L307"> <span class="tok-kw">else</span> => {},</span>
|
||||
<span class="line" id="L308"> }</span>
|
||||
<span class="line" id="L309"> <span class="tok-kw">break</span>;</span>
|
||||
<span class="line" id="L310"> }</span>
|
||||
<span class="line" id="L311"> <span class="tok-kw">return</span> <span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@intFromBool</span>((((o != <span class="tok-number">0</span>) <span class="tok-kw">and</span> ((o & <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">1</span>))))) == <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">0</span>)))))) <span class="tok-kw">and</span> ((o & <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">6</span>))))) != <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">6</span>)))))) <span class="tok-kw">and</span> (<span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_uint</span>, <span class="tok-builtin">@as</span>([*c]fiobj_type_enum, <span class="tok-builtin">@ptrCast</span>(<span class="tok-builtin">@alignCast</span>(<span class="tok-builtin">@as</span>(?*<span class="tok-type">anyopaque</span>, <span class="tok-builtin">@ptrFromInt</span>(o & ~<span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">7</span>)))))))))[<span class="tok-builtin">@as</span>(<span class="tok-type">c_uint</span>, <span class="tok-builtin">@intCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">0</span>)))]))) == <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_uint</span>, @"type"))))))));</span>
|
||||
<span class="line" id="L312">}</span>
|
||||
<span class="line" id="L313"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_type</span>(arg_o: FIOBJ) <span class="tok-kw">callconv</span>(.C) fiobj_type_enum {</span>
|
||||
<span class="line" id="L314"> <span class="tok-kw">const</span> o = arg_o;</span>
|
||||
<span class="line" id="L315"> <span class="tok-kw">if</span> (!(o != <span class="tok-number">0</span>)) <span class="tok-kw">return</span> <span class="tok-builtin">@as</span>(<span class="tok-type">u8</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">i8</span>, <span class="tok-builtin">@truncate</span>(FIOBJ_T_NULL))));</span>
|
||||
<span class="line" id="L316"> <span class="tok-kw">if</span> ((o & <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">1</span>))))) != <span class="tok-number">0</span>) <span class="tok-kw">return</span> <span class="tok-builtin">@as</span>(<span class="tok-type">u8</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">i8</span>, <span class="tok-builtin">@truncate</span>(FIOBJ_T_NUMBER))));</span>
|
||||
<span class="line" id="L317"> <span class="tok-kw">if</span> ((o & <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">6</span>))))) == <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">6</span>))))) <span class="tok-kw">return</span> <span class="tok-builtin">@as</span>(<span class="tok-type">u8</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">u8</span>, <span class="tok-builtin">@truncate</span>(o))));</span>
|
||||
<span class="line" id="L318"> <span class="tok-kw">if</span> (<span class="tok-null">true</span> <span class="tok-kw">and</span> ((o & <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">6</span>))))) == <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">2</span>)))))) <span class="tok-kw">return</span> <span class="tok-builtin">@as</span>(<span class="tok-type">u8</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">i8</span>, <span class="tok-builtin">@truncate</span>(FIOBJ_T_STRING))));</span>
|
||||
<span class="line" id="L319"> <span class="tok-kw">if</span> (<span class="tok-null">true</span> <span class="tok-kw">and</span> ((o & <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">6</span>))))) == <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">4</span>)))))) <span class="tok-kw">return</span> <span class="tok-builtin">@as</span>(<span class="tok-type">u8</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">i8</span>, <span class="tok-builtin">@truncate</span>(FIOBJ_T_HASH))));</span>
|
||||
<span class="line" id="L320"> <span class="tok-kw">return</span> <span class="tok-builtin">@as</span>([*c]fiobj_type_enum, <span class="tok-builtin">@ptrCast</span>(<span class="tok-builtin">@alignCast</span>(<span class="tok-builtin">@as</span>(?*<span class="tok-type">anyopaque</span>, <span class="tok-builtin">@ptrFromInt</span>(o & ~<span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">7</span>)))))))))[<span class="tok-builtin">@as</span>(<span class="tok-type">c_uint</span>, <span class="tok-builtin">@intCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">0</span>)))];</span>
|
||||
<span class="line" id="L321">}</span>
|
||||
<span class="line" id="L322"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">const</span> FIOBJECT_VTABLE_NUMBER: fiobj_object_vtable_s;</span>
|
||||
<span class="line" id="L323"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">const</span> FIOBJECT_VTABLE_FLOAT: fiobj_object_vtable_s;</span>
|
||||
<span class="line" id="L324"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">const</span> FIOBJECT_VTABLE_STRING: fiobj_object_vtable_s;</span>
|
||||
<span class="line" id="L325"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">const</span> FIOBJECT_VTABLE_ARRAY: fiobj_object_vtable_s;</span>
|
||||
<span class="line" id="L326"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">const</span> FIOBJECT_VTABLE_HASH: fiobj_object_vtable_s;</span>
|
||||
<span class="line" id="L327"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">const</span> FIOBJECT_VTABLE_DATA: fiobj_object_vtable_s;</span>
|
||||
<span class="line" id="L328"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_type_vtable</span>(arg_o: FIOBJ) <span class="tok-kw">callconv</span>(.C) [*c]<span class="tok-kw">const</span> fiobj_object_vtable_s {</span>
|
||||
<span class="line" id="L329"> <span class="tok-kw">const</span> o = arg_o;</span>
|
||||
<span class="line" id="L330"> <span class="tok-kw">while</span> (<span class="tok-null">true</span>) {</span>
|
||||
<span class="line" id="L331"> <span class="tok-kw">switch</span> (<span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_uint</span>, fiobj_type(o))))) {</span>
|
||||
<span class="line" id="L332"> <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">1</span>) => <span class="tok-kw">return</span> &FIOBJECT_VTABLE_NUMBER,</span>
|
||||
<span class="line" id="L333"> <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">39</span>) => <span class="tok-kw">return</span> &FIOBJECT_VTABLE_FLOAT,</span>
|
||||
<span class="line" id="L334"> <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">40</span>) => <span class="tok-kw">return</span> &FIOBJECT_VTABLE_STRING,</span>
|
||||
<span class="line" id="L335"> <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">41</span>) => <span class="tok-kw">return</span> &FIOBJECT_VTABLE_ARRAY,</span>
|
||||
<span class="line" id="L336"> <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">42</span>) => <span class="tok-kw">return</span> &FIOBJECT_VTABLE_HASH,</span>
|
||||
<span class="line" id="L337"> <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">43</span>) => <span class="tok-kw">return</span> &FIOBJECT_VTABLE_DATA,</span>
|
||||
<span class="line" id="L338"> <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">6</span>), <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">22</span>), <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">38</span>), <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">44</span>) => <span class="tok-kw">return</span> <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L339"> <span class="tok-kw">else</span> => {},</span>
|
||||
<span class="line" id="L340"> }</span>
|
||||
<span class="line" id="L341"> <span class="tok-kw">break</span>;</span>
|
||||
<span class="line" id="L342"> }</span>
|
||||
<span class="line" id="L343"> <span class="tok-kw">return</span> <span class="tok-null">null</span>;</span>
|
||||
<span class="line" id="L344">}</span>
|
||||
<span class="line" id="L345"></span>
|
||||
<span class="line" id="L346"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_obj2num</span>(o: FIOBJ) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">isize</span> {</span>
|
||||
<span class="line" id="L347"> <span class="tok-kw">if</span> ((o & <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">1</span>))))) != <span class="tok-number">0</span>) {</span>
|
||||
<span class="line" id="L348"> <span class="tok-kw">const</span> sign: <span class="tok-type">usize</span> = <span class="tok-kw">if</span> ((o & ~(~<span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">0</span>)))) >> <span class="tok-builtin">@as</span>(<span class="tok-builtin">@import</span>(<span class="tok-str">"std"</span>).math.Log2Int(<span class="tok-type">usize</span>), <span class="tok-builtin">@intCast</span>(<span class="tok-number">1</span>)))) != <span class="tok-number">0</span>) ~(~<span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">0</span>)))) >> <span class="tok-builtin">@as</span>(<span class="tok-builtin">@import</span>(<span class="tok-str">"std"</span>).math.Log2Int(<span class="tok-type">usize</span>), <span class="tok-builtin">@intCast</span>(<span class="tok-number">1</span>))) | (~(~<span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">0</span>)))) >> <span class="tok-builtin">@as</span>(<span class="tok-builtin">@import</span>(<span class="tok-str">"std"</span>).math.Log2Int(<span class="tok-type">usize</span>), <span class="tok-builtin">@intCast</span>(<span class="tok-number">1</span>))) >> <span class="tok-builtin">@as</span>(<span class="tok-builtin">@import</span>(<span class="tok-str">"std"</span>).math.Log2Int(<span class="tok-type">usize</span>), <span class="tok-builtin">@intCast</span>(<span class="tok-number">1</span>))) <span class="tok-kw">else</span> <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">0</span>))));</span>
|
||||
<span class="line" id="L349"> <span class="tok-kw">return</span> <span class="tok-builtin">@as</span>(<span class="tok-type">isize</span>, <span class="tok-builtin">@bitCast</span>(((o & (~<span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">0</span>)))) >> <span class="tok-builtin">@as</span>(<span class="tok-builtin">@import</span>(<span class="tok-str">"std"</span>).math.Log2Int(<span class="tok-type">usize</span>), <span class="tok-builtin">@intCast</span>(<span class="tok-number">1</span>)))) >> <span class="tok-builtin">@as</span>(<span class="tok-builtin">@import</span>(<span class="tok-str">"std"</span>).math.Log2Int(<span class="tok-type">c_ulong</span>), <span class="tok-builtin">@intCast</span>(<span class="tok-number">1</span>))) | sign));</span>
|
||||
<span class="line" id="L350"> }</span>
|
||||
<span class="line" id="L351"> <span class="tok-kw">if</span> (!(o != <span class="tok-number">0</span>) <span class="tok-kw">or</span> !(((o != <span class="tok-number">0</span>) <span class="tok-kw">and</span> ((o & <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">1</span>))))) == <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">0</span>)))))) <span class="tok-kw">and</span> ((o & <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">6</span>))))) != <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">6</span>))))))) <span class="tok-kw">return</span> <span class="tok-builtin">@as</span>(<span class="tok-type">isize</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@intFromBool</span>(o == <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, FIOBJ_T_TRUE)))))));</span>
|
||||
<span class="line" id="L352"> <span class="tok-kw">return</span> fiobj_type_vtable(o).*.to_i.?(o);</span>
|
||||
<span class="line" id="L353">}</span>
|
||||
<span class="line" id="L354"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_obj2float</span>(o: FIOBJ) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">f64</span> {</span>
|
||||
<span class="line" id="L355"> <span class="tok-kw">if</span> ((o & <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">1</span>))))) != <span class="tok-number">0</span>) <span class="tok-kw">return</span> <span class="tok-builtin">@as</span>(<span class="tok-type">f64</span>, <span class="tok-builtin">@floatFromInt</span>(fiobj_obj2num(o)));</span>
|
||||
<span class="line" id="L356"> <span class="tok-comment">// the below doesn't parse and we don't support ints here anyway</span>
|
||||
</span>
|
||||
<span class="line" id="L357"> <span class="tok-comment">// if (!(o != 0) or ((o & @bitCast(c_ulong, @as(c_long, @as(c_int, 6)))) == @bitCast(c_ulong, @as(c_long, @as(c_int, 6))))) return @intToFloat(f64, o == @bitCast(c_ulong, @as(c_long, FIOBJ_T_TRUE)));</span>
|
||||
</span>
|
||||
<span class="line" id="L358"> <span class="tok-kw">return</span> fiobj_type_vtable(o).*.to_f.?(o);</span>
|
||||
<span class="line" id="L359">}</span>
|
||||
<span class="line" id="L360"></span>
|
||||
<span class="line" id="L361"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fio_ltocstr</span>(<span class="tok-type">c_long</span>) fio_str_info_s;</span>
|
||||
<span class="line" id="L362"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_obj2cstr</span>(o: FIOBJ) <span class="tok-kw">callconv</span>(.C) fio_str_info_s {</span>
|
||||
<span class="line" id="L363"> <span class="tok-kw">if</span> (!(o != <span class="tok-number">0</span>)) {</span>
|
||||
<span class="line" id="L364"> <span class="tok-kw">const</span> ret: fio_str_info_s = fio_str_info_s{</span>
|
||||
<span class="line" id="L365"> .capa = <span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">0</span>)))),</span>
|
||||
<span class="line" id="L366"> .len = <span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">4</span>)))),</span>
|
||||
<span class="line" id="L367"> .data = <span class="tok-builtin">@as</span>([*c]<span class="tok-type">u8</span>, <span class="tok-builtin">@ptrFromInt</span>(<span class="tok-builtin">@intFromPtr</span>(<span class="tok-str">"null"</span>))),</span>
|
||||
<span class="line" id="L368"> };</span>
|
||||
<span class="line" id="L369"> <span class="tok-kw">return</span> ret;</span>
|
||||
<span class="line" id="L370"> }</span>
|
||||
<span class="line" id="L371"> <span class="tok-kw">if</span> ((o & <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">1</span>))))) != <span class="tok-number">0</span>) <span class="tok-kw">return</span> fio_ltocstr(<span class="tok-builtin">@as</span>(<span class="tok-type">isize</span>, <span class="tok-builtin">@bitCast</span>(o)) >> <span class="tok-builtin">@as</span>(<span class="tok-builtin">@import</span>(<span class="tok-str">"std"</span>).math.Log2Int(<span class="tok-type">isize</span>), <span class="tok-builtin">@intCast</span>(<span class="tok-number">1</span>)));</span>
|
||||
<span class="line" id="L372"> <span class="tok-kw">if</span> ((o & <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">6</span>))))) == <span class="tok-builtin">@as</span>(<span class="tok-type">c_ulong</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">6</span>))))) {</span>
|
||||
<span class="line" id="L373"> <span class="tok-kw">while</span> (<span class="tok-null">true</span>) {</span>
|
||||
<span class="line" id="L374"> <span class="tok-kw">switch</span> (<span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_uint</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">u8</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">u8</span>, <span class="tok-builtin">@truncate</span>(o)))))))) {</span>
|
||||
<span class="line" id="L375"> <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">6</span>) => {</span>
|
||||
<span class="line" id="L376"> {</span>
|
||||
<span class="line" id="L377"> <span class="tok-kw">const</span> ret: fio_str_info_s = fio_str_info_s{</span>
|
||||
<span class="line" id="L378"> .capa = <span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">0</span>)))),</span>
|
||||
<span class="line" id="L379"> .len = <span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">4</span>)))),</span>
|
||||
<span class="line" id="L380"> .data = <span class="tok-builtin">@as</span>([*c]<span class="tok-type">u8</span>, <span class="tok-builtin">@ptrFromInt</span>(<span class="tok-builtin">@intFromPtr</span>(<span class="tok-str">"null"</span>))),</span>
|
||||
<span class="line" id="L381"> };</span>
|
||||
<span class="line" id="L382"> <span class="tok-kw">return</span> ret;</span>
|
||||
<span class="line" id="L383"> }</span>
|
||||
<span class="line" id="L384"> },</span>
|
||||
<span class="line" id="L385"> <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">38</span>) => {</span>
|
||||
<span class="line" id="L386"> {</span>
|
||||
<span class="line" id="L387"> <span class="tok-kw">const</span> ret: fio_str_info_s = fio_str_info_s{</span>
|
||||
<span class="line" id="L388"> .capa = <span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">0</span>)))),</span>
|
||||
<span class="line" id="L389"> .len = <span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">5</span>)))),</span>
|
||||
<span class="line" id="L390"> .data = <span class="tok-builtin">@as</span>([*c]<span class="tok-type">u8</span>, <span class="tok-builtin">@ptrFromInt</span>(<span class="tok-builtin">@intFromPtr</span>(<span class="tok-str">"false"</span>))),</span>
|
||||
<span class="line" id="L391"> };</span>
|
||||
<span class="line" id="L392"> <span class="tok-kw">return</span> ret;</span>
|
||||
<span class="line" id="L393"> }</span>
|
||||
<span class="line" id="L394"> },</span>
|
||||
<span class="line" id="L395"> <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">22</span>) => {</span>
|
||||
<span class="line" id="L396"> {</span>
|
||||
<span class="line" id="L397"> <span class="tok-kw">const</span> ret: fio_str_info_s = fio_str_info_s{</span>
|
||||
<span class="line" id="L398"> .capa = <span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">0</span>)))),</span>
|
||||
<span class="line" id="L399"> .len = <span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@bitCast</span>(<span class="tok-builtin">@as</span>(<span class="tok-type">c_long</span>, <span class="tok-builtin">@as</span>(<span class="tok-type">c_int</span>, <span class="tok-number">4</span>)))),</span>
|
||||
<span class="line" id="L400"> .data = <span class="tok-builtin">@as</span>([*c]<span class="tok-type">u8</span>, <span class="tok-builtin">@ptrFromInt</span>(<span class="tok-builtin">@intFromPtr</span>(<span class="tok-str">"true"</span>))),</span>
|
||||
<span class="line" id="L401"> };</span>
|
||||
<span class="line" id="L402"> <span class="tok-kw">return</span> ret;</span>
|
||||
<span class="line" id="L403"> }</span>
|
||||
<span class="line" id="L404"> },</span>
|
||||
<span class="line" id="L405"> <span class="tok-kw">else</span> => <span class="tok-kw">break</span>,</span>
|
||||
<span class="line" id="L406"> }</span>
|
||||
<span class="line" id="L407"> <span class="tok-kw">break</span>;</span>
|
||||
<span class="line" id="L408"> }</span>
|
||||
<span class="line" id="L409"> }</span>
|
||||
<span class="line" id="L410"> <span class="tok-kw">return</span> fiobj_type_vtable(o).*.to_str.?(o);</span>
|
||||
<span class="line" id="L411">}</span>
|
||||
<span class="line" id="L412"><span class="tok-comment">// pub const http_cookie_args_s = opaque {};</span>
|
||||
</span>
|
||||
<span class="line" id="L413"></span>
|
||||
<span class="line" id="L414"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_set_header</span>(h: [*c]http_s, name: FIOBJ, value: FIOBJ) <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L415"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_set_header2</span>(h: [*c]http_s, name: fio_str_info_s, value: fio_str_info_s) <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L416"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_set_cookie</span>(h: [*c]http_s, http_cookie_args_s) <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L417"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_sendfile</span>(h: [*c]http_s, fd: <span class="tok-type">c_int</span>, length: <span class="tok-type">usize</span>, offset: <span class="tok-type">usize</span>) <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L418"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_sendfile2</span>(h: [*c]http_s, prefix: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span>, prefix_len: <span class="tok-type">usize</span>, encoded: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span>, encoded_len: <span class="tok-type">usize</span>) <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L419"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_send_error</span>(h: [*c]http_s, error_code: <span class="tok-type">usize</span>) <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L420"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_finish</span>(h: [*c]http_s) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L421"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_push_data</span>(h: [*c]http_s, data: ?*<span class="tok-type">anyopaque</span>, length: <span class="tok-type">usize</span>, mime_type: FIOBJ) <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L422"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_push_file</span>(h: [*c]http_s, filename: FIOBJ, mime_type: FIOBJ) <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L423"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> struct_http_pause_handle_s = <span class="tok-kw">opaque</span> {};</span>
|
||||
<span class="line" id="L424"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> http_pause_handle_s = struct_http_pause_handle_s;</span>
|
||||
<span class="line" id="L425"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_pause</span>(h: [*c]http_s, task: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (?*http_pause_handle_s) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span>) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L426"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_resume</span>(http: ?*http_pause_handle_s, task: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> ([*c]http_s) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span>, fallback: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (?*<span class="tok-type">anyopaque</span>) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span>) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L427"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_paused_udata_get</span>(http: ?*http_pause_handle_s) ?*<span class="tok-type">anyopaque</span>;</span>
|
||||
<span class="line" id="L428"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_paused_udata_set</span>(http: ?*http_pause_handle_s, udata: ?*<span class="tok-type">anyopaque</span>) ?*<span class="tok-type">anyopaque</span>;</span>
|
||||
<span class="line" id="L429"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_listen</span>(port: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span>, binding: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span>, struct_http_settings_s) <span class="tok-type">isize</span>;</span>
|
||||
<span class="line" id="L430"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_connect</span>(url: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span>, unix_address: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span>, struct_http_settings_s) <span class="tok-type">isize</span>;</span>
|
||||
<span class="line" id="L431"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_settings</span>(h: [*c]http_s) [*c]struct_http_settings_s;</span>
|
||||
<span class="line" id="L432"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_peer_addr</span>(h: [*c]http_s) fio_str_info_s;</span>
|
||||
<span class="line" id="L433"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_hijack</span>(h: [*c]http_s, leftover: [*c]fio_str_info_s) <span class="tok-type">isize</span>;</span>
|
||||
<span class="line" id="L434"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> struct_ws_s = <span class="tok-kw">opaque</span> {};</span>
|
||||
<span class="line" id="L435"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> ws_s = struct_ws_s;</span>
|
||||
<span class="line" id="L436"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> websocket_settings_s = <span class="tok-kw">extern</span> <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L437"> on_message: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (?*ws_s, fio_str_info_s, <span class="tok-type">u8</span>) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span>,</span>
|
||||
<span class="line" id="L438"> on_open: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (?*ws_s) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span>,</span>
|
||||
<span class="line" id="L439"> on_ready: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (?*ws_s) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span>,</span>
|
||||
<span class="line" id="L440"> on_shutdown: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (?*ws_s) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span>,</span>
|
||||
<span class="line" id="L441"> on_close: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (<span class="tok-type">isize</span>, ?*<span class="tok-type">anyopaque</span>) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span>,</span>
|
||||
<span class="line" id="L442"> udata: ?*<span class="tok-type">anyopaque</span>,</span>
|
||||
<span class="line" id="L443">};</span>
|
||||
<span class="line" id="L444"></span>
|
||||
<span class="line" id="L445"><span class="tok-comment">// struct websocket_subscribe_s_zigcompat {</span>
|
||||
</span>
|
||||
<span class="line" id="L446"><span class="tok-comment">// ws_s *ws;</span>
|
||||
</span>
|
||||
<span class="line" id="L447"><span class="tok-comment">// fio_str_info_s channel;</span>
|
||||
</span>
|
||||
<span class="line" id="L448"><span class="tok-comment">// void (*on_message)(ws_s *ws, fio_str_info_s channel, fio_str_info_s msg, void *udata);</span>
|
||||
</span>
|
||||
<span class="line" id="L449"><span class="tok-comment">// void (*on_unsubscribe)(void *udata);</span>
|
||||
</span>
|
||||
<span class="line" id="L450"><span class="tok-comment">// void *udata;</span>
|
||||
</span>
|
||||
<span class="line" id="L451"><span class="tok-comment">// fio_match_fn match;</span>
|
||||
</span>
|
||||
<span class="line" id="L452"><span class="tok-comment">// unsigned char force_binary;</span>
|
||||
</span>
|
||||
<span class="line" id="L453"><span class="tok-comment">// unsigned char force_text;</span>
|
||||
</span>
|
||||
<span class="line" id="L454"><span class="tok-comment">// };</span>
|
||||
</span>
|
||||
<span class="line" id="L455"></span>
|
||||
<span class="line" id="L456"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> websocket_subscribe_s_zigcompat = <span class="tok-kw">extern</span> <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L457"> ws: ?*ws_s,</span>
|
||||
<span class="line" id="L458"> channel: fio_str_info_s,</span>
|
||||
<span class="line" id="L459"> on_message: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (?*ws_s, fio_str_info_s, fio_str_info_s, ?*<span class="tok-type">anyopaque</span>) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span>,</span>
|
||||
<span class="line" id="L460"> on_unsubscribe: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (?*<span class="tok-type">anyopaque</span>) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span>,</span>
|
||||
<span class="line" id="L461"> udata: ?*<span class="tok-type">anyopaque</span>,</span>
|
||||
<span class="line" id="L462"> match: fio_match_fn,</span>
|
||||
<span class="line" id="L463"> force_binary: <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L464"> force_text: <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L465">};</span>
|
||||
<span class="line" id="L466"></span>
|
||||
<span class="line" id="L467"><span class="tok-comment">/// 0 on failure</span></span>
|
||||
<span class="line" id="L468"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">websocket_subscribe_zigcompat</span>(websocket_subscribe_s_zigcompat) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">usize</span>;</span>
|
||||
<span class="line" id="L469"></span>
|
||||
<span class="line" id="L470"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_upgrade2ws</span>(http: [*c]http_s, websocket_settings_s) <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L471"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">websocket_connect</span>(url: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span>, settings: websocket_settings_s) <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L472"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">websocket_attach</span>(uuid: <span class="tok-type">isize</span>, http_settings: [*c]http_settings_s, args: [*c]websocket_settings_s, data: ?*<span class="tok-type">anyopaque</span>, length: <span class="tok-type">usize</span>) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L473"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">websocket_udata_get</span>(ws: ?*ws_s) ?*<span class="tok-type">anyopaque</span>;</span>
|
||||
<span class="line" id="L474"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">websocket_udata_set</span>(ws: ?*ws_s, udata: ?*<span class="tok-type">anyopaque</span>) ?*<span class="tok-type">anyopaque</span>;</span>
|
||||
<span class="line" id="L475"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">websocket_uuid</span>(ws: ?*ws_s) <span class="tok-type">isize</span>;</span>
|
||||
<span class="line" id="L476"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">websocket_is_client</span>(ws: ?*ws_s) <span class="tok-type">u8</span>;</span>
|
||||
<span class="line" id="L477"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">websocket_write</span>(ws: ?*ws_s, msg: fio_str_info_s, is_text: <span class="tok-type">u8</span>) <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L478"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">websocket_close</span>(ws: ?*ws_s) <span class="tok-type">void</span>; <span class="tok-comment">// zig-cache/i/e0c8a6e617497ade13de512cbe191f23/include/websockets.h:104:12: warning: struct demoted to opaque type - has bitfield</span>
|
||||
</span>
|
||||
<span class="line" id="L479"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> struct_websocket_subscribe_s = <span class="tok-kw">opaque</span> {};</span>
|
||||
<span class="line" id="L480"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">websocket_subscribe</span>(args: struct_websocket_subscribe_s) <span class="tok-type">usize</span>;</span>
|
||||
<span class="line" id="L481"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">websocket_unsubscribe</span>(ws: ?*ws_s, subscription_id: <span class="tok-type">usize</span>) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L482"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">websocket_optimize4broadcasts</span>(@"type": <span class="tok-type">isize</span>, enable: <span class="tok-type">c_int</span>) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L483"></span>
|
||||
<span class="line" id="L484"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fio_publish</span>(args: fio_publish_args_s) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L485"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> fio_publish_args_s = struct_fio_publish_args_s;</span>
|
||||
<span class="line" id="L486"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> struct_fio_publish_args_s = <span class="tok-kw">extern</span> <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L487"> engine: ?*<span class="tok-type">anyopaque</span> = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L488"> <span class="tok-comment">// we don't support engines other than default</span>
|
||||
</span>
|
||||
<span class="line" id="L489"> <span class="tok-comment">// engine: [*c]const fio_pubsub_engine_s,</span>
|
||||
</span>
|
||||
<span class="line" id="L490"> filter: <span class="tok-type">i32</span> = <span class="tok-number">0</span>,</span>
|
||||
<span class="line" id="L491"> channel: fio_str_info_s,</span>
|
||||
<span class="line" id="L492"> message: fio_str_info_s,</span>
|
||||
<span class="line" id="L493"> is_json: <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L494">};</span>
|
||||
<span class="line" id="L495"></span>
|
||||
<span class="line" id="L496"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> http_sse_s = struct_http_sse_s;</span>
|
||||
<span class="line" id="L497"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> struct_http_sse_s = <span class="tok-kw">extern</span> <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L498"> on_open: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> ([*c]http_sse_s) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span>,</span>
|
||||
<span class="line" id="L499"> on_ready: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> ([*c]http_sse_s) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span>,</span>
|
||||
<span class="line" id="L500"> on_shutdown: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> ([*c]http_sse_s) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span>,</span>
|
||||
<span class="line" id="L501"> on_close: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> ([*c]http_sse_s) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span>,</span>
|
||||
<span class="line" id="L502"> udata: ?*<span class="tok-type">anyopaque</span>,</span>
|
||||
<span class="line" id="L503">};</span>
|
||||
<span class="line" id="L504"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_upgrade2sse</span>(h: [*c]http_s, http_sse_s) <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L505"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_sse_set_timout</span>(sse: [*c]http_sse_s, timeout: <span class="tok-type">u8</span>) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L506"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> fio_match_fn = ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (fio_str_info_s, fio_str_info_s) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L507"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> struct_http_sse_subscribe_args = <span class="tok-kw">extern</span> <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L508"> channel: fio_str_info_s,</span>
|
||||
<span class="line" id="L509"> on_message: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> ([*c]http_sse_s, fio_str_info_s, fio_str_info_s, ?*<span class="tok-type">anyopaque</span>) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span>,</span>
|
||||
<span class="line" id="L510"> on_unsubscribe: ?*<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (?*<span class="tok-type">anyopaque</span>) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span>,</span>
|
||||
<span class="line" id="L511"> udata: ?*<span class="tok-type">anyopaque</span>,</span>
|
||||
<span class="line" id="L512"> match: fio_match_fn,</span>
|
||||
<span class="line" id="L513">};</span>
|
||||
<span class="line" id="L514"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_sse_subscribe</span>(sse: [*c]http_sse_s, args: struct_http_sse_subscribe_args) <span class="tok-type">usize</span>;</span>
|
||||
<span class="line" id="L515"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_sse_unsubscribe</span>(sse: [*c]http_sse_s, subscription: <span class="tok-type">usize</span>) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L516"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> struct_http_sse_write_args = <span class="tok-kw">extern</span> <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L517"> id: fio_str_info_s,</span>
|
||||
<span class="line" id="L518"> event: fio_str_info_s,</span>
|
||||
<span class="line" id="L519"> data: fio_str_info_s,</span>
|
||||
<span class="line" id="L520"> retry: <span class="tok-type">isize</span>,</span>
|
||||
<span class="line" id="L521">};</span>
|
||||
<span class="line" id="L522"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_sse_write</span>(sse: [*c]http_sse_s, struct_http_sse_write_args) <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L523"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_sse2uuid</span>(sse: [*c]http_sse_s) <span class="tok-type">isize</span>;</span>
|
||||
<span class="line" id="L524"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_sse_close</span>(sse: [*c]http_sse_s) <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L525"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_sse_dup</span>(sse: [*c]http_sse_s) [*c]http_sse_s;</span>
|
||||
<span class="line" id="L526"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_sse_free</span>(sse: [*c]http_sse_s) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L527"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_parse_body</span>(h: [*c]http_s) <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L528"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_parse_query</span>(h: [*c]http_s) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L529"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_parse_cookies</span>(h: [*c]http_s, is_url_encoded: <span class="tok-type">u8</span>) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L530"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_add2hash</span>(dest: FIOBJ, name: [*c]<span class="tok-type">u8</span>, name_len: <span class="tok-type">usize</span>, value: [*c]<span class="tok-type">u8</span>, value_len: <span class="tok-type">usize</span>, encoded: <span class="tok-type">u8</span>) <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L531"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_add2hash2</span>(dest: FIOBJ, name: [*c]<span class="tok-type">u8</span>, name_len: <span class="tok-type">usize</span>, value: FIOBJ, encoded: <span class="tok-type">u8</span>) <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L532"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_status2str</span>(status: <span class="tok-type">usize</span>) fio_str_info_s;</span>
|
||||
<span class="line" id="L533"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_mimetype_register</span>(file_ext: [*c]<span class="tok-type">u8</span>, file_ext_len: <span class="tok-type">usize</span>, mime_type_str: FIOBJ) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L534"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_mimetype_find</span>(file_ext: [*c]<span class="tok-type">u8</span>, file_ext_len: <span class="tok-type">usize</span>) FIOBJ;</span>
|
||||
<span class="line" id="L535"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_mimetype_find2</span>(url: FIOBJ) FIOBJ;</span>
|
||||
<span class="line" id="L536"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_mimetype_clear</span>() <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L537"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">var</span> HTTP_HEADER_ACCEPT: FIOBJ;</span>
|
||||
<span class="line" id="L538"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">var</span> HTTP_HEADER_CACHE_CONTROL: FIOBJ;</span>
|
||||
<span class="line" id="L539"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">var</span> HTTP_HEADER_CONNECTION: FIOBJ;</span>
|
||||
<span class="line" id="L540"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">var</span> HTTP_HEADER_CONTENT_ENCODING: FIOBJ;</span>
|
||||
<span class="line" id="L541"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">var</span> HTTP_HEADER_CONTENT_LENGTH: FIOBJ;</span>
|
||||
<span class="line" id="L542"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">var</span> HTTP_HEADER_CONTENT_RANGE: FIOBJ;</span>
|
||||
<span class="line" id="L543"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">var</span> HTTP_HEADER_CONTENT_TYPE: FIOBJ;</span>
|
||||
<span class="line" id="L544"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">var</span> HTTP_HEADER_COOKIE: FIOBJ;</span>
|
||||
<span class="line" id="L545"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">var</span> HTTP_HEADER_DATE: FIOBJ;</span>
|
||||
<span class="line" id="L546"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">var</span> HTTP_HEADER_ETAG: FIOBJ;</span>
|
||||
<span class="line" id="L547"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">var</span> HTTP_HEADER_HOST: FIOBJ;</span>
|
||||
<span class="line" id="L548"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">var</span> HTTP_HEADER_LAST_MODIFIED: FIOBJ;</span>
|
||||
<span class="line" id="L549"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">var</span> HTTP_HEADER_ORIGIN: FIOBJ;</span>
|
||||
<span class="line" id="L550"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">var</span> HTTP_HEADER_SET_COOKIE: FIOBJ;</span>
|
||||
<span class="line" id="L551"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">var</span> HTTP_HEADER_UPGRADE: FIOBJ;</span>
|
||||
<span class="line" id="L552"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_req2str</span>(h: [*c]http_s) FIOBJ;</span>
|
||||
<span class="line" id="L553"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_write_log</span>(h: [*c]http_s) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L554"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_gmtime</span>(timer: time_t, tmbuf: [*c]struct_tm) [*c]struct_tm;</span>
|
||||
<span class="line" id="L555"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_date2rfc7231</span>(target: [*c]<span class="tok-type">u8</span>, tmbuf: [*c]struct_tm) <span class="tok-type">usize</span>;</span>
|
||||
<span class="line" id="L556"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_date2rfc2109</span>(target: [*c]<span class="tok-type">u8</span>, tmbuf: [*c]struct_tm) <span class="tok-type">usize</span>;</span>
|
||||
<span class="line" id="L557"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_date2rfc2822</span>(target: [*c]<span class="tok-type">u8</span>, tmbuf: [*c]struct_tm) <span class="tok-type">usize</span>;</span>
|
||||
<span class="line" id="L558"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_date2str</span>(arg_target: [*c]<span class="tok-type">u8</span>, arg_tmbuf: [*c]struct_tm) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">usize</span> {</span>
|
||||
<span class="line" id="L559"> <span class="tok-kw">const</span> target = arg_target;</span>
|
||||
<span class="line" id="L560"> <span class="tok-kw">const</span> tmbuf = arg_tmbuf;</span>
|
||||
<span class="line" id="L561"> <span class="tok-kw">return</span> http_date2rfc7231(target, tmbuf);</span>
|
||||
<span class="line" id="L562">}</span>
|
||||
<span class="line" id="L563"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_time2str</span>(target: [*c]<span class="tok-type">u8</span>, t: time_t) <span class="tok-type">usize</span>;</span>
|
||||
<span class="line" id="L564"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_decode_url_unsafe</span>(dest: [*c]<span class="tok-type">u8</span>, url_data: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span>) <span class="tok-type">isize</span>;</span>
|
||||
<span class="line" id="L565"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_decode_url</span>(dest: [*c]<span class="tok-type">u8</span>, url_data: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span>, length: <span class="tok-type">usize</span>) <span class="tok-type">isize</span>;</span>
|
||||
<span class="line" id="L566"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_decode_path_unsafe</span>(dest: [*c]<span class="tok-type">u8</span>, url_data: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span>) <span class="tok-type">isize</span>;</span>
|
||||
<span class="line" id="L567"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">http_decode_path</span>(dest: [*c]<span class="tok-type">u8</span>, url_data: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span>, length: <span class="tok-type">usize</span>) <span class="tok-type">isize</span>;</span>
|
||||
<span class="line" id="L568"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> http_url_s = fio_url_s;</span>
|
||||
<span class="line" id="L569"></span>
|
||||
<span class="line" id="L570"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> struct_tm = <span class="tok-kw">extern</span> <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L571"> tm_sec: <span class="tok-type">c_int</span>,</span>
|
||||
<span class="line" id="L572"> tm_min: <span class="tok-type">c_int</span>,</span>
|
||||
<span class="line" id="L573"> tm_hour: <span class="tok-type">c_int</span>,</span>
|
||||
<span class="line" id="L574"> tm_mday: <span class="tok-type">c_int</span>,</span>
|
||||
<span class="line" id="L575"> tm_mon: <span class="tok-type">c_int</span>,</span>
|
||||
<span class="line" id="L576"> tm_year: <span class="tok-type">c_int</span>,</span>
|
||||
<span class="line" id="L577"> tm_wday: <span class="tok-type">c_int</span>,</span>
|
||||
<span class="line" id="L578"> tm_yday: <span class="tok-type">c_int</span>,</span>
|
||||
<span class="line" id="L579"> tm_isdst: <span class="tok-type">c_int</span>,</span>
|
||||
<span class="line" id="L580"> tm_gmtoff: <span class="tok-type">c_long</span>,</span>
|
||||
<span class="line" id="L581"> tm_zone: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L582">};</span>
|
||||
<span class="line" id="L583"></span>
|
||||
</code></pre></body>
|
||||
</html>
|
|
@ -1,250 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>http.zig - source view</title>
|
||||
<link rel="icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAgklEQVR4AWMYWuD7EllJIM4G4g4g5oIJ/odhOJ8wToOxSTXgNxDHoeiBMfA4+wGShjyYOCkG/IGqWQziEzYAoUAeiF9D5U+DxEg14DRU7jWIT5IBIOdCxf+A+CQZAAoopEB7QJwBCBwHiip8UYmRdrAlDpIMgApwQZNnNii5Dq0MBgCxxycBnwEd+wAAAABJRU5ErkJggg==">
|
||||
<link rel="icon" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNTMgMTQwIj48ZyBmaWxsPSIjRjdBNDFEIj48Zz48cG9seWdvbiBwb2ludHM9IjQ2LDIyIDI4LDQ0IDE5LDMwIi8+PHBvbHlnb24gcG9pbnRzPSI0NiwyMiAzMywzMyAyOCw0NCAyMiw0NCAyMiw5NSAzMSw5NSAyMCwxMDAgMTIsMTE3IDAsMTE3IDAsMjIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMzEsOTUgMTIsMTE3IDQsMTA2Ii8+PC9nPjxnPjxwb2x5Z29uIHBvaW50cz0iNTYsMjIgNjIsMzYgMzcsNDQiLz48cG9seWdvbiBwb2ludHM9IjU2LDIyIDExMSwyMiAxMTEsNDQgMzcsNDQgNTYsMzIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTE2LDk1IDk3LDExNyA5MCwxMDQiLz48cG9seWdvbiBwb2ludHM9IjExNiw5NSAxMDAsMTA0IDk3LDExNyA0MiwxMTcgNDIsOTUiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTUwLDAgNTIsMTE3IDMsMTQwIDEwMSwyMiIvPjwvZz48Zz48cG9seWdvbiBwb2ludHM9IjE0MSwyMiAxNDAsNDAgMTIyLDQ1Ii8+PHBvbHlnb24gcG9pbnRzPSIxNTMsMjIgMTUzLDExNyAxMDYsMTE3IDEyMCwxMDUgMTI1LDk1IDEzMSw5NSAxMzEsNDUgMTIyLDQ1IDEzMiwzNiAxNDEsMjIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTI1LDk1IDEzMCwxMTAgMTA2LDExNyIvPjwvZz48L2c+PC9zdmc+">
|
||||
<style>
|
||||
body{
|
||||
font-family: system-ui, -apple-system, Roboto, "Segoe UI", sans-serif;
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
pre > code {
|
||||
display: block;
|
||||
overflow: auto;
|
||||
line-height: normal;
|
||||
margin: 0em;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-str {
|
||||
color: #d14;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #005C7A;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #545454;
|
||||
font-style: italic;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #900;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-null {
|
||||
color: #005C5C;
|
||||
}
|
||||
.tok-number {
|
||||
color: #005C5C;
|
||||
}
|
||||
.tok-type {
|
||||
color: #458;
|
||||
font-weight: bold;
|
||||
}
|
||||
pre {
|
||||
counter-reset: line;
|
||||
}
|
||||
pre .line:before {
|
||||
counter-increment: line;
|
||||
content: counter(line);
|
||||
display: inline-block;
|
||||
padding-right: 1em;
|
||||
width: 2em;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.line {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
.line:target {
|
||||
border-top: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ccc;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body{
|
||||
background:#222;
|
||||
color: #ccc;
|
||||
}
|
||||
pre > code {
|
||||
color: #ccc;
|
||||
background: #222;
|
||||
border: unset;
|
||||
}
|
||||
.line:target {
|
||||
border-top: 1px solid #444;
|
||||
border-bottom: 1px solid #444;
|
||||
background: #333;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #eee;
|
||||
}
|
||||
.tok-str {
|
||||
color: #2e5;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #ff894c;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #aa7;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #B1A0F8;
|
||||
}
|
||||
.tok-null {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-number {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-type {
|
||||
color: #68f;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre><code><span class="line" id="L1"><span class="tok-kw">const</span> std = <span class="tok-builtin">@import</span>(<span class="tok-str">"std"</span>);</span>
|
||||
<span class="line" id="L2"></span>
|
||||
<span class="line" id="L3"><span class="tok-comment">/// HTTP Status codes according to `rfc7231`</span></span>
|
||||
<span class="line" id="L4"><span class="tok-comment">/// https://tools.ietf.org/html/rfc7231#section-6</span></span>
|
||||
<span class="line" id="L5"><span class="tok-comment">/// (taken from https://github.com/Luukdegram/apple_pie/blob/master/src/response.zig)</span></span>
|
||||
<span class="line" id="L6"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> StatusCode = <span class="tok-kw">enum</span>(<span class="tok-type">u16</span>) {</span>
|
||||
<span class="line" id="L7"> <span class="tok-comment">// Informational 1xx</span>
|
||||
</span>
|
||||
<span class="line" id="L8"> @"continue" = <span class="tok-number">100</span>,</span>
|
||||
<span class="line" id="L9"> <span class="tok-comment">// Successful 2xx</span>
|
||||
</span>
|
||||
<span class="line" id="L10"> switching_protocols = <span class="tok-number">101</span>,</span>
|
||||
<span class="line" id="L11"> ok = <span class="tok-number">200</span>,</span>
|
||||
<span class="line" id="L12"> created = <span class="tok-number">201</span>,</span>
|
||||
<span class="line" id="L13"> accepted = <span class="tok-number">202</span>,</span>
|
||||
<span class="line" id="L14"> non_authoritative_information = <span class="tok-number">203</span>,</span>
|
||||
<span class="line" id="L15"> no_content = <span class="tok-number">204</span>,</span>
|
||||
<span class="line" id="L16"> reset_content = <span class="tok-number">205</span>,</span>
|
||||
<span class="line" id="L17"> <span class="tok-comment">// redirections 3xx</span>
|
||||
</span>
|
||||
<span class="line" id="L18"> partial_content = <span class="tok-number">206</span>,</span>
|
||||
<span class="line" id="L19"> multiple_choices = <span class="tok-number">300</span>,</span>
|
||||
<span class="line" id="L20"> moved_permanently = <span class="tok-number">301</span>,</span>
|
||||
<span class="line" id="L21"> found = <span class="tok-number">302</span>,</span>
|
||||
<span class="line" id="L22"> see_other = <span class="tok-number">303</span>,</span>
|
||||
<span class="line" id="L23"> not_modified = <span class="tok-number">304</span>,</span>
|
||||
<span class="line" id="L24"> use_proxy = <span class="tok-number">305</span>,</span>
|
||||
<span class="line" id="L25"> temporary_redirect = <span class="tok-number">307</span>,</span>
|
||||
<span class="line" id="L26"> <span class="tok-comment">// client errors 4xx</span>
|
||||
</span>
|
||||
<span class="line" id="L27"> bad_request = <span class="tok-number">400</span>,</span>
|
||||
<span class="line" id="L28"> unauthorized = <span class="tok-number">401</span>,</span>
|
||||
<span class="line" id="L29"> payment_required = <span class="tok-number">402</span>,</span>
|
||||
<span class="line" id="L30"> forbidden = <span class="tok-number">403</span>,</span>
|
||||
<span class="line" id="L31"> not_found = <span class="tok-number">404</span>,</span>
|
||||
<span class="line" id="L32"> method_not_allowed = <span class="tok-number">405</span>,</span>
|
||||
<span class="line" id="L33"> not_acceptable = <span class="tok-number">406</span>,</span>
|
||||
<span class="line" id="L34"> proxy_authentication_required = <span class="tok-number">407</span>,</span>
|
||||
<span class="line" id="L35"> request_timeout = <span class="tok-number">408</span>,</span>
|
||||
<span class="line" id="L36"> conflict = <span class="tok-number">409</span>,</span>
|
||||
<span class="line" id="L37"> gone = <span class="tok-number">410</span>,</span>
|
||||
<span class="line" id="L38"> length_required = <span class="tok-number">411</span>,</span>
|
||||
<span class="line" id="L39"> precondition_failed = <span class="tok-number">412</span>,</span>
|
||||
<span class="line" id="L40"> request_entity_too_large = <span class="tok-number">413</span>,</span>
|
||||
<span class="line" id="L41"> request_uri_too_long = <span class="tok-number">414</span>,</span>
|
||||
<span class="line" id="L42"> unsupported_mediatype = <span class="tok-number">415</span>,</span>
|
||||
<span class="line" id="L43"> requested_range_not_satisfiable = <span class="tok-number">416</span>,</span>
|
||||
<span class="line" id="L44"> expectation_failed = <span class="tok-number">417</span>,</span>
|
||||
<span class="line" id="L45"> <span class="tok-comment">/// teapot is an extension status code and not required for clients to support</span></span>
|
||||
<span class="line" id="L46"> teapot = <span class="tok-number">418</span>,</span>
|
||||
<span class="line" id="L47"> upgrade_required = <span class="tok-number">426</span>,</span>
|
||||
<span class="line" id="L48"> <span class="tok-comment">/// extra status code according to `https://tools.ietf.org/html/rfc6585#section-5`</span></span>
|
||||
<span class="line" id="L49"> request_header_fields_too_large = <span class="tok-number">431</span>,</span>
|
||||
<span class="line" id="L50"> <span class="tok-comment">// server errors 5xx</span>
|
||||
</span>
|
||||
<span class="line" id="L51"> internal_server_error = <span class="tok-number">500</span>,</span>
|
||||
<span class="line" id="L52"> not_implemented = <span class="tok-number">501</span>,</span>
|
||||
<span class="line" id="L53"> bad_gateway = <span class="tok-number">502</span>,</span>
|
||||
<span class="line" id="L54"> service_unavailable = <span class="tok-number">503</span>,</span>
|
||||
<span class="line" id="L55"> gateway_timeout = <span class="tok-number">504</span>,</span>
|
||||
<span class="line" id="L56"> http_version_not_supported = <span class="tok-number">505</span>,</span>
|
||||
<span class="line" id="L57"> _,</span>
|
||||
<span class="line" id="L58"></span>
|
||||
<span class="line" id="L59"> <span class="tok-comment">/// Returns the string value of a `StatusCode`</span></span>
|
||||
<span class="line" id="L60"> <span class="tok-comment">/// for example: .ResetContent returns "Returns Content".</span></span>
|
||||
<span class="line" id="L61"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">toString</span>(self: StatusCode) []<span class="tok-kw">const</span> <span class="tok-type">u8</span> {</span>
|
||||
<span class="line" id="L62"> <span class="tok-kw">return</span> <span class="tok-kw">switch</span> (self) {</span>
|
||||
<span class="line" id="L63"> .@"continue" => <span class="tok-str">"Continue"</span>,</span>
|
||||
<span class="line" id="L64"> .switching_protocols => <span class="tok-str">"Switching Protocols"</span>,</span>
|
||||
<span class="line" id="L65"> .ok => <span class="tok-str">"Ok"</span>,</span>
|
||||
<span class="line" id="L66"> .created => <span class="tok-str">"Created"</span>,</span>
|
||||
<span class="line" id="L67"> .accepted => <span class="tok-str">"Accepted"</span>,</span>
|
||||
<span class="line" id="L68"> .non_authoritative_information => <span class="tok-str">"Non Authoritative Information"</span>,</span>
|
||||
<span class="line" id="L69"> .no_content => <span class="tok-str">"No Content"</span>,</span>
|
||||
<span class="line" id="L70"> .reset_content => <span class="tok-str">"Reset Content"</span>,</span>
|
||||
<span class="line" id="L71"> .partial_content => <span class="tok-str">"Partial Content"</span>,</span>
|
||||
<span class="line" id="L72"> .multiple_choices => <span class="tok-str">"Multiple Choices"</span>,</span>
|
||||
<span class="line" id="L73"> .moved_permanently => <span class="tok-str">"Moved Permanently"</span>,</span>
|
||||
<span class="line" id="L74"> .found => <span class="tok-str">"Found"</span>,</span>
|
||||
<span class="line" id="L75"> .see_other => <span class="tok-str">"See Other"</span>,</span>
|
||||
<span class="line" id="L76"> .not_modified => <span class="tok-str">"Not Modified"</span>,</span>
|
||||
<span class="line" id="L77"> .use_proxy => <span class="tok-str">"Use Proxy"</span>,</span>
|
||||
<span class="line" id="L78"> .temporary_redirect => <span class="tok-str">"Temporary Redirect"</span>,</span>
|
||||
<span class="line" id="L79"> .bad_request => <span class="tok-str">"Bad Request"</span>,</span>
|
||||
<span class="line" id="L80"> .unauthorized => <span class="tok-str">"Unauthorized"</span>,</span>
|
||||
<span class="line" id="L81"> .payment_required => <span class="tok-str">"Payment Required"</span>,</span>
|
||||
<span class="line" id="L82"> .forbidden => <span class="tok-str">"Forbidden"</span>,</span>
|
||||
<span class="line" id="L83"> .not_found => <span class="tok-str">"Not Found"</span>,</span>
|
||||
<span class="line" id="L84"> .method_not_allowed => <span class="tok-str">"Method Not Allowed"</span>,</span>
|
||||
<span class="line" id="L85"> .not_acceptable => <span class="tok-str">"Not Acceptable"</span>,</span>
|
||||
<span class="line" id="L86"> .proxy_authentication_required => <span class="tok-str">"Proxy Authentication Required"</span>,</span>
|
||||
<span class="line" id="L87"> .request_timeout => <span class="tok-str">"Request Timeout"</span>,</span>
|
||||
<span class="line" id="L88"> .conflict => <span class="tok-str">"Conflict"</span>,</span>
|
||||
<span class="line" id="L89"> .gone => <span class="tok-str">"Gone"</span>,</span>
|
||||
<span class="line" id="L90"> .length_required => <span class="tok-str">"Length Required"</span>,</span>
|
||||
<span class="line" id="L91"> .precondition_failed => <span class="tok-str">"Precondition Failed"</span>,</span>
|
||||
<span class="line" id="L92"> .request_entity_too_large => <span class="tok-str">"Request Entity Too Large"</span>,</span>
|
||||
<span class="line" id="L93"> .request_uri_too_long => <span class="tok-str">"Request-URI Too Long"</span>,</span>
|
||||
<span class="line" id="L94"> .unsupported_mediatype => <span class="tok-str">"Unsupported Media Type"</span>,</span>
|
||||
<span class="line" id="L95"> .requested_range_not_satisfiable => <span class="tok-str">"Requested Range Not Satisfiable"</span>,</span>
|
||||
<span class="line" id="L96"> .teapot => <span class="tok-str">"I'm a Teapot"</span>,</span>
|
||||
<span class="line" id="L97"> .upgrade_required => <span class="tok-str">"Upgrade Required"</span>,</span>
|
||||
<span class="line" id="L98"> .request_header_fields_too_large => <span class="tok-str">"Request Header Fields Too Large"</span>,</span>
|
||||
<span class="line" id="L99"> .expectation_failed => <span class="tok-str">"Expectation Failed"</span>,</span>
|
||||
<span class="line" id="L100"> .internal_server_error => <span class="tok-str">"Internal Server Error"</span>,</span>
|
||||
<span class="line" id="L101"> .not_implemented => <span class="tok-str">"Not Implemented"</span>,</span>
|
||||
<span class="line" id="L102"> .bad_gateway => <span class="tok-str">"Bad Gateway"</span>,</span>
|
||||
<span class="line" id="L103"> .service_unavailable => <span class="tok-str">"Service Unavailable"</span>,</span>
|
||||
<span class="line" id="L104"> .gateway_timeout => <span class="tok-str">"Gateway Timeout"</span>,</span>
|
||||
<span class="line" id="L105"> .http_version_not_supported => <span class="tok-str">"HTTP Version Not Supported"</span>,</span>
|
||||
<span class="line" id="L106"> _ => <span class="tok-str">""</span>,</span>
|
||||
<span class="line" id="L107"> };</span>
|
||||
<span class="line" id="L108"> }</span>
|
||||
<span class="line" id="L109">};</span>
|
||||
<span class="line" id="L110"></span>
|
||||
<span class="line" id="L111"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> Method = <span class="tok-kw">enum</span> {</span>
|
||||
<span class="line" id="L112"> GET,</span>
|
||||
<span class="line" id="L113"> POST,</span>
|
||||
<span class="line" id="L114"> PUT,</span>
|
||||
<span class="line" id="L115"> DELETE,</span>
|
||||
<span class="line" id="L116"> PATCH,</span>
|
||||
<span class="line" id="L117"> OPTIONS,</span>
|
||||
<span class="line" id="L118"> UNKNOWN,</span>
|
||||
<span class="line" id="L119">};</span>
|
||||
<span class="line" id="L120"></span>
|
||||
<span class="line" id="L121"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">methodToEnum</span>(method: ?[]<span class="tok-kw">const</span> <span class="tok-type">u8</span>) Method {</span>
|
||||
<span class="line" id="L122"> {</span>
|
||||
<span class="line" id="L123"> <span class="tok-kw">if</span> (method) |m| {</span>
|
||||
<span class="line" id="L124"> <span class="tok-kw">return</span> std.meta.stringToEnum(Method, m) <span class="tok-kw">orelse</span> .UNKNOWN;</span>
|
||||
<span class="line" id="L125"> }</span>
|
||||
<span class="line" id="L126"> <span class="tok-kw">return</span> Method.UNKNOWN;</span>
|
||||
<span class="line" id="L127"> }</span>
|
||||
<span class="line" id="L128">}</span>
|
||||
<span class="line" id="L129"></span>
|
||||
</code></pre></body>
|
||||
</html>
|
|
@ -1,766 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>http_auth.zig - source view</title>
|
||||
<link rel="icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAgklEQVR4AWMYWuD7EllJIM4G4g4g5oIJ/odhOJ8wToOxSTXgNxDHoeiBMfA4+wGShjyYOCkG/IGqWQziEzYAoUAeiF9D5U+DxEg14DRU7jWIT5IBIOdCxf+A+CQZAAoopEB7QJwBCBwHiip8UYmRdrAlDpIMgApwQZNnNii5Dq0MBgCxxycBnwEd+wAAAABJRU5ErkJggg==">
|
||||
<link rel="icon" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNTMgMTQwIj48ZyBmaWxsPSIjRjdBNDFEIj48Zz48cG9seWdvbiBwb2ludHM9IjQ2LDIyIDI4LDQ0IDE5LDMwIi8+PHBvbHlnb24gcG9pbnRzPSI0NiwyMiAzMywzMyAyOCw0NCAyMiw0NCAyMiw5NSAzMSw5NSAyMCwxMDAgMTIsMTE3IDAsMTE3IDAsMjIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMzEsOTUgMTIsMTE3IDQsMTA2Ii8+PC9nPjxnPjxwb2x5Z29uIHBvaW50cz0iNTYsMjIgNjIsMzYgMzcsNDQiLz48cG9seWdvbiBwb2ludHM9IjU2LDIyIDExMSwyMiAxMTEsNDQgMzcsNDQgNTYsMzIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTE2LDk1IDk3LDExNyA5MCwxMDQiLz48cG9seWdvbiBwb2ludHM9IjExNiw5NSAxMDAsMTA0IDk3LDExNyA0MiwxMTcgNDIsOTUiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTUwLDAgNTIsMTE3IDMsMTQwIDEwMSwyMiIvPjwvZz48Zz48cG9seWdvbiBwb2ludHM9IjE0MSwyMiAxNDAsNDAgMTIyLDQ1Ii8+PHBvbHlnb24gcG9pbnRzPSIxNTMsMjIgMTUzLDExNyAxMDYsMTE3IDEyMCwxMDUgMTI1LDk1IDEzMSw5NSAxMzEsNDUgMTIyLDQ1IDEzMiwzNiAxNDEsMjIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTI1LDk1IDEzMCwxMTAgMTA2LDExNyIvPjwvZz48L2c+PC9zdmc+">
|
||||
<style>
|
||||
body{
|
||||
font-family: system-ui, -apple-system, Roboto, "Segoe UI", sans-serif;
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
pre > code {
|
||||
display: block;
|
||||
overflow: auto;
|
||||
line-height: normal;
|
||||
margin: 0em;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-str {
|
||||
color: #d14;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #005C7A;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #545454;
|
||||
font-style: italic;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #900;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-null {
|
||||
color: #005C5C;
|
||||
}
|
||||
.tok-number {
|
||||
color: #005C5C;
|
||||
}
|
||||
.tok-type {
|
||||
color: #458;
|
||||
font-weight: bold;
|
||||
}
|
||||
pre {
|
||||
counter-reset: line;
|
||||
}
|
||||
pre .line:before {
|
||||
counter-increment: line;
|
||||
content: counter(line);
|
||||
display: inline-block;
|
||||
padding-right: 1em;
|
||||
width: 2em;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.line {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
.line:target {
|
||||
border-top: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ccc;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body{
|
||||
background:#222;
|
||||
color: #ccc;
|
||||
}
|
||||
pre > code {
|
||||
color: #ccc;
|
||||
background: #222;
|
||||
border: unset;
|
||||
}
|
||||
.line:target {
|
||||
border-top: 1px solid #444;
|
||||
border-bottom: 1px solid #444;
|
||||
background: #333;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #eee;
|
||||
}
|
||||
.tok-str {
|
||||
color: #2e5;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #ff894c;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #aa7;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #B1A0F8;
|
||||
}
|
||||
.tok-null {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-number {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-type {
|
||||
color: #68f;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre><code><span class="line" id="L1"><span class="tok-kw">const</span> std = <span class="tok-builtin">@import</span>(<span class="tok-str">"std"</span>);</span>
|
||||
<span class="line" id="L2"><span class="tok-kw">const</span> zap = <span class="tok-builtin">@import</span>(<span class="tok-str">"zap.zig"</span>);</span>
|
||||
<span class="line" id="L3"></span>
|
||||
<span class="line" id="L4"><span class="tok-comment">/// Authentication Scheme enum: Basic or Bearer.</span></span>
|
||||
<span class="line" id="L5"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> AuthScheme = <span class="tok-kw">enum</span> {</span>
|
||||
<span class="line" id="L6"> Basic,</span>
|
||||
<span class="line" id="L7"> Bearer,</span>
|
||||
<span class="line" id="L8"></span>
|
||||
<span class="line" id="L9"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">str</span>(self: AuthScheme) []<span class="tok-kw">const</span> <span class="tok-type">u8</span> {</span>
|
||||
<span class="line" id="L10"> <span class="tok-kw">return</span> <span class="tok-kw">switch</span> (self) {</span>
|
||||
<span class="line" id="L11"> .Basic => <span class="tok-str">"Basic "</span>,</span>
|
||||
<span class="line" id="L12"> .Bearer => <span class="tok-str">"Bearer "</span>,</span>
|
||||
<span class="line" id="L13"> };</span>
|
||||
<span class="line" id="L14"> }</span>
|
||||
<span class="line" id="L15"></span>
|
||||
<span class="line" id="L16"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">headerFieldStrFio</span>(self: AuthScheme) []<span class="tok-kw">const</span> <span class="tok-type">u8</span> {</span>
|
||||
<span class="line" id="L17"> <span class="tok-kw">return</span> <span class="tok-kw">switch</span> (self) {</span>
|
||||
<span class="line" id="L18"> .Basic => <span class="tok-str">"authentication"</span>,</span>
|
||||
<span class="line" id="L19"> .Bearer => <span class="tok-str">"authorization"</span>,</span>
|
||||
<span class="line" id="L20"> };</span>
|
||||
<span class="line" id="L21"> }</span>
|
||||
<span class="line" id="L22"></span>
|
||||
<span class="line" id="L23"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">headerFieldStrHeader</span>(self: AuthScheme) [:<span class="tok-number">0</span>]<span class="tok-kw">const</span> <span class="tok-type">u8</span> {</span>
|
||||
<span class="line" id="L24"> <span class="tok-kw">return</span> <span class="tok-kw">switch</span> (self) {</span>
|
||||
<span class="line" id="L25"> .Basic => <span class="tok-str">"Authentication"</span>,</span>
|
||||
<span class="line" id="L26"> .Bearer => <span class="tok-str">"Authorization"</span>,</span>
|
||||
<span class="line" id="L27"> };</span>
|
||||
<span class="line" id="L28"> }</span>
|
||||
<span class="line" id="L29">};</span>
|
||||
<span class="line" id="L30"></span>
|
||||
<span class="line" id="L31"><span class="tok-comment">/// Used internally: check for presence of the requested auth header.</span></span>
|
||||
<span class="line" id="L32"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">checkAuthHeader</span>(scheme: AuthScheme, auth_header: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>) <span class="tok-type">bool</span> {</span>
|
||||
<span class="line" id="L33"> <span class="tok-kw">return</span> <span class="tok-kw">switch</span> (scheme) {</span>
|
||||
<span class="line" id="L34"> .Basic => |b| std.mem.startsWith(<span class="tok-type">u8</span>, auth_header, b.str()) <span class="tok-kw">and</span> auth_header.len > b.str().len,</span>
|
||||
<span class="line" id="L35"> .Bearer => |b| std.mem.startsWith(<span class="tok-type">u8</span>, auth_header, b.str()) <span class="tok-kw">and</span> auth_header.len > b.str().len,</span>
|
||||
<span class="line" id="L36"> };</span>
|
||||
<span class="line" id="L37">}</span>
|
||||
<span class="line" id="L38"></span>
|
||||
<span class="line" id="L39"><span class="tok-comment">/// Used internally: return the requested auth header.</span></span>
|
||||
<span class="line" id="L40"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">extractAuthHeader</span>(scheme: AuthScheme, r: *<span class="tok-kw">const</span> zap.Request) ?[]<span class="tok-kw">const</span> <span class="tok-type">u8</span> {</span>
|
||||
<span class="line" id="L41"> <span class="tok-kw">return</span> <span class="tok-kw">switch</span> (scheme) {</span>
|
||||
<span class="line" id="L42"> .Basic => |b| r.getHeader(b.headerFieldStrFio()),</span>
|
||||
<span class="line" id="L43"> .Bearer => |b| r.getHeader(b.headerFieldStrFio()),</span>
|
||||
<span class="line" id="L44"> };</span>
|
||||
<span class="line" id="L45">}</span>
|
||||
<span class="line" id="L46"></span>
|
||||
<span class="line" id="L47"><span class="tok-comment">/// Decoding Strategy for Basic Authentication</span></span>
|
||||
<span class="line" id="L48"><span class="tok-kw">const</span> BasicAuthStrategy = <span class="tok-kw">enum</span> {</span>
|
||||
<span class="line" id="L49"> <span class="tok-comment">/// decode into user and pass, then check pass</span></span>
|
||||
<span class="line" id="L50"> UserPass,</span>
|
||||
<span class="line" id="L51"> <span class="tok-comment">/// just look up the encoded user:pass token</span></span>
|
||||
<span class="line" id="L52"> Token68,</span>
|
||||
<span class="line" id="L53">};</span>
|
||||
<span class="line" id="L54"></span>
|
||||
<span class="line" id="L55"><span class="tok-comment">/// Authentication result</span></span>
|
||||
<span class="line" id="L56"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> AuthResult = <span class="tok-kw">enum</span> {</span>
|
||||
<span class="line" id="L57"> <span class="tok-comment">/// authentication / authorization was successful</span></span>
|
||||
<span class="line" id="L58"> AuthOK,</span>
|
||||
<span class="line" id="L59"> <span class="tok-comment">/// authentication / authorization failed</span></span>
|
||||
<span class="line" id="L60"> AuthFailed,</span>
|
||||
<span class="line" id="L61"> <span class="tok-comment">/// The authenticator handled the request that didn't pass authentication /</span></span>
|
||||
<span class="line" id="L62"> <span class="tok-comment">/// authorization.</span></span>
|
||||
<span class="line" id="L63"> <span class="tok-comment">/// This is used to implement authenticators that redirect to a login</span></span>
|
||||
<span class="line" id="L64"> <span class="tok-comment">/// page. An Authenticating endpoint will not do the default, which is trying</span></span>
|
||||
<span class="line" id="L65"> <span class="tok-comment">/// to call the `unauthorized` callback if one exists orelse ignore the request.</span></span>
|
||||
<span class="line" id="L66"> Handled,</span>
|
||||
<span class="line" id="L67">};</span>
|
||||
<span class="line" id="L68"></span>
|
||||
<span class="line" id="L69"><span class="tok-comment">/// HTTP Basic Authentication RFC 7617.</span></span>
|
||||
<span class="line" id="L70"><span class="tok-comment">/// "Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="</span></span>
|
||||
<span class="line" id="L71"><span class="tok-comment">/// user-pass strings: "$username:$password" -> base64</span></span>
|
||||
<span class="line" id="L72"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L73"><span class="tok-comment">/// Notes:</span></span>
|
||||
<span class="line" id="L74"><span class="tok-comment">/// - we only look at the Authentication header</span></span>
|
||||
<span class="line" id="L75"><span class="tok-comment">/// - we ignore the required realm parameter</span></span>
|
||||
<span class="line" id="L76"><span class="tok-comment">/// - we ignore the optional charset parameter</span></span>
|
||||
<span class="line" id="L77"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L78"><span class="tok-comment">/// Errors:</span></span>
|
||||
<span class="line" id="L79"><span class="tok-comment">/// WWW-Authenticate: Basic realm="this"</span></span>
|
||||
<span class="line" id="L80"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L81"><span class="tok-comment">/// Lookup : any kind of map that implements get([]const u8) -> []const u8</span></span>
|
||||
<span class="line" id="L82"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">Basic</span>(<span class="tok-kw">comptime</span> Lookup: <span class="tok-type">type</span>, <span class="tok-kw">comptime</span> kind: BasicAuthStrategy) <span class="tok-type">type</span> {</span>
|
||||
<span class="line" id="L83"> <span class="tok-kw">return</span> <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L84"> allocator: std.mem.Allocator,</span>
|
||||
<span class="line" id="L85"> realm: ?[]<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L86"> lookup: *Lookup,</span>
|
||||
<span class="line" id="L87"></span>
|
||||
<span class="line" id="L88"> <span class="tok-kw">const</span> Self = <span class="tok-builtin">@This</span>();</span>
|
||||
<span class="line" id="L89"></span>
|
||||
<span class="line" id="L90"> <span class="tok-comment">/// Creates a BasicAuth. `lookup` must implement `.get([]const u8) -> []const u8`</span></span>
|
||||
<span class="line" id="L91"> <span class="tok-comment">/// different implementations can</span></span>
|
||||
<span class="line" id="L92"> <span class="tok-comment">/// - either decode, lookup and compare passwords</span></span>
|
||||
<span class="line" id="L93"> <span class="tok-comment">/// - or just check for existence of the base64-encoded user:pass combination</span></span>
|
||||
<span class="line" id="L94"> <span class="tok-comment">/// if realm is provided (not null), a copy of it is taken -> call deinit() to clean up</span></span>
|
||||
<span class="line" id="L95"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">init</span>(allocator: std.mem.Allocator, lookup: *Lookup, realm: ?[]<span class="tok-kw">const</span> <span class="tok-type">u8</span>) !Self {</span>
|
||||
<span class="line" id="L96"> <span class="tok-kw">return</span> .{</span>
|
||||
<span class="line" id="L97"> .allocator = allocator,</span>
|
||||
<span class="line" id="L98"> .lookup = lookup,</span>
|
||||
<span class="line" id="L99"> .realm = <span class="tok-kw">if</span> (realm) |the_realm| <span class="tok-kw">try</span> allocator.dupe(<span class="tok-type">u8</span>, the_realm) <span class="tok-kw">else</span> <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L100"> };</span>
|
||||
<span class="line" id="L101"> }</span>
|
||||
<span class="line" id="L102"></span>
|
||||
<span class="line" id="L103"> <span class="tok-comment">/// Deinit the authenticator.</span></span>
|
||||
<span class="line" id="L104"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">deinit</span>(self: *Self) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L105"> <span class="tok-kw">if</span> (self.realm) |the_realm| {</span>
|
||||
<span class="line" id="L106"> self.allocator.free(the_realm);</span>
|
||||
<span class="line" id="L107"> }</span>
|
||||
<span class="line" id="L108"> }</span>
|
||||
<span class="line" id="L109"></span>
|
||||
<span class="line" id="L110"> <span class="tok-comment">/// Use this to decode the auth_header into user:pass, lookup pass in lookup.</span></span>
|
||||
<span class="line" id="L111"> <span class="tok-comment">/// Note: usually, you don't want to use this; you'd go for `authenticateRequest()`.</span></span>
|
||||
<span class="line" id="L112"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">authenticateUserPass</span>(self: *Self, auth_header: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>) AuthResult {</span>
|
||||
<span class="line" id="L113"> zap.debug(<span class="tok-str">"AuthenticateUserPass\n"</span>, .{});</span>
|
||||
<span class="line" id="L114"> <span class="tok-kw">const</span> encoded = auth_header[AuthScheme.Basic.str().len..];</span>
|
||||
<span class="line" id="L115"> <span class="tok-kw">const</span> decoder = std.base64.standard.Decoder;</span>
|
||||
<span class="line" id="L116"> <span class="tok-kw">var</span> buffer: [<span class="tok-number">0x100</span>]<span class="tok-type">u8</span> = <span class="tok-null">undefined</span>;</span>
|
||||
<span class="line" id="L117"> <span class="tok-kw">if</span> (decoder.calcSizeForSlice(encoded)) |decoded_size| {</span>
|
||||
<span class="line" id="L118"> <span class="tok-kw">if</span> (decoded_size >= buffer.len) {</span>
|
||||
<span class="line" id="L119"> zap.debug(</span>
|
||||
<span class="line" id="L120"> <span class="tok-str">"ERROR: UserPassAuth: decoded_size {d} >= buffer.len {d}\n"</span>,</span>
|
||||
<span class="line" id="L121"> .{ decoded_size, buffer.len },</span>
|
||||
<span class="line" id="L122"> );</span>
|
||||
<span class="line" id="L123"> <span class="tok-kw">return</span> .AuthFailed;</span>
|
||||
<span class="line" id="L124"> }</span>
|
||||
<span class="line" id="L125"> <span class="tok-kw">const</span> decoded = buffer[<span class="tok-number">0</span>..decoded_size];</span>
|
||||
<span class="line" id="L126"> decoder.decode(decoded, encoded) <span class="tok-kw">catch</span> |err| {</span>
|
||||
<span class="line" id="L127"> zap.debug(</span>
|
||||
<span class="line" id="L128"> <span class="tok-str">"ERROR: UserPassAuth: unable to decode `{s}`: {any}\n"</span>,</span>
|
||||
<span class="line" id="L129"> .{ encoded, err },</span>
|
||||
<span class="line" id="L130"> );</span>
|
||||
<span class="line" id="L131"> <span class="tok-kw">return</span> .AuthFailed;</span>
|
||||
<span class="line" id="L132"> };</span>
|
||||
<span class="line" id="L133"> <span class="tok-comment">// we have decoded</span>
|
||||
</span>
|
||||
<span class="line" id="L134"> <span class="tok-comment">// we can split</span>
|
||||
</span>
|
||||
<span class="line" id="L135"> <span class="tok-kw">var</span> it = std.mem.split(<span class="tok-type">u8</span>, decoded, <span class="tok-str">":"</span>);</span>
|
||||
<span class="line" id="L136"> <span class="tok-kw">const</span> user = it.next();</span>
|
||||
<span class="line" id="L137"> <span class="tok-kw">const</span> pass = it.next();</span>
|
||||
<span class="line" id="L138"> <span class="tok-kw">if</span> (user == <span class="tok-null">null</span> <span class="tok-kw">or</span> pass == <span class="tok-null">null</span>) {</span>
|
||||
<span class="line" id="L139"> zap.debug(</span>
|
||||
<span class="line" id="L140"> <span class="tok-str">"ERROR: UserPassAuth: user {any} or pass {any} is null\n"</span>,</span>
|
||||
<span class="line" id="L141"> .{ user, pass },</span>
|
||||
<span class="line" id="L142"> );</span>
|
||||
<span class="line" id="L143"> <span class="tok-kw">return</span> .AuthFailed;</span>
|
||||
<span class="line" id="L144"> }</span>
|
||||
<span class="line" id="L145"> <span class="tok-comment">// now, do the lookup</span>
|
||||
</span>
|
||||
<span class="line" id="L146"> <span class="tok-kw">const</span> actual_pw = self.lookup.*.get(user.?);</span>
|
||||
<span class="line" id="L147"> <span class="tok-kw">if</span> (actual_pw) |pw| {</span>
|
||||
<span class="line" id="L148"> <span class="tok-kw">const</span> ret = std.mem.eql(<span class="tok-type">u8</span>, pass.?, pw);</span>
|
||||
<span class="line" id="L149"> zap.debug(</span>
|
||||
<span class="line" id="L150"> <span class="tok-str">"INFO: UserPassAuth for user `{s}`: `{s}` == pass `{s}` = {}\n"</span>,</span>
|
||||
<span class="line" id="L151"> .{ user.?, pw, pass.?, ret },</span>
|
||||
<span class="line" id="L152"> );</span>
|
||||
<span class="line" id="L153"> <span class="tok-kw">return</span> <span class="tok-kw">if</span> (ret) .AuthOK <span class="tok-kw">else</span> .AuthFailed;</span>
|
||||
<span class="line" id="L154"> } <span class="tok-kw">else</span> {</span>
|
||||
<span class="line" id="L155"> zap.debug(</span>
|
||||
<span class="line" id="L156"> <span class="tok-str">"ERROR: UserPassAuth: user `{s}` not found in map of size {d}!\n"</span>,</span>
|
||||
<span class="line" id="L157"> .{ user.?, self.lookup.*.count() },</span>
|
||||
<span class="line" id="L158"> );</span>
|
||||
<span class="line" id="L159"> <span class="tok-kw">return</span> .AuthFailed;</span>
|
||||
<span class="line" id="L160"> }</span>
|
||||
<span class="line" id="L161"> } <span class="tok-kw">else</span> |err| {</span>
|
||||
<span class="line" id="L162"> <span class="tok-comment">// can't calc slice size --> fallthrough to return false</span>
|
||||
</span>
|
||||
<span class="line" id="L163"> zap.debug(</span>
|
||||
<span class="line" id="L164"> <span class="tok-str">"ERROR: UserPassAuth: cannot calc slize size for encoded `{s}`: {any} \n"</span>,</span>
|
||||
<span class="line" id="L165"> .{ encoded, err },</span>
|
||||
<span class="line" id="L166"> );</span>
|
||||
<span class="line" id="L167"> <span class="tok-kw">return</span> .AuthFailed;</span>
|
||||
<span class="line" id="L168"> }</span>
|
||||
<span class="line" id="L169"> zap.debug(<span class="tok-str">"UNREACHABLE\n"</span>, .{});</span>
|
||||
<span class="line" id="L170"> <span class="tok-kw">return</span> .AuthFailed;</span>
|
||||
<span class="line" id="L171"> }</span>
|
||||
<span class="line" id="L172"></span>
|
||||
<span class="line" id="L173"> <span class="tok-comment">/// Use this to just look up if the base64-encoded auth_header exists in lookup.</span></span>
|
||||
<span class="line" id="L174"> <span class="tok-comment">/// Note: usually, you don't want to use this; you'd go for `authenticateRequest()`.</span></span>
|
||||
<span class="line" id="L175"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">authenticateToken68</span>(self: *Self, auth_header: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>) AuthResult {</span>
|
||||
<span class="line" id="L176"> <span class="tok-kw">const</span> token = auth_header[AuthScheme.Basic.str().len..];</span>
|
||||
<span class="line" id="L177"> <span class="tok-kw">return</span> <span class="tok-kw">if</span> (self.lookup.*.contains(token)) .AuthOK <span class="tok-kw">else</span> .AuthFailed;</span>
|
||||
<span class="line" id="L178"> }</span>
|
||||
<span class="line" id="L179"></span>
|
||||
<span class="line" id="L180"> <span class="tok-comment">/// dispatch based on kind (.UserPass / .Token689) and try to authenticate based on the header.</span></span>
|
||||
<span class="line" id="L181"> <span class="tok-comment">/// Note: usually, you don't want to use this; you'd go for `authenticateRequest()`.</span></span>
|
||||
<span class="line" id="L182"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">authenticate</span>(self: *Self, auth_header: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>) AuthResult {</span>
|
||||
<span class="line" id="L183"> zap.debug(<span class="tok-str">"AUTHENTICATE\n"</span>, .{});</span>
|
||||
<span class="line" id="L184"> <span class="tok-kw">switch</span> (kind) {</span>
|
||||
<span class="line" id="L185"> .UserPass => <span class="tok-kw">return</span> self.authenticateUserPass(auth_header),</span>
|
||||
<span class="line" id="L186"> .Token68 => <span class="tok-kw">return</span> self.authenticateToken68(auth_header),</span>
|
||||
<span class="line" id="L187"> }</span>
|
||||
<span class="line" id="L188"> }</span>
|
||||
<span class="line" id="L189"></span>
|
||||
<span class="line" id="L190"> <span class="tok-comment">/// The zap authentication request handler.</span></span>
|
||||
<span class="line" id="L191"> <span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L192"> <span class="tok-comment">/// Tries to extract the authentication header and perform the authentication.</span></span>
|
||||
<span class="line" id="L193"> <span class="tok-comment">/// If no authentication header is found, an authorization header is tried.</span></span>
|
||||
<span class="line" id="L194"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">authenticateRequest</span>(self: *Self, r: *<span class="tok-kw">const</span> zap.Request) AuthResult {</span>
|
||||
<span class="line" id="L195"> zap.debug(<span class="tok-str">"AUTHENTICATE REQUEST\n"</span>, .{});</span>
|
||||
<span class="line" id="L196"> <span class="tok-kw">if</span> (extractAuthHeader(.Basic, r)) |auth_header| {</span>
|
||||
<span class="line" id="L197"> zap.debug(<span class="tok-str">"Authentication Header found!\n"</span>, .{});</span>
|
||||
<span class="line" id="L198"> <span class="tok-kw">return</span> self.authenticate(auth_header);</span>
|
||||
<span class="line" id="L199"> } <span class="tok-kw">else</span> {</span>
|
||||
<span class="line" id="L200"> <span class="tok-comment">// try with .Authorization</span>
|
||||
</span>
|
||||
<span class="line" id="L201"> <span class="tok-kw">if</span> (extractAuthHeader(.Bearer, r)) |auth_header| {</span>
|
||||
<span class="line" id="L202"> zap.debug(<span class="tok-str">"Authorization Header found!\n"</span>, .{});</span>
|
||||
<span class="line" id="L203"> <span class="tok-kw">return</span> self.authenticate(auth_header);</span>
|
||||
<span class="line" id="L204"> }</span>
|
||||
<span class="line" id="L205"> }</span>
|
||||
<span class="line" id="L206"> zap.debug(<span class="tok-str">"NO fitting Auth Header found!\n"</span>, .{});</span>
|
||||
<span class="line" id="L207"> <span class="tok-kw">return</span> .AuthFailed;</span>
|
||||
<span class="line" id="L208"> }</span>
|
||||
<span class="line" id="L209"> };</span>
|
||||
<span class="line" id="L210">}</span>
|
||||
<span class="line" id="L211"></span>
|
||||
<span class="line" id="L212"><span class="tok-comment">/// HTTP bearer authentication for a single token</span></span>
|
||||
<span class="line" id="L213"><span class="tok-comment">/// RFC 6750</span></span>
|
||||
<span class="line" id="L214"><span class="tok-comment">/// "Authentication: Bearer TOKEN"</span></span>
|
||||
<span class="line" id="L215"><span class="tok-comment">/// `Bearer` is case-sensitive</span></span>
|
||||
<span class="line" id="L216"><span class="tok-comment">/// - we don't support form-encoded `access_token` body parameter</span></span>
|
||||
<span class="line" id="L217"><span class="tok-comment">/// - we don't support URI query parameter `access_token`</span></span>
|
||||
<span class="line" id="L218"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L219"><span class="tok-comment">/// Errors:</span></span>
|
||||
<span class="line" id="L220"><span class="tok-comment">/// HTTP/1.1 401 Unauthorized</span></span>
|
||||
<span class="line" id="L221"><span class="tok-comment">/// WWW-Authenticate: Bearer realm="example", error="invalid_token", error_description="..."</span></span>
|
||||
<span class="line" id="L222"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> BearerSingle = <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L223"> allocator: std.mem.Allocator,</span>
|
||||
<span class="line" id="L224"> token: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L225"> realm: ?[]<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L226"></span>
|
||||
<span class="line" id="L227"> <span class="tok-kw">const</span> Self = <span class="tok-builtin">@This</span>();</span>
|
||||
<span class="line" id="L228"></span>
|
||||
<span class="line" id="L229"> <span class="tok-comment">/// Creates a Single-Token Bearer Authenticator.</span></span>
|
||||
<span class="line" id="L230"> <span class="tok-comment">/// Takes a copy of the token.</span></span>
|
||||
<span class="line" id="L231"> <span class="tok-comment">/// If realm is provided (not null), a copy is taken call deinit() to clean up.</span></span>
|
||||
<span class="line" id="L232"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">init</span>(allocator: std.mem.Allocator, token: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>, realm: ?[]<span class="tok-kw">const</span> <span class="tok-type">u8</span>) !Self {</span>
|
||||
<span class="line" id="L233"> <span class="tok-kw">return</span> .{</span>
|
||||
<span class="line" id="L234"> .allocator = allocator,</span>
|
||||
<span class="line" id="L235"> .token = <span class="tok-kw">try</span> allocator.dupe(<span class="tok-type">u8</span>, token),</span>
|
||||
<span class="line" id="L236"> .realm = <span class="tok-kw">if</span> (realm) |the_realm| <span class="tok-kw">try</span> allocator.dupe(<span class="tok-type">u8</span>, the_realm) <span class="tok-kw">else</span> <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L237"> };</span>
|
||||
<span class="line" id="L238"> }</span>
|
||||
<span class="line" id="L239"></span>
|
||||
<span class="line" id="L240"> <span class="tok-comment">/// Try to authenticate based on the header.</span></span>
|
||||
<span class="line" id="L241"> <span class="tok-comment">/// Note: usually, you don't want to use this; you'd go for `authenticateRequest()`.</span></span>
|
||||
<span class="line" id="L242"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">authenticate</span>(self: *Self, auth_header: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>) AuthResult {</span>
|
||||
<span class="line" id="L243"> <span class="tok-kw">if</span> (checkAuthHeader(.Bearer, auth_header) == <span class="tok-null">false</span>) {</span>
|
||||
<span class="line" id="L244"> <span class="tok-kw">return</span> .AuthFailed;</span>
|
||||
<span class="line" id="L245"> }</span>
|
||||
<span class="line" id="L246"> <span class="tok-kw">const</span> token = auth_header[AuthScheme.Bearer.str().len..];</span>
|
||||
<span class="line" id="L247"> <span class="tok-kw">return</span> <span class="tok-kw">if</span> (std.mem.eql(<span class="tok-type">u8</span>, token, self.token)) .AuthOK <span class="tok-kw">else</span> .AuthFailed;</span>
|
||||
<span class="line" id="L248"> }</span>
|
||||
<span class="line" id="L249"></span>
|
||||
<span class="line" id="L250"> <span class="tok-comment">/// The zap authentication request handler.</span></span>
|
||||
<span class="line" id="L251"> <span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L252"> <span class="tok-comment">/// Tries to extract the authentication header and perform the authentication.</span></span>
|
||||
<span class="line" id="L253"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">authenticateRequest</span>(self: *Self, r: *<span class="tok-kw">const</span> zap.Request) AuthResult {</span>
|
||||
<span class="line" id="L254"> <span class="tok-kw">if</span> (extractAuthHeader(.Bearer, r)) |auth_header| {</span>
|
||||
<span class="line" id="L255"> <span class="tok-kw">return</span> self.authenticate(auth_header);</span>
|
||||
<span class="line" id="L256"> }</span>
|
||||
<span class="line" id="L257"> <span class="tok-kw">return</span> .AuthFailed;</span>
|
||||
<span class="line" id="L258"> }</span>
|
||||
<span class="line" id="L259"></span>
|
||||
<span class="line" id="L260"> <span class="tok-comment">/// Deinits the authenticator.</span></span>
|
||||
<span class="line" id="L261"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">deinit</span>(self: *Self) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L262"> <span class="tok-kw">if</span> (self.realm) |the_realm| {</span>
|
||||
<span class="line" id="L263"> self.allocator.free(the_realm);</span>
|
||||
<span class="line" id="L264"> }</span>
|
||||
<span class="line" id="L265"> self.allocator.free(self.token);</span>
|
||||
<span class="line" id="L266"> }</span>
|
||||
<span class="line" id="L267">};</span>
|
||||
<span class="line" id="L268"></span>
|
||||
<span class="line" id="L269"><span class="tok-comment">/// HTTP bearer authentication for multiple tokens</span></span>
|
||||
<span class="line" id="L270"><span class="tok-comment">/// RFC 6750</span></span>
|
||||
<span class="line" id="L271"><span class="tok-comment">/// "Authentication: Bearer TOKEN"</span></span>
|
||||
<span class="line" id="L272"><span class="tok-comment">/// `Bearer` is case-sensitive</span></span>
|
||||
<span class="line" id="L273"><span class="tok-comment">/// - we don't support form-encoded `access_token` body parameter</span></span>
|
||||
<span class="line" id="L274"><span class="tok-comment">/// - we don't support URI query parameter `access_token`</span></span>
|
||||
<span class="line" id="L275"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L276"><span class="tok-comment">/// Errors:</span></span>
|
||||
<span class="line" id="L277"><span class="tok-comment">/// HTTP/1.1 401 Unauthorized</span></span>
|
||||
<span class="line" id="L278"><span class="tok-comment">/// WWW-Authenticate: Bearer realm="example", error="invalid_token", error_description="..."</span></span>
|
||||
<span class="line" id="L279"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">BearerMulti</span>(<span class="tok-kw">comptime</span> Lookup: <span class="tok-type">type</span>) <span class="tok-type">type</span> {</span>
|
||||
<span class="line" id="L280"> <span class="tok-kw">return</span> <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L281"> allocator: std.mem.Allocator,</span>
|
||||
<span class="line" id="L282"> lookup: *Lookup,</span>
|
||||
<span class="line" id="L283"> realm: ?[]<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L284"></span>
|
||||
<span class="line" id="L285"> <span class="tok-kw">const</span> Self = <span class="tok-builtin">@This</span>();</span>
|
||||
<span class="line" id="L286"></span>
|
||||
<span class="line" id="L287"> <span class="tok-comment">/// Creates a Multi Token Bearer Authenticator. `lookup` must implement</span></span>
|
||||
<span class="line" id="L288"> <span class="tok-comment">/// `.get([]const u8) -> []const u8` to look up tokens.</span></span>
|
||||
<span class="line" id="L289"> <span class="tok-comment">/// If realm is provided (not null), a copy of it is taken -> call deinit() to clean up.</span></span>
|
||||
<span class="line" id="L290"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">init</span>(allocator: std.mem.Allocator, lookup: *Lookup, realm: ?[]<span class="tok-kw">const</span> <span class="tok-type">u8</span>) !Self {</span>
|
||||
<span class="line" id="L291"> <span class="tok-kw">return</span> .{</span>
|
||||
<span class="line" id="L292"> .allocator = allocator,</span>
|
||||
<span class="line" id="L293"> .lookup = lookup,</span>
|
||||
<span class="line" id="L294"> .realm = <span class="tok-kw">if</span> (realm) |the_realm| <span class="tok-kw">try</span> allocator.dupe(<span class="tok-type">u8</span>, the_realm) <span class="tok-kw">else</span> <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L295"> };</span>
|
||||
<span class="line" id="L296"> }</span>
|
||||
<span class="line" id="L297"></span>
|
||||
<span class="line" id="L298"> <span class="tok-comment">/// Deinit the authenticator. Only required if a realm was provided at</span></span>
|
||||
<span class="line" id="L299"> <span class="tok-comment">/// init() time.</span></span>
|
||||
<span class="line" id="L300"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">deinit</span>(self: *Self) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L301"> <span class="tok-kw">if</span> (self.realm) |the_realm| {</span>
|
||||
<span class="line" id="L302"> self.allocator.free(the_realm);</span>
|
||||
<span class="line" id="L303"> }</span>
|
||||
<span class="line" id="L304"> }</span>
|
||||
<span class="line" id="L305"></span>
|
||||
<span class="line" id="L306"> <span class="tok-comment">/// Try to authenticate based on the header.</span></span>
|
||||
<span class="line" id="L307"> <span class="tok-comment">/// Note: usually, you don't want to use this; you'd go for `authenticateRequest()`.</span></span>
|
||||
<span class="line" id="L308"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">authenticate</span>(self: *Self, auth_header: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>) AuthResult {</span>
|
||||
<span class="line" id="L309"> <span class="tok-kw">if</span> (checkAuthHeader(.Bearer, auth_header) == <span class="tok-null">false</span>) {</span>
|
||||
<span class="line" id="L310"> <span class="tok-kw">return</span> .AuthFailed;</span>
|
||||
<span class="line" id="L311"> }</span>
|
||||
<span class="line" id="L312"> <span class="tok-kw">const</span> token = auth_header[AuthScheme.Bearer.str().len..];</span>
|
||||
<span class="line" id="L313"> <span class="tok-kw">return</span> <span class="tok-kw">if</span> (self.lookup.*.contains(token)) .AuthOK <span class="tok-kw">else</span> .AuthFailed;</span>
|
||||
<span class="line" id="L314"> }</span>
|
||||
<span class="line" id="L315"></span>
|
||||
<span class="line" id="L316"> <span class="tok-comment">/// The zap authentication request handler.</span></span>
|
||||
<span class="line" id="L317"> <span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L318"> <span class="tok-comment">/// Tries to extract the authentication header and perform the authentication.</span></span>
|
||||
<span class="line" id="L319"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">authenticateRequest</span>(self: *Self, r: *<span class="tok-kw">const</span> zap.Request) AuthResult {</span>
|
||||
<span class="line" id="L320"> <span class="tok-kw">if</span> (extractAuthHeader(.Bearer, r)) |auth_header| {</span>
|
||||
<span class="line" id="L321"> <span class="tok-kw">return</span> self.authenticate(auth_header);</span>
|
||||
<span class="line" id="L322"> }</span>
|
||||
<span class="line" id="L323"> <span class="tok-kw">return</span> .AuthFailed;</span>
|
||||
<span class="line" id="L324"> }</span>
|
||||
<span class="line" id="L325"> };</span>
|
||||
<span class="line" id="L326">}</span>
|
||||
<span class="line" id="L327"></span>
|
||||
<span class="line" id="L328"><span class="tok-comment">/// Settings to initialize a UserPassSession authenticator.</span></span>
|
||||
<span class="line" id="L329"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> UserPassSessionArgs = <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L330"> <span class="tok-comment">/// username body parameter</span></span>
|
||||
<span class="line" id="L331"> usernameParam: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L332"> <span class="tok-comment">/// password body parameter</span></span>
|
||||
<span class="line" id="L333"> passwordParam: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L334"> <span class="tok-comment">/// redirect to this page if auth fails</span></span>
|
||||
<span class="line" id="L335"> loginPage: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L336"> <span class="tok-comment">/// name of the auth cookie</span></span>
|
||||
<span class="line" id="L337"> cookieName: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L338"> <span class="tok-comment">/// cookie max age in seconds; 0 -> session cookie</span></span>
|
||||
<span class="line" id="L339"> cookieMaxAge: <span class="tok-type">u8</span> = <span class="tok-number">0</span>,</span>
|
||||
<span class="line" id="L340"> <span class="tok-comment">/// redirect status code, defaults to 302 found</span></span>
|
||||
<span class="line" id="L341"> redirectCode: zap.StatusCode = .found,</span>
|
||||
<span class="line" id="L342">};</span>
|
||||
<span class="line" id="L343"></span>
|
||||
<span class="line" id="L344"><span class="tok-comment">/// UserPassSession supports the following use case:</span></span>
|
||||
<span class="line" id="L345"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L346"><span class="tok-comment">/// - checks every request: is it going to the login page? -> let the request through.</span></span>
|
||||
<span class="line" id="L347"><span class="tok-comment">/// - else:</span></span>
|
||||
<span class="line" id="L348"><span class="tok-comment">/// - checks every request for a session token in a cookie</span></span>
|
||||
<span class="line" id="L349"><span class="tok-comment">/// - if there is no token, it checks for correct username and password body params</span></span>
|
||||
<span class="line" id="L350"><span class="tok-comment">/// - if username and password are present and correct, it will create a session token,</span></span>
|
||||
<span class="line" id="L351"><span class="tok-comment">/// create a response cookie containing the token, and carry on with the request</span></span>
|
||||
<span class="line" id="L352"><span class="tok-comment">/// - else it will redirect to the login page</span></span>
|
||||
<span class="line" id="L353"><span class="tok-comment">/// - if the session token is present and correct: it will let the request through</span></span>
|
||||
<span class="line" id="L354"><span class="tok-comment">/// - else: it will redirect to the login page</span></span>
|
||||
<span class="line" id="L355"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L356"><span class="tok-comment">/// Please note the implications of this simple approach: IF YOU REUSE "username"</span></span>
|
||||
<span class="line" id="L357"><span class="tok-comment">/// and "password" body params for anything else in your application, then the</span></span>
|
||||
<span class="line" id="L358"><span class="tok-comment">/// mechanisms described above will still kick in. For that reason: please know what</span></span>
|
||||
<span class="line" id="L359"><span class="tok-comment">/// you're doing.</span></span>
|
||||
<span class="line" id="L360"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L361"><span class="tok-comment">/// See UserPassSessionArgs:</span></span>
|
||||
<span class="line" id="L362"><span class="tok-comment">/// - username & password param names can be defined by you</span></span>
|
||||
<span class="line" id="L363"><span class="tok-comment">/// - session cookie name and max-age can be defined by you</span></span>
|
||||
<span class="line" id="L364"><span class="tok-comment">/// - login page and redirect code (.302) can be defined by you</span></span>
|
||||
<span class="line" id="L365"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L366"><span class="tok-comment">/// Comptime Parameters:</span></span>
|
||||
<span class="line" id="L367"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L368"><span class="tok-comment">/// - `Lookup` must implement .get([]const u8) -> []const u8 for user password retrieval</span></span>
|
||||
<span class="line" id="L369"><span class="tok-comment">/// - `lockedPwLookups` : if true, accessing the provided Lookup instance will be protected</span></span>
|
||||
<span class="line" id="L370"><span class="tok-comment">/// by a Mutex. You can access the mutex yourself via the `passwordLookupLock`.</span></span>
|
||||
<span class="line" id="L371"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L372"><span class="tok-comment">/// Note: In order to be quick, you can set lockedTokenLookups to false.</span></span>
|
||||
<span class="line" id="L373"><span class="tok-comment">/// -> we generate it on init() and leave it static</span></span>
|
||||
<span class="line" id="L374"><span class="tok-comment">/// -> there is no way to 100% log out apart from re-starting the server</span></span>
|
||||
<span class="line" id="L375"><span class="tok-comment">/// -> because: we send a cookie to the browser that invalidates the session cookie</span></span>
|
||||
<span class="line" id="L376"><span class="tok-comment">/// -> another browser program with the page still open would still be able to use</span></span>
|
||||
<span class="line" id="L377"><span class="tok-comment">/// -> the session. Which is kindof OK, but not as cool as erasing the token</span></span>
|
||||
<span class="line" id="L378"><span class="tok-comment">/// -> on the server side which immediately block all other browsers as well.</span></span>
|
||||
<span class="line" id="L379"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">UserPassSession</span>(<span class="tok-kw">comptime</span> Lookup: <span class="tok-type">type</span>, <span class="tok-kw">comptime</span> lockedPwLookups: <span class="tok-type">bool</span>) <span class="tok-type">type</span> {</span>
|
||||
<span class="line" id="L380"> <span class="tok-kw">return</span> <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L381"> allocator: std.mem.Allocator,</span>
|
||||
<span class="line" id="L382"> lookup: *Lookup,</span>
|
||||
<span class="line" id="L383"> settings: UserPassSessionArgs,</span>
|
||||
<span class="line" id="L384"></span>
|
||||
<span class="line" id="L385"> <span class="tok-comment">// TODO: cookie store per user?</span>
|
||||
</span>
|
||||
<span class="line" id="L386"> sessionTokens: SessionTokenMap,</span>
|
||||
<span class="line" id="L387"> passwordLookupLock: std.Thread.Mutex = .{},</span>
|
||||
<span class="line" id="L388"> tokenLookupLock: std.Thread.Mutex = .{},</span>
|
||||
<span class="line" id="L389"></span>
|
||||
<span class="line" id="L390"> <span class="tok-kw">const</span> Self = <span class="tok-builtin">@This</span>();</span>
|
||||
<span class="line" id="L391"> <span class="tok-kw">const</span> SessionTokenMap = std.StringHashMap(<span class="tok-type">void</span>);</span>
|
||||
<span class="line" id="L392"> <span class="tok-kw">const</span> Hash = std.crypto.hash.sha2.Sha256;</span>
|
||||
<span class="line" id="L393"></span>
|
||||
<span class="line" id="L394"> <span class="tok-kw">const</span> Token = [Hash.digest_length * <span class="tok-number">2</span>]<span class="tok-type">u8</span>;</span>
|
||||
<span class="line" id="L395"></span>
|
||||
<span class="line" id="L396"> <span class="tok-comment">/// Construct this authenticator. See above and related types for more</span></span>
|
||||
<span class="line" id="L397"> <span class="tok-comment">/// information.</span></span>
|
||||
<span class="line" id="L398"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">init</span>(</span>
|
||||
<span class="line" id="L399"> allocator: std.mem.Allocator,</span>
|
||||
<span class="line" id="L400"> lookup: *Lookup,</span>
|
||||
<span class="line" id="L401"> args: UserPassSessionArgs,</span>
|
||||
<span class="line" id="L402"> ) !Self {</span>
|
||||
<span class="line" id="L403"> <span class="tok-kw">const</span> ret: Self = .{</span>
|
||||
<span class="line" id="L404"> .allocator = allocator,</span>
|
||||
<span class="line" id="L405"> .settings = .{</span>
|
||||
<span class="line" id="L406"> .usernameParam = <span class="tok-kw">try</span> allocator.dupe(<span class="tok-type">u8</span>, args.usernameParam),</span>
|
||||
<span class="line" id="L407"> .passwordParam = <span class="tok-kw">try</span> allocator.dupe(<span class="tok-type">u8</span>, args.passwordParam),</span>
|
||||
<span class="line" id="L408"> .loginPage = <span class="tok-kw">try</span> allocator.dupe(<span class="tok-type">u8</span>, args.loginPage),</span>
|
||||
<span class="line" id="L409"> .cookieName = <span class="tok-kw">try</span> allocator.dupe(<span class="tok-type">u8</span>, args.cookieName),</span>
|
||||
<span class="line" id="L410"> .cookieMaxAge = args.cookieMaxAge,</span>
|
||||
<span class="line" id="L411"> .redirectCode = args.redirectCode,</span>
|
||||
<span class="line" id="L412"> },</span>
|
||||
<span class="line" id="L413"> .lookup = lookup,</span>
|
||||
<span class="line" id="L414"> .sessionTokens = SessionTokenMap.init(allocator),</span>
|
||||
<span class="line" id="L415"> };</span>
|
||||
<span class="line" id="L416"></span>
|
||||
<span class="line" id="L417"> <span class="tok-kw">return</span> ret;</span>
|
||||
<span class="line" id="L418"> }</span>
|
||||
<span class="line" id="L419"></span>
|
||||
<span class="line" id="L420"> <span class="tok-comment">/// De-init this authenticator.</span></span>
|
||||
<span class="line" id="L421"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">deinit</span>(self: *Self) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L422"> self.allocator.free(self.settings.usernameParam);</span>
|
||||
<span class="line" id="L423"> self.allocator.free(self.settings.passwordParam);</span>
|
||||
<span class="line" id="L424"> self.allocator.free(self.settings.loginPage);</span>
|
||||
<span class="line" id="L425"> self.allocator.free(self.settings.cookieName);</span>
|
||||
<span class="line" id="L426"></span>
|
||||
<span class="line" id="L427"> <span class="tok-comment">// clean up the session tokens: the key strings are duped</span>
|
||||
</span>
|
||||
<span class="line" id="L428"> <span class="tok-kw">var</span> key_it = self.sessionTokens.keyIterator();</span>
|
||||
<span class="line" id="L429"> <span class="tok-kw">while</span> (key_it.next()) |key_ptr| {</span>
|
||||
<span class="line" id="L430"> self.allocator.free(key_ptr.*);</span>
|
||||
<span class="line" id="L431"> }</span>
|
||||
<span class="line" id="L432"> self.sessionTokens.deinit();</span>
|
||||
<span class="line" id="L433"> }</span>
|
||||
<span class="line" id="L434"></span>
|
||||
<span class="line" id="L435"> <span class="tok-comment">/// Check for session token cookie, remove the token from the valid tokens</span></span>
|
||||
<span class="line" id="L436"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">logout</span>(self: *Self, r: *<span class="tok-kw">const</span> zap.Request) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L437"> <span class="tok-comment">// we erase the list of valid tokens server-side (later) and set the</span>
|
||||
</span>
|
||||
<span class="line" id="L438"> <span class="tok-comment">// cookie to "invalid" on the client side.</span>
|
||||
</span>
|
||||
<span class="line" id="L439"> <span class="tok-kw">if</span> (r.setCookie(.{</span>
|
||||
<span class="line" id="L440"> .name = self.settings.cookieName,</span>
|
||||
<span class="line" id="L441"> .value = <span class="tok-str">"invalid"</span>,</span>
|
||||
<span class="line" id="L442"> .max_age_s = -<span class="tok-number">1</span>,</span>
|
||||
<span class="line" id="L443"> })) {</span>
|
||||
<span class="line" id="L444"> zap.debug(<span class="tok-str">"logout ok\n"</span>, .{});</span>
|
||||
<span class="line" id="L445"> } <span class="tok-kw">else</span> |err| {</span>
|
||||
<span class="line" id="L446"> zap.debug(<span class="tok-str">"logout cookie setting failed: {any}\n"</span>, .{err});</span>
|
||||
<span class="line" id="L447"> }</span>
|
||||
<span class="line" id="L448"></span>
|
||||
<span class="line" id="L449"> r.parseCookies(<span class="tok-null">false</span>);</span>
|
||||
<span class="line" id="L450"></span>
|
||||
<span class="line" id="L451"> <span class="tok-comment">// check for session cookie</span>
|
||||
</span>
|
||||
<span class="line" id="L452"> <span class="tok-kw">if</span> (r.getCookieStr(self.allocator, self.settings.cookieName, <span class="tok-null">false</span>)) |maybe_cookie| {</span>
|
||||
<span class="line" id="L453"> <span class="tok-kw">if</span> (maybe_cookie) |cookie| {</span>
|
||||
<span class="line" id="L454"> <span class="tok-kw">defer</span> cookie.deinit();</span>
|
||||
<span class="line" id="L455"> self.tokenLookupLock.lock();</span>
|
||||
<span class="line" id="L456"> <span class="tok-kw">defer</span> self.tokenLookupLock.unlock();</span>
|
||||
<span class="line" id="L457"> <span class="tok-kw">if</span> (self.sessionTokens.getKeyPtr(cookie.str)) |keyPtr| {</span>
|
||||
<span class="line" id="L458"> <span class="tok-kw">const</span> keySlice = keyPtr.*;</span>
|
||||
<span class="line" id="L459"> <span class="tok-comment">// if cookie is a valid session, remove it!</span>
|
||||
</span>
|
||||
<span class="line" id="L460"> _ = self.sessionTokens.remove(cookie.str);</span>
|
||||
<span class="line" id="L461"> <span class="tok-comment">// only now can we let go of the cookie str slice that</span>
|
||||
</span>
|
||||
<span class="line" id="L462"> <span class="tok-comment">// was used as the key</span>
|
||||
</span>
|
||||
<span class="line" id="L463"> self.allocator.free(keySlice);</span>
|
||||
<span class="line" id="L464"> }</span>
|
||||
<span class="line" id="L465"> }</span>
|
||||
<span class="line" id="L466"> } <span class="tok-kw">else</span> |err| {</span>
|
||||
<span class="line" id="L467"> zap.debug(<span class="tok-str">"unreachable: UserPassSession.logout: {any}"</span>, .{err});</span>
|
||||
<span class="line" id="L468"> }</span>
|
||||
<span class="line" id="L469"> }</span>
|
||||
<span class="line" id="L470"></span>
|
||||
<span class="line" id="L471"> <span class="tok-kw">fn</span> <span class="tok-fn">_internal_authenticateRequest</span>(self: *Self, r: *<span class="tok-kw">const</span> zap.Request) AuthResult {</span>
|
||||
<span class="line" id="L472"> <span class="tok-comment">// if we're requesting the login page, let the request through</span>
|
||||
</span>
|
||||
<span class="line" id="L473"> <span class="tok-kw">if</span> (r.path) |p| {</span>
|
||||
<span class="line" id="L474"> <span class="tok-kw">if</span> (std.mem.startsWith(<span class="tok-type">u8</span>, p, self.settings.loginPage)) {</span>
|
||||
<span class="line" id="L475"> <span class="tok-kw">return</span> .AuthOK;</span>
|
||||
<span class="line" id="L476"> }</span>
|
||||
<span class="line" id="L477"> }</span>
|
||||
<span class="line" id="L478"></span>
|
||||
<span class="line" id="L479"> <span class="tok-comment">// parse body</span>
|
||||
</span>
|
||||
<span class="line" id="L480"> r.parseBody() <span class="tok-kw">catch</span> {</span>
|
||||
<span class="line" id="L481"> <span class="tok-comment">// zap.debug("warning: parseBody() failed in UserPassSession: {any}", .{err});</span>
|
||||
</span>
|
||||
<span class="line" id="L482"> <span class="tok-comment">// this is not an error in case of e.g. gets with querystrings</span>
|
||||
</span>
|
||||
<span class="line" id="L483"> };</span>
|
||||
<span class="line" id="L484"></span>
|
||||
<span class="line" id="L485"> r.parseCookies(<span class="tok-null">false</span>);</span>
|
||||
<span class="line" id="L486"></span>
|
||||
<span class="line" id="L487"> <span class="tok-comment">// check for session cookie</span>
|
||||
</span>
|
||||
<span class="line" id="L488"> <span class="tok-kw">if</span> (r.getCookieStr(self.allocator, self.settings.cookieName, <span class="tok-null">false</span>)) |maybe_cookie| {</span>
|
||||
<span class="line" id="L489"> <span class="tok-kw">if</span> (maybe_cookie) |cookie| {</span>
|
||||
<span class="line" id="L490"> <span class="tok-kw">defer</span> cookie.deinit();</span>
|
||||
<span class="line" id="L491"> <span class="tok-comment">// locked or unlocked token lookup</span>
|
||||
</span>
|
||||
<span class="line" id="L492"> self.tokenLookupLock.lock();</span>
|
||||
<span class="line" id="L493"> <span class="tok-kw">defer</span> self.tokenLookupLock.unlock();</span>
|
||||
<span class="line" id="L494"> <span class="tok-kw">if</span> (self.sessionTokens.contains(cookie.str)) {</span>
|
||||
<span class="line" id="L495"> <span class="tok-comment">// cookie is a valid session!</span>
|
||||
</span>
|
||||
<span class="line" id="L496"> zap.debug(<span class="tok-str">"Auth: COOKIE IS OK!!!!: {s}\n"</span>, .{cookie.str});</span>
|
||||
<span class="line" id="L497"> <span class="tok-kw">return</span> .AuthOK;</span>
|
||||
<span class="line" id="L498"> } <span class="tok-kw">else</span> {</span>
|
||||
<span class="line" id="L499"> zap.debug(<span class="tok-str">"Auth: COOKIE IS BAD!!!!: {s}\n"</span>, .{cookie.str});</span>
|
||||
<span class="line" id="L500"> <span class="tok-comment">// this is not necessarily a bad thing. it could be a</span>
|
||||
</span>
|
||||
<span class="line" id="L501"> <span class="tok-comment">// stale cookie from a previous session. So let's check</span>
|
||||
</span>
|
||||
<span class="line" id="L502"> <span class="tok-comment">// if username and password are being sent and correct.</span>
|
||||
</span>
|
||||
<span class="line" id="L503"> }</span>
|
||||
<span class="line" id="L504"> }</span>
|
||||
<span class="line" id="L505"> } <span class="tok-kw">else</span> |err| {</span>
|
||||
<span class="line" id="L506"> zap.debug(<span class="tok-str">"unreachable: could not check for cookie in UserPassSession: {any}"</span>, .{err});</span>
|
||||
<span class="line" id="L507"> }</span>
|
||||
<span class="line" id="L508"></span>
|
||||
<span class="line" id="L509"> <span class="tok-comment">// get params of username and password</span>
|
||||
</span>
|
||||
<span class="line" id="L510"> <span class="tok-kw">if</span> (r.getParamStr(self.allocator, self.settings.usernameParam, <span class="tok-null">false</span>)) |maybe_username| {</span>
|
||||
<span class="line" id="L511"> <span class="tok-kw">if</span> (maybe_username) |*username| {</span>
|
||||
<span class="line" id="L512"> <span class="tok-kw">defer</span> username.deinit();</span>
|
||||
<span class="line" id="L513"> <span class="tok-kw">if</span> (r.getParamStr(self.allocator, self.settings.passwordParam, <span class="tok-null">false</span>)) |maybe_pw| {</span>
|
||||
<span class="line" id="L514"> <span class="tok-kw">if</span> (maybe_pw) |*pw| {</span>
|
||||
<span class="line" id="L515"> <span class="tok-kw">defer</span> pw.deinit();</span>
|
||||
<span class="line" id="L516"></span>
|
||||
<span class="line" id="L517"> <span class="tok-comment">// now check</span>
|
||||
</span>
|
||||
<span class="line" id="L518"> <span class="tok-kw">const</span> correct_pw_optional = brk: {</span>
|
||||
<span class="line" id="L519"> <span class="tok-kw">if</span> (lockedPwLookups) {</span>
|
||||
<span class="line" id="L520"> self.passwordLookupLock.lock();</span>
|
||||
<span class="line" id="L521"> <span class="tok-kw">defer</span> self.passwordLookupLock.unlock();</span>
|
||||
<span class="line" id="L522"> <span class="tok-kw">break</span> :brk self.lookup.*.get(username.str);</span>
|
||||
<span class="line" id="L523"> } <span class="tok-kw">else</span> {</span>
|
||||
<span class="line" id="L524"> <span class="tok-kw">break</span> :brk self.lookup.*.get(username.str);</span>
|
||||
<span class="line" id="L525"> }</span>
|
||||
<span class="line" id="L526"> };</span>
|
||||
<span class="line" id="L527"> <span class="tok-kw">if</span> (correct_pw_optional) |correct_pw| {</span>
|
||||
<span class="line" id="L528"> <span class="tok-kw">if</span> (std.mem.eql(<span class="tok-type">u8</span>, pw.str, correct_pw)) {</span>
|
||||
<span class="line" id="L529"> <span class="tok-comment">// create session token</span>
|
||||
</span>
|
||||
<span class="line" id="L530"> <span class="tok-kw">if</span> (self.createAndStoreSessionToken(username.str, pw.str)) |token| {</span>
|
||||
<span class="line" id="L531"> <span class="tok-kw">defer</span> self.allocator.free(token);</span>
|
||||
<span class="line" id="L532"> <span class="tok-comment">// now set the cookie header</span>
|
||||
</span>
|
||||
<span class="line" id="L533"> <span class="tok-kw">if</span> (r.setCookie(.{</span>
|
||||
<span class="line" id="L534"> .name = self.settings.cookieName,</span>
|
||||
<span class="line" id="L535"> .value = token,</span>
|
||||
<span class="line" id="L536"> .max_age_s = self.settings.cookieMaxAge,</span>
|
||||
<span class="line" id="L537"> })) {</span>
|
||||
<span class="line" id="L538"> <span class="tok-kw">return</span> .AuthOK;</span>
|
||||
<span class="line" id="L539"> } <span class="tok-kw">else</span> |err| {</span>
|
||||
<span class="line" id="L540"> zap.debug(<span class="tok-str">"could not set session token: {any}"</span>, .{err});</span>
|
||||
<span class="line" id="L541"> }</span>
|
||||
<span class="line" id="L542"> } <span class="tok-kw">else</span> |err| {</span>
|
||||
<span class="line" id="L543"> zap.debug(<span class="tok-str">"could not create session token: {any}"</span>, .{err});</span>
|
||||
<span class="line" id="L544"> }</span>
|
||||
<span class="line" id="L545"> <span class="tok-comment">// errors with token don't mean the auth itself wasn't OK</span>
|
||||
</span>
|
||||
<span class="line" id="L546"> <span class="tok-kw">return</span> .AuthOK;</span>
|
||||
<span class="line" id="L547"> }</span>
|
||||
<span class="line" id="L548"> }</span>
|
||||
<span class="line" id="L549"> }</span>
|
||||
<span class="line" id="L550"> } <span class="tok-kw">else</span> |err| {</span>
|
||||
<span class="line" id="L551"> zap.debug(<span class="tok-str">"getParamSt() for password failed in UserPassSession: {any}"</span>, .{err});</span>
|
||||
<span class="line" id="L552"> <span class="tok-kw">return</span> .AuthFailed;</span>
|
||||
<span class="line" id="L553"> }</span>
|
||||
<span class="line" id="L554"> }</span>
|
||||
<span class="line" id="L555"> } <span class="tok-kw">else</span> |err| {</span>
|
||||
<span class="line" id="L556"> zap.debug(<span class="tok-str">"getParamSt() for user failed in UserPassSession: {any}"</span>, .{err});</span>
|
||||
<span class="line" id="L557"> <span class="tok-kw">return</span> .AuthFailed;</span>
|
||||
<span class="line" id="L558"> }</span>
|
||||
<span class="line" id="L559"> <span class="tok-kw">return</span> .AuthFailed;</span>
|
||||
<span class="line" id="L560"> }</span>
|
||||
<span class="line" id="L561"></span>
|
||||
<span class="line" id="L562"> <span class="tok-comment">/// The zap authentication request handler.</span></span>
|
||||
<span class="line" id="L563"> <span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L564"> <span class="tok-comment">/// See above for how it works.</span></span>
|
||||
<span class="line" id="L565"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">authenticateRequest</span>(self: *Self, r: *<span class="tok-kw">const</span> zap.Request) AuthResult {</span>
|
||||
<span class="line" id="L566"> <span class="tok-kw">switch</span> (self._internal_authenticateRequest(r)) {</span>
|
||||
<span class="line" id="L567"> .AuthOK => {</span>
|
||||
<span class="line" id="L568"> <span class="tok-comment">// username and pass are ok -> created token, set header, caller can continue</span>
|
||||
</span>
|
||||
<span class="line" id="L569"> <span class="tok-kw">return</span> .AuthOK;</span>
|
||||
<span class="line" id="L570"> },</span>
|
||||
<span class="line" id="L571"> <span class="tok-comment">// this does not happen, just for completeness</span>
|
||||
</span>
|
||||
<span class="line" id="L572"> .Handled => <span class="tok-kw">return</span> .Handled,</span>
|
||||
<span class="line" id="L573"> <span class="tok-comment">// auth failed -> redirect</span>
|
||||
</span>
|
||||
<span class="line" id="L574"> .AuthFailed => {</span>
|
||||
<span class="line" id="L575"> <span class="tok-comment">// we need to redirect and return .Handled</span>
|
||||
</span>
|
||||
<span class="line" id="L576"> self.redirect(r) <span class="tok-kw">catch</span> |err| {</span>
|
||||
<span class="line" id="L577"> <span class="tok-comment">// we just give up</span>
|
||||
</span>
|
||||
<span class="line" id="L578"> zap.debug(<span class="tok-str">"redirect() failed in UserPassSession: {any}"</span>, .{err});</span>
|
||||
<span class="line" id="L579"> };</span>
|
||||
<span class="line" id="L580"> <span class="tok-kw">return</span> .Handled;</span>
|
||||
<span class="line" id="L581"> },</span>
|
||||
<span class="line" id="L582"> }</span>
|
||||
<span class="line" id="L583"> }</span>
|
||||
<span class="line" id="L584"></span>
|
||||
<span class="line" id="L585"> <span class="tok-kw">fn</span> <span class="tok-fn">redirect</span>(self: *Self, r: *<span class="tok-kw">const</span> zap.Request) !<span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L586"> <span class="tok-kw">try</span> r.redirectTo(self.settings.loginPage, self.settings.redirectCode);</span>
|
||||
<span class="line" id="L587"> }</span>
|
||||
<span class="line" id="L588"></span>
|
||||
<span class="line" id="L589"> <span class="tok-kw">fn</span> <span class="tok-fn">createSessionToken</span>(self: *Self, username: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>, password: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>) ![]<span class="tok-kw">const</span> <span class="tok-type">u8</span> {</span>
|
||||
<span class="line" id="L590"> <span class="tok-kw">var</span> hasher = Hash.init(.{});</span>
|
||||
<span class="line" id="L591"> hasher.update(username);</span>
|
||||
<span class="line" id="L592"> hasher.update(password);</span>
|
||||
<span class="line" id="L593"> <span class="tok-kw">var</span> buf: [<span class="tok-number">16</span>]<span class="tok-type">u8</span> = <span class="tok-null">undefined</span>;</span>
|
||||
<span class="line" id="L594"> <span class="tok-kw">const</span> time_nano = std.time.nanoTimestamp();</span>
|
||||
<span class="line" id="L595"> <span class="tok-kw">const</span> timestampHex = <span class="tok-kw">try</span> std.fmt.bufPrint(&buf, <span class="tok-str">"{0x}"</span>, .{time_nano});</span>
|
||||
<span class="line" id="L596"> hasher.update(timestampHex);</span>
|
||||
<span class="line" id="L597"></span>
|
||||
<span class="line" id="L598"> <span class="tok-kw">var</span> digest: [Hash.digest_length]<span class="tok-type">u8</span> = <span class="tok-null">undefined</span>;</span>
|
||||
<span class="line" id="L599"> hasher.final(&digest);</span>
|
||||
<span class="line" id="L600"> <span class="tok-kw">const</span> token: Token = std.fmt.bytesToHex(digest, .lower);</span>
|
||||
<span class="line" id="L601"> <span class="tok-kw">const</span> token_str = <span class="tok-kw">try</span> self.allocator.dupe(<span class="tok-type">u8</span>, token[<span class="tok-number">0</span>..token.len]);</span>
|
||||
<span class="line" id="L602"> <span class="tok-kw">return</span> token_str;</span>
|
||||
<span class="line" id="L603"> }</span>
|
||||
<span class="line" id="L604"></span>
|
||||
<span class="line" id="L605"> <span class="tok-kw">fn</span> <span class="tok-fn">createAndStoreSessionToken</span>(self: *Self, username: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>, password: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>) ![]<span class="tok-kw">const</span> <span class="tok-type">u8</span> {</span>
|
||||
<span class="line" id="L606"> <span class="tok-kw">const</span> token = <span class="tok-kw">try</span> self.createSessionToken(username, password);</span>
|
||||
<span class="line" id="L607"> self.tokenLookupLock.lock();</span>
|
||||
<span class="line" id="L608"> <span class="tok-kw">defer</span> self.tokenLookupLock.unlock();</span>
|
||||
<span class="line" id="L609"></span>
|
||||
<span class="line" id="L610"> <span class="tok-kw">if</span> (!self.sessionTokens.contains(token)) {</span>
|
||||
<span class="line" id="L611"> <span class="tok-kw">try</span> self.sessionTokens.put(<span class="tok-kw">try</span> self.allocator.dupe(<span class="tok-type">u8</span>, token), {});</span>
|
||||
<span class="line" id="L612"> }</span>
|
||||
<span class="line" id="L613"> <span class="tok-kw">return</span> token;</span>
|
||||
<span class="line" id="L614"> }</span>
|
||||
<span class="line" id="L615"> };</span>
|
||||
<span class="line" id="L616">}</span>
|
||||
<span class="line" id="L617"></span>
|
||||
</code></pre></body>
|
||||
</html>
|
|
@ -1,172 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>log.zig - source view</title>
|
||||
<link rel="icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAgklEQVR4AWMYWuD7EllJIM4G4g4g5oIJ/odhOJ8wToOxSTXgNxDHoeiBMfA4+wGShjyYOCkG/IGqWQziEzYAoUAeiF9D5U+DxEg14DRU7jWIT5IBIOdCxf+A+CQZAAoopEB7QJwBCBwHiip8UYmRdrAlDpIMgApwQZNnNii5Dq0MBgCxxycBnwEd+wAAAABJRU5ErkJggg==">
|
||||
<link rel="icon" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNTMgMTQwIj48ZyBmaWxsPSIjRjdBNDFEIj48Zz48cG9seWdvbiBwb2ludHM9IjQ2LDIyIDI4LDQ0IDE5LDMwIi8+PHBvbHlnb24gcG9pbnRzPSI0NiwyMiAzMywzMyAyOCw0NCAyMiw0NCAyMiw5NSAzMSw5NSAyMCwxMDAgMTIsMTE3IDAsMTE3IDAsMjIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMzEsOTUgMTIsMTE3IDQsMTA2Ii8+PC9nPjxnPjxwb2x5Z29uIHBvaW50cz0iNTYsMjIgNjIsMzYgMzcsNDQiLz48cG9seWdvbiBwb2ludHM9IjU2LDIyIDExMSwyMiAxMTEsNDQgMzcsNDQgNTYsMzIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTE2LDk1IDk3LDExNyA5MCwxMDQiLz48cG9seWdvbiBwb2ludHM9IjExNiw5NSAxMDAsMTA0IDk3LDExNyA0MiwxMTcgNDIsOTUiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTUwLDAgNTIsMTE3IDMsMTQwIDEwMSwyMiIvPjwvZz48Zz48cG9seWdvbiBwb2ludHM9IjE0MSwyMiAxNDAsNDAgMTIyLDQ1Ii8+PHBvbHlnb24gcG9pbnRzPSIxNTMsMjIgMTUzLDExNyAxMDYsMTE3IDEyMCwxMDUgMTI1LDk1IDEzMSw5NSAxMzEsNDUgMTIyLDQ1IDEzMiwzNiAxNDEsMjIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTI1LDk1IDEzMCwxMTAgMTA2LDExNyIvPjwvZz48L2c+PC9zdmc+">
|
||||
<style>
|
||||
body{
|
||||
font-family: system-ui, -apple-system, Roboto, "Segoe UI", sans-serif;
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
pre > code {
|
||||
display: block;
|
||||
overflow: auto;
|
||||
line-height: normal;
|
||||
margin: 0em;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-str {
|
||||
color: #d14;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #005C7A;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #545454;
|
||||
font-style: italic;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #900;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-null {
|
||||
color: #005C5C;
|
||||
}
|
||||
.tok-number {
|
||||
color: #005C5C;
|
||||
}
|
||||
.tok-type {
|
||||
color: #458;
|
||||
font-weight: bold;
|
||||
}
|
||||
pre {
|
||||
counter-reset: line;
|
||||
}
|
||||
pre .line:before {
|
||||
counter-increment: line;
|
||||
content: counter(line);
|
||||
display: inline-block;
|
||||
padding-right: 1em;
|
||||
width: 2em;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.line {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
.line:target {
|
||||
border-top: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ccc;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body{
|
||||
background:#222;
|
||||
color: #ccc;
|
||||
}
|
||||
pre > code {
|
||||
color: #ccc;
|
||||
background: #222;
|
||||
border: unset;
|
||||
}
|
||||
.line:target {
|
||||
border-top: 1px solid #444;
|
||||
border-bottom: 1px solid #444;
|
||||
background: #333;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #eee;
|
||||
}
|
||||
.tok-str {
|
||||
color: #2e5;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #ff894c;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #aa7;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #B1A0F8;
|
||||
}
|
||||
.tok-null {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-number {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-type {
|
||||
color: #68f;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre><code><span class="line" id="L1"><span class="tok-kw">const</span> std = <span class="tok-builtin">@import</span>(<span class="tok-str">"std"</span>);</span>
|
||||
<span class="line" id="L2"></span>
|
||||
<span class="line" id="L3"><span class="tok-comment">// TODO: rework logging in zap</span>
|
||||
</span>
|
||||
<span class="line" id="L4"></span>
|
||||
<span class="line" id="L5">debugOn: <span class="tok-type">bool</span>,</span>
|
||||
<span class="line" id="L6"></span>
|
||||
<span class="line" id="L7"><span class="tok-comment">/// Access to facil.io's logging facilities</span></span>
|
||||
<span class="line" id="L8"><span class="tok-kw">const</span> Self = <span class="tok-builtin">@This</span>();</span>
|
||||
<span class="line" id="L9"></span>
|
||||
<span class="line" id="L10"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">init</span>(<span class="tok-kw">comptime</span> debug: <span class="tok-type">bool</span>) Self {</span>
|
||||
<span class="line" id="L11"> <span class="tok-kw">return</span> .{</span>
|
||||
<span class="line" id="L12"> .debugOn = debug,</span>
|
||||
<span class="line" id="L13"> };</span>
|
||||
<span class="line" id="L14">}</span>
|
||||
<span class="line" id="L15"></span>
|
||||
<span class="line" id="L16"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">log</span>(self: *<span class="tok-kw">const</span> Self, <span class="tok-kw">comptime</span> fmt: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>, args: <span class="tok-kw">anytype</span>) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L17"> <span class="tok-kw">if</span> (self.debugOn) {</span>
|
||||
<span class="line" id="L18"> std.debug.print(<span class="tok-str">"[zap] - "</span> ++ fmt, args);</span>
|
||||
<span class="line" id="L19"> }</span>
|
||||
<span class="line" id="L20">}</span>
|
||||
<span class="line" id="L21"></span>
|
||||
<span class="line" id="L22"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">const</span> fio_log_level_none: <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L23"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">const</span> fio_log_level_fatal: <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L24"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">const</span> fio_log_level_error: <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L25"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">const</span> fio_log_level_warning: <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L26"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">const</span> fio_log_level_info: <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L27"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">const</span> fio_log_level_debug: <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L28"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fio_set_log_level</span>(level: <span class="tok-type">c_int</span>) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L29"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fio_get_log_level</span>() <span class="tok-type">c_int</span>;</span>
|
||||
<span class="line" id="L30"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fio_log_print</span>(level: <span class="tok-type">c_int</span>, msg: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span>) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L31"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fio_log_info</span>(msg: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span>) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L32"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fio_log_warning</span>(msg: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span>) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L33"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fio_log_error</span>(msg: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span>) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L34"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fio_log_fatal</span>(msg: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span>) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L35"><span class="tok-kw">pub</span> <span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fio_log_debug</span>(msg: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span>) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L36"></span>
|
||||
<span class="line" id="L37"><span class="tok-comment">// pub fn getDebugLogger(comptime debug: bool) type {</span>
|
||||
</span>
|
||||
<span class="line" id="L38"><span class="tok-comment">// return struct {</span>
|
||||
</span>
|
||||
<span class="line" id="L39"><span class="tok-comment">// pub fn log(comptime fmt: []const u8, args: anytype) void {</span>
|
||||
</span>
|
||||
<span class="line" id="L40"><span class="tok-comment">// if (debug) {</span>
|
||||
</span>
|
||||
<span class="line" id="L41"><span class="tok-comment">// std.debug.print("[zap] - " ++ fmt, args);</span>
|
||||
</span>
|
||||
<span class="line" id="L42"><span class="tok-comment">// }</span>
|
||||
</span>
|
||||
<span class="line" id="L43"><span class="tok-comment">// }</span>
|
||||
</span>
|
||||
<span class="line" id="L44"><span class="tok-comment">// };</span>
|
||||
</span>
|
||||
<span class="line" id="L45"><span class="tok-comment">// }</span>
|
||||
</span>
|
||||
<span class="line" id="L46"></span>
|
||||
</code></pre></body>
|
||||
</html>
|
|
@ -1,307 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>middleware.zig - source view</title>
|
||||
<link rel="icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAgklEQVR4AWMYWuD7EllJIM4G4g4g5oIJ/odhOJ8wToOxSTXgNxDHoeiBMfA4+wGShjyYOCkG/IGqWQziEzYAoUAeiF9D5U+DxEg14DRU7jWIT5IBIOdCxf+A+CQZAAoopEB7QJwBCBwHiip8UYmRdrAlDpIMgApwQZNnNii5Dq0MBgCxxycBnwEd+wAAAABJRU5ErkJggg==">
|
||||
<link rel="icon" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNTMgMTQwIj48ZyBmaWxsPSIjRjdBNDFEIj48Zz48cG9seWdvbiBwb2ludHM9IjQ2LDIyIDI4LDQ0IDE5LDMwIi8+PHBvbHlnb24gcG9pbnRzPSI0NiwyMiAzMywzMyAyOCw0NCAyMiw0NCAyMiw5NSAzMSw5NSAyMCwxMDAgMTIsMTE3IDAsMTE3IDAsMjIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMzEsOTUgMTIsMTE3IDQsMTA2Ii8+PC9nPjxnPjxwb2x5Z29uIHBvaW50cz0iNTYsMjIgNjIsMzYgMzcsNDQiLz48cG9seWdvbiBwb2ludHM9IjU2LDIyIDExMSwyMiAxMTEsNDQgMzcsNDQgNTYsMzIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTE2LDk1IDk3LDExNyA5MCwxMDQiLz48cG9seWdvbiBwb2ludHM9IjExNiw5NSAxMDAsMTA0IDk3LDExNyA0MiwxMTcgNDIsOTUiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTUwLDAgNTIsMTE3IDMsMTQwIDEwMSwyMiIvPjwvZz48Zz48cG9seWdvbiBwb2ludHM9IjE0MSwyMiAxNDAsNDAgMTIyLDQ1Ii8+PHBvbHlnb24gcG9pbnRzPSIxNTMsMjIgMTUzLDExNyAxMDYsMTE3IDEyMCwxMDUgMTI1LDk1IDEzMSw5NSAxMzEsNDUgMTIyLDQ1IDEzMiwzNiAxNDEsMjIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTI1LDk1IDEzMCwxMTAgMTA2LDExNyIvPjwvZz48L2c+PC9zdmc+">
|
||||
<style>
|
||||
body{
|
||||
font-family: system-ui, -apple-system, Roboto, "Segoe UI", sans-serif;
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
pre > code {
|
||||
display: block;
|
||||
overflow: auto;
|
||||
line-height: normal;
|
||||
margin: 0em;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-str {
|
||||
color: #d14;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #005C7A;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #545454;
|
||||
font-style: italic;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #900;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-null {
|
||||
color: #005C5C;
|
||||
}
|
||||
.tok-number {
|
||||
color: #005C5C;
|
||||
}
|
||||
.tok-type {
|
||||
color: #458;
|
||||
font-weight: bold;
|
||||
}
|
||||
pre {
|
||||
counter-reset: line;
|
||||
}
|
||||
pre .line:before {
|
||||
counter-increment: line;
|
||||
content: counter(line);
|
||||
display: inline-block;
|
||||
padding-right: 1em;
|
||||
width: 2em;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.line {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
.line:target {
|
||||
border-top: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ccc;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body{
|
||||
background:#222;
|
||||
color: #ccc;
|
||||
}
|
||||
pre > code {
|
||||
color: #ccc;
|
||||
background: #222;
|
||||
border: unset;
|
||||
}
|
||||
.line:target {
|
||||
border-top: 1px solid #444;
|
||||
border-bottom: 1px solid #444;
|
||||
background: #333;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #eee;
|
||||
}
|
||||
.tok-str {
|
||||
color: #2e5;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #ff894c;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #aa7;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #B1A0F8;
|
||||
}
|
||||
.tok-null {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-number {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-type {
|
||||
color: #68f;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre><code><span class="line" id="L1"><span class="tok-kw">const</span> std = <span class="tok-builtin">@import</span>(<span class="tok-str">"std"</span>);</span>
|
||||
<span class="line" id="L2"><span class="tok-kw">const</span> zap = <span class="tok-builtin">@import</span>(<span class="tok-str">"zap.zig"</span>);</span>
|
||||
<span class="line" id="L3"></span>
|
||||
<span class="line" id="L4"><span class="tok-comment">/// Your middleware components need to contain a handler.</span></span>
|
||||
<span class="line" id="L5"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L6"><span class="tok-comment">/// A Handler is one element in the chain of request handlers that will be tried</span></span>
|
||||
<span class="line" id="L7"><span class="tok-comment">/// by the listener when a request arrives. Handlers indicate to the previous</span></span>
|
||||
<span class="line" id="L8"><span class="tok-comment">/// handler whether they processed a request by returning `true` from their</span></span>
|
||||
<span class="line" id="L9"><span class="tok-comment">/// `on_request` function, in which case a typical request handler would stop</span></span>
|
||||
<span class="line" id="L10"><span class="tok-comment">/// trying to pass the request on to the next handler in the chain. See</span></span>
|
||||
<span class="line" id="L11"><span class="tok-comment">/// the `handle_other` function in this struct.</span></span>
|
||||
<span class="line" id="L12"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">Handler</span>(<span class="tok-kw">comptime</span> ContextType: <span class="tok-kw">anytype</span>) <span class="tok-type">type</span> {</span>
|
||||
<span class="line" id="L13"> <span class="tok-kw">return</span> <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L14"> other_handler: ?*Self = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L15"> on_request: ?RequestFn = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L16"></span>
|
||||
<span class="line" id="L17"> <span class="tok-comment">// will be set</span>
|
||||
</span>
|
||||
<span class="line" id="L18"> allocator: ?std.mem.Allocator = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L19"></span>
|
||||
<span class="line" id="L20"> <span class="tok-kw">pub</span> <span class="tok-kw">const</span> RequestFn = *<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (*Self, zap.Request, *ContextType) <span class="tok-type">bool</span>;</span>
|
||||
<span class="line" id="L21"> <span class="tok-kw">const</span> Self = <span class="tok-builtin">@This</span>();</span>
|
||||
<span class="line" id="L22"></span>
|
||||
<span class="line" id="L23"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">init</span>(on_request: RequestFn, other: ?*Self) Self {</span>
|
||||
<span class="line" id="L24"> <span class="tok-kw">return</span> .{</span>
|
||||
<span class="line" id="L25"> .other_handler = other,</span>
|
||||
<span class="line" id="L26"> .on_request = on_request,</span>
|
||||
<span class="line" id="L27"> };</span>
|
||||
<span class="line" id="L28"> }</span>
|
||||
<span class="line" id="L29"></span>
|
||||
<span class="line" id="L30"> <span class="tok-comment">// example for handling a request request</span>
|
||||
</span>
|
||||
<span class="line" id="L31"> <span class="tok-comment">// which you can use in your components, e.g.:</span>
|
||||
</span>
|
||||
<span class="line" id="L32"> <span class="tok-comment">// return self.handler.handleOther(r, context);</span>
|
||||
</span>
|
||||
<span class="line" id="L33"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">handleOther</span>(self: *Self, r: zap.Request, context: *ContextType) <span class="tok-type">bool</span> {</span>
|
||||
<span class="line" id="L34"> <span class="tok-comment">// in structs embedding a handler, we'd @fieldParentPtr the first</span>
|
||||
</span>
|
||||
<span class="line" id="L35"> <span class="tok-comment">// param to get to the real self</span>
|
||||
</span>
|
||||
<span class="line" id="L36"></span>
|
||||
<span class="line" id="L37"> <span class="tok-comment">// First, do our pre-other stuff</span>
|
||||
</span>
|
||||
<span class="line" id="L38"> <span class="tok-comment">// ..</span>
|
||||
</span>
|
||||
<span class="line" id="L39"></span>
|
||||
<span class="line" id="L40"> <span class="tok-comment">// then call the wrapped thing</span>
|
||||
</span>
|
||||
<span class="line" id="L41"> <span class="tok-kw">var</span> other_handler_finished = <span class="tok-null">false</span>;</span>
|
||||
<span class="line" id="L42"> <span class="tok-kw">if</span> (self.other_handler) |other_handler| {</span>
|
||||
<span class="line" id="L43"> <span class="tok-kw">if</span> (other_handler.on_request) |on_request| {</span>
|
||||
<span class="line" id="L44"> other_handler_finished = on_request(other_handler, r, context);</span>
|
||||
<span class="line" id="L45"> }</span>
|
||||
<span class="line" id="L46"> }</span>
|
||||
<span class="line" id="L47"></span>
|
||||
<span class="line" id="L48"> <span class="tok-comment">// now do our post stuff</span>
|
||||
</span>
|
||||
<span class="line" id="L49"> <span class="tok-kw">return</span> other_handler_finished;</span>
|
||||
<span class="line" id="L50"> }</span>
|
||||
<span class="line" id="L51"> };</span>
|
||||
<span class="line" id="L52">}</span>
|
||||
<span class="line" id="L53"></span>
|
||||
<span class="line" id="L54"><span class="tok-comment">/// A convenience handler for artibrary zap.Endpoint</span></span>
|
||||
<span class="line" id="L55"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">EndpointHandler</span>(<span class="tok-kw">comptime</span> HandlerType: <span class="tok-kw">anytype</span>, <span class="tok-kw">comptime</span> ContextType: <span class="tok-kw">anytype</span>) <span class="tok-type">type</span> {</span>
|
||||
<span class="line" id="L56"> <span class="tok-kw">return</span> <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L57"> handler: HandlerType,</span>
|
||||
<span class="line" id="L58"> endpoint: *zap.Endpoint,</span>
|
||||
<span class="line" id="L59"> breakOnFinish: <span class="tok-type">bool</span>,</span>
|
||||
<span class="line" id="L60"></span>
|
||||
<span class="line" id="L61"> <span class="tok-kw">const</span> Self = <span class="tok-builtin">@This</span>();</span>
|
||||
<span class="line" id="L62"></span>
|
||||
<span class="line" id="L63"> <span class="tok-comment">/// Create an endpointhandler from an endpoint and pass in the next (other) handler in the chain.</span></span>
|
||||
<span class="line" id="L64"> <span class="tok-comment">/// If `breakOnFinish` is `true`, the handler will stop handing requests down the chain if</span></span>
|
||||
<span class="line" id="L65"> <span class="tok-comment">/// the endpoint processed the request.</span></span>
|
||||
<span class="line" id="L66"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">init</span>(endpoint: *zap.Endpoint, other: ?*HandlerType, breakOnFinish: <span class="tok-type">bool</span>) Self {</span>
|
||||
<span class="line" id="L67"> <span class="tok-kw">return</span> .{</span>
|
||||
<span class="line" id="L68"> .handler = HandlerType.init(onRequest, other),</span>
|
||||
<span class="line" id="L69"> .endpoint = endpoint,</span>
|
||||
<span class="line" id="L70"> .breakOnFinish = breakOnFinish,</span>
|
||||
<span class="line" id="L71"> };</span>
|
||||
<span class="line" id="L72"> }</span>
|
||||
<span class="line" id="L73"></span>
|
||||
<span class="line" id="L74"> <span class="tok-comment">/// Provides the handler as a common interface to chain stuff</span></span>
|
||||
<span class="line" id="L75"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">getHandler</span>(self: *Self) *HandlerType {</span>
|
||||
<span class="line" id="L76"> <span class="tok-kw">return</span> &self.handler;</span>
|
||||
<span class="line" id="L77"> }</span>
|
||||
<span class="line" id="L78"></span>
|
||||
<span class="line" id="L79"> <span class="tok-comment">/// The Handler's request handling function. Gets called from the listener</span></span>
|
||||
<span class="line" id="L80"> <span class="tok-comment">/// with the request and a context instance. Calls the endpoint.</span></span>
|
||||
<span class="line" id="L81"> <span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L82"> <span class="tok-comment">/// If `breakOnFinish` is `true`, the handler will stop handing requests down the chain if</span></span>
|
||||
<span class="line" id="L83"> <span class="tok-comment">/// the endpoint processed the request.</span></span>
|
||||
<span class="line" id="L84"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">onRequest</span>(handler: *HandlerType, r: zap.Request, context: *ContextType) <span class="tok-type">bool</span> {</span>
|
||||
<span class="line" id="L85"> <span class="tok-kw">var</span> self = <span class="tok-builtin">@fieldParentPtr</span>(Self, <span class="tok-str">"handler"</span>, handler);</span>
|
||||
<span class="line" id="L86"> r.setUserContext(context);</span>
|
||||
<span class="line" id="L87"> self.endpoint.onRequest(r);</span>
|
||||
<span class="line" id="L88"></span>
|
||||
<span class="line" id="L89"> <span class="tok-comment">// if the request was handled by the endpoint, we may break the chain here</span>
|
||||
</span>
|
||||
<span class="line" id="L90"> <span class="tok-kw">if</span> (r.isFinished() <span class="tok-kw">and</span> self.breakOnFinish) {</span>
|
||||
<span class="line" id="L91"> <span class="tok-kw">return</span> <span class="tok-null">true</span>;</span>
|
||||
<span class="line" id="L92"> }</span>
|
||||
<span class="line" id="L93"> <span class="tok-kw">return</span> self.handler.handleOther(r, context);</span>
|
||||
<span class="line" id="L94"> }</span>
|
||||
<span class="line" id="L95"> };</span>
|
||||
<span class="line" id="L96">}</span>
|
||||
<span class="line" id="L97"></span>
|
||||
<span class="line" id="L98"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> Error = <span class="tok-kw">error</span>{</span>
|
||||
<span class="line" id="L99"> <span class="tok-comment">/// The listener could not be created because the settings provided to its</span></span>
|
||||
<span class="line" id="L100"> <span class="tok-comment">/// init() function contained an `on_request` callback that was not null.</span></span>
|
||||
<span class="line" id="L101"> InitOnRequestIsNotNull,</span>
|
||||
<span class="line" id="L102">};</span>
|
||||
<span class="line" id="L103"></span>
|
||||
<span class="line" id="L104"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> RequestAllocatorFn = *<span class="tok-kw">const</span> <span class="tok-kw">fn</span> () std.mem.Allocator;</span>
|
||||
<span class="line" id="L105"></span>
|
||||
<span class="line" id="L106"><span class="tok-comment">/// Special Listener that supports chaining request handlers.</span></span>
|
||||
<span class="line" id="L107"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">Listener</span>(<span class="tok-kw">comptime</span> ContextType: <span class="tok-kw">anytype</span>) <span class="tok-type">type</span> {</span>
|
||||
<span class="line" id="L108"> <span class="tok-kw">return</span> <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L109"> listener: zap.HttpListener = <span class="tok-null">undefined</span>,</span>
|
||||
<span class="line" id="L110"> settings: zap.HttpListenerSettings,</span>
|
||||
<span class="line" id="L111"></span>
|
||||
<span class="line" id="L112"> <span class="tok-comment">// static initial handler</span>
|
||||
</span>
|
||||
<span class="line" id="L113"> <span class="tok-kw">var</span> handler: ?*Handler(ContextType) = <span class="tok-null">undefined</span>;</span>
|
||||
<span class="line" id="L114"> <span class="tok-comment">// static allocator getter</span>
|
||||
</span>
|
||||
<span class="line" id="L115"> <span class="tok-kw">var</span> requestAllocator: ?RequestAllocatorFn = <span class="tok-null">null</span>;</span>
|
||||
<span class="line" id="L116"></span>
|
||||
<span class="line" id="L117"> <span class="tok-kw">const</span> Self = <span class="tok-builtin">@This</span>();</span>
|
||||
<span class="line" id="L118"></span>
|
||||
<span class="line" id="L119"> <span class="tok-comment">/// Construct and initialize a middleware handler.</span></span>
|
||||
<span class="line" id="L120"> <span class="tok-comment">/// The passed in settings must have on_request set to null! If that is</span></span>
|
||||
<span class="line" id="L121"> <span class="tok-comment">/// not the case, an InitOnRequestIsNotNull error will be returned.</span></span>
|
||||
<span class="line" id="L122"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">init</span>(settings: zap.HttpListenerSettings, initial_handler: *Handler(ContextType), request_alloc: ?RequestAllocatorFn) Error!Self {</span>
|
||||
<span class="line" id="L123"> <span class="tok-comment">// override on_request with ourselves</span>
|
||||
</span>
|
||||
<span class="line" id="L124"> <span class="tok-kw">if</span> (settings.on_request != <span class="tok-null">null</span>) {</span>
|
||||
<span class="line" id="L125"> <span class="tok-kw">return</span> Error.InitOnRequestIsNotNull;</span>
|
||||
<span class="line" id="L126"> }</span>
|
||||
<span class="line" id="L127"> requestAllocator = request_alloc;</span>
|
||||
<span class="line" id="L128"> std.debug.assert(requestAllocator != <span class="tok-null">null</span>);</span>
|
||||
<span class="line" id="L129"></span>
|
||||
<span class="line" id="L130"> <span class="tok-kw">var</span> ret: Self = .{</span>
|
||||
<span class="line" id="L131"> .settings = settings,</span>
|
||||
<span class="line" id="L132"> };</span>
|
||||
<span class="line" id="L133"></span>
|
||||
<span class="line" id="L134"> ret.settings.on_request = onRequest;</span>
|
||||
<span class="line" id="L135"> ret.listener = zap.HttpListener.init(ret.settings);</span>
|
||||
<span class="line" id="L136"> handler = initial_handler;</span>
|
||||
<span class="line" id="L137"> <span class="tok-kw">return</span> ret;</span>
|
||||
<span class="line" id="L138"> }</span>
|
||||
<span class="line" id="L139"></span>
|
||||
<span class="line" id="L140"> <span class="tok-comment">/// Start listening.</span></span>
|
||||
<span class="line" id="L141"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">listen</span>(self: *Self) !<span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L142"> <span class="tok-kw">try</span> self.listener.listen();</span>
|
||||
<span class="line" id="L143"> }</span>
|
||||
<span class="line" id="L144"></span>
|
||||
<span class="line" id="L145"> <span class="tok-comment">/// The listener's request handler, stepping through the chain of Handlers</span></span>
|
||||
<span class="line" id="L146"> <span class="tok-comment">/// by calling the initial one which takes it from there.</span></span>
|
||||
<span class="line" id="L147"> <span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L148"> <span class="tok-comment">/// This is just a reference implementation that you can use by default.</span></span>
|
||||
<span class="line" id="L149"> <span class="tok-comment">/// Create your own listener if you want different behavior.</span></span>
|
||||
<span class="line" id="L150"> <span class="tok-comment">/// (Didn't want to make this a callback. Submit an issue if you really</span></span>
|
||||
<span class="line" id="L151"> <span class="tok-comment">/// think that's an issue).</span></span>
|
||||
<span class="line" id="L152"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">onRequest</span>(r: zap.Request) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L153"> <span class="tok-comment">// we are the 1st handler in the chain, so we create a context</span>
|
||||
</span>
|
||||
<span class="line" id="L154"> <span class="tok-kw">var</span> context: ContextType = .{};</span>
|
||||
<span class="line" id="L155"></span>
|
||||
<span class="line" id="L156"> <span class="tok-comment">// handlers might need an allocator</span>
|
||||
</span>
|
||||
<span class="line" id="L157"> <span class="tok-comment">// we CAN provide an allocator getter</span>
|
||||
</span>
|
||||
<span class="line" id="L158"> <span class="tok-kw">var</span> allocator: ?std.mem.Allocator = <span class="tok-null">null</span>;</span>
|
||||
<span class="line" id="L159"> <span class="tok-kw">if</span> (requestAllocator) |foo| {</span>
|
||||
<span class="line" id="L160"> allocator = foo();</span>
|
||||
<span class="line" id="L161"> }</span>
|
||||
<span class="line" id="L162"></span>
|
||||
<span class="line" id="L163"> <span class="tok-kw">if</span> (handler) |initial_handler| {</span>
|
||||
<span class="line" id="L164"> initial_handler.allocator = allocator;</span>
|
||||
<span class="line" id="L165"> <span class="tok-kw">if</span> (initial_handler.on_request) |on_request| {</span>
|
||||
<span class="line" id="L166"> <span class="tok-comment">// we don't care about the return value at the top level</span>
|
||||
</span>
|
||||
<span class="line" id="L167"> _ = on_request(initial_handler, r, &context);</span>
|
||||
<span class="line" id="L168"> }</span>
|
||||
<span class="line" id="L169"> }</span>
|
||||
<span class="line" id="L170"> }</span>
|
||||
<span class="line" id="L171"> };</span>
|
||||
<span class="line" id="L172">}</span>
|
||||
<span class="line" id="L173"></span>
|
||||
</code></pre></body>
|
||||
</html>
|
|
@ -1,383 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>mustache.zig - source view</title>
|
||||
<link rel="icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAgklEQVR4AWMYWuD7EllJIM4G4g4g5oIJ/odhOJ8wToOxSTXgNxDHoeiBMfA4+wGShjyYOCkG/IGqWQziEzYAoUAeiF9D5U+DxEg14DRU7jWIT5IBIOdCxf+A+CQZAAoopEB7QJwBCBwHiip8UYmRdrAlDpIMgApwQZNnNii5Dq0MBgCxxycBnwEd+wAAAABJRU5ErkJggg==">
|
||||
<link rel="icon" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNTMgMTQwIj48ZyBmaWxsPSIjRjdBNDFEIj48Zz48cG9seWdvbiBwb2ludHM9IjQ2LDIyIDI4LDQ0IDE5LDMwIi8+PHBvbHlnb24gcG9pbnRzPSI0NiwyMiAzMywzMyAyOCw0NCAyMiw0NCAyMiw5NSAzMSw5NSAyMCwxMDAgMTIsMTE3IDAsMTE3IDAsMjIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMzEsOTUgMTIsMTE3IDQsMTA2Ii8+PC9nPjxnPjxwb2x5Z29uIHBvaW50cz0iNTYsMjIgNjIsMzYgMzcsNDQiLz48cG9seWdvbiBwb2ludHM9IjU2LDIyIDExMSwyMiAxMTEsNDQgMzcsNDQgNTYsMzIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTE2LDk1IDk3LDExNyA5MCwxMDQiLz48cG9seWdvbiBwb2ludHM9IjExNiw5NSAxMDAsMTA0IDk3LDExNyA0MiwxMTcgNDIsOTUiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTUwLDAgNTIsMTE3IDMsMTQwIDEwMSwyMiIvPjwvZz48Zz48cG9seWdvbiBwb2ludHM9IjE0MSwyMiAxNDAsNDAgMTIyLDQ1Ii8+PHBvbHlnb24gcG9pbnRzPSIxNTMsMjIgMTUzLDExNyAxMDYsMTE3IDEyMCwxMDUgMTI1LDk1IDEzMSw5NSAxMzEsNDUgMTIyLDQ1IDEzMiwzNiAxNDEsMjIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTI1LDk1IDEzMCwxMTAgMTA2LDExNyIvPjwvZz48L2c+PC9zdmc+">
|
||||
<style>
|
||||
body{
|
||||
font-family: system-ui, -apple-system, Roboto, "Segoe UI", sans-serif;
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
pre > code {
|
||||
display: block;
|
||||
overflow: auto;
|
||||
line-height: normal;
|
||||
margin: 0em;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-str {
|
||||
color: #d14;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #005C7A;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #545454;
|
||||
font-style: italic;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #900;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-null {
|
||||
color: #005C5C;
|
||||
}
|
||||
.tok-number {
|
||||
color: #005C5C;
|
||||
}
|
||||
.tok-type {
|
||||
color: #458;
|
||||
font-weight: bold;
|
||||
}
|
||||
pre {
|
||||
counter-reset: line;
|
||||
}
|
||||
pre .line:before {
|
||||
counter-increment: line;
|
||||
content: counter(line);
|
||||
display: inline-block;
|
||||
padding-right: 1em;
|
||||
width: 2em;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.line {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
.line:target {
|
||||
border-top: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ccc;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body{
|
||||
background:#222;
|
||||
color: #ccc;
|
||||
}
|
||||
pre > code {
|
||||
color: #ccc;
|
||||
background: #222;
|
||||
border: unset;
|
||||
}
|
||||
.line:target {
|
||||
border-top: 1px solid #444;
|
||||
border-bottom: 1px solid #444;
|
||||
background: #333;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #eee;
|
||||
}
|
||||
.tok-str {
|
||||
color: #2e5;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #ff894c;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #aa7;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #B1A0F8;
|
||||
}
|
||||
.tok-null {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-number {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-type {
|
||||
color: #68f;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre><code><span class="line" id="L1"><span class="tok-kw">const</span> std = <span class="tok-builtin">@import</span>(<span class="tok-str">"std"</span>);</span>
|
||||
<span class="line" id="L2"><span class="tok-kw">const</span> fio = <span class="tok-builtin">@import</span>(<span class="tok-str">"fio.zig"</span>);</span>
|
||||
<span class="line" id="L3"><span class="tok-kw">const</span> util = <span class="tok-builtin">@import</span>(<span class="tok-str">"util.zig"</span>);</span>
|
||||
<span class="line" id="L4"></span>
|
||||
<span class="line" id="L5"><span class="tok-kw">const</span> Self = <span class="tok-builtin">@This</span>();</span>
|
||||
<span class="line" id="L6"></span>
|
||||
<span class="line" id="L7"><span class="tok-kw">const</span> struct_mustache_s = <span class="tok-kw">opaque</span> {};</span>
|
||||
<span class="line" id="L8"><span class="tok-kw">const</span> mustache_s = struct_mustache_s;</span>
|
||||
<span class="line" id="L9"><span class="tok-kw">const</span> enum_mustache_error_en = <span class="tok-type">c_uint</span>;</span>
|
||||
<span class="line" id="L10"><span class="tok-kw">const</span> mustache_error_en = enum_mustache_error_en;</span>
|
||||
<span class="line" id="L11"></span>
|
||||
<span class="line" id="L12"><span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_mustache_new</span>(args: MustacheLoadArgsFio) ?*mustache_s;</span>
|
||||
<span class="line" id="L13"><span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_mustache_build</span>(mustache: ?*mustache_s, data: fio.FIOBJ) fio.FIOBJ;</span>
|
||||
<span class="line" id="L14"><span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_mustache_build2</span>(dest: fio.FIOBJ, mustache: ?*mustache_s, data: fio.FIOBJ) fio.FIOBJ;</span>
|
||||
<span class="line" id="L15"><span class="tok-kw">extern</span> <span class="tok-kw">fn</span> <span class="tok-fn">fiobj_mustache_free</span>(mustache: ?*mustache_s) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L16"></span>
|
||||
<span class="line" id="L17"><span class="tok-comment">/// Load arguments used when creating a new Mustache instance.</span></span>
|
||||
<span class="line" id="L18"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> MustacheLoadArgs = <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L19"> <span class="tok-comment">/// Filename. This enables partial templates on filesystem.</span></span>
|
||||
<span class="line" id="L20"> filename: ?[]<span class="tok-kw">const</span> <span class="tok-type">u8</span> = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L21"></span>
|
||||
<span class="line" id="L22"> <span class="tok-comment">/// String data. Should be used if no filename is specified.</span></span>
|
||||
<span class="line" id="L23"> data: ?[]<span class="tok-kw">const</span> <span class="tok-type">u8</span> = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L24">};</span>
|
||||
<span class="line" id="L25"></span>
|
||||
<span class="line" id="L26"><span class="tok-comment">/// Internal struct used for interfacing with fio.</span></span>
|
||||
<span class="line" id="L27"><span class="tok-kw">const</span> MustacheLoadArgsFio = <span class="tok-kw">extern</span> <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L28"> filename: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L29"> filename_len: <span class="tok-type">usize</span>,</span>
|
||||
<span class="line" id="L30"> data: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L31"> data_len: <span class="tok-type">usize</span>,</span>
|
||||
<span class="line" id="L32"> err: [*c]mustache_error_en,</span>
|
||||
<span class="line" id="L33">};</span>
|
||||
<span class="line" id="L34"></span>
|
||||
<span class="line" id="L35"><span class="tok-comment">/// Handle to the underlying fiobj mustache instance.</span></span>
|
||||
<span class="line" id="L36">handle: *mustache_s,</span>
|
||||
<span class="line" id="L37"></span>
|
||||
<span class="line" id="L38"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> Error = <span class="tok-kw">error</span>{</span>
|
||||
<span class="line" id="L39"> MUSTACHE_ERR_TOO_DEEP,</span>
|
||||
<span class="line" id="L40"> MUSTACHE_ERR_CLOSURE_MISMATCH,</span>
|
||||
<span class="line" id="L41"> MUSTACHE_ERR_FILE_NOT_FOUND,</span>
|
||||
<span class="line" id="L42"> MUSTACHE_ERR_FILE_TOO_BIG,</span>
|
||||
<span class="line" id="L43"> MUSTACHE_ERR_FILE_NAME_TOO_LONG,</span>
|
||||
<span class="line" id="L44"> MUSTACHE_ERR_FILE_NAME_TOO_SHORT,</span>
|
||||
<span class="line" id="L45"> MUSTACHE_ERR_EMPTY_TEMPLATE,</span>
|
||||
<span class="line" id="L46"> MUSTACHE_ERR_DELIMITER_TOO_LONG,</span>
|
||||
<span class="line" id="L47"> MUSTACHE_ERR_NAME_TOO_LONG,</span>
|
||||
<span class="line" id="L48"> MUSTACHE_ERR_UNKNOWN,</span>
|
||||
<span class="line" id="L49"> MUSTACHE_ERR_USER_ERROR,</span>
|
||||
<span class="line" id="L50">};</span>
|
||||
<span class="line" id="L51"></span>
|
||||
<span class="line" id="L52"><span class="tok-comment">/// Create a new `Mustache` instance; `deinit()` should be called to free</span></span>
|
||||
<span class="line" id="L53"><span class="tok-comment">/// the object after usage.</span></span>
|
||||
<span class="line" id="L54"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">init</span>(load_args: MustacheLoadArgs) Error!Self {</span>
|
||||
<span class="line" id="L55"> <span class="tok-kw">var</span> err: mustache_error_en = <span class="tok-null">undefined</span>;</span>
|
||||
<span class="line" id="L56"></span>
|
||||
<span class="line" id="L57"> <span class="tok-kw">const</span> args: MustacheLoadArgsFio = .{</span>
|
||||
<span class="line" id="L58"> .filename = filn: {</span>
|
||||
<span class="line" id="L59"> <span class="tok-kw">if</span> (load_args.filename) |filn| <span class="tok-kw">break</span> :filn filn.ptr <span class="tok-kw">else</span> <span class="tok-kw">break</span> :filn <span class="tok-null">null</span>;</span>
|
||||
<span class="line" id="L60"> },</span>
|
||||
<span class="line" id="L61"> .filename_len = filn_len: {</span>
|
||||
<span class="line" id="L62"> <span class="tok-kw">if</span> (load_args.filename) |filn| <span class="tok-kw">break</span> :filn_len filn.len <span class="tok-kw">else</span> <span class="tok-kw">break</span> :filn_len <span class="tok-number">0</span>;</span>
|
||||
<span class="line" id="L63"> },</span>
|
||||
<span class="line" id="L64"> .data = data: {</span>
|
||||
<span class="line" id="L65"> <span class="tok-kw">if</span> (load_args.data) |data| <span class="tok-kw">break</span> :data data.ptr <span class="tok-kw">else</span> <span class="tok-kw">break</span> :data <span class="tok-null">null</span>;</span>
|
||||
<span class="line" id="L66"> },</span>
|
||||
<span class="line" id="L67"> .data_len = data_len: {</span>
|
||||
<span class="line" id="L68"> <span class="tok-kw">if</span> (load_args.data) |data| <span class="tok-kw">break</span> :data_len data.len <span class="tok-kw">else</span> <span class="tok-kw">break</span> :data_len <span class="tok-number">0</span>;</span>
|
||||
<span class="line" id="L69"> },</span>
|
||||
<span class="line" id="L70"> .err = &err,</span>
|
||||
<span class="line" id="L71"> };</span>
|
||||
<span class="line" id="L72"></span>
|
||||
<span class="line" id="L73"> <span class="tok-kw">const</span> ret = fiobj_mustache_new(args);</span>
|
||||
<span class="line" id="L74"> <span class="tok-kw">switch</span> (err) {</span>
|
||||
<span class="line" id="L75"> <span class="tok-number">0</span> => <span class="tok-kw">return</span> Self{</span>
|
||||
<span class="line" id="L76"> .handle = ret.?,</span>
|
||||
<span class="line" id="L77"> },</span>
|
||||
<span class="line" id="L78"> <span class="tok-number">1</span> => <span class="tok-kw">return</span> Error.MUSTACHE_ERR_TOO_DEEP,</span>
|
||||
<span class="line" id="L79"> <span class="tok-number">2</span> => <span class="tok-kw">return</span> Error.MUSTACHE_ERR_CLOSURE_MISMATCH,</span>
|
||||
<span class="line" id="L80"> <span class="tok-number">3</span> => <span class="tok-kw">return</span> Error.MUSTACHE_ERR_FILE_NOT_FOUND,</span>
|
||||
<span class="line" id="L81"> <span class="tok-number">4</span> => <span class="tok-kw">return</span> Error.MUSTACHE_ERR_FILE_TOO_BIG,</span>
|
||||
<span class="line" id="L82"> <span class="tok-number">5</span> => <span class="tok-kw">return</span> Error.MUSTACHE_ERR_FILE_NAME_TOO_LONG,</span>
|
||||
<span class="line" id="L83"> <span class="tok-number">6</span> => <span class="tok-kw">return</span> Error.MUSTACHE_ERR_FILE_NAME_TOO_SHORT,</span>
|
||||
<span class="line" id="L84"> <span class="tok-number">7</span> => <span class="tok-kw">return</span> Error.MUSTACHE_ERR_EMPTY_TEMPLATE,</span>
|
||||
<span class="line" id="L85"> <span class="tok-number">8</span> => <span class="tok-kw">return</span> Error.MUSTACHE_ERR_DELIMITER_TOO_LONG,</span>
|
||||
<span class="line" id="L86"> <span class="tok-number">9</span> => <span class="tok-kw">return</span> Error.MUSTACHE_ERR_NAME_TOO_LONG,</span>
|
||||
<span class="line" id="L87"> <span class="tok-number">10</span> => <span class="tok-kw">return</span> Error.MUSTACHE_ERR_UNKNOWN,</span>
|
||||
<span class="line" id="L88"> <span class="tok-number">11</span> => <span class="tok-kw">return</span> Error.MUSTACHE_ERR_USER_ERROR,</span>
|
||||
<span class="line" id="L89"> <span class="tok-kw">else</span> => <span class="tok-kw">return</span> Error.MUSTACHE_ERR_UNKNOWN,</span>
|
||||
<span class="line" id="L90"> }</span>
|
||||
<span class="line" id="L91"> <span class="tok-kw">unreachable</span>;</span>
|
||||
<span class="line" id="L92">}</span>
|
||||
<span class="line" id="L93"></span>
|
||||
<span class="line" id="L94"><span class="tok-comment">/// Convenience function to create a new `Mustache` instance with in-memory data loaded;</span></span>
|
||||
<span class="line" id="L95"><span class="tok-comment">/// `deinit()` should be called to free the object after usage..</span></span>
|
||||
<span class="line" id="L96"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">fromData</span>(data: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>) Error!Self {</span>
|
||||
<span class="line" id="L97"> <span class="tok-kw">return</span> Self.init(.{ .data = data });</span>
|
||||
<span class="line" id="L98">}</span>
|
||||
<span class="line" id="L99"></span>
|
||||
<span class="line" id="L100"><span class="tok-comment">/// Convenience function to create a new `Mustache` instance with file-based data loaded;</span></span>
|
||||
<span class="line" id="L101"><span class="tok-comment">/// `deinit()` should be called to free the object after usage..</span></span>
|
||||
<span class="line" id="L102"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">fromFile</span>(filename: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>) Error!Self {</span>
|
||||
<span class="line" id="L103"> <span class="tok-kw">return</span> Self.init(.{ .filename = filename });</span>
|
||||
<span class="line" id="L104">}</span>
|
||||
<span class="line" id="L105"></span>
|
||||
<span class="line" id="L106"><span class="tok-comment">/// Free the data backing a `Mustache` instance.</span></span>
|
||||
<span class="line" id="L107"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">deinit</span>(self: *Self) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L108"> fiobj_mustache_free(self.handle);</span>
|
||||
<span class="line" id="L109">}</span>
|
||||
<span class="line" id="L110"></span>
|
||||
<span class="line" id="L111"><span class="tok-comment">// TODO: implement these - fiobj_mustache.c</span>
|
||||
</span>
|
||||
<span class="line" id="L112"><span class="tok-comment">// pub extern fn fiobj_mustache_build(mustache: ?*mustache_s, data: FIOBJ) FIOBJ;</span>
|
||||
</span>
|
||||
<span class="line" id="L113"><span class="tok-comment">// pub extern fn fiobj_mustache_build2(dest: FIOBJ, mustache: ?*mustache_s, data: FIOBJ) FIOBJ;</span>
|
||||
</span>
|
||||
<span class="line" id="L114"></span>
|
||||
<span class="line" id="L115"><span class="tok-comment">/// The result from calling `build`.</span></span>
|
||||
<span class="line" id="L116"><span class="tok-kw">const</span> MustacheBuildResult = <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L117"> fiobj_result: fio.FIOBJ = <span class="tok-number">0</span>,</span>
|
||||
<span class="line" id="L118"></span>
|
||||
<span class="line" id="L119"> <span class="tok-comment">/// Holds the context converted into a fiobj.</span></span>
|
||||
<span class="line" id="L120"> <span class="tok-comment">/// This is used in `build`.</span></span>
|
||||
<span class="line" id="L121"> fiobj_context: fio.FIOBJ = <span class="tok-number">0</span>,</span>
|
||||
<span class="line" id="L122"></span>
|
||||
<span class="line" id="L123"> <span class="tok-comment">/// Free the data backing a `MustacheBuildResult` instance.</span></span>
|
||||
<span class="line" id="L124"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">deinit</span>(m: *<span class="tok-kw">const</span> MustacheBuildResult) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L125"> fio.fiobj_free_wrapped(m.fiobj_result);</span>
|
||||
<span class="line" id="L126"> fio.fiobj_free_wrapped(m.fiobj_context);</span>
|
||||
<span class="line" id="L127"> }</span>
|
||||
<span class="line" id="L128"></span>
|
||||
<span class="line" id="L129"> <span class="tok-comment">/// Retrieve a string representation of the built template.</span></span>
|
||||
<span class="line" id="L130"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">str</span>(m: *<span class="tok-kw">const</span> MustacheBuildResult) ?[]<span class="tok-kw">const</span> <span class="tok-type">u8</span> {</span>
|
||||
<span class="line" id="L131"> <span class="tok-kw">return</span> util.fio2str(m.fiobj_result);</span>
|
||||
<span class="line" id="L132"> }</span>
|
||||
<span class="line" id="L133">};</span>
|
||||
<span class="line" id="L134"></span>
|
||||
<span class="line" id="L135"><span class="tok-comment">/// Build the Mustache template; `deinit()` should be called on the build</span></span>
|
||||
<span class="line" id="L136"><span class="tok-comment">/// result to free the data.</span></span>
|
||||
<span class="line" id="L137"><span class="tok-comment">// TODO: The build may be slow because it needs to convert zig types to facil.io</span>
|
||||
</span>
|
||||
<span class="line" id="L138"><span class="tok-comment">// types. However, this needs to be investigated into.</span>
|
||||
</span>
|
||||
<span class="line" id="L139"><span class="tok-comment">// See `fiobjectify` for more information.</span>
|
||||
</span>
|
||||
<span class="line" id="L140"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">build</span>(self: *Self, data: <span class="tok-kw">anytype</span>) MustacheBuildResult {</span>
|
||||
<span class="line" id="L141"> <span class="tok-kw">const</span> T = <span class="tok-builtin">@TypeOf</span>(data);</span>
|
||||
<span class="line" id="L142"> <span class="tok-kw">if</span> (<span class="tok-builtin">@typeInfo</span>(T) != .Struct) {</span>
|
||||
<span class="line" id="L143"> <span class="tok-builtin">@compileError</span>(<span class="tok-str">"No struct: '"</span> ++ <span class="tok-builtin">@typeName</span>(T) ++ <span class="tok-str">"'"</span>);</span>
|
||||
<span class="line" id="L144"> }</span>
|
||||
<span class="line" id="L145"></span>
|
||||
<span class="line" id="L146"> <span class="tok-kw">var</span> result: MustacheBuildResult = .{};</span>
|
||||
<span class="line" id="L147"></span>
|
||||
<span class="line" id="L148"> result.fiobj_context = fiobjectify(data);</span>
|
||||
<span class="line" id="L149"> result.fiobj_result = fiobj_mustache_build(self.handle, result.fiobj_context);</span>
|
||||
<span class="line" id="L150"> <span class="tok-kw">return</span> result;</span>
|
||||
<span class="line" id="L151">}</span>
|
||||
<span class="line" id="L152"></span>
|
||||
<span class="line" id="L153"><span class="tok-comment">/// Internal function used to convert zig types to facil.io types.</span></span>
|
||||
<span class="line" id="L154"><span class="tok-comment">/// Used when providing the context to `fiobj_mustache_build`.</span></span>
|
||||
<span class="line" id="L155"><span class="tok-kw">fn</span> <span class="tok-fn">fiobjectify</span>(</span>
|
||||
<span class="line" id="L156"> value: <span class="tok-kw">anytype</span>,</span>
|
||||
<span class="line" id="L157">) fio.FIOBJ {</span>
|
||||
<span class="line" id="L158"> <span class="tok-kw">const</span> T = <span class="tok-builtin">@TypeOf</span>(value);</span>
|
||||
<span class="line" id="L159"> <span class="tok-kw">switch</span> (<span class="tok-builtin">@typeInfo</span>(T)) {</span>
|
||||
<span class="line" id="L160"> .Float, .ComptimeFloat => {</span>
|
||||
<span class="line" id="L161"> <span class="tok-kw">return</span> fio.fiobj_float_new(value);</span>
|
||||
<span class="line" id="L162"> },</span>
|
||||
<span class="line" id="L163"> .Int, .ComptimeInt => {</span>
|
||||
<span class="line" id="L164"> <span class="tok-kw">return</span> fio.fiobj_num_new_bignum(value);</span>
|
||||
<span class="line" id="L165"> },</span>
|
||||
<span class="line" id="L166"> .Bool => {</span>
|
||||
<span class="line" id="L167"> <span class="tok-kw">return</span> <span class="tok-kw">if</span> (value) fio.fiobj_true() <span class="tok-kw">else</span> fio.fiobj_false();</span>
|
||||
<span class="line" id="L168"> },</span>
|
||||
<span class="line" id="L169"> .Null => {</span>
|
||||
<span class="line" id="L170"> <span class="tok-kw">return</span> <span class="tok-number">0</span>;</span>
|
||||
<span class="line" id="L171"> },</span>
|
||||
<span class="line" id="L172"> .Optional => {</span>
|
||||
<span class="line" id="L173"> <span class="tok-kw">if</span> (value) |payload| {</span>
|
||||
<span class="line" id="L174"> <span class="tok-kw">return</span> fiobjectify(payload);</span>
|
||||
<span class="line" id="L175"> } <span class="tok-kw">else</span> {</span>
|
||||
<span class="line" id="L176"> <span class="tok-kw">return</span> fiobjectify(<span class="tok-null">null</span>);</span>
|
||||
<span class="line" id="L177"> }</span>
|
||||
<span class="line" id="L178"> },</span>
|
||||
<span class="line" id="L179"> .Enum => {</span>
|
||||
<span class="line" id="L180"> <span class="tok-kw">return</span> fio.fiobj_num_new_bignum(<span class="tok-builtin">@intFromEnum</span>(value));</span>
|
||||
<span class="line" id="L181"> },</span>
|
||||
<span class="line" id="L182"> .Union => {</span>
|
||||
<span class="line" id="L183"> <span class="tok-kw">const</span> info = <span class="tok-builtin">@typeInfo</span>(T).Union;</span>
|
||||
<span class="line" id="L184"> <span class="tok-kw">if</span> (info.tag_type) |UnionTagType| {</span>
|
||||
<span class="line" id="L185"> <span class="tok-kw">inline</span> <span class="tok-kw">for</span> (info.fields) |u_field| {</span>
|
||||
<span class="line" id="L186"> <span class="tok-kw">if</span> (value == <span class="tok-builtin">@field</span>(UnionTagType, u_field.name)) {</span>
|
||||
<span class="line" id="L187"> <span class="tok-kw">return</span> fiobjectify(<span class="tok-builtin">@field</span>(value, u_field.name));</span>
|
||||
<span class="line" id="L188"> }</span>
|
||||
<span class="line" id="L189"> }</span>
|
||||
<span class="line" id="L190"> } <span class="tok-kw">else</span> {</span>
|
||||
<span class="line" id="L191"> <span class="tok-builtin">@compileError</span>(<span class="tok-str">"Unable to fiobjectify untagged union '"</span> ++ <span class="tok-builtin">@typeName</span>(T) ++ <span class="tok-str">"'"</span>);</span>
|
||||
<span class="line" id="L192"> }</span>
|
||||
<span class="line" id="L193"> },</span>
|
||||
<span class="line" id="L194"> .Struct => |S| {</span>
|
||||
<span class="line" id="L195"> <span class="tok-comment">// create a new fio hashmap</span>
|
||||
</span>
|
||||
<span class="line" id="L196"> <span class="tok-kw">const</span> m = fio.fiobj_hash_new();</span>
|
||||
<span class="line" id="L197"> <span class="tok-comment">// std.debug.print("new struct\n", .{});</span>
|
||||
</span>
|
||||
<span class="line" id="L198"> <span class="tok-kw">inline</span> <span class="tok-kw">for</span> (S.fields) |Field| {</span>
|
||||
<span class="line" id="L199"> <span class="tok-comment">// don't include void fields</span>
|
||||
</span>
|
||||
<span class="line" id="L200"> <span class="tok-kw">if</span> (Field.<span class="tok-type">type</span> == <span class="tok-type">void</span>) <span class="tok-kw">continue</span>;</span>
|
||||
<span class="line" id="L201"></span>
|
||||
<span class="line" id="L202"> <span class="tok-comment">// std.debug.print(" new field: {s}\n", .{Field.name});</span>
|
||||
</span>
|
||||
<span class="line" id="L203"> <span class="tok-kw">const</span> fname = fio.fiobj_str_new(util.toCharPtr(Field.name), Field.name.len);</span>
|
||||
<span class="line" id="L204"> <span class="tok-comment">// std.debug.print(" fiobj name : {any}\n", .{fname});</span>
|
||||
</span>
|
||||
<span class="line" id="L205"> <span class="tok-kw">const</span> v = <span class="tok-builtin">@field</span>(value, Field.name);</span>
|
||||
<span class="line" id="L206"> <span class="tok-comment">// std.debug.print(" value: {any}\n", .{v});</span>
|
||||
</span>
|
||||
<span class="line" id="L207"> <span class="tok-kw">const</span> fvalue = fiobjectify(v);</span>
|
||||
<span class="line" id="L208"> <span class="tok-comment">// std.debug.print(" fiobj value: {any}\n", .{fvalue});</span>
|
||||
</span>
|
||||
<span class="line" id="L209"> _ = fio.fiobj_hash_set(m, fname, fvalue);</span>
|
||||
<span class="line" id="L210"> fio.fiobj_free_wrapped(fname);</span>
|
||||
<span class="line" id="L211"> }</span>
|
||||
<span class="line" id="L212"> <span class="tok-kw">return</span> m;</span>
|
||||
<span class="line" id="L213"> },</span>
|
||||
<span class="line" id="L214"> .ErrorSet => <span class="tok-kw">return</span> fiobjectify(<span class="tok-builtin">@as</span>([]<span class="tok-kw">const</span> <span class="tok-type">u8</span>, <span class="tok-builtin">@errorName</span>(value))),</span>
|
||||
<span class="line" id="L215"> .Pointer => |ptr_info| <span class="tok-kw">switch</span> (ptr_info.size) {</span>
|
||||
<span class="line" id="L216"> .One => <span class="tok-kw">switch</span> (<span class="tok-builtin">@typeInfo</span>(ptr_info.child)) {</span>
|
||||
<span class="line" id="L217"> .Array => {</span>
|
||||
<span class="line" id="L218"> <span class="tok-kw">const</span> Slice = []<span class="tok-kw">const</span> std.meta.Elem(ptr_info.child);</span>
|
||||
<span class="line" id="L219"> <span class="tok-kw">return</span> fiobjectify(<span class="tok-builtin">@as</span>(Slice, value));</span>
|
||||
<span class="line" id="L220"> },</span>
|
||||
<span class="line" id="L221"> <span class="tok-kw">else</span> => {</span>
|
||||
<span class="line" id="L222"> <span class="tok-comment">// TODO: avoid loops?</span>
|
||||
</span>
|
||||
<span class="line" id="L223"> <span class="tok-kw">return</span> fiobjectify(value.*);</span>
|
||||
<span class="line" id="L224"> },</span>
|
||||
<span class="line" id="L225"> },</span>
|
||||
<span class="line" id="L226"> <span class="tok-comment">// TODO: .Many when there is a sentinel (waiting for https://github.com/ziglang/zig/pull/3972)</span>
|
||||
</span>
|
||||
<span class="line" id="L227"> .Slice => {</span>
|
||||
<span class="line" id="L228"> <span class="tok-comment">// std.debug.print("new slice\n", .{});</span>
|
||||
</span>
|
||||
<span class="line" id="L229"> <span class="tok-kw">if</span> (ptr_info.child == <span class="tok-type">u8</span> <span class="tok-kw">and</span> std.unicode.utf8ValidateSlice(value)) {</span>
|
||||
<span class="line" id="L230"> <span class="tok-kw">return</span> fio.fiobj_str_new(util.toCharPtr(value), value.len);</span>
|
||||
<span class="line" id="L231"> }</span>
|
||||
<span class="line" id="L232"></span>
|
||||
<span class="line" id="L233"> <span class="tok-kw">const</span> arr = fio.fiobj_ary_new2(value.len);</span>
|
||||
<span class="line" id="L234"> <span class="tok-kw">for</span> (value) |x| {</span>
|
||||
<span class="line" id="L235"> <span class="tok-kw">const</span> v = fiobjectify(x);</span>
|
||||
<span class="line" id="L236"> fio.fiobj_ary_push(arr, v);</span>
|
||||
<span class="line" id="L237"> }</span>
|
||||
<span class="line" id="L238"> <span class="tok-kw">return</span> arr;</span>
|
||||
<span class="line" id="L239"> },</span>
|
||||
<span class="line" id="L240"> <span class="tok-kw">else</span> => <span class="tok-builtin">@compileError</span>(<span class="tok-str">"Unable to fiobjectify type '"</span> ++ <span class="tok-builtin">@typeName</span>(T) ++ <span class="tok-str">"'"</span>),</span>
|
||||
<span class="line" id="L241"> },</span>
|
||||
<span class="line" id="L242"> .Array => <span class="tok-kw">return</span> fiobjectify(&value),</span>
|
||||
<span class="line" id="L243"> .Vector => |info| {</span>
|
||||
<span class="line" id="L244"> <span class="tok-kw">const</span> array: [info.len]info.child = value;</span>
|
||||
<span class="line" id="L245"> <span class="tok-kw">return</span> fiobjectify(&array);</span>
|
||||
<span class="line" id="L246"> },</span>
|
||||
<span class="line" id="L247"> <span class="tok-kw">else</span> => <span class="tok-builtin">@compileError</span>(<span class="tok-str">"Unable to fiobjectify type '"</span> ++ <span class="tok-builtin">@typeName</span>(T) ++ <span class="tok-str">"'"</span>),</span>
|
||||
<span class="line" id="L248"> }</span>
|
||||
<span class="line" id="L249"> <span class="tok-kw">unreachable</span>;</span>
|
||||
<span class="line" id="L250">}</span>
|
||||
<span class="line" id="L251"></span>
|
||||
</code></pre></body>
|
||||
</html>
|
|
@ -1,942 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>request.zig - source view</title>
|
||||
<link rel="icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAgklEQVR4AWMYWuD7EllJIM4G4g4g5oIJ/odhOJ8wToOxSTXgNxDHoeiBMfA4+wGShjyYOCkG/IGqWQziEzYAoUAeiF9D5U+DxEg14DRU7jWIT5IBIOdCxf+A+CQZAAoopEB7QJwBCBwHiip8UYmRdrAlDpIMgApwQZNnNii5Dq0MBgCxxycBnwEd+wAAAABJRU5ErkJggg==">
|
||||
<link rel="icon" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNTMgMTQwIj48ZyBmaWxsPSIjRjdBNDFEIj48Zz48cG9seWdvbiBwb2ludHM9IjQ2LDIyIDI4LDQ0IDE5LDMwIi8+PHBvbHlnb24gcG9pbnRzPSI0NiwyMiAzMywzMyAyOCw0NCAyMiw0NCAyMiw5NSAzMSw5NSAyMCwxMDAgMTIsMTE3IDAsMTE3IDAsMjIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMzEsOTUgMTIsMTE3IDQsMTA2Ii8+PC9nPjxnPjxwb2x5Z29uIHBvaW50cz0iNTYsMjIgNjIsMzYgMzcsNDQiLz48cG9seWdvbiBwb2ludHM9IjU2LDIyIDExMSwyMiAxMTEsNDQgMzcsNDQgNTYsMzIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTE2LDk1IDk3LDExNyA5MCwxMDQiLz48cG9seWdvbiBwb2ludHM9IjExNiw5NSAxMDAsMTA0IDk3LDExNyA0MiwxMTcgNDIsOTUiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTUwLDAgNTIsMTE3IDMsMTQwIDEwMSwyMiIvPjwvZz48Zz48cG9seWdvbiBwb2ludHM9IjE0MSwyMiAxNDAsNDAgMTIyLDQ1Ii8+PHBvbHlnb24gcG9pbnRzPSIxNTMsMjIgMTUzLDExNyAxMDYsMTE3IDEyMCwxMDUgMTI1LDk1IDEzMSw5NSAxMzEsNDUgMTIyLDQ1IDEzMiwzNiAxNDEsMjIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTI1LDk1IDEzMCwxMTAgMTA2LDExNyIvPjwvZz48L2c+PC9zdmc+">
|
||||
<style>
|
||||
body{
|
||||
font-family: system-ui, -apple-system, Roboto, "Segoe UI", sans-serif;
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
pre > code {
|
||||
display: block;
|
||||
overflow: auto;
|
||||
line-height: normal;
|
||||
margin: 0em;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-str {
|
||||
color: #d14;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #005C7A;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #545454;
|
||||
font-style: italic;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #900;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-null {
|
||||
color: #005C5C;
|
||||
}
|
||||
.tok-number {
|
||||
color: #005C5C;
|
||||
}
|
||||
.tok-type {
|
||||
color: #458;
|
||||
font-weight: bold;
|
||||
}
|
||||
pre {
|
||||
counter-reset: line;
|
||||
}
|
||||
pre .line:before {
|
||||
counter-increment: line;
|
||||
content: counter(line);
|
||||
display: inline-block;
|
||||
padding-right: 1em;
|
||||
width: 2em;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.line {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
.line:target {
|
||||
border-top: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ccc;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body{
|
||||
background:#222;
|
||||
color: #ccc;
|
||||
}
|
||||
pre > code {
|
||||
color: #ccc;
|
||||
background: #222;
|
||||
border: unset;
|
||||
}
|
||||
.line:target {
|
||||
border-top: 1px solid #444;
|
||||
border-bottom: 1px solid #444;
|
||||
background: #333;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #eee;
|
||||
}
|
||||
.tok-str {
|
||||
color: #2e5;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #ff894c;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #aa7;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #B1A0F8;
|
||||
}
|
||||
.tok-null {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-number {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-type {
|
||||
color: #68f;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre><code><span class="line" id="L1"><span class="tok-kw">const</span> std = <span class="tok-builtin">@import</span>(<span class="tok-str">"std"</span>);</span>
|
||||
<span class="line" id="L2"><span class="tok-kw">const</span> Log = <span class="tok-builtin">@import</span>(<span class="tok-str">"log.zig"</span>);</span>
|
||||
<span class="line" id="L3"><span class="tok-kw">const</span> http = <span class="tok-builtin">@import</span>(<span class="tok-str">"http.zig"</span>);</span>
|
||||
<span class="line" id="L4"><span class="tok-kw">const</span> fio = <span class="tok-builtin">@import</span>(<span class="tok-str">"fio.zig"</span>);</span>
|
||||
<span class="line" id="L5"></span>
|
||||
<span class="line" id="L6"><span class="tok-kw">const</span> util = <span class="tok-builtin">@import</span>(<span class="tok-str">"util.zig"</span>);</span>
|
||||
<span class="line" id="L7"><span class="tok-kw">const</span> zap = <span class="tok-builtin">@import</span>(<span class="tok-str">"zap.zig"</span>);</span>
|
||||
<span class="line" id="L8"></span>
|
||||
<span class="line" id="L9"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> HttpError = <span class="tok-kw">error</span>{</span>
|
||||
<span class="line" id="L10"> HttpSendBody,</span>
|
||||
<span class="line" id="L11"> HttpSetContentType,</span>
|
||||
<span class="line" id="L12"> HttpSetHeader,</span>
|
||||
<span class="line" id="L13"> HttpParseBody,</span>
|
||||
<span class="line" id="L14"> HttpIterParams,</span>
|
||||
<span class="line" id="L15"> SetCookie,</span>
|
||||
<span class="line" id="L16"> SendFile,</span>
|
||||
<span class="line" id="L17">};</span>
|
||||
<span class="line" id="L18"></span>
|
||||
<span class="line" id="L19"><span class="tok-comment">/// Http Content Type enum.</span></span>
|
||||
<span class="line" id="L20"><span class="tok-comment">/// Needs some love.</span></span>
|
||||
<span class="line" id="L21"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> ContentType = <span class="tok-kw">enum</span> {</span>
|
||||
<span class="line" id="L22"> TEXT,</span>
|
||||
<span class="line" id="L23"> HTML,</span>
|
||||
<span class="line" id="L24"> JSON,</span>
|
||||
<span class="line" id="L25"> <span class="tok-comment">// TODO: more content types</span>
|
||||
</span>
|
||||
<span class="line" id="L26">};</span>
|
||||
<span class="line" id="L27"></span>
|
||||
<span class="line" id="L28"><span class="tok-comment">/// Key value pair of strings from HTTP parameters</span></span>
|
||||
<span class="line" id="L29"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> HttpParamStrKV = <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L30"> key: util.FreeOrNot,</span>
|
||||
<span class="line" id="L31"> value: util.FreeOrNot,</span>
|
||||
<span class="line" id="L32"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">deinit</span>(self: *<span class="tok-builtin">@This</span>()) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L33"> self.key.deinit();</span>
|
||||
<span class="line" id="L34"> self.value.deinit();</span>
|
||||
<span class="line" id="L35"> }</span>
|
||||
<span class="line" id="L36">};</span>
|
||||
<span class="line" id="L37"></span>
|
||||
<span class="line" id="L38"><span class="tok-comment">/// List of key value pairs of Http param strings.</span></span>
|
||||
<span class="line" id="L39"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> HttpParamStrKVList = <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L40"> items: []HttpParamStrKV,</span>
|
||||
<span class="line" id="L41"> allocator: std.mem.Allocator,</span>
|
||||
<span class="line" id="L42"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">deinit</span>(self: *<span class="tok-builtin">@This</span>()) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L43"> <span class="tok-kw">for</span> (self.items) |*item| {</span>
|
||||
<span class="line" id="L44"> item.deinit();</span>
|
||||
<span class="line" id="L45"> }</span>
|
||||
<span class="line" id="L46"> self.allocator.free(self.items);</span>
|
||||
<span class="line" id="L47"> }</span>
|
||||
<span class="line" id="L48">};</span>
|
||||
<span class="line" id="L49"></span>
|
||||
<span class="line" id="L50"><span class="tok-comment">/// List of key value pairs of Http params (might be of different types).</span></span>
|
||||
<span class="line" id="L51"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> HttpParamKVList = <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L52"> items: []HttpParamKV,</span>
|
||||
<span class="line" id="L53"> allocator: std.mem.Allocator,</span>
|
||||
<span class="line" id="L54"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">deinit</span>(self: *<span class="tok-kw">const</span> <span class="tok-builtin">@This</span>()) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L55"> <span class="tok-kw">for</span> (self.items) |*item| {</span>
|
||||
<span class="line" id="L56"> item.deinit();</span>
|
||||
<span class="line" id="L57"> }</span>
|
||||
<span class="line" id="L58"> self.allocator.free(self.items);</span>
|
||||
<span class="line" id="L59"> }</span>
|
||||
<span class="line" id="L60">};</span>
|
||||
<span class="line" id="L61"></span>
|
||||
<span class="line" id="L62"><span class="tok-comment">/// Enum for HttpParam tagged union</span></span>
|
||||
<span class="line" id="L63"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> HttpParamValueType = <span class="tok-kw">enum</span> {</span>
|
||||
<span class="line" id="L64"> <span class="tok-comment">// Null,</span>
|
||||
</span>
|
||||
<span class="line" id="L65"> Bool,</span>
|
||||
<span class="line" id="L66"> Int,</span>
|
||||
<span class="line" id="L67"> Float,</span>
|
||||
<span class="line" id="L68"> String,</span>
|
||||
<span class="line" id="L69"> Unsupported,</span>
|
||||
<span class="line" id="L70"> Hash_Binfile,</span>
|
||||
<span class="line" id="L71"> Array_Binfile,</span>
|
||||
<span class="line" id="L72">};</span>
|
||||
<span class="line" id="L73"></span>
|
||||
<span class="line" id="L74"><span class="tok-comment">/// Tagged union holding a typed Http param</span></span>
|
||||
<span class="line" id="L75"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> HttpParam = <span class="tok-kw">union</span>(HttpParamValueType) {</span>
|
||||
<span class="line" id="L76"> Bool: <span class="tok-type">bool</span>,</span>
|
||||
<span class="line" id="L77"> Int: <span class="tok-type">isize</span>,</span>
|
||||
<span class="line" id="L78"> Float: <span class="tok-type">f64</span>,</span>
|
||||
<span class="line" id="L79"> <span class="tok-comment">/// we don't do writable strings here</span></span>
|
||||
<span class="line" id="L80"> String: util.FreeOrNot,</span>
|
||||
<span class="line" id="L81"> <span class="tok-comment">/// value will always be null</span></span>
|
||||
<span class="line" id="L82"> Unsupported: ?<span class="tok-type">void</span>,</span>
|
||||
<span class="line" id="L83"> <span class="tok-comment">/// we assume hashes are because of file transmissions</span></span>
|
||||
<span class="line" id="L84"> Hash_Binfile: HttpParamBinaryFile,</span>
|
||||
<span class="line" id="L85"> <span class="tok-comment">/// value will always be null</span></span>
|
||||
<span class="line" id="L86"> Array_Binfile: std.ArrayList(HttpParamBinaryFile),</span>
|
||||
<span class="line" id="L87">};</span>
|
||||
<span class="line" id="L88"></span>
|
||||
<span class="line" id="L89"><span class="tok-comment">/// Key value pair of one typed Http param</span></span>
|
||||
<span class="line" id="L90"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> HttpParamKV = <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L91"> key: util.FreeOrNot,</span>
|
||||
<span class="line" id="L92"> value: ?HttpParam,</span>
|
||||
<span class="line" id="L93"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">deinit</span>(self: *<span class="tok-builtin">@This</span>()) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L94"> self.key.deinit();</span>
|
||||
<span class="line" id="L95"> <span class="tok-kw">if</span> (self.value) |p| {</span>
|
||||
<span class="line" id="L96"> <span class="tok-kw">switch</span> (p) {</span>
|
||||
<span class="line" id="L97"> .String => |*s| s.deinit(),</span>
|
||||
<span class="line" id="L98"> <span class="tok-kw">else</span> => {},</span>
|
||||
<span class="line" id="L99"> }</span>
|
||||
<span class="line" id="L100"> }</span>
|
||||
<span class="line" id="L101"> }</span>
|
||||
<span class="line" id="L102">};</span>
|
||||
<span class="line" id="L103"></span>
|
||||
<span class="line" id="L104"><span class="tok-comment">/// Struct representing an uploaded file.</span></span>
|
||||
<span class="line" id="L105"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> HttpParamBinaryFile = <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L106"> <span class="tok-comment">/// file contents</span></span>
|
||||
<span class="line" id="L107"> data: ?[]<span class="tok-kw">const</span> <span class="tok-type">u8</span> = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L108"> <span class="tok-comment">/// mimetype</span></span>
|
||||
<span class="line" id="L109"> mimetype: ?[]<span class="tok-kw">const</span> <span class="tok-type">u8</span> = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L110"> <span class="tok-comment">/// filename</span></span>
|
||||
<span class="line" id="L111"> filename: ?[]<span class="tok-kw">const</span> <span class="tok-type">u8</span> = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L112"></span>
|
||||
<span class="line" id="L113"> <span class="tok-comment">/// format function for printing file upload data</span></span>
|
||||
<span class="line" id="L114"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">format</span>(value: <span class="tok-builtin">@This</span>(), <span class="tok-kw">comptime</span> _: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>, _: std.fmt.FormatOptions, writer: <span class="tok-kw">anytype</span>) !<span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L115"> <span class="tok-kw">const</span> d = value.data <span class="tok-kw">orelse</span> <span class="tok-str">"\\0"</span>;</span>
|
||||
<span class="line" id="L116"> <span class="tok-kw">const</span> m = value.mimetype <span class="tok-kw">orelse</span> <span class="tok-str">"null"</span>;</span>
|
||||
<span class="line" id="L117"> <span class="tok-kw">const</span> f = value.filename <span class="tok-kw">orelse</span> <span class="tok-str">"null"</span>;</span>
|
||||
<span class="line" id="L118"> <span class="tok-kw">return</span> writer.print(<span class="tok-str">"<{s} ({s}): {any}>"</span>, .{ f, m, d });</span>
|
||||
<span class="line" id="L119"> }</span>
|
||||
<span class="line" id="L120">};</span>
|
||||
<span class="line" id="L121"></span>
|
||||
<span class="line" id="L122"><span class="tok-kw">fn</span> <span class="tok-fn">parseBinfilesFrom</span>(a: std.mem.Allocator, o: fio.FIOBJ) !HttpParam {</span>
|
||||
<span class="line" id="L123"> <span class="tok-kw">const</span> key_name = fio.fiobj_str_new(<span class="tok-str">"name"</span>, <span class="tok-number">4</span>);</span>
|
||||
<span class="line" id="L124"> <span class="tok-kw">const</span> key_data = fio.fiobj_str_new(<span class="tok-str">"data"</span>, <span class="tok-number">4</span>);</span>
|
||||
<span class="line" id="L125"> <span class="tok-kw">const</span> key_type = fio.fiobj_str_new(<span class="tok-str">"type"</span>, <span class="tok-number">4</span>);</span>
|
||||
<span class="line" id="L126"> <span class="tok-kw">defer</span> {</span>
|
||||
<span class="line" id="L127"> fio.fiobj_free_wrapped(key_name);</span>
|
||||
<span class="line" id="L128"> fio.fiobj_free_wrapped(key_data);</span>
|
||||
<span class="line" id="L129"> fio.fiobj_free_wrapped(key_type);</span>
|
||||
<span class="line" id="L130"> } <span class="tok-comment">// files: they should have "data", "type", and "filename" keys</span>
|
||||
</span>
|
||||
<span class="line" id="L131"> <span class="tok-kw">if</span> (fio.fiobj_hash_haskey(o, key_data) == <span class="tok-number">1</span> <span class="tok-kw">and</span> fio.fiobj_hash_haskey(o, key_type) == <span class="tok-number">1</span> <span class="tok-kw">and</span> fio.fiobj_hash_haskey(o, key_name) == <span class="tok-number">1</span>) {</span>
|
||||
<span class="line" id="L132"> <span class="tok-kw">const</span> filename = fio.fiobj_obj2cstr(fio.fiobj_hash_get(o, key_name));</span>
|
||||
<span class="line" id="L133"> <span class="tok-kw">const</span> mimetype = fio.fiobj_obj2cstr(fio.fiobj_hash_get(o, key_type));</span>
|
||||
<span class="line" id="L134"> <span class="tok-kw">const</span> data = fio.fiobj_hash_get(o, key_data);</span>
|
||||
<span class="line" id="L135"></span>
|
||||
<span class="line" id="L136"> <span class="tok-kw">var</span> data_slice: ?[]<span class="tok-kw">const</span> <span class="tok-type">u8</span> = <span class="tok-null">null</span>;</span>
|
||||
<span class="line" id="L137"></span>
|
||||
<span class="line" id="L138"> <span class="tok-kw">switch</span> (fio.fiobj_type(data)) {</span>
|
||||
<span class="line" id="L139"> fio.FIOBJ_T_DATA => {</span>
|
||||
<span class="line" id="L140"> <span class="tok-kw">if</span> (fio.is_invalid(data) == <span class="tok-number">1</span>) {</span>
|
||||
<span class="line" id="L141"> data_slice = <span class="tok-str">"(zap: invalid data)"</span>;</span>
|
||||
<span class="line" id="L142"> std.log.warn(<span class="tok-str">"WARNING: HTTP param binary file is not a data object\n"</span>, .{});</span>
|
||||
<span class="line" id="L143"> } <span class="tok-kw">else</span> {</span>
|
||||
<span class="line" id="L144"> <span class="tok-comment">// the data</span>
|
||||
</span>
|
||||
<span class="line" id="L145"> <span class="tok-kw">const</span> data_len = fio.fiobj_data_len(data);</span>
|
||||
<span class="line" id="L146"> <span class="tok-kw">var</span> data_buf = fio.fiobj_data_read(data, data_len);</span>
|
||||
<span class="line" id="L147"></span>
|
||||
<span class="line" id="L148"> <span class="tok-kw">if</span> (data_len < <span class="tok-number">0</span>) {</span>
|
||||
<span class="line" id="L149"> std.log.warn(<span class="tok-str">"WARNING: HTTP param binary file size negative: {d}\n"</span>, .{data_len});</span>
|
||||
<span class="line" id="L150"> std.log.warn(<span class="tok-str">"FIOBJ_TYPE of data is: {d}\n"</span>, .{fio.fiobj_type(data)});</span>
|
||||
<span class="line" id="L151"> } <span class="tok-kw">else</span> {</span>
|
||||
<span class="line" id="L152"> <span class="tok-kw">if</span> (data_buf.len != data_len) {</span>
|
||||
<span class="line" id="L153"> std.log.warn(<span class="tok-str">"WARNING: HTTP param binary file size mismatch: should {d}, is: {d}\n"</span>, .{ data_len, data_buf.len });</span>
|
||||
<span class="line" id="L154"> }</span>
|
||||
<span class="line" id="L155"></span>
|
||||
<span class="line" id="L156"> <span class="tok-kw">if</span> (data_buf.len > <span class="tok-number">0</span>) {</span>
|
||||
<span class="line" id="L157"> data_slice = data_buf.data[<span class="tok-number">0</span>..data_buf.len];</span>
|
||||
<span class="line" id="L158"> } <span class="tok-kw">else</span> {</span>
|
||||
<span class="line" id="L159"> std.log.warn(<span class="tok-str">"WARNING: HTTP param binary file buffer size negative: {d}\n"</span>, .{data_buf.len});</span>
|
||||
<span class="line" id="L160"> data_slice = <span class="tok-str">"(zap: invalid data: negative BUFFER size)"</span>;</span>
|
||||
<span class="line" id="L161"> }</span>
|
||||
<span class="line" id="L162"> }</span>
|
||||
<span class="line" id="L163"> }</span>
|
||||
<span class="line" id="L164"> },</span>
|
||||
<span class="line" id="L165"> fio.FIOBJ_T_STRING => {</span>
|
||||
<span class="line" id="L166"> <span class="tok-kw">const</span> fiostr = fio.fiobj_obj2cstr(data);</span>
|
||||
<span class="line" id="L167"> <span class="tok-kw">if</span> (fiostr.len == <span class="tok-number">0</span>) {</span>
|
||||
<span class="line" id="L168"> data_slice = <span class="tok-str">"(zap: empty string data)"</span>;</span>
|
||||
<span class="line" id="L169"> std.log.warn(<span class="tok-str">"WARNING: HTTP param binary file has empty string object\n"</span>, .{});</span>
|
||||
<span class="line" id="L170"> } <span class="tok-kw">else</span> {</span>
|
||||
<span class="line" id="L171"> data_slice = fiostr.data[<span class="tok-number">0</span>..fiostr.len];</span>
|
||||
<span class="line" id="L172"> }</span>
|
||||
<span class="line" id="L173"> },</span>
|
||||
<span class="line" id="L174"> fio.FIOBJ_T_ARRAY => {</span>
|
||||
<span class="line" id="L175"> <span class="tok-comment">// OK, data is an array</span>
|
||||
</span>
|
||||
<span class="line" id="L176"> <span class="tok-kw">const</span> len = fio.fiobj_ary_count(data);</span>
|
||||
<span class="line" id="L177"> <span class="tok-kw">const</span> fn_ary = fio.fiobj_hash_get(o, key_name);</span>
|
||||
<span class="line" id="L178"> <span class="tok-kw">const</span> mt_ary = fio.fiobj_hash_get(o, key_type);</span>
|
||||
<span class="line" id="L179"></span>
|
||||
<span class="line" id="L180"> <span class="tok-kw">if</span> (fio.fiobj_ary_count(fn_ary) == len <span class="tok-kw">and</span> fio.fiobj_ary_count(mt_ary) == len) {</span>
|
||||
<span class="line" id="L181"> <span class="tok-kw">var</span> i: <span class="tok-type">isize</span> = <span class="tok-number">0</span>;</span>
|
||||
<span class="line" id="L182"> <span class="tok-kw">var</span> ret = std.ArrayList(HttpParamBinaryFile).init(a);</span>
|
||||
<span class="line" id="L183"> <span class="tok-kw">while</span> (i < len) : (i += <span class="tok-number">1</span>) {</span>
|
||||
<span class="line" id="L184"> <span class="tok-kw">const</span> file_data_obj = fio.fiobj_ary_entry(data, i);</span>
|
||||
<span class="line" id="L185"> <span class="tok-kw">const</span> file_name_obj = fio.fiobj_ary_entry(fn_ary, i);</span>
|
||||
<span class="line" id="L186"> <span class="tok-kw">const</span> file_mimetype_obj = fio.fiobj_ary_entry(mt_ary, i);</span>
|
||||
<span class="line" id="L187"> <span class="tok-kw">var</span> has_error: <span class="tok-type">bool</span> = <span class="tok-null">false</span>;</span>
|
||||
<span class="line" id="L188"> <span class="tok-kw">if</span> (fio.is_invalid(file_data_obj) == <span class="tok-number">1</span>) {</span>
|
||||
<span class="line" id="L189"> std.log.debug(<span class="tok-str">"file data invalid in array"</span>, .{});</span>
|
||||
<span class="line" id="L190"> has_error = <span class="tok-null">true</span>;</span>
|
||||
<span class="line" id="L191"> }</span>
|
||||
<span class="line" id="L192"> <span class="tok-kw">if</span> (fio.is_invalid(file_name_obj) == <span class="tok-number">1</span>) {</span>
|
||||
<span class="line" id="L193"> std.log.debug(<span class="tok-str">"file name invalid in array"</span>, .{});</span>
|
||||
<span class="line" id="L194"> has_error = <span class="tok-null">true</span>;</span>
|
||||
<span class="line" id="L195"> }</span>
|
||||
<span class="line" id="L196"> <span class="tok-kw">if</span> (fio.is_invalid(file_mimetype_obj) == <span class="tok-number">1</span>) {</span>
|
||||
<span class="line" id="L197"> std.log.debug(<span class="tok-str">"file mimetype invalid in array"</span>, .{});</span>
|
||||
<span class="line" id="L198"> has_error = <span class="tok-null">true</span>;</span>
|
||||
<span class="line" id="L199"> }</span>
|
||||
<span class="line" id="L200"> <span class="tok-kw">if</span> (has_error) {</span>
|
||||
<span class="line" id="L201"> <span class="tok-kw">return</span> <span class="tok-kw">error</span>.Invalid;</span>
|
||||
<span class="line" id="L202"> }</span>
|
||||
<span class="line" id="L203"></span>
|
||||
<span class="line" id="L204"> <span class="tok-kw">const</span> file_data = fio.fiobj_obj2cstr(file_data_obj);</span>
|
||||
<span class="line" id="L205"> <span class="tok-kw">const</span> file_name = fio.fiobj_obj2cstr(file_name_obj);</span>
|
||||
<span class="line" id="L206"> <span class="tok-kw">const</span> file_mimetype = fio.fiobj_obj2cstr(file_mimetype_obj);</span>
|
||||
<span class="line" id="L207"> <span class="tok-kw">try</span> ret.append(.{</span>
|
||||
<span class="line" id="L208"> .data = file_data.data[<span class="tok-number">0</span>..file_data.len],</span>
|
||||
<span class="line" id="L209"> .mimetype = file_mimetype.data[<span class="tok-number">0</span>..file_mimetype.len],</span>
|
||||
<span class="line" id="L210"> .filename = file_name.data[<span class="tok-number">0</span>..file_name.len],</span>
|
||||
<span class="line" id="L211"> });</span>
|
||||
<span class="line" id="L212"> }</span>
|
||||
<span class="line" id="L213"> <span class="tok-kw">return</span> .{ .Array_Binfile = ret };</span>
|
||||
<span class="line" id="L214"> } <span class="tok-kw">else</span> {</span>
|
||||
<span class="line" id="L215"> <span class="tok-kw">return</span> <span class="tok-kw">error</span>.ArrayLenMismatch;</span>
|
||||
<span class="line" id="L216"> }</span>
|
||||
<span class="line" id="L217"> },</span>
|
||||
<span class="line" id="L218"> <span class="tok-kw">else</span> => {</span>
|
||||
<span class="line" id="L219"> <span class="tok-comment">// don't know what to do</span>
|
||||
</span>
|
||||
<span class="line" id="L220"> <span class="tok-kw">return</span> <span class="tok-kw">error</span>.Unsupported;</span>
|
||||
<span class="line" id="L221"> },</span>
|
||||
<span class="line" id="L222"> }</span>
|
||||
<span class="line" id="L223"></span>
|
||||
<span class="line" id="L224"> <span class="tok-kw">return</span> .{ .Hash_Binfile = .{</span>
|
||||
<span class="line" id="L225"> .filename = filename.data[<span class="tok-number">0</span>..filename.len],</span>
|
||||
<span class="line" id="L226"> .mimetype = mimetype.data[<span class="tok-number">0</span>..mimetype.len],</span>
|
||||
<span class="line" id="L227"> .data = data_slice,</span>
|
||||
<span class="line" id="L228"> } };</span>
|
||||
<span class="line" id="L229"> } <span class="tok-kw">else</span> {</span>
|
||||
<span class="line" id="L230"> <span class="tok-kw">return</span> .{ .Hash_Binfile = .{} };</span>
|
||||
<span class="line" id="L231"> }</span>
|
||||
<span class="line" id="L232">}</span>
|
||||
<span class="line" id="L233"></span>
|
||||
<span class="line" id="L234"><span class="tok-comment">/// Parse FIO object into a typed Http param. Supports file uploads.</span></span>
|
||||
<span class="line" id="L235"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">Fiobj2HttpParam</span>(a: std.mem.Allocator, o: fio.FIOBJ, dupe_string: <span class="tok-type">bool</span>) !?HttpParam {</span>
|
||||
<span class="line" id="L236"> <span class="tok-kw">return</span> <span class="tok-kw">switch</span> (fio.fiobj_type(o)) {</span>
|
||||
<span class="line" id="L237"> fio.FIOBJ_T_NULL => <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L238"> fio.FIOBJ_T_TRUE => .{ .Bool = <span class="tok-null">true</span> },</span>
|
||||
<span class="line" id="L239"> fio.FIOBJ_T_FALSE => .{ .Bool = <span class="tok-null">false</span> },</span>
|
||||
<span class="line" id="L240"> fio.FIOBJ_T_NUMBER => .{ .Int = fio.fiobj_obj2num(o) },</span>
|
||||
<span class="line" id="L241"> fio.FIOBJ_T_FLOAT => .{ .Float = fio.fiobj_obj2float(o) },</span>
|
||||
<span class="line" id="L242"> fio.FIOBJ_T_STRING => .{ .String = <span class="tok-kw">try</span> util.fio2strAllocOrNot(a, o, dupe_string) },</span>
|
||||
<span class="line" id="L243"> fio.FIOBJ_T_ARRAY => {</span>
|
||||
<span class="line" id="L244"> <span class="tok-kw">return</span> .{ .Unsupported = <span class="tok-null">null</span> };</span>
|
||||
<span class="line" id="L245"> },</span>
|
||||
<span class="line" id="L246"> fio.FIOBJ_T_HASH => {</span>
|
||||
<span class="line" id="L247"> <span class="tok-kw">const</span> file = <span class="tok-kw">try</span> parseBinfilesFrom(a, o);</span>
|
||||
<span class="line" id="L248"> <span class="tok-kw">return</span> file;</span>
|
||||
<span class="line" id="L249"> },</span>
|
||||
<span class="line" id="L250"> <span class="tok-kw">else</span> => .{ .Unsupported = <span class="tok-null">null</span> },</span>
|
||||
<span class="line" id="L251"> };</span>
|
||||
<span class="line" id="L252">}</span>
|
||||
<span class="line" id="L253"></span>
|
||||
<span class="line" id="L254"><span class="tok-comment">/// Args for setting a cookie</span></span>
|
||||
<span class="line" id="L255"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> CookieArgs = <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L256"> name: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L257"> value: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L258"> domain: ?[]<span class="tok-kw">const</span> <span class="tok-type">u8</span> = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L259"> path: ?[]<span class="tok-kw">const</span> <span class="tok-type">u8</span> = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L260"> <span class="tok-comment">/// max age in seconds. 0 -> session</span></span>
|
||||
<span class="line" id="L261"> max_age_s: <span class="tok-type">c_int</span> = <span class="tok-number">0</span>,</span>
|
||||
<span class="line" id="L262"> secure: <span class="tok-type">bool</span> = <span class="tok-null">true</span>,</span>
|
||||
<span class="line" id="L263"> http_only: <span class="tok-type">bool</span> = <span class="tok-null">true</span>,</span>
|
||||
<span class="line" id="L264">};</span>
|
||||
<span class="line" id="L265"></span>
|
||||
<span class="line" id="L266">path: ?[]<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L267">query: ?[]<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L268">body: ?[]<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L269">method: ?[]<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L270">h: [*c]fio.http_s,</span>
|
||||
<span class="line" id="L271"></span>
|
||||
<span class="line" id="L272"><span class="tok-comment">/// NEVER touch this field!!!!</span></span>
|
||||
<span class="line" id="L273"><span class="tok-comment">/// if you absolutely MUST, then you may provide context here</span></span>
|
||||
<span class="line" id="L274"><span class="tok-comment">/// via setUserContext and getUserContext</span></span>
|
||||
<span class="line" id="L275">_user_context: *UserContext,</span>
|
||||
<span class="line" id="L276"><span class="tok-comment">/// NEVER touch this field!!!!</span></span>
|
||||
<span class="line" id="L277"><span class="tok-comment">/// use markAsFinished() and isFinished() instead</span></span>
|
||||
<span class="line" id="L278"><span class="tok-comment">/// this is a hack: the listener will put a pointer to this into the udata</span></span>
|
||||
<span class="line" id="L279"><span class="tok-comment">/// field of `h`. So copies of the Request will all have way to the</span></span>
|
||||
<span class="line" id="L280"><span class="tok-comment">/// same instance of this field.</span></span>
|
||||
<span class="line" id="L281">_is_finished_request_global: <span class="tok-type">bool</span>,</span>
|
||||
<span class="line" id="L282"><span class="tok-comment">/// NEVER touch this field!!!!</span></span>
|
||||
<span class="line" id="L283"><span class="tok-comment">/// this is part of the hack.</span></span>
|
||||
<span class="line" id="L284">_is_finished: *<span class="tok-type">bool</span> = <span class="tok-null">undefined</span>,</span>
|
||||
<span class="line" id="L285"></span>
|
||||
<span class="line" id="L286"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> UserContext = <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L287"> user_context: ?*<span class="tok-type">anyopaque</span> = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L288">};</span>
|
||||
<span class="line" id="L289"></span>
|
||||
<span class="line" id="L290"><span class="tok-kw">const</span> Self = <span class="tok-builtin">@This</span>();</span>
|
||||
<span class="line" id="L291"></span>
|
||||
<span class="line" id="L292"><span class="tok-comment">/// mark the current request as finished. Important for middleware-style</span></span>
|
||||
<span class="line" id="L293"><span class="tok-comment">/// request handler chaining. Called when sending a body, redirecting, etc.</span></span>
|
||||
<span class="line" id="L294"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">markAsFinished</span>(self: *<span class="tok-kw">const</span> Self, finished: <span class="tok-type">bool</span>) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L295"> <span class="tok-comment">// we might be a copy</span>
|
||||
</span>
|
||||
<span class="line" id="L296"> self._is_finished.* = finished;</span>
|
||||
<span class="line" id="L297">}</span>
|
||||
<span class="line" id="L298"></span>
|
||||
<span class="line" id="L299"><span class="tok-comment">/// tell whether request processing has finished. (e.g. response sent,</span></span>
|
||||
<span class="line" id="L300"><span class="tok-comment">/// redirected, ...)</span></span>
|
||||
<span class="line" id="L301"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">isFinished</span>(self: *<span class="tok-kw">const</span> Self) <span class="tok-type">bool</span> {</span>
|
||||
<span class="line" id="L302"> <span class="tok-comment">// we might be a copy</span>
|
||||
</span>
|
||||
<span class="line" id="L303"> <span class="tok-kw">return</span> self._is_finished.*;</span>
|
||||
<span class="line" id="L304">}</span>
|
||||
<span class="line" id="L305"></span>
|
||||
<span class="line" id="L306"><span class="tok-comment">/// if you absolutely must, you can set any context on the request here</span></span>
|
||||
<span class="line" id="L307"><span class="tok-comment">// (note, this line is linked to from the readme) -- TODO: sync</span>
|
||||
</span>
|
||||
<span class="line" id="L308"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">setUserContext</span>(self: *<span class="tok-kw">const</span> Self, context: *<span class="tok-type">anyopaque</span>) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L309"> self._user_context.*.user_context = context;</span>
|
||||
<span class="line" id="L310">}</span>
|
||||
<span class="line" id="L311"></span>
|
||||
<span class="line" id="L312"><span class="tok-comment">/// get the associated user context of the request.</span></span>
|
||||
<span class="line" id="L313"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">getUserContext</span>(self: *<span class="tok-kw">const</span> Self, <span class="tok-kw">comptime</span> Context: <span class="tok-type">type</span>) ?*Context {</span>
|
||||
<span class="line" id="L314"> <span class="tok-kw">if</span> (self._user_context.*.user_context) |ptr| {</span>
|
||||
<span class="line" id="L315"> <span class="tok-kw">return</span> <span class="tok-builtin">@as</span>(*Context, <span class="tok-builtin">@ptrCast</span>(<span class="tok-builtin">@alignCast</span>(ptr)));</span>
|
||||
<span class="line" id="L316"> } <span class="tok-kw">else</span> {</span>
|
||||
<span class="line" id="L317"> <span class="tok-kw">return</span> <span class="tok-null">null</span>;</span>
|
||||
<span class="line" id="L318"> }</span>
|
||||
<span class="line" id="L319">}</span>
|
||||
<span class="line" id="L320"></span>
|
||||
<span class="line" id="L321"><span class="tok-comment">/// Tries to send an error stack trace.</span></span>
|
||||
<span class="line" id="L322"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">sendError</span>(self: *<span class="tok-kw">const</span> Self, err: <span class="tok-type">anyerror</span>, errorcode_num: <span class="tok-type">usize</span>) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L323"> <span class="tok-comment">// TODO: query accept headers</span>
|
||||
</span>
|
||||
<span class="line" id="L324"> <span class="tok-kw">if</span> (self._internal_sendError(err, errorcode_num)) {</span>
|
||||
<span class="line" id="L325"> <span class="tok-kw">return</span>;</span>
|
||||
<span class="line" id="L326"> } <span class="tok-kw">else</span> |_| {</span>
|
||||
<span class="line" id="L327"> self.sendBody(<span class="tok-builtin">@errorName</span>(err)) <span class="tok-kw">catch</span> <span class="tok-kw">return</span>;</span>
|
||||
<span class="line" id="L328"> }</span>
|
||||
<span class="line" id="L329">}</span>
|
||||
<span class="line" id="L330"></span>
|
||||
<span class="line" id="L331"><span class="tok-comment">/// Used internally. Probably does not need to be public.</span></span>
|
||||
<span class="line" id="L332"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">_internal_sendError</span>(self: *<span class="tok-kw">const</span> Self, err: <span class="tok-type">anyerror</span>, errorcode_num: <span class="tok-type">usize</span>) !<span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L333"> <span class="tok-comment">// TODO: query accept headers</span>
|
||||
</span>
|
||||
<span class="line" id="L334"> <span class="tok-comment">// TODO: let's hope 20k is enough. Maybe just really allocate here</span>
|
||||
</span>
|
||||
<span class="line" id="L335"> self.h.*.status = errorcode_num;</span>
|
||||
<span class="line" id="L336"> <span class="tok-kw">var</span> buf: [<span class="tok-number">20</span> * <span class="tok-number">1024</span>]<span class="tok-type">u8</span> = <span class="tok-null">undefined</span>;</span>
|
||||
<span class="line" id="L337"> <span class="tok-kw">var</span> fba = std.heap.FixedBufferAllocator.init(&buf);</span>
|
||||
<span class="line" id="L338"> <span class="tok-kw">var</span> string = std.ArrayList(<span class="tok-type">u8</span>).init(fba.allocator());</span>
|
||||
<span class="line" id="L339"> <span class="tok-kw">var</span> writer = string.writer();</span>
|
||||
<span class="line" id="L340"> <span class="tok-kw">try</span> writer.print(<span class="tok-str">"ERROR: {any}\n\n"</span>, .{err});</span>
|
||||
<span class="line" id="L341"></span>
|
||||
<span class="line" id="L342"> <span class="tok-kw">const</span> debugInfo = <span class="tok-kw">try</span> std.debug.getSelfDebugInfo();</span>
|
||||
<span class="line" id="L343"> <span class="tok-kw">const</span> ttyConfig: std.io.tty.Config = .no_color;</span>
|
||||
<span class="line" id="L344"> <span class="tok-kw">try</span> std.debug.writeCurrentStackTrace(writer, debugInfo, ttyConfig, <span class="tok-null">null</span>);</span>
|
||||
<span class="line" id="L345"> <span class="tok-kw">try</span> self.sendBody(string.items);</span>
|
||||
<span class="line" id="L346">}</span>
|
||||
<span class="line" id="L347"></span>
|
||||
<span class="line" id="L348"><span class="tok-comment">/// Send body.</span></span>
|
||||
<span class="line" id="L349"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">sendBody</span>(self: *<span class="tok-kw">const</span> Self, body: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>) HttpError!<span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L350"> <span class="tok-kw">const</span> ret = fio.http_send_body(self.h, <span class="tok-builtin">@as</span>(</span>
|
||||
<span class="line" id="L351"> *<span class="tok-type">anyopaque</span>,</span>
|
||||
<span class="line" id="L352"> <span class="tok-builtin">@ptrFromInt</span>(<span class="tok-builtin">@intFromPtr</span>(body.ptr)),</span>
|
||||
<span class="line" id="L353"> ), body.len);</span>
|
||||
<span class="line" id="L354"> zap.debug(<span class="tok-str">"Request.sendBody(): ret = {}\n"</span>, .{ret});</span>
|
||||
<span class="line" id="L355"> <span class="tok-kw">if</span> (ret == -<span class="tok-number">1</span>) <span class="tok-kw">return</span> <span class="tok-kw">error</span>.HttpSendBody;</span>
|
||||
<span class="line" id="L356"> self.markAsFinished(<span class="tok-null">true</span>);</span>
|
||||
<span class="line" id="L357">}</span>
|
||||
<span class="line" id="L358"></span>
|
||||
<span class="line" id="L359"><span class="tok-comment">/// Set content type and send json buffer.</span></span>
|
||||
<span class="line" id="L360"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">sendJson</span>(self: *<span class="tok-kw">const</span> Self, json: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>) HttpError!<span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L361"> <span class="tok-kw">if</span> (self.setContentType(.JSON)) {</span>
|
||||
<span class="line" id="L362"> <span class="tok-kw">if</span> (fio.http_send_body(self.h, <span class="tok-builtin">@as</span>(</span>
|
||||
<span class="line" id="L363"> *<span class="tok-type">anyopaque</span>,</span>
|
||||
<span class="line" id="L364"> <span class="tok-builtin">@ptrFromInt</span>(<span class="tok-builtin">@intFromPtr</span>(json.ptr)),</span>
|
||||
<span class="line" id="L365"> ), json.len) != <span class="tok-number">0</span>) <span class="tok-kw">return</span> <span class="tok-kw">error</span>.HttpSendBody;</span>
|
||||
<span class="line" id="L366"> self.markAsFinished(<span class="tok-null">true</span>);</span>
|
||||
<span class="line" id="L367"> } <span class="tok-kw">else</span> |err| <span class="tok-kw">return</span> err;</span>
|
||||
<span class="line" id="L368">}</span>
|
||||
<span class="line" id="L369"></span>
|
||||
<span class="line" id="L370"><span class="tok-comment">/// Set content type.</span></span>
|
||||
<span class="line" id="L371"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">setContentType</span>(self: *<span class="tok-kw">const</span> Self, c: ContentType) HttpError!<span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L372"> <span class="tok-kw">const</span> s = <span class="tok-kw">switch</span> (c) {</span>
|
||||
<span class="line" id="L373"> .TEXT => <span class="tok-str">"text/plain"</span>,</span>
|
||||
<span class="line" id="L374"> .JSON => <span class="tok-str">"application/json"</span>,</span>
|
||||
<span class="line" id="L375"> <span class="tok-kw">else</span> => <span class="tok-str">"text/html"</span>,</span>
|
||||
<span class="line" id="L376"> };</span>
|
||||
<span class="line" id="L377"> zap.debug(<span class="tok-str">"setting content-type to {s}\n"</span>, .{s});</span>
|
||||
<span class="line" id="L378"> <span class="tok-kw">return</span> self.setHeader(<span class="tok-str">"content-type"</span>, s);</span>
|
||||
<span class="line" id="L379">}</span>
|
||||
<span class="line" id="L380"></span>
|
||||
<span class="line" id="L381"><span class="tok-comment">/// redirect to path with status code 302 by default</span></span>
|
||||
<span class="line" id="L382"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">redirectTo</span>(self: *<span class="tok-kw">const</span> Self, path: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>, code: ?http.StatusCode) HttpError!<span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L383"> self.setStatus(<span class="tok-kw">if</span> (code) |status| status <span class="tok-kw">else</span> .found);</span>
|
||||
<span class="line" id="L384"> <span class="tok-kw">try</span> self.setHeader(<span class="tok-str">"Location"</span>, path);</span>
|
||||
<span class="line" id="L385"> <span class="tok-kw">try</span> self.sendBody(<span class="tok-str">"moved"</span>);</span>
|
||||
<span class="line" id="L386"> self.markAsFinished(<span class="tok-null">true</span>);</span>
|
||||
<span class="line" id="L387">}</span>
|
||||
<span class="line" id="L388"></span>
|
||||
<span class="line" id="L389"><span class="tok-comment">/// shows how to use the logger</span></span>
|
||||
<span class="line" id="L390"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">setContentTypeWithLogger</span>(</span>
|
||||
<span class="line" id="L391"> self: *<span class="tok-kw">const</span> Self,</span>
|
||||
<span class="line" id="L392"> c: ContentType,</span>
|
||||
<span class="line" id="L393"> logger: *<span class="tok-kw">const</span> Log,</span>
|
||||
<span class="line" id="L394">) HttpError!<span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L395"> <span class="tok-kw">const</span> s = <span class="tok-kw">switch</span> (c) {</span>
|
||||
<span class="line" id="L396"> .TEXT => <span class="tok-str">"text/plain"</span>,</span>
|
||||
<span class="line" id="L397"> .JSON => <span class="tok-str">"application/json"</span>,</span>
|
||||
<span class="line" id="L398"> <span class="tok-kw">else</span> => <span class="tok-str">"text/html"</span>,</span>
|
||||
<span class="line" id="L399"> };</span>
|
||||
<span class="line" id="L400"> logger.log(<span class="tok-str">"setting content-type to {s}\n"</span>, .{s});</span>
|
||||
<span class="line" id="L401"> <span class="tok-kw">return</span> self.setHeader(<span class="tok-str">"content-type"</span>, s);</span>
|
||||
<span class="line" id="L402">}</span>
|
||||
<span class="line" id="L403"></span>
|
||||
<span class="line" id="L404"><span class="tok-comment">/// Tries to determine the content type by file extension of request path, and sets it.</span></span>
|
||||
<span class="line" id="L405"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">setContentTypeFromPath</span>(self: *<span class="tok-kw">const</span> Self) !<span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L406"> <span class="tok-kw">const</span> t = fio.http_mimetype_find2(self.h.*.path);</span>
|
||||
<span class="line" id="L407"> <span class="tok-kw">if</span> (fio.is_invalid(t) == <span class="tok-number">1</span>) <span class="tok-kw">return</span> <span class="tok-kw">error</span>.HttpSetContentType;</span>
|
||||
<span class="line" id="L408"> <span class="tok-kw">const</span> ret = fio.fiobj_hash_set(</span>
|
||||
<span class="line" id="L409"> self.h.*.private_data.out_headers,</span>
|
||||
<span class="line" id="L410"> fio.HTTP_HEADER_CONTENT_TYPE,</span>
|
||||
<span class="line" id="L411"> t,</span>
|
||||
<span class="line" id="L412"> );</span>
|
||||
<span class="line" id="L413"> <span class="tok-kw">if</span> (ret == -<span class="tok-number">1</span>) <span class="tok-kw">return</span> <span class="tok-kw">error</span>.HttpSetContentType;</span>
|
||||
<span class="line" id="L414">}</span>
|
||||
<span class="line" id="L415"></span>
|
||||
<span class="line" id="L416"><span class="tok-comment">/// Tries to determine the content type by filename extension, and sets it.</span></span>
|
||||
<span class="line" id="L417"><span class="tok-comment">/// If the extension cannot be determined, NoExtensionInFilename error is</span></span>
|
||||
<span class="line" id="L418"><span class="tok-comment">/// returned.</span></span>
|
||||
<span class="line" id="L419"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">setContentTypeFromFilename</span>(self: *<span class="tok-kw">const</span> Self, filename: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>) !<span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L420"> <span class="tok-kw">const</span> ext = std.fs.path.extension(filename);</span>
|
||||
<span class="line" id="L421"></span>
|
||||
<span class="line" id="L422"> <span class="tok-kw">if</span> (ext.len > <span class="tok-number">1</span>) {</span>
|
||||
<span class="line" id="L423"> <span class="tok-kw">const</span> e = ext[<span class="tok-number">1</span>..];</span>
|
||||
<span class="line" id="L424"> <span class="tok-kw">const</span> obj = fio.http_mimetype_find(<span class="tok-builtin">@constCast</span>(e.ptr), e.len);</span>
|
||||
<span class="line" id="L425"></span>
|
||||
<span class="line" id="L426"> <span class="tok-kw">if</span> (util.fio2str(obj)) |mime_str| {</span>
|
||||
<span class="line" id="L427"> <span class="tok-kw">try</span> self.setHeader(<span class="tok-str">"content-type"</span>, mime_str);</span>
|
||||
<span class="line" id="L428"> }</span>
|
||||
<span class="line" id="L429"> } <span class="tok-kw">else</span> {</span>
|
||||
<span class="line" id="L430"> <span class="tok-kw">return</span> <span class="tok-kw">error</span>.NoExtensionInFilename;</span>
|
||||
<span class="line" id="L431"> }</span>
|
||||
<span class="line" id="L432">}</span>
|
||||
<span class="line" id="L433"></span>
|
||||
<span class="line" id="L434"><span class="tok-comment">/// Returns the header value of given key name. Returned mem is temp.</span></span>
|
||||
<span class="line" id="L435"><span class="tok-comment">/// Do not free it.</span></span>
|
||||
<span class="line" id="L436"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">getHeader</span>(self: *<span class="tok-kw">const</span> Self, name: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>) ?[]<span class="tok-kw">const</span> <span class="tok-type">u8</span> {</span>
|
||||
<span class="line" id="L437"> <span class="tok-kw">const</span> hname = fio.fiobj_str_new(util.toCharPtr(name), name.len);</span>
|
||||
<span class="line" id="L438"> <span class="tok-kw">defer</span> fio.fiobj_free_wrapped(hname);</span>
|
||||
<span class="line" id="L439"> <span class="tok-kw">return</span> util.fio2str(fio.fiobj_hash_get(self.h.*.headers, hname));</span>
|
||||
<span class="line" id="L440">}</span>
|
||||
<span class="line" id="L441"></span>
|
||||
<span class="line" id="L442"><span class="tok-comment">/// Set header.</span></span>
|
||||
<span class="line" id="L443"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">setHeader</span>(self: *<span class="tok-kw">const</span> Self, name: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>, value: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>) HttpError!<span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L444"> <span class="tok-kw">const</span> hname: fio.fio_str_info_s = .{</span>
|
||||
<span class="line" id="L445"> .data = util.toCharPtr(name),</span>
|
||||
<span class="line" id="L446"> .len = name.len,</span>
|
||||
<span class="line" id="L447"> .capa = name.len,</span>
|
||||
<span class="line" id="L448"> };</span>
|
||||
<span class="line" id="L449"></span>
|
||||
<span class="line" id="L450"> zap.debug(<span class="tok-str">"setHeader: hname = {s}\n"</span>, .{name});</span>
|
||||
<span class="line" id="L451"> <span class="tok-kw">const</span> vname: fio.fio_str_info_s = .{</span>
|
||||
<span class="line" id="L452"> .data = util.toCharPtr(value),</span>
|
||||
<span class="line" id="L453"> .len = value.len,</span>
|
||||
<span class="line" id="L454"> .capa = value.len,</span>
|
||||
<span class="line" id="L455"> };</span>
|
||||
<span class="line" id="L456"> zap.debug(<span class="tok-str">"setHeader: vname = {s}\n"</span>, .{value});</span>
|
||||
<span class="line" id="L457"> <span class="tok-kw">const</span> ret = fio.http_set_header2(self.h, hname, vname);</span>
|
||||
<span class="line" id="L458"></span>
|
||||
<span class="line" id="L459"> <span class="tok-comment">// FIXME without the following if, we get errors in release builds</span>
|
||||
</span>
|
||||
<span class="line" id="L460"> <span class="tok-comment">// at least we don't have to log unconditionally</span>
|
||||
</span>
|
||||
<span class="line" id="L461"> <span class="tok-kw">if</span> (ret == -<span class="tok-number">1</span>) {</span>
|
||||
<span class="line" id="L462"> std.debug.print(<span class="tok-str">"***************** zap.zig:274\n"</span>, .{});</span>
|
||||
<span class="line" id="L463"> }</span>
|
||||
<span class="line" id="L464"> zap.debug(<span class="tok-str">"setHeader: ret = {}\n"</span>, .{ret});</span>
|
||||
<span class="line" id="L465"></span>
|
||||
<span class="line" id="L466"> <span class="tok-kw">if</span> (ret == <span class="tok-number">0</span>) <span class="tok-kw">return</span>;</span>
|
||||
<span class="line" id="L467"> <span class="tok-kw">return</span> <span class="tok-kw">error</span>.HttpSetHeader;</span>
|
||||
<span class="line" id="L468">}</span>
|
||||
<span class="line" id="L469"></span>
|
||||
<span class="line" id="L470"><span class="tok-comment">/// Set status by numeric value.</span></span>
|
||||
<span class="line" id="L471"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">setStatusNumeric</span>(self: *<span class="tok-kw">const</span> Self, status: <span class="tok-type">usize</span>) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L472"> self.h.*.status = status;</span>
|
||||
<span class="line" id="L473">}</span>
|
||||
<span class="line" id="L474"></span>
|
||||
<span class="line" id="L475"><span class="tok-comment">/// Set status by enum.</span></span>
|
||||
<span class="line" id="L476"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">setStatus</span>(self: *<span class="tok-kw">const</span> Self, status: http.StatusCode) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L477"> self.h.*.status = <span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@intCast</span>(<span class="tok-builtin">@intFromEnum</span>(status)));</span>
|
||||
<span class="line" id="L478">}</span>
|
||||
<span class="line" id="L479"></span>
|
||||
<span class="line" id="L480"><span class="tok-comment">/// Sends a file if present in the filesystem orelse returns an error.</span></span>
|
||||
<span class="line" id="L481"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L482"><span class="tok-comment">/// - efficiently sends a file using gzip compression</span></span>
|
||||
<span class="line" id="L483"><span class="tok-comment">/// - also handles range requests if `Range` or `If-Range` headers are present in the request.</span></span>
|
||||
<span class="line" id="L484"><span class="tok-comment">/// - sends the response headers and the specified file (the response's body).</span></span>
|
||||
<span class="line" id="L485"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L486"><span class="tok-comment">/// On success, the `self.h` handle will be consumed and invalid.</span></span>
|
||||
<span class="line" id="L487"><span class="tok-comment">/// On error, the handle will still be valid and should be used to send an error response</span></span>
|
||||
<span class="line" id="L488"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L489"><span class="tok-comment">/// Important: sets last-modified and cache-control headers with a max-age value of 1 hour!</span></span>
|
||||
<span class="line" id="L490"><span class="tok-comment">/// You can override that by setting those headers yourself, e.g.: setHeader("Cache-Control", "no-cache")</span></span>
|
||||
<span class="line" id="L491"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">sendFile</span>(self: *<span class="tok-kw">const</span> Self, file_path: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>) !<span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L492"> <span class="tok-kw">if</span> (fio.http_sendfile2(self.h, util.toCharPtr(file_path), file_path.len, <span class="tok-null">null</span>, <span class="tok-number">0</span>) != <span class="tok-number">0</span>)</span>
|
||||
<span class="line" id="L493"> <span class="tok-kw">return</span> <span class="tok-kw">error</span>.SendFile;</span>
|
||||
<span class="line" id="L494"> self.markAsFinished(<span class="tok-null">true</span>);</span>
|
||||
<span class="line" id="L495">}</span>
|
||||
<span class="line" id="L496"></span>
|
||||
<span class="line" id="L497"><span class="tok-comment">/// Attempts to decode the request's body.</span></span>
|
||||
<span class="line" id="L498"><span class="tok-comment">/// This should be called BEFORE parseQuery</span></span>
|
||||
<span class="line" id="L499"><span class="tok-comment">/// Result is accessible via parametersToOwnedSlice(), parametersToOwnedStrSlice()</span></span>
|
||||
<span class="line" id="L500"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L501"><span class="tok-comment">/// Supported body types:</span></span>
|
||||
<span class="line" id="L502"><span class="tok-comment">/// - application/x-www-form-urlencoded</span></span>
|
||||
<span class="line" id="L503"><span class="tok-comment">/// - application/json</span></span>
|
||||
<span class="line" id="L504"><span class="tok-comment">/// - multipart/form-data</span></span>
|
||||
<span class="line" id="L505"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">parseBody</span>(self: *<span class="tok-kw">const</span> Self) HttpError!<span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L506"> <span class="tok-kw">if</span> (fio.http_parse_body(self.h) == -<span class="tok-number">1</span>) <span class="tok-kw">return</span> <span class="tok-kw">error</span>.HttpParseBody;</span>
|
||||
<span class="line" id="L507">}</span>
|
||||
<span class="line" id="L508"></span>
|
||||
<span class="line" id="L509"><span class="tok-comment">/// Parses the query part of an HTTP request</span></span>
|
||||
<span class="line" id="L510"><span class="tok-comment">/// This should be called AFTER parseBody(), just in case the body is a JSON</span></span>
|
||||
<span class="line" id="L511"><span class="tok-comment">/// object that doesn't have a hash map at its root.</span></span>
|
||||
<span class="line" id="L512"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L513"><span class="tok-comment">/// Result is accessible via parametersToOwnedSlice(), parametersToOwnedStrSlice()</span></span>
|
||||
<span class="line" id="L514"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">parseQuery</span>(self: *<span class="tok-kw">const</span> Self) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L515"> fio.http_parse_query(self.h);</span>
|
||||
<span class="line" id="L516">}</span>
|
||||
<span class="line" id="L517"></span>
|
||||
<span class="line" id="L518"><span class="tok-comment">/// Parse received cookie headers</span></span>
|
||||
<span class="line" id="L519"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">parseCookies</span>(self: *<span class="tok-kw">const</span> Self, url_encoded: <span class="tok-type">bool</span>) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L520"> fio.http_parse_cookies(self.h, <span class="tok-kw">if</span> (url_encoded) <span class="tok-number">1</span> <span class="tok-kw">else</span> <span class="tok-number">0</span>);</span>
|
||||
<span class="line" id="L521">}</span>
|
||||
<span class="line" id="L522"></span>
|
||||
<span class="line" id="L523"><span class="tok-comment">/// Set a response cookie</span></span>
|
||||
<span class="line" id="L524"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">setCookie</span>(self: *<span class="tok-kw">const</span> Self, args: CookieArgs) HttpError!<span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L525"> <span class="tok-kw">const</span> c: fio.http_cookie_args_s = .{</span>
|
||||
<span class="line" id="L526"> .name = util.toCharPtr(args.name),</span>
|
||||
<span class="line" id="L527"> .name_len = <span class="tok-builtin">@as</span>(<span class="tok-type">isize</span>, <span class="tok-builtin">@intCast</span>(args.name.len)),</span>
|
||||
<span class="line" id="L528"> .value = util.toCharPtr(args.value),</span>
|
||||
<span class="line" id="L529"> .value_len = <span class="tok-builtin">@as</span>(<span class="tok-type">isize</span>, <span class="tok-builtin">@intCast</span>(args.value.len)),</span>
|
||||
<span class="line" id="L530"> .domain = <span class="tok-kw">if</span> (args.domain) |p| util.toCharPtr(p) <span class="tok-kw">else</span> <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L531"> .domain_len = <span class="tok-kw">if</span> (args.domain) |p| <span class="tok-builtin">@as</span>(<span class="tok-type">isize</span>, <span class="tok-builtin">@intCast</span>(p.len)) <span class="tok-kw">else</span> <span class="tok-number">0</span>,</span>
|
||||
<span class="line" id="L532"> .path = <span class="tok-kw">if</span> (args.path) |p| util.toCharPtr(p) <span class="tok-kw">else</span> <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L533"> .path_len = <span class="tok-kw">if</span> (args.path) |p| <span class="tok-builtin">@as</span>(<span class="tok-type">isize</span>, <span class="tok-builtin">@intCast</span>(p.len)) <span class="tok-kw">else</span> <span class="tok-number">0</span>,</span>
|
||||
<span class="line" id="L534"> .max_age = args.max_age_s,</span>
|
||||
<span class="line" id="L535"> .secure = <span class="tok-kw">if</span> (args.secure) <span class="tok-number">1</span> <span class="tok-kw">else</span> <span class="tok-number">0</span>,</span>
|
||||
<span class="line" id="L536"> .http_only = <span class="tok-kw">if</span> (args.http_only) <span class="tok-number">1</span> <span class="tok-kw">else</span> <span class="tok-number">0</span>,</span>
|
||||
<span class="line" id="L537"> };</span>
|
||||
<span class="line" id="L538"></span>
|
||||
<span class="line" id="L539"> <span class="tok-comment">// TODO WAT?</span>
|
||||
</span>
|
||||
<span class="line" id="L540"> <span class="tok-comment">// if we:</span>
|
||||
</span>
|
||||
<span class="line" id="L541"> <span class="tok-comment">// if(fio.http_set_cookie(...) == -1)</span>
|
||||
</span>
|
||||
<span class="line" id="L542"> <span class="tok-comment">// instead of capturing it in `ret` first and then checking it,</span>
|
||||
</span>
|
||||
<span class="line" id="L543"> <span class="tok-comment">// all ReleaseXXX builds return an error!</span>
|
||||
</span>
|
||||
<span class="line" id="L544"> <span class="tok-comment">// TODO: still happening?</span>
|
||||
</span>
|
||||
<span class="line" id="L545"> <span class="tok-kw">const</span> ret = fio.http_set_cookie(self.h, c);</span>
|
||||
<span class="line" id="L546"> <span class="tok-kw">if</span> (ret == -<span class="tok-number">1</span>) {</span>
|
||||
<span class="line" id="L547"> std.log.err(<span class="tok-str">"fio.http_set_cookie returned: {}\n"</span>, .{ret});</span>
|
||||
<span class="line" id="L548"> <span class="tok-kw">return</span> <span class="tok-kw">error</span>.SetCookie;</span>
|
||||
<span class="line" id="L549"> }</span>
|
||||
<span class="line" id="L550">}</span>
|
||||
<span class="line" id="L551"></span>
|
||||
<span class="line" id="L552"><span class="tok-comment">/// Returns named cookie. Works like getParamStr().</span></span>
|
||||
<span class="line" id="L553"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">getCookieStr</span>(self: *<span class="tok-kw">const</span> Self, a: std.mem.Allocator, name: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>, always_alloc: <span class="tok-type">bool</span>) !?util.FreeOrNot {</span>
|
||||
<span class="line" id="L554"> <span class="tok-kw">if</span> (self.h.*.cookies == <span class="tok-number">0</span>) <span class="tok-kw">return</span> <span class="tok-null">null</span>;</span>
|
||||
<span class="line" id="L555"> <span class="tok-kw">const</span> key = fio.fiobj_str_new(name.ptr, name.len);</span>
|
||||
<span class="line" id="L556"> <span class="tok-kw">defer</span> fio.fiobj_free_wrapped(key);</span>
|
||||
<span class="line" id="L557"> <span class="tok-kw">const</span> value = fio.fiobj_hash_get(self.h.*.cookies, key);</span>
|
||||
<span class="line" id="L558"> <span class="tok-kw">if</span> (value == fio.FIOBJ_INVALID) {</span>
|
||||
<span class="line" id="L559"> <span class="tok-kw">return</span> <span class="tok-null">null</span>;</span>
|
||||
<span class="line" id="L560"> }</span>
|
||||
<span class="line" id="L561"> <span class="tok-kw">return</span> <span class="tok-kw">try</span> util.fio2strAllocOrNot(a, value, always_alloc);</span>
|
||||
<span class="line" id="L562">}</span>
|
||||
<span class="line" id="L563"></span>
|
||||
<span class="line" id="L564"><span class="tok-comment">/// Returns the number of cookies after parsing.</span></span>
|
||||
<span class="line" id="L565"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L566"><span class="tok-comment">/// Parse with parseCookies()</span></span>
|
||||
<span class="line" id="L567"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">getCookiesCount</span>(self: *<span class="tok-kw">const</span> Self) <span class="tok-type">isize</span> {</span>
|
||||
<span class="line" id="L568"> <span class="tok-kw">if</span> (self.h.*.cookies == <span class="tok-number">0</span>) <span class="tok-kw">return</span> <span class="tok-number">0</span>;</span>
|
||||
<span class="line" id="L569"> <span class="tok-kw">return</span> fio.fiobj_obj2num(self.h.*.cookies);</span>
|
||||
<span class="line" id="L570">}</span>
|
||||
<span class="line" id="L571"></span>
|
||||
<span class="line" id="L572"><span class="tok-comment">/// Returns the number of parameters after parsing.</span></span>
|
||||
<span class="line" id="L573"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L574"><span class="tok-comment">/// Parse with parseBody() and / or parseQuery()</span></span>
|
||||
<span class="line" id="L575"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">getParamCount</span>(self: *<span class="tok-kw">const</span> Self) <span class="tok-type">isize</span> {</span>
|
||||
<span class="line" id="L576"> <span class="tok-kw">if</span> (self.h.*.params == <span class="tok-number">0</span>) <span class="tok-kw">return</span> <span class="tok-number">0</span>;</span>
|
||||
<span class="line" id="L577"> <span class="tok-kw">return</span> fio.fiobj_obj2num(self.h.*.params);</span>
|
||||
<span class="line" id="L578">}</span>
|
||||
<span class="line" id="L579"></span>
|
||||
<span class="line" id="L580"><span class="tok-comment">/// Same as parametersToOwnedStrList() but for cookies</span></span>
|
||||
<span class="line" id="L581"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">cookiesToOwnedStrList</span>(self: *<span class="tok-kw">const</span> Self, a: std.mem.Allocator, always_alloc: <span class="tok-type">bool</span>) <span class="tok-type">anyerror</span>!HttpParamStrKVList {</span>
|
||||
<span class="line" id="L582"> <span class="tok-kw">var</span> params = <span class="tok-kw">try</span> std.ArrayList(HttpParamStrKV).initCapacity(a, <span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@intCast</span>(self.getCookiesCount())));</span>
|
||||
<span class="line" id="L583"> <span class="tok-kw">var</span> context: _parametersToOwnedStrSliceContext = .{</span>
|
||||
<span class="line" id="L584"> .params = &params,</span>
|
||||
<span class="line" id="L585"> .allocator = a,</span>
|
||||
<span class="line" id="L586"> .always_alloc = always_alloc,</span>
|
||||
<span class="line" id="L587"> };</span>
|
||||
<span class="line" id="L588"> <span class="tok-kw">const</span> howmany = fio.fiobj_each1(self.h.*.cookies, <span class="tok-number">0</span>, _each_nextParamStr, &context);</span>
|
||||
<span class="line" id="L589"> <span class="tok-kw">if</span> (howmany != self.getCookiesCount()) {</span>
|
||||
<span class="line" id="L590"> <span class="tok-kw">return</span> <span class="tok-kw">error</span>.HttpIterParams;</span>
|
||||
<span class="line" id="L591"> }</span>
|
||||
<span class="line" id="L592"> <span class="tok-kw">return</span> .{ .items = <span class="tok-kw">try</span> params.toOwnedSlice(), .allocator = a };</span>
|
||||
<span class="line" id="L593">}</span>
|
||||
<span class="line" id="L594"></span>
|
||||
<span class="line" id="L595"><span class="tok-comment">/// Same as parametersToOwnedList() but for cookies</span></span>
|
||||
<span class="line" id="L596"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">cookiesToOwnedList</span>(self: *<span class="tok-kw">const</span> Self, a: std.mem.Allocator, dupe_strings: <span class="tok-type">bool</span>) !HttpParamKVList {</span>
|
||||
<span class="line" id="L597"> <span class="tok-kw">var</span> params = <span class="tok-kw">try</span> std.ArrayList(HttpParamKV).initCapacity(a, <span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@intCast</span>(self.getCookiesCount())));</span>
|
||||
<span class="line" id="L598"> <span class="tok-kw">var</span> context: _parametersToOwnedSliceContext = .{ .params = &params, .allocator = a, .dupe_strings = dupe_strings };</span>
|
||||
<span class="line" id="L599"> <span class="tok-kw">const</span> howmany = fio.fiobj_each1(self.h.*.cookies, <span class="tok-number">0</span>, _each_nextParam, &context);</span>
|
||||
<span class="line" id="L600"> <span class="tok-kw">if</span> (howmany != self.getCookiesCount()) {</span>
|
||||
<span class="line" id="L601"> <span class="tok-kw">return</span> <span class="tok-kw">error</span>.HttpIterParams;</span>
|
||||
<span class="line" id="L602"> }</span>
|
||||
<span class="line" id="L603"> <span class="tok-kw">return</span> .{ .items = <span class="tok-kw">try</span> params.toOwnedSlice(), .allocator = a };</span>
|
||||
<span class="line" id="L604">}</span>
|
||||
<span class="line" id="L605"></span>
|
||||
<span class="line" id="L606"><span class="tok-comment">/// Returns the query / body parameters as key/value pairs, as strings.</span></span>
|
||||
<span class="line" id="L607"><span class="tok-comment">/// Supported param types that will be converted:</span></span>
|
||||
<span class="line" id="L608"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L609"><span class="tok-comment">/// - Bool</span></span>
|
||||
<span class="line" id="L610"><span class="tok-comment">/// - Int</span></span>
|
||||
<span class="line" id="L611"><span class="tok-comment">/// - Float</span></span>
|
||||
<span class="line" id="L612"><span class="tok-comment">/// - String</span></span>
|
||||
<span class="line" id="L613"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L614"><span class="tok-comment">/// At the moment, no fio ARRAYs are supported as well as HASH maps.</span></span>
|
||||
<span class="line" id="L615"><span class="tok-comment">/// So, for JSON body payloads: parse the body instead.</span></span>
|
||||
<span class="line" id="L616"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L617"><span class="tok-comment">/// Requires parseBody() and/or parseQuery() have been called.</span></span>
|
||||
<span class="line" id="L618"><span class="tok-comment">/// Returned list needs to be deinited.</span></span>
|
||||
<span class="line" id="L619"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">parametersToOwnedStrList</span>(self: *<span class="tok-kw">const</span> Self, a: std.mem.Allocator, always_alloc: <span class="tok-type">bool</span>) <span class="tok-type">anyerror</span>!HttpParamStrKVList {</span>
|
||||
<span class="line" id="L620"> <span class="tok-kw">var</span> params = <span class="tok-kw">try</span> std.ArrayList(HttpParamStrKV).initCapacity(a, <span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@intCast</span>(self.getParamCount())));</span>
|
||||
<span class="line" id="L621"> <span class="tok-kw">var</span> context: _parametersToOwnedStrSliceContext = .{</span>
|
||||
<span class="line" id="L622"> .params = &params,</span>
|
||||
<span class="line" id="L623"> .allocator = a,</span>
|
||||
<span class="line" id="L624"> .always_alloc = always_alloc,</span>
|
||||
<span class="line" id="L625"> };</span>
|
||||
<span class="line" id="L626"> <span class="tok-kw">const</span> howmany = fio.fiobj_each1(self.h.*.params, <span class="tok-number">0</span>, _each_nextParamStr, &context);</span>
|
||||
<span class="line" id="L627"> <span class="tok-kw">if</span> (howmany != self.getParamCount()) {</span>
|
||||
<span class="line" id="L628"> <span class="tok-kw">return</span> <span class="tok-kw">error</span>.HttpIterParams;</span>
|
||||
<span class="line" id="L629"> }</span>
|
||||
<span class="line" id="L630"> <span class="tok-kw">return</span> .{ .items = <span class="tok-kw">try</span> params.toOwnedSlice(), .allocator = a };</span>
|
||||
<span class="line" id="L631">}</span>
|
||||
<span class="line" id="L632"></span>
|
||||
<span class="line" id="L633"><span class="tok-kw">const</span> _parametersToOwnedStrSliceContext = <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L634"> allocator: std.mem.Allocator,</span>
|
||||
<span class="line" id="L635"> params: *std.ArrayList(HttpParamStrKV),</span>
|
||||
<span class="line" id="L636"> last_error: ?<span class="tok-type">anyerror</span> = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L637"> always_alloc: <span class="tok-type">bool</span>,</span>
|
||||
<span class="line" id="L638">};</span>
|
||||
<span class="line" id="L639"></span>
|
||||
<span class="line" id="L640"><span class="tok-kw">fn</span> <span class="tok-fn">_each_nextParamStr</span>(fiobj_value: fio.FIOBJ, context: ?*<span class="tok-type">anyopaque</span>) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">c_int</span> {</span>
|
||||
<span class="line" id="L641"> <span class="tok-kw">const</span> ctx: *_parametersToOwnedStrSliceContext = <span class="tok-builtin">@as</span>(*_parametersToOwnedStrSliceContext, <span class="tok-builtin">@ptrCast</span>(<span class="tok-builtin">@alignCast</span>(context)));</span>
|
||||
<span class="line" id="L642"> <span class="tok-comment">// this is thread-safe, guaranteed by fio</span>
|
||||
</span>
|
||||
<span class="line" id="L643"> <span class="tok-kw">const</span> fiobj_key: fio.FIOBJ = fio.fiobj_hash_key_in_loop();</span>
|
||||
<span class="line" id="L644"> ctx.params.append(.{</span>
|
||||
<span class="line" id="L645"> .key = util.fio2strAllocOrNot(ctx.allocator, fiobj_key, ctx.always_alloc) <span class="tok-kw">catch</span> |err| {</span>
|
||||
<span class="line" id="L646"> ctx.last_error = err;</span>
|
||||
<span class="line" id="L647"> <span class="tok-kw">return</span> -<span class="tok-number">1</span>;</span>
|
||||
<span class="line" id="L648"> },</span>
|
||||
<span class="line" id="L649"> .value = util.fio2strAllocOrNot(ctx.allocator, fiobj_value, ctx.always_alloc) <span class="tok-kw">catch</span> |err| {</span>
|
||||
<span class="line" id="L650"> ctx.last_error = err;</span>
|
||||
<span class="line" id="L651"> <span class="tok-kw">return</span> -<span class="tok-number">1</span>;</span>
|
||||
<span class="line" id="L652"> },</span>
|
||||
<span class="line" id="L653"> }) <span class="tok-kw">catch</span> |err| {</span>
|
||||
<span class="line" id="L654"> <span class="tok-comment">// what to do?</span>
|
||||
</span>
|
||||
<span class="line" id="L655"> <span class="tok-comment">// signal the caller that an error occured by returning -1</span>
|
||||
</span>
|
||||
<span class="line" id="L656"> <span class="tok-comment">// also, set the error</span>
|
||||
</span>
|
||||
<span class="line" id="L657"> ctx.last_error = err;</span>
|
||||
<span class="line" id="L658"> <span class="tok-kw">return</span> -<span class="tok-number">1</span>;</span>
|
||||
<span class="line" id="L659"> };</span>
|
||||
<span class="line" id="L660"> <span class="tok-kw">return</span> <span class="tok-number">0</span>;</span>
|
||||
<span class="line" id="L661">}</span>
|
||||
<span class="line" id="L662"></span>
|
||||
<span class="line" id="L663"><span class="tok-comment">/// Returns the query / body parameters as key/value pairs</span></span>
|
||||
<span class="line" id="L664"><span class="tok-comment">/// Supported param types that will be converted:</span></span>
|
||||
<span class="line" id="L665"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L666"><span class="tok-comment">/// - Bool</span></span>
|
||||
<span class="line" id="L667"><span class="tok-comment">/// - Int</span></span>
|
||||
<span class="line" id="L668"><span class="tok-comment">/// - Float</span></span>
|
||||
<span class="line" id="L669"><span class="tok-comment">/// - String</span></span>
|
||||
<span class="line" id="L670"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L671"><span class="tok-comment">/// At the moment, no fio ARRAYs are supported as well as HASH maps.</span></span>
|
||||
<span class="line" id="L672"><span class="tok-comment">/// So, for JSON body payloads: parse the body instead.</span></span>
|
||||
<span class="line" id="L673"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L674"><span class="tok-comment">/// Requires parseBody() and/or parseQuery() have been called.</span></span>
|
||||
<span class="line" id="L675"><span class="tok-comment">/// Returned slice needs to be freed.</span></span>
|
||||
<span class="line" id="L676"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">parametersToOwnedList</span>(self: *<span class="tok-kw">const</span> Self, a: std.mem.Allocator, dupe_strings: <span class="tok-type">bool</span>) !HttpParamKVList {</span>
|
||||
<span class="line" id="L677"> <span class="tok-kw">var</span> params = <span class="tok-kw">try</span> std.ArrayList(HttpParamKV).initCapacity(a, <span class="tok-builtin">@as</span>(<span class="tok-type">usize</span>, <span class="tok-builtin">@intCast</span>(self.getParamCount())));</span>
|
||||
<span class="line" id="L678"> <span class="tok-kw">var</span> context: _parametersToOwnedSliceContext = .{ .params = &params, .allocator = a, .dupe_strings = dupe_strings };</span>
|
||||
<span class="line" id="L679"> <span class="tok-kw">const</span> howmany = fio.fiobj_each1(self.h.*.params, <span class="tok-number">0</span>, _each_nextParam, &context);</span>
|
||||
<span class="line" id="L680"> <span class="tok-kw">if</span> (howmany != self.getParamCount()) {</span>
|
||||
<span class="line" id="L681"> <span class="tok-kw">return</span> <span class="tok-kw">error</span>.HttpIterParams;</span>
|
||||
<span class="line" id="L682"> }</span>
|
||||
<span class="line" id="L683"> <span class="tok-kw">return</span> .{ .items = <span class="tok-kw">try</span> params.toOwnedSlice(), .allocator = a };</span>
|
||||
<span class="line" id="L684">}</span>
|
||||
<span class="line" id="L685"></span>
|
||||
<span class="line" id="L686"><span class="tok-kw">const</span> _parametersToOwnedSliceContext = <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L687"> params: *std.ArrayList(HttpParamKV),</span>
|
||||
<span class="line" id="L688"> last_error: ?<span class="tok-type">anyerror</span> = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L689"> allocator: std.mem.Allocator,</span>
|
||||
<span class="line" id="L690"> dupe_strings: <span class="tok-type">bool</span>,</span>
|
||||
<span class="line" id="L691">};</span>
|
||||
<span class="line" id="L692"></span>
|
||||
<span class="line" id="L693"><span class="tok-kw">fn</span> <span class="tok-fn">_each_nextParam</span>(fiobj_value: fio.FIOBJ, context: ?*<span class="tok-type">anyopaque</span>) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">c_int</span> {</span>
|
||||
<span class="line" id="L694"> <span class="tok-kw">const</span> ctx: *_parametersToOwnedSliceContext = <span class="tok-builtin">@as</span>(*_parametersToOwnedSliceContext, <span class="tok-builtin">@ptrCast</span>(<span class="tok-builtin">@alignCast</span>(context)));</span>
|
||||
<span class="line" id="L695"> <span class="tok-comment">// this is thread-safe, guaranteed by fio</span>
|
||||
</span>
|
||||
<span class="line" id="L696"> <span class="tok-kw">const</span> fiobj_key: fio.FIOBJ = fio.fiobj_hash_key_in_loop();</span>
|
||||
<span class="line" id="L697"> ctx.params.append(.{</span>
|
||||
<span class="line" id="L698"> .key = util.fio2strAllocOrNot(ctx.allocator, fiobj_key, ctx.dupe_strings) <span class="tok-kw">catch</span> |err| {</span>
|
||||
<span class="line" id="L699"> ctx.last_error = err;</span>
|
||||
<span class="line" id="L700"> <span class="tok-kw">return</span> -<span class="tok-number">1</span>;</span>
|
||||
<span class="line" id="L701"> },</span>
|
||||
<span class="line" id="L702"> .value = Fiobj2HttpParam(ctx.allocator, fiobj_value, ctx.dupe_strings) <span class="tok-kw">catch</span> |err| {</span>
|
||||
<span class="line" id="L703"> ctx.last_error = err;</span>
|
||||
<span class="line" id="L704"> <span class="tok-kw">return</span> -<span class="tok-number">1</span>;</span>
|
||||
<span class="line" id="L705"> },</span>
|
||||
<span class="line" id="L706"> }) <span class="tok-kw">catch</span> |err| {</span>
|
||||
<span class="line" id="L707"> <span class="tok-comment">// what to do?</span>
|
||||
</span>
|
||||
<span class="line" id="L708"> <span class="tok-comment">// signal the caller that an error occured by returning -1</span>
|
||||
</span>
|
||||
<span class="line" id="L709"> <span class="tok-comment">// also, set the error</span>
|
||||
</span>
|
||||
<span class="line" id="L710"> ctx.last_error = err;</span>
|
||||
<span class="line" id="L711"> <span class="tok-kw">return</span> -<span class="tok-number">1</span>;</span>
|
||||
<span class="line" id="L712"> };</span>
|
||||
<span class="line" id="L713"> <span class="tok-kw">return</span> <span class="tok-number">0</span>;</span>
|
||||
<span class="line" id="L714">}</span>
|
||||
<span class="line" id="L715"></span>
|
||||
<span class="line" id="L716"><span class="tok-comment">/// get named parameter as string</span></span>
|
||||
<span class="line" id="L717"><span class="tok-comment">/// Supported param types that will be converted:</span></span>
|
||||
<span class="line" id="L718"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L719"><span class="tok-comment">/// - Bool</span></span>
|
||||
<span class="line" id="L720"><span class="tok-comment">/// - Int</span></span>
|
||||
<span class="line" id="L721"><span class="tok-comment">/// - Float</span></span>
|
||||
<span class="line" id="L722"><span class="tok-comment">/// - String</span></span>
|
||||
<span class="line" id="L723"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L724"><span class="tok-comment">/// At the moment, no fio ARRAYs are supported as well as HASH maps.</span></span>
|
||||
<span class="line" id="L725"><span class="tok-comment">/// So, for JSON body payloads: parse the body instead.</span></span>
|
||||
<span class="line" id="L726"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L727"><span class="tok-comment">/// Requires parseBody() and/or parseQuery() have been called.</span></span>
|
||||
<span class="line" id="L728"><span class="tok-comment">/// The returned string needs to be deinited with .deinit()</span></span>
|
||||
<span class="line" id="L729"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">getParamStr</span>(self: *<span class="tok-kw">const</span> Self, a: std.mem.Allocator, name: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>, always_alloc: <span class="tok-type">bool</span>) !?util.FreeOrNot {</span>
|
||||
<span class="line" id="L730"> <span class="tok-kw">if</span> (self.h.*.params == <span class="tok-number">0</span>) <span class="tok-kw">return</span> <span class="tok-null">null</span>;</span>
|
||||
<span class="line" id="L731"> <span class="tok-kw">const</span> key = fio.fiobj_str_new(name.ptr, name.len);</span>
|
||||
<span class="line" id="L732"> <span class="tok-kw">defer</span> fio.fiobj_free_wrapped(key);</span>
|
||||
<span class="line" id="L733"> <span class="tok-kw">const</span> value = fio.fiobj_hash_get(self.h.*.params, key);</span>
|
||||
<span class="line" id="L734"> <span class="tok-kw">if</span> (value == fio.FIOBJ_INVALID) {</span>
|
||||
<span class="line" id="L735"> <span class="tok-kw">return</span> <span class="tok-null">null</span>;</span>
|
||||
<span class="line" id="L736"> }</span>
|
||||
<span class="line" id="L737"> <span class="tok-kw">return</span> <span class="tok-kw">try</span> util.fio2strAllocOrNot(a, value, always_alloc);</span>
|
||||
<span class="line" id="L738">}</span>
|
||||
<span class="line" id="L739"></span>
|
||||
<span class="line" id="L740"><span class="tok-comment">/// similar to getParamStr, except it will return the part of the querystring</span></span>
|
||||
<span class="line" id="L741"><span class="tok-comment">/// after the equals sign, non-decoded, and always as character slice.</span></span>
|
||||
<span class="line" id="L742"><span class="tok-comment">/// - no allocation!</span></span>
|
||||
<span class="line" id="L743"><span class="tok-comment">/// - does not requre parseQuery() or anything to be called in advance</span></span>
|
||||
<span class="line" id="L744"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">getParamSlice</span>(self: *<span class="tok-kw">const</span> Self, name: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>) ?[]<span class="tok-kw">const</span> <span class="tok-type">u8</span> {</span>
|
||||
<span class="line" id="L745"> <span class="tok-kw">if</span> (self.query) |query| {</span>
|
||||
<span class="line" id="L746"> <span class="tok-kw">var</span> amp_it = std.mem.tokenizeScalar(<span class="tok-type">u8</span>, query, <span class="tok-str">'&'</span>);</span>
|
||||
<span class="line" id="L747"> <span class="tok-kw">while</span> (amp_it.next()) |maybe_pair| {</span>
|
||||
<span class="line" id="L748"> <span class="tok-kw">if</span> (std.mem.indexOfScalar(<span class="tok-type">u8</span>, maybe_pair, <span class="tok-str">'='</span>)) |pos_of_eq| {</span>
|
||||
<span class="line" id="L749"> <span class="tok-kw">const</span> pname = maybe_pair[<span class="tok-number">0</span>..pos_of_eq];</span>
|
||||
<span class="line" id="L750"> <span class="tok-kw">if</span> (std.mem.eql(<span class="tok-type">u8</span>, pname, name)) {</span>
|
||||
<span class="line" id="L751"> <span class="tok-kw">if</span> (maybe_pair.len > pos_of_eq) {</span>
|
||||
<span class="line" id="L752"> <span class="tok-kw">const</span> pval = maybe_pair[pos_of_eq + <span class="tok-number">1</span> ..];</span>
|
||||
<span class="line" id="L753"> <span class="tok-kw">return</span> pval;</span>
|
||||
<span class="line" id="L754"> }</span>
|
||||
<span class="line" id="L755"> }</span>
|
||||
<span class="line" id="L756"> }</span>
|
||||
<span class="line" id="L757"> }</span>
|
||||
<span class="line" id="L758"> }</span>
|
||||
<span class="line" id="L759"> <span class="tok-kw">return</span> <span class="tok-null">null</span>;</span>
|
||||
<span class="line" id="L760">}</span>
|
||||
<span class="line" id="L761"></span>
|
||||
<span class="line" id="L762"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> ParameterSlices = <span class="tok-kw">struct</span> { name: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>, value: []<span class="tok-kw">const</span> <span class="tok-type">u8</span> };</span>
|
||||
<span class="line" id="L763"></span>
|
||||
<span class="line" id="L764"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> ParamSliceIterator = <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L765"> amp_it: std.mem.TokenIterator(<span class="tok-type">u8</span>, .scalar),</span>
|
||||
<span class="line" id="L766"></span>
|
||||
<span class="line" id="L767"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">init</span>(query: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>) <span class="tok-builtin">@This</span>() {</span>
|
||||
<span class="line" id="L768"> <span class="tok-kw">return</span> .{</span>
|
||||
<span class="line" id="L769"> .amp_it = std.mem.tokenizeScalar(<span class="tok-type">u8</span>, query, <span class="tok-str">'&'</span>),</span>
|
||||
<span class="line" id="L770"> };</span>
|
||||
<span class="line" id="L771"> }</span>
|
||||
<span class="line" id="L772"></span>
|
||||
<span class="line" id="L773"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">next</span>(self: *<span class="tok-builtin">@This</span>()) ?ParameterSlices {</span>
|
||||
<span class="line" id="L774"> <span class="tok-kw">while</span> (self.amp_it.next()) |maybe_pair| {</span>
|
||||
<span class="line" id="L775"> <span class="tok-kw">if</span> (std.mem.indexOfScalar(<span class="tok-type">u8</span>, maybe_pair, <span class="tok-str">'='</span>)) |pos_of_eq| {</span>
|
||||
<span class="line" id="L776"> <span class="tok-kw">const</span> pname = maybe_pair[<span class="tok-number">0</span>..pos_of_eq];</span>
|
||||
<span class="line" id="L777"> <span class="tok-kw">if</span> (maybe_pair.len > pos_of_eq) {</span>
|
||||
<span class="line" id="L778"> <span class="tok-kw">const</span> pval = maybe_pair[pos_of_eq + <span class="tok-number">1</span> ..];</span>
|
||||
<span class="line" id="L779"> <span class="tok-kw">return</span> .{ .name = pname, .value = pval };</span>
|
||||
<span class="line" id="L780"> }</span>
|
||||
<span class="line" id="L781"> }</span>
|
||||
<span class="line" id="L782"> }</span>
|
||||
<span class="line" id="L783"> <span class="tok-kw">return</span> <span class="tok-null">null</span>;</span>
|
||||
<span class="line" id="L784"> }</span>
|
||||
<span class="line" id="L785">};</span>
|
||||
<span class="line" id="L786"></span>
|
||||
<span class="line" id="L787"><span class="tok-comment">/// Returns an iterator that yields all query parameters on next() in the</span></span>
|
||||
<span class="line" id="L788"><span class="tok-comment">/// form of a ParameterSlices struct { .name, .value }</span></span>
|
||||
<span class="line" id="L789"><span class="tok-comment">/// As with getParamSlice(), the value is not decoded</span></span>
|
||||
<span class="line" id="L790"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">getParamSlices</span>(self: *<span class="tok-kw">const</span> Self) ParamSliceIterator {</span>
|
||||
<span class="line" id="L791"> <span class="tok-kw">const</span> query = self.query <span class="tok-kw">orelse</span> <span class="tok-str">""</span>;</span>
|
||||
<span class="line" id="L792"> <span class="tok-kw">return</span> ParamSliceIterator.init(query);</span>
|
||||
<span class="line" id="L793">}</span>
|
||||
<span class="line" id="L794"></span>
|
||||
<span class="line" id="L795"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">methodAsEnum</span>(self: *<span class="tok-kw">const</span> Self) http.Method {</span>
|
||||
<span class="line" id="L796"> <span class="tok-kw">return</span> http.methodToEnum(self.method);</span>
|
||||
<span class="line" id="L797">}</span>
|
||||
<span class="line" id="L798"></span>
|
||||
</code></pre></body>
|
||||
</html>
|
|
@ -1,179 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>router.zig - source view</title>
|
||||
<link rel="icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAgklEQVR4AWMYWuD7EllJIM4G4g4g5oIJ/odhOJ8wToOxSTXgNxDHoeiBMfA4+wGShjyYOCkG/IGqWQziEzYAoUAeiF9D5U+DxEg14DRU7jWIT5IBIOdCxf+A+CQZAAoopEB7QJwBCBwHiip8UYmRdrAlDpIMgApwQZNnNii5Dq0MBgCxxycBnwEd+wAAAABJRU5ErkJggg==">
|
||||
<link rel="icon" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNTMgMTQwIj48ZyBmaWxsPSIjRjdBNDFEIj48Zz48cG9seWdvbiBwb2ludHM9IjQ2LDIyIDI4LDQ0IDE5LDMwIi8+PHBvbHlnb24gcG9pbnRzPSI0NiwyMiAzMywzMyAyOCw0NCAyMiw0NCAyMiw5NSAzMSw5NSAyMCwxMDAgMTIsMTE3IDAsMTE3IDAsMjIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMzEsOTUgMTIsMTE3IDQsMTA2Ii8+PC9nPjxnPjxwb2x5Z29uIHBvaW50cz0iNTYsMjIgNjIsMzYgMzcsNDQiLz48cG9seWdvbiBwb2ludHM9IjU2LDIyIDExMSwyMiAxMTEsNDQgMzcsNDQgNTYsMzIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTE2LDk1IDk3LDExNyA5MCwxMDQiLz48cG9seWdvbiBwb2ludHM9IjExNiw5NSAxMDAsMTA0IDk3LDExNyA0MiwxMTcgNDIsOTUiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTUwLDAgNTIsMTE3IDMsMTQwIDEwMSwyMiIvPjwvZz48Zz48cG9seWdvbiBwb2ludHM9IjE0MSwyMiAxNDAsNDAgMTIyLDQ1Ii8+PHBvbHlnb24gcG9pbnRzPSIxNTMsMjIgMTUzLDExNyAxMDYsMTE3IDEyMCwxMDUgMTI1LDk1IDEzMSw5NSAxMzEsNDUgMTIyLDQ1IDEzMiwzNiAxNDEsMjIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTI1LDk1IDEzMCwxMTAgMTA2LDExNyIvPjwvZz48L2c+PC9zdmc+">
|
||||
<style>
|
||||
body{
|
||||
font-family: system-ui, -apple-system, Roboto, "Segoe UI", sans-serif;
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
pre > code {
|
||||
display: block;
|
||||
overflow: auto;
|
||||
line-height: normal;
|
||||
margin: 0em;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-str {
|
||||
color: #d14;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #005C7A;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #545454;
|
||||
font-style: italic;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #900;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-null {
|
||||
color: #005C5C;
|
||||
}
|
||||
.tok-number {
|
||||
color: #005C5C;
|
||||
}
|
||||
.tok-type {
|
||||
color: #458;
|
||||
font-weight: bold;
|
||||
}
|
||||
pre {
|
||||
counter-reset: line;
|
||||
}
|
||||
pre .line:before {
|
||||
counter-increment: line;
|
||||
content: counter(line);
|
||||
display: inline-block;
|
||||
padding-right: 1em;
|
||||
width: 2em;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.line {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
.line:target {
|
||||
border-top: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ccc;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body{
|
||||
background:#222;
|
||||
color: #ccc;
|
||||
}
|
||||
pre > code {
|
||||
color: #ccc;
|
||||
background: #222;
|
||||
border: unset;
|
||||
}
|
||||
.line:target {
|
||||
border-top: 1px solid #444;
|
||||
border-bottom: 1px solid #444;
|
||||
background: #333;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #eee;
|
||||
}
|
||||
.tok-str {
|
||||
color: #2e5;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #ff894c;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #aa7;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #B1A0F8;
|
||||
}
|
||||
.tok-null {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-number {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-type {
|
||||
color: #68f;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre><code><span class="line" id="L1"><span class="tok-kw">const</span> std = <span class="tok-builtin">@import</span>(<span class="tok-str">"std"</span>);</span>
|
||||
<span class="line" id="L2"><span class="tok-kw">const</span> zap = <span class="tok-builtin">@import</span>(<span class="tok-str">"zap.zig"</span>);</span>
|
||||
<span class="line" id="L3"></span>
|
||||
<span class="line" id="L4"><span class="tok-kw">const</span> Allocator = std.mem.Allocator;</span>
|
||||
<span class="line" id="L5"><span class="tok-kw">const</span> RouterError = <span class="tok-kw">error</span>{</span>
|
||||
<span class="line" id="L6"> AlreadyExists,</span>
|
||||
<span class="line" id="L7"> EmptyPath,</span>
|
||||
<span class="line" id="L8">};</span>
|
||||
<span class="line" id="L9"></span>
|
||||
<span class="line" id="L10"><span class="tok-kw">const</span> Self = <span class="tok-builtin">@This</span>();</span>
|
||||
<span class="line" id="L11"></span>
|
||||
<span class="line" id="L12"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> Options = <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L13"> not_found: ?zap.HttpRequestFn = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L14">};</span>
|
||||
<span class="line" id="L15"></span>
|
||||
<span class="line" id="L16">routes: std.StringHashMap(zap.HttpRequestFn),</span>
|
||||
<span class="line" id="L17">not_found: ?zap.HttpRequestFn,</span>
|
||||
<span class="line" id="L18"></span>
|
||||
<span class="line" id="L19"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">init</span>(allocator: Allocator, options: Options) Self {</span>
|
||||
<span class="line" id="L20"> <span class="tok-kw">return</span> .{</span>
|
||||
<span class="line" id="L21"> .routes = std.StringHashMap(zap.HttpRequestFn).init(allocator),</span>
|
||||
<span class="line" id="L22"></span>
|
||||
<span class="line" id="L23"> .not_found = options.not_found,</span>
|
||||
<span class="line" id="L24"> };</span>
|
||||
<span class="line" id="L25">}</span>
|
||||
<span class="line" id="L26"></span>
|
||||
<span class="line" id="L27"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">deinit</span>(self: *Self) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L28"> self.routes.deinit();</span>
|
||||
<span class="line" id="L29">}</span>
|
||||
<span class="line" id="L30"></span>
|
||||
<span class="line" id="L31"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">handle_func</span>(self: *Self, path: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>, h: zap.HttpRequestFn) !<span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L32"> <span class="tok-kw">if</span> (path.len == <span class="tok-number">0</span>) {</span>
|
||||
<span class="line" id="L33"> <span class="tok-kw">return</span> RouterError.EmptyPath;</span>
|
||||
<span class="line" id="L34"> }</span>
|
||||
<span class="line" id="L35"></span>
|
||||
<span class="line" id="L36"> <span class="tok-kw">const</span> route = self.routes.get(path);</span>
|
||||
<span class="line" id="L37"></span>
|
||||
<span class="line" id="L38"> <span class="tok-kw">if</span> (route != <span class="tok-null">null</span>) {</span>
|
||||
<span class="line" id="L39"> <span class="tok-kw">return</span> RouterError.AlreadyExists;</span>
|
||||
<span class="line" id="L40"> }</span>
|
||||
<span class="line" id="L41"></span>
|
||||
<span class="line" id="L42"> <span class="tok-kw">try</span> self.routes.put(path, h);</span>
|
||||
<span class="line" id="L43">}</span>
|
||||
<span class="line" id="L44"></span>
|
||||
<span class="line" id="L45"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">serve</span>(self: *Self, r: zap.Request) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L46"> <span class="tok-kw">const</span> path = <span class="tok-kw">if</span> (r.path) |p| p <span class="tok-kw">else</span> <span class="tok-str">"/"</span>;</span>
|
||||
<span class="line" id="L47"></span>
|
||||
<span class="line" id="L48"> <span class="tok-kw">const</span> route = self.routes.get(path);</span>
|
||||
<span class="line" id="L49"></span>
|
||||
<span class="line" id="L50"> <span class="tok-kw">if</span> (route) |handler| {</span>
|
||||
<span class="line" id="L51"> handler(r);</span>
|
||||
<span class="line" id="L52"> } <span class="tok-kw">else</span> <span class="tok-kw">if</span> (self.not_found) |handler| {</span>
|
||||
<span class="line" id="L53"> <span class="tok-comment">// not found handler</span>
|
||||
</span>
|
||||
<span class="line" id="L54"> handler(r);</span>
|
||||
<span class="line" id="L55"> } <span class="tok-kw">else</span> {</span>
|
||||
<span class="line" id="L56"> <span class="tok-comment">// default 404 output</span>
|
||||
</span>
|
||||
<span class="line" id="L57"> r.setStatus(.not_found);</span>
|
||||
<span class="line" id="L58"> r.sendBody(<span class="tok-str">"404 Not Found"</span>) <span class="tok-kw">catch</span> <span class="tok-kw">return</span>;</span>
|
||||
<span class="line" id="L59"> }</span>
|
||||
<span class="line" id="L60">}</span>
|
||||
<span class="line" id="L61"></span>
|
||||
</code></pre></body>
|
||||
</html>
|
|
@ -1,202 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>tls.zig - source view</title>
|
||||
<link rel="icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAgklEQVR4AWMYWuD7EllJIM4G4g4g5oIJ/odhOJ8wToOxSTXgNxDHoeiBMfA4+wGShjyYOCkG/IGqWQziEzYAoUAeiF9D5U+DxEg14DRU7jWIT5IBIOdCxf+A+CQZAAoopEB7QJwBCBwHiip8UYmRdrAlDpIMgApwQZNnNii5Dq0MBgCxxycBnwEd+wAAAABJRU5ErkJggg==">
|
||||
<link rel="icon" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNTMgMTQwIj48ZyBmaWxsPSIjRjdBNDFEIj48Zz48cG9seWdvbiBwb2ludHM9IjQ2LDIyIDI4LDQ0IDE5LDMwIi8+PHBvbHlnb24gcG9pbnRzPSI0NiwyMiAzMywzMyAyOCw0NCAyMiw0NCAyMiw5NSAzMSw5NSAyMCwxMDAgMTIsMTE3IDAsMTE3IDAsMjIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMzEsOTUgMTIsMTE3IDQsMTA2Ii8+PC9nPjxnPjxwb2x5Z29uIHBvaW50cz0iNTYsMjIgNjIsMzYgMzcsNDQiLz48cG9seWdvbiBwb2ludHM9IjU2LDIyIDExMSwyMiAxMTEsNDQgMzcsNDQgNTYsMzIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTE2LDk1IDk3LDExNyA5MCwxMDQiLz48cG9seWdvbiBwb2ludHM9IjExNiw5NSAxMDAsMTA0IDk3LDExNyA0MiwxMTcgNDIsOTUiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTUwLDAgNTIsMTE3IDMsMTQwIDEwMSwyMiIvPjwvZz48Zz48cG9seWdvbiBwb2ludHM9IjE0MSwyMiAxNDAsNDAgMTIyLDQ1Ii8+PHBvbHlnb24gcG9pbnRzPSIxNTMsMjIgMTUzLDExNyAxMDYsMTE3IDEyMCwxMDUgMTI1LDk1IDEzMSw5NSAxMzEsNDUgMTIyLDQ1IDEzMiwzNiAxNDEsMjIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTI1LDk1IDEzMCwxMTAgMTA2LDExNyIvPjwvZz48L2c+PC9zdmc+">
|
||||
<style>
|
||||
body{
|
||||
font-family: system-ui, -apple-system, Roboto, "Segoe UI", sans-serif;
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
pre > code {
|
||||
display: block;
|
||||
overflow: auto;
|
||||
line-height: normal;
|
||||
margin: 0em;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-str {
|
||||
color: #d14;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #005C7A;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #545454;
|
||||
font-style: italic;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #900;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-null {
|
||||
color: #005C5C;
|
||||
}
|
||||
.tok-number {
|
||||
color: #005C5C;
|
||||
}
|
||||
.tok-type {
|
||||
color: #458;
|
||||
font-weight: bold;
|
||||
}
|
||||
pre {
|
||||
counter-reset: line;
|
||||
}
|
||||
pre .line:before {
|
||||
counter-increment: line;
|
||||
content: counter(line);
|
||||
display: inline-block;
|
||||
padding-right: 1em;
|
||||
width: 2em;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.line {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
.line:target {
|
||||
border-top: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ccc;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body{
|
||||
background:#222;
|
||||
color: #ccc;
|
||||
}
|
||||
pre > code {
|
||||
color: #ccc;
|
||||
background: #222;
|
||||
border: unset;
|
||||
}
|
||||
.line:target {
|
||||
border-top: 1px solid #444;
|
||||
border-bottom: 1px solid #444;
|
||||
background: #333;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #eee;
|
||||
}
|
||||
.tok-str {
|
||||
color: #2e5;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #ff894c;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #aa7;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #B1A0F8;
|
||||
}
|
||||
.tok-null {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-number {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-type {
|
||||
color: #68f;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre><code><span class="line" id="L1"><span class="tok-kw">const</span> fio = <span class="tok-builtin">@import</span>(<span class="tok-str">"fio.zig"</span>);</span>
|
||||
<span class="line" id="L2"></span>
|
||||
<span class="line" id="L3"><span class="tok-comment">/// Server-Side TLS function wrapper</span></span>
|
||||
<span class="line" id="L4"><span class="tok-kw">const</span> Tls = <span class="tok-builtin">@This</span>();</span>
|
||||
<span class="line" id="L5"></span>
|
||||
<span class="line" id="L6">fio_tls: ?*<span class="tok-type">anyopaque</span> = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L7"></span>
|
||||
<span class="line" id="L8"><span class="tok-comment">/// TLS settings used in init() and addCertificate()</span></span>
|
||||
<span class="line" id="L9"><span class="tok-comment">/// If all values are NULL, a TLS object wll be created without a</span></span>
|
||||
<span class="line" id="L10"><span class="tok-comment">/// certificate. This could be used for clients together with Tls.trust().</span></span>
|
||||
<span class="line" id="L11"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> TlsSettings = <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L12"> <span class="tok-comment">/// If a server name is provided, then NULL values _can_ be used to create an anonymous (unverified)</span></span>
|
||||
<span class="line" id="L13"> <span class="tok-comment">/// context / settings object.</span></span>
|
||||
<span class="line" id="L14"> server_name: ?[*:<span class="tok-number">0</span>]<span class="tok-kw">const</span> <span class="tok-type">u8</span> = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L15"> public_certificate_file: ?[*:<span class="tok-number">0</span>]<span class="tok-kw">const</span> <span class="tok-type">u8</span> = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L16"> private_key_file: ?[*:<span class="tok-number">0</span>]<span class="tok-kw">const</span> <span class="tok-type">u8</span> = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L17"> <span class="tok-comment">/// The private_key_password can be NULL if the private key PEM file isn't password protected.</span></span>
|
||||
<span class="line" id="L18"> private_key_password: ?[*:<span class="tok-number">0</span>]<span class="tok-kw">const</span> <span class="tok-type">u8</span> = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L19">};</span>
|
||||
<span class="line" id="L20"></span>
|
||||
<span class="line" id="L21"><span class="tok-comment">/// Creates a new SSL/TLS context / settings object with a default certificate (if any).</span></span>
|
||||
<span class="line" id="L22"><span class="tok-comment">/// If a server name is provided, then NULL values can be used to create an anonymous (unverified)</span></span>
|
||||
<span class="line" id="L23"><span class="tok-comment">/// context / settings object. If all values are NULL, a TLS object will be created without a</span></span>
|
||||
<span class="line" id="L24"><span class="tok-comment">/// certificate. This could be used for clients together with Tls.trust().</span></span>
|
||||
<span class="line" id="L25"><span class="tok-comment">/// The private_key_password can be NULL if the private key PEM file isn't password protected.</span></span>
|
||||
<span class="line" id="L26"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">init</span>(settings: TlsSettings) !Tls {</span>
|
||||
<span class="line" id="L27"> <span class="tok-kw">const</span> ret = fio.fio_tls_new(</span>
|
||||
<span class="line" id="L28"> settings.server_name,</span>
|
||||
<span class="line" id="L29"> settings.public_certificate_file,</span>
|
||||
<span class="line" id="L30"> settings.private_key_file,</span>
|
||||
<span class="line" id="L31"> settings.private_key_password,</span>
|
||||
<span class="line" id="L32"> );</span>
|
||||
<span class="line" id="L33"> <span class="tok-kw">if</span> (ret == <span class="tok-null">null</span>) <span class="tok-kw">return</span> <span class="tok-kw">error</span>.FileNotFound;</span>
|
||||
<span class="line" id="L34"> <span class="tok-kw">return</span> Tls{ .fio_tls = ret };</span>
|
||||
<span class="line" id="L35">}</span>
|
||||
<span class="line" id="L36"></span>
|
||||
<span class="line" id="L37"><span class="tok-comment">/// Destroys the SSL/TLS context / settings object and frees any related resources / memory.</span></span>
|
||||
<span class="line" id="L38"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">deinit</span>(tls: *<span class="tok-kw">const</span> Tls) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L39"> fio.fio_tls_destroy(tls.fio_tls);</span>
|
||||
<span class="line" id="L40">}</span>
|
||||
<span class="line" id="L41"></span>
|
||||
<span class="line" id="L42"><span class="tok-comment">// pub fn incRefCount(tls: *Tls) !void {</span>
|
||||
</span>
|
||||
<span class="line" id="L43"><span class="tok-comment">// if (tls.fio_tls == null) {</span>
|
||||
</span>
|
||||
<span class="line" id="L44"><span class="tok-comment">// return error.Uninitialized;</span>
|
||||
</span>
|
||||
<span class="line" id="L45"><span class="tok-comment">// }</span>
|
||||
</span>
|
||||
<span class="line" id="L46"><span class="tok-comment">// fio.fio_tls_dup(tls.fio_tls);</span>
|
||||
</span>
|
||||
<span class="line" id="L47"><span class="tok-comment">// }</span>
|
||||
</span>
|
||||
<span class="line" id="L48"></span>
|
||||
<span class="line" id="L49"><span class="tok-comment">/// Adds a certificate a new SSL/TLS context / settings object (SNI support).</span></span>
|
||||
<span class="line" id="L50"><span class="tok-comment">/// The private_key_password can be NULL if the private key PEM file isn't password protected.</span></span>
|
||||
<span class="line" id="L51"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">addCertificate</span>(tls: *Tls, settings: TlsSettings) !<span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L52"> <span class="tok-kw">if</span> (tls.fio_tls == <span class="tok-null">null</span>) {</span>
|
||||
<span class="line" id="L53"> <span class="tok-kw">return</span> <span class="tok-kw">error</span>.Uninitialized;</span>
|
||||
<span class="line" id="L54"> }</span>
|
||||
<span class="line" id="L55"></span>
|
||||
<span class="line" id="L56"> <span class="tok-kw">const</span> ret = fio.fio_tls_cert_add(</span>
|
||||
<span class="line" id="L57"> tls.fio_tls,</span>
|
||||
<span class="line" id="L58"> settings.server_name,</span>
|
||||
<span class="line" id="L59"> settings.public_certificate_file,</span>
|
||||
<span class="line" id="L60"> settings.private_key_file,</span>
|
||||
<span class="line" id="L61"> settings.private_key_password,</span>
|
||||
<span class="line" id="L62"> );</span>
|
||||
<span class="line" id="L63"></span>
|
||||
<span class="line" id="L64"> <span class="tok-kw">if</span> (ret != <span class="tok-number">0</span>) <span class="tok-kw">return</span> <span class="tok-kw">error</span>.FileNotFound;</span>
|
||||
<span class="line" id="L65"> <span class="tok-kw">return</span>;</span>
|
||||
<span class="line" id="L66">}</span>
|
||||
<span class="line" id="L67"></span>
|
||||
<span class="line" id="L68"><span class="tok-comment">/// Adds a certificate to the "trust" list, which automatically adds a peer verification requirement.</span></span>
|
||||
<span class="line" id="L69"><span class="tok-comment">/// Note: when the fio_tls_s object is used for server connections, this will limit connections to</span></span>
|
||||
<span class="line" id="L70"><span class="tok-comment">/// clients that connect using a trusted certificate.</span></span>
|
||||
<span class="line" id="L71"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">trust</span>(tls: *Tls, public_cert_file: [*:<span class="tok-number">0</span>]<span class="tok-kw">const</span> <span class="tok-type">u8</span>) !<span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L72"> <span class="tok-kw">if</span> (tls.fio_tls == <span class="tok-null">null</span>) {</span>
|
||||
<span class="line" id="L73"> <span class="tok-kw">return</span> <span class="tok-kw">error</span>.Uninitialized;</span>
|
||||
<span class="line" id="L74"> }</span>
|
||||
<span class="line" id="L75"></span>
|
||||
<span class="line" id="L76"> <span class="tok-kw">const</span> ret = fio.fio_tls_trust(tls.fio_tls, public_cert_file);</span>
|
||||
<span class="line" id="L77"> <span class="tok-kw">if</span> (ret != <span class="tok-number">0</span>) <span class="tok-kw">return</span> <span class="tok-kw">error</span>.FileNotFound;</span>
|
||||
<span class="line" id="L78"> <span class="tok-kw">return</span>;</span>
|
||||
<span class="line" id="L79">}</span>
|
||||
<span class="line" id="L80"></span>
|
||||
</code></pre></body>
|
||||
</html>
|
|
@ -1,226 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>util.zig - source view</title>
|
||||
<link rel="icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAgklEQVR4AWMYWuD7EllJIM4G4g4g5oIJ/odhOJ8wToOxSTXgNxDHoeiBMfA4+wGShjyYOCkG/IGqWQziEzYAoUAeiF9D5U+DxEg14DRU7jWIT5IBIOdCxf+A+CQZAAoopEB7QJwBCBwHiip8UYmRdrAlDpIMgApwQZNnNii5Dq0MBgCxxycBnwEd+wAAAABJRU5ErkJggg==">
|
||||
<link rel="icon" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNTMgMTQwIj48ZyBmaWxsPSIjRjdBNDFEIj48Zz48cG9seWdvbiBwb2ludHM9IjQ2LDIyIDI4LDQ0IDE5LDMwIi8+PHBvbHlnb24gcG9pbnRzPSI0NiwyMiAzMywzMyAyOCw0NCAyMiw0NCAyMiw5NSAzMSw5NSAyMCwxMDAgMTIsMTE3IDAsMTE3IDAsMjIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMzEsOTUgMTIsMTE3IDQsMTA2Ii8+PC9nPjxnPjxwb2x5Z29uIHBvaW50cz0iNTYsMjIgNjIsMzYgMzcsNDQiLz48cG9seWdvbiBwb2ludHM9IjU2LDIyIDExMSwyMiAxMTEsNDQgMzcsNDQgNTYsMzIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTE2LDk1IDk3LDExNyA5MCwxMDQiLz48cG9seWdvbiBwb2ludHM9IjExNiw5NSAxMDAsMTA0IDk3LDExNyA0MiwxMTcgNDIsOTUiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTUwLDAgNTIsMTE3IDMsMTQwIDEwMSwyMiIvPjwvZz48Zz48cG9seWdvbiBwb2ludHM9IjE0MSwyMiAxNDAsNDAgMTIyLDQ1Ii8+PHBvbHlnb24gcG9pbnRzPSIxNTMsMjIgMTUzLDExNyAxMDYsMTE3IDEyMCwxMDUgMTI1LDk1IDEzMSw5NSAxMzEsNDUgMTIyLDQ1IDEzMiwzNiAxNDEsMjIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTI1LDk1IDEzMCwxMTAgMTA2LDExNyIvPjwvZz48L2c+PC9zdmc+">
|
||||
<style>
|
||||
body{
|
||||
font-family: system-ui, -apple-system, Roboto, "Segoe UI", sans-serif;
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
pre > code {
|
||||
display: block;
|
||||
overflow: auto;
|
||||
line-height: normal;
|
||||
margin: 0em;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-str {
|
||||
color: #d14;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #005C7A;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #545454;
|
||||
font-style: italic;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #900;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-null {
|
||||
color: #005C5C;
|
||||
}
|
||||
.tok-number {
|
||||
color: #005C5C;
|
||||
}
|
||||
.tok-type {
|
||||
color: #458;
|
||||
font-weight: bold;
|
||||
}
|
||||
pre {
|
||||
counter-reset: line;
|
||||
}
|
||||
pre .line:before {
|
||||
counter-increment: line;
|
||||
content: counter(line);
|
||||
display: inline-block;
|
||||
padding-right: 1em;
|
||||
width: 2em;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.line {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
.line:target {
|
||||
border-top: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ccc;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body{
|
||||
background:#222;
|
||||
color: #ccc;
|
||||
}
|
||||
pre > code {
|
||||
color: #ccc;
|
||||
background: #222;
|
||||
border: unset;
|
||||
}
|
||||
.line:target {
|
||||
border-top: 1px solid #444;
|
||||
border-bottom: 1px solid #444;
|
||||
background: #333;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #eee;
|
||||
}
|
||||
.tok-str {
|
||||
color: #2e5;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #ff894c;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #aa7;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #B1A0F8;
|
||||
}
|
||||
.tok-null {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-number {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-type {
|
||||
color: #68f;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre><code><span class="line" id="L1"><span class="tok-kw">const</span> std = <span class="tok-builtin">@import</span>(<span class="tok-str">"std"</span>);</span>
|
||||
<span class="line" id="L2"><span class="tok-kw">const</span> fio = <span class="tok-builtin">@import</span>(<span class="tok-str">"fio.zig"</span>);</span>
|
||||
<span class="line" id="L3"><span class="tok-kw">const</span> zap = <span class="tok-builtin">@import</span>(<span class="tok-str">"zap.zig"</span>);</span>
|
||||
<span class="line" id="L4"></span>
|
||||
<span class="line" id="L5"><span class="tok-comment">/// capture self for RequestFn signature support</span></span>
|
||||
<span class="line" id="L6"><span class="tok-kw">pub</span> <span class="tok-kw">inline</span> <span class="tok-kw">fn</span> <span class="tok-fn">RequestHandler</span>(self: <span class="tok-kw">anytype</span>, func: *<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (<span class="tok-builtin">@TypeOf</span>(self), zap.Request) <span class="tok-type">void</span>) *<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (zap.Request) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L7"> <span class="tok-kw">return</span> (<span class="tok-kw">opaque</span> {</span>
|
||||
<span class="line" id="L8"> <span class="tok-kw">var</span> hidden_self: <span class="tok-builtin">@TypeOf</span>(self) = <span class="tok-null">undefined</span>;</span>
|
||||
<span class="line" id="L9"> <span class="tok-kw">var</span> hidden_func: *<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (<span class="tok-builtin">@TypeOf</span>(self), zap.Request) <span class="tok-type">void</span> = <span class="tok-null">undefined</span>;</span>
|
||||
<span class="line" id="L10"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">init</span>(h_self: <span class="tok-builtin">@TypeOf</span>(self), h_func: *<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (<span class="tok-builtin">@TypeOf</span>(self), zap.Request) <span class="tok-type">void</span>) *<span class="tok-kw">const</span> <span class="tok-builtin">@TypeOf</span>(run) {</span>
|
||||
<span class="line" id="L11"> hidden_self = h_self;</span>
|
||||
<span class="line" id="L12"> hidden_func = h_func;</span>
|
||||
<span class="line" id="L13"> <span class="tok-kw">return</span> &run;</span>
|
||||
<span class="line" id="L14"> }</span>
|
||||
<span class="line" id="L15"></span>
|
||||
<span class="line" id="L16"> <span class="tok-kw">fn</span> <span class="tok-fn">run</span>(req: zap.Request) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L17"> hidden_func(hidden_self, req);</span>
|
||||
<span class="line" id="L18"> }</span>
|
||||
<span class="line" id="L19"> }).init(self, func);</span>
|
||||
<span class="line" id="L20">}</span>
|
||||
<span class="line" id="L21"></span>
|
||||
<span class="line" id="L22"><span class="tok-comment">/// Used internally: convert a FIO object into its string representation.</span></span>
|
||||
<span class="line" id="L23"><span class="tok-comment">/// note: since this is called from within request functions, we don't make</span></span>
|
||||
<span class="line" id="L24"><span class="tok-comment">/// copies. Also, we return temp memory from fio. -> don't hold on to it outside</span></span>
|
||||
<span class="line" id="L25"><span class="tok-comment">/// of a request function. FIO temp memory strings do not need to be freed.</span></span>
|
||||
<span class="line" id="L26"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">fio2str</span>(o: fio.FIOBJ) ?[]<span class="tok-kw">const</span> <span class="tok-type">u8</span> {</span>
|
||||
<span class="line" id="L27"> <span class="tok-kw">if</span> (o == <span class="tok-number">0</span>) <span class="tok-kw">return</span> <span class="tok-null">null</span>;</span>
|
||||
<span class="line" id="L28"> <span class="tok-kw">const</span> x: fio.fio_str_info_s = fio.fiobj_obj2cstr(o);</span>
|
||||
<span class="line" id="L29"> <span class="tok-kw">if</span> (x.data == <span class="tok-number">0</span>)</span>
|
||||
<span class="line" id="L30"> <span class="tok-kw">return</span> <span class="tok-null">null</span>; <span class="tok-comment">// TODO: should we return an error? Actually, looking at fiobj_obj2cstr, this is unreachable</span>
|
||||
</span>
|
||||
<span class="line" id="L31"> <span class="tok-kw">return</span> x.data[<span class="tok-number">0</span>..x.len];</span>
|
||||
<span class="line" id="L32">}</span>
|
||||
<span class="line" id="L33"></span>
|
||||
<span class="line" id="L34"><span class="tok-comment">/// A "string" type used internally that carries a flag whether its buffer needs</span></span>
|
||||
<span class="line" id="L35"><span class="tok-comment">/// to be freed or not - and honors it in `deinit()`. That way, it's always</span></span>
|
||||
<span class="line" id="L36"><span class="tok-comment">/// safe to call deinit().</span></span>
|
||||
<span class="line" id="L37"><span class="tok-comment">/// For instance, slices taken directly from the zap.Request need not be freed.</span></span>
|
||||
<span class="line" id="L38"><span class="tok-comment">/// But the ad-hoc created string representation of a float parameter must be</span></span>
|
||||
<span class="line" id="L39"><span class="tok-comment">/// freed after use.</span></span>
|
||||
<span class="line" id="L40"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> FreeOrNot = <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L41"> str: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L42"> freeme: <span class="tok-type">bool</span>,</span>
|
||||
<span class="line" id="L43"> allocator: ?std.mem.Allocator = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L44"></span>
|
||||
<span class="line" id="L45"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">deinit</span>(self: *<span class="tok-kw">const</span> <span class="tok-builtin">@This</span>()) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L46"> <span class="tok-kw">if</span> (self.freeme) {</span>
|
||||
<span class="line" id="L47"> self.allocator.?.free(self.str);</span>
|
||||
<span class="line" id="L48"> }</span>
|
||||
<span class="line" id="L49"> }</span>
|
||||
<span class="line" id="L50">};</span>
|
||||
<span class="line" id="L51"></span>
|
||||
<span class="line" id="L52"><span class="tok-comment">/// Used internally: convert a FIO object into its string representation.</span></span>
|
||||
<span class="line" id="L53"><span class="tok-comment">/// Depending on the type of the object, a buffer will be created. Hence a</span></span>
|
||||
<span class="line" id="L54"><span class="tok-comment">/// FreeOrNot type is used as the return type.</span></span>
|
||||
<span class="line" id="L55"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">fio2strAllocOrNot</span>(a: std.mem.Allocator, o: fio.FIOBJ, always_alloc: <span class="tok-type">bool</span>) !FreeOrNot {</span>
|
||||
<span class="line" id="L56"> <span class="tok-kw">if</span> (o == <span class="tok-number">0</span>) <span class="tok-kw">return</span> .{ .str = <span class="tok-str">"null"</span>, .freeme = <span class="tok-null">false</span> };</span>
|
||||
<span class="line" id="L57"> <span class="tok-kw">if</span> (o == fio.FIOBJ_INVALID) <span class="tok-kw">return</span> .{ .str = <span class="tok-str">"invalid"</span>, .freeme = <span class="tok-null">false</span> };</span>
|
||||
<span class="line" id="L58"> <span class="tok-kw">return</span> <span class="tok-kw">switch</span> (fio.fiobj_type(o)) {</span>
|
||||
<span class="line" id="L59"> fio.FIOBJ_T_TRUE => .{ .str = <span class="tok-str">"true"</span>, .freeme = <span class="tok-null">false</span> },</span>
|
||||
<span class="line" id="L60"> fio.FIOBJ_T_FALSE => .{ .str = <span class="tok-str">"false"</span>, .freeme = <span class="tok-null">false</span> },</span>
|
||||
<span class="line" id="L61"> <span class="tok-comment">// according to fio2str above, the orelse should never happen</span>
|
||||
</span>
|
||||
<span class="line" id="L62"> fio.FIOBJ_T_NUMBER => .{ .str = <span class="tok-kw">try</span> a.dupe(<span class="tok-type">u8</span>, fio2str(o) <span class="tok-kw">orelse</span> <span class="tok-str">"null"</span>), .freeme = <span class="tok-null">true</span>, .allocator = a },</span>
|
||||
<span class="line" id="L63"> fio.FIOBJ_T_FLOAT => .{ .str = <span class="tok-kw">try</span> a.dupe(<span class="tok-type">u8</span>, fio2str(o) <span class="tok-kw">orelse</span> <span class="tok-str">"null"</span>), .freeme = <span class="tok-null">true</span>, .allocator = a },</span>
|
||||
<span class="line" id="L64"> <span class="tok-comment">// the string comes out of the request, so it is safe to not make a copy</span>
|
||||
</span>
|
||||
<span class="line" id="L65"> fio.FIOBJ_T_STRING => .{ .str = <span class="tok-kw">if</span> (always_alloc) <span class="tok-kw">try</span> a.dupe(<span class="tok-type">u8</span>, fio2str(o) <span class="tok-kw">orelse</span> <span class="tok-str">""</span>) <span class="tok-kw">else</span> fio2str(o) <span class="tok-kw">orelse</span> <span class="tok-str">""</span>, .freeme = <span class="tok-kw">if</span> (always_alloc) <span class="tok-null">true</span> <span class="tok-kw">else</span> <span class="tok-null">false</span>, .allocator = a },</span>
|
||||
<span class="line" id="L66"> <span class="tok-kw">else</span> => .{ .str = <span class="tok-str">"unknown_type"</span>, .freeme = <span class="tok-null">false</span> },</span>
|
||||
<span class="line" id="L67"> };</span>
|
||||
<span class="line" id="L68">}</span>
|
||||
<span class="line" id="L69"></span>
|
||||
<span class="line" id="L70"><span class="tok-comment">/// Used internally: convert a zig slice into a FIO string.</span></span>
|
||||
<span class="line" id="L71"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">str2fio</span>(s: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>) fio.fio_str_info_s {</span>
|
||||
<span class="line" id="L72"> <span class="tok-kw">return</span> .{</span>
|
||||
<span class="line" id="L73"> .data = toCharPtr(s),</span>
|
||||
<span class="line" id="L74"> .len = s.len,</span>
|
||||
<span class="line" id="L75"> .capa = s.len,</span>
|
||||
<span class="line" id="L76"> };</span>
|
||||
<span class="line" id="L77">}</span>
|
||||
<span class="line" id="L78"></span>
|
||||
<span class="line" id="L79"><span class="tok-comment">/// Used internally: convert a zig slice into a C pointer</span></span>
|
||||
<span class="line" id="L80"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">toCharPtr</span>(s: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>) [*c]<span class="tok-type">u8</span> {</span>
|
||||
<span class="line" id="L81"> <span class="tok-kw">return</span> <span class="tok-builtin">@as</span>([*c]<span class="tok-type">u8</span>, <span class="tok-builtin">@ptrFromInt</span>(<span class="tok-builtin">@intFromPtr</span>(s.ptr)));</span>
|
||||
<span class="line" id="L82">}</span>
|
||||
<span class="line" id="L83"></span>
|
||||
<span class="line" id="L84"><span class="tok-comment">//</span>
|
||||
</span>
|
||||
<span class="line" id="L85"><span class="tok-comment">// JSON helpers</span>
|
||||
</span>
|
||||
<span class="line" id="L86"><span class="tok-comment">//</span>
|
||||
</span>
|
||||
<span class="line" id="L87"></span>
|
||||
<span class="line" id="L88"><span class="tok-comment">/// Concenience: format an arbitrary value into a JSON string buffer.</span></span>
|
||||
<span class="line" id="L89"><span class="tok-comment">/// Provide your own buf; this function is NOT mutex-protected!</span></span>
|
||||
<span class="line" id="L90"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">stringifyBuf</span>(</span>
|
||||
<span class="line" id="L91"> buffer: []<span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L92"> value: <span class="tok-kw">anytype</span>,</span>
|
||||
<span class="line" id="L93"> options: std.json.StringifyOptions,</span>
|
||||
<span class="line" id="L94">) ?[]<span class="tok-kw">const</span> <span class="tok-type">u8</span> {</span>
|
||||
<span class="line" id="L95"> <span class="tok-kw">var</span> fba = std.heap.FixedBufferAllocator.init(buffer);</span>
|
||||
<span class="line" id="L96"> <span class="tok-kw">var</span> string = std.ArrayList(<span class="tok-type">u8</span>).init(fba.allocator());</span>
|
||||
<span class="line" id="L97"> <span class="tok-kw">if</span> (std.json.stringify(value, options, string.writer())) {</span>
|
||||
<span class="line" id="L98"> <span class="tok-kw">return</span> string.items;</span>
|
||||
<span class="line" id="L99"> } <span class="tok-kw">else</span> |_| { <span class="tok-comment">// error</span>
|
||||
</span>
|
||||
<span class="line" id="L100"> <span class="tok-kw">return</span> <span class="tok-null">null</span>;</span>
|
||||
<span class="line" id="L101"> }</span>
|
||||
<span class="line" id="L102">}</span>
|
||||
<span class="line" id="L103"></span>
|
||||
</code></pre></body>
|
||||
</html>
|
|
@ -1,346 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>websockets.zig - source view</title>
|
||||
<link rel="icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAgklEQVR4AWMYWuD7EllJIM4G4g4g5oIJ/odhOJ8wToOxSTXgNxDHoeiBMfA4+wGShjyYOCkG/IGqWQziEzYAoUAeiF9D5U+DxEg14DRU7jWIT5IBIOdCxf+A+CQZAAoopEB7QJwBCBwHiip8UYmRdrAlDpIMgApwQZNnNii5Dq0MBgCxxycBnwEd+wAAAABJRU5ErkJggg==">
|
||||
<link rel="icon" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNTMgMTQwIj48ZyBmaWxsPSIjRjdBNDFEIj48Zz48cG9seWdvbiBwb2ludHM9IjQ2LDIyIDI4LDQ0IDE5LDMwIi8+PHBvbHlnb24gcG9pbnRzPSI0NiwyMiAzMywzMyAyOCw0NCAyMiw0NCAyMiw5NSAzMSw5NSAyMCwxMDAgMTIsMTE3IDAsMTE3IDAsMjIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMzEsOTUgMTIsMTE3IDQsMTA2Ii8+PC9nPjxnPjxwb2x5Z29uIHBvaW50cz0iNTYsMjIgNjIsMzYgMzcsNDQiLz48cG9seWdvbiBwb2ludHM9IjU2LDIyIDExMSwyMiAxMTEsNDQgMzcsNDQgNTYsMzIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTE2LDk1IDk3LDExNyA5MCwxMDQiLz48cG9seWdvbiBwb2ludHM9IjExNiw5NSAxMDAsMTA0IDk3LDExNyA0MiwxMTcgNDIsOTUiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTUwLDAgNTIsMTE3IDMsMTQwIDEwMSwyMiIvPjwvZz48Zz48cG9seWdvbiBwb2ludHM9IjE0MSwyMiAxNDAsNDAgMTIyLDQ1Ii8+PHBvbHlnb24gcG9pbnRzPSIxNTMsMjIgMTUzLDExNyAxMDYsMTE3IDEyMCwxMDUgMTI1LDk1IDEzMSw5NSAxMzEsNDUgMTIyLDQ1IDEzMiwzNiAxNDEsMjIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTI1LDk1IDEzMCwxMTAgMTA2LDExNyIvPjwvZz48L2c+PC9zdmc+">
|
||||
<style>
|
||||
body{
|
||||
font-family: system-ui, -apple-system, Roboto, "Segoe UI", sans-serif;
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
pre > code {
|
||||
display: block;
|
||||
overflow: auto;
|
||||
line-height: normal;
|
||||
margin: 0em;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-str {
|
||||
color: #d14;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #005C7A;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #545454;
|
||||
font-style: italic;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #900;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-null {
|
||||
color: #005C5C;
|
||||
}
|
||||
.tok-number {
|
||||
color: #005C5C;
|
||||
}
|
||||
.tok-type {
|
||||
color: #458;
|
||||
font-weight: bold;
|
||||
}
|
||||
pre {
|
||||
counter-reset: line;
|
||||
}
|
||||
pre .line:before {
|
||||
counter-increment: line;
|
||||
content: counter(line);
|
||||
display: inline-block;
|
||||
padding-right: 1em;
|
||||
width: 2em;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.line {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
.line:target {
|
||||
border-top: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ccc;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body{
|
||||
background:#222;
|
||||
color: #ccc;
|
||||
}
|
||||
pre > code {
|
||||
color: #ccc;
|
||||
background: #222;
|
||||
border: unset;
|
||||
}
|
||||
.line:target {
|
||||
border-top: 1px solid #444;
|
||||
border-bottom: 1px solid #444;
|
||||
background: #333;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #eee;
|
||||
}
|
||||
.tok-str {
|
||||
color: #2e5;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #ff894c;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #aa7;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #B1A0F8;
|
||||
}
|
||||
.tok-null {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-number {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-type {
|
||||
color: #68f;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre><code><span class="line" id="L1"><span class="tok-kw">const</span> std = <span class="tok-builtin">@import</span>(<span class="tok-str">"std"</span>);</span>
|
||||
<span class="line" id="L2"><span class="tok-kw">const</span> zap = <span class="tok-builtin">@import</span>(<span class="tok-str">"zap.zig"</span>);</span>
|
||||
<span class="line" id="L3"><span class="tok-kw">const</span> fio = <span class="tok-builtin">@import</span>(<span class="tok-str">"fio.zig"</span>);</span>
|
||||
<span class="line" id="L4"><span class="tok-kw">const</span> util = <span class="tok-builtin">@import</span>(<span class="tok-str">"util.zig"</span>);</span>
|
||||
<span class="line" id="L5"></span>
|
||||
<span class="line" id="L6"><span class="tok-comment">/// The Handle type used for WebSocket connections. Do not mess with this.</span></span>
|
||||
<span class="line" id="L7"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> WsHandle = ?*fio.ws_s;</span>
|
||||
<span class="line" id="L8"></span>
|
||||
<span class="line" id="L9"><span class="tok-comment">/// WebSocket Handler. Pass in a Context type and it will give you a struct that</span></span>
|
||||
<span class="line" id="L10"><span class="tok-comment">/// contains all the types and functions you need. See the websocket example</span></span>
|
||||
<span class="line" id="L11"><span class="tok-comment">/// for more details.</span></span>
|
||||
<span class="line" id="L12"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">Handler</span>(<span class="tok-kw">comptime</span> ContextType: <span class="tok-type">type</span>) <span class="tok-type">type</span> {</span>
|
||||
<span class="line" id="L13"> <span class="tok-kw">return</span> <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L14"> <span class="tok-comment">/// OnMessage Callback on a websocket, type.</span></span>
|
||||
<span class="line" id="L15"> <span class="tok-kw">pub</span> <span class="tok-kw">const</span> WsOnMessageFn = *<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (</span>
|
||||
<span class="line" id="L16"> <span class="tok-comment">/// user-provided context, passed in from websocketHttpUpgrade()</span></span>
|
||||
<span class="line" id="L17"> context: ?*ContextType,</span>
|
||||
<span class="line" id="L18"> <span class="tok-comment">/// websocket handle, used to identify the websocket internally</span></span>
|
||||
<span class="line" id="L19"> handle: WsHandle,</span>
|
||||
<span class="line" id="L20"> <span class="tok-comment">/// the received message</span></span>
|
||||
<span class="line" id="L21"> message: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L22"> <span class="tok-comment">/// indicator if message is text or binary</span></span>
|
||||
<span class="line" id="L23"> is_text: <span class="tok-type">bool</span>,</span>
|
||||
<span class="line" id="L24"> ) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L25"></span>
|
||||
<span class="line" id="L26"> <span class="tok-comment">/// Callback (type) when websocket is closed. uuid is a connection identifier,</span></span>
|
||||
<span class="line" id="L27"> <span class="tok-comment">/// it is -1 if a connection could not be established</span></span>
|
||||
<span class="line" id="L28"> <span class="tok-kw">pub</span> <span class="tok-kw">const</span> WsOnCloseFn = *<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (context: ?*ContextType, uuid: <span class="tok-type">isize</span>) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L29"></span>
|
||||
<span class="line" id="L30"> <span class="tok-comment">/// A websocket callback function type. provides the context passed in at</span></span>
|
||||
<span class="line" id="L31"> <span class="tok-comment">/// websocketHttpUpgrade().</span></span>
|
||||
<span class="line" id="L32"> <span class="tok-kw">pub</span> <span class="tok-kw">const</span> WsFn = *<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (context: ?*ContextType, handle: WsHandle) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L33"></span>
|
||||
<span class="line" id="L34"> <span class="tok-comment">/// Websocket connection handler creation settings. Provide the callbacks you need,</span></span>
|
||||
<span class="line" id="L35"> <span class="tok-comment">/// and an optional context.</span></span>
|
||||
<span class="line" id="L36"> <span class="tok-kw">pub</span> <span class="tok-kw">const</span> WebSocketSettings = <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L37"> <span class="tok-comment">/// on_message(context, handle, message, is_text)</span></span>
|
||||
<span class="line" id="L38"> on_message: ?WsOnMessageFn = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L39"> <span class="tok-comment">/// on_open(context)</span></span>
|
||||
<span class="line" id="L40"> on_open: ?WsFn = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L41"> <span class="tok-comment">/// on_ready(context)</span></span>
|
||||
<span class="line" id="L42"> on_ready: ?WsFn = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L43"> <span class="tok-comment">/// on_shutdown(context, uuid)</span></span>
|
||||
<span class="line" id="L44"> on_shutdown: ?WsFn = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L45"> <span class="tok-comment">/// on_close(context)</span></span>
|
||||
<span class="line" id="L46"> on_close: ?WsOnCloseFn = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L47"> <span class="tok-comment">/// passed-in user-defined context</span></span>
|
||||
<span class="line" id="L48"> context: ?*ContextType = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L49"> };</span>
|
||||
<span class="line" id="L50"></span>
|
||||
<span class="line" id="L51"> <span class="tok-comment">/// This function will end the HTTP stage of the connection and attempt to "upgrade" to a WebSockets connection.</span></span>
|
||||
<span class="line" id="L52"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">upgrade</span>(h: [*c]fio.http_s, settings: *WebSocketSettings) WebSocketError!<span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L53"> <span class="tok-kw">const</span> fio_settings: fio.websocket_settings_s = .{</span>
|
||||
<span class="line" id="L54"> .on_message = internal_on_message,</span>
|
||||
<span class="line" id="L55"> .on_open = internal_on_open,</span>
|
||||
<span class="line" id="L56"> .on_ready = internal_on_ready,</span>
|
||||
<span class="line" id="L57"> .on_shutdown = internal_on_shutdown,</span>
|
||||
<span class="line" id="L58"> .on_close = internal_on_close,</span>
|
||||
<span class="line" id="L59"> .udata = settings,</span>
|
||||
<span class="line" id="L60"> };</span>
|
||||
<span class="line" id="L61"> <span class="tok-kw">if</span> (fio.http_upgrade2ws(h, fio_settings) != <span class="tok-number">0</span>) {</span>
|
||||
<span class="line" id="L62"> <span class="tok-kw">return</span> <span class="tok-kw">error</span>.UpgradeError;</span>
|
||||
<span class="line" id="L63"> }</span>
|
||||
<span class="line" id="L64"> }</span>
|
||||
<span class="line" id="L65"></span>
|
||||
<span class="line" id="L66"> <span class="tok-kw">fn</span> <span class="tok-fn">internal_on_message</span>(handle: WsHandle, msg: fio.fio_str_info_s, is_text: <span class="tok-type">u8</span>) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L67"> <span class="tok-kw">const</span> user_provided_settings: ?*WebSocketSettings = <span class="tok-builtin">@as</span>(?*WebSocketSettings, <span class="tok-builtin">@ptrCast</span>(<span class="tok-builtin">@alignCast</span>(fio.websocket_udata_get(handle))));</span>
|
||||
<span class="line" id="L68"> <span class="tok-kw">const</span> message = msg.data[<span class="tok-number">0</span>..msg.len];</span>
|
||||
<span class="line" id="L69"> <span class="tok-kw">if</span> (user_provided_settings) |settings| {</span>
|
||||
<span class="line" id="L70"> <span class="tok-kw">if</span> (settings.on_message) |on_message| {</span>
|
||||
<span class="line" id="L71"> on_message(settings.context, handle, message, is_text == <span class="tok-number">1</span>);</span>
|
||||
<span class="line" id="L72"> }</span>
|
||||
<span class="line" id="L73"> }</span>
|
||||
<span class="line" id="L74"> }</span>
|
||||
<span class="line" id="L75"></span>
|
||||
<span class="line" id="L76"> <span class="tok-kw">fn</span> <span class="tok-fn">internal_on_open</span>(handle: WsHandle) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L77"> <span class="tok-kw">const</span> user_provided_settings: ?*WebSocketSettings = <span class="tok-builtin">@as</span>(?*WebSocketSettings, <span class="tok-builtin">@ptrCast</span>(<span class="tok-builtin">@alignCast</span>(fio.websocket_udata_get(handle))));</span>
|
||||
<span class="line" id="L78"> <span class="tok-kw">if</span> (user_provided_settings) |settings| {</span>
|
||||
<span class="line" id="L79"> <span class="tok-kw">if</span> (settings.on_open) |on_open| {</span>
|
||||
<span class="line" id="L80"> on_open(settings.context, handle);</span>
|
||||
<span class="line" id="L81"> }</span>
|
||||
<span class="line" id="L82"> }</span>
|
||||
<span class="line" id="L83"> }</span>
|
||||
<span class="line" id="L84"></span>
|
||||
<span class="line" id="L85"> <span class="tok-kw">fn</span> <span class="tok-fn">internal_on_ready</span>(handle: WsHandle) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L86"> <span class="tok-kw">const</span> user_provided_settings: ?*WebSocketSettings = <span class="tok-builtin">@as</span>(?*WebSocketSettings, <span class="tok-builtin">@ptrCast</span>(<span class="tok-builtin">@alignCast</span>(fio.websocket_udata_get(handle))));</span>
|
||||
<span class="line" id="L87"> <span class="tok-kw">if</span> (user_provided_settings) |settings| {</span>
|
||||
<span class="line" id="L88"> <span class="tok-kw">if</span> (settings.on_ready) |on_ready| {</span>
|
||||
<span class="line" id="L89"> on_ready(settings.context, handle);</span>
|
||||
<span class="line" id="L90"> }</span>
|
||||
<span class="line" id="L91"> }</span>
|
||||
<span class="line" id="L92"> }</span>
|
||||
<span class="line" id="L93"></span>
|
||||
<span class="line" id="L94"> <span class="tok-kw">fn</span> <span class="tok-fn">internal_on_shutdown</span>(handle: WsHandle) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L95"> <span class="tok-kw">const</span> user_provided_settings: ?*WebSocketSettings = <span class="tok-builtin">@as</span>(?*WebSocketSettings, <span class="tok-builtin">@ptrCast</span>(<span class="tok-builtin">@alignCast</span>(fio.websocket_udata_get(handle))));</span>
|
||||
<span class="line" id="L96"> <span class="tok-kw">if</span> (user_provided_settings) |settings| {</span>
|
||||
<span class="line" id="L97"> <span class="tok-kw">if</span> (settings.on_shutdown) |on_shutdown| {</span>
|
||||
<span class="line" id="L98"> on_shutdown(settings.context, handle);</span>
|
||||
<span class="line" id="L99"> }</span>
|
||||
<span class="line" id="L100"> }</span>
|
||||
<span class="line" id="L101"> }</span>
|
||||
<span class="line" id="L102"></span>
|
||||
<span class="line" id="L103"> <span class="tok-kw">fn</span> <span class="tok-fn">internal_on_close</span>(uuid: <span class="tok-type">isize</span>, udata: ?*<span class="tok-type">anyopaque</span>) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L104"> <span class="tok-kw">const</span> user_provided_settings: ?*WebSocketSettings = <span class="tok-builtin">@as</span>(?*WebSocketSettings, <span class="tok-builtin">@ptrCast</span>(<span class="tok-builtin">@alignCast</span>(udata)));</span>
|
||||
<span class="line" id="L105"> <span class="tok-kw">if</span> (user_provided_settings) |settings| {</span>
|
||||
<span class="line" id="L106"> <span class="tok-kw">if</span> (settings.on_close) |on_close| {</span>
|
||||
<span class="line" id="L107"> on_close(settings.context, uuid);</span>
|
||||
<span class="line" id="L108"> }</span>
|
||||
<span class="line" id="L109"> }</span>
|
||||
<span class="line" id="L110"> }</span>
|
||||
<span class="line" id="L111"></span>
|
||||
<span class="line" id="L112"> <span class="tok-kw">pub</span> <span class="tok-kw">const</span> WebSocketError = <span class="tok-kw">error</span>{</span>
|
||||
<span class="line" id="L113"> WriteError,</span>
|
||||
<span class="line" id="L114"> UpgradeError,</span>
|
||||
<span class="line" id="L115"> SubscribeError,</span>
|
||||
<span class="line" id="L116"> };</span>
|
||||
<span class="line" id="L117"></span>
|
||||
<span class="line" id="L118"> <span class="tok-comment">/// Write to the websocket identified by the handle.</span></span>
|
||||
<span class="line" id="L119"> <span class="tok-kw">pub</span> <span class="tok-kw">inline</span> <span class="tok-kw">fn</span> <span class="tok-fn">write</span>(handle: WsHandle, message: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>, is_text: <span class="tok-type">bool</span>) WebSocketError!<span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L120"> <span class="tok-kw">if</span> (fio.websocket_write(</span>
|
||||
<span class="line" id="L121"> handle,</span>
|
||||
<span class="line" id="L122"> fio.str2fio(message),</span>
|
||||
<span class="line" id="L123"> <span class="tok-kw">if</span> (is_text) <span class="tok-number">1</span> <span class="tok-kw">else</span> <span class="tok-number">0</span>,</span>
|
||||
<span class="line" id="L124"> ) != <span class="tok-number">0</span>) {</span>
|
||||
<span class="line" id="L125"> <span class="tok-kw">return</span> <span class="tok-kw">error</span>.WriteError;</span>
|
||||
<span class="line" id="L126"> }</span>
|
||||
<span class="line" id="L127"> }</span>
|
||||
<span class="line" id="L128"></span>
|
||||
<span class="line" id="L129"> <span class="tok-comment">/// The context pointer is stored in facilio's udata pointer. Use</span></span>
|
||||
<span class="line" id="L130"> <span class="tok-comment">/// this function to turn that pointer into a pointer to your</span></span>
|
||||
<span class="line" id="L131"> <span class="tok-comment">/// ContextType.</span></span>
|
||||
<span class="line" id="L132"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">udataToContext</span>(udata: *<span class="tok-type">anyopaque</span>) *ContextType {</span>
|
||||
<span class="line" id="L133"> <span class="tok-kw">return</span> <span class="tok-builtin">@as</span>(*ContextType, <span class="tok-builtin">@ptrCast</span>(<span class="tok-builtin">@alignCast</span>(udata)));</span>
|
||||
<span class="line" id="L134"> }</span>
|
||||
<span class="line" id="L135"></span>
|
||||
<span class="line" id="L136"> <span class="tok-comment">/// Close the websocket connection.</span></span>
|
||||
<span class="line" id="L137"> <span class="tok-kw">pub</span> <span class="tok-kw">inline</span> <span class="tok-kw">fn</span> <span class="tok-fn">close</span>(handle: WsHandle) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L138"> fio.websocket_close(handle);</span>
|
||||
<span class="line" id="L139"> }</span>
|
||||
<span class="line" id="L140"></span>
|
||||
<span class="line" id="L141"> <span class="tok-comment">/// Settings for publishing a message in a channel.</span></span>
|
||||
<span class="line" id="L142"> <span class="tok-kw">const</span> PublishArgs = <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L143"> channel: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L144"> message: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L145"> is_json: <span class="tok-type">bool</span> = <span class="tok-null">false</span>,</span>
|
||||
<span class="line" id="L146"> };</span>
|
||||
<span class="line" id="L147"></span>
|
||||
<span class="line" id="L148"> <span class="tok-comment">/// Publish a message in a channel.</span></span>
|
||||
<span class="line" id="L149"> <span class="tok-kw">pub</span> <span class="tok-kw">inline</span> <span class="tok-kw">fn</span> <span class="tok-fn">publish</span>(args: PublishArgs) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L150"> fio.fio_publish(.{</span>
|
||||
<span class="line" id="L151"> .channel = util.str2fio(args.channel),</span>
|
||||
<span class="line" id="L152"> .message = util.str2fio(args.message),</span>
|
||||
<span class="line" id="L153"> .is_json = <span class="tok-kw">if</span> (args.is_json) <span class="tok-number">1</span> <span class="tok-kw">else</span> <span class="tok-number">0</span>,</span>
|
||||
<span class="line" id="L154"> });</span>
|
||||
<span class="line" id="L155"> }</span>
|
||||
<span class="line" id="L156"></span>
|
||||
<span class="line" id="L157"> <span class="tok-comment">/// Type for callback on subscription message.</span></span>
|
||||
<span class="line" id="L158"> <span class="tok-kw">pub</span> <span class="tok-kw">const</span> SubscriptionOnMessageFn = *<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (context: ?*ContextType, handle: WsHandle, channel: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>, message: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L159"></span>
|
||||
<span class="line" id="L160"> <span class="tok-comment">/// Type for callback on unsubscribe message.</span></span>
|
||||
<span class="line" id="L161"> <span class="tok-kw">pub</span> <span class="tok-kw">const</span> SubscriptionOnUnsubscribeFn = *<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (context: ?*ContextType) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L162"></span>
|
||||
<span class="line" id="L163"> <span class="tok-comment">/// Settings for subscribing to a channel.</span></span>
|
||||
<span class="line" id="L164"> <span class="tok-kw">pub</span> <span class="tok-kw">const</span> SubscribeArgs = <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L165"> <span class="tok-comment">/// channel name</span></span>
|
||||
<span class="line" id="L166"> channel: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>,</span>
|
||||
<span class="line" id="L167"> <span class="tok-comment">/// on message callback</span></span>
|
||||
<span class="line" id="L168"> on_message: ?SubscriptionOnMessageFn = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L169"> <span class="tok-comment">/// on unsubscribe callback</span></span>
|
||||
<span class="line" id="L170"> on_unsubscribe: ?SubscriptionOnUnsubscribeFn = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L171"> <span class="tok-comment">/// this is not wrapped nicely yet</span></span>
|
||||
<span class="line" id="L172"> match: fio.fio_match_fn = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L173"> <span class="tok-comment">/// When using direct message forwarding (no on_message callback), this indicates if</span></span>
|
||||
<span class="line" id="L174"> <span class="tok-comment">/// messages should be sent to the client as binary blobs, which is the safest approach.</span></span>
|
||||
<span class="line" id="L175"> <span class="tok-comment">/// By default, facil.io will test for UTF-8 data validity and send the data as text if</span></span>
|
||||
<span class="line" id="L176"> <span class="tok-comment">/// it's a valid UTF-8. Messages above ~32Kb might be assumed to be binary rather than</span></span>
|
||||
<span class="line" id="L177"> <span class="tok-comment">/// tested.</span></span>
|
||||
<span class="line" id="L178"> force_binary: <span class="tok-type">bool</span> = <span class="tok-null">false</span>,</span>
|
||||
<span class="line" id="L179"> <span class="tok-comment">/// When using direct message forwarding (no on_message callback), this indicates if</span></span>
|
||||
<span class="line" id="L180"> <span class="tok-comment">/// messages should be sent to the client as UTF-8 text. By default, facil.io will test</span></span>
|
||||
<span class="line" id="L181"> <span class="tok-comment">/// for UTF-8 data validity and send the data as text if it's a valid UTF-8. Messages</span></span>
|
||||
<span class="line" id="L182"> <span class="tok-comment">/// above ~32Kb might be assumed to be binary rather than tested. force_binary has</span></span>
|
||||
<span class="line" id="L183"> <span class="tok-comment">/// precedence over force_text.</span></span>
|
||||
<span class="line" id="L184"> force_text: <span class="tok-type">bool</span> = <span class="tok-null">false</span>,</span>
|
||||
<span class="line" id="L185"> <span class="tok-comment">/// your provided arbitrary context</span></span>
|
||||
<span class="line" id="L186"> context: ?*ContextType = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L187"> };</span>
|
||||
<span class="line" id="L188"></span>
|
||||
<span class="line" id="L189"> <span class="tok-comment">/// Subscribe to a channel.</span></span>
|
||||
<span class="line" id="L190"> <span class="tok-comment">/// Returns a subscription ID on success and 0 on failure.</span></span>
|
||||
<span class="line" id="L191"> <span class="tok-comment">/// we copy the pointer so make sure the struct stays valid.</span></span>
|
||||
<span class="line" id="L192"> <span class="tok-comment">/// we need it to look up the ziggified callbacks.</span></span>
|
||||
<span class="line" id="L193"> <span class="tok-kw">pub</span> <span class="tok-kw">inline</span> <span class="tok-kw">fn</span> <span class="tok-fn">subscribe</span>(handle: WsHandle, args: *SubscribeArgs) WebSocketError!<span class="tok-type">usize</span> {</span>
|
||||
<span class="line" id="L194"> <span class="tok-kw">if</span> (handle == <span class="tok-null">null</span>) <span class="tok-kw">return</span> <span class="tok-kw">error</span>.SubscribeError;</span>
|
||||
<span class="line" id="L195"> <span class="tok-kw">const</span> fio_args: fio.websocket_subscribe_s_zigcompat = .{</span>
|
||||
<span class="line" id="L196"> .ws = handle.?,</span>
|
||||
<span class="line" id="L197"> .channel = util.str2fio(args.channel),</span>
|
||||
<span class="line" id="L198"> .on_message = <span class="tok-kw">if</span> (args.on_message) |_| internal_subscription_on_message <span class="tok-kw">else</span> <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L199"> .on_unsubscribe = <span class="tok-kw">if</span> (args.on_unsubscribe) |_| internal_subscription_on_unsubscribe <span class="tok-kw">else</span> <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L200"> .match = args.match,</span>
|
||||
<span class="line" id="L201"> .force_binary = <span class="tok-kw">if</span> (args.force_binary) <span class="tok-number">1</span> <span class="tok-kw">else</span> <span class="tok-number">0</span>,</span>
|
||||
<span class="line" id="L202"> .force_text = <span class="tok-kw">if</span> (args.force_text) <span class="tok-number">1</span> <span class="tok-kw">else</span> <span class="tok-number">0</span>,</span>
|
||||
<span class="line" id="L203"> .udata = args,</span>
|
||||
<span class="line" id="L204"> };</span>
|
||||
<span class="line" id="L205"> <span class="tok-kw">const</span> ret = fio.websocket_subscribe_zigcompat(fio_args);</span>
|
||||
<span class="line" id="L206"> <span class="tok-kw">if</span> (ret == <span class="tok-number">0</span>) {</span>
|
||||
<span class="line" id="L207"> <span class="tok-kw">return</span> <span class="tok-kw">error</span>.SubscribeError;</span>
|
||||
<span class="line" id="L208"> }</span>
|
||||
<span class="line" id="L209"> <span class="tok-kw">return</span> ret;</span>
|
||||
<span class="line" id="L210"> }</span>
|
||||
<span class="line" id="L211"></span>
|
||||
<span class="line" id="L212"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">internal_subscription_on_message</span>(handle: WsHandle, channel: fio.fio_str_info_s, message: fio.fio_str_info_s, udata: ?*<span class="tok-type">anyopaque</span>) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L213"> <span class="tok-kw">if</span> (udata) |p| {</span>
|
||||
<span class="line" id="L214"> <span class="tok-kw">const</span> args = <span class="tok-builtin">@as</span>(*SubscribeArgs, <span class="tok-builtin">@ptrCast</span>(<span class="tok-builtin">@alignCast</span>(p)));</span>
|
||||
<span class="line" id="L215"> <span class="tok-kw">if</span> (args.on_message) |on_message| {</span>
|
||||
<span class="line" id="L216"> on_message(args.context, handle, channel.data[<span class="tok-number">0</span>..channel.len], message.data[<span class="tok-number">0</span>..message.len]);</span>
|
||||
<span class="line" id="L217"> }</span>
|
||||
<span class="line" id="L218"> }</span>
|
||||
<span class="line" id="L219"> }</span>
|
||||
<span class="line" id="L220"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">internal_subscription_on_unsubscribe</span>(udata: ?*<span class="tok-type">anyopaque</span>) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L221"> <span class="tok-kw">if</span> (udata) |p| {</span>
|
||||
<span class="line" id="L222"> <span class="tok-kw">const</span> args = <span class="tok-builtin">@as</span>(*SubscribeArgs, <span class="tok-builtin">@ptrCast</span>(<span class="tok-builtin">@alignCast</span>(p)));</span>
|
||||
<span class="line" id="L223"> <span class="tok-kw">if</span> (args.on_unsubscribe) |on_unsubscribe| {</span>
|
||||
<span class="line" id="L224"> on_unsubscribe(args.context);</span>
|
||||
<span class="line" id="L225"> }</span>
|
||||
<span class="line" id="L226"> }</span>
|
||||
<span class="line" id="L227"> }</span>
|
||||
<span class="line" id="L228"> };</span>
|
||||
<span class="line" id="L229">}</span>
|
||||
<span class="line" id="L230"></span>
|
||||
</code></pre></body>
|
||||
</html>
|
|
@ -1,550 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>zap.zig - source view</title>
|
||||
<link rel="icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAgklEQVR4AWMYWuD7EllJIM4G4g4g5oIJ/odhOJ8wToOxSTXgNxDHoeiBMfA4+wGShjyYOCkG/IGqWQziEzYAoUAeiF9D5U+DxEg14DRU7jWIT5IBIOdCxf+A+CQZAAoopEB7QJwBCBwHiip8UYmRdrAlDpIMgApwQZNnNii5Dq0MBgCxxycBnwEd+wAAAABJRU5ErkJggg==">
|
||||
<link rel="icon" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNTMgMTQwIj48ZyBmaWxsPSIjRjdBNDFEIj48Zz48cG9seWdvbiBwb2ludHM9IjQ2LDIyIDI4LDQ0IDE5LDMwIi8+PHBvbHlnb24gcG9pbnRzPSI0NiwyMiAzMywzMyAyOCw0NCAyMiw0NCAyMiw5NSAzMSw5NSAyMCwxMDAgMTIsMTE3IDAsMTE3IDAsMjIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMzEsOTUgMTIsMTE3IDQsMTA2Ii8+PC9nPjxnPjxwb2x5Z29uIHBvaW50cz0iNTYsMjIgNjIsMzYgMzcsNDQiLz48cG9seWdvbiBwb2ludHM9IjU2LDIyIDExMSwyMiAxMTEsNDQgMzcsNDQgNTYsMzIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTE2LDk1IDk3LDExNyA5MCwxMDQiLz48cG9seWdvbiBwb2ludHM9IjExNiw5NSAxMDAsMTA0IDk3LDExNyA0MiwxMTcgNDIsOTUiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTUwLDAgNTIsMTE3IDMsMTQwIDEwMSwyMiIvPjwvZz48Zz48cG9seWdvbiBwb2ludHM9IjE0MSwyMiAxNDAsNDAgMTIyLDQ1Ii8+PHBvbHlnb24gcG9pbnRzPSIxNTMsMjIgMTUzLDExNyAxMDYsMTE3IDEyMCwxMDUgMTI1LDk1IDEzMSw5NSAxMzEsNDUgMTIyLDQ1IDEzMiwzNiAxNDEsMjIiIHNoYXBlLXJlbmRlcmluZz0iY3Jpc3BFZGdlcyIvPjxwb2x5Z29uIHBvaW50cz0iMTI1LDk1IDEzMCwxMTAgMTA2LDExNyIvPjwvZz48L2c+PC9zdmc+">
|
||||
<style>
|
||||
body{
|
||||
font-family: system-ui, -apple-system, Roboto, "Segoe UI", sans-serif;
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
pre > code {
|
||||
display: block;
|
||||
overflow: auto;
|
||||
line-height: normal;
|
||||
margin: 0em;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-str {
|
||||
color: #d14;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #005C7A;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #545454;
|
||||
font-style: italic;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #900;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tok-null {
|
||||
color: #005C5C;
|
||||
}
|
||||
.tok-number {
|
||||
color: #005C5C;
|
||||
}
|
||||
.tok-type {
|
||||
color: #458;
|
||||
font-weight: bold;
|
||||
}
|
||||
pre {
|
||||
counter-reset: line;
|
||||
}
|
||||
pre .line:before {
|
||||
counter-increment: line;
|
||||
content: counter(line);
|
||||
display: inline-block;
|
||||
padding-right: 1em;
|
||||
width: 2em;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.line {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
.line:target {
|
||||
border-top: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ccc;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body{
|
||||
background:#222;
|
||||
color: #ccc;
|
||||
}
|
||||
pre > code {
|
||||
color: #ccc;
|
||||
background: #222;
|
||||
border: unset;
|
||||
}
|
||||
.line:target {
|
||||
border-top: 1px solid #444;
|
||||
border-bottom: 1px solid #444;
|
||||
background: #333;
|
||||
}
|
||||
.tok-kw {
|
||||
color: #eee;
|
||||
}
|
||||
.tok-str {
|
||||
color: #2e5;
|
||||
}
|
||||
.tok-builtin {
|
||||
color: #ff894c;
|
||||
}
|
||||
.tok-comment {
|
||||
color: #aa7;
|
||||
}
|
||||
.tok-fn {
|
||||
color: #B1A0F8;
|
||||
}
|
||||
.tok-null {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-number {
|
||||
color: #ff8080;
|
||||
}
|
||||
.tok-type {
|
||||
color: #68f;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre><code><span class="line" id="L1"><span class="tok-comment">// zig type definitions for facilio lib</span>
|
||||
</span>
|
||||
<span class="line" id="L2"><span class="tok-comment">// or maybe let's just make it zap directly...</span>
|
||||
</span>
|
||||
<span class="line" id="L3"></span>
|
||||
<span class="line" id="L4"><span class="tok-kw">const</span> std = <span class="tok-builtin">@import</span>(<span class="tok-str">"std"</span>);</span>
|
||||
<span class="line" id="L5"></span>
|
||||
<span class="line" id="L6"><span class="tok-comment">/// The facilio C API. No need to use this.</span></span>
|
||||
<span class="line" id="L7"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> fio = <span class="tok-builtin">@import</span>(<span class="tok-str">"fio.zig"</span>);</span>
|
||||
<span class="line" id="L8"></span>
|
||||
<span class="line" id="L9"><span class="tok-comment">/// Server-Side TLS function wrapper</span></span>
|
||||
<span class="line" id="L10"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> Tls = <span class="tok-builtin">@import</span>(<span class="tok-str">"tls.zig"</span>);</span>
|
||||
<span class="line" id="L11"></span>
|
||||
<span class="line" id="L12"><span class="tok-comment">/// Endpoint and supporting types.</span></span>
|
||||
<span class="line" id="L13"><span class="tok-comment">/// Create one and pass in your callbacks. Then,</span></span>
|
||||
<span class="line" id="L14"><span class="tok-comment">/// pass it to a HttpListener's `register()` function to register with the</span></span>
|
||||
<span class="line" id="L15"><span class="tok-comment">/// listener.</span></span>
|
||||
<span class="line" id="L16"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L17"><span class="tok-comment">/// **NOTE**: A common endpoint pattern for zap is to create your own struct</span></span>
|
||||
<span class="line" id="L18"><span class="tok-comment">/// that embeds an Endpoint, provides specific callbacks, and uses</span></span>
|
||||
<span class="line" id="L19"><span class="tok-comment">/// `@fieldParentPtr` to get a reference to itself.</span></span>
|
||||
<span class="line" id="L20"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L21"><span class="tok-comment">/// Example:</span></span>
|
||||
<span class="line" id="L22"><span class="tok-comment">/// A simple endpoint listening on the /stop route that shuts down zap.</span></span>
|
||||
<span class="line" id="L23"><span class="tok-comment">/// The main thread usually continues at the instructions after the call to zap.start().</span></span>
|
||||
<span class="line" id="L24"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L25"><span class="tok-comment">/// ```zig</span></span>
|
||||
<span class="line" id="L26"><span class="tok-comment">/// const StopEndpoint = struct {</span></span>
|
||||
<span class="line" id="L27"><span class="tok-comment">/// ep: zap.Endpoint = undefined,</span></span>
|
||||
<span class="line" id="L28"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L29"><span class="tok-comment">/// pub fn init(</span></span>
|
||||
<span class="line" id="L30"><span class="tok-comment">/// path: []const u8,</span></span>
|
||||
<span class="line" id="L31"><span class="tok-comment">/// ) StopEndpoint {</span></span>
|
||||
<span class="line" id="L32"><span class="tok-comment">/// return .{</span></span>
|
||||
<span class="line" id="L33"><span class="tok-comment">/// .ep = zap.Endpoint.init(.{</span></span>
|
||||
<span class="line" id="L34"><span class="tok-comment">/// .path = path,</span></span>
|
||||
<span class="line" id="L35"><span class="tok-comment">/// .get = get,</span></span>
|
||||
<span class="line" id="L36"><span class="tok-comment">/// }),</span></span>
|
||||
<span class="line" id="L37"><span class="tok-comment">/// };</span></span>
|
||||
<span class="line" id="L38"><span class="tok-comment">/// }</span></span>
|
||||
<span class="line" id="L39"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L40"><span class="tok-comment">/// // access the internal Endpoint</span></span>
|
||||
<span class="line" id="L41"><span class="tok-comment">/// pub fn endpoint(self: *StopEndpoint) *zap.Endpoint {</span></span>
|
||||
<span class="line" id="L42"><span class="tok-comment">/// return &self.ep;</span></span>
|
||||
<span class="line" id="L43"><span class="tok-comment">/// }</span></span>
|
||||
<span class="line" id="L44"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L45"><span class="tok-comment">/// fn get(e: *zap.Endpoint, r: zap.Request) void {</span></span>
|
||||
<span class="line" id="L46"><span class="tok-comment">/// const self: *StopEndpoint = @fieldParentPtr(StopEndpoint, "ep", e);</span></span>
|
||||
<span class="line" id="L47"><span class="tok-comment">/// _ = self;</span></span>
|
||||
<span class="line" id="L48"><span class="tok-comment">/// _ = r;</span></span>
|
||||
<span class="line" id="L49"><span class="tok-comment">/// zap.stop();</span></span>
|
||||
<span class="line" id="L50"><span class="tok-comment">/// }</span></span>
|
||||
<span class="line" id="L51"><span class="tok-comment">/// };</span></span>
|
||||
<span class="line" id="L52"><span class="tok-comment">/// ```</span></span>
|
||||
<span class="line" id="L53"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> Endpoint = <span class="tok-builtin">@import</span>(<span class="tok-str">"endpoint.zig"</span>);</span>
|
||||
<span class="line" id="L54"></span>
|
||||
<span class="line" id="L55"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> Router = <span class="tok-builtin">@import</span>(<span class="tok-str">"router.zig"</span>);</span>
|
||||
<span class="line" id="L56"></span>
|
||||
<span class="line" id="L57"><span class="tok-kw">pub</span> <span class="tok-kw">usingnamespace</span> <span class="tok-builtin">@import</span>(<span class="tok-str">"util.zig"</span>);</span>
|
||||
<span class="line" id="L58"><span class="tok-kw">pub</span> <span class="tok-kw">usingnamespace</span> <span class="tok-builtin">@import</span>(<span class="tok-str">"http.zig"</span>);</span>
|
||||
<span class="line" id="L59"></span>
|
||||
<span class="line" id="L60"><span class="tok-comment">/// A struct to handle Mustache templating.</span></span>
|
||||
<span class="line" id="L61"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L62"><span class="tok-comment">/// This is a wrapper around fiobj's mustache template handling.</span></span>
|
||||
<span class="line" id="L63"><span class="tok-comment">/// See http://facil.io/0.7.x/fiobj_mustache for more information.</span></span>
|
||||
<span class="line" id="L64"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> Mustache = <span class="tok-builtin">@import</span>(<span class="tok-str">"mustache.zig"</span>);</span>
|
||||
<span class="line" id="L65"></span>
|
||||
<span class="line" id="L66"><span class="tok-comment">/// Authenticators</span></span>
|
||||
<span class="line" id="L67"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> Auth = <span class="tok-builtin">@import</span>(<span class="tok-str">"http_auth.zig"</span>);</span>
|
||||
<span class="line" id="L68"></span>
|
||||
<span class="line" id="L69"><span class="tok-comment">/// Http request and supporting types.</span></span>
|
||||
<span class="line" id="L70"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> Request = <span class="tok-builtin">@import</span>(<span class="tok-str">"request.zig"</span>);</span>
|
||||
<span class="line" id="L71"></span>
|
||||
<span class="line" id="L72"><span class="tok-comment">/// Middleware support.</span></span>
|
||||
<span class="line" id="L73"><span class="tok-comment">/// Contains a special Listener and a Handler struct that support chaining</span></span>
|
||||
<span class="line" id="L74"><span class="tok-comment">/// requests handlers, with an optional stop once a handler indicates it</span></span>
|
||||
<span class="line" id="L75"><span class="tok-comment">/// processed the request. Also sports an EndpointHandler for using regular zap</span></span>
|
||||
<span class="line" id="L76"><span class="tok-comment">/// Endpoints as Handlers.</span></span>
|
||||
<span class="line" id="L77"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> Middleware = <span class="tok-builtin">@import</span>(<span class="tok-str">"middleware.zig"</span>);</span>
|
||||
<span class="line" id="L78"></span>
|
||||
<span class="line" id="L79"><span class="tok-comment">/// Websocket API</span></span>
|
||||
<span class="line" id="L80"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> WebSockets = <span class="tok-builtin">@import</span>(<span class="tok-str">"websockets.zig"</span>);</span>
|
||||
<span class="line" id="L81"></span>
|
||||
<span class="line" id="L82"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> Log = <span class="tok-builtin">@import</span>(<span class="tok-str">"log.zig"</span>);</span>
|
||||
<span class="line" id="L83"><span class="tok-kw">const</span> http = <span class="tok-builtin">@import</span>(<span class="tok-str">"http.zig"</span>);</span>
|
||||
<span class="line" id="L84"></span>
|
||||
<span class="line" id="L85"><span class="tok-kw">const</span> util = <span class="tok-builtin">@import</span>(<span class="tok-str">"util.zig"</span>);</span>
|
||||
<span class="line" id="L86"></span>
|
||||
<span class="line" id="L87"><span class="tok-comment">// TODO: replace with comptime debug logger like in log.zig</span>
|
||||
</span>
|
||||
<span class="line" id="L88"><span class="tok-kw">var</span> _debug: <span class="tok-type">bool</span> = <span class="tok-null">false</span>;</span>
|
||||
<span class="line" id="L89"></span>
|
||||
<span class="line" id="L90"><span class="tok-comment">/// Start the IO reactor</span></span>
|
||||
<span class="line" id="L91"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L92"><span class="tok-comment">/// Will start listeners etc.</span></span>
|
||||
<span class="line" id="L93"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">start</span>(args: fio.fio_start_args) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L94"> fio.fio_start(args);</span>
|
||||
<span class="line" id="L95">}</span>
|
||||
<span class="line" id="L96"></span>
|
||||
<span class="line" id="L97"><span class="tok-comment">/// Stop ZAP:</span></span>
|
||||
<span class="line" id="L98"><span class="tok-comment">///</span></span>
|
||||
<span class="line" id="L99"><span class="tok-comment">/// 1. Stop accepting further incoming requests</span></span>
|
||||
<span class="line" id="L100"><span class="tok-comment">/// 2. Wait for all running request handlers to return</span></span>
|
||||
<span class="line" id="L101"><span class="tok-comment">/// 3. return from `zap.start(...)`</span></span>
|
||||
<span class="line" id="L102"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">stop</span>() <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L103"> fio.fio_stop();</span>
|
||||
<span class="line" id="L104">}</span>
|
||||
<span class="line" id="L105"></span>
|
||||
<span class="line" id="L106"><span class="tok-comment">/// Extremely simplistic zap debug function.</span></span>
|
||||
<span class="line" id="L107"><span class="tok-comment">/// TODO: re-wwrite logging or use std.log</span></span>
|
||||
<span class="line" id="L108"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">debug</span>(<span class="tok-kw">comptime</span> fmt: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>, args: <span class="tok-kw">anytype</span>) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L109"> <span class="tok-kw">if</span> (_debug) {</span>
|
||||
<span class="line" id="L110"> std.debug.print(<span class="tok-str">"[zap] - "</span> ++ fmt, args);</span>
|
||||
<span class="line" id="L111"> }</span>
|
||||
<span class="line" id="L112">}</span>
|
||||
<span class="line" id="L113"></span>
|
||||
<span class="line" id="L114"><span class="tok-comment">/// Enable zap debug logging</span></span>
|
||||
<span class="line" id="L115"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">enableDebugLog</span>() <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L116"> _debug = <span class="tok-null">true</span>;</span>
|
||||
<span class="line" id="L117">}</span>
|
||||
<span class="line" id="L118"></span>
|
||||
<span class="line" id="L119"><span class="tok-comment">/// start Zap with debug logging on</span></span>
|
||||
<span class="line" id="L120"><span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">startWithLogging</span>(args: fio.fio_start_args) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L121"> debug = <span class="tok-null">true</span>;</span>
|
||||
<span class="line" id="L122"> fio.fio_start(args);</span>
|
||||
<span class="line" id="L123">}</span>
|
||||
<span class="line" id="L124"></span>
|
||||
<span class="line" id="L125"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> ListenError = <span class="tok-kw">error</span>{</span>
|
||||
<span class="line" id="L126"> AlreadyListening,</span>
|
||||
<span class="line" id="L127"> ListenError,</span>
|
||||
<span class="line" id="L128">};</span>
|
||||
<span class="line" id="L129"></span>
|
||||
<span class="line" id="L130"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> HttpError = <span class="tok-kw">error</span>{</span>
|
||||
<span class="line" id="L131"> HttpSendBody,</span>
|
||||
<span class="line" id="L132"> HttpSetContentType,</span>
|
||||
<span class="line" id="L133"> HttpSetHeader,</span>
|
||||
<span class="line" id="L134"> HttpParseBody,</span>
|
||||
<span class="line" id="L135"> HttpIterParams,</span>
|
||||
<span class="line" id="L136"> SetCookie,</span>
|
||||
<span class="line" id="L137"> SendFile,</span>
|
||||
<span class="line" id="L138">};</span>
|
||||
<span class="line" id="L139"></span>
|
||||
<span class="line" id="L140"><span class="tok-comment">/// Http Content Type enum.</span></span>
|
||||
<span class="line" id="L141"><span class="tok-comment">/// Needs some love.</span></span>
|
||||
<span class="line" id="L142"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> ContentType = <span class="tok-kw">enum</span> {</span>
|
||||
<span class="line" id="L143"> TEXT,</span>
|
||||
<span class="line" id="L144"> HTML,</span>
|
||||
<span class="line" id="L145"> JSON,</span>
|
||||
<span class="line" id="L146"> <span class="tok-comment">// TODO: more content types</span>
|
||||
</span>
|
||||
<span class="line" id="L147">};</span>
|
||||
<span class="line" id="L148"></span>
|
||||
<span class="line" id="L149"><span class="tok-comment">/// Used internally: facilio Http request callback function type</span></span>
|
||||
<span class="line" id="L150"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> FioHttpRequestFn = *<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (r: [*c]fio.http_s) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L151"></span>
|
||||
<span class="line" id="L152"><span class="tok-comment">/// Zap Http request callback function type.</span></span>
|
||||
<span class="line" id="L153"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> HttpRequestFn = *<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (Request) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L154"></span>
|
||||
<span class="line" id="L155"><span class="tok-comment">/// websocket connection upgrade callback type</span></span>
|
||||
<span class="line" id="L156"><span class="tok-comment">/// fn(request, targetstring)</span></span>
|
||||
<span class="line" id="L157"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> HttpUpgradeFn = *<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (r: Request, target_protocol: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L158"></span>
|
||||
<span class="line" id="L159"><span class="tok-comment">/// http finish, called when zap finishes. You get your udata back in the</span></span>
|
||||
<span class="line" id="L160"><span class="tok-comment">/// HttpFinishSetting struct.</span></span>
|
||||
<span class="line" id="L161"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> HttpFinishSettings = [*c]fio.struct_http_settings_s;</span>
|
||||
<span class="line" id="L162"></span>
|
||||
<span class="line" id="L163"><span class="tok-comment">/// Http finish callback type</span></span>
|
||||
<span class="line" id="L164"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> HttpFinishFn = *<span class="tok-kw">const</span> <span class="tok-kw">fn</span> (HttpFinishSettings) <span class="tok-type">void</span>;</span>
|
||||
<span class="line" id="L165"></span>
|
||||
<span class="line" id="L166"><span class="tok-comment">/// Listener settings</span></span>
|
||||
<span class="line" id="L167"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> HttpListenerSettings = <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L168"> port: <span class="tok-type">usize</span>,</span>
|
||||
<span class="line" id="L169"> interface: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span> = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L170"> on_request: ?HttpRequestFn,</span>
|
||||
<span class="line" id="L171"> on_response: ?HttpRequestFn = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L172"> on_upgrade: ?HttpUpgradeFn = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L173"> on_finish: ?HttpFinishFn = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L174"> <span class="tok-comment">// provide any pointer in there for "user data". it will be passed pack in</span>
|
||||
</span>
|
||||
<span class="line" id="L175"> <span class="tok-comment">// on_finish()'s copy of the struct_http_settings_s</span>
|
||||
</span>
|
||||
<span class="line" id="L176"> udata: ?*<span class="tok-type">anyopaque</span> = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L177"> public_folder: ?[]<span class="tok-kw">const</span> <span class="tok-type">u8</span> = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L178"> max_clients: ?<span class="tok-type">isize</span> = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L179"> max_body_size: ?<span class="tok-type">usize</span> = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L180"> timeout: ?<span class="tok-type">u8</span> = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L181"> log: <span class="tok-type">bool</span> = <span class="tok-null">false</span>,</span>
|
||||
<span class="line" id="L182"> ws_timeout: <span class="tok-type">u8</span> = <span class="tok-number">40</span>,</span>
|
||||
<span class="line" id="L183"> ws_max_msg_size: <span class="tok-type">usize</span> = <span class="tok-number">262144</span>,</span>
|
||||
<span class="line" id="L184"> tls: ?Tls = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L185">};</span>
|
||||
<span class="line" id="L186"></span>
|
||||
<span class="line" id="L187"><span class="tok-comment">/// Http listener</span></span>
|
||||
<span class="line" id="L188"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> HttpListener = <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L189"> settings: HttpListenerSettings,</span>
|
||||
<span class="line" id="L190"></span>
|
||||
<span class="line" id="L191"> <span class="tok-kw">const</span> Self = <span class="tok-builtin">@This</span>();</span>
|
||||
<span class="line" id="L192"> <span class="tok-kw">var</span> the_one_and_only_listener: ?*HttpListener = <span class="tok-null">null</span>;</span>
|
||||
<span class="line" id="L193"></span>
|
||||
<span class="line" id="L194"> <span class="tok-comment">/// Create a listener</span></span>
|
||||
<span class="line" id="L195"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">init</span>(settings: HttpListenerSettings) Self {</span>
|
||||
<span class="line" id="L196"> std.debug.assert(settings.on_request != <span class="tok-null">null</span>);</span>
|
||||
<span class="line" id="L197"> <span class="tok-kw">return</span> .{</span>
|
||||
<span class="line" id="L198"> .settings = settings,</span>
|
||||
<span class="line" id="L199"> };</span>
|
||||
<span class="line" id="L200"> }</span>
|
||||
<span class="line" id="L201"></span>
|
||||
<span class="line" id="L202"> <span class="tok-comment">// we could make it dynamic by passing a HttpListener via udata</span>
|
||||
</span>
|
||||
<span class="line" id="L203"> <span class="tok-comment">/// Used internally: the listener's facilio request callback</span></span>
|
||||
<span class="line" id="L204"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">theOneAndOnlyRequestCallBack</span>(r: [*c]fio.http_s) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L205"> <span class="tok-kw">if</span> (the_one_and_only_listener) |l| {</span>
|
||||
<span class="line" id="L206"> <span class="tok-kw">var</span> req: Request = .{</span>
|
||||
<span class="line" id="L207"> .path = util.fio2str(r.*.path),</span>
|
||||
<span class="line" id="L208"> .query = util.fio2str(r.*.query),</span>
|
||||
<span class="line" id="L209"> .body = util.fio2str(r.*.body),</span>
|
||||
<span class="line" id="L210"> .method = util.fio2str(r.*.method),</span>
|
||||
<span class="line" id="L211"> .h = r,</span>
|
||||
<span class="line" id="L212"> ._is_finished_request_global = <span class="tok-null">false</span>,</span>
|
||||
<span class="line" id="L213"> ._user_context = <span class="tok-null">undefined</span>,</span>
|
||||
<span class="line" id="L214"> };</span>
|
||||
<span class="line" id="L215"> req._is_finished = &req._is_finished_request_global;</span>
|
||||
<span class="line" id="L216"></span>
|
||||
<span class="line" id="L217"> <span class="tok-kw">var</span> user_context: Request.UserContext = .{};</span>
|
||||
<span class="line" id="L218"> req._user_context = &user_context;</span>
|
||||
<span class="line" id="L219"></span>
|
||||
<span class="line" id="L220"> req.markAsFinished(<span class="tok-null">false</span>);</span>
|
||||
<span class="line" id="L221"> std.debug.assert(l.settings.on_request != <span class="tok-null">null</span>);</span>
|
||||
<span class="line" id="L222"> <span class="tok-kw">if</span> (l.settings.on_request) |on_request| {</span>
|
||||
<span class="line" id="L223"> <span class="tok-comment">// l.settings.on_request.?(req);</span>
|
||||
</span>
|
||||
<span class="line" id="L224"> on_request(req);</span>
|
||||
<span class="line" id="L225"> }</span>
|
||||
<span class="line" id="L226"> }</span>
|
||||
<span class="line" id="L227"> }</span>
|
||||
<span class="line" id="L228"></span>
|
||||
<span class="line" id="L229"> <span class="tok-comment">/// Used internally: the listener's facilio response callback</span></span>
|
||||
<span class="line" id="L230"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">theOneAndOnlyResponseCallBack</span>(r: [*c]fio.http_s) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L231"> <span class="tok-kw">if</span> (the_one_and_only_listener) |l| {</span>
|
||||
<span class="line" id="L232"> <span class="tok-kw">var</span> req: Request = .{</span>
|
||||
<span class="line" id="L233"> .path = util.fio2str(r.*.path),</span>
|
||||
<span class="line" id="L234"> .query = util.fio2str(r.*.query),</span>
|
||||
<span class="line" id="L235"> .body = util.fio2str(r.*.body),</span>
|
||||
<span class="line" id="L236"> .method = util.fio2str(r.*.method),</span>
|
||||
<span class="line" id="L237"> .h = r,</span>
|
||||
<span class="line" id="L238"> ._is_finished_request_global = <span class="tok-null">false</span>,</span>
|
||||
<span class="line" id="L239"> ._user_context = <span class="tok-null">undefined</span>,</span>
|
||||
<span class="line" id="L240"> };</span>
|
||||
<span class="line" id="L241"> req._is_finished = &req._is_finished_request_global;</span>
|
||||
<span class="line" id="L242"></span>
|
||||
<span class="line" id="L243"> <span class="tok-kw">var</span> user_context: Request.UserContext = .{};</span>
|
||||
<span class="line" id="L244"> req._user_context = &user_context;</span>
|
||||
<span class="line" id="L245"></span>
|
||||
<span class="line" id="L246"> l.settings.on_response.?(req);</span>
|
||||
<span class="line" id="L247"> }</span>
|
||||
<span class="line" id="L248"> }</span>
|
||||
<span class="line" id="L249"></span>
|
||||
<span class="line" id="L250"> <span class="tok-comment">/// Used internally: the listener's facilio upgrade callback</span></span>
|
||||
<span class="line" id="L251"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">theOneAndOnlyUpgradeCallBack</span>(r: [*c]fio.http_s, target: [*c]<span class="tok-type">u8</span>, target_len: <span class="tok-type">usize</span>) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L252"> <span class="tok-kw">if</span> (the_one_and_only_listener) |l| {</span>
|
||||
<span class="line" id="L253"> <span class="tok-kw">var</span> req: Request = .{</span>
|
||||
<span class="line" id="L254"> .path = util.fio2str(r.*.path),</span>
|
||||
<span class="line" id="L255"> .query = util.fio2str(r.*.query),</span>
|
||||
<span class="line" id="L256"> .body = util.fio2str(r.*.body),</span>
|
||||
<span class="line" id="L257"> .method = util.fio2str(r.*.method),</span>
|
||||
<span class="line" id="L258"> .h = r,</span>
|
||||
<span class="line" id="L259"> ._is_finished_request_global = <span class="tok-null">false</span>,</span>
|
||||
<span class="line" id="L260"> ._user_context = <span class="tok-null">undefined</span>,</span>
|
||||
<span class="line" id="L261"> };</span>
|
||||
<span class="line" id="L262"> <span class="tok-kw">const</span> zigtarget: []<span class="tok-type">u8</span> = target[<span class="tok-number">0</span>..target_len];</span>
|
||||
<span class="line" id="L263"> req._is_finished = &req._is_finished_request_global;</span>
|
||||
<span class="line" id="L264"></span>
|
||||
<span class="line" id="L265"> <span class="tok-kw">var</span> user_context: Request.UserContext = .{};</span>
|
||||
<span class="line" id="L266"> req._user_context = &user_context;</span>
|
||||
<span class="line" id="L267"></span>
|
||||
<span class="line" id="L268"> l.settings.on_upgrade.?(req, zigtarget);</span>
|
||||
<span class="line" id="L269"> }</span>
|
||||
<span class="line" id="L270"> }</span>
|
||||
<span class="line" id="L271"></span>
|
||||
<span class="line" id="L272"> <span class="tok-comment">/// Used internally: the listener's facilio finish callback</span></span>
|
||||
<span class="line" id="L273"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">theOneAndOnlyFinishCallBack</span>(s: [*c]fio.struct_http_settings_s) <span class="tok-kw">callconv</span>(.C) <span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L274"> <span class="tok-kw">if</span> (the_one_and_only_listener) |l| {</span>
|
||||
<span class="line" id="L275"> l.settings.on_finish.?(s);</span>
|
||||
<span class="line" id="L276"> }</span>
|
||||
<span class="line" id="L277"> }</span>
|
||||
<span class="line" id="L278"></span>
|
||||
<span class="line" id="L279"> <span class="tok-comment">/// Start listening</span></span>
|
||||
<span class="line" id="L280"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">listen</span>(self: *Self) !<span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L281"> <span class="tok-kw">var</span> pfolder: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span> = <span class="tok-null">null</span>;</span>
|
||||
<span class="line" id="L282"> <span class="tok-kw">var</span> pfolder_len: <span class="tok-type">usize</span> = <span class="tok-number">0</span>;</span>
|
||||
<span class="line" id="L283"></span>
|
||||
<span class="line" id="L284"> <span class="tok-kw">if</span> (self.settings.public_folder) |pf| {</span>
|
||||
<span class="line" id="L285"> debug(<span class="tok-str">"HttpListener.listen(): public folder is {s}\n"</span>, .{pf});</span>
|
||||
<span class="line" id="L286"> pfolder_len = pf.len;</span>
|
||||
<span class="line" id="L287"> pfolder = pf.ptr;</span>
|
||||
<span class="line" id="L288"> }</span>
|
||||
<span class="line" id="L289"></span>
|
||||
<span class="line" id="L290"> <span class="tok-kw">const</span> x: fio.http_settings_s = .{</span>
|
||||
<span class="line" id="L291"> .on_request = <span class="tok-kw">if</span> (self.settings.on_request) |_| Self.theOneAndOnlyRequestCallBack <span class="tok-kw">else</span> <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L292"> .on_upgrade = <span class="tok-kw">if</span> (self.settings.on_upgrade) |_| Self.theOneAndOnlyUpgradeCallBack <span class="tok-kw">else</span> <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L293"> .on_response = <span class="tok-kw">if</span> (self.settings.on_response) |_| Self.theOneAndOnlyResponseCallBack <span class="tok-kw">else</span> <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L294"> .on_finish = <span class="tok-kw">if</span> (self.settings.on_finish) |_| Self.theOneAndOnlyFinishCallBack <span class="tok-kw">else</span> <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L295"> .udata = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L296"> .public_folder = pfolder,</span>
|
||||
<span class="line" id="L297"> .public_folder_length = pfolder_len,</span>
|
||||
<span class="line" id="L298"> .max_header_size = <span class="tok-number">32</span> * <span class="tok-number">1024</span>,</span>
|
||||
<span class="line" id="L299"> .max_body_size = self.settings.max_body_size <span class="tok-kw">orelse</span> <span class="tok-number">50</span> * <span class="tok-number">1024</span> * <span class="tok-number">1024</span>,</span>
|
||||
<span class="line" id="L300"> <span class="tok-comment">// fio provides good default:</span>
|
||||
</span>
|
||||
<span class="line" id="L301"> .max_clients = self.settings.max_clients <span class="tok-kw">orelse</span> <span class="tok-number">0</span>,</span>
|
||||
<span class="line" id="L302"> .tls = <span class="tok-kw">if</span> (self.settings.tls) |tls| tls.fio_tls <span class="tok-kw">else</span> <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L303"> .reserved1 = <span class="tok-number">0</span>,</span>
|
||||
<span class="line" id="L304"> .reserved2 = <span class="tok-number">0</span>,</span>
|
||||
<span class="line" id="L305"> .reserved3 = <span class="tok-number">0</span>,</span>
|
||||
<span class="line" id="L306"> .ws_max_msg_size = <span class="tok-number">0</span>,</span>
|
||||
<span class="line" id="L307"> .timeout = self.settings.timeout <span class="tok-kw">orelse</span> <span class="tok-number">5</span>,</span>
|
||||
<span class="line" id="L308"> .ws_timeout = self.settings.ws_timeout,</span>
|
||||
<span class="line" id="L309"> .log = <span class="tok-kw">if</span> (self.settings.log) <span class="tok-number">1</span> <span class="tok-kw">else</span> <span class="tok-number">0</span>,</span>
|
||||
<span class="line" id="L310"> .is_client = <span class="tok-number">0</span>,</span>
|
||||
<span class="line" id="L311"> };</span>
|
||||
<span class="line" id="L312"> <span class="tok-comment">// TODO: BUG: without this print/sleep statement, -Drelease* loop forever</span>
|
||||
</span>
|
||||
<span class="line" id="L313"> <span class="tok-comment">// in debug2 and debug3 of hello example</span>
|
||||
</span>
|
||||
<span class="line" id="L314"> <span class="tok-comment">// std.debug.print("X\n", .{});</span>
|
||||
</span>
|
||||
<span class="line" id="L315"> <span class="tok-comment">// TODO: still happening?</span>
|
||||
</span>
|
||||
<span class="line" id="L316"> std.time.sleep(<span class="tok-number">500</span> * std.time.ns_per_ms);</span>
|
||||
<span class="line" id="L317"></span>
|
||||
<span class="line" id="L318"> <span class="tok-kw">var</span> portbuf: [<span class="tok-number">100</span>]<span class="tok-type">u8</span> = <span class="tok-null">undefined</span>;</span>
|
||||
<span class="line" id="L319"> <span class="tok-kw">const</span> printed_port = <span class="tok-kw">try</span> std.fmt.bufPrintZ(&portbuf, <span class="tok-str">"{d}"</span>, .{self.settings.port});</span>
|
||||
<span class="line" id="L320"></span>
|
||||
<span class="line" id="L321"> <span class="tok-kw">const</span> ret = fio.http_listen(printed_port.ptr, self.settings.interface, x);</span>
|
||||
<span class="line" id="L322"> <span class="tok-kw">if</span> (ret == -<span class="tok-number">1</span>) {</span>
|
||||
<span class="line" id="L323"> <span class="tok-kw">return</span> <span class="tok-kw">error</span>.ListenError;</span>
|
||||
<span class="line" id="L324"> }</span>
|
||||
<span class="line" id="L325"></span>
|
||||
<span class="line" id="L326"> <span class="tok-comment">// set ourselves up to handle requests:</span>
|
||||
</span>
|
||||
<span class="line" id="L327"> <span class="tok-comment">// TODO: do we mind the race condition?</span>
|
||||
</span>
|
||||
<span class="line" id="L328"> <span class="tok-comment">// the HttpRequestFn will check if this is null and not process</span>
|
||||
</span>
|
||||
<span class="line" id="L329"> <span class="tok-comment">// the request if it isn't set. hence, if started under full load, the</span>
|
||||
</span>
|
||||
<span class="line" id="L330"> <span class="tok-comment">// first request(s) might not be serviced, as long as it takes from</span>
|
||||
</span>
|
||||
<span class="line" id="L331"> <span class="tok-comment">// fio.http_listen() to here</span>
|
||||
</span>
|
||||
<span class="line" id="L332"> Self.the_one_and_only_listener = self;</span>
|
||||
<span class="line" id="L333"> }</span>
|
||||
<span class="line" id="L334">};</span>
|
||||
<span class="line" id="L335"></span>
|
||||
<span class="line" id="L336"><span class="tok-comment">/// Low-level API</span></span>
|
||||
<span class="line" id="L337"><span class="tok-kw">pub</span> <span class="tok-kw">const</span> LowLevel = <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L338"> <span class="tok-comment">/// lower level listening, if you don't want to use a listener but rather use</span></span>
|
||||
<span class="line" id="L339"> <span class="tok-comment">/// the listen() function.</span></span>
|
||||
<span class="line" id="L340"> <span class="tok-kw">pub</span> <span class="tok-kw">const</span> ListenSettings = <span class="tok-kw">struct</span> {</span>
|
||||
<span class="line" id="L341"> on_request: ?FioHttpRequestFn = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L342"> on_upgrade: ?FioHttpRequestFn = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L343"> on_response: ?FioHttpRequestFn = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L344"> on_finish: ?FioHttpRequestFn = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L345"> public_folder: ?[]<span class="tok-kw">const</span> <span class="tok-type">u8</span> = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L346"> max_header_size: <span class="tok-type">usize</span> = <span class="tok-number">32</span> * <span class="tok-number">1024</span>,</span>
|
||||
<span class="line" id="L347"> max_body_size: <span class="tok-type">usize</span> = <span class="tok-number">50</span> * <span class="tok-number">1024</span> * <span class="tok-number">1024</span>,</span>
|
||||
<span class="line" id="L348"> max_clients: <span class="tok-type">isize</span> = <span class="tok-number">100</span>,</span>
|
||||
<span class="line" id="L349"> keepalive_timeout_s: <span class="tok-type">u8</span> = <span class="tok-number">5</span>,</span>
|
||||
<span class="line" id="L350"> log: <span class="tok-type">bool</span> = <span class="tok-null">false</span>,</span>
|
||||
<span class="line" id="L351"></span>
|
||||
<span class="line" id="L352"> <span class="tok-kw">const</span> Self = <span class="tok-builtin">@This</span>();</span>
|
||||
<span class="line" id="L353"></span>
|
||||
<span class="line" id="L354"> <span class="tok-comment">/// Create settings with defaults</span></span>
|
||||
<span class="line" id="L355"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">init</span>() Self {</span>
|
||||
<span class="line" id="L356"> <span class="tok-kw">return</span> .{};</span>
|
||||
<span class="line" id="L357"> }</span>
|
||||
<span class="line" id="L358"> };</span>
|
||||
<span class="line" id="L359"></span>
|
||||
<span class="line" id="L360"> <span class="tok-comment">/// Low level listen function</span></span>
|
||||
<span class="line" id="L361"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">listen</span>(port: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span>, interface: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span>, settings: ListenSettings) ListenError!<span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L362"> <span class="tok-kw">var</span> pfolder: [*c]<span class="tok-kw">const</span> <span class="tok-type">u8</span> = <span class="tok-null">null</span>;</span>
|
||||
<span class="line" id="L363"> <span class="tok-kw">var</span> pfolder_len: <span class="tok-type">usize</span> = <span class="tok-number">0</span>;</span>
|
||||
<span class="line" id="L364"></span>
|
||||
<span class="line" id="L365"> <span class="tok-kw">if</span> (settings.public_folder) |pf| {</span>
|
||||
<span class="line" id="L366"> pfolder_len = pf.len;</span>
|
||||
<span class="line" id="L367"> pfolder = pf.ptr;</span>
|
||||
<span class="line" id="L368"> }</span>
|
||||
<span class="line" id="L369"> <span class="tok-kw">const</span> x: fio.http_settings_s = .{</span>
|
||||
<span class="line" id="L370"> .on_request = settings.on_request,</span>
|
||||
<span class="line" id="L371"> .on_upgrade = settings.on_upgrade,</span>
|
||||
<span class="line" id="L372"> .on_response = settings.on_response,</span>
|
||||
<span class="line" id="L373"> .on_finish = settings.on_finish,</span>
|
||||
<span class="line" id="L374"> .udata = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L375"> .public_folder = pfolder,</span>
|
||||
<span class="line" id="L376"> .public_folder_length = pfolder_len,</span>
|
||||
<span class="line" id="L377"> .max_header_size = settings.max_header_size,</span>
|
||||
<span class="line" id="L378"> .max_body_size = settings.max_body_size,</span>
|
||||
<span class="line" id="L379"> .max_clients = settings.max_clients,</span>
|
||||
<span class="line" id="L380"> .tls = <span class="tok-null">null</span>,</span>
|
||||
<span class="line" id="L381"> .reserved1 = <span class="tok-number">0</span>,</span>
|
||||
<span class="line" id="L382"> .reserved2 = <span class="tok-number">0</span>,</span>
|
||||
<span class="line" id="L383"> .reserved3 = <span class="tok-number">0</span>,</span>
|
||||
<span class="line" id="L384"> .ws_max_msg_size = settings.ws_max_msg_size,</span>
|
||||
<span class="line" id="L385"> .timeout = settings.keepalive_timeout_s,</span>
|
||||
<span class="line" id="L386"> .ws_timeout = <span class="tok-number">0</span>,</span>
|
||||
<span class="line" id="L387"> .log = <span class="tok-kw">if</span> (settings.log) <span class="tok-number">1</span> <span class="tok-kw">else</span> <span class="tok-number">0</span>,</span>
|
||||
<span class="line" id="L388"> .is_client = <span class="tok-number">0</span>,</span>
|
||||
<span class="line" id="L389"> };</span>
|
||||
<span class="line" id="L390"> <span class="tok-comment">// TODO: BUG: without this print/sleep statement, -Drelease* loop forever</span>
|
||||
</span>
|
||||
<span class="line" id="L391"> <span class="tok-comment">// in debug2 and debug3 of hello example</span>
|
||||
</span>
|
||||
<span class="line" id="L392"> <span class="tok-comment">// std.debug.print("X\n", .{});</span>
|
||||
</span>
|
||||
<span class="line" id="L393"> <span class="tok-comment">// TODO: still happening?</span>
|
||||
</span>
|
||||
<span class="line" id="L394"> std.time.sleep(<span class="tok-number">500</span> * std.time.ns_per_ms);</span>
|
||||
<span class="line" id="L395"></span>
|
||||
<span class="line" id="L396"> <span class="tok-kw">if</span> (fio.http_listen(port, interface, x) == -<span class="tok-number">1</span>) {</span>
|
||||
<span class="line" id="L397"> <span class="tok-kw">return</span> <span class="tok-kw">error</span>.ListenError;</span>
|
||||
<span class="line" id="L398"> }</span>
|
||||
<span class="line" id="L399"> }</span>
|
||||
<span class="line" id="L400"></span>
|
||||
<span class="line" id="L401"> <span class="tok-comment">/// lower level sendBody</span></span>
|
||||
<span class="line" id="L402"> <span class="tok-kw">pub</span> <span class="tok-kw">fn</span> <span class="tok-fn">sendBody</span>(request: [*c]fio.http_s, body: []<span class="tok-kw">const</span> <span class="tok-type">u8</span>) HttpError!<span class="tok-type">void</span> {</span>
|
||||
<span class="line" id="L403"> <span class="tok-kw">const</span> ret = fio.http_send_body(request, <span class="tok-builtin">@as</span>(</span>
|
||||
<span class="line" id="L404"> *<span class="tok-type">anyopaque</span>,</span>
|
||||
<span class="line" id="L405"> <span class="tok-builtin">@ptrFromInt</span>(<span class="tok-builtin">@intFromPtr</span>(body.ptr)),</span>
|
||||
<span class="line" id="L406"> ), body.len);</span>
|
||||
<span class="line" id="L407"> debug(<span class="tok-str">"sendBody(): ret = {}\n"</span>, .{ret});</span>
|
||||
<span class="line" id="L408"> <span class="tok-kw">if</span> (ret != -<span class="tok-number">1</span>) <span class="tok-kw">return</span> <span class="tok-kw">error</span>.HttpSendBody;</span>
|
||||
<span class="line" id="L409"> }</span>
|
||||
<span class="line" id="L410">};</span>
|
||||
<span class="line" id="L411"></span>
|
||||
</code></pre></body>
|
||||
</html>
|
2147
docs/ziglexer.js
2147
docs/ziglexer.js
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue