Message.h
1/*
2 * Copyright (C) 2012 by Marc Boris Duerner
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * As a special exception, you may use this file as part of a free
10 * software library without restriction. Specifically, if other files
11 * instantiate templates or use macros or inline functions from this
12 * file, or you compile this file and link it with other files to
13 * produce an executable, this file does not by itself cause the
14 * resulting executable to be covered by the GNU General Public
15 * License. This exception does not however invalidate any other
16 * reasons why the executable file might be covered by the GNU Library
17 * General Public License.
18 *
19 * This library is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Lesser General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with this library; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29#ifndef Pt_Http_Message_h
30#define Pt_Http_Message_h
31
32#include <Pt/Http/Api.h>
33#include <Pt/NonCopyable.h>
34#include <iostream>
35#include <streambuf>
36#include <string>
37#include <cstring>
38#include <cstddef>
39
40namespace Pt {
41
42namespace Http {
43
44class Connection;
45
73class PT_HTTP_API MessageHeader : private Pt::NonCopyable
74{
75 public:
78 class Field
79 {
80 public:
84 : _name(0)
85 , _value(0)
86 {}
87
90 Field(const char* f, const char* s)
91 : _name(f)
92 , _value(s)
93 {}
94
97 const char* name() const
98 { return _name; }
99
102 void setName(const char* name)
103 { _name = name; }
104
107 const char* value() const
108 { return _value; }
109
112 void setValue(const char* value)
113 { _value = value; }
114
115 private:
116 const char* _name;
117 const char* _value;
118 };
119
123 {
124 friend class MessageHeader;
125
126 public:
130 { }
131
132 explicit ConstIterator(const char* p)
133 : current(p, p)
134 {
135 fixup();
136 }
137
140 bool operator== (const ConstIterator& it) const
141 { return current.name() == it.current.name(); }
142
145 bool operator!= (const ConstIterator& it) const
146 { return current.name() != it.current.name(); }
147
151 {
152 moveForward();
153 return *this;
154 }
155
159 {
160 ConstIterator ret = *this;
161 moveForward();
162 return ret;
163 }
164
167 const Field& operator*() const
168 { return current; }
169
172 const Field* operator->() const
173 { return &current; }
174
175 private:
177 void fixup()
178 {
179 if( *current.name() )
180 {
181 current.setValue( current.name() + std::strlen(current.name()) + 1 );
182 }
183 else
184 {
185 current.setName(0);
186 current.setValue(0);
187 }
188 }
189
191 void moveForward()
192 {
193 current.setName( current.value() + std::strlen(current.value()) + 1 );
194 fixup();
195 }
196
197 private:
198 Field current;
199 };
200
201 public:
205
209
212 void clear();
213
216 void set(const char* key, const char* value);
217
220 void add(const char* key, const char* value);
221
224 void remove(const char* key);
225
228 const char* get(const char* key) const;
229
232 bool has(const char* key) const
233 { return get(key) != 0; }
234
237 bool isSet(const char* key, const char* value) const;
238
242 { return ConstIterator(_rawdata); }
243
247 { return ConstIterator(); }
248
251 unsigned versionMajor() const
252 { return _httpVersionMajor; }
253
256 unsigned versionMinor() const
257 { return _httpVersionMinor; }
258
261 void setVersion(unsigned major, unsigned minor)
262 {
263 _httpVersionMajor = major;
264 _httpVersionMinor = minor;
265 }
266
269 bool isChunked() const;
270
273 std::size_t contentLength() const;
274
277 bool isKeepAlive() const;
278
282
285 bool isUpgrade() const;
286
290
295 static char* htdateCurrent(char* buffer);
296
297 private:
299 char* eptr()
300 { return _rawdata + _endOffset; }
301
302 private:
303 static const unsigned MaxHeaderSize = 4096;
304 char _rawdata[MaxHeaderSize]; // key_1\0value_1\0key_2\0value_2\0...key_n\0value_n\0\0
305 std::size_t _endOffset;
306 unsigned _httpVersionMajor;
307 unsigned _httpVersionMinor;
308};
309
337{
338 private:
340 enum Result
341 {
342 InProgress = 1,
343 Header = 2,
344 Body = 4,
345 Finished = 8,
346 Trailer = 16, // NOTE: questionable if we need this
347 };
348
349 public:
353 : _result(InProgress)
354 {}
355
358 bool header() const
359 { return (_result & Header) == Header; }
360
363 bool body() const
364 { return (_result & Body) == Body; }
365
368 bool trailer() const
369 { return (_result & Trailer) == Trailer; }
370
373 bool finished() const
374 { return (_result & Finished) == Finished; }
375
377 void setFinished()
378 { _result |= Finished ; }
379
381 void setHeader()
382 { _result |= Header; }
383
385 void setBody()
386 { _result |= Body; }
387
389 void setTrailer()
390 { _result |= Trailer; }
391
393 unsigned long mask() const
394 { return _result; }
395
396 private:
397 unsigned long _result;
398};
399
403class MessageBuffer : public std::streambuf
404{
405 public:
407 MessageBuffer();
408
410 ~MessageBuffer();
411
413 void discard()
414 {
415 this->setp(_buffer, _buffer + _bufferSize);
416 this->setg(0,0,0);
417 }
418
420 std::size_t size() const
421 { return pptr() - pbase(); }
422
424 const char* data() const
425 { return _buffer; }
426
427 protected:
428 // @internal
429 virtual int_type overflow(int_type ch);
430
431 // @internal
432 virtual int_type underflow();
433
434 private:
435 static const unsigned int BufferSize = 512;
436 char* _buffer;
437 std::size_t _bufferSize;
438};
439
459class PT_HTTP_API Message
460{
461 friend class Connection;
462
463 public:
465 explicit Message(Http::Connection& conn);
466
468 Connection& connection()
469 { return *_conn; }
470
473 { return _header; }
474
476 const MessageHeader& header() const
477 { return _header; }
478
480 std::iostream& body()
481 { return _ios; }
482
484 std::size_t available() const;
485
487 std::size_t pending() const;
488
490 void discard();
491
493 bool isSending() const
494 { return _isSending; }
495
497 bool isReceiving() const
498 { return _isReceiving; }
499
501 bool isFinished() const
502 { return _finished; }
503
505 MessageBuffer& buffer()
506 { return _buf; }
507
508 protected:
510 void setBuffer(std::streambuf& sb)
511 { _ios.rdbuf(&sb); }
512
514 void setSending(bool b)
515 { _isSending = b; }
516
518 void setReceiving(bool b)
519 { _isReceiving = b; }
520
522 void setFinished(bool b)
523 { _finished = b; }
524
525 private:
526 Http::Connection* _conn;
527 MessageHeader _header;
528 MessageBuffer _buf;
529 std::iostream _ios;
530 bool _isSending;
531 bool _isReceiving;
532 bool _finished;
533};
534
535} // namespace Http
536
537} // namespace Pt
538
539#endif // Pt_Http_Message_h
HTTP header field iterator.
Definition Message.h:123
const Field & operator*() const
Returns the header field.
Definition Message.h:167
const Field * operator->() const
Returns the header field.
Definition Message.h:172
ConstIterator operator++(int)
Advance the iterator.
Definition Message.h:158
ConstIterator & operator++()
Advance the iterator.
Definition Message.h:150
ConstIterator()
Default constructor.
Definition Message.h:129
Field of a HTTP header.
Definition Message.h:79
Field()
Default constructor.
Definition Message.h:83
void setValue(const char *value)
Sets the field value.
Definition Message.h:112
const char * value() const
Returns the field value.
Definition Message.h:107
Field(const char *f, const char *s)
Construct with field name and value.
Definition Message.h:90
const char * name() const
Returns the field name.
Definition Message.h:97
void setName(const char *name)
Sets the field name.
Definition Message.h:102
HTTP message header.
Definition Message.h:74
const char * get(const char *key) const
Returns a field value.
bool isUpgrade() const
Returns true if the Upgrade header is set.
void setKeepAlive()
Sets the HTTP keep-alive header.
void setUpgrade()
Sets the Upgrade header.
void add(const char *key, const char *value)
Adds a header field.
~MessageHeader()
Destructor.
std::size_t contentLength() const
Returns the content length.
bool has(const char *key) const
Returns true if the field is present.
Definition Message.h:232
void set(const char *key, const char *value)
Sets a header field.
unsigned versionMajor() const
Returns the major HTTP version number.
Definition Message.h:251
ConstIterator end() const
Returns the end of the header fields.
Definition Message.h:246
bool isSet(const char *key, const char *value) const
Returns true if the field is set to the value.
void setVersion(unsigned major, unsigned minor)
Sets the HTTP version number.
Definition Message.h:261
static char * htdateCurrent(char *buffer)
Writes a current HTTP date into buffer.
MessageHeader()
Default constructor.
bool isKeepAlive() const
Returns true if HTTP keep-alive is set.
void clear()
Clears all content.
unsigned versionMinor() const
Returns the minor HTTP version number.
Definition Message.h:256
ConstIterator begin() const
Returns the begin of the header fields.
Definition Message.h:241
bool isChunked() const
Returns true if chunked encoding is set.
void remove(const char *key)
Removes a header field.
bool body() const
Returns true if the body was processed.
Definition Message.h:363
MessageProgress()
Default Constructor.
Definition Message.h:352
bool trailer() const
Returns true if the trailer was processed.
Definition Message.h:368
bool header() const
Returns true if the header was processed.
Definition Message.h:358
bool finished() const
Returns true if message is complete.
Definition Message.h:373
const MessageHeader & header() const
Returns the header of the message.
Definition Message.h:476
void discard()
Discards the message body.
std::iostream & body()
Returns the body of the message.
Definition Message.h:480
Message(Http::Connection &conn)
Constructs with connection to use.
MessageHeader & header()
Returns the header of the message.
Definition Message.h:472
std::size_t pending() const
Returns the number of bytes pending to be written.
Connection & connection()
Returns the used connection.
Definition Message.h:468
std::size_t available() const
Returns the number of bytes available to read.
Base class that disables copy construction and assignment.
Definition NonCopyable.h:59
void fixup(const FixupInfo &fixup, T *&fixme)
Fixup references during serialization.
Definition FixupInfo.h:136
HTTP clients and servers.
Core module.
Definition Allocator.h:33