<commit_before>#include "storj.h"
#include "http.h"
#include "utils.h"
#include "crypto.h"

#define STORJ_DOWNLOAD_CONCURRENCY 4

// TODO memory cleanup

// TODO move to a header file for downloader
static void queue_next_work(storj_download_state_t *state);

static void request_token(uv_work_t *work)
{
    token_request_token_t *req = work->data;

    char *path = ne_concat("/buckets/", req->bucket_id, "/tokens", NULL);

    struct json_object *body = json_object_new_object();
    json_object *op_string = json_object_new_string(req->bucket_op);
    json_object_object_add(body, "operation", op_string);

    int status_code = 0;
    struct json_object *response = fetch_json(req->options,
                                              "POST",
                                              path,
                                              body,
                                              true,
                                              NULL,
                                              &status_code);

    if (status_code == 201) {
        struct json_object *token_value;
        if (!json_object_object_get_ex(response, "token", &token_value)) {
            req->error_status = STORJ_BRIDGE_JSON_ERROR;
        }

        if (!json_object_is_type(token_value, json_type_string) == 1) {
            req->error_status = STORJ_BRIDGE_JSON_ERROR;
        }

        req->token = (char *)json_object_get_string(token_value);

        free(token_value);

    } else if (status_code == 403 || status_code == 401) {
        req->error_status = STORJ_BRIDGE_AUTH_ERROR;
    } else if (status_code == 404) {
        req->error_status = STORJ_BRIDGE_BUCKET_NOTFOUND_ERROR;
    } else if (status_code == 500) {
        req->error_status = STORJ_BRIDGE_INTERNAL_ERROR;
    }

    req->status_code = status_code;

    free(response);
    free(body);
}

static void after_request_token(uv_work_t *work, int status)
{

    token_request_token_t *req = work->data;

    req->download_state->requesting_token = false;

    if (status != 0) {
        req->download_state->error_status = STORJ_BRIDGE_TOKEN_ERROR;
    } else if (req->status_code == 201) {
        req->download_state->token = req->token;
    } else if (req->error_status){
        req->download_state->error_status = req->error_status;
    } else {
        // TODO retry logic
        req->download_state->error_status = STORJ_BRIDGE_TOKEN_ERROR;
    }

    queue_next_work(req->download_state);

    free(req);
    free(work);
}

static int queue_request_bucket_token(storj_download_state_t *state)
{
    if (state->requesting_token) {
        return 0;
    }

    uv_work_t *work = malloc(sizeof(uv_work_t));
    assert(work != NULL);

    token_request_token_t *req = malloc(sizeof(token_request_token_t));
    assert(req != NULL);

    req->options = state->env->bridge_options;
    req->bucket_id = state->bucket_id;
    req->bucket_op = BUCKET_OP[BUCKET_PULL];
    req->download_state = state;
    work->data = req;

    int status = uv_queue_work(state->env->loop, (uv_work_t*) work,
                               request_token, after_request_token);

    // TODO check status
    state->requesting_token = true;

    return status;

}

static void request_pointers(uv_work_t *work)
{
    json_request_download_t *req = work->data;

    int status_code;
    req->response = fetch_json(req->options, req->method, req->path, req->body,
                               req->auth, req->token, &status_code);<commit_msg>Clear warning const qualifier<commit_after>#include "storj.h"
#include "http.h"
#include "utils.h"
#include "crypto.h"

#define STORJ_DOWNLOAD_CONCURRENCY 4

// TODO memory cleanup

// TODO move to a header file for downloader
static void queue_next_work(storj_download_state_t *state);

static void request_token(uv_work_t *work)
{
    token_request_token_t *req = work->data;

    char *path = ne_concat("/buckets/", req->bucket_id, "/tokens", NULL);

    struct json_object *body = json_object_new_object();
    json_object *op_string = json_object_new_string(req->bucket_op);
    json_object_object_add(body, "operation", op_string);

    int status_code = 0;
    struct json_object *response = fetch_json(req->options,
                                              "POST",
                                              path,
                                              body,
                                              true,
                                              NULL,
                                              &status_code);

    if (status_code == 201) {
        struct json_object *token_value;
        if (!json_object_object_get_ex(response, "token", &token_value)) {
            req->error_status = STORJ_BRIDGE_JSON_ERROR;
        }

        if (!json_object_is_type(token_value, json_type_string) == 1) {
            req->error_status = STORJ_BRIDGE_JSON_ERROR;
        }

        req->token = (char *)json_object_get_string(token_value);

        free(token_value);

    } else if (status_code == 403 || status_code == 401) {
        req->error_status = STORJ_BRIDGE_AUTH_ERROR;
    } else if (status_code == 404) {
        req->error_status = STORJ_BRIDGE_BUCKET_NOTFOUND_ERROR;
    } else if (status_code == 500) {
        req->error_status = STORJ_BRIDGE_INTERNAL_ERROR;
    }

    req->status_code = status_code;

    free(response);
    free(body);
}

static void after_request_token(uv_work_t *work, int status)
{

    token_request_token_t *req = work->data;

    req->download_state->requesting_token = false;

    if (status != 0) {
        req->download_state->error_status = STORJ_BRIDGE_TOKEN_ERROR;
    } else if (req->status_code == 201) {
        req->download_state->token = req->token;
    } else if (req->error_status){
        req->download_state->error_status = req->error_status;
    } else {
        // TODO retry logic
        req->download_state->error_status = STORJ_BRIDGE_TOKEN_ERROR;
    }

    queue_next_work(req->download_state);

    free(req);
    free(work);
}

static int queue_request_bucket_token(storj_download_state_t *state)
{
    if (state->requesting_token) {
        return 0;
    }

    uv_work_t *work = malloc(sizeof(uv_work_t));
    assert(work != NULL);

    token_request_token_t *req = malloc(sizeof(token_request_token_t));
    assert(req != NULL);

    req->options = state->env->bridge_options;
    req->bucket_id = state->bucket_id;
    req->bucket_op = (char *)BUCKET_OP[BUCKET_PULL];
    req->download_state = state;
    work->data = req;

    int status = uv_queue_work(state->env->loop, (uv_work_t*) work,
                               request_token, after_request_token);

    // TODO check status
    state->requesting_token = true;

    return status;

}

static void request_pointers(uv_work_t *work)
{
    json_request_download_t *req = work->data;

    int status_code;
    req->response = fetch_json(req->options, req->method, req->path, req->body,
                               req->auth, req->token, &status_code);
{'fraction_non_alphanumeric': 0.11068266209654384, 'fraction_numerical': 0.006569551556698086, 'mean_word_length': 2.3945710130877362, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 97, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 46, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4179149', 'n_tokens_mistral': 2274, 'n_tokens_neox': 2183, 'n_words': 409}