1/*
2   Utility functions for HTTP client tests
3   Copyright (C) 2001-2008, Joe Orton <joe@manyfish.co.uk>
4
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 2 of the License, or
8   (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14
15   You should have received a copy of the GNU General Public License
16   along with this program; if not, write to the Free Software
17   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19*/
20
21#include "config.h"
22
23#ifdef HAVE_UNISTD_H
24#include <unistd.h> /* for sleep() */
25#endif
26#ifdef HAVE_STDLIB_H
27#include <stdlib.h>
28#endif
29
30#include "ne_session.h"
31
32#include "child.h"
33#include "tests.h"
34#include "utils.h"
35
36int make_session(ne_session **sess, server_fn fn, void *ud)
37{
38    *sess = ne_session_create("http", "localhost", 7777);
39    return spawn_server(7777, fn, ud);
40}
41
42static int serve_response(ne_socket *s, const char *response)
43{
44    CALL(discard_request(s));
45    CALL(discard_body(s));
46    ONN("failed to send response", SEND_STRING(s, response));
47    return OK;
48}
49
50int single_serve_string(ne_socket *s, void *userdata)
51{
52    const char *str = userdata;
53    return serve_response(s, str);
54}
55
56int double_serve_sstring(ne_socket *s, void *userdata)
57{
58    struct double_serve_args *args = userdata;
59    struct string *str;
60
61    CALL(discard_request(s));
62    CALL(discard_body(s));
63
64    str = &args->first;
65    NE_DEBUG(NE_DBG_SOCKET, "Serving string: [[[%.*s]]]\n",
66	     (int)str->len, str->data);
67    ONN("write failed", ne_sock_fullwrite(s, str->data, str->len));
68
69    CALL(discard_request(s));
70    CALL(discard_body(s));
71
72    str = &args->second;
73    NE_DEBUG(NE_DBG_SOCKET, "Serving string: [[[%.*s]]]\n",
74	     (int)str->len, str->data);
75    ONN("write failed", ne_sock_fullwrite(s, str->data, str->len));
76
77    return OK;
78}
79
80int sleepy_server(ne_socket *sock, void *userdata)
81{
82    sleep(10);
83    return 0;
84}
85
86int many_serve_string(ne_socket *s, void *userdata)
87{
88    int n;
89    struct many_serve_args *args = userdata;
90
91    for (n = 0; n < args->count; n++) {
92	NE_DEBUG(NE_DBG_HTTP, "Serving response %d\n", n);
93	CALL(serve_response(s, args->str));
94    }
95
96    return OK;
97}
98
99int any_request(ne_session *sess, const char *uri)
100{
101    ne_request *req = ne_request_create(sess, "GET", uri);
102    int ret = ne_request_dispatch(req);
103    ne_request_destroy(req);
104    return ret;
105}
106
107int any_2xx_request(ne_session *sess, const char *uri)
108{
109    ne_request *req = ne_request_create(sess, "GET", uri);
110    int ret = ne_request_dispatch(req);
111    int klass = ne_get_status(req)->klass;
112    ne_request_destroy(req);
113    ONV(ret != NE_OK || klass != 2,
114	("request failed: %s", ne_get_error(sess)));
115    return ret;
116}
117
118int any_2xx_request_body(ne_session *sess, const char *uri)
119{
120    ne_request *req = ne_request_create(sess, "GET", uri);
121#define BSIZE 5000
122    char *body = memset(ne_malloc(BSIZE), 'A', BSIZE);
123    int ret;
124    ne_set_request_body_buffer(req, body, BSIZE);
125    ret = ne_request_dispatch(req);
126    ne_free(body);
127    ONV(ret != NE_OK || ne_get_status(req)->klass != 2,
128	("request failed: %s", ne_get_error(sess)));
129    ne_request_destroy(req);
130    return ret;
131}
132
133int serve_sstring(ne_socket *sock, void *ud)
134{
135    struct string *str = ud;
136
137    NE_DEBUG(NE_DBG_SOCKET, "Serving string: [[[%.*s]]]\n",
138	     (int)str->len, str->data);
139
140    ONN("write failed", ne_sock_fullwrite(sock, str->data, str->len));
141
142    return 0;
143}
144
145int serve_sstring_slowly(ne_socket *sock, void *ud)
146{
147    struct string *str = ud;
148    size_t n;
149
150    NE_DEBUG(NE_DBG_SOCKET, "Slowly serving string: [[[%.*s]]]\n",
151	     (int)str->len, str->data);
152
153    for (n = 0; n < str->len; n++) {
154	ONN("write failed", ne_sock_fullwrite(sock, &str->data[n], 1));
155	minisleep();
156    }
157
158    return 0;
159}
160
161int serve_infinite(ne_socket *sock, void *ud)
162{
163    struct infinite *i = ud;
164
165    CALL(discard_request(sock));
166
167    SEND_STRING(sock, i->header);
168
169    while (server_send(sock, i->repeat, strlen(i->repeat)) == 0)
170        /* nullop */;
171
172    return OK;
173}
174
175int full_write(ne_socket *sock, const char *data, size_t len)
176{
177    int ret = ne_sock_fullwrite(sock, data, len);
178    NE_DEBUG(NE_DBG_SOCKET, "wrote: [%.*s]\n", (int)len, data);
179    ONV(ret, ("write failed (%d): %s", ret, ne_sock_error(sock)));
180    return OK;
181}
182
183