url.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. #include "precompile.h"
  2. #include "url.h"
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <ctype.h>
  6. #include <winpr/string.h>
  7. #include "memutil.h"
  8. /* from libasynchttp */
  9. TOOLKIT_API char* urlencode(unsigned char *string) {
  10. int escapecount = 0;
  11. unsigned char *src, *dest;
  12. unsigned char *newstr;
  13. char hextable[] = { '0', '1', '2', '3', '4', '5', '6', '7',
  14. '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
  15. if (string == NULL) return NULL;
  16. for (src = string; *src != 0; src++)
  17. if (!isalnum(*src)) escapecount++;
  18. newstr = (unsigned char*)malloc(strlen((char*)string) - escapecount + (escapecount * 3) + 1);
  19. src = string;
  20. dest = newstr;
  21. while (*src != 0) {
  22. if (!isalnum(*src)) {
  23. *dest++ = '%';
  24. *dest++ = hextable[*src >> 4];
  25. *dest++ = hextable[*src & 0x0F];
  26. src++;
  27. } else {
  28. *dest++ = *src++;
  29. }
  30. }
  31. *dest = 0;
  32. return (char*)newstr;
  33. }
  34. TOOLKIT_API unsigned char* urldecode(char *string) {
  35. int destlen = 0;
  36. unsigned char *src, *dest;
  37. unsigned char *newstr;
  38. if (string == NULL) return NULL;
  39. for (src = (unsigned char*)string; *src != 0; src++) {
  40. if (*src == '%') { src+=2; } /* FIXME: this isn't robust. should check
  41. the next two chars for 0 */
  42. destlen++;
  43. }
  44. newstr = (unsigned char*)malloc(destlen + 1);
  45. src = (unsigned char*)string;
  46. dest = newstr;
  47. while (*src != 0) {
  48. if (*src == '%') {
  49. char h = toupper(src[1]);
  50. char l = toupper(src[2]);
  51. int vh, vl;
  52. vh = isalpha(h) ? (10+(h-'A')) : (h-'0');
  53. vl = isalpha(l) ? (10+(l-'A')) : (l-'0');
  54. *dest++ = ((vh<<4)+vl);
  55. src += 3;
  56. } else if (*src == '+') {
  57. *dest++ = ' ';
  58. src++;
  59. } else {
  60. *dest++ = *src++;
  61. }
  62. }
  63. *dest = 0;
  64. return newstr;
  65. }
  66. TOOLKIT_API char* util_skipline(char *text) {
  67. while (*text != 0) {
  68. if (*text == '\n') {
  69. text++;
  70. break;
  71. }
  72. text++;
  73. }
  74. return text;
  75. }
  76. TOOLKIT_API char* util_getline(char *text) {
  77. int len;
  78. char *str;
  79. for (len = 0; text[len] != 0; len++)
  80. if (text[len] == '\r' || text[len] == '\n') break;
  81. str = (char*)malloc(len+1);
  82. memcpy(str, text, len+1);
  83. str[len] = 0;
  84. return str;
  85. }
  86. static char*strgrab(char *src, int len) {
  87. char *ret = (char*)malloc(len+1);
  88. memcpy(ret, src, len);
  89. ret[len] = 0;
  90. return ret;
  91. }
  92. static char* strscan(char *src, char *origsearch) {
  93. char *search;
  94. while (*src) {
  95. search = origsearch;
  96. while (*search) {
  97. if (*src == *search)
  98. return src;
  99. search++;
  100. }
  101. src++;
  102. }
  103. return src;
  104. }
  105. TOOLKIT_API int url_parse(char *url, url_fields *uf) {
  106. char *s, *e;
  107. memset(uf, 0, sizeof(url_fields));
  108. /* search for end of scheme */
  109. s = url;
  110. e = strscan(s, ":");
  111. uf->scheme = strgrab(s, e-s);
  112. s = e+1;
  113. if (*s == 0) goto err;
  114. if (*s == '/' && *(s+1) == '/') {
  115. /* it's a net_path */
  116. } else goto err;
  117. s = s+2;
  118. /* search for / or : trailing hostname */
  119. e = strscan(s, "/:");
  120. if (e == s) goto err;
  121. uf->host = strgrab(s, e-s);
  122. s = e;
  123. if (*s == ':') {
  124. char *port;
  125. s++;
  126. /* grab the port */
  127. e = strscan(s, "/");
  128. if (e == s) goto err;
  129. port = strgrab(s, e-s);
  130. uf->port = atoi(port);
  131. free(port);
  132. s = e;
  133. }
  134. /* grab remainder into path */
  135. e = strscan(s, "");
  136. uf->path = strgrab(s, e-s);
  137. /* if they've not specified a path, default to / */
  138. if (uf->path[0] == 0) {
  139. free(uf->path);
  140. uf->path = _strdup("/");
  141. }
  142. return 0;
  143. err:
  144. if (uf->path) free(uf->path);
  145. if (uf->host) free(uf->host);
  146. if (uf->scheme) free(uf->scheme);
  147. return -(e-url);
  148. }
  149. TOOLKIT_API void url_free_fields(url_fields *uf) {
  150. if (uf->scheme) free(uf->scheme);
  151. if (uf->host) free(uf->host);
  152. if (uf->path) free(uf->path);
  153. }