5. Handle Request Callback

The http server library has a single callback entry point.

The handle request callback can be divided up into the following steps:

- URL parsing - Writing to buffer - Pushing buffer to HTTP body

<<static_funcdefs>>=
static void handle_request(struct http_request_s* request);

This is the struct passed to the org parser. It will go somewhere else eventually, but it was first conceived here.

<<structs>>=
typedef struct {
    orgparse *op;
    orgparse_state *state;
    wws_buffer *buf;
    wwserver_d *wws;
} wws_parser_d;
<<functions>>=
#define RESPONSE "What is my purpose?"
static void handle_request(struct http_request_s* request)
{
    /* TODO: implement */
    wwserver_d *wws;
    struct http_string_s target;
    const char *name;
    int len;
    wws = wwserver_global_get();
    target = http_request_target(request);

    printf("Request: ");
    fwrite(target.buf, 1, target.len, stdout);
    printf("\n");
    fflush(stdout);

    if (wws == NULL) return;

    len = 0;

    if (is_wiki(&target, &name, &len)) {
        wws_buffer buf;
        sqlite3 *db;
        sqlite3_stmt *stmt;
        int rc;

        struct http_response_s* response = http_response_init();
        wws_buffer_alloc(&buf, 2048);

        db = weewiki_db(wws->ww);
        sqlite3_prepare_v2(db,
                        "SELECT value FROM wiki WHERE(key==?1);",
                        -1,
                        &stmt,
                        NULL);
        sqlite3_bind_text(stmt, 1, name, len, NULL);
        rc = sqlite3_step(stmt);

        if (rc != SQLITE_ROW) {
            wws_buffer_write(&buf, "Could not find page: ", 21);
            wws_buffer_write(&buf, name, len);
            http_response_status(response, 404);
            http_response_header(response, "Content-Type", "text/plain");
        } else {
            orgparse *op;
            orgparse_state *state;
            wws_parser_d pd;
            char *namebuf;

            op = calloc(1, orgparse_size());
            state = calloc(1, orgparse_state_size());
            pd.op = op;
            pd.state = state;
            pd.buf = &buf;
            pd.wws = wws;
            wws_orgparse_setup(op);
            http_response_header(response, "Content-Type", "text/html");
            http_response_status(response, 200);
            weewiki_ud_set(wws->ww, &pd);

            /* copy name to null-terminated string */
            namebuf = calloc(1, len + 1);
            strncpy(namebuf, name, len);
            weewiki_pgname_set(wws->ww, namebuf);

            janet_dostring(wws->env,
                        (const unsigned char *)"(html-header)",
                        NULL, NULL);
            orgparse_init_and_run(op,
                                  (const char *)sqlite3_column_text(stmt, 0),
                                  sqlite3_column_bytes(stmt, 0),
                                  &pd,
                                  state);
            orgparse_end(op, &pd, state);
            janet_dostring(wws->env,
                        (const unsigned char *)"(html-footer)",
                        NULL, NULL);

            weewiki_ud_set(wws->ww, NULL);
            free(op);
            free(state);
            free(namebuf);
        }

        http_response_body(response, (const char *)buf.buf, buf.pos);
        http_respond(request, response);
        wws_buffer_free(&buf);
        sqlite3_finalize(stmt);
    } else if (wws_find_and_serve(wws, request, &target)) {
        return;
    } else {
        /* TODO: pass URLs to Janet to be processed */
        /* if that doesn't work, 404 it */
        struct http_response_s* response = http_response_init();
        http_response_status(response, 404);
        http_response_header(response, "Content-Type", "text/plain");
        http_response_body(response, RESPONSE, sizeof(RESPONSE) - 1);
        http_respond(request, response);
    }
}



prev | home | next