|
@@ -26,6 +26,7 @@
|
26
|
26
|
#include <stdlib.h>
|
27
|
27
|
#include <string.h>
|
28
|
28
|
#include <libgen.h>
|
|
29
|
+#include <ctype.h>
|
29
|
30
|
#include <gpxe/vsprintf.h>
|
30
|
31
|
#include <gpxe/uri.h>
|
31
|
32
|
|
|
@@ -381,3 +382,80 @@ struct uri * resolve_uri ( struct uri *base_uri,
|
381
|
382
|
free ( tmp_path );
|
382
|
383
|
return new_uri;
|
383
|
384
|
}
|
|
385
|
+
|
|
386
|
+/**
|
|
387
|
+ * Test for unreserved URI characters
|
|
388
|
+ *
|
|
389
|
+ * @v c Character to test
|
|
390
|
+ * @ret is_unreserved Character is an unreserved character
|
|
391
|
+ */
|
|
392
|
+static int is_unreserved_uri_char ( int c ) {
|
|
393
|
+ /* According to RFC3986, the unreserved character set is
|
|
394
|
+ *
|
|
395
|
+ * A-Z a-z 0-9 - _ . ~
|
|
396
|
+ */
|
|
397
|
+ return ( isupper ( c ) || islower ( c ) || isdigit ( c ) ||
|
|
398
|
+ ( c == '-' ) || ( c == '_' ) ||
|
|
399
|
+ ( c == '.' ) || ( c == '~' ) );
|
|
400
|
+}
|
|
401
|
+
|
|
402
|
+/**
|
|
403
|
+ * URI-encode string
|
|
404
|
+ *
|
|
405
|
+ * @v raw_string String to be URI-encoded
|
|
406
|
+ * @v buf Buffer to contain encoded string
|
|
407
|
+ * @v len Length of buffer
|
|
408
|
+ * @ret len Length of encoded string (excluding NUL)
|
|
409
|
+ */
|
|
410
|
+size_t uri_encode ( const char *raw_string, char *buf, size_t len ) {
|
|
411
|
+ ssize_t remaining = len;
|
|
412
|
+ size_t used;
|
|
413
|
+ unsigned char c;
|
|
414
|
+
|
|
415
|
+ if ( len )
|
|
416
|
+ buf[0] = '\0';
|
|
417
|
+
|
|
418
|
+ while ( ( c = *(raw_string++) ) ) {
|
|
419
|
+ if ( is_unreserved_uri_char ( c ) ) {
|
|
420
|
+ used = ssnprintf ( buf, remaining, "%c", c );
|
|
421
|
+ } else {
|
|
422
|
+ used = ssnprintf ( buf, remaining, "%%%02X", c );
|
|
423
|
+ }
|
|
424
|
+ buf += used;
|
|
425
|
+ remaining -= used;
|
|
426
|
+ }
|
|
427
|
+
|
|
428
|
+ return ( len - remaining );
|
|
429
|
+}
|
|
430
|
+
|
|
431
|
+/**
|
|
432
|
+ * Decode URI-encoded string
|
|
433
|
+ *
|
|
434
|
+ * @v encoded_string URI-encoded string
|
|
435
|
+ * @v buf Buffer to contain decoded string
|
|
436
|
+ * @v len Length of buffer
|
|
437
|
+ * @ret len Length of decoded string (excluding NUL)
|
|
438
|
+ */
|
|
439
|
+size_t uri_decode ( const char *encoded_string, char *buf, size_t len ) {
|
|
440
|
+ ssize_t remaining = len;
|
|
441
|
+ char hexbuf[3];
|
|
442
|
+ char *hexbuf_end;
|
|
443
|
+ unsigned char c;
|
|
444
|
+
|
|
445
|
+ if ( len )
|
|
446
|
+ buf[0] = '\0';
|
|
447
|
+
|
|
448
|
+ while ( *encoded_string ) {
|
|
449
|
+ if ( *encoded_string == '%' ) {
|
|
450
|
+ encoded_string++;
|
|
451
|
+ snprintf ( hexbuf, sizeof ( hexbuf ), "%s",
|
|
452
|
+ encoded_string );
|
|
453
|
+ c = strtoul ( hexbuf, &hexbuf_end, 16 );
|
|
454
|
+ encoded_string += ( hexbuf_end - hexbuf );
|
|
455
|
+ } else {
|
|
456
|
+ c = *(encoded_string++);
|
|
457
|
+ }
|
|
458
|
+ ssnprintf ( buf++, remaining--, "%c", c );
|
|
459
|
+ }
|
|
460
|
+ return ( len - remaining );
|
|
461
|
+}
|