userver: userver/http/content_type.hpp Source File
Loading...
Searching...
No Matches
content_type.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/http/content_type.hpp
4/// @brief @copybrief http::ContentType
5
6#include <iosfwd>
7#include <stdexcept>
8#include <string>
9#include <string_view>
10
11#include <fmt/core.h>
12
13#include <userver/logging/fwd.hpp>
14#include <userver/utils/str_icase.hpp>
15
16USERVER_NAMESPACE_BEGIN
17
18/// @brief HTTP primitives: status codes, URLs, headers, and parsing helpers.
19namespace http {
20
21/// @brief Content-Type parsing error
22class MalformedContentType : public std::runtime_error {
23public:
24 using std::runtime_error::runtime_error;
25
26 MalformedContentType(const MalformedContentType&) = default;
27 MalformedContentType(MalformedContentType&&) = default;
28 MalformedContentType& operator=(const MalformedContentType&) = default;
29 MalformedContentType& operator=(MalformedContentType&&) = default;
30
31 ~MalformedContentType() override;
32};
33
34/// @ingroup userver_universal userver_containers
35///
36/// @brief Content-Type representation
38public:
39 /// Constructor from a single content-type/media-range header value
40 /// as per RFC7231.
41 /// @{
42 /* implicit */ ContentType(std::string_view);
43 /* implicit */ ContentType(const std::string&);
44 /* implicit */ ContentType(const char*);
45 /// @}
46
47 /// Media type (application/json).
48 std::string MediaType() const;
49
50 /// "type" token of media type (application).
51 const std::string& TypeToken() const;
52
53 /// "subtype" token of media type (json).
54 const std::string& SubtypeToken() const;
55
56 /// Whether the "charset" option was explicitly specified.
57 bool HasExplicitCharset() const;
58
59 /// Charset (utf-8).
60 const std::string& Charset() const;
61
62 /// Value of "q" parameter in range 0--1000.
63 int Quality() const;
64
65 /// Whether this media range accepts specified content type.
66 /// Differs from equality comparison in wildcard support.
67 bool DoesAccept(const ContentType&) const;
68
69 /// Value of "boundary" parameter.
70 const std::string& Boundary() const;
71
72 /// Builds a string representation of content-type/media-range
73 std::string ToString() const;
74
75private:
76 friend logging::LogHelper& operator<<(logging::LogHelper&, const ContentType&);
77 friend std::ostream& operator<<(std::ostream&, const ContentType&);
78
79 void BuildStringRepresentation();
80
81 std::string type_;
82 std::string subtype_;
83 std::string charset_;
84 std::string boundary_;
85 int quality_;
86
87 std::string string_representation_;
88};
89
90bool operator==(const ContentType&, const ContentType&);
91
92/// Weak ordering for Accept media-ranges checking.
93/// Positions less specific types before more specific, so that the most
94/// specific type can be matched first.
95bool operator<(const ContentType&, const ContentType&);
96
98public:
99 size_t operator()(const ContentType&) const;
100
101private:
102 utils::StrIcaseHash str_hasher_;
103};
104
105/// @brief MIME content type helpers.
106namespace content_type {
107
108extern const ContentType kApplicationOctetStream;
109extern const ContentType kApplicationJson;
110extern const ContentType kTextPlain;
111
112} // namespace content_type
113} // namespace http
114
115USERVER_NAMESPACE_END
116
117template <>
118struct fmt::formatter<USERVER_NAMESPACE::http::ContentType> {
119 constexpr static auto parse(format_parse_context& ctx) { return ctx.begin(); }
120
121 template <typename FormatContext>
122 auto format(const USERVER_NAMESPACE::http::ContentType& value, FormatContext& ctx) const -> decltype(ctx.out()) {
123 return fmt::format_to(ctx.out(), "{}", value.ToString());
124 }
125};