hurl.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. #include "hurl.h"
  2. #include "hdef.h"
  3. #include "hbase.h"
  4. /*
  5. static bool Curl_isunreserved(unsigned char in)
  6. {
  7. switch(in) {
  8. case '0': case '1': case '2': case '3': case '4':
  9. case '5': case '6': case '7': case '8': case '9':
  10. case 'a': case 'b': case 'c': case 'd': case 'e':
  11. case 'f': case 'g': case 'h': case 'i': case 'j':
  12. case 'k': case 'l': case 'm': case 'n': case 'o':
  13. case 'p': case 'q': case 'r': case 's': case 't':
  14. case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
  15. case 'A': case 'B': case 'C': case 'D': case 'E':
  16. case 'F': case 'G': case 'H': case 'I': case 'J':
  17. case 'K': case 'L': case 'M': case 'N': case 'O':
  18. case 'P': case 'Q': case 'R': case 'S': case 'T':
  19. case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z':
  20. case '-': case '.': case '_': case '~':
  21. return TRUE;
  22. default:
  23. break;
  24. }
  25. return FLASE;
  26. }
  27. */
  28. static inline bool is_unambiguous(char c) {
  29. return IS_ALPHANUM(c) ||
  30. c == '-' ||
  31. c == '_' ||
  32. c == '.' ||
  33. c == '~';
  34. }
  35. static inline bool char_in_str(char c, const char* str) {
  36. const char* p = str;
  37. while (*p && *p != c) ++p;
  38. return *p != '\0';
  39. }
  40. static inline unsigned char hex2i(char hex) {
  41. return hex <= '9' ? hex - '0' :
  42. hex <= 'F' ? hex - 'A' + 10 : hex - 'a' + 10;
  43. }
  44. std::string HUrl::escape(const std::string& str, const char* unescaped_chars) {
  45. std::string ostr;
  46. static char tab[] = "0123456789ABCDEF";
  47. const unsigned char* p = reinterpret_cast<const unsigned char*>(str.c_str());
  48. char szHex[4] = "%00";
  49. while (*p != '\0') {
  50. if (is_unambiguous(*p) || char_in_str(*p, unescaped_chars)) {
  51. ostr += *p;
  52. }
  53. else {
  54. szHex[1] = tab[*p >> 4];
  55. szHex[2] = tab[*p & 0xF];
  56. ostr += szHex;
  57. }
  58. ++p;
  59. }
  60. return ostr;
  61. }
  62. std::string HUrl::unescape(const std::string& str) {
  63. std::string ostr;
  64. const char* p = str.c_str();
  65. while (*p != '\0') {
  66. if (*p == '%' &&
  67. IS_HEX(p[1]) &&
  68. IS_HEX(p[2])) {
  69. ostr += ((hex2i(p[1]) << 4) | hex2i(p[2]));
  70. p += 3;
  71. }
  72. else {
  73. if (*p == '+') {
  74. ostr += ' ';
  75. } else {
  76. ostr += *p;
  77. }
  78. ++p;
  79. }
  80. }
  81. return ostr;
  82. }
  83. void HUrl::reset() {
  84. url.clear();
  85. scheme.clear();
  86. username.clear();
  87. password.clear();
  88. host.clear();
  89. port = 0;
  90. path.clear();
  91. query.clear();
  92. fragment.clear();
  93. }
  94. bool HUrl::parse(const std::string& url) {
  95. reset();
  96. this->url = url;
  97. hurl_t stURL;
  98. if (hv_parse_url(&stURL, url.c_str()) != 0) {
  99. return false;
  100. }
  101. int len = stURL.fields[HV_URL_SCHEME].len;
  102. if (len > 0) {
  103. scheme = url.substr(stURL.fields[HV_URL_SCHEME].off, len);
  104. }
  105. len = stURL.fields[HV_URL_USERNAME].len;
  106. if (len > 0) {
  107. username = url.substr(stURL.fields[HV_URL_USERNAME].off, len);
  108. len = stURL.fields[HV_URL_PASSWORD].len;
  109. if (len > 0) {
  110. password = url.substr(stURL.fields[HV_URL_PASSWORD].off, len);
  111. }
  112. }
  113. len = stURL.fields[HV_URL_HOST].len;
  114. if (len > 0) {
  115. host = url.substr(stURL.fields[HV_URL_HOST].off, len);
  116. }
  117. port = stURL.port;
  118. len = stURL.fields[HV_URL_PATH].len;
  119. if (len > 0) {
  120. path = url.substr(stURL.fields[HV_URL_PATH].off, len);
  121. } else {
  122. path = "/";
  123. }
  124. len = stURL.fields[HV_URL_QUERY].len;
  125. if (len > 0) {
  126. query = url.substr(stURL.fields[HV_URL_QUERY].off, len);
  127. }
  128. len = stURL.fields[HV_URL_FRAGMENT].len;
  129. if (len > 0) {
  130. fragment = url.substr(stURL.fields[HV_URL_FRAGMENT].off, len);
  131. }
  132. return true;
  133. }
  134. const std::string& HUrl::dump() {
  135. url.clear();
  136. // scheme://
  137. if (!scheme.empty()) {
  138. url += scheme;
  139. url += "://";
  140. }
  141. // user:pswd@
  142. if (!username.empty()) {
  143. url += username;
  144. if (!password.empty()) {
  145. url += ":";
  146. url += password;
  147. }
  148. url += "@";
  149. }
  150. // host:port
  151. if (!host.empty()) {
  152. url += host;
  153. if (port != 80 && port != 443) {
  154. char buf[16] = {0};
  155. snprintf(buf, sizeof(buf), ":%d", port);
  156. url += port;
  157. }
  158. }
  159. // /path
  160. if (!path.empty()) {
  161. url += path;
  162. }
  163. // ?query
  164. if (!query.empty()) {
  165. url += '?';
  166. url += query;
  167. }
  168. // #fragment
  169. if (!fragment.empty()) {
  170. url += '#';
  171. url += fragment;
  172. }
  173. return url;
  174. }
  175. namespace hv {
  176. std::string escapeHTML(const std::string& str) {
  177. std::string ostr;
  178. const char* p = str.c_str();
  179. while (*p != '\0') {
  180. switch (*p) {
  181. case '<': ostr += "&lt;"; break;
  182. case '>': ostr += "&gt;"; break;
  183. case '&': ostr += "&amp;"; break;
  184. case '\"': ostr += "&quot;"; break;
  185. case '\'': ostr += "&apos;"; break;
  186. // case ' ': ostr += "&nbsp;"; break;
  187. default: ostr += *p; break;
  188. }
  189. ++p;
  190. }
  191. return ostr;
  192. }
  193. }