url.c 3.4 KB

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