rfc7230.ipp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. //
  2. // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // Official repository: https://github.com/boostorg/beast
  8. //
  9. #ifndef BOOST_BEAST_HTTP_IMPL_RFC7230_IPP
  10. #define BOOST_BEAST_HTTP_IMPL_RFC7230_IPP
  11. #include <boost/beast/http/rfc7230.hpp>
  12. namespace boost {
  13. namespace beast {
  14. namespace http {
  15. std::string
  16. param_list::const_iterator::
  17. unquote(string_view sr)
  18. {
  19. std::string s;
  20. s.reserve(sr.size());
  21. auto it = sr.begin() + 1;
  22. auto end = sr.end() - 1;
  23. while(it != end)
  24. {
  25. if(*it == '\\')
  26. ++it;
  27. s.push_back(*it);
  28. ++it;
  29. }
  30. return s;
  31. }
  32. void
  33. param_list::const_iterator::
  34. increment()
  35. {
  36. s_.clear();
  37. pi_.increment();
  38. if(pi_.empty())
  39. {
  40. pi_.it = pi_.last;
  41. pi_.first = pi_.last;
  42. }
  43. else if(! pi_.v.second.empty() &&
  44. pi_.v.second.front() == '"')
  45. {
  46. s_ = unquote(pi_.v.second);
  47. pi_.v.second = string_view{
  48. s_.data(), s_.size()};
  49. }
  50. }
  51. void
  52. ext_list::const_iterator::
  53. increment()
  54. {
  55. /*
  56. ext-list = *( "," OWS ) ext *( OWS "," [ OWS ext ] )
  57. ext = token param-list
  58. param-list = *( OWS ";" OWS param )
  59. param = token OWS "=" OWS ( token / quoted-string )
  60. chunked;a=b;i=j;gzip;windowBits=12
  61. x,y
  62. ,,,,,chameleon
  63. */
  64. auto const err =
  65. [&]
  66. {
  67. it_ = last_;
  68. first_ = last_;
  69. };
  70. auto need_comma = it_ != first_;
  71. v_.first = {};
  72. first_ = it_;
  73. for(;;)
  74. {
  75. detail::skip_ows(it_, last_);
  76. if(it_ == last_)
  77. return err();
  78. auto const c = *it_;
  79. if(detail::is_token_char(c))
  80. {
  81. if(need_comma)
  82. return err();
  83. auto const p0 = it_;
  84. for(;;)
  85. {
  86. ++it_;
  87. if(it_ == last_)
  88. break;
  89. if(! detail::is_token_char(*it_))
  90. break;
  91. }
  92. v_.first = string_view{&*p0,
  93. static_cast<std::size_t>(it_ - p0)};
  94. if (it_ == last_)
  95. return;
  96. detail::param_iter pi;
  97. pi.it = it_;
  98. pi.first = it_;
  99. pi.last = last_;
  100. for(;;)
  101. {
  102. pi.increment();
  103. if(pi.empty())
  104. break;
  105. }
  106. v_.second = param_list{string_view{&*it_,
  107. static_cast<std::size_t>(pi.it - it_)}};
  108. it_ = pi.it;
  109. return;
  110. }
  111. if(c != ',')
  112. return err();
  113. need_comma = false;
  114. ++it_;
  115. }
  116. }
  117. void
  118. token_list::const_iterator::
  119. increment()
  120. {
  121. /*
  122. token-list = *( "," OWS ) token *( OWS "," [ OWS ext ] )
  123. */
  124. auto const err =
  125. [&]
  126. {
  127. it_ = last_;
  128. first_ = last_;
  129. };
  130. auto need_comma = it_ != first_;
  131. v_ = {};
  132. first_ = it_;
  133. for(;;)
  134. {
  135. detail::skip_ows(it_, last_);
  136. if(it_ == last_)
  137. return err();
  138. auto const c = *it_;
  139. if(detail::is_token_char(c))
  140. {
  141. if(need_comma)
  142. return err();
  143. auto const p0 = it_;
  144. for(;;)
  145. {
  146. ++it_;
  147. if(it_ == last_)
  148. break;
  149. if(! detail::is_token_char(*it_))
  150. break;
  151. }
  152. v_ = string_view{&*p0,
  153. static_cast<std::size_t>(it_ - p0)};
  154. return;
  155. }
  156. if(c != ',')
  157. return err();
  158. need_comma = false;
  159. ++it_;
  160. }
  161. }
  162. } // http
  163. } // beast
  164. } // boost
  165. #endif // BOOST_BEAST_HTTP_IMPL_RFC7230_IPP