uri.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*##############################################################################
  2. Copyright (C) 2012 HPCC Systems.
  3. All rights reserved. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as
  5. published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Affero General Public License for more details.
  11. You should have received a copy of the GNU Affero General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ############################################################################## */
  14. #include "uri.hpp"
  15. #include "jexcept.hpp"
  16. URI::URI(const char* path)
  17. {
  18. state.uri = &uri;
  19. try {
  20. if (uriParseUriA(&state, path) != URI_SUCCESS)
  21. throw MakeStringException(-1, "Invalid URI '%s'", path);
  22. populateFields(); // In a format we understand
  23. }
  24. // On parser failure, but also system exceptions (bad alloc, etc)
  25. catch (IException *)
  26. {
  27. uriFreeUriMembersA(&uri);
  28. throw;
  29. }
  30. uriFreeUriMembersA(&uri);
  31. }
  32. // Helper, to validate URI before creating object
  33. bool URI::isURI(const char *path)
  34. {
  35. UriParserStateA state;
  36. UriUriA uri;
  37. state.uri = &uri;
  38. bool match = (uriParseUriA(&state, path) == URI_SUCCESS);
  39. uriFreeUriMembersA(&uri);
  40. return match;
  41. }
  42. void URI::populateFields()
  43. {
  44. // Scheme (defines which resolver to use, see above)
  45. StringBuffer schemeStr(uri.scheme.afterLast - uri.scheme.first, uri.scheme.first);
  46. schemeStr.toLowerCase();
  47. if (strcmp(schemeStr.str(), "hpcc") == 0)
  48. scheme = URIScheme_hpcc;
  49. else if (strcmp(schemeStr.str(), "file") == 0)
  50. scheme = URIScheme_file;
  51. else
  52. scheme = URIScheme_error;
  53. // Server
  54. server.user.set(uri.userInfo.first, uri.userInfo.afterLast - uri.userInfo.first);
  55. server.host.set(uri.hostText.first, uri.hostText.afterLast - uri.hostText.first);
  56. StringAttr portStr(uri.portText.first, uri.portText.afterLast - uri.portText.first);
  57. server.port = atoi(portStr.get()); // More - use default ports?
  58. // Path
  59. UriPathSegmentA* cur = uri.pathHead;
  60. StringBuffer pathStr;
  61. if (uri.absolutePath || scheme == URIScheme_file)
  62. pathStr.append("/");
  63. bool first = true;
  64. while (cur)
  65. {
  66. if (!first)
  67. pathStr.append("/");
  68. pathStr.append(cur->text.afterLast - cur->text.first, cur->text.first);
  69. first = false;
  70. cur = cur->next;
  71. }
  72. path.path.set(pathStr.str());
  73. // Extra info
  74. if (scheme == URIScheme_hpcc)
  75. {
  76. StringBuffer query(uri.query.afterLast - uri.query.first, uri.query.first);
  77. query.toLowerCase();
  78. if (strcmp(query.str(), "super") == 0)
  79. {
  80. path.type = URIFile_super;
  81. path.subname.set(uri.fragment.first, uri.fragment.afterLast - uri.fragment.first);
  82. path.index = 0;
  83. }
  84. else if (strcmp(query.str(), "stream") == 0)
  85. {
  86. path.type = URIFile_stream;
  87. StringAttr index(uri.fragment.first, uri.fragment.afterLast - uri.fragment.first);
  88. path.index = atoi(index.get());
  89. }
  90. else
  91. {
  92. path.type = URIFile_logic;
  93. path.index = 0;
  94. }
  95. }
  96. else
  97. {
  98. path.type = URIFile_local;
  99. path.index = 0;
  100. }
  101. }
  102. void URI::appendSchemeStr(StringBuffer& buf)
  103. {
  104. switch(scheme)
  105. {
  106. case URIScheme_hpcc:
  107. buf.append("hpcc");
  108. return;
  109. case URIScheme_file:
  110. buf.append("file");
  111. return;
  112. default:
  113. buf.append("unknown");
  114. return;
  115. }
  116. }
  117. void URI::appendServerStr(StringBuffer& buf)
  118. {
  119. if (!server.user.isEmpty())
  120. buf.append(server.user.get()).append("@");
  121. buf.append(server.host.get());
  122. if (server.port)
  123. buf.append(":").append(server.port);
  124. }
  125. void URI::appendPathStr(StringBuffer& buf)
  126. {
  127. buf.append(path.path.get());
  128. switch(path.type)
  129. {
  130. case URIFile_super:
  131. buf.append("?super");
  132. break;
  133. case URIFile_stream:
  134. buf.append("?stream");
  135. break;
  136. }
  137. if (path.index)
  138. buf.append("#").append(path.index);
  139. else if (path.subname.length())
  140. buf.append("#").append(path.subname.get());
  141. }