3030#include < cstring>
3131#include < iomanip>
3232#include < sstream>
33- #include < stdexcept>
33+
34+ #include " common/error_text.hpp"
3435
3536namespace fc ::common {
36- HttpUri::HttpUri ( const std::string &uri) {
37- try {
38- parse (uri);
39- } catch ( const std::exception &exception) {
40- throw std::runtime_error ( std::string ( " Bad URI ← " ) + exception. what ( ));
41- }
37+ inline const auto kOutOfData { ERROR_TEXT ( " HttpUri: Out of data " )};
38+
39+ outcome::result<HttpUri> HttpUri:: parse (const std::string &string) {
40+ HttpUri uri;
41+ OUTCOME_TRY (uri. parseThis (string ));
42+ return uri;
4243 }
4344
44- void HttpUri::parse (const std::string &string) {
45+ outcome::result< void > HttpUri::parseThis (const std::string &string) {
4546 const char *s = string.c_str ();
4647 const auto *end = string.c_str () + string.size ();
4748
@@ -51,7 +52,7 @@ namespace fc::common {
5152 s += 2 ;
5253 } else if (*s == ' /' ) {
5354 scheme_ = Scheme::UNDEFINED;
54- parsePath (s, end);
55+ OUTCOME_TRY ( parsePath (s, end) );
5556 } else if (string.length () >= 7 && strncasecmp (s, " http://" , 7 ) == 0 ) {
5657 scheme_ = Scheme::HTTP;
5758 port_ = 80 ;
@@ -61,84 +62,86 @@ namespace fc::common {
6162 port_ = 443 ;
6263 s += 8 ;
6364 } else {
64- throw std::runtime_error (" Wrong scheme" );
65+ return ERROR_TEXT (" Wrong scheme" );
6566 }
6667
6768 // host:
6869 while (*s != 0 && *s != ' :' && *s != ' /' && *s != ' ?' && *s != ' #'
6970 && isspace (*s) == 0 ) {
7071 if (isalnum (*s) == 0 && *s != ' .' && *s != ' -' ) {
71- throw std::runtime_error (" Wrong hostname" );
72+ return ERROR_TEXT (" Wrong hostname" );
7273 }
7374 host_.push_back (static_cast <char >(tolower (*s)));
7475 if (++s > end) {
75- throw std::runtime_error ( " Out of data " ) ;
76+ return kOutOfData ;
7677 }
7778 }
7879
7980 // port:
8081 if (*s == ' :' ) {
8182 if (++s > end) {
82- throw std::runtime_error ( " Out of data " ) ;
83+ return kOutOfData ;
8384 }
8485 uint64_t port = 0 ;
8586 while (*s != 0 && *s != ' /' && *s != ' ?' && *s != ' #'
8687 && isspace (*s) == 0 ) {
8788 if (isdigit (*s) == 0 ) {
88- throw std::runtime_error (" Wrong port" );
89+ return ERROR_TEXT (" Wrong port" );
8990 }
9091 port = port * 10 + *s - ' 0' ;
9192 if (port < 1 || port > 65535 ) {
92- throw std::runtime_error (" Wrong port" );
93+ return ERROR_TEXT (" Wrong port" );
9394 }
9495 if (++s > end) {
95- throw std::runtime_error ( " Out of data " ) ;
96+ return kOutOfData ;
9697 }
9798 }
9899 port_ = static_cast <uint16_t >(port);
99100 }
100101
101102 // path:
102- parsePath (s, end);
103+ OUTCOME_TRY (parsePath (s, end));
104+ return outcome::success ();
103105 }
104106
105- void HttpUri::parsePath (const char *s, const char *end) {
107+ outcome::result< void > HttpUri::parsePath (const char *s, const char *end) {
106108 if (*s == ' /' ) {
107109 while (*s != 0 && *s != ' ?' && *s != ' #' && isspace (*s) == 0 ) {
108110 path_.push_back (*s);
109111 if (++s > end) {
110- throw std::runtime_error ( " Out of data " ) ;
112+ return kOutOfData ;
111113 }
112114 }
113115 }
114116
115117 // query:
116118 if (*s == ' ?' ) {
117119 if (++s > end) {
118- throw std::runtime_error ( " Out of data " ) ;
120+ return kOutOfData ;
119121 }
120122 hasQuery_ = true ;
121123 while (*s != 0 && *s != ' #' && isspace (*s) == 0 ) {
122124 query_.push_back (*s);
123125 if (++s > end) {
124- throw std::runtime_error ( " Out of data " ) ;
126+ return kOutOfData ;
125127 }
126128 }
127129 }
128130
129131 // fragment:
130132 if (*s == ' #' ) {
131133 if (++s > end) {
132- throw std::runtime_error ( " Out of data " ) ;
134+ return kOutOfData ;
133135 }
134136 hasFragment_ = true ;
135137 while (*s != 0 && isspace (*s) == 0 ) {
136138 fragment_.push_back (*s);
137139 if (++s > end) {
138- throw std::runtime_error ( " Out of data " ) ;
140+ return kOutOfData ;
139141 }
140142 }
141143 }
144+ return outcome::success ();
142145 }
143146
144147 const std::string &HttpUri::str () const {
@@ -171,7 +174,7 @@ namespace fc::common {
171174 return thisAsString_;
172175 }
173176
174- std::string HttpUri::urldecode (const std::string &input_) {
177+ outcome::result< std::string> HttpUri::urldecode (const std::string &input_) {
175178 std::string input (input_);
176179 std::replace (input.begin (), input.end (), ' +' , ' ' );
177180 return PercentEncoding::decode (input);
0 commit comments