Made compilable
This commit is contained in:
parent
a49e32dff8
commit
fc33a0e49e
|
@ -54,10 +54,6 @@ aisl_status_t
|
|||
aisl_flush( aisl_stream_t stream );
|
||||
|
||||
|
||||
void
|
||||
aisl_cancel( aisl_stream_t stream );
|
||||
|
||||
|
||||
void
|
||||
aisl_reject( aisl_stream_t stream );
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ typedef enum
|
|||
|
||||
} aisl_status_t;
|
||||
|
||||
#ifdef WITH_STRINGIFIERS
|
||||
#ifndef WITHOUT_STRINGIFIERS
|
||||
|
||||
const char *
|
||||
aisl_status_to_string(aisl_status_t status);
|
||||
|
@ -72,7 +72,7 @@ typedef enum
|
|||
|
||||
} aisl_http_version_t;
|
||||
|
||||
#ifdef WITH_STRINGIFIERS
|
||||
#ifndef WITHOUT_STRINGIFIERS
|
||||
|
||||
const char *
|
||||
aisl_http_version_to_string( aisl_http_version_t version );
|
||||
|
@ -95,7 +95,7 @@ typedef enum
|
|||
|
||||
} aisl_http_method_t;
|
||||
|
||||
#ifdef WITH_STRINGIFIERS
|
||||
#ifndef WITHOUT_STRINGIFIERS
|
||||
|
||||
const char *
|
||||
aisl_http_method_to_string( aisl_http_method_t method );
|
||||
|
@ -153,15 +153,12 @@ typedef enum
|
|||
|
||||
} aisl_http_response_t;
|
||||
|
||||
#ifdef WITH_STRINGIFIERS
|
||||
|
||||
const char *
|
||||
aisl_http_response_to_string( aisl_http_response_t code );
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef WITH_STRINGIFIERS
|
||||
#ifndef WITHOUT_STRINGIFIERS
|
||||
|
||||
const char *
|
||||
aisl_http_secure_to_string( bool is_secure );
|
||||
|
@ -192,7 +189,7 @@ enum
|
|||
|
||||
};
|
||||
|
||||
#ifdef WITH_STRINGIFIERS
|
||||
#ifndef WITHOUT_STRINGIFIERS
|
||||
|
||||
const char *
|
||||
aisl_event_to_string( aisl_event_t event );
|
||||
|
|
81
src/buffer.c
81
src/buffer.c
|
@ -4,45 +4,36 @@
|
|||
#include <string.h>
|
||||
#include "buffer.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
buffer_t
|
||||
buffer_new( size_t initial_size )
|
||||
int32_t
|
||||
buffer_init( buffer_t buffer, int32_t size )
|
||||
{
|
||||
buffer_t self;
|
||||
|
||||
if ( (self = calloc(1, sizeof(struct buffer))) != NULL)
|
||||
if ((buffer->data = malloc(size)) != NULL)
|
||||
{
|
||||
if ( (self->size = initial_size) > 0 )
|
||||
{
|
||||
if ( !(self->data = calloc( initial_size+1, sizeof(char) )) )
|
||||
{
|
||||
free(self);
|
||||
self = NULL;
|
||||
}
|
||||
}
|
||||
buffer->size = size;
|
||||
buffer->length = 0;
|
||||
return size;
|
||||
}
|
||||
|
||||
return self;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
buffer_free( buffer_t self )
|
||||
buffer_release( buffer_t buffer )
|
||||
{
|
||||
if (self->data)
|
||||
free(self->data);
|
||||
if (buffer->data)
|
||||
free(buffer->data);
|
||||
|
||||
free(self);
|
||||
buffer->length = 0;
|
||||
buffer->size = 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
size_t
|
||||
buffer_add( buffer_t self, const char * data, size_t size )
|
||||
int32_t
|
||||
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;
|
||||
|
||||
|
@ -54,41 +45,39 @@ buffer_add( buffer_t self, const char * data, size_t size )
|
|||
self->size = result;
|
||||
}
|
||||
else
|
||||
result = BUFFER_EOB;
|
||||
result = -1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
size_t
|
||||
buffer_clear( buffer_t self, size_t to_alloc )
|
||||
int32_t
|
||||
buffer_clear( buffer_t self, int32_t to_alloc )
|
||||
{
|
||||
char * data;
|
||||
self->length = 0;
|
||||
|
||||
self->size = 0;
|
||||
|
||||
if (to_alloc)
|
||||
if (to_alloc > 0)
|
||||
{
|
||||
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;
|
||||
}
|
||||
else
|
||||
to_alloc = -1;
|
||||
}
|
||||
|
||||
free(self->data);
|
||||
self->data = NULL;
|
||||
|
||||
return 0;
|
||||
return to_alloc;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
size_t
|
||||
buffer_shift( buffer_t self, size_t size )
|
||||
int32_t
|
||||
buffer_shift( buffer_t self, int32_t size )
|
||||
{
|
||||
size_t result;
|
||||
int32_t result;
|
||||
|
||||
if (size && !(size > self->size))
|
||||
{
|
||||
|
@ -97,17 +86,16 @@ buffer_shift( buffer_t self, size_t size )
|
|||
self->size = result;
|
||||
}
|
||||
else
|
||||
result = BUFFER_EOB;
|
||||
result = -1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
size_t
|
||||
buffer_insert( buffer_t self, size_t offset, const char * data, size_t size )
|
||||
int32_t
|
||||
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;
|
||||
|
||||
|
@ -120,10 +108,7 @@ buffer_insert( buffer_t self, size_t offset, const char * data, size_t size )
|
|||
self->size = result;
|
||||
}
|
||||
else
|
||||
result = BUFFER_EOB;
|
||||
result = -1;
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
|
35
src/buffer.h
35
src/buffer.h
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include <sys/types.h>
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
struct buffer
|
||||
{
|
||||
|
@ -14,41 +13,29 @@ struct buffer
|
|||
|
||||
typedef struct buffer * buffer_t;
|
||||
|
||||
#define BUFFER_EOB ( ~0L )
|
||||
|
||||
|
||||
int
|
||||
int32_t
|
||||
buffer_init( buffer_t buffer, int32_t size );
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
buffer_t
|
||||
buffer_new( size_t initial_size );
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
buffer_free( buffer_t self );
|
||||
buffer_release( buffer_t buffer );
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
size_t
|
||||
buffer_insert( buffer_t self, size_t offset, const char * data, size_t size );
|
||||
int32_t
|
||||
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
|
||||
|
|
|
@ -64,6 +64,15 @@ bool
|
|||
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.
|
||||
* @param client an #aisl_client_t instance pointer.
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
#include <sys/select.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifndef AISL_WITHOUT_SSL
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
|
||||
#include "list.h"
|
||||
#include "str-utils.h"
|
||||
#include "buffer.h"
|
||||
|
@ -46,7 +50,6 @@ struct aisl
|
|||
list_t ssl_spool;
|
||||
#endif
|
||||
|
||||
buffer_t buffer;
|
||||
char * last_error;
|
||||
|
||||
size_t iterator;
|
||||
|
@ -89,9 +92,6 @@ aisl_new( aisl_config_t config )
|
|||
if ( !(instance->callback_spool = list_new(config->callback_spool_size)) )
|
||||
goto release;
|
||||
|
||||
if ( !(instance->buffer = buffer_new(config->initial_buffer_size)) )
|
||||
goto release;
|
||||
|
||||
#ifndef AISL_WITHOUT_SSL
|
||||
if ( !(instance->ssl_spool = list_new(config->ssl_spool_size)) )
|
||||
goto release;
|
||||
|
@ -124,12 +124,9 @@ aisl_free( aisl_t instance )
|
|||
if (instance->callback_spool)
|
||||
list_free(instance->callback_spool, (list_destructor_t) free);
|
||||
|
||||
if (instance->buffer)
|
||||
buffer_free(instance->buffer);
|
||||
|
||||
#ifndef AISL_WITHOUT_SSL
|
||||
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
|
||||
|
||||
if (instance->last_error)
|
||||
|
@ -166,14 +163,66 @@ aisl_listen( aisl_t instance, const char * address, uint16_t port )
|
|||
|
||||
#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") ))
|
||||
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 * crt_file )
|
||||
{
|
||||
SSL_CTX * ssl_ctx = NULL;
|
||||
ssl_t ssl;
|
||||
aisl_ssl_t ssl;
|
||||
size_t i;
|
||||
|
||||
/* 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 (list_append(instance->ssl_spool, ssl) != LIST_NAN)
|
||||
return AISL_SUCCESS;
|
||||
if (!ssl_ctx || (aisl_set_ssl_ctx(instance, ssl) == AISL_SUCCESS))
|
||||
{
|
||||
if (list_append(instance->ssl_spool, ssl) != LIST_NAN)
|
||||
return AISL_SUCCESS;
|
||||
}
|
||||
|
||||
ssl_free(ssl);
|
||||
aisl_ssl_free(ssl);
|
||||
}
|
||||
|
||||
return AISL_MALLOC_ERROR;
|
||||
|
@ -201,17 +253,17 @@ aisl_set_ssl( aisl_t instance, const char * domain,
|
|||
|
||||
|
||||
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;
|
||||
ssl_t ssl;
|
||||
aisl_ssl_t ssl;
|
||||
|
||||
if (domain)
|
||||
if (host)
|
||||
{
|
||||
for (i=0; i<instance->ssl_spool->count; i++)
|
||||
{
|
||||
ssl = list_index(instance->ssl_spool, i);
|
||||
if (strcmp(ssl->domain, domain) != 0)
|
||||
if (strcmp(ssl->host, host) != 0)
|
||||
continue;
|
||||
|
||||
return ssl->ctx;
|
||||
|
|
126
src/ssl.c
126
src/ssl.c
|
@ -7,112 +7,64 @@
|
|||
|
||||
#include <openssl/err.h>
|
||||
#include "ssl.h"
|
||||
#include "str-utils.h"
|
||||
|
||||
|
||||
#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 (ctx)
|
||||
if ((ssl = calloc(1, sizeof(struct aisl_ssl))) != NULL)
|
||||
{
|
||||
SSL_set_SSL_CTX(ssl, ctx);
|
||||
if ((ssl->host = str_copy( host ? host : "*" )) != NULL)
|
||||
{
|
||||
if (ctx)
|
||||
{
|
||||
ssl->ctx = ctx;
|
||||
return ssl;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((ssl->key_file = str_copy(key_file)) != NULL)
|
||||
{
|
||||
if ((ssl->crt_file = str_copy(crt_file)) != NULL)
|
||||
{
|
||||
return ssl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
aisl_ssl_free(ssl);
|
||||
}
|
||||
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static SSL_CTX *
|
||||
create_ssl_context( aisl_t instance,
|
||||
const char * key_file,
|
||||
const char * crt_file )
|
||||
void
|
||||
aisl_ssl_free( aisl_ssl_t ssl )
|
||||
{
|
||||
const SSL_METHOD * method;
|
||||
SSL_CTX * ctx;
|
||||
if (ssl->host)
|
||||
free(ssl->host);
|
||||
|
||||
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)
|
||||
free(self->srvName);
|
||||
|
||||
if (self->keyFile)
|
||||
if (ssl->key_file)
|
||||
{
|
||||
free(self->keyFile);
|
||||
SSL_CTX_free(self->sslCtx);
|
||||
free(ssl->key_file);
|
||||
SSL_CTX_free(ssl->ctx);
|
||||
}
|
||||
|
||||
if (self->crtFile)
|
||||
free(self->crtFile);
|
||||
if (ssl->crt_file)
|
||||
free(ssl->crt_file);
|
||||
|
||||
free(self);
|
||||
free(ssl);
|
||||
}
|
||||
|
||||
|
||||
static crypter_t
|
||||
crypter_new( const char * server_name,
|
||||
const char * key_file,
|
||||
const char * crt_file )
|
||||
{
|
||||
crypter_t self;
|
||||
|
||||
if ( (self=calloc(1, sizeof(struct crypter))) != NULL )
|
||||
{
|
||||
if (!(self->srvName = str_copy( server_name ? server_name : "*" )))
|
||||
goto release;
|
||||
|
||||
if ( key_file && !(self->keyFile = str_copy(key_file)))
|
||||
goto release;
|
||||
|
||||
if ( crt_file && !(self->crtFile = str_copy(crt_file)))
|
||||
goto release;
|
||||
|
||||
}
|
||||
|
||||
goto finally;
|
||||
|
||||
|
||||
release:
|
||||
crypter_free(self);
|
||||
self = NULL;
|
||||
|
||||
finally:
|
||||
return self;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
15
src/ssl.h
15
src/ssl.h
|
@ -14,23 +14,26 @@
|
|||
#include <openssl/ssl.h>
|
||||
|
||||
|
||||
struct ssl
|
||||
struct aisl_ssl
|
||||
{
|
||||
char * key_file;
|
||||
char * crt_file;
|
||||
char * domain;
|
||||
char * host;
|
||||
SSL_CTX * ctx;
|
||||
};
|
||||
|
||||
typedef struct ssl * ssl_t;
|
||||
typedef struct aisl_ssl * aisl_ssl_t;
|
||||
|
||||
|
||||
ssl_t
|
||||
ssl_new( const char * key_file, const char * crt_file, const char * domain, SSL_CTX * ctx );
|
||||
aisl_ssl_t
|
||||
aisl_ssl_new( const char * key_file,
|
||||
const char * crt_file,
|
||||
const char * host,
|
||||
SSL_CTX * ctx );
|
||||
|
||||
|
||||
void
|
||||
ssl_free( ssl_t self );
|
||||
aisl_ssl_free( aisl_ssl_t ssl );
|
||||
|
||||
|
||||
#endif /* !AISL_SSL_H */
|
||||
|
|
259
src/stream.c
259
src/stream.c
|
@ -2,19 +2,25 @@
|
|||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "instance.h"
|
||||
#include "client.h"
|
||||
#include "server.h"
|
||||
#include "buffer.h"
|
||||
#include "str-utils.h"
|
||||
#include "stream.h"
|
||||
|
||||
#define FLAG_OUTPUT_READY (1<<0)
|
||||
#define FLAG_OUTPUT_CHUNKED (1<<1)
|
||||
|
||||
#define SIZE_NAN (~0)
|
||||
|
||||
struct aisl_stream
|
||||
{
|
||||
struct buffer buffer;
|
||||
aisl_client_t client;
|
||||
|
||||
struct buffer buffer;
|
||||
|
||||
const char *content_type;
|
||||
void * u_ptr;
|
||||
const char * content_type;
|
||||
|
||||
size_t content_length;
|
||||
int32_t content_offset;
|
||||
|
@ -23,221 +29,145 @@ struct aisl_stream
|
|||
|
||||
aisl_http_response_t response;
|
||||
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);
|
||||
free(stream);
|
||||
|
||||
static void
|
||||
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
|
||||
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));
|
||||
|
||||
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->c_length_unknown = true;
|
||||
stream->flags = 0;
|
||||
stream->id = id;
|
||||
stream->client = client;
|
||||
aisl_stream_reset(stream, true);
|
||||
}
|
||||
|
||||
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
|
||||
stream_free(aisl_stream_t stream)
|
||||
aisl_stream_free(aisl_stream_t stream)
|
||||
{
|
||||
if (stream->buffer) buffer_free(stream->buffer);
|
||||
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);
|
||||
aisl_stream_reset(stream, false);
|
||||
free(stream);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int
|
||||
stream_write(aisl_stream_t stream, const char * data, uint32_t d_len)
|
||||
/* Why it was here?
|
||||
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") ))
|
||||
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") ))
|
||||
void *
|
||||
aisl_get_context(aisl_aisl_stream_t s)
|
||||
aisl_get_context(aisl_stream_t s)
|
||||
{
|
||||
return s->u_ptr;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
__attribute__ ((visibility ("default") ))
|
||||
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;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
__attribute__ ((visibility ("default") ))
|
||||
aisl_client_t
|
||||
aisl_get_client(aisl_aisl_stream_t s)
|
||||
aisl_get_client(aisl_stream_t s)
|
||||
{
|
||||
return s->client;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
__attribute__ ((visibility ("default") ))
|
||||
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") ))
|
||||
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 cli->protocol;
|
||||
return aisl_client_get_http_version(s->client);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
__attribute__ ((visibility ("default") ))
|
||||
void
|
||||
aisl_reject(aisl_aisl_stream_t s)
|
||||
aisl_reject(aisl_stream_t s)
|
||||
{
|
||||
client_t cli = (client_t) s->client;
|
||||
|
||||
client_close( cli );
|
||||
aisl_client_close( s->client );
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
|
||||
static char *
|
||||
get_response_begin(aisl_stream_t stream)
|
||||
aisl_stream_get_response_begin(aisl_stream_t stream)
|
||||
{
|
||||
char * r;
|
||||
client_t cli = CLIENT(ASTREAM(stream)->client);
|
||||
|
||||
r = str_printf(
|
||||
"%s %d %s\r\n"
|
||||
"Server: AISL\r\n"
|
||||
"Connection: %s\r\n\r\n",
|
||||
aisl_http_version_to_string(cli->protocol),
|
||||
aisl_get_http_version(stream),
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
__attribute__ ((visibility ("default") ))
|
||||
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,
|
||||
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 */
|
||||
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(stream)->c_type = content_type;
|
||||
STREAM(stream)->c_length = content_length;
|
||||
stream->response = status_code;
|
||||
stream->content_type = content_type;
|
||||
stream->content_length = content_length;
|
||||
|
||||
if ( !(pch = get_response_begin(STREAM(stream))) )
|
||||
if ( !(pch = aisl_stream_get_response_begin(stream)) )
|
||||
return AISL_MALLOC_ERROR;
|
||||
|
||||
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);
|
||||
|
||||
if (l == BUFFER_EOB) return AISL_MALLOC_ERROR;
|
||||
if (l == -1) return AISL_MALLOC_ERROR;
|
||||
|
||||
if (content_length)
|
||||
{
|
||||
|
@ -277,7 +207,7 @@ aisl_response(aisl_aisl_stream_t stream, aisl_http_response_t status_code,
|
|||
return AISL_MALLOC_ERROR;
|
||||
}
|
||||
|
||||
STREAM(stream)->state = STREAM_RESPONSE_HEADER;
|
||||
stream->state = AISL_STREAM_STATE_SEND_HEADER;
|
||||
|
||||
return AISL_SUCCESS;
|
||||
}
|
||||
|
@ -285,24 +215,23 @@ aisl_response(aisl_aisl_stream_t stream, aisl_http_response_t status_code,
|
|||
|
||||
__attribute__ ((visibility ("default") ))
|
||||
aisl_status_t
|
||||
aisl_flush(aisl_aisl_stream_t stream)
|
||||
aisl_flush(aisl_stream_t s)
|
||||
{
|
||||
aisl_stream_t s = STREAM(stream);
|
||||
if ( ! s->c_length )
|
||||
if ( ! s->content_length )
|
||||
{
|
||||
s->c_length = s->buffer->size - s->c_offset - 2;
|
||||
if (!aisl_header_printf(stream, "Content-Length", "%u", s->c_length))
|
||||
s->content_length = s->buffer.size - s->content_offset - 2;
|
||||
if (!aisl_header_printf(s, "Content-Length", "%u", s->content_length))
|
||||
return AISL_MALLOC_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
fprintf(stdout, "(%lu bytes)------->\n", STREAM(stream)->buffer->size);
|
||||
fwrite(STREAM(stream)->buffer->data, 1, STREAM(stream)->buffer->size, stdout);
|
||||
fprintf(stdout, "(%lu bytes)------->\n", stream->buffer->size);
|
||||
fwrite(stream->buffer->data, 1, stream->buffer->size, stdout);
|
||||
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;
|
||||
}
|
||||
|
@ -310,7 +239,7 @@ aisl_flush(aisl_aisl_stream_t stream)
|
|||
|
||||
__attribute__ ((visibility ("default") ))
|
||||
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;
|
||||
char * pch;
|
||||
|
@ -319,16 +248,16 @@ aisl_header(aisl_aisl_stream_t stream, const char *key, const char *value)
|
|||
{
|
||||
ret = strlen(pch);
|
||||
if ( buffer_insert(
|
||||
STREAM(stream)->buffer,
|
||||
STREAM(stream)->c_offset,
|
||||
&stream->buffer,
|
||||
stream->content_offset,
|
||||
pch,
|
||||
ret
|
||||
) == BUFFER_EOB )
|
||||
) == -1 )
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
else
|
||||
STREAM(stream)->c_offset += ret;
|
||||
stream->content_offset += ret;
|
||||
|
||||
free(pch);
|
||||
}
|
||||
|
@ -341,7 +270,7 @@ aisl_header(aisl_aisl_stream_t stream, const char *key, const char *value)
|
|||
|
||||
__attribute__ ((visibility ("default") ))
|
||||
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, ...)
|
||||
{
|
||||
int ret;
|
||||
|
@ -359,7 +288,7 @@ aisl_header_printf(aisl_aisl_stream_t stream, const char *key,
|
|||
|
||||
__attribute__ ((visibility ("default") ))
|
||||
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,
|
||||
va_list args)
|
||||
{
|
||||
|
@ -380,7 +309,7 @@ aisl_header_vprintf(aisl_aisl_stream_t stream, const char *key,
|
|||
|
||||
__attribute__ ((visibility ("default") ))
|
||||
int
|
||||
aisl_printf(aisl_aisl_stream_t stream, const char *format, ...)
|
||||
aisl_printf(aisl_stream_t stream, const char *format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
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
|
||||
*
|
||||
* if (STREAM(stream)->c_length_unknown)
|
||||
STREAM(stream)->c_length += result;
|
||||
* if (stream->c_length_unknown)
|
||||
stream->c_length += result;
|
||||
*/
|
||||
|
||||
|
||||
|
@ -403,7 +332,7 @@ aisl_printf(aisl_aisl_stream_t stream, const char *format, ...)
|
|||
|
||||
__attribute__ ((visibility ("default") ))
|
||||
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;
|
||||
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)
|
||||
{
|
||||
result = strlen(r);
|
||||
if (buffer_add(STREAM(stream)->buffer, r, result) == BUFFER_EOB)
|
||||
if (buffer_add(&stream->buffer, r, result) == -1)
|
||||
result = -1;
|
||||
|
||||
free(r);
|
||||
|
@ -425,12 +354,12 @@ aisl_vprintf(aisl_aisl_stream_t stream, const char *format, va_list args)
|
|||
|
||||
__attribute__ ((visibility ("default") ))
|
||||
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)
|
||||
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;
|
||||
|
||||
return d_len;
|
||||
|
@ -439,7 +368,7 @@ aisl_write(aisl_aisl_stream_t stream, const char *data, int d_len)
|
|||
|
||||
__attribute__ ((visibility ("default") ))
|
||||
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));
|
||||
}
|
||||
|
|
|
@ -31,12 +31,6 @@ void
|
|||
aisl_stream_free(aisl_stream_t stream);
|
||||
|
||||
|
||||
/* to be removed ??
|
||||
* aisl_stream_t
|
||||
* aisl_stream_reset(aisl_stream_t stream);
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
aisl_stream_set_chunked_output(aisl_stream_t stream, bool value);
|
||||
|
||||
|
|
Loading…
Reference in New Issue