1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
// -*- mode: c++; c-basic-offset: 2; -*-
#ifndef HTTP_HH
#define HTTP_HH
#include <cstdint>
#include <memory>
#include <string>
// glibc defines these even tho it shouldn't if you ask posix
#ifdef major
# undef major
#endif
#ifdef minor
# undef minor
#endif
struct Version {
uint16_t major;
uint16_t minor;
Version()
: major(0), minor(0) {
}
Version(uint16_t major, uint16_t minor)
: major(major), minor(minor) {
}
};
class HeaderIterator {
public:
virtual ~HeaderIterator() {}
virtual bool valid() const = 0;
virtual std::string name() const = 0;
virtual bool name_equal(std::string const& name) const = 0;
virtual std::string value() const = 0;
virtual void next() = 0;
protected:
HeaderIterator() {}
HeaderIterator(HeaderIterator const&) = delete;
};
class Http {
public:
virtual ~Http() {}
virtual bool good() const = 0;
virtual std::string proto() const = 0;
virtual bool proto_equal(std::string const& proto) const = 0;
virtual Version proto_version() const = 0;
virtual std::unique_ptr<HeaderIterator> header() const = 0;
virtual std::unique_ptr<HeaderIterator> header(
std::string const& name) const = 0;
std::string first_header(std::string const& name) const;
virtual size_t size() const = 0;
protected:
Http() {}
Http(Http const&) = delete;
};
class HttpResponse : public virtual Http {
public:
virtual ~HttpResponse() {}
static HttpResponse* parse(std::string const& data);
static HttpResponse* parse(char const* data, size_t len, bool copy = true);
static HttpResponse* parse(std::shared_ptr<char> data,
size_t offset, size_t len);
virtual uint16_t status_code() const = 0;
virtual std::string status_message() const = 0;
protected:
HttpResponse() {}
HttpResponse(HttpResponse const&) = delete;
};
class HttpRequest : public virtual Http {
public:
virtual ~HttpRequest() {}
static HttpRequest* parse(std::string const& data);
static HttpRequest* parse(char const* data, size_t len, bool copy = true);
static HttpRequest* parse(std::shared_ptr<char> data,
size_t offset, size_t len);
virtual std::string method() const = 0;
virtual bool method_equal(std::string const& method) const = 0;
virtual std::string url() const = 0;
protected:
HttpRequest() {}
HttpRequest(HttpRequest const&) = delete;
};
class HttpResponseBuilder {
public:
virtual ~HttpResponseBuilder() {}
static HttpResponseBuilder* create(
std::string const& proto, Version version,
uint16_t status_code, std::string const& status_message);
virtual void add_header(std::string const& name,
std::string const& value) = 0;
// This will add a content-length header unless there already is one
virtual void set_content(std::string const& content) = 0;
virtual std::string build() const = 0;
protected:
HttpResponseBuilder() {}
HttpResponseBuilder(HttpResponseBuilder const&) = delete;
};
class HttpRequestBuilder {
public:
virtual ~HttpRequestBuilder() {}
static HttpRequestBuilder* create(
std::string const& method, std::string const& url,
std::string const& proto, Version version);
virtual void add_header(std::string const& name,
std::string const& value) = 0;
// This will add a content-length header unless there already is one
virtual void set_content(std::string const& content) = 0;
virtual std::string build() const = 0;
protected:
HttpRequestBuilder() {}
HttpRequestBuilder(HttpRequestBuilder const&) = delete;
};
#endif // HTTP_HH
|