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