iPXE
uri_test.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 /** @file
27  *
28  * URI self-tests
29  *
30  */
31 
32 /* Forcibly enable assertions */
33 #undef NDEBUG
34 
35 #include <string.h>
36 #include <byteswap.h>
37 #include <ipxe/uri.h>
38 #include <ipxe/tcpip.h>
39 #include <ipxe/params.h>
40 #include <ipxe/test.h>
41 
42 /** A URI parsing/formatting test */
43 struct uri_test {
44  /** URI string */
45  const char *string;
46  /** URI */
47  struct uri uri;
48 };
49 
50 /** A URI port number test */
51 struct uri_port_test {
52  /** URI string */
53  const char *string;
54  /** Default port number */
55  unsigned int default_port;
56  /** Expected port number */
57  unsigned int port;
58 };
59 
60 /** A URI or path resolution test */
62  /** Base path or URI */
63  const char *base;
64  /** Relative path or URI */
65  const char *relative;
66  /** Expected resolved path or URI */
67  const char *resolved;
68 };
69 
70 /** A PXE URI test */
71 struct uri_pxe_test {
72  /** Server address */
73  union {
74  struct sockaddr sa;
75  struct sockaddr_in sin;
78  } server;
79  /** Filename */
80  const char *filename;
81  /** URI */
82  struct uri uri;
83  /** URI string (for display only; cannot be reparsed) */
84  const char *string;
85 };
86 
87 /** A current working URI test */
89  /** Relative URI */
90  const char *relative;
91  /** Expected new working URI */
92  const char *expected;
93 };
94 
95 /** A form parameter URI test list */
97  /** Key */
98  const char *key;
99  /** Value */
100  const char *value;
101 };
102 
103 /** A form parameter URI test */
105  /** URI string */
106  const char *string;
107  /** URI */
108  struct uri uri;
109  /** Parameter list name */
110  const char *name;
111  /** Parameter list */
113 };
114 
115 /**
116  * Compare two URI component strings
117  *
118  * @v first First string, or NULL
119  * @v second Second string, or NULL
120  * @v difference Difference
121  */
122 static int uristrcmp ( const char *first, const char *second ) {
123 
124  /* Compare strings, allowing for either to be NULL */
125  if ( first == second ) {
126  return 0;
127  } else if ( ( first == NULL ) || ( second == NULL ) ) {
128  return -1;
129  } else {
130  return strcmp ( first, second );
131  }
132 }
133 
134 /**
135  * Report URI equality test result
136  *
137  * @v uri URI
138  * @v expected Expected URI
139  * @v file Test code file
140  * @v line Test code line
141  */
142 static void uri_okx ( struct uri *uri, struct uri *expected, const char *file,
143  unsigned int line ) {
144 
145  okx ( uristrcmp ( uri->scheme, expected->scheme ) == 0, file, line );
146  okx ( uristrcmp ( uri->opaque, expected->opaque ) == 0, file, line );
147  okx ( uristrcmp ( uri->user, expected->user ) == 0, file, line );
148  okx ( uristrcmp ( uri->password, expected->password ) == 0, file, line);
149  okx ( uristrcmp ( uri->host, expected->host ) == 0, file, line );
150  okx ( uristrcmp ( uri->port, expected->port ) == 0, file, line );
151  okx ( uristrcmp ( uri->path, expected->path ) == 0, file, line );
152  okx ( uristrcmp ( uri->query, expected->query ) == 0, file, line );
153  okx ( uristrcmp ( uri->fragment, expected->fragment ) == 0, file, line);
154  okx ( uri->params == expected->params, file, line );
155 }
156 #define uri_ok( uri, expected ) uri_okx ( uri, expected, __FILE__, __LINE__ )
157 
158 /**
159  * Report URI parsing test result
160  *
161  * @v test URI test
162  * @v file Test code file
163  * @v line Test code line
164  */
165 static void uri_parse_okx ( struct uri_test *test, const char *file,
166  unsigned int line ) {
167  struct uri *uri;
168 
169  /* Parse URI */
170  uri = parse_uri ( test->string );
171  okx ( uri != NULL, file, line );
172  if ( uri )
173  uri_okx ( uri, &test->uri, file, line );
174  uri_put ( uri );
175 }
176 #define uri_parse_ok( test ) uri_parse_okx ( test, __FILE__, __LINE__ )
177 
178 /**
179  * Report URI formatting test result
180  *
181  * @v test URI test
182  * @v file Test code file
183  * @v line Test code line
184  */
185 static void uri_format_okx ( struct uri_test *test, const char *file,
186  unsigned int line ) {
187  char buf[ strlen ( test->string ) + 1 /* NUL */ ];
188  char *tmp;
189  size_t len;
190 
191  /* Format into fixed-size buffer */
192  len = format_uri ( &test->uri, buf, sizeof ( buf ) );
193  okx ( len == ( sizeof ( buf ) - 1 /* NUL */ ), file, line );
194  okx ( strcmp ( buf, test->string ) == 0, file, line );
195 
196  /* Format into temporarily allocated buffer */
197  tmp = format_uri_alloc ( &test->uri );
198  okx ( tmp != NULL, file, line );
199  if ( tmp )
200  okx ( strcmp ( tmp, test->string ) == 0, file, line );
201  free ( tmp );
202 }
203 #define uri_format_ok( test ) uri_format_okx ( test, __FILE__, __LINE__ )
204 
205 /**
206  * Report URI duplication test result
207  *
208  * @v test URI
209  * @v file Test code file
210  * @v line Test code line
211  */
212 static void uri_dup_okx ( struct uri *uri, const char *file,
213  unsigned int line ) {
214  struct uri *dup;
215 
216  dup = uri_dup ( uri );
217  okx ( dup != NULL, file, line );
218  if ( dup )
219  uri_okx ( dup, uri, file, line );
220  uri_put ( dup );
221 }
222 #define uri_dup_ok( test ) uri_dup_okx ( test, __FILE__, __LINE__ )
223 
224 /**
225  * Report URI combined parsing and formatting test result
226  *
227  * @v test URI test
228  * @v file Test code file
229  * @v line Test code line
230  */
231 static void uri_parse_format_dup_okx ( struct uri_test *test, const char *file,
232  unsigned int line ) {
233 
234  uri_parse_okx ( test, file, line );
235  uri_format_okx ( test, file, line );
236  uri_dup_okx ( &test->uri, file, line );
237 }
238 #define uri_parse_format_dup_ok( test ) \
239  uri_parse_format_dup_okx ( test, __FILE__, __LINE__ )
240 
241 /**
242  * Report URI port number test result
243  *
244  * @v test URI port number test
245  * @v file Test code file
246  * @v line Test code line
247  */
248 static void uri_port_okx ( struct uri_port_test *test, const char *file,
249  unsigned int line ) {
250  struct uri *uri;
251  unsigned int port;
252 
253  /* Parse URI */
254  uri = parse_uri ( test->string );
255  okx ( uri != NULL, file, line );
256  if ( uri ) {
257  port = uri_port ( uri, test->default_port );
258  okx ( port == test->port, file, line );
259  }
260  uri_put ( uri );
261 }
262 #define uri_port_ok( test ) uri_port_okx ( test, __FILE__, __LINE__ )
263 
264 /**
265  * Report URI resolution test result
266  *
267  * @v test Path resolution test
268  * @v file Test code file
269  * @v line Test code line
270  */
271 static void uri_resolve_okx ( struct uri_resolve_test *test,
272  const char *file, unsigned int line ) {
273  struct uri *base;
274  struct uri *relative;
275  struct uri *resolved = NULL;
276  char *formatted;
277 
278  /* Parse URIs */
279  base = parse_uri ( test->base );
280  okx ( base != NULL, file, line );
281  relative = parse_uri ( test->relative );
282  okx ( relative != NULL, file, line );
283 
284  /* Resolve URI */
285  if ( base && relative ) {
286  resolved = resolve_uri ( base, relative );
287  okx ( resolved != NULL, file, line );
288  }
289 
290  /* Format resolved URI */
291  formatted = format_uri_alloc ( resolved );
292  okx ( formatted != NULL, file, line );
293 
294  /* Check resolved URI */
295  if ( formatted )
296  okx ( strcmp ( formatted, test->resolved ) == 0, file, line );
297 
298  free ( formatted );
299  uri_put ( resolved );
300  uri_put ( relative );
301  uri_put ( base );
302 }
303 #define uri_resolve_ok( test ) uri_resolve_okx ( test, __FILE__, __LINE__ )
304 
305 /**
306  * Report path resolution test result
307  *
308  * @v test Path resolution test
309  * @v file Test code file
310  * @v line Test code line
311  */
313  const char *file, unsigned int line ) {
314  char *resolved;
315 
316  /* Resolve paths using resolve_path() directly */
317  resolved = resolve_path ( test->base, test->relative );
318  okx ( resolved != NULL, file, line );
319  if ( resolved )
320  okx ( strcmp ( resolved, test->resolved ) == 0, file, line );
321  free ( resolved );
322 
323  /* Resolve paths as URIs (since all paths are valid URIs) */
324  uri_resolve_okx ( test, file, line );
325 }
326 #define uri_resolve_path_ok( test ) \
327  uri_resolve_path_okx ( test, __FILE__, __LINE__ )
328 
329 /**
330  * Report URI PXE test result
331  *
332  * @v test URI PXE test
333  * @v file Test code file
334  * @v line Test code line
335  */
336 static void uri_pxe_okx ( struct uri_pxe_test *test, const char *file,
337  unsigned int line ) {
338  char buf[ strlen ( test->string ) + 1 /* NUL */ ];
339  struct uri *uri;
340  size_t len;
341 
342  /* Construct URI */
343  uri = pxe_uri ( &test->server.sa, test->filename );
344  okx ( uri != NULL, file, line );
345  if ( uri ) {
346  uri_okx ( uri, &test->uri, file, line );
347  len = format_uri ( uri, buf, sizeof ( buf ) );
348  okx ( len == ( sizeof ( buf ) - 1 /* NUL */ ), file, line );
349  okx ( strcmp ( buf, test->string ) == 0, file, line );
350  }
351  uri_put ( uri );
352 }
353 #define uri_pxe_ok( test ) uri_pxe_okx ( test, __FILE__, __LINE__ )
354 
355 /**
356  * Report current working URI test result
357  *
358  * @v tests List of current working URI tests
359  * @v file Test code file
360  * @v line Test code line
361  */
362 static void uri_churi_okx ( struct uri_churi_test *test, const char *file,
363  unsigned int line ) {
364  struct uri *old_cwuri;
365  struct uri *uri;
366  char *formatted;
367 
368  /* Preserve original current working URI */
369  old_cwuri = uri_get ( cwuri );
370 
371  /* Perform sequence of current working URI changes */
372  do {
373  /* Parse relative URI */
374  uri = parse_uri ( test->relative );
375  okx ( uri != NULL, file, line );
376 
377  /* Move to this URI */
378  churi ( uri );
379 
380  /* Format new current working URI */
382  okx ( formatted != NULL, file, line );
383  if ( formatted ) {
384  okx ( strcmp ( formatted, test->expected ) == 0,
385  file, line );
386  }
387 
388  /* Free temporary storage */
389  free ( formatted );
390  uri_put ( uri );
391 
392  /* Move to next current working URI test */
393  test++;
394 
395  } while ( test->relative != NULL );
396 
397  /* Restore original current working URI */
398  churi ( old_cwuri );
399  uri_put ( old_cwuri );
400 }
401 #define uri_churi_ok( test ) uri_churi_okx ( test, __FILE__, __LINE__ )
402 
403 /**
404  * Report form parameter URI test list result
405  *
406  * @v test Form parameter URI test
407  * @v uri URI
408  * @v file Test code file
409  * @v line Test code line
410  */
412  struct uri *uri, const char *file,
413  unsigned int line ) {
414  struct uri_params_test_list *list;
415  struct parameter *param;
416 
417  /* Check URI */
418  uri_okx ( uri, &test->uri, file, line );
419 
420  /* Check URI parameters */
421  okx ( uri->params != NULL, file, line );
422  if ( uri->params ) {
423  list = test->list;
425  okx ( strcmp ( param->key, list->key ) == 0,
426  file, line );
427  okx ( strcmp ( param->value, list->value ) == 0,
428  file, line );
429  list++;
430  }
431  okx ( list->key == NULL, file, line );
432  }
433 }
434 #define uri_params_list_ok( test ) \
435  uri_params_list_okx ( test, __FILE__, __LINE__ )
436 
437 /**
438  * Report form parameter URI test result
439  *
440  * @v test Form parameter URI test
441  * @v file Test code file
442  * @v line Test code line
443  */
444 static void uri_params_okx ( struct uri_params_test *test, const char *file,
445  unsigned int line ) {
446  struct uri_params_test_list *list;
447  struct parameters *params;
448  struct parameter *param;
449  struct uri *uri;
450  struct uri *dup;
451 
452  /* Create parameter list */
453  params = create_parameters ( test->name );
454  okx ( params != NULL, file, line );
455  if ( params ) {
456  for ( list = test->list ; list->key ; list++ ) {
457  param = add_parameter ( params, list->key, list->value);
458  okx ( param != NULL, file, line );
459  }
460  }
461 
462  /* Record parameter list as part of expected URI */
463  test->uri.params = params;
464 
465  /* Parse URI */
466  uri = parse_uri ( test->string );
467  okx ( uri != NULL, file, line );
468  if ( uri )
469  uri_params_list_okx ( test, uri, file, line );
470 
471  /* Duplicate URI */
472  dup = uri_dup ( uri );
473  okx ( dup != NULL, file, line );
474  if ( dup )
475  uri_params_list_okx ( test, dup, file, line );
476 
477  /* Clear parameter list in expected URI */
478  test->uri.params = NULL;
479 
480  uri_put ( uri );
481  uri_put ( dup );
482 }
483 #define uri_params_ok( test ) uri_params_okx ( test, __FILE__, __LINE__ )
484 
485 /** Empty URI */
486 static struct uri_test uri_empty = {
487  .string = "",
488 };
489 
490 /** Basic HTTP URI */
491 static struct uri_test uri_boot_ipxe_org = {
492  "http://boot.ipxe.org/demo/boot.php",
493  { .scheme = "http", .host = "boot.ipxe.org", .path = "/demo/boot.php" }
494 };
495 
496 /** Basic opaque URI */
497 static struct uri_test uri_mailto = {
498  "mailto:ipxe-devel@lists.ipxe.org",
499  { .scheme = "mailto", .opaque = "ipxe-devel@lists.ipxe.org" }
500 };
501 
502 /** Basic path-only URI */
503 static struct uri_test uri_path = {
504  "/var/lib/tftpboot/pxelinux.0",
505  { .path = "/var/lib/tftpboot/pxelinux.0" },
506 };
507 
508 /** Path-only URI with escaped characters */
509 static struct uri_test uri_path_escaped = {
510  "/hello%20world%3F",
511  { .path = "/hello world?" },
512 };
513 
514 /** HTTP URI with all the trimmings */
515 static struct uri_test uri_http_all = {
516  "http://anon:password@example.com:3001/~foo/cgi-bin/foo.pl?a=b&c=d#bit",
517  {
518  .scheme = "http",
519  .user = "anon",
520  .password = "password",
521  .host = "example.com",
522  .port = "3001",
523  .path = "/~foo/cgi-bin/foo.pl",
524  .query = "a=b&c=d",
525  .fragment = "bit",
526  },
527 };
528 
529 /** HTTP URI with escaped characters */
530 static struct uri_test uri_http_escaped = {
531  "https://test.ipxe.org/wtf%3F%0A?kind%23of/uri%20is#this%3F",
532  {
533  .scheme = "https",
534  .host = "test.ipxe.org",
535  .path = "/wtf?\n",
536  .query = "kind#of/uri is",
537  .fragment = "this?",
538  },
539 };
540 
541 /** HTTP URI with improperly escaped characters */
543  /* We accept for parsing improperly escaped characters.
544  * (Formatting the parsed URI would produce the properly
545  * encoded form, and so would not exactly match the original
546  * URI string.)
547  */
548  "https://test%2eipxe.org/wt%66%3f\n?kind%23of/uri is#this?",
549  {
550  .scheme = "https",
551  .host = "test.ipxe.org",
552  .path = "/wtf?\n",
553  .query = "kind#of/uri is",
554  .fragment = "this?",
555  },
556 };
557 
558 /** IPv6 URI */
559 static struct uri_test uri_ipv6 = {
560  "http://[2001:ba8:0:1d4::6950:5845]/",
561  {
562  .scheme = "http",
563  .host = "[2001:ba8:0:1d4::6950:5845]",
564  .path = "/",
565  },
566 };
567 
568 /** IPv6 URI with port */
569 static struct uri_test uri_ipv6_port = {
570  "http://[2001:ba8:0:1d4::6950:5845]:8001/boot",
571  {
572  .scheme = "http",
573  .host = "[2001:ba8:0:1d4::6950:5845]",
574  .port = "8001",
575  .path = "/boot",
576  },
577 };
578 
579 /** IPv6 URI with link-local address */
580 static struct uri_test uri_ipv6_local = {
581  "http://[fe80::69ff:fe50:5845%25net0]/ipxe",
582  {
583  .scheme = "http",
584  .host = "[fe80::69ff:fe50:5845%net0]",
585  .path = "/ipxe",
586  },
587 };
588 
589 /** IPv6 URI with link-local address not conforming to RFC 6874 */
591  /* We accept for parsing a single "%" in "%net0" (rather than
592  * the properly encoded form "%25net0"). (Formatting the
593  * parsed URI would produce the properly encoded form, and so
594  * would not exactly match the original URI string.)
595  */
596  "http://[fe80::69ff:fe50:5845%net0]/ipxe",
597  {
598  .scheme = "http",
599  .host = "[fe80::69ff:fe50:5845%net0]",
600  .path = "/ipxe",
601  },
602 };
603 
604 /** iSCSI URI */
605 static struct uri_test uri_iscsi = {
606  "iscsi:10.253.253.1::::iqn.2010-04.org.ipxe:rabbit",
607  {
608  .scheme = "iscsi",
609  .opaque = "10.253.253.1::::iqn.2010-04.org.ipxe:rabbit",
610  },
611 };
612 
613 /** File URI with relative (opaque) path */
614 static struct uri_test uri_file_relative = {
615  "file:boot/script.ipxe",
616  {
617  .scheme = "file",
618  .opaque = "boot/script.ipxe",
619  },
620 };
621 
622 /** File URI with absolute path */
623 static struct uri_test uri_file_absolute = {
624  "file:/boot/script.ipxe",
625  {
626  .scheme = "file",
627  .path = "/boot/script.ipxe",
628  },
629 };
630 
631 /** File URI with volume name */
632 static struct uri_test uri_file_volume = {
633  "file://hpilo/boot/script.ipxe",
634  {
635  .scheme = "file",
636  .host = "hpilo",
637  .path = "/boot/script.ipxe",
638  },
639 };
640 
641 /** URI with port number */
643  "http://192.168.0.1:8080/boot.php",
644  80,
645  8080,
646 };
647 
648 /** URI without port number */
650  "http://192.168.0.1/boot.php",
651  80,
652  80,
653 };
654 
655 /** Simple path resolution test */
657  "/etc/passwd",
658  "group",
659  "/etc/group",
660 };
661 
662 /** Path resolution test with "." and ".." elements */
664  "/var/lib/tftpboot/pxe/pxelinux.0",
665  "./../ipxe/undionly.kpxe",
666  "/var/lib/tftpboot/ipxe/undionly.kpxe",
667 };
668 
669 /** Path resolution test terminating with directory */
671  "/test/cgi-bin.pl/boot.ipxe",
672  "..",
673  "/test/",
674 };
675 
676 /** Path resolution test with excessive ".." elements */
678  "/var/lib/tftpboot/ipxe.pxe",
679  "../../../../../../../foo",
680  "/foo",
681 };
682 
683 /** Path resolution test with absolute path */
685  "/var/lib/tftpboot",
686  "/etc/hostname",
687  "/etc/hostname",
688 };
689 
690 /** Relative URI resolution test */
692  "http://boot.ipxe.org/demo/boot.php?vendor=10ec&device=8139",
693  "initrd.img",
694  "http://boot.ipxe.org/demo/initrd.img",
695 };
696 
697 /** Absolute URI resolution test */
699  "http://boot.ipxe.org/demo/boot.php",
700  "ftp://192.168.0.1/boot.ipxe",
701  "ftp://192.168.0.1/boot.ipxe",
702 };
703 
704 /** Absolute path URI resolution test */
706  "http://boot.ipxe.org/demo/boot.php#test",
707  "/demo/vmlinuz",
708  "http://boot.ipxe.org/demo/vmlinuz",
709 };
710 
711 /** Query URI resolution test */
712 static struct uri_resolve_test uri_query = {
713  "http://10.253.253.1/test.pl?mac=02-00-69-50-58-45",
714  "?mac=00-1f-16-bc-fe-2f",
715  "http://10.253.253.1/test.pl?mac=00-1f-16-bc-fe-2f",
716 };
717 
718 /** Fragment URI resolution test */
720  "http://192.168.0.254/test#foo",
721  "#bar",
722  "http://192.168.0.254/test#bar",
723 };
724 
725 /** PXE URI with absolute URI */
727  {
728  /* 192.168.0.3 */
729  .sin = {
730  .sin_family = AF_INET,
731  .sin_addr = { .s_addr = htonl ( 0xc0a80003 ) },
732  },
733  },
734  "http://not.a.tftp/uri",
735  {
736  .scheme = "http",
737  .host = "not.a.tftp",
738  .path = "/uri",
739  },
740  "http://not.a.tftp/uri",
741 };
742 
743 /** PXE URI with absolute path */
745  {
746  /* 192.168.0.2 */
747  .sin = {
748  .sin_family = AF_INET,
749  .sin_addr = { .s_addr = htonl ( 0xc0a80002 ) },
750  },
751  },
752  "/absolute/path",
753  {
754  .scheme = "tftp",
755  .host = "192.168.0.2",
756  .path = "//absolute/path",
757  },
758  "tftp://192.168.0.2//absolute/path",
759 };
760 
761 /** PXE URI with relative path */
763  {
764  /* 192.168.0.3 */
765  .sin = {
766  .sin_family = AF_INET,
767  .sin_addr = { .s_addr = htonl ( 0xc0a80003 ) },
768  },
769  },
770  "relative/path",
771  {
772  .scheme = "tftp",
773  .host = "192.168.0.3",
774  .path = "/relative/path",
775  },
776  "tftp://192.168.0.3/relative/path",
777 };
778 
779 /** PXE URI with path containing special characters */
780 static struct uri_pxe_test uri_pxe_icky = {
781  {
782  /* 10.0.0.6 */
783  .sin = {
784  .sin_family = AF_INET,
785  .sin_addr = { .s_addr = htonl ( 0x0a000006 ) },
786  },
787  },
788  "C:\\tftpboot\\icky#path",
789  {
790  .scheme = "tftp",
791  .host = "10.0.0.6",
792  .path = "/C:\\tftpboot\\icky#path",
793  },
794  "tftp://10.0.0.6/C%3A\\tftpboot\\icky%23path",
795 };
796 
797 /** PXE URI with custom port */
798 static struct uri_pxe_test uri_pxe_port = {
799  {
800  /* 192.168.0.1:4069 */
801  .sin = {
802  .sin_family = AF_INET,
803  .sin_addr = { .s_addr = htonl ( 0xc0a80001 ) },
804  .sin_port = htons ( 4069 ),
805  },
806  },
807  "/another/path",
808  {
809  .scheme = "tftp",
810  .host = "192.168.0.1",
811  .port = "4069",
812  .path = "//another/path",
813  },
814  "tftp://192.168.0.1:4069//another/path",
815 };
816 
817 /** Current working URI test */
818 static struct uri_churi_test uri_churi[] = {
819  {
820  "http://boot.ipxe.org/demo/boot.php",
821  "http://boot.ipxe.org/demo/boot.php",
822  },
823  {
824  "?vendor=10ec&device=8139",
825  "http://boot.ipxe.org/demo/boot.php?vendor=10ec&device=8139",
826  },
827  {
828  "fedora/fedora.ipxe",
829  "http://boot.ipxe.org/demo/fedora/fedora.ipxe",
830  },
831  {
832  "vmlinuz",
833  "http://boot.ipxe.org/demo/fedora/vmlinuz",
834  },
835  {
836  "http://local/boot/initrd.img",
837  "http://local/boot/initrd.img",
838  },
839  {
840  "modules/8139too.ko",
841  "http://local/boot/modules/8139too.ko",
842  },
843  {
844  NULL,
845  NULL,
846  }
847 };
848 
849 /** Form parameter URI test list */
851  {
852  "vendor",
853  "10ec",
854  },
855  {
856  "device",
857  "8139",
858  },
859  {
860  "uuid",
861  "f59fac00-758f-498f-9fe5-87d790045d94",
862  },
863  {
864  NULL,
865  NULL,
866  }
867 };
868 
869 /** Form parameter URI test */
870 static struct uri_params_test uri_params = {
871  "http://boot.ipxe.org/demo/boot.php##params",
872  {
873  .scheme = "http",
874  .host = "boot.ipxe.org",
875  .path = "/demo/boot.php",
876  },
877  NULL,
879 };
880 
881 /** Named form parameter URI test list */
883  {
884  "mac",
885  "00:1e:65:80:d3:b6",
886  },
887  {
888  "serial",
889  "LXTQ20Z1139322762F2000",
890  },
891  {
892  NULL,
893  NULL,
894  }
895 };
896 
897 /** Named form parameter URI test */
899  "http://192.168.100.4:3001/register##params=foo",
900  {
901  .scheme = "http",
902  .host = "192.168.100.4",
903  .port = "3001",
904  .path = "/register",
905  },
906  "foo",
908 };
909 
910 /**
911  * Perform URI self-test
912  *
913  */
914 static void uri_test_exec ( void ) {
915 
916  /* URI parsing, formatting, and duplication tests */
924  uri_parse_ok ( &uri_http_escaped_improper ); /* Parse only */
928  uri_parse_ok ( &uri_ipv6_local_non_conforming ); /* Parse only */
933 
934  /** URI port number tests */
937 
938  /** Path resolution tests */
944 
945  /** URI resolution tests */
951 
952  /* PXE URI construction tests */
958 
959  /* Current working URI tests */
961 
962  /* Form parameter URI tests */
965 }
966 
967 /** URI self-test */
969  .name = "uri",
970  .exec = uri_test_exec,
971 };
TCP/IP socket address.
Definition: tcpip.h:75
static struct uri_test uri_ipv6_local
IPv6 URI with link-local address.
Definition: uri_test.c:580
A URI parsing/formatting test.
Definition: uri_test.c:43
unsigned int default_port
Default port number.
Definition: uri_test.c:55
static void uri_put(struct uri *uri)
Decrement URI reference count.
Definition: uri.h:188
const char * value
Value.
Definition: uri_test.c:100
static struct uri_test uri_ipv6
IPv6 URI.
Definition: uri_test.c:559
static struct uri * uri_get(struct uri *uri)
Increment URI reference count.
Definition: uri.h:177
static struct uri_resolve_test uri_absolute
Absolute URI resolution test.
Definition: uri_test.c:698
static void uri_churi_okx(struct uri_churi_test *test, const char *file, unsigned int line)
Report current working URI test result.
Definition: uri_test.c:362
const char * string
URI string.
Definition: uri_test.c:106
const char * string
URI string (for display only; cannot be reparsed)
Definition: uri_test.c:84
const char * filename
Filename.
Definition: uri_test.c:80
#define for_each_param(param, params)
Iterate over all form parameters in a list.
Definition: params.h:75
static struct uri_port_test uri_explicit_port
URI with port number.
Definition: uri_test.c:642
static void uri_resolve_okx(struct uri_resolve_test *test, const char *file, unsigned int line)
Report URI resolution test result.
Definition: uri_test.c:271
const char * string
URI string.
Definition: uri_test.c:45
static struct uri_pxe_test uri_pxe_relative_path
PXE URI with relative path.
Definition: uri_test.c:762
struct uri * pxe_uri(struct sockaddr *sa_server, const char *filename)
Construct URI from server address and filename.
Definition: uri.c:774
static struct uri_test uri_http_escaped
HTTP URI with escaped characters.
Definition: uri_test.c:530
static void uri_okx(struct uri *uri, struct uri *expected, const char *file, unsigned int line)
Report URI equality test result.
Definition: uri_test.c:142
static __always_inline int off_t userptr_t second
Definition: efi_uaccess.h:80
static struct uri_test uri_empty
Empty URI.
Definition: uri_test.c:486
struct sockaddr_in6 sin6
Definition: uri_test.c:76
A form parameter list.
Definition: params.h:16
struct sockaddr sa
Definition: uri_test.c:74
#define uri_parse_format_dup_ok(test)
Definition: uri_test.c:238
static struct uri_pxe_test uri_pxe_absolute
PXE URI with absolute URI.
Definition: uri_test.c:726
static struct uri_params_test_list uri_params_list[]
Form parameter URI test list.
Definition: uri_test.c:850
union uri_pxe_test::@423 server
Server address.
static struct uri_params_test uri_params
Form parameter URI test.
Definition: uri_test.c:870
static struct uri_test uri_file_volume
File URI with volume name.
Definition: uri_test.c:632
Self-test infrastructure.
const char * name
Test set name.
Definition: test.h:17
static struct uri_test uri_file_relative
File URI with relative (opaque) path.
Definition: uri_test.c:614
IPv4 socket address.
Definition: in.h:82
static struct uri_pxe_test uri_pxe_port
PXE URI with custom port.
Definition: uri_test.c:798
static struct uri_resolve_test uri_fragment
Fragment URI resolution test.
Definition: uri_test.c:719
Uniform Resource Identifiers.
static void uri_test_exec(void)
Perform URI self-test.
Definition: uri_test.c:914
sa_family_t sin_family
Socket address family (part of struct sockaddr)
Definition: in.h:87
A self-test set.
Definition: test.h:15
#define htonl(value)
Definition: byteswap.h:133
A PXE URI test.
Definition: uri_test.c:71
#define uri_port_ok(test)
Definition: uri_test.c:262
static struct uri_resolve_test uri_query
Query URI resolution test.
Definition: uri_test.c:712
#define uri_resolve_ok(test)
Definition: uri_test.c:303
const char * port
Port number.
Definition: uri.h:64
static struct uri_resolve_test uri_relative_path
Path resolution test with "." and ".." elements.
Definition: uri_test.c:663
struct sockaddr_tcpip st
Definition: uri_test.c:77
const char * key
Key.
Definition: uri_test.c:98
static void uri_format_okx(struct uri_test *test, const char *file, unsigned int line)
Report URI formatting test result.
Definition: uri_test.c:185
static struct uri_resolve_test uri_absolute_path
Path resolution test with absolute path.
Definition: uri_test.c:684
const char * scheme
Scheme.
Definition: uri.h:54
u8 port
Port number.
Definition: CIB_PRM.h:31
static struct uri_test uri_boot_ipxe_org
Basic HTTP URI.
Definition: uri_test.c:491
#define okx(success, file, line)
Report test result.
Definition: test.h:44
void churi(struct uri *uri)
Change working URI.
Definition: cwuri.c:45
static struct uri_resolve_test uri_directory_path
Path resolution test terminating with directory.
Definition: uri_test.c:670
struct parameter * add_parameter(struct parameters *params, const char *key, const char *value)
Add form parameter.
Definition: params.c:128
Form parameters.
static struct uri_test uri_iscsi
iSCSI URI
Definition: uri_test.c:605
const char * relative
Relative path or URI.
Definition: uri_test.c:65
const char * base
Base path or URI.
Definition: uri_test.c:63
A URI port number test.
Definition: uri_test.c:51
static struct uri_test uri_http_escaped_improper
HTTP URI with improperly escaped characters.
Definition: uri_test.c:542
const char * path
Path.
Definition: uri.h:66
static void uri_params_list_okx(struct uri_params_test *test, struct uri *uri, const char *file, unsigned int line)
Report form parameter URI test list result.
Definition: uri_test.c:411
static struct uri_resolve_test uri_excessive_path
Path resolution test with excessive ".." elements.
Definition: uri_test.c:677
Transport-network layer interface.
size_t format_uri(const struct uri *uri, char *buf, size_t len)
Format URI.
Definition: uri.c:457
struct parameters * create_parameters(const char *name)
Create form parameter list.
Definition: params.c:86
static struct uri_churi_test uri_churi[]
Current working URI test.
Definition: uri_test.c:818
char * format_uri_alloc(const struct uri *uri)
Format URI.
Definition: uri.c:522
static struct uri_test uri_http_all
HTTP URI with all the trimmings.
Definition: uri_test.c:515
struct self_test uri_test __self_test
URI self-test.
Definition: uri_test.c:968
char * resolve_path(const char *base_path, const char *relative_path)
Resolve base+relative path.
Definition: uri.c:614
struct parameters * params
Form parameters.
Definition: uri.h:72
Generalized socket address structure.
Definition: socket.h:96
A form parameter URI test.
Definition: uri_test.c:104
static struct uri_test uri_ipv6_port
IPv6 URI with port.
Definition: uri_test.c:569
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
static struct uri_resolve_test uri_absolute_uri_path
Absolute path URI resolution test.
Definition: uri_test.c:705
struct hv_monitor_parameter param[4][32]
Parameters.
Definition: hyperv.h:24
struct uri * uri_dup(const struct uri *uri)
Duplicate URI.
Definition: uri.c:576
uint8_t * tmp
Definition: entropy.h:156
size_t strlen(const char *src)
Get length of string.
Definition: string.c:228
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
static void uri_port_okx(struct uri_port_test *test, const char *file, unsigned int line)
Report URI port number test result.
Definition: uri_test.c:248
struct list_head list
List of form parameters.
Definition: params.h:30
A current working URI test.
Definition: uri_test.c:88
static struct uri_params_test uri_named_params
Named form parameter URI test.
Definition: uri_test.c:898
const char * host
Host name.
Definition: uri.h:62
A URI or path resolution test.
Definition: uri_test.c:61
uint16_t base
Base address.
Definition: edd.h:14
#define uri_params_ok(test)
Definition: uri_test.c:483
const char * expected
Expected new working URI.
Definition: uri_test.c:92
static struct uri_test uri_path
Basic path-only URI.
Definition: uri_test.c:503
static void uri_dup_okx(struct uri *uri, const char *file, unsigned int line)
Report URI duplication test result.
Definition: uri_test.c:212
uint8_t formatted[5]
Formatted area.
Definition: smbios.h:29
static void uri_pxe_okx(struct uri_pxe_test *test, const char *file, unsigned int line)
Report URI PXE test result.
Definition: uri_test.c:336
static struct uri_test uri_mailto
Basic opaque URI.
Definition: uri_test.c:497
static struct uri_resolve_test uri_relative
Relative URI resolution test.
Definition: uri_test.c:691
const char * query
Query.
Definition: uri.h:68
uint32_t len
Length.
Definition: ena.h:14
const char * opaque
Opaque part.
Definition: uri.h:56
const char * string
URI string.
Definition: uri_test.c:53
#define uri_churi_ok(test)
Definition: uri_test.c:401
int strcmp(const char *first, const char *second)
Compare strings.
Definition: string.c:172
const char * fragment
Fragment.
Definition: uri.h:70
static void uri_resolve_path_okx(struct uri_resolve_test *test, const char *file, unsigned int line)
Report path resolution test result.
Definition: uri_test.c:312
static struct uri_pxe_test uri_pxe_absolute_path
PXE URI with absolute path.
Definition: uri_test.c:744
static struct uri_test uri_file_absolute
File URI with absolute path.
Definition: uri_test.c:623
unsigned int uri_port(const struct uri *uri, unsigned int default_port)
Get port from URI.
Definition: uri.c:441
const char * password
Password.
Definition: uri.h:60
#define uri_pxe_ok(test)
Definition: uri_test.c:353
static struct uri_test uri_path_escaped
Path-only URI with escaped characters.
Definition: uri_test.c:509
IPv6 socket address.
Definition: in.h:115
const char * user
User name.
Definition: uri.h:58
static void uri_params_okx(struct uri_params_test *test, const char *file, unsigned int line)
Report form parameter URI test result.
Definition: uri_test.c:444
const char * name
Parameter list name.
Definition: uri_test.c:110
A Uniform Resource Identifier.
Definition: uri.h:50
A form parameter.
Definition: params.h:28
A form parameter URI test list.
Definition: uri_test.c:96
struct uri * resolve_uri(const struct uri *base_uri, struct uri *relative_uri)
Resolve base+relative URI.
Definition: uri.c:676
static struct uri_resolve_test uri_simple_path
Simple path resolution test.
Definition: uri_test.c:656
unsigned int port
Expected port number.
Definition: uri_test.c:57
struct sockaddr_in sin
Definition: uri_test.c:75
static struct uri_params_test_list uri_named_params_list[]
Named form parameter URI test list.
Definition: uri_test.c:882
#define uri_resolve_path_ok(test)
Definition: uri_test.c:326
const char * resolved
Expected resolved path or URI.
Definition: uri_test.c:67
struct uri * cwuri
Current working URI.
Definition: cwuri.c:38
static int uristrcmp(const char *first, const char *second)
Compare two URI component strings.
Definition: uri_test.c:122
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
static void uri_parse_format_dup_okx(struct uri_test *test, const char *file, unsigned int line)
Report URI combined parsing and formatting test result.
Definition: uri_test.c:231
static struct uri_port_test uri_default_port
URI without port number.
Definition: uri_test.c:649
#define uri_parse_ok(test)
Definition: uri_test.c:176
String functions.
static struct uri_pxe_test uri_pxe_icky
PXE URI with path containing special characters.
Definition: uri_test.c:780
#define htons(value)
Definition: byteswap.h:135
static struct uri_test uri_ipv6_local_non_conforming
IPv6 URI with link-local address not conforming to RFC 6874.
Definition: uri_test.c:590
uint32_t first
Length to skip in first segment.
Definition: pccrc.h:23
const char * relative
Relative URI.
Definition: uri_test.c:90
#define AF_INET
IPv4 Internet addresses.
Definition: socket.h:63
static int test
Definition: epic100.c:73
struct uri * parse_uri(const char *uri_string)
Parse URI.
Definition: uri.c:295
static void uri_parse_okx(struct uri_test *test, const char *file, unsigned int line)
Report URI parsing test result.
Definition: uri_test.c:165
struct uri_params_test_list * list
Parameter list.
Definition: uri_test.c:112