#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <cx/string.h>
#include <cx/utils.h>
#include <cx/printf.h>
#include "../util/pblock.h"
#include "../util/io.h"
#include "testutils.h"
Session* testutil_session(
void) {
pool_handle_t *pool = pool_create();
NSAPISession *sn = nsapisession_create(pool);
sn->connection = testutil_dummy_connection(pool);
return &sn->sn;
}
Request* testutil_request(
pool_handle_t *pool,
const char *method,
const char *uri) {
NSAPIRequest *rq = pool_malloc(pool,
sizeof(NSAPIRequest));
ZERO(rq,
sizeof(NSAPIRequest));
HTTPRequest httprequest;
ZERO(&httprequest,
sizeof(HTTPRequest));
request_initialize(pool, &httprequest, rq);
cxmutstr clf = cx_asprintf(
"%s %s HTTP/1.1", method, uri);
pblock_kvinsert(
pb_key_clf_request,
clf.ptr,
clf.length,
rq->rq.reqpb);
free(clf.ptr);
pblock_nvinsert(
"method",
method,
rq->rq.reqpb);
pblock_nvinsert(
"protocol",
"HTTP/1.1",
rq->rq.reqpb);
pblock_nvinsert(
"uri", uri, rq->rq.reqpb);
return &rq->rq;
}
static int dummyconn_read(Connection *conn,
void *buf,
int len) {
return len;
}
static int dummyconn_write(Connection *conn,
const void *buf,
int len) {
return len;
}
static void dummyconn_close(Connection *conn) {
}
Connection* testutil_dummy_connection(
pool_handle_t *pool) {
Connection *conn = pool_malloc(pool,
sizeof(Connection));
ZERO(conn,
sizeof(Connection));
conn->read = dummyconn_read;
conn->write = dummyconn_write;
conn->close = dummyconn_close;
return conn;
}
void testutil_request_body(Session *sn, Request *rq,
const char *body,
size_t len) {
cxmutstr cl = cx_asprintf(
"%d", (
int)len);
pblock_nvreplace(
"content-length", cl.ptr, rq->headers);
free(cl.ptr);
netbuf *inbuf = pool_malloc(sn->pool,
sizeof(netbuf));
inbuf->sd =
NULL;
inbuf->inbuf = pool_malloc(sn->pool, len);
inbuf->pos =
0;
inbuf->maxsize = len;
inbuf->cursize = len;
sn->inbuf = inbuf;
memcpy(inbuf->inbuf, body, len);
}
void testutil_destroy_session(Session *sn) {
pool_destroy(sn->pool);
}
static ssize_t test_io_write(IOStream *io,
const void *buf,
size_t size) {
TestIOStream *st = (TestIOStream*)io;
if(size > st->max_write) size = st->max_write;
return cxBufferWrite(buf,
1, size, st->buf);
}
static ssize_t test_io_writev(IOStream *io,
struct iovec *iovec,
int iovctn) {
TestIOStream *st = (TestIOStream*)io;
ssize_t wv =
0;
for(
int i=
0;i<iovctn;i++) {
ssize_t available = st->max_write - wv;
size_t len = iovec[i].iov_len;
if(len > available) {
len = available;
}
ssize_t w = test_io_write(io, iovec[i].iov_base, len);
if(w <=
0) {
break;
}
wv += w;
if(wv >= st->max_write) {
break;
}
}
return wv;
}
static ssize_t test_io_read(IOStream *io,
void *buf,
size_t size) {
return -
1;
}
static void test_io_close(IOStream *io) {
}
static void test_io_finish(IOStream *io) {
}
static void test_io_setmode(IOStream *io,
int mode) {
}
static int test_io_poll(IOStream *io, EventHandler *ev,
int events , Event *event) {
return 1;
}
TestIOStream* testutil_iostream(
size_t size,
int autoextend) {
TestIOStream *stream = calloc(
1,
sizeof(TestIOStream));
int flags =
0;
if(autoextend) {
flags =
CX_BUFFER_AUTO_EXTEND|
CX_BUFFER_FREE_CONTENTS;
}
stream->buf = malloc(
sizeof(CxBuffer));
stream->max_write =
INT_MAX;
cxBufferInit(stream->buf,
NULL, size, cxDefaultAllocator, flags);
stream->io.st.write = test_io_write;
stream->io.st.writev = test_io_writev;
stream->io.st.close = test_io_close;
stream->io.st.finish = test_io_finish;
stream->io.st.type =
IO_STREAM_TYPE_HTTP;
return stream;
}
void testutil_iostream_destroy(TestIOStream *stream) {
cxBufferDestroy(stream->buf);
free(stream->buf);
free(stream);
}