1//
2// HTTPMessage.cpp
3//
4// Library: Net
5// Package: HTTP
6// Module: HTTPMessage
7//
8// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
9// and Contributors.
10//
11// SPDX-License-Identifier: BSL-1.0
12//
13
14
15#include "Poco/Net/HTTPMessage.h"
16#include "Poco/Net/MediaType.h"
17#include "Poco/NumberFormatter.h"
18#include "Poco/NumberParser.h"
19#include "Poco/String.h"
20
21
22using Poco::NumberFormatter;
23using Poco::NumberParser;
24using Poco::icompare;
25
26
27namespace Poco {
28namespace Net {
29
30
31const std::string HTTPMessage::HTTP_1_0 = "HTTP/1.0";
32const std::string HTTPMessage::HTTP_1_1 = "HTTP/1.1";
33const std::string HTTPMessage::IDENTITY_TRANSFER_ENCODING = "identity";
34const std::string HTTPMessage::CHUNKED_TRANSFER_ENCODING = "chunked";
35const int HTTPMessage::UNKNOWN_CONTENT_LENGTH = -1;
36const std::string HTTPMessage::UNKNOWN_CONTENT_TYPE;
37const std::string HTTPMessage::CONTENT_LENGTH = "Content-Length";
38const std::string HTTPMessage::CONTENT_TYPE = "Content-Type";
39const std::string HTTPMessage::TRANSFER_ENCODING = "Transfer-Encoding";
40const std::string HTTPMessage::CONNECTION = "Connection";
41const std::string HTTPMessage::PROXY_CONNECTION = "Proxy-Connection";
42const std::string HTTPMessage::CONNECTION_KEEP_ALIVE = "Keep-Alive";
43const std::string HTTPMessage::CONNECTION_CLOSE = "Close";
44const std::string HTTPMessage::EMPTY;
45
46
47HTTPMessage::HTTPMessage():
48 _version(HTTP_1_0)
49{
50}
51
52
53HTTPMessage::HTTPMessage(const std::string& version):
54 _version(version)
55{
56}
57
58
59HTTPMessage::HTTPMessage(const HTTPMessage& other):
60 MessageHeader(other),
61 _version(other._version)
62{
63}
64
65
66HTTPMessage::~HTTPMessage()
67{
68}
69
70
71HTTPMessage& HTTPMessage::operator = (const HTTPMessage& other)
72{
73 if (this != &other)
74 {
75 MessageHeader::operator = (other);
76 _version = other._version;
77 }
78 return *this;
79}
80
81
82void HTTPMessage::setVersion(const std::string& version)
83{
84 _version = version;
85}
86
87
88void HTTPMessage::setContentLength(std::streamsize length)
89{
90 if (length != UNKNOWN_CONTENT_LENGTH)
91 set(CONTENT_LENGTH, NumberFormatter::format(static_cast<Poco::UInt64>(length)));
92 else
93 erase(CONTENT_LENGTH);
94}
95
96
97std::streamsize HTTPMessage::getContentLength() const
98{
99 const std::string& contentLength = get(CONTENT_LENGTH, EMPTY);
100 if (!contentLength.empty())
101 {
102 if (sizeof(std::streamsize) == sizeof(Poco::Int64))
103 return static_cast<std::streamsize>(NumberParser::parse64(contentLength));
104 else
105 return static_cast<std::streamsize>(NumberParser::parse(contentLength));
106 }
107 else return UNKNOWN_CONTENT_LENGTH;
108}
109
110
111#if defined(POCO_HAVE_INT64)
112void HTTPMessage::setContentLength64(Poco::Int64 length)
113{
114 if (length != UNKNOWN_CONTENT_LENGTH)
115 set(CONTENT_LENGTH, NumberFormatter::format(length));
116 else
117 erase(CONTENT_LENGTH);
118}
119
120
121Poco::Int64 HTTPMessage::getContentLength64() const
122{
123 const std::string& contentLength = get(CONTENT_LENGTH, EMPTY);
124 if (!contentLength.empty())
125 {
126 return NumberParser::parse64(contentLength);
127 }
128 else return UNKNOWN_CONTENT_LENGTH;
129}
130#endif // defined(POCO_HAVE_INT64)
131
132
133void HTTPMessage::setTransferEncoding(const std::string& transferEncoding)
134{
135 if (icompare(transferEncoding, IDENTITY_TRANSFER_ENCODING) == 0)
136 erase(TRANSFER_ENCODING);
137 else
138 set(TRANSFER_ENCODING, transferEncoding);
139}
140
141
142const std::string& HTTPMessage::getTransferEncoding() const
143{
144 return get(TRANSFER_ENCODING, IDENTITY_TRANSFER_ENCODING);
145}
146
147
148void HTTPMessage::setChunkedTransferEncoding(bool flag)
149{
150 if (flag)
151 setTransferEncoding(CHUNKED_TRANSFER_ENCODING);
152 else
153 setTransferEncoding(IDENTITY_TRANSFER_ENCODING);
154}
155
156
157bool HTTPMessage::getChunkedTransferEncoding() const
158{
159 return icompare(getTransferEncoding(), CHUNKED_TRANSFER_ENCODING) == 0;
160}
161
162
163void HTTPMessage::setContentType(const std::string& mediaType)
164{
165 if (mediaType.empty())
166 erase(CONTENT_TYPE);
167 else
168 set(CONTENT_TYPE, mediaType);
169}
170
171
172void HTTPMessage::setContentType(const MediaType& mediaType)
173{
174 setContentType(mediaType.toString());
175}
176
177
178const std::string& HTTPMessage::getContentType() const
179{
180 return get(CONTENT_TYPE, UNKNOWN_CONTENT_TYPE);
181}
182
183
184void HTTPMessage::setKeepAlive(bool keepAlive)
185{
186 if (keepAlive)
187 set(CONNECTION, CONNECTION_KEEP_ALIVE);
188 else
189 set(CONNECTION, CONNECTION_CLOSE);
190}
191
192
193bool HTTPMessage::getKeepAlive() const
194{
195 const std::string& connection = get(CONNECTION, EMPTY);
196 if (!connection.empty())
197 return icompare(connection, CONNECTION_CLOSE) != 0;
198 else
199 return getVersion() == HTTP_1_1;
200}
201
202
203} } // namespace Poco::Net
204