Exemple #1
0
static void run_wconnection(struct connection *cn)
{
	int n;
	short r;

	n = cn->pollno;
	if (n == -1)
		return;
	r = pollfds[n].revents;
	if (r & POLLERR || r == POLLHUP) {
		close_connection(cn);
		return;
	}
	if (r & POLLOUT)
		write_connection(cn);
}
Exemple #2
0
ERROR_CODE write_http_message(
    struct connection_t *connection,
    char *buffer, size_t size,
    enum http_version_e version,
    int status_code,
    char *status_message,
    char *message,
    enum http_keep_alive_e keep_alive,
    connection_data_callback_hu callback,
    void *callback_parameters
) {
    /* allocates the headers buffer (it will be releases automatically by the writter)
    it need to be allocated in the heap so it gets throught the request cycle */
    char *headers_buffer = buffer == NULL ? MALLOC(VIRIATUM_HTTP_SIZE) : buffer;
    size = size == 0 ? VIRIATUM_HTTP_SIZE : size;

    /* writes the http static headers to the response and
    then writes the error description itself */
    write_http_headers_m(
        connection,
        headers_buffer,
        size,
        version,
        status_code,
        status_message,
        keep_alive,
        strlen(message),
        NO_CACHE,
        message
    );

    /* writes both the headers to the connection, registers for the appropriate callbacks */
    write_connection(
        connection,
        (unsigned char *) headers_buffer,
        (unsigned int) strlen(headers_buffer),
        (connection_data_callback) callback,
        callback_parameters
    );

    /* raises no error */
    RAISE_NO_ERROR;
}
void
subscribe_channels(Connection *connection, Statistics *stats)
{
    char buffer[BUFFER_SIZE];
    int len = 0, bytes_written = 0;
    long i = 0;

    len = sprintf(buffer, "GET /sub");
    for (i = connection->channel_start; i <= connection->channel_end; i++) {
        len += sprintf(buffer + len, "/my_channel_%ld", i);
    }

    len += sprintf(buffer + len, "?conn=%d HTTP/1.1\r\nHost: loadtest\r\n\r\n", connection->index);

    if (write_connection(connection, stats, buffer, len) == EXIT_FAILURE) {
        stats->connections--;
        reopen_connection(connection);
        return;
    }
}
Exemple #4
0
ERROR_CODE open_handler_stream_http_client(struct io_connection_t *io_connection) {
    /* allocates the http client connection and retrieves the
    "upper" connection (for parameters retrieval) */
    struct http_client_connection_t *http_client_connection;
    struct connection_t *connection = (struct connection_t *) io_connection->connection;
    struct http_client_parameters_t *parameters = (struct http_client_parameters_t *) connection->parameters;
    char *buffer = MALLOC(VIRIATUM_HTTP_SIZE);

    /* creates the http message header from the provided
    information, note that the parmeters are allways set*/
    SPRINTF(
        buffer,
        VIRIATUM_HTTP_SIZE,
        "%s %s?%s %s\r\n"
        "User-Agent: %s\r\n"
        "Connection: Keep-Alive\r\n\r\n",
        http_method_strings[parameters->method - 1],
        parameters->url,
        parameters->params,
        http_version_strings[parameters->version - 1],
        VIRIATUM_AGENT
    );

    /* creates the http client connection object populating
    all of its internal element for future usage */
    create_http_client_connection(&http_client_connection, io_connection);

    /* writes the created header buffer to the connection
    and waits for the response from the server side */
    write_connection(
        io_connection->connection,
        (unsigned char *) buffer,
        (unsigned int) strlen(buffer),
        NULL,
        NULL
    );

    /* raises no error */
    RAISE_NO_ERROR;
}
void
write_message(Connection *connection, Statistics *stats)
{
    char buffer[BUFFER_SIZE];
    int len = 0, bytes_written = 0;

    if ((connection->channel_id <= connection->channel_start) || (connection->channel_id > connection->channel_end)) {
        connection->channel_id = connection->channel_start;
        connection->message_count++;

        // gives a message payload of 140 bytes
        connection->content_length = sprintf(connection->content_buffer, "**MSG** msg=%06d 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789", connection->message_count);
        connection->content_buffer[connection->content_length] = '\0';
    }

    len = sprintf(buffer, "POST /pub?id=my_channel_%ld HTTP/1.1\r\nHost: loadtest\r\nContent-Length: %d\r\n\r\n%s", connection->channel_id, connection->content_length, connection->content_buffer);

    if (write_connection(connection, stats, buffer, len) == EXIT_FAILURE) {
        reopen_connection(connection);
        return;
    }

    connection->channel_id++;
}
Exemple #6
0
ERROR_CODE write_http_error_a(
    struct connection_t *connection,
    char *buffer,
    size_t size,
    enum http_version_e version,
    int error_code,
    char *error_message,
    char *error_description,
    char *realm,
    enum http_keep_alive_e keep_alive,
    connection_data_callback_hu callback,
    void *callback_parameters
) {
    /* allocates space for the result buffer related
    variables (for both the buffer pointer and size) */
    size_t result_length;
    unsigned char *result_buffer;

    /* allocates space for the references the string
    buffer and template handler structures */
    struct string_buffer_t *string_buffer;
    struct template_handler_t *template_handler;

    /* allocates space for the "possible" locally generated
    error description (format based generation) */
    char _error_description[1024];

    /* allocates space to the path to the template file to
    be used for template generation */
    unsigned char template_path[VIRIATUM_MAX_PATH_SIZE];

    /* retrieves the service from the connection structure and
    then uses it to retrieve its options */
    struct service_t *service = connection->service;
    struct service_options_t *options = service->options;

    /* allocates the headers buffer (it will be releases automatically by the writter)
    it need to be allocated in the heap so it gets throught the request cycle */
    char *headers_buffer = buffer == NULL ? MALLOC(VIRIATUM_HTTP_SIZE) : buffer;
    size = size == 0 ? VIRIATUM_HTTP_SIZE : size;

#ifndef VIRIATUM_DEBUG
    /* sets the error description as null in order to avoid any
    display of the (internal) message, otherwise a possible
    security hole would be created */
    error_description = NULL;
#endif

    /* in case the use template flag is set the error
    should be displayed using the template */
    if(options->use_template) {
        /* creates the complete path to the template file */
        SPRINTF(
            (char *) template_path,
            sizeof(template_path),
            "%s%s",
            VIRIATUM_RESOURCES_PATH,
            VIRIATUM_ERROR_PATH
        );

        /* prints a debug message */
        V_DEBUG_F("Processing template file '%s'\n", template_path);

        /* creates the template handler that will hold the error
        information contents */
        create_template_handler(&template_handler);

        /* assigns the various error related variables into the
        template handler to be used, they may be used to display
        information arround the error, note that the error description
        value is conditional and may not be set */
        assign_integer_template_handler(template_handler, (unsigned char *) "error_code", error_code);
        assign_string_template_handler(template_handler, (unsigned char *) "error_message", error_message);
        if(error_description != NULL) {
            assign_string_template_handler(template_handler, (unsigned char *) "error_description", error_description);
        }

        /* processes the file as a template handler, at this point
        the output buffer of the template engine should be populated
        with the complete header information, the apropriate header
        writing method is chosen based on the existence or not of
        the realm authorization field */
        process_template_handler(template_handler, template_path);
        realm == NULL ? write_http_headers_c(
            connection,
            headers_buffer,
            size,
            version,
            error_code,
            error_message,
            keep_alive,
            strlen((char *) template_handler->string_value),
            NO_CACHE,
            TRUE
        ) : write_http_headers_a(
            connection,
            headers_buffer,
            size,
            version,
            error_code,
            error_message,
            keep_alive,
            strlen((char *) template_handler->string_value),
            NO_CACHE,
            realm,
            TRUE
        );

        /* creates a new string buffer to hold the complete set of contents
        to be sent to the client then first writes the buffer containing
        the headers and then the resulting contents from the template handler */
        create_string_buffer(&string_buffer);
        append_string_buffer(string_buffer, (unsigned char *) headers_buffer);
        append_string_buffer(string_buffer, template_handler->string_value);
        join_string_buffer(string_buffer, &result_buffer);
        result_length = string_buffer->string_length;
        delete_string_buffer(string_buffer);

        /* deletes the template handler as all the processing on it
        has been done (buffer generated) */
        delete_template_handler(template_handler);

        /* releases the contents of the headers buffer, no more need to
        continue using them (not requried) */
        FREE(headers_buffer);

        /* writes the resulting buffer into the connection in order to be sent
        to the client (sends the template results) in one chunk */
        write_connection(
            connection,
            result_buffer,
            (unsigned int) result_length,
            (connection_data_callback) callback,
            callback_parameters
        );
    } else {
        /* "stringfies" a possible null error description into a description
        string in order to be correctly displayed then formats the error
        message using the code, message and description */
        error_description = error_description == NULL ? (char *) service->description : error_description;
        SPRINTF(
            _error_description,
            sizeof(_error_description),
            "%d - %s - %s",
            error_code,
            error_message,
            error_description
        );

        /* writes the http static headers to the response and
        then writes the error description itself */
        write_http_headers_m(
            connection,
            headers_buffer,
            size,
            version,
            error_code,
            error_message,
            keep_alive,
            strlen(_error_description),
            NO_CACHE,
            _error_description
        );

        /* writes both the headers to the connection, an then
        registers for the appropriate callbacks */
        write_connection(
            connection,
            (unsigned char *) headers_buffer,
            (unsigned int) strlen(headers_buffer),
            (connection_data_callback) callback,
            callback_parameters
        );
    }

    /* raises no error */
    RAISE_NO_ERROR;
}