-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathHttpMessageGenerator
More file actions
149 lines (123 loc) · 3.18 KB
/
HttpMessageGenerator
File metadata and controls
149 lines (123 loc) · 3.18 KB
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
142
143
144
145
146
147
148
149
/*
* Copyright (C) 2021 Frank Mertens.
*
* Distribution and use is allowed under the terms of the GNU General Public License version 3
* (see CoreComponents/LICENSE-gpl-3.0).
*
*/
#pragma once
#include <cc/TransferMeter>
#include <cc/Format>
#include <cc/Map>
namespace cc {
/** \class HttpMessageGenerator cc/HttpMessageGenerator
* \ingroup http_protocol
* \brief HTTP message generator
*/
class HttpMessageGenerator: public Object
{
public:
/** Create a null HTTP message generator
*/
HttpMessageGenerator() = default;
/** %Set message header \a name to \a value
*/
void setHeader(const String &name, const String &value)
{
me().setHeader(name, value);
}
/** Transmit HTTP message without payload
*/
void transmit()
{
me().transmit();
}
/** Transmit HTTP message with attached \a payload
*/
void transmit(const String &payload)
{
me().transmit(payload);
}
/** Transmit HTTP message and stream the payload from \a source
*/
void transmit(const Stream &source)
{
me().transmit(source);
}
/** %Set a custom message header
*/
void setHeader(const Map<String, String> &header)
{
me().setHeader(header);
}
/** Begin message transmission
*/
void beginTransmission(long long contentLength = -1)
{
me().beginTransmission(contentLength);
}
/** Get access to the payload stream
*/
Stream payload()
{
return me().payload();
}
/** Write \a data to the payload stream
*/
void write(const Bytes &data)
{
me().write(data);
}
/** Create a new payload chunk with given format \a pattern
*/
Format chunk(const String &pattern)
{
return me().chunk(pattern);
}
/** Create a new payload chunk
*/
Format chunk()
{
return me().chunk();
}
/** End of message transmission
*/
void endTransmission()
{
me().endTransmission();
}
protected:
struct State: public Object::State
{
void setHeader(const String &name, const String &value);
void transmit();
void transmit(const String &payload);
void transmit(const Stream &source);
void setHeader(const Map<String, String> &header);
void beginTransmission(long long contentLength = -1);
Stream payload();
void write(const Bytes &data);
Format chunk(const String &pattern);
Format chunk();
void endTransmission();
protected:
State(const Stream &stream):
stream_{stream}
{}
virtual void polishHeader() = 0;
virtual void writeFirstLine(Format &sink) = 0;
void writeHeader();
Stream stream_;
Map<String, String> header_;
bool headerWritten_ { false };
TransferMeter payload_;
long long contentLength_ { -1 };
long long bytesWritten_ { 0 };
};
HttpMessageGenerator(State *newState):
Object{newState}
{}
State &me() { return Object::me.as<State>(); }
const State &me() const { return Object::me.as<State>(); }
};
} // namespace cc