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::CONNECTION_KEEP_ALIVE = "Keep-Alive";
42const std::string HTTPMessage::CONNECTION_CLOSE = "Close";
43const std::string HTTPMessage::EMPTY;
44
45
46HTTPMessage::HTTPMessage():
47 _version(HTTP_1_0)
48{
49}
50
51
52HTTPMessage::HTTPMessage(const std::string& version):
53 _version(version)
54{
55}
56
57
58HTTPMessage::~HTTPMessage()
59{
60}
61
62
63void HTTPMessage::setVersion(const std::string& version)
64{
65 _version = version;
66}
67
68
69void HTTPMessage::setContentLength(std::streamsize length)
70{
71 if (length != UNKNOWN_CONTENT_LENGTH)
72 set(CONTENT_LENGTH, NumberFormatter::format(static_cast<Poco::UInt64>(length)));
73 else
74 erase(CONTENT_LENGTH);
75}
76
77
78std::streamsize HTTPMessage::getContentLength() const
79{
80 const std::string& contentLength = get(CONTENT_LENGTH, EMPTY);
81 if (!contentLength.empty())
82 {
83 if (sizeof(std::streamsize) == sizeof(Poco::Int64))
84 return static_cast<std::streamsize>(NumberParser::parse64(contentLength));
85 else
86 return static_cast<std::streamsize>(NumberParser::parse(contentLength));
87 }
88 else return UNKNOWN_CONTENT_LENGTH;
89}
90
91
92#if defined(POCO_HAVE_INT64)
93void HTTPMessage::setContentLength64(Poco::Int64 length)
94{
95 if (length != UNKNOWN_CONTENT_LENGTH)
96 set(CONTENT_LENGTH, NumberFormatter::format(length));
97 else
98 erase(CONTENT_LENGTH);
99}
100
101
102Poco::Int64 HTTPMessage::getContentLength64() const
103{
104 const std::string& contentLength = get(CONTENT_LENGTH, EMPTY);
105 if (!contentLength.empty())
106 {
107 return NumberParser::parse64(contentLength);
108 }
109 else return UNKNOWN_CONTENT_LENGTH;
110}
111#endif // defined(POCO_HAVE_INT64)
112
113
114void HTTPMessage::setTransferEncoding(const std::string& transferEncoding)
115{
116 if (icompare(transferEncoding, IDENTITY_TRANSFER_ENCODING) == 0)
117 erase(TRANSFER_ENCODING);
118 else
119 set(TRANSFER_ENCODING, transferEncoding);
120}
121
122
123const std::string& HTTPMessage::getTransferEncoding() const
124{
125 return get(TRANSFER_ENCODING, IDENTITY_TRANSFER_ENCODING);
126}
127
128
129void HTTPMessage::setChunkedTransferEncoding(bool flag)
130{
131 if (flag)
132 setTransferEncoding(CHUNKED_TRANSFER_ENCODING);
133 else
134 setTransferEncoding(IDENTITY_TRANSFER_ENCODING);
135}
136
137
138bool HTTPMessage::getChunkedTransferEncoding() const
139{
140 return icompare(getTransferEncoding(), CHUNKED_TRANSFER_ENCODING) == 0;
141}
142
143
144void HTTPMessage::setContentType(const std::string& mediaType)
145{
146 if (mediaType.empty())
147 erase(CONTENT_TYPE);
148 else
149 set(CONTENT_TYPE, mediaType);
150}
151
152
153void HTTPMessage::setContentType(const MediaType& mediaType)
154{
155 setContentType(mediaType.toString());
156}
157
158
159const std::string& HTTPMessage::getContentType() const
160{
161 return get(CONTENT_TYPE, UNKNOWN_CONTENT_TYPE);
162}
163
164
165void HTTPMessage::setKeepAlive(bool keepAlive)
166{
167 if (keepAlive)
168 set(CONNECTION, CONNECTION_KEEP_ALIVE);
169 else
170 set(CONNECTION, CONNECTION_CLOSE);
171}
172
173
174bool HTTPMessage::getKeepAlive() const
175{
176 const std::string& connection = get(CONNECTION, EMPTY);
177 if (!connection.empty())
178 return icompare(connection, CONNECTION_CLOSE) != 0;
179 else
180 return getVersion() == HTTP_1_1;
181}
182
183
184} } // namespace Poco::Net
185