Update configure to generate config.h
[yaz-moved-to-github.git] / test / test_comstack.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) 1995-2010 Index Data
3  * See the file LICENSE for details.
4  */
5 #if HAVE_CONFIG_H
6 #include <config.h>
7 #endif
8
9 #include <stdlib.h>
10 #include <string.h>
11 #include <stdio.h>
12
13 #include <yaz/test.h>
14 #include <yaz/comstack.h>
15 #include <yaz/tcpip.h>
16
17 static void tst_http_request(void)
18 {
19     {
20         /* no content, no headers */
21         const char *http_buf = 
22             /*123456789012345678 */
23             "GET / HTTP/1.1\r\n"
24             "\r\n"
25             "GET / HTTP/1.0\r\n";
26         
27         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 1), 0);
28         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 2), 0);
29         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 16), 0);
30         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 17), 0);
31         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 18), 18);
32         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 19), 18);
33     }
34     {
35         /* one header, no content */
36         const char *http_buf = 
37             /*123456789012345678 */
38             "GET / HTTP/1.1\r\n"
39             "Content-Type: x\r\n"
40             "\r\n"
41             "GET / HTTP/1.0\r\n";
42         
43         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 1), 0);
44         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 2), 0);
45         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 34), 0);
46         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 35), 35);
47         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 36), 35);
48     }        
49     {
50         /* one content-length header, length 0 */
51         const char *http_buf = 
52             /*123456789012345678 */
53             "GET / HTTP/1.1\r\n"
54             "Content-Length: 0\r\n"
55             "\r\n"
56             "GET / HTTP/1.0\r\n";
57         
58         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 1), 0);
59         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 2), 0);
60         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 35), 0);
61         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 37), 37);
62         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 38), 37);
63     }        
64     {
65         /* one content-length header, length 5 */
66         const char *http_buf = 
67             /*123456789012345678 */
68             "GET / HTTP/1.1\r\n"
69             "Content-Length: 5\r\n"
70             "\r\n"
71             "ABCDE"
72             "GET / HTTP/1.0\r\n";
73         
74         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 1), 0);
75         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 2), 0);
76         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 41), 0);
77         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 42), 42);
78         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 43), 42);
79     }        
80     {
81         /* LF only in GET, one content-length header, length 5 */
82         const char *http_buf = 
83             /*123456789012345678 */
84             "GET / HTTP/1.1\n"
85             "Content-Length: 5\r\n"
86             "\r\n"
87             "ABCDE"
88             "GET / HTTP/1.0\r\n";
89         
90         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 1), 0);
91         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 2), 0);
92         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 40), 0);
93         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 41), 41);
94         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 42), 41);
95     }        
96     {
97         /* LF only in all places, one content-length header, length 5 */
98         const char *http_buf = 
99             /*123456789012345678 */
100             "GET / HTTP/1.1\n"
101             "Content-Length: 5\n"
102             "\n"
103             "ABCDE"
104             "GET / HTTP/1.0\r\n";
105         
106         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 1), 0);
107         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 2), 0);
108         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 38), 0);
109         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 39), 39);
110         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 40), 39);
111     }        
112
113     {
114         /* one header, unknown transfer-encoding (no content) */
115         const char *http_buf = 
116             /*12345678901234567890123456789 */
117             "GET / HTTP/1.1\r\n"
118             "Transfer-Encoding: chunke_\r\n"
119             "\r\n"
120             "GET / HTTP/1.0\r\n";
121         
122         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 45), 0);
123         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 46), 46);
124     }        
125
126     {
127         /* one header, one chunk */
128         const char *http_buf = 
129             /*12345678901234567890123456789 */
130             "GET / HTTP/1.1\r\n"
131             "Transfer-Encoding: chunked\r\n"
132             "\r\n"
133             "3\r\n"
134             "123\r\n"
135             "0\r\n\r\n"
136             "GET / HTTP/1.0\r\n";
137         
138         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 58), 0);
139         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 59), 59);
140     }        
141
142     {
143         /* one header, two chunks */
144         const char *http_buf = 
145             /*12345678901234567890123456789 */
146             "GET / HTTP/1.1\r\n"
147             "Transfer-Encoding: chunked\r\n"
148             "\r\n"
149             "3\r\n"
150             "123\r\n"
151             "2\r\n"
152             "12\n"
153             "0\r\n\r\n"
154             "GET / HTTP/1.0\r\n";
155         
156         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 64), 0);
157         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 65), 65);
158     }        
159 }
160
161 static void tst_http_response(void)
162 {
163     {
164         /* unlimited content, no headers */
165         const char *http_buf = 
166             /*123456789012345678 */
167             "HTTP/1.1 200 OK\r\n"
168             "\r\n"
169             "HTTP/1.1 200 OK\r\n";
170         
171         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 1), 0);
172         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 2), 0);
173         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 24), 0);
174     }
175     {
176         /* response, content  */
177         const char *http_buf = 
178             /*123456789012345678 */
179             "HTTP/1.1 200 OK\r\n"
180             "Content-Length: 2\r\n"
181             "\r\n"
182             "12"
183             "HTTP/1.1 200 OK\r\n";
184         
185         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 1), 0);
186         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 2), 0);
187         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 39), 0);
188         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 40), 40);
189         YAZ_CHECK_EQ(cs_complete_auto(http_buf, 41), 40);
190     }
191 }
192
193 /** \brief COMSTACK synopsis from manual, doc/comstack.xml */
194 static int comstack_example(const char *server_address_str)
195 {    
196     COMSTACK stack;
197     char *buf = 0;
198     int size = 0, length_incoming;
199     void *server_address_ip;
200     int status;
201
202     char *protocol_package = "GET / HTTP/1.0\r\n\r\n";
203     int protocol_package_length = strlen(protocol_package);
204
205     stack = cs_create(tcpip_type, 1, PROTO_HTTP);
206     if (!stack) {
207         perror("cs_create");  /* use perror() here since we have no stack yet */
208         return -1;
209     }
210     
211     server_address_ip = cs_straddr(stack, server_address_str);
212     if (!server_address_ip)
213     {
214         fprintf(stderr, "cs_straddr: address could not be resolved\n");
215         return -1;
216     }
217     
218     status = cs_connect(stack, server_address_ip);
219     if (status != 0) {
220         fprintf(stderr, "cs_connect: %s\n", cs_strerror(stack));
221         return -1;
222     }
223     
224     status = cs_put(stack, protocol_package, protocol_package_length);
225     if (status) {
226         fprintf(stderr, "cs_put: %s\n", cs_strerror(stack));
227         return -1;
228     }
229     
230     /* Now get a response */
231     
232     length_incoming = cs_get(stack, &buf, &size);
233     if (!length_incoming) {
234         fprintf(stderr, "Connection closed\n");
235         return -1;
236     } else if (length_incoming < 0) {
237         fprintf(stderr, "cs_get: %s\n", cs_strerror(stack));
238         return -1;
239     }
240     
241     /* Print result */
242     fwrite(buf, length_incoming, 1, stdout);
243     
244     /* clean up */
245     cs_close(stack);
246     if (buf)
247         free(buf);
248     return 0;
249 }
250
251
252 int main (int argc, char **argv)
253 {
254     YAZ_CHECK_INIT(argc, argv);
255     YAZ_CHECK_LOG();
256     if (argc == 2)
257        comstack_example(argv[1]);
258     tst_http_request();
259     tst_http_response();
260     YAZ_CHECK_TERM;
261 }
262
263 /*
264  * Local variables:
265  * c-basic-offset: 4
266  * c-file-style: "Stroustrup"
267  * indent-tabs-mode: nil
268  * End:
269  * vim: shiftwidth=4 tabstop=8 expandtab
270  */
271