<commit_before>/*
 * Web Application Socket client.
 *
 * author: <NAME> <<EMAIL>>
 */

#include "was-client.h"
#include "was-quark.h"
#include "was-control.h"
#include "was-output.h"
#include "was-input.h"
#include "http-response.h"
#include "async.h"
#include "please.h"
#include "pevent.h"
#include "direct.h"
#include "istream-internal.h"
#include "fifo-buffer.h"
#include "buffered_io.h"
#include "fd-util.h"
#include "strmap.h"

#include <daemon/log.h>
#include <was/protocol.h>

#include <errno.h>
#include <string.h>
#include <sys/socket.h>

struct was_client {
    struct pool *pool, *caller_pool;

    struct was_control *control;

    struct lease_ref lease_ref;

    struct http_response_handler_ref handler;
    struct async_operation async;

    struct {
        struct was_output *body;
    } request;

    struct {
        http_status_t status;

        /**
         * Response headers being assembled.  This pointer is set to
         * NULL before the response is dispatched to the response
         * handler.
         */
        struct strmap *headers;

        struct was_input *body;

        /**
         * If set, then the invocation of the response handler is
         * postponed, until the remaining control packets have been
         * evaluated.
         */
        bool pending;
    } response;
};

/**
 * Are we currently receiving response metadata (such as headers)?
 */
static bool
was_client_receiving_metadata(const struct was_client *client)
{
    return client->response.headers != NULL && !client->response.pending;
}

/**
 * Has the response been submitted to the response handler?
 */
static bool
was_client_response_submitted(const struct was_client *client)
{
    return client->response.headers == NULL;
}

/**
 * Destroys the objects was_control, was_input, was_output and
 * releases the socket lease.
 */
static void
was_client_clear(struct was_client *client, GError *error)
{
    if (client->request.body != NULL)
        was_output_free_p(&client->request.body);

    if (client->response.body != NULL)
        was_input_free_p(&client->response.body, error);
    else
        g_error_free(error);

    if (client->control != NULL) {
        was_control_free(client->control);
        client->control = NULL;
    }

    p_lease_release(&client->lease_ref, false, client->pool);
}

/**
 * Like was_client_clear(), but assumes the response body has not been
 * enabled.
 */
static void
was_client_clear_unused(struct was_client *client)
{
    if (client->request.body != NULL)
        was_output_free_p(&client->request.body);

    if (client->response.body != NULL)
        was_input_free_unused_p(&client->response.body);

    if (client->control != NULL) {
        was_control_free(client->control);
        client->control = NULL;
    }

    p_lease_release(&client->lease_ref, false, client->pool);
}

/**
 * Abort receiving the response status/headers from the WAS server.
 */
static void
was_client_abort_response_headers(struct was_client *client, GError *error)
{
    assert(was_client_receiving_metadata(client));

    async_operation_finished(&client->async);

    was_client_clear(client, g_error_copy(error));

    http_response_handler_invoke_abort(&client->handler, error);
    pool_unref(client->caller_pool);<commit_msg>was-client: move code to _clear_request_body()<commit_after>/*
 * Web Application Socket client.
 *
 * author: <NAME> <<EMAIL>>
 */

#include "was-client.h"
#include "was-quark.h"
#include "was-control.h"
#include "was-output.h"
#include "was-input.h"
#include "http-response.h"
#include "async.h"
#include "please.h"
#include "pevent.h"
#include "direct.h"
#include "istream-internal.h"
#include "fifo-buffer.h"
#include "buffered_io.h"
#include "fd-util.h"
#include "strmap.h"

#include <daemon/log.h>
#include <was/protocol.h>

#include <errno.h>
#include <string.h>
#include <sys/socket.h>

struct was_client {
    struct pool *pool, *caller_pool;

    struct was_control *control;

    struct lease_ref lease_ref;

    struct http_response_handler_ref handler;
    struct async_operation async;

    struct {
        struct was_output *body;
    } request;

    struct {
        http_status_t status;

        /**
         * Response headers being assembled.  This pointer is set to
         * NULL before the response is dispatched to the response
         * handler.
         */
        struct strmap *headers;

        struct was_input *body;

        /**
         * If set, then the invocation of the response handler is
         * postponed, until the remaining control packets have been
         * evaluated.
         */
        bool pending;
    } response;
};

/**
 * Are we currently receiving response metadata (such as headers)?
 */
static bool
was_client_receiving_metadata(const struct was_client *client)
{
    return client->response.headers != NULL && !client->response.pending;
}

/**
 * Has the response been submitted to the response handler?
 */
static bool
was_client_response_submitted(const struct was_client *client)
{
    return client->response.headers == NULL;
}

static void
was_client_clear_request_body(struct was_client *client)
{
    if (client->request.body != NULL)
        was_output_free_p(&client->request.body);
}

/**
 * Destroys the objects was_control, was_input, was_output and
 * releases the socket lease.
 */
static void
was_client_clear(struct was_client *client, GError *error)
{
    was_client_clear_request_body(client);

    if (client->response.body != NULL)
        was_input_free_p(&client->response.body, error);
    else
        g_error_free(error);

    if (client->control != NULL) {
        was_control_free(client->control);
        client->control = NULL;
    }

    p_lease_release(&client->lease_ref, false, client->pool);
}

/**
 * Like was_client_clear(), but assumes the response body has not been
 * enabled.
 */
static void
was_client_clear_unused(struct was_client *client)
{
    was_client_clear_request_body(client);

    if (client->response.body != NULL)
        was_input_free_unused_p(&client->response.body);

    if (client->control != NULL) {
        was_control_free(client->control);
        client->control = NULL;
    }

    p_lease_release(&client->lease_ref, false, client->pool);
}

/**
 * Abort receiving the response status/headers from the WAS server.
 */
static void
was_client_abort_response_headers(struct was_client *client, GError *error)
{
    assert(was_client_receiving_metadata(client));

    async_operation_finished(&client->async);

    was_client_clear(client, g_error_copy(error));

    http_response_handler_invoke_abort(&client->handler, error);
    pool_unref(client->caller_pool);
{'fraction_non_alphanumeric': 0.11730337078651686, 'fraction_numerical': 0.0, 'mean_word_length': 3.418266048974189, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6491767', 'n_tokens_mistral': 2098, 'n_tokens_neox': 2053, 'n_words': 510}