Made compilable

This commit is contained in:
Ilja Kartašov 2019-03-13 16:47:23 +01:00
parent a49e32dff8
commit fc33a0e49e
10 changed files with 270 additions and 366 deletions

View File

@ -54,10 +54,6 @@ aisl_status_t
aisl_flush( aisl_stream_t stream ); aisl_flush( aisl_stream_t stream );
void
aisl_cancel( aisl_stream_t stream );
void void
aisl_reject( aisl_stream_t stream ); aisl_reject( aisl_stream_t stream );

View File

@ -55,7 +55,7 @@ typedef enum
} aisl_status_t; } aisl_status_t;
#ifdef WITH_STRINGIFIERS #ifndef WITHOUT_STRINGIFIERS
const char * const char *
aisl_status_to_string(aisl_status_t status); aisl_status_to_string(aisl_status_t status);
@ -72,7 +72,7 @@ typedef enum
} aisl_http_version_t; } aisl_http_version_t;
#ifdef WITH_STRINGIFIERS #ifndef WITHOUT_STRINGIFIERS
const char * const char *
aisl_http_version_to_string( aisl_http_version_t version ); aisl_http_version_to_string( aisl_http_version_t version );
@ -95,7 +95,7 @@ typedef enum
} aisl_http_method_t; } aisl_http_method_t;
#ifdef WITH_STRINGIFIERS #ifndef WITHOUT_STRINGIFIERS
const char * const char *
aisl_http_method_to_string( aisl_http_method_t method ); aisl_http_method_to_string( aisl_http_method_t method );
@ -153,15 +153,12 @@ typedef enum
} aisl_http_response_t; } aisl_http_response_t;
#ifdef WITH_STRINGIFIERS
const char * const char *
aisl_http_response_to_string( aisl_http_response_t code ); aisl_http_response_to_string( aisl_http_response_t code );
#endif
#ifndef WITHOUT_STRINGIFIERS
#ifdef WITH_STRINGIFIERS
const char * const char *
aisl_http_secure_to_string( bool is_secure ); aisl_http_secure_to_string( bool is_secure );
@ -192,7 +189,7 @@ enum
}; };
#ifdef WITH_STRINGIFIERS #ifndef WITHOUT_STRINGIFIERS
const char * const char *
aisl_event_to_string( aisl_event_t event ); aisl_event_to_string( aisl_event_t event );

View File

@ -4,45 +4,36 @@
#include <string.h> #include <string.h>
#include "buffer.h" #include "buffer.h"
/* -------------------------------------------------------------------------- */
buffer_t int32_t
buffer_new( size_t initial_size ) buffer_init( buffer_t buffer, int32_t size )
{ {
buffer_t self; if ((buffer->data = malloc(size)) != NULL)
if ( (self = calloc(1, sizeof(struct buffer))) != NULL)
{ {
if ( (self->size = initial_size) > 0 ) buffer->size = size;
{ buffer->length = 0;
if ( !(self->data = calloc( initial_size+1, sizeof(char) )) ) return size;
{
free(self);
self = NULL;
}
}
} }
return self; return -1;
} }
/* -------------------------------------------------------------------------- */
void void
buffer_free( buffer_t self ) buffer_release( buffer_t buffer )
{ {
if (self->data) if (buffer->data)
free(self->data); free(buffer->data);
free(self); buffer->length = 0;
buffer->size = 0;
} }
/* -------------------------------------------------------------------------- */
size_t int32_t
buffer_add( buffer_t self, const char * data, size_t size ) buffer_add( buffer_t self, const char * data, int32_t size )
{ {
size_t result = size+self->size; int32_t result = size+self->size;
char * ptr; char * ptr;
@ -54,41 +45,39 @@ buffer_add( buffer_t self, const char * data, size_t size )
self->size = result; self->size = result;
} }
else else
result = BUFFER_EOB; result = -1;
return result; return result;
} }
/* -------------------------------------------------------------------------- */
size_t int32_t
buffer_clear( buffer_t self, size_t to_alloc ) buffer_clear( buffer_t self, int32_t to_alloc )
{ {
char * data; self->length = 0;
self->size = 0; if (to_alloc > 0)
if (to_alloc)
{ {
if ( (data = realloc(self->data, to_alloc)) != NULL ) if ( (self->data = realloc(self->data, to_alloc)) != NULL )
{ {
self->data = data; self->size = to_alloc;
return to_alloc; return to_alloc;
} }
else
to_alloc = -1;
} }
free(self->data); free(self->data);
self->data = NULL; self->data = NULL;
return 0; return to_alloc;
} }
/* -------------------------------------------------------------------------- */
size_t int32_t
buffer_shift( buffer_t self, size_t size ) buffer_shift( buffer_t self, int32_t size )
{ {
size_t result; int32_t result;
if (size && !(size > self->size)) if (size && !(size > self->size))
{ {
@ -97,17 +86,16 @@ buffer_shift( buffer_t self, size_t size )
self->size = result; self->size = result;
} }
else else
result = BUFFER_EOB; result = -1;
return result; return result;
} }
/* -------------------------------------------------------------------------- */
size_t int32_t
buffer_insert( buffer_t self, size_t offset, const char * data, size_t size ) buffer_insert( buffer_t self, int32_t offset, const char * data, int32_t size )
{ {
size_t result = size + self->size; int32_t result = size + self->size;
char * ptr; char * ptr;
@ -120,10 +108,7 @@ buffer_insert( buffer_t self, size_t offset, const char * data, size_t size )
self->size = result; self->size = result;
} }
else else
result = BUFFER_EOB; result = -1;
return result; return result;
} }
/* -------------------------------------------------------------------------- */

View File

@ -3,7 +3,6 @@
#include <sys/types.h> #include <sys/types.h>
/* -------------------------------------------------------------------------- */
struct buffer struct buffer
{ {
@ -14,41 +13,29 @@ struct buffer
typedef struct buffer * buffer_t; typedef struct buffer * buffer_t;
#define BUFFER_EOB ( ~0L )
int32_t
int
buffer_init( buffer_t buffer, int32_t size ); buffer_init( buffer_t buffer, int32_t size );
/* -------------------------------------------------------------------------- */
buffer_t
buffer_new( size_t initial_size );
/* -------------------------------------------------------------------------- */
void void
buffer_free( buffer_t self ); buffer_release( buffer_t buffer );
/* -------------------------------------------------------------------------- */
size_t int32_t
buffer_insert( buffer_t self, size_t offset, const char * data, size_t size ); buffer_clear( buffer_t self, int32_t to_alloc );
/* -------------------------------------------------------------------------- */
size_t
buffer_add( buffer_t self, const char * data, size_t size );
/* -------------------------------------------------------------------------- */ int32_t
buffer_insert( buffer_t self, int32_t offset, const char * data, int32_t size );
size_t
buffer_clear( buffer_t self, size_t to_alloc );
/* -------------------------------------------------------------------------- */ int32_t
buffer_add( buffer_t self, const char * data, int32_t size );
size_t
buffer_shift( buffer_t self, size_t size );
/* -------------------------------------------------------------------------- */ int32_t
buffer_shift( buffer_t self, int32_t size );
#endif #endif

View File

@ -64,6 +64,15 @@ bool
aisl_client_is_timed_out(aisl_client_t client, uint32_t timeout); aisl_client_is_timed_out(aisl_client_t client, uint32_t timeout);
/**
* @Brief Checks if client is about to keep connection alive.
* @param client an #aisl_client_t instance pointer.
* @return true if keepalive mode is on, otherwise false.
*/
bool
aisl_client_is_keepalive(aisl_client_t client);
/** /**
* @brief Gets socket descriptor associated with #aisl_client_t instance. * @brief Gets socket descriptor associated with #aisl_client_t instance.
* @param client an #aisl_client_t instance pointer. * @param client an #aisl_client_t instance pointer.

View File

@ -15,6 +15,10 @@
#include <sys/select.h> #include <sys/select.h>
#include <sys/time.h> #include <sys/time.h>
#ifndef AISL_WITHOUT_SSL
#include <openssl/err.h>
#endif
#include "list.h" #include "list.h"
#include "str-utils.h" #include "str-utils.h"
#include "buffer.h" #include "buffer.h"
@ -46,7 +50,6 @@ struct aisl
list_t ssl_spool; list_t ssl_spool;
#endif #endif
buffer_t buffer;
char * last_error; char * last_error;
size_t iterator; size_t iterator;
@ -89,9 +92,6 @@ aisl_new( aisl_config_t config )
if ( !(instance->callback_spool = list_new(config->callback_spool_size)) ) if ( !(instance->callback_spool = list_new(config->callback_spool_size)) )
goto release; goto release;
if ( !(instance->buffer = buffer_new(config->initial_buffer_size)) )
goto release;
#ifndef AISL_WITHOUT_SSL #ifndef AISL_WITHOUT_SSL
if ( !(instance->ssl_spool = list_new(config->ssl_spool_size)) ) if ( !(instance->ssl_spool = list_new(config->ssl_spool_size)) )
goto release; goto release;
@ -124,12 +124,9 @@ aisl_free( aisl_t instance )
if (instance->callback_spool) if (instance->callback_spool)
list_free(instance->callback_spool, (list_destructor_t) free); list_free(instance->callback_spool, (list_destructor_t) free);
if (instance->buffer)
buffer_free(instance->buffer);
#ifndef AISL_WITHOUT_SSL #ifndef AISL_WITHOUT_SSL
if (instance->ssl_spool) if (instance->ssl_spool)
list_free(instance->ssl_spool, (list_destructor_t) ssl_free ); list_free(instance->ssl_spool, (list_destructor_t) aisl_ssl_free );
#endif #endif
if (instance->last_error) if (instance->last_error)
@ -166,14 +163,66 @@ aisl_listen( aisl_t instance, const char * address, uint16_t port )
#ifndef AISL_WITHOUT_SSL #ifndef AISL_WITHOUT_SSL
static int
aisl_on_get_ssl( SSL * ssl, int * ptr, void * instance )
{
const char * server_name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
SSL_CTX * ctx = aisl_get_ssl_ctx( (aisl_t) instance, server_name );
if (ctx)
{
SSL_set_SSL_CTX(ssl, ctx);
}
(void)ptr;
return SSL_TLSEXT_ERR_OK;
}
static aisl_status_t
aisl_set_ssl_ctx(aisl_t instance, aisl_ssl_t ssl)
{
const SSL_METHOD * method;
SSL_CTX * ctx;
method = SSLv23_server_method();
if ( (ctx = SSL_CTX_new(method)) != NULL )
{
SSL_CTX_set_ecdh_auto(ctx, 1);
SSL_CTX_set_tlsext_servername_callback( ctx, aisl_on_get_ssl );
SSL_CTX_set_tlsext_servername_arg( ctx, (void *) instance );
if (!(SSL_CTX_use_certificate_file(ctx, ssl->crt_file, SSL_FILETYPE_PEM)>0))
goto except;
if (!(SSL_CTX_use_PrivateKey_file(ctx, ssl->key_file, SSL_FILETYPE_PEM)>0))
goto except;
ssl->ctx = ctx;
return AISL_SUCCESS;
}
except:
SSL_CTX_free(ctx);
aisl_set_error( instance, ERR_error_string(ERR_get_error(),NULL) );
return AISL_SYSCALL_ERROR;
}
__attribute__ ((visibility ("default") )) __attribute__ ((visibility ("default") ))
aisl_status_t aisl_status_t
aisl_set_ssl( aisl_t instance, const char * domain, aisl_set_ssl( aisl_t instance, const char * host,
const char * key_file, const char * key_file,
const char * crt_file ) const char * crt_file )
{ {
SSL_CTX * ssl_ctx = NULL; SSL_CTX * ssl_ctx = NULL;
ssl_t ssl; aisl_ssl_t ssl;
size_t i; size_t i;
/* lookup for existing contexts */ /* lookup for existing contexts */
@ -188,12 +237,15 @@ aisl_set_ssl( aisl_t instance, const char * domain,
} }
} }
if ((ssl = ssl_new(domain, key_file, crt_file, ssl_ctx)) != NULL) if ((ssl = aisl_ssl_new(host, key_file, crt_file, ssl_ctx)) != NULL)
{
if (!ssl_ctx || (aisl_set_ssl_ctx(instance, ssl) == AISL_SUCCESS))
{ {
if (list_append(instance->ssl_spool, ssl) != LIST_NAN) if (list_append(instance->ssl_spool, ssl) != LIST_NAN)
return AISL_SUCCESS; return AISL_SUCCESS;
}
ssl_free(ssl); aisl_ssl_free(ssl);
} }
return AISL_MALLOC_ERROR; return AISL_MALLOC_ERROR;
@ -201,17 +253,17 @@ aisl_set_ssl( aisl_t instance, const char * domain,
SSL_CTX * SSL_CTX *
aisl_get_ssl_ctx( aisl_t instance, const char * domain ) aisl_get_ssl_ctx( aisl_t instance, const char * host )
{ {
size_t i; size_t i;
ssl_t ssl; aisl_ssl_t ssl;
if (domain) if (host)
{ {
for (i=0; i<instance->ssl_spool->count; i++) for (i=0; i<instance->ssl_spool->count; i++)
{ {
ssl = list_index(instance->ssl_spool, i); ssl = list_index(instance->ssl_spool, i);
if (strcmp(ssl->domain, domain) != 0) if (strcmp(ssl->host, host) != 0)
continue; continue;
return ssl->ctx; return ssl->ctx;

118
src/ssl.c
View File

@ -7,112 +7,64 @@
#include <openssl/err.h> #include <openssl/err.h>
#include "ssl.h" #include "ssl.h"
#include "str-utils.h"
#ifndef AISL_WITHOUT_SSL #ifndef AISL_WITHOUT_SSL
static int
get_ssl_context( SSL * ssl, int * ptr, void * handle ) aisl_ssl_t
aisl_ssl_new( const char * key_file,
const char * crt_file,
const char * host,
SSL_CTX * ctx )
{ {
const char * server_name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); aisl_ssl_t ssl;
SSL_CTX * ctx = aisl_get_ssl_ctx( (aisl_t) handle, server_name );
if ((ssl = calloc(1, sizeof(struct aisl_ssl))) != NULL)
{
if ((ssl->host = str_copy( host ? host : "*" )) != NULL)
{
if (ctx) if (ctx)
{ {
SSL_set_SSL_CTX(ssl, ctx); ssl->ctx = ctx;
return ssl;
} }
else
return SSL_TLSEXT_ERR_OK;
}
/* -------------------------------------------------------------------------- */
static SSL_CTX *
create_ssl_context( aisl_t instance,
const char * key_file,
const char * crt_file )
{ {
const SSL_METHOD * method; if ((ssl->key_file = str_copy(key_file)) != NULL)
SSL_CTX * ctx;
method = SSLv23_server_method();
if ( !(ctx = SSL_CTX_new(method)) )
goto except;
SSL_CTX_set_ecdh_auto(ctx, 1);
SSL_CTX_set_tlsext_servername_callback( ctx, get_ssl_context );
SSL_CTX_set_tlsext_servername_arg( ctx, (void *) instance );
if (!(SSL_CTX_use_certificate_file(ctx, crt_file, SSL_FILETYPE_PEM) > 0))
goto release;
if (!(SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) > 0))
goto release;
goto finally;
release:
SSL_CTX_free(ctx);
ctx = NULL;
except:
aisl_set_error( instance, ERR_error_string(ERR_get_error(),NULL) );
finally:
return ctx;
}
static void
crypter_free( crypter_t self )
{ {
if (self->srvName) if ((ssl->crt_file = str_copy(crt_file)) != NULL)
free(self->srvName);
if (self->keyFile)
{ {
free(self->keyFile); return ssl;
SSL_CTX_free(self->sslCtx); }
}
}
}
aisl_ssl_free(ssl);
} }
if (self->crtFile) return NULL;
free(self->crtFile);
free(self);
} }
static crypter_t void
crypter_new( const char * server_name, aisl_ssl_free( aisl_ssl_t ssl )
const char * key_file,
const char * crt_file )
{ {
crypter_t self; if (ssl->host)
free(ssl->host);
if ( (self=calloc(1, sizeof(struct crypter))) != NULL ) if (ssl->key_file)
{ {
if (!(self->srvName = str_copy( server_name ? server_name : "*" ))) free(ssl->key_file);
goto release; SSL_CTX_free(ssl->ctx);
if ( key_file && !(self->keyFile = str_copy(key_file)))
goto release;
if ( crt_file && !(self->crtFile = str_copy(crt_file)))
goto release;
} }
goto finally; if (ssl->crt_file)
free(ssl->crt_file);
free(ssl);
release:
crypter_free(self);
self = NULL;
finally:
return self;
} }
#endif #endif

View File

@ -14,23 +14,26 @@
#include <openssl/ssl.h> #include <openssl/ssl.h>
struct ssl struct aisl_ssl
{ {
char * key_file; char * key_file;
char * crt_file; char * crt_file;
char * domain; char * host;
SSL_CTX * ctx; SSL_CTX * ctx;
}; };
typedef struct ssl * ssl_t; typedef struct aisl_ssl * aisl_ssl_t;
ssl_t aisl_ssl_t
ssl_new( const char * key_file, const char * crt_file, const char * domain, SSL_CTX * ctx ); aisl_ssl_new( const char * key_file,
const char * crt_file,
const char * host,
SSL_CTX * ctx );
void void
ssl_free( ssl_t self ); aisl_ssl_free( aisl_ssl_t ssl );
#endif /* !AISL_SSL_H */ #endif /* !AISL_SSL_H */

View File

@ -2,18 +2,24 @@
#include <stdarg.h> #include <stdarg.h>
#include <string.h> #include <string.h>
#include "instance.h"
#include "client.h"
#include "server.h"
#include "buffer.h" #include "buffer.h"
#include "str-utils.h"
#include "stream.h" #include "stream.h"
#define FLAG_OUTPUT_READY (1<<0) #define FLAG_OUTPUT_READY (1<<0)
#define FLAG_OUTPUT_CHUNKED (1<<1) #define FLAG_OUTPUT_CHUNKED (1<<1)
#define SIZE_NAN (~0)
struct aisl_stream struct aisl_stream
{ {
struct buffer buffer;
aisl_client_t client; aisl_client_t client;
struct buffer buffer; void * u_ptr;
const char * content_type; const char * content_type;
size_t content_length; size_t content_length;
@ -23,221 +29,145 @@ struct aisl_stream
aisl_http_response_t response; aisl_http_response_t response;
aisl_stream_state_t state; aisl_stream_state_t state;
bool c_length_unknown;
}; };
static void
pair_free( pair_t stream )
{
if (!stream) return;
if(stream->key) free(stream->key);
if(stream->value) free(stream->value); static void
free(stream); aisl_stream_reset(aisl_stream_t stream, bool initial)
{
if (!initial)
{
aisl_t instance;
instance = aisl_stream_get_instance(stream);
aisl_raise(instance, stream, AISL_EVENT_STREAM_CLOSE);
aisl_unset_callbacks_for(instance, stream);
} }
/* -------------------------------------------------------------------------- */
buffer_release(&stream->buffer);
stream->u_ptr = NULL;
stream->content_type = NULL;
stream->content_length = SIZE_NAN;
stream->content_offset = 0; /* headers length */
stream->flags = 0;
stream->state = AISL_STREAM_STATE_IDLE;
stream->response = AISL_HTTP_OK;
}
aisl_stream_t aisl_stream_t
stream_new(struct sockaddr_in *client, int id, stream_state_t state) aisl_stream_new(aisl_client_t client, int id)
{ {
aisl_stream_t stream = malloc(sizeof(struct aisl_stream)); aisl_stream_t stream = malloc(sizeof(struct aisl_stream));
if (stream) if (stream)
{ {
/* public data */
ASTREAM(stream)->client = client;
ASTREAM(stream)->host = NULL;
ASTREAM(stream)->path = NULL;
ASTREAM(stream)->query = NULL;
ASTREAM(stream)->scheme = NULL;
ASTREAM(stream)->u_ptr = NULL;
ASTREAM(stream)->request_method = AISL_HTTP_GET;
/* private data */
stream->headers = NULL; /* request headers */
stream->buffer = buffer_new(0);
stream->c_type = NULL;
stream->response = AISL_HTTP_OK;
stream->state = STREAM_REQUEST_METHOD;
stream->c_length = 0;
stream->c_offset = 0; /* headers length */
stream->id = id; stream->id = id;
stream->c_length_unknown = true; stream->client = client;
stream->flags = 0; aisl_stream_reset(stream, true);
} }
return stream; return stream;
} }
/*
aisl_stream_t
stream_reset(aisl_stream_t stream)
{
if (ASTREAM(stream)->path)
{
free( (char*) ASTREAM(stream)->path);
ASTREAM(stream)->path = NULL;
}
if (ASTREAM(stream)->query)
{
free( (char*) ASTREAM(stream)->query);
ASTREAM(stream)->query = NULL;
}
ASTREAM(stream)->u_ptr = NULL;
ASTREAM(stream)->request_method = AISL_HTTP_GET;
if (stream->headers)
{
list_free(stream->headers, (list_destructor_t) pair_free);
stream->headers = NULL;
}
stream->c_type = NULL;
stream->response = AISL_HTTP_OK;
stream->state = STREAM_REQUEST_METHOD;
stream->c_length = 0;
stream->c_offset = 0; / * headers length * /
stream->c_length_unknown = true;
stream->flags = 0;
return stream;
}
*/
/* -------------------------------------------------------------------------- */
void void
stream_free(aisl_stream_t stream) aisl_stream_free(aisl_stream_t stream)
{ {
if (stream->buffer) buffer_free(stream->buffer); aisl_stream_reset(stream, false);
if (stream->headers) list_free(stream->headers, (list_destructor_t) pair_free);
if (ASTREAM(stream)->path) free( (char*) ASTREAM(stream)->path);
if (ASTREAM(stream)->query) free( (char*) ASTREAM(stream)->query);
aisl_handle_t hd = ((client_t) ASTREAM(stream)->client)->server->owner;
aisl_raise_event(hd, stream, AISL_STREAM_CLOSE);
ASTREAM(stream)->u_ptr = NULL;
aisl_remove_listeners_for(hd, stream);
free(stream); free(stream);
} }
/* -------------------------------------------------------------------------- */
int /* Why it was here?
stream_write(aisl_stream_t stream, const char * data, uint32_t d_len) static int
aisl_stream_write(aisl_stream_t stream, const char * data, uint32_t d_len)
{ {
return buffer_add( stream->buffer, data, d_len); return buffer_add( &stream->buffer, data, d_len);
} }
/* -------------------------------------------------------------------------- */
__attribute__ ((visibility ("default") )) __attribute__ ((visibility ("default") ))
void void
aisl_cancel(aisl_aisl_stream_t s) aisl_cancel(aisl_stream_t stream)
{ {
client_close( (client_t) s->client ); aisl_client_close( stream->client );
} }
*/
/* -------------------------------------------------------------------------- */
__attribute__ ((visibility ("default") ))
bool
aisl_is_secure(aisl_aisl_stream_t s)
{
client_t cli = (client_t) s->client;
return (cli->ssl) ? true : false;
}
/* -------------------------------------------------------------------------- */
__attribute__ ((visibility ("default") )) __attribute__ ((visibility ("default") ))
void * void *
aisl_get_context(aisl_aisl_stream_t s) aisl_get_context(aisl_stream_t s)
{ {
return s->u_ptr; return s->u_ptr;
} }
/* -------------------------------------------------------------------------- */
__attribute__ ((visibility ("default") )) __attribute__ ((visibility ("default") ))
void void
aisl_set_context(aisl_aisl_stream_t s, void * u_ptr) aisl_set_context(aisl_stream_t s, void * u_ptr)
{ {
s->u_ptr = u_ptr; s->u_ptr = u_ptr;
} }
/* -------------------------------------------------------------------------- */
__attribute__ ((visibility ("default") )) __attribute__ ((visibility ("default") ))
aisl_client_t aisl_client_t
aisl_get_client(aisl_aisl_stream_t s) aisl_get_client(aisl_stream_t s)
{ {
return s->client; return s->client;
} }
/* -------------------------------------------------------------------------- */
__attribute__ ((visibility ("default") )) __attribute__ ((visibility ("default") ))
aisl_server_t aisl_server_t
aisl_get_server(aisl_aisl_stream_t s) aisl_get_server(aisl_stream_t s)
{ {
return (aisl_server_t) (((client_t) s->client)->server); return aisl_client_get_server(s->client);
} }
/* -------------------------------------------------------------------------- */
__attribute__ ((visibility ("default") )) __attribute__ ((visibility ("default") ))
aisl_http_version_t aisl_http_version_t
aisl_get_http_version(aisl_aisl_stream_t s) aisl_get_http_version(aisl_stream_t s)
{ {
client_t cli = (client_t) s->client; return aisl_client_get_http_version(s->client);
return cli->protocol;
} }
/* -------------------------------------------------------------------------- */
__attribute__ ((visibility ("default") )) __attribute__ ((visibility ("default") ))
void void
aisl_reject(aisl_aisl_stream_t s) aisl_reject(aisl_stream_t s)
{ {
client_t cli = (client_t) s->client; aisl_client_close( s->client );
client_close( cli );
} }
/* -------------------------------------------------------------------------- */
static char * static char *
get_response_begin(aisl_stream_t stream) aisl_stream_get_response_begin(aisl_stream_t stream)
{ {
char * r; char * r;
client_t cli = CLIENT(ASTREAM(stream)->client);
r = str_printf( r = str_printf(
"%s %d %s\r\n" "%s %d %s\r\n"
"Server: AISL\r\n" "Server: AISL\r\n"
"Connection: %s\r\n\r\n", "Connection: %s\r\n\r\n",
aisl_http_version_to_string(cli->protocol), aisl_get_http_version(stream),
stream->response, stream->response,
aisl_http_response_to_string(stream->response), aisl_http_response_to_string(stream->response),
((cli->flags & CLIENT_FLAG_KEEPALIVE) ? "keep-alive" : "close") aisl_client_is_keepalive(stream->client) ? "keep-alive" : "close"
); );
return r; return r;
} }
__attribute__ ((visibility ("default") )) __attribute__ ((visibility ("default") ))
aisl_status_t aisl_status_t
aisl_response(aisl_aisl_stream_t stream, aisl_http_response_t status_code, aisl_response(aisl_stream_t stream, aisl_http_response_t status_code,
const char *content_type, const char *content_type,
uint32_t content_length) uint32_t content_length)
{ {
@ -246,24 +176,24 @@ aisl_response(aisl_aisl_stream_t stream, aisl_http_response_t status_code,
/* check if those headers were already sent */ /* check if those headers were already sent */
if (STREAM(stream)->state > STREAM_REQUEST_READY) return AISL_IDLE; if (stream->state > AISL_STREAM_STATE_READY) return AISL_IDLE;
STREAM(stream)->response = status_code; stream->response = status_code;
STREAM(stream)->c_type = content_type; stream->content_type = content_type;
STREAM(stream)->c_length = content_length; stream->content_length = content_length;
if ( !(pch = get_response_begin(STREAM(stream))) ) if ( !(pch = aisl_stream_get_response_begin(stream)) )
return AISL_MALLOC_ERROR; return AISL_MALLOC_ERROR;
l = strlen(pch); l = strlen(pch);
STREAM(stream)->c_offset = l-2; stream->content_offset = l-2;
buffer_clear(STREAM(stream)->buffer, content_length); buffer_clear(&stream->buffer, content_length);
l = buffer_add( STREAM(stream)->buffer, pch, l ); l = buffer_add( &stream->buffer, pch, l );
free(pch); free(pch);
if (l == BUFFER_EOB) return AISL_MALLOC_ERROR; if (l == -1) return AISL_MALLOC_ERROR;
if (content_length) if (content_length)
{ {
@ -277,7 +207,7 @@ aisl_response(aisl_aisl_stream_t stream, aisl_http_response_t status_code,
return AISL_MALLOC_ERROR; return AISL_MALLOC_ERROR;
} }
STREAM(stream)->state = STREAM_RESPONSE_HEADER; stream->state = AISL_STREAM_STATE_SEND_HEADER;
return AISL_SUCCESS; return AISL_SUCCESS;
} }
@ -285,24 +215,23 @@ aisl_response(aisl_aisl_stream_t stream, aisl_http_response_t status_code,
__attribute__ ((visibility ("default") )) __attribute__ ((visibility ("default") ))
aisl_status_t aisl_status_t
aisl_flush(aisl_aisl_stream_t stream) aisl_flush(aisl_stream_t s)
{ {
aisl_stream_t s = STREAM(stream); if ( ! s->content_length )
if ( ! s->c_length )
{ {
s->c_length = s->buffer->size - s->c_offset - 2; s->content_length = s->buffer.size - s->content_offset - 2;
if (!aisl_header_printf(stream, "Content-Length", "%u", s->c_length)) if (!aisl_header_printf(s, "Content-Length", "%u", s->content_length))
return AISL_MALLOC_ERROR; return AISL_MALLOC_ERROR;
} }
/* /*
fprintf(stdout, "(%lu bytes)------->\n", STREAM(stream)->buffer->size); fprintf(stdout, "(%lu bytes)------->\n", stream->buffer->size);
fwrite(STREAM(stream)->buffer->data, 1, STREAM(stream)->buffer->size, stdout); fwrite(stream->buffer->data, 1, stream->buffer->size, stdout);
fprintf(stdout, "<------\n"); fprintf(stdout, "<------\n");
*/ */
s->state = STREAM_RESPONSE_READY; s->state = AISL_STREAM_STATE_READY;
s->flags |= STREAM_FLAG_OUTPUT_READY; s->flags |= FLAG_OUTPUT_READY;
return AISL_SUCCESS; return AISL_SUCCESS;
} }
@ -310,7 +239,7 @@ aisl_flush(aisl_aisl_stream_t stream)
__attribute__ ((visibility ("default") )) __attribute__ ((visibility ("default") ))
int int
aisl_header(aisl_aisl_stream_t stream, const char *key, const char *value) aisl_header(aisl_stream_t stream, const char *key, const char *value)
{ {
int ret; int ret;
char * pch; char * pch;
@ -319,16 +248,16 @@ aisl_header(aisl_aisl_stream_t stream, const char *key, const char *value)
{ {
ret = strlen(pch); ret = strlen(pch);
if ( buffer_insert( if ( buffer_insert(
STREAM(stream)->buffer, &stream->buffer,
STREAM(stream)->c_offset, stream->content_offset,
pch, pch,
ret ret
) == BUFFER_EOB ) ) == -1 )
{ {
ret = -1; ret = -1;
} }
else else
STREAM(stream)->c_offset += ret; stream->content_offset += ret;
free(pch); free(pch);
} }
@ -341,7 +270,7 @@ aisl_header(aisl_aisl_stream_t stream, const char *key, const char *value)
__attribute__ ((visibility ("default") )) __attribute__ ((visibility ("default") ))
int int
aisl_header_printf(aisl_aisl_stream_t stream, const char *key, aisl_header_printf(aisl_stream_t stream, const char *key,
const char *f_value, ...) const char *f_value, ...)
{ {
int ret; int ret;
@ -359,7 +288,7 @@ aisl_header_printf(aisl_aisl_stream_t stream, const char *key,
__attribute__ ((visibility ("default") )) __attribute__ ((visibility ("default") ))
int int
aisl_header_vprintf(aisl_aisl_stream_t stream, const char *key, aisl_header_vprintf(aisl_stream_t stream, const char *key,
const char *format, const char *format,
va_list args) va_list args)
{ {
@ -380,7 +309,7 @@ aisl_header_vprintf(aisl_aisl_stream_t stream, const char *key,
__attribute__ ((visibility ("default") )) __attribute__ ((visibility ("default") ))
int int
aisl_printf(aisl_aisl_stream_t stream, const char *format, ...) aisl_printf(aisl_stream_t stream, const char *format, ...)
{ {
va_list arg; va_list arg;
va_start(arg, format); va_start(arg, format);
@ -391,8 +320,8 @@ aisl_printf(aisl_aisl_stream_t stream, const char *format, ...)
/* No need to update length there, because vprintf do that /* No need to update length there, because vprintf do that
* *
* if (STREAM(stream)->c_length_unknown) * if (stream->c_length_unknown)
STREAM(stream)->c_length += result; stream->c_length += result;
*/ */
@ -403,7 +332,7 @@ aisl_printf(aisl_aisl_stream_t stream, const char *format, ...)
__attribute__ ((visibility ("default") )) __attribute__ ((visibility ("default") ))
int int
aisl_vprintf(aisl_aisl_stream_t stream, const char *format, va_list args) aisl_vprintf(aisl_stream_t stream, const char *format, va_list args)
{ {
int result; int result;
char * r; char * r;
@ -411,7 +340,7 @@ aisl_vprintf(aisl_aisl_stream_t stream, const char *format, va_list args)
if ( (r = str_vprintf(format, args)) != NULL) if ( (r = str_vprintf(format, args)) != NULL)
{ {
result = strlen(r); result = strlen(r);
if (buffer_add(STREAM(stream)->buffer, r, result) == BUFFER_EOB) if (buffer_add(&stream->buffer, r, result) == -1)
result = -1; result = -1;
free(r); free(r);
@ -425,12 +354,12 @@ aisl_vprintf(aisl_aisl_stream_t stream, const char *format, va_list args)
__attribute__ ((visibility ("default") )) __attribute__ ((visibility ("default") ))
int int
aisl_write(aisl_aisl_stream_t stream, const char *data, int d_len) aisl_write(aisl_stream_t stream, const char *data, int d_len)
{ {
if (d_len < 0) if (d_len < 0)
d_len = strlen(data); d_len = strlen(data);
if (buffer_add(STREAM(stream)->buffer, data, d_len) == BUFFER_EOB) if (buffer_add(&stream->buffer, data, d_len) == -1)
d_len = -1; d_len = -1;
return d_len; return d_len;
@ -439,7 +368,7 @@ aisl_write(aisl_aisl_stream_t stream, const char *data, int d_len)
__attribute__ ((visibility ("default") )) __attribute__ ((visibility ("default") ))
int int
aisl_puts(const char *str, aisl_aisl_stream_t stream) aisl_puts(const char *str, aisl_stream_t stream)
{ {
return aisl_write( stream, str, strlen(str)); return aisl_write( stream, str, strlen(str));
} }

View File

@ -31,12 +31,6 @@ void
aisl_stream_free(aisl_stream_t stream); aisl_stream_free(aisl_stream_t stream);
/* to be removed ??
* aisl_stream_t
* aisl_stream_reset(aisl_stream_t stream);
*/
void void
aisl_stream_set_chunked_output(aisl_stream_t stream, bool value); aisl_stream_set_chunked_output(aisl_stream_t stream, bool value);