コード例 #1
0
ファイル: request.c プロジェクト: tinkertim/slash
static void
parse_query_string(sl_vm_t* vm, SLVAL dict, size_t len, uint8_t* query_string)
{
    uint8_t *key = query_string, *value = NULL;
    size_t key_len = 0, value_len = 0;
    size_t i;
    SLVAL addee = dict, k, v;
    int bracket_mode = 0, in_bracket = 0;
    for(i = 0; i <= len; i++) {
        if(i == len || query_string[i] == '&') {
            if(key_len > 0) {
                k = sl_string_url_decode(vm, sl_make_string(vm, key, key_len));
                if(value) {
                    v = sl_string_url_decode(vm, sl_make_string(vm, value, value_len));
                }
                sl_dict_set(vm, addee, k, value ? v : vm->lib.nil);
            }
            key = query_string + i + 1;
            key_len = 0;
            value = NULL;
            value_len = 0;
            addee = dict;
            in_bracket = 0;
            bracket_mode = 0;
            continue;
        }
        if(query_string[i] == '=' && !value) {
            value = query_string + i + 1;
            continue;
        }
        if(value) {
            value_len++;
        } else {
            if(query_string[i] == '[') {
                k = sl_make_string(vm, key, key_len);
                key = query_string + i + 1;
                key_len = 0;
                if(!sl_is_a(vm, sl_dict_get(vm, addee, k), vm->lib.Dict)) {
                    sl_dict_set(vm, addee, k, sl_make_dict(vm, 0, NULL));
                }
                addee = sl_dict_get(vm, addee, k);
                in_bracket = 1;
                bracket_mode = 1;
                continue;
            }
            if(query_string[i] == ']' && in_bracket) {
                in_bracket = 0;
                continue;
            }
            if(bracket_mode && !in_bracket) {
                /* skip until \0, & or = */
                while(i + 1 < len && query_string[i + 1] != '&' && query_string[i + 1] != '=') {
                    i++;
                }
                continue;
            }
            key_len++;
        }
    }
}
コード例 #2
0
ファイル: request.c プロジェクト: tinkertim/slash
static void
parse_cookie_string(sl_vm_t* vm, SLVAL dict, size_t len, uint8_t* cookies)
{
    uint8_t *key = NULL, *value = NULL;
    size_t key_len = 0, value_len = 0;
    size_t i;
    for(i = 0; i <= len; i++) {
        if(i == len || cookies[i] == ';') {
            if(key_len) {
                sl_dict_set(vm, dict,
                    sl_string_url_decode(vm, sl_make_string(vm, key, key_len)),
                    sl_string_url_decode(vm, sl_make_string(vm, value, value_len)));
            }
            key_len = 0;
            value_len = 0;
            key = NULL;
            value = NULL;
        }
        if(cookies[i] != ' ' && !key) {
            key = cookies + i;
            key_len++;
            continue;
        }
        if(cookies[i] == '=' && !value) {
            value = cookies + i + 1;
            continue;
        }
        if(!value) {
            key_len++;
        } else {
            value_len++;
        }
    }
}
コード例 #3
0
ファイル: request.c プロジェクト: tinkertim/slash
void
sl_request_set_opts(sl_vm_t* vm, sl_request_opts_t* opts)
{
    size_t i;
    SLVAL n, v, cookies;
    sl_string_t* str;
    sl_request_internal_opts_t* req = sl_alloc(vm->arena, sizeof(sl_request_internal_opts_t));
    req->method       = sl_make_cstring(vm, opts->method);
    req->uri          = sl_make_cstring(vm, opts->uri);
    req->path_info    = sl_make_cstring(vm, opts->path_info ? opts->path_info : "");
    req->query_string = sl_make_cstring(vm, opts->query_string ? opts->query_string : "");
    req->remote_addr  = sl_make_cstring(vm, opts->remote_addr);
    req->headers      = sl_make_dict(vm, 0, NULL);
    req->env          = sl_make_dict(vm, 0, NULL);
    req->get          = sl_make_dict(vm, 0, NULL);
    req->post         = sl_make_dict(vm, 0, NULL);
    req->post_data    = sl_make_string(vm, (uint8_t*)opts->post_data, opts->post_length);
    req->cookies      = sl_make_dict(vm, 0, NULL);
    for(i = 0; i < opts->header_count; i++) {
        n = sl_make_cstring(vm, opts->headers[i].name);
        v = sl_make_cstring(vm, opts->headers[i].value);
        sl_dict_set(vm, req->headers, n, v);
    }
    for(i = 0; i < opts->env_count; i++) {
        n = sl_make_cstring(vm, opts->env[i].name);
        v = sl_make_cstring(vm, opts->env[i].value);
        sl_dict_set(vm, req->env, n, v);
    }
    if(opts->query_string) {
        parse_query_string(vm, req->get, strlen(opts->query_string), (uint8_t*)opts->query_string);
    }
    if(opts->content_type && strcmp(opts->content_type, "application/x-www-form-urlencoded") == 0) {
        parse_query_string(vm, req->post, opts->post_length, (uint8_t*)opts->post_data);
    }
    cookies = sl_dict_get(vm, req->headers, sl_make_cstring(vm, "Cookie"));
    if(sl_is_a(vm, cookies, vm->lib.String)) {
        str = (sl_string_t*)sl_get_ptr(cookies);
        parse_cookie_string(vm, req->cookies, str->buff_len, str->buff);
    }
    req->params = sl_dict_merge(vm, req->get, req->post);
    sl_vm_store_put(vm, &Request_opts, sl_make_ptr((sl_object_t*)req));
}
コード例 #4
0
ファイル: mysql.c プロジェクト: Hmaal/slash
static SLVAL
sl_mysql_stmt_execute(sl_vm_t* vm, SLVAL self, size_t argc, SLVAL* argv)
{
    mysql_stmt_t* stmt = get_mysql_stmt(vm, self);
    size_t req = mysql_stmt_param_count(stmt->stmt);
    if(argc < req) {
        char buff[100];
        sprintf(buff, "Prepared statement has %lu parameter markers, but only %lu parameters were given", req, argc);
        sl_throw_message2(vm, vm->lib.ArgumentError, buff);
    }

    if(!stmt->bind) {
        stmt->bind = sl_alloc(vm->arena, sizeof(MYSQL_BIND) * req);
    }

    for(size_t i = 0; i < req; i++) {
        stmt->bind[i].buffer_type = MYSQL_TYPE_STRING;
        sl_string_t* str = sl_get_string(vm, sl_to_s(vm, argv[i]));
        stmt->bind[i].buffer = str->buff;
        stmt->bind[i].buffer_length = str->buff_len;
        stmt->bind[i].length = NULL;
        stmt->bind[i].is_null = NULL;
        stmt->bind[i].is_unsigned = 1;
        stmt->bind[i].error = NULL;
    }

    if(mysql_stmt_bind_param(stmt->stmt, stmt->bind)) {
        sl_mysql_stmt_check_error(vm, stmt->stmt);
    }

    if(mysql_stmt_execute(stmt->stmt)) {
        sl_mysql_stmt_check_error(vm, stmt->stmt);
    }

    MYSQL_RES* res = mysql_stmt_result_metadata(stmt->stmt);
    if(!res) {
        /* query did not produce a result set */
        return sl_make_int(vm, mysql_stmt_affected_rows(stmt->stmt));
    }

    int field_count = mysql_stmt_field_count(stmt->stmt);
    MYSQL_FIELD* field;
    SLVAL field_names[field_count];
    enum enum_field_types field_types[field_count];
    size_t field_i = 0;
    while((field = mysql_fetch_field(res))) {
        field_names[field_i] = sl_make_cstring(vm, field->name);
        if(field->type == MYSQL_TYPE_LONG || field->type == MYSQL_TYPE_SHORT || field->type == MYSQL_TYPE_TINY) {
            field_types[field_i] = MYSQL_TYPE_LONG;
        } else {
            field_types[field_i] = MYSQL_TYPE_STRING;
        }
        field_i++;
    }

    MYSQL_BIND output_binds[field_count];
    my_bool output_errors[field_count];
    my_bool output_is_nulls[field_count];
    unsigned long output_lengths[field_count];
    for(int i = 0; i < field_count; i++) {
        output_binds[i].buffer_type = MYSQL_TYPE_STRING;
        output_binds[i].buffer = NULL;
        output_binds[i].buffer_length = 0;
        output_binds[i].length = &output_lengths[i];
        output_binds[i].is_null = &output_is_nulls[i];
        output_binds[i].error = &output_errors[i];
    }
    if(mysql_stmt_bind_result(stmt->stmt, output_binds)) {
        sl_mysql_stmt_check_error(vm, stmt->stmt);
    }

    SLVAL result_rows = sl_make_array(vm, 0, NULL);
    while(1) {
        int code = mysql_stmt_fetch(stmt->stmt);
        if(code == MYSQL_NO_DATA) {
            break;
        }
        if(code == 1) {
            sl_mysql_stmt_check_error(vm, stmt->stmt);
        }
        SLVAL row = sl_make_dict(vm, 0, NULL);
        for(int i = 0; i < field_count; i++) {
            MYSQL_BIND cell;
            cell.length = &output_lengths[i];
            cell.is_null = &output_is_nulls[i];
            cell.error = &output_errors[i];
            cell.buffer_type = field_types[i];
            int buffer_long;
            switch(field_types[i]) {
                case MYSQL_TYPE_LONG:
                    cell.buffer = &buffer_long;
                    cell.buffer_length = sizeof(buffer_long);
                    break;
                default: /* MYSQL_TYPE_STRING */
                    cell.buffer = sl_alloc_buffer(vm->arena, output_lengths[i] + 1);
                    cell.buffer_length = output_lengths[i];
                    break;
            }
            if(mysql_stmt_fetch_column(stmt->stmt, &cell, i, 0)) {
                sl_mysql_stmt_check_error(vm, stmt->stmt);
            }
            switch(field_types[i]) {
                case MYSQL_TYPE_LONG:
                    sl_dict_set(vm, row, field_names[i], sl_make_int(vm, buffer_long));
                    break;
                default: /* MYSQL_TYPE_STRING */
                    sl_dict_set(vm, row, field_names[i], sl_make_string(vm, cell.buffer, output_lengths[i]));
                    break;
            }
        }
        sl_array_push(vm, result_rows, 1, &row);
    }

    return result_rows;
}