1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <limits.h>
32
33 #include <cx/string.h>
34 #include <cx/utils.h>
35 #include <cx/printf.h>
36
37 #include "../util/pblock.h"
38
39 #include "../util/io.h"
40
41 #include "testutils.h"
42
43 Session* testutil_session(
void) {
44 pool_handle_t *pool = pool_create();
45 NSAPISession *sn = nsapisession_create(pool);
46 sn->connection = testutil_dummy_connection(pool);
47
48 return &sn->sn;
49 }
50
51 Request* testutil_request(
pool_handle_t *pool,
const char *method,
const char *uri) {
52 NSAPIRequest *rq = pool_malloc(pool,
sizeof(NSAPIRequest));
53 ZERO(rq,
sizeof(NSAPIRequest));
54
55 HTTPRequest httprequest;
56 ZERO(&httprequest,
sizeof(HTTPRequest));
57 request_initialize(pool, &httprequest, rq);
58
59 cxmutstr clf = cx_asprintf(
"%s %s HTTP/1.1", method, uri);
60 pblock_kvinsert(
61 pb_key_clf_request,
62 clf.ptr,
63 clf.length,
64 rq->rq.reqpb);
65 free(clf.ptr);
66
67 pblock_nvinsert(
68 "method",
69 method,
70 rq->rq.reqpb);
71
72 pblock_nvinsert(
73 "protocol",
74 "HTTP/1.1",
75 rq->rq.reqpb);
76
77 pblock_nvinsert(
"uri", uri, rq->rq.reqpb);
78
79 return &rq->rq;
80 }
81
82 static int dummyconn_read(Connection *conn,
void *buf,
int len) {
83 return len;
84 }
85
86 static int dummyconn_write(Connection *conn,
const void *buf,
int len) {
87 return len;
88 }
89
90 static void dummyconn_close(Connection *conn) {
91
92 }
93
94
95 Connection* testutil_dummy_connection(
pool_handle_t *pool) {
96 Connection *conn = pool_malloc(pool,
sizeof(Connection));
97 ZERO(conn,
sizeof(Connection));
98 conn->read = dummyconn_read;
99 conn->write = dummyconn_write;
100 conn->close = dummyconn_close;
101 return conn;
102 }
103
104 void testutil_request_body(Session *sn, Request *rq,
const char *body,
size_t len) {
105 cxmutstr cl = cx_asprintf(
"%d", (
int)len);
106 pblock_nvreplace(
"content-length", cl.ptr, rq->headers);
107 free(cl.ptr);
108
109 netbuf *inbuf = pool_malloc(sn->pool,
sizeof(netbuf));
110 inbuf->sd =
NULL;
111 inbuf->inbuf = pool_malloc(sn->pool, len);
112 inbuf->pos =
0;
113 inbuf->maxsize = len;
114 inbuf->cursize = len;
115 sn->inbuf = inbuf;
116
117 memcpy(inbuf->inbuf, body, len);
118 }
119
120 void testutil_destroy_session(Session *sn) {
121 pool_destroy(sn->pool);
122 }
123
124
125 static ssize_t test_io_write(IOStream *io,
const void *buf,
size_t size) {
126 TestIOStream *st = (TestIOStream*)io;
127 if(size > st->max_write) size = st->max_write;
128 return cxBufferWrite(buf,
1, size, st->buf);
129 }
130
131 static ssize_t test_io_writev(IOStream *io,
struct iovec *iovec,
int iovctn) {
132 TestIOStream *st = (TestIOStream*)io;
133 ssize_t wv =
0;
134 for(
int i=
0;i<iovctn;i++) {
135 ssize_t available = st->max_write - wv;
136 size_t len = iovec[i].iov_len;
137 if(len > available) {
138 len = available;
139 }
140
141 ssize_t w = test_io_write(io, iovec[i].iov_base, len);
142 if(w <=
0) {
143 break;
144 }
145 wv += w;
146 if(wv >= st->max_write) {
147 break;
148 }
149 }
150 return wv;
151 }
152
153 static ssize_t test_io_read(IOStream *io,
void *buf,
size_t size) {
154 return -
1;
155 }
156
157 static void test_io_close(IOStream *io) {
158
159 }
160
161 static void test_io_finish(IOStream *io) {
162
163 }
164
165 static void test_io_setmode(IOStream *io,
int mode) {
166
167 }
168
169 static int test_io_poll(IOStream *io, EventHandler *ev,
int events , Event *event) {
170 return 1;
171 }
172
173 TestIOStream* testutil_iostream(
size_t size,
int autoextend) {
174 TestIOStream *stream = calloc(
1,
sizeof(TestIOStream));
175 int flags =
0;
176 if(autoextend) {
177 flags =
CX_BUFFER_AUTO_EXTEND|
CX_BUFFER_FREE_CONTENTS;
178 }
179 stream->buf = malloc(
sizeof(CxBuffer));
180 stream->max_write =
INT_MAX;
181 cxBufferInit(stream->buf,
NULL, size, cxDefaultAllocator, flags);
182
183 stream->io.st.write = test_io_write;
184 stream->io.st.writev = test_io_writev;
185 stream->io.st.close = test_io_close;
186 stream->io.st.finish = test_io_finish;
187 stream->io.st.type =
IO_STREAM_TYPE_HTTP;
188
189 return stream;
190 }
191
192 void testutil_iostream_destroy(TestIOStream *stream) {
193 cxBufferDestroy(stream->buf);
194 free(stream->buf);
195 free(stream);
196 }
197