| 4726 | |
| 4727 | #ifdef CPPHTTPLIB_NO_EXCEPTIONS |
| 4728 | inline bool parse_range_header(const std::string &s, Ranges &ranges) { |
| 4729 | #else |
| 4730 | inline bool parse_range_header(const std::string &s, Ranges &ranges) try { |
| 4731 | #endif |
| 4732 | auto is_valid = [](const std::string &str) { |
| 4733 | return std::all_of(str.cbegin(), str.cend(), |
| 4734 | [](unsigned char c) { return std::isdigit(c); }); |
| 4735 | }; |
| 4736 | |
| 4737 | if (s.size() > 7 && s.compare(0, 6, "bytes=") == 0) { |
| 4738 | const auto pos = static_cast<size_t>(6); |
| 4739 | const auto len = static_cast<size_t>(s.size() - 6); |
| 4740 | auto all_valid_ranges = true; |
| 4741 | split(&s[pos], &s[pos + len], ',', [&](const char *b, const char *e) { |
| 4742 | if (!all_valid_ranges) { return; } |
| 4743 | |
| 4744 | const auto it = std::find(b, e, '-'); |
| 4745 | if (it == e) { |
| 4746 | all_valid_ranges = false; |
| 4747 | return; |
| 4748 | } |
| 4749 | |
| 4750 | const auto lhs = std::string(b, it); |
| 4751 | const auto rhs = std::string(it + 1, e); |
| 4752 | if (!is_valid(lhs) || !is_valid(rhs)) { |
| 4753 | all_valid_ranges = false; |
| 4754 | return; |
| 4755 | } |
| 4756 | |
| 4757 | const auto first = |
| 4758 | static_cast<ssize_t>(lhs.empty() ? -1 : std::stoll(lhs)); |
| 4759 | const auto last = |
| 4760 | static_cast<ssize_t>(rhs.empty() ? -1 : std::stoll(rhs)); |
| 4761 | if ((first == -1 && last == -1) || |
| 4762 | (first != -1 && last != -1 && first > last)) { |
| 4763 | all_valid_ranges = false; |
| 4764 | return; |
| 4765 | } |
| 4766 | |
| 4767 | ranges.emplace_back(first, last); |
| 4768 | }); |
| 4769 | return all_valid_ranges && !ranges.empty(); |
| 4770 | } |
| 4771 | return false; |
| 4772 | #ifdef CPPHTTPLIB_NO_EXCEPTIONS |
| 4773 | } |
| 4774 | #else |
| 4775 | } catch (...) { return false; } |
| 4776 | #endif |
| 4777 | |
| 4778 | class MultipartFormDataParser { |
| 4779 | public: |
| 4780 | MultipartFormDataParser() = default; |
| 4781 | |
| 4782 | void set_boundary(std::string &&boundary) { |
| 4783 | boundary_ = boundary; |
| 4784 | dash_boundary_crlf_ = dash_ + boundary_ + crlf_; |
| 4785 | crlf_dash_boundary_ = crlf_ + dash_ + boundary_; |
no test coverage detected