HomePort
url_parser_test.c
Go to the documentation of this file.
1 /*
2  * Copyright 2011 Aalborg University. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification, are
5  * permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice, this list of
8  * conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11  * of conditions and the following disclaimer in the documentation and/or other materials
12  * provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY Aalborg University ''AS IS'' AND ANY EXPRESS OR IMPLIED
15  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Aalborg University OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  * The views and conclusions contained in the software and documentation are those of the
25  * authors and should not be interpreted as representing official policies, either expressed
26  */
27 
28 #include "url_parser.c"
29 #include "unit_test.h"
30 #include <string.h>
31 
32 struct data {
33  char *protocol;
34  char *host;
35  char *port;
36  char *path;
37  int cur_path;
38  char *key;
40  char *value;
42  int errors;
43  char *url;
44 };
45 
46 void on_begin(void *data)
47 {
48  int _errors = 0;
49  struct data *dat = data;
50  ASSERT_EQUAL(dat->call_order, 0);
51  dat->call_order = dat->call_order | 1;
52  dat->errors += _errors;
53 }
54 
55 void on_protocol(void *data, const char* protocol, size_t length)
56 {
57  int _errors = 0;
58  struct data *dat = data;
59  ASSERT_EQUAL(dat->call_order, 1);
60  dat->call_order = dat->call_order | 2;
61  ASSERT_EQUAL(strncmp(protocol, dat->protocol, length), 0);
62  dat->errors += _errors;
63  strncat(dat->url, protocol, length);
64  strcat(dat->url, "://");
65 }
66 
67 void on_host(void *data, const char* host, size_t length)
68 {
69  int _errors = 0;
70  struct data *dat = data;
71  ASSERT_EQUAL((dat->call_order & 61), 1);
72  dat->call_order = dat->call_order | 4;
73  ASSERT_EQUAL(strncmp(host, dat->host, length), 0);
74  dat->errors += _errors;
75  strncat(dat->url, host, length);
76 }
77 
78 void on_port(void *data, const char* port, size_t length)
79 {
80  int _errors = 0;
81  struct data *dat = data;
82  ASSERT_EQUAL((dat->call_order & 61), 5);
83  dat->call_order = dat->call_order | 8;
84  ASSERT_EQUAL(strncmp(port, dat->port, length), 0);
85  dat->errors += _errors;
86  strcat(dat->url, ":");
87  strncat(dat->url, port, length);
88 }
89 
90 void on_path_segment(void *data, const char* seg, size_t length)
91 {
92  int i;
93  int _errors = 0;
94  struct data *dat = data;
95 
96  // Find expect
97  char *expect = dat->path;
98  ASSERT_EQUAL((dat->call_order & 33), 1);
99  dat->call_order = dat->call_order | 16;
100  for (i = 0; i < dat->cur_path; i++) {
101  expect = &expect[strlen(expect)+1];
102  }
103 
104  // Find got
105  char *got = malloc((length+1)*sizeof(char));
106  strncpy(got, seg, length);
107  got[length] = '\0';
108 
109  ASSERT_STR_EQUAL(got, expect);
110  dat->cur_path++;
111  dat->errors += _errors;
112  strcat(dat->url, "/");
113  strncat(dat->url, seg, length);
114 
115  free(got);
116 }
117 
118 void on_path_complete(void *data, const char* seg, size_t length)
119 {
120  int i;
121  int _errors = 0;
122  struct data *dat = data;
123 
124  // Check order
125  ASSERT_EQUAL((dat->call_order & 49), 17);
126 
127  // Construct expect
128  char *expect = malloc(sizeof(char));
129  expect[0] = '\0';
130  char *ptr = dat->path;
131  int len = 1;
132  for (i = 0; i < dat->cur_path; i++) {
133  len += strlen(ptr) + 1;
134  expect = realloc(expect, len*sizeof(char));
135  strcat(expect, "/");
136  strcat(expect, ptr);
137  ptr = &ptr[strlen(ptr)+1];
138  }
139 
140  // Construct got
141  char *got = malloc((length+1)*sizeof(char));
142  got[0] = '\0';
143  strncpy(got, seg, length);
144  got[length] = '\0';
145 
146  // Check path
147  ASSERT_STR_EQUAL(got, expect);
148 
149  // Clean up
150  free(got);
151  free(expect);
152  dat->errors += _errors;
153 }
154 
155 void on_key_value(void * data,
156  const char* key, size_t key_length,
157  const char* value, size_t value_length)
158 {
159  int i;
160  int _errors = 0;
161  struct data *dat = data;
162  char *expect_key = dat->key;
163  char *expect_val = dat->value;
164  ASSERT_EQUAL((dat->call_order & 17), 17);
165  dat->call_order = dat->call_order | 32;
166  for (i = 0; i < dat->cur_key_value; i++) {
167  expect_key = &expect_key[strlen(expect_key)+1];
168  expect_val = &expect_val[strlen(expect_val)+1];
169  }
170  ASSERT_EQUAL(strncmp(key, expect_key, key_length), 0);
171  ASSERT_EQUAL(strncmp(value, expect_val, value_length), 0);
172  dat->cur_key_value++;
173  dat->errors += _errors;
174  if (dat->cur_key_value == 1) strcat(dat->url, "?");
175  else strcat(dat->url, "&");
176  strncat(dat->url, key, key_length);
177  strcat(dat->url, "=");
178  strncat(dat->url, value, value_length);
179 }
180 
181 TEST_START("url_parser.c")
182 
191 
192 TEST(non chunked url parsing)
193 
194  char* url = "http://localhost:8080/device/tv?id=1&brand=Apple";
195 
196  struct data data;
197  data.protocol = "http";
198  data.host = "localhost";
199  data.port = "8080";
200  data.path = "device\0tv";
201  data.cur_path = 0;
202  data.key = "id\0brand";
203  data.cur_key_value = 0;
204  data.value = "1\0Apple";
205  data.call_order = 0;
206  data.errors = 0;
207  data.url = malloc((strlen(url)+1)*sizeof(char));
208  data.url[0] = '\0';
209 
210  struct up *instance = up_create(&settings, &data);
211 
212  up_add_chunk(instance, url, strlen(url));
213  up_complete(instance);
214  up_destroy(instance);
215 
216  ASSERT_STR_EQUAL(data.url, url);
217 
218  _errors += data.errors;
219 
220  free(data.url);
221 
222 TSET()
223 
224 TEST(non chunked url parsing with no port)
225 
226  char* url = "http://localhost/device/tv?id=1&brand=Apple";
227 
228  struct data data;
229  data.protocol = "http";
230  data.host = "localhost";
231  data.port = "";
232  data.path = "device\0tv";
233  data.cur_path = 0;
234  data.key = "id\0brand";
235  data.cur_key_value = 0;
236  data.value = "1\0Apple";
237  data.call_order = 0;
238  data.errors = 0;
239  data.url = malloc((strlen(url)+1)*sizeof(char));
240  data.url[0] = '\0';
241 
242  struct up *instance = up_create(&settings, &data);
243 
244  up_add_chunk(instance, url, strlen(url));
245  up_complete(instance);
246  up_destroy(instance);
247 
248  ASSERT_STR_EQUAL(data.url, url);
249 
250  _errors += data.errors;
251 
252  free(data.url);
253 
254 TSET()
255 
256 TEST(chunked url parsing)
257 
258  char* url = "http://localhost:8080/device/tv?id=1&brand=Apple";
259  char* url1 = "http://localhost:8080/device/";
260  char* url2 = "tv?id=1&brand=Apple";
261 
262  struct data data;
263  data.protocol = "http";
264  data.host = "localhost";
265  data.port = "8080";
266  data.path = "device\0tv";
267  data.cur_path = 0;
268  data.key = "id\0brand";
269  data.cur_key_value = 0;
270  data.value = "1\0Apple";
271  data.call_order = 0;
272  data.errors = 0;
273  data.url = malloc((strlen(url1)+strlen(url2)+1)*sizeof(char));
274  data.url[0] = '\0';
275 
276  struct up *instance = up_create(&settings, &data);
277 
278  up_add_chunk(instance, url1, strlen(url1));
279  up_add_chunk(instance, url2, strlen(url2));
280  up_complete(instance);
281  up_destroy(instance);
282 
283  ASSERT_STR_EQUAL(data.url, url);
284 
285  _errors += data.errors;
286 
287  free(data.url);
288 
289 TSET()
290 
291 TEST(empty path test)
292 
293  char *url = "http://localhost:8080";
294 
295  struct data data;
296  data.protocol = "http";
297  data.host = "localhost";
298  data.port = "8080";
299  data.path = "";
300  data.cur_path = 0;
301  data.key = "";
302  data.cur_key_value = 0;
303  data.value = "";
304  data.call_order = 0;
305  data.errors = 0;
306  data.url = malloc((strlen(url)+1)*sizeof(char));
307  data.url[0] = '\0';
308 
309  struct up *instance = up_create(&settings, &data);
310 
311  up_add_chunk(instance, url, strlen(url));
312  up_complete(instance);
313  up_destroy(instance);
314 
315  ASSERT_STR_EQUAL(data.url, url);
316 
317  _errors += data.errors;
318 
319  free(data.url);
320 
321 TSET()
322 
323 TEST(only host test)
324 
325  char *url = "http://localhost";
326 
327  struct data data;
328  data.protocol = "http";
329  data.host = "localhost";
330  data.port = "";
331  data.path = "";
332  data.cur_path = 0;
333  data.key = "";
334  data.cur_key_value = 0;
335  data.value = "";
336  data.call_order = 0;
337  data.errors = 0;
338  data.url = malloc((strlen(url)+1)*sizeof(char));
339  data.url[0] = '\0';
340 
341  struct up *instance = up_create(&settings, &data);
342 
343  up_add_chunk(instance, url, strlen(url));
344  up_complete(instance);
345  up_destroy(instance);
346 
347  ASSERT_STR_EQUAL(data.url, url);
348 
349  _errors += data.errors;
350 
351  free(data.url);
352 
353 TSET()
354 
355 TEST(path test)
356 
357  char *url = "/devices/";
358 
359  struct data data;
360  data.protocol = "";
361  data.host = "";
362  data.port = "";
363  data.path = "devices\0";
364  data.cur_path = 0;
365  data.key = "";
366  data.cur_key_value = 0;
367  data.value = "";
368  data.call_order = 0;
369  data.errors = 0;
370  data.url = malloc((strlen(url)+1)*sizeof(char));
371  data.url[0] = '\0';
372 
373  struct up *instance = up_create(&settings, &data);
374 
375  up_add_chunk(instance, url, strlen(url));
376  up_complete(instance);
377  up_destroy(instance);
378 
379  ASSERT_STR_EQUAL(data.url, url);
380 
381  _errors += data.errors;
382 
383  free(data.url);
384 
385 TSET()
386 
387 TEST(slash test)
388 
389  char url = '/';
390 
391  struct data data;
392  data.protocol = "";
393  data.host = "";
394  data.port = "";
395  data.path = "";
396  data.cur_path = 0;
397  data.key = "";
398  data.cur_key_value = 0;
399  data.value = "";
400  data.call_order = 0;
401  data.errors = 0;
402  data.url = malloc((1+1)*sizeof(char));
403  data.url[0] = '\0';
404 
405  struct up *instance = up_create(&settings, &data);
406 
407  up_add_chunk(instance, &url, 1);
408  up_complete(instance);
409  up_destroy(instance);
410 
411  ASSERT_STR_EQUAL(data.url, "/");
412 
413  _errors += data.errors;
414 
415  free(data.url);
416 
417 TSET()
418 
419 TEST_END()
_errors
char * url
data cur_path
struct up * instance
settings on_protocol
char * value
data errors
An URL Parser instance.
char * path
data path
char * url
free(data.url)
char * host
ASSERT_STR_EQUAL(data.url, url)
#define UP_SETTINGS_DEFAULT
TEST(CASE, sendf)
struct data data
data key
data protocol
up_complete(instance)
settings on_begin
settings on_path_segment
char * protocol
up_destroy(instance)
settings on_key_value
data value
int cur_key_value
data port
data host
settings on_path_complete
char * url2
char * port
ASSERT_EQUAL(data.count, 2)
settings on_port
data call_order
char * url1
int call_order
Settings struct for the URL Parser.
char * key
hpd_error_t up_create(struct up **instance, struct up_settings *settings, const hpd_module_t *context, void *data)
Create URL parser instance.
data cur_key_value
struct up_settings settings
settings on_host
up_add_chunk(instance, url, strlen(url))
int cur_path