~caolan/zig-scgi

SCGI library for Zig
add context parameter to request handler
fix variable shadowing

refs

master
browse  log 

clone

read-only
https://git.sr.ht/~caolan/zig-scgi
read/write
git@git.sr.ht:~caolan/zig-scgi

You can also use your local clone with git send-email.

#zig-scgi

A zig server implementing the Simple Common Gateway Interface (SCGI).

#Dependencies

This library requires zig-netstring.

#Usage

Nested dependencies are currently a bit awkward in build.zig, so to include both zig-scgi and zig-netstring try something like the following:

const std = @import("std");

pub fn build(b: *std.build.Builder) void {
    const target = b.standardTargetOptions(.{});
    const mode = b.standardReleaseOptions();

    const netstring = std.build.Pkg {
        .name = "netstring",
        .path = std.build.FileSource {
            .path = "path/to/deps/netstring/src/netstring.zig"
        },
    };
    const scgi = std.build.Pkg {
        .name = "scgi",
        .path = std.build.FileSource {
            .path = "path/to/deps/scgi/src/scgi.zig"
        },
        .dependencies = &[_]std.build.Pkg {
            netstring
        },
    };
    
    const example = b.addExecutable("example", "src/main.zig");
    example.addPackage(netstring);
    example.addPackage(scgi);
    example.setTarget(target);
    example.setBuildMode(mode);
    example.install();
}

#Example

const scgi = @import("scgi");
const std = @import("std");
const net = std.net;

// A config object used in request_handler calls.
const Context = struct {
    greeting: []const u8,
};

// This echos SCGI headers over the Gemini protocol, you could just as easily make a HTTP response.
fn handle_request(context: Context, headers: scgi.SCGIHeaders, stream: net.Stream) !void {
    var writer = stream.writer();
    try writer.writeAll("20 text/gemini; charset=utf-8\x0D\x0A");
    try writer.writeAll(context.greeting);
    try writer.writeAll("\n\n");
    try writer.writeAll("```\n");
    var iter = headers.iterator();
    while (iter.next()) |kv| {
       try writer.print("{s} = {s}\n", .{kv.key_ptr.*, kv.value_ptr.*});
    }
    try writer.writeAll("```\n");
}

pub fn main() anyerror!void {
    var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    defer arena.deinit();
    const allocator = arena.allocator();

    const address = try net.Address.initUnix("scgi.sock");
    const context = Context { .greeting = "Hello, world!" };
    var server = scgi.server(Context, allocator, handle_request, context);
    defer server.deinit();

    try server.listen(address);
    std.debug.print("Listening on {s}\n", .{address});

    // Blocks while handling requests
    try server.run();
}

#Running test suite

$ zig build tests