Commit 8e503d63 authored by Mathieu Stefani's avatar Mathieu Stefani

Added Accept header parsing

parent 352745b4
......@@ -100,6 +100,36 @@ UserAgent::write(std::ostream& os) const {
void
Accept::parseRaw(const char *str, size_t len) {
auto remaining = [&](const char* p) {
return len - (p - str);
};
auto eof = [&](const char *p) {
return remaining(p) == 0;
};
const char *p = static_cast<const char *>(memchr(str, ',', len));
const char *begin = str;
if (p == NULL) {
mediaRange_.push_back(Mime::MediaType::fromRaw(str, len));
} else {
do {
const size_t mimeLen = p - begin;
mediaRange_.push_back(Mime::MediaType::fromRaw(begin, mimeLen));
while (!eof(p) && (*p == ',' || *p == ' ')) ++p;
if (eof(p)) throw std::runtime_error("Invalid format for Accept header");
begin = p;
p = static_cast<const char *>(memchr(p, ',', remaining(p)));
} while (p != NULL);
mediaRange_.push_back(Mime::MediaType::fromRaw(begin, remaining(begin)));
}
}
void
......
......@@ -184,8 +184,10 @@ public:
void parseRaw(const char *str, size_t len);
void write(std::ostream& os) const;
const std::vector<Mime::MediaType> media() const { return mediaRange_; }
private:
std::string data;
std::vector<Mime::MediaType> mediaRange_;
};
class ContentEncoding : public Header {
......
......@@ -3,6 +3,64 @@
using namespace Net::Http;
TEST(headers_test, accept) {
Header::Accept a1;
a1.parse("audio/*; q=0.2");
{
const auto& media = a1.media();
ASSERT_EQ(media.size(), 1);
const auto& mime = media[0];
ASSERT_EQ(mime, MIME(Audio, Star));
ASSERT_EQ(mime.q().getOrElse(Mime::Q(0)), Mime::Q(20));
}
Header::Accept a2;
a2.parse("text/*, text/html, text/html;level=1, */*");
{
const auto& media = a2.media();
ASSERT_EQ(media.size(), 4);
const auto &m1 = media[0];
ASSERT_EQ(m1, MIME(Text, Star));
const auto &m2 = media[1];
ASSERT_EQ(m2, MIME(Text, Html));
const auto& m3 = media[2];
ASSERT_EQ(m3, MIME(Text, Html));
auto level = m3.getParam("level");
ASSERT_EQ(level.getOrElse(""), "1");
const auto& m4 = media[3];
ASSERT_EQ(m4, MIME(Star, Star));
}
Header::Accept a3;
a3.parse("text/*;q=0.3, text/html;q=0.7, text/html;level=1, "
"text/html;level=2;q=0.4, */*;q=0.5");
{
const auto& media = a3.media();
ASSERT_EQ(media.size(), 5);
ASSERT_EQ(media[0], MIME(Text, Star));
ASSERT_EQ(media[0].q().getOrElse(Mime::Q(0)), Mime::Q(30));
ASSERT_EQ(media[1], MIME(Text, Html));
ASSERT_EQ(media[2], MIME(Text, Html));
ASSERT_EQ(media[3], MIME(Text, Html));
ASSERT_EQ(media[4], MIME(Star, Star));
ASSERT_EQ(media[4].q().getOrElse(Mime::Q(0)), Mime::Q::fromFloat(0.5));
}
Header::Accept a4;
ASSERT_THROW(a4.parse("text/*;q=0.4, text/html;q=0.3,"), std::runtime_error);
Header::Accept a5;
ASSERT_THROW(a4.parse("text/*;q=0.4, text/html;q=0.3, "), std::runtime_error);
}
TEST(headers_test, content_length) {
Header::ContentLength cl;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment