Ejemplo n.º 1
0
void clax_dispatch_download(clax_ctx_t *clax_ctx, clax_http_request_t *req, clax_http_response_t *res)
{
    char *file = req->path_info + strlen("/tree/");

    char buf[255];
    char base_buf[255];
    char last_modified_buf[30];
    struct stat st;
    struct tm last_modified_time;
    struct tm *last_modified_time_p;

    if (stat(file, &st) != 0 || !(st.st_mode & S_IFREG)) {
        clax_dispatch_not_found(clax_ctx, req, res);
        return;
    }

    unsigned long crc32 = clax_crc32_calc_file(file);
    char crc32_hex[9] = {0};
    snprintf(crc32_hex, sizeof(crc32_hex), "%lx", crc32);

    FILE *fh = fopen(file, "rb");

    if (fh == NULL) {
        clax_dispatch_not_found(clax_ctx, req, res);
        return;
    }

    snprintf(buf, sizeof(buf), "%d", (int)st.st_size);

    char *base = basename(file);
    strcpy(base_buf, "attachment; filename=\"");
    strcat(base_buf, base);
    strcat(base_buf, "\"");

    res->status_code = 200;
    clax_kv_list_push(&res->headers, "Content-Type", "application/octet-stream");
    clax_kv_list_push(&res->headers, "Content-Disposition", base_buf);
    clax_kv_list_push(&res->headers, "Pragma", "no-cache");
    clax_kv_list_push(&res->headers, "Content-Length", buf);

    last_modified_time_p = gmtime_r(&st.st_mtime, &last_modified_time);

    strftime(last_modified_buf, sizeof(last_modified_buf), "%a, %d %b %Y %H:%M:%S GMT", last_modified_time_p);
    clax_kv_list_push(&res->headers, "Last-Modified", last_modified_buf);

    clax_kv_list_push(&res->headers, "X-Clax-CRC32", crc32_hex);

    if (req->method == HTTP_GET)
        res->body_fh = fh;
    else
        fclose(fh);
}
Ejemplo n.º 2
0
void clax_dispatch(clax_ctx_t *clax_ctx, clax_http_request_t *req, clax_http_response_t *res)
{
    char *path_info = req->path_info;
    size_t path_info_len = strlen(path_info);

    size_t len = sizeof clax_dispatcher_actions / sizeof clax_dispatcher_actions[0];

    clax_log("Matching request %s %s", http_method_str(req->method), path_info);

    for (int i = 0; i < len; i++) {
        clax_dispatcher_action_t *action = &clax_dispatcher_actions[i];

        size_t match = clax_dispatcher_match(path_info, path_info_len, action->path, strlen(action->path));

        if (match) {
            clax_log("Action matched");

            if (action->method_mask & (1 << req->method)) {
                clax_log("Method matched");

                if (req->continue_expected) {
                    if (action->flags_mask & (1 << CLAX_DISPATCHER_FLAG_100_CONTINUE)) {
                        action->fn(clax_ctx, req, res);
                    }
                    else {
                        return;
                    }
                } else {
                    action->fn(clax_ctx, req, res);
                }

                return;
            } else {
                clax_dispatch_method_not_allowed(clax_ctx, req, res);

                return;
            }
        }
    }

    clax_log("No suitable action matched");

    clax_dispatch_not_found(clax_ctx, req, res);

    return;
}
Ejemplo n.º 3
0
void clax_dispatch_delete(clax_ctx_t *clax_ctx, clax_http_request_t *req, clax_http_response_t *res)
{
    char *file = req->path_info + strlen("/tree/");
    struct stat st;

    if (stat(file, &st) != 0 || !(st.st_mode & S_IFREG)) {
        clax_dispatch_not_found(clax_ctx, req, res);
        return;
    }

    int ret = unlink(file);

    if (ret == 0) {
        res->status_code = 200;
        clax_kv_list_push(&res->headers, "Content-Type", "application/json");
        clax_big_buf_append_str(&res->body, "{\"message\":\"ok\"}");
    }
    else {
        clax_dispatch_system_error(clax_ctx, req, res);
        return;
    }
}