Skip to content

Commit 03ddca5

Browse files
committed
porting rev.1894 to trunk
1 parent 348ca08 commit 03ddca5

13 files changed

Lines changed: 168 additions & 46 deletions

CHANGELOG

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
This is the changelog file for the POCO C++ Libraries.
22

33

4-
Release 1.5.0 (2012-07-30)
4+
Release 1.5.0 (2012-08-??)
55
==========================
66

77
- added JSON
@@ -23,7 +23,7 @@ Release 1.5.0 (2012-07-30)
2323
- IPAddress force IPv6 always lowercase (RFC 5952)
2424
- fixed SF#3538785: SMTPClientSession::sendMessage() should take recipient list
2525

26-
Release 1.4.4 (2012-07-??)
26+
Release 1.4.4 (2012-08-??)
2727
==========================
2828

2929
- ZipStream now builds correctly in unbundled build.
@@ -53,6 +53,10 @@ Release 1.4.4 (2012-07-??)
5353
- Added Poco::ObjectPool class template.
5454
- Poco::Net::HTTPServer has a new stopAll() method allowing stopping/aborting of all
5555
currently active client connections.
56+
- The HTTP server framework now actively prevents sending a message body in the
57+
response to a HEAD request, or in case of a 204 No Content or 304 Not Modified
58+
response status.
59+
- fixed a DOM parser performance bug (patch by Peter Klotz)
5660

5761
Release 1.4.3p1 (2012-01-23)
5862
============================

Net/include/Poco/Net/HTTPFixedLengthStream.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,13 @@ class Net_API HTTPFixedLengthStreamBuf: public HTTPBasicStreamBuf
6363
public:
6464
typedef HTTPBasicStreamBuf::openmode openmode;
6565

66-
HTTPFixedLengthStreamBuf(HTTPSession& session, std::streamsize length, openmode mode);
66+
#if defined(POCO_HAVE_INT64)
67+
typedef Poco::Int64 ContentLength;
68+
#else
69+
typedef std::streamsize ContentLength;
70+
#endif
71+
72+
HTTPFixedLengthStreamBuf(HTTPSession& session, ContentLength length, openmode mode);
6773
~HTTPFixedLengthStreamBuf();
6874

6975
protected:
@@ -72,16 +78,16 @@ class Net_API HTTPFixedLengthStreamBuf: public HTTPBasicStreamBuf
7278

7379
private:
7480
HTTPSession& _session;
75-
std::streamsize _length;
76-
std::streamsize _count;
81+
ContentLength _length;
82+
ContentLength _count;
7783
};
7884

7985

8086
class Net_API HTTPFixedLengthIOS: public virtual std::ios
8187
/// The base class for HTTPFixedLengthInputStream.
8288
{
8389
public:
84-
HTTPFixedLengthIOS(HTTPSession& session, std::streamsize length, HTTPFixedLengthStreamBuf::openmode mode);
90+
HTTPFixedLengthIOS(HTTPSession& session, HTTPFixedLengthStreamBuf::ContentLength length, HTTPFixedLengthStreamBuf::openmode mode);
8591
~HTTPFixedLengthIOS();
8692
HTTPFixedLengthStreamBuf* rdbuf();
8793

@@ -94,7 +100,7 @@ class Net_API HTTPFixedLengthInputStream: public HTTPFixedLengthIOS, public std:
94100
/// This class is for internal use by HTTPSession only.
95101
{
96102
public:
97-
HTTPFixedLengthInputStream(HTTPSession& session, std::streamsize length);
103+
HTTPFixedLengthInputStream(HTTPSession& session, HTTPFixedLengthStreamBuf::ContentLength length);
98104
~HTTPFixedLengthInputStream();
99105

100106
void* operator new(std::size_t size);
@@ -109,7 +115,7 @@ class Net_API HTTPFixedLengthOutputStream: public HTTPFixedLengthIOS, public std
109115
/// This class is for internal use by HTTPSession only.
110116
{
111117
public:
112-
HTTPFixedLengthOutputStream(HTTPSession& session, std::streamsize length);
118+
HTTPFixedLengthOutputStream(HTTPSession& session, HTTPFixedLengthStreamBuf::ContentLength length);
113119
~HTTPFixedLengthOutputStream();
114120

115121
void* operator new(std::size_t size);

Net/include/Poco/Net/HTTPMessage.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ class Net_API HTTPMessage: public MessageHeader
9595
/// always returns a 64-bit integer for content length.
9696
#endif // defined(POCO_HAVE_INT64)
9797

98+
bool hasContentLength() const;
99+
/// Returns true iff a Content-Length header is present.
100+
98101
void setTransferEncoding(const std::string& transferEncoding);
99102
/// Sets the transfer encoding for this message.
100103
///
@@ -192,6 +195,12 @@ inline const std::string& HTTPMessage::getVersion() const
192195
}
193196

194197

198+
inline bool HTTPMessage::hasContentLength() const
199+
{
200+
return has(CONTENT_LENGTH);
201+
}
202+
203+
195204
} } // namespace Poco::Net
196205

197206

Net/include/Poco/Net/HTTPServerRequestImpl.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242

4343
#include "Poco/Net/Net.h"
4444
#include "Poco/Net/HTTPServerRequest.h"
45+
#include "Poco/Net/HTTPServerResponseImpl.h"
4546
#include "Poco/Net/SocketAddress.h"
4647
#include "Poco/AutoPtr.h"
4748
#include <istream>
@@ -64,7 +65,7 @@ class Net_API HTTPServerRequestImpl: public HTTPServerRequest
6465
/// handleRequest() method of HTTPRequestHandler.
6566
{
6667
public:
67-
HTTPServerRequestImpl(HTTPServerResponse& response, HTTPServerSession& session, HTTPServerParams* pParams);
68+
HTTPServerRequestImpl(HTTPServerResponseImpl& response, HTTPServerSession& session, HTTPServerParams* pParams);
6869
/// Creates the HTTPServerRequestImpl, using the
6970
/// given HTTPServerSession.
7071

@@ -105,7 +106,7 @@ class Net_API HTTPServerRequestImpl: public HTTPServerRequest
105106
static const std::string EXPECT;
106107

107108
private:
108-
HTTPServerResponse& _response;
109+
HTTPServerResponseImpl& _response;
109110
HTTPServerSession& _session;
110111
std::istream* _pStream;
111112
Poco::AutoPtr<HTTPServerParams> _pParams;

Net/include/Poco/Net/HTTPServerResponseImpl.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ namespace Net {
4949

5050

5151
class HTTPServerSession;
52-
class HTTPCookie;
52+
class HTTPServerRequestImpl;
5353

5454

5555
class Net_API HTTPServerResponseImpl: public HTTPServerResponse
@@ -128,9 +128,15 @@ class Net_API HTTPServerResponseImpl: public HTTPServerResponse
128128
bool sent() const;
129129
/// Returns true if the response (header) has been sent.
130130

131+
protected:
132+
void attachRequest(HTTPServerRequestImpl* pRequest);
133+
131134
private:
132135
HTTPServerSession& _session;
136+
HTTPServerRequestImpl* _pRequest;
133137
std::ostream* _pStream;
138+
139+
friend class HTTPServerRequestImpl;
134140
};
135141

136142

@@ -143,6 +149,12 @@ inline bool HTTPServerResponseImpl::sent() const
143149
}
144150

145151

152+
inline void HTTPServerResponseImpl::attachRequest(HTTPServerRequestImpl* pRequest)
153+
{
154+
_pRequest = pRequest;
155+
}
156+
157+
146158
} } // namespace Poco::Net
147159

148160

Net/src/HTTPClientSession.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,11 +223,15 @@ std::ostream& HTTPClientSession::sendRequest(HTTPRequest& request)
223223
request.write(hos);
224224
_pRequestStream = new HTTPChunkedOutputStream(*this);
225225
}
226-
else if (request.getContentLength() != HTTPMessage::UNKNOWN_CONTENT_LENGTH)
226+
else if (request.hasContentLength())
227227
{
228228
Poco::CountingOutputStream cs;
229229
request.write(cs);
230+
#if POCO_HAVE_INT64
231+
_pRequestStream = new HTTPFixedLengthOutputStream(*this, request.getContentLength64() + cs.chars());
232+
#else
230233
_pRequestStream = new HTTPFixedLengthOutputStream(*this, request.getContentLength() + cs.chars());
234+
#endif
231235
request.write(*_pRequestStream);
232236
}
233237
else if (request.getMethod() != HTTPRequest::HTTP_PUT && request.getMethod() != HTTPRequest::HTTP_POST)
@@ -284,12 +288,16 @@ std::istream& HTTPClientSession::receiveResponse(HTTPResponse& response)
284288

285289
_mustReconnect = getKeepAlive() && !response.getKeepAlive();
286290

287-
if (!_expectResponseBody)
291+
if (!_expectResponseBody || response.getStatus() < 200 || response.getStatus() == HTTPResponse::HTTP_NO_CONTENT || response.getStatus() == HTTPResponse::HTTP_NOT_MODIFIED)
288292
_pResponseStream = new HTTPFixedLengthInputStream(*this, 0);
289293
else if (response.getChunkedTransferEncoding())
290294
_pResponseStream = new HTTPChunkedInputStream(*this);
291-
else if (response.getContentLength() != HTTPMessage::UNKNOWN_CONTENT_LENGTH)
295+
else if (response.hasContentLength())
296+
#if defined(POCO_HAVE_INT64)
297+
_pResponseStream = new HTTPFixedLengthInputStream(*this, response.getContentLength64());
298+
#else
292299
_pResponseStream = new HTTPFixedLengthInputStream(*this, response.getContentLength());
300+
#endif
293301
else
294302
_pResponseStream = new HTTPInputStream(*this);
295303

Net/src/HTTPFixedLengthStream.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ namespace Net {
5050
//
5151

5252

53-
HTTPFixedLengthStreamBuf::HTTPFixedLengthStreamBuf(HTTPSession& session, std::streamsize length, openmode mode):
53+
HTTPFixedLengthStreamBuf::HTTPFixedLengthStreamBuf(HTTPSession& session, ContentLength length, openmode mode):
5454
HTTPBasicStreamBuf(HTTPBufferAllocator::BUFFER_SIZE, mode),
5555
_session(session),
5656
_length(length),
@@ -70,7 +70,7 @@ int HTTPFixedLengthStreamBuf::readFromDevice(char* buffer, std::streamsize lengt
7070
if (_count < _length)
7171
{
7272
if (_count + length > _length)
73-
length = _length - _count;
73+
length = static_cast<std::streamsize>(_length - _count);
7474
n = _session.read(buffer, length);
7575
if (n > 0) _count += n;
7676
}
@@ -84,7 +84,7 @@ int HTTPFixedLengthStreamBuf::writeToDevice(const char* buffer, std::streamsize
8484
if (_count < _length)
8585
{
8686
if (_count + length > _length)
87-
length = _length - _count;
87+
length = static_cast<std::streamsize>(_length - _count);
8888
n = _session.write(buffer, length);
8989
if (n > 0) _count += n;
9090
}
@@ -97,7 +97,7 @@ int HTTPFixedLengthStreamBuf::writeToDevice(const char* buffer, std::streamsize
9797
//
9898

9999

100-
HTTPFixedLengthIOS::HTTPFixedLengthIOS(HTTPSession& session, std::streamsize length, HTTPFixedLengthStreamBuf::openmode mode):
100+
HTTPFixedLengthIOS::HTTPFixedLengthIOS(HTTPSession& session, HTTPFixedLengthStreamBuf::ContentLength length, HTTPFixedLengthStreamBuf::openmode mode):
101101
_buf(session, length, mode)
102102
{
103103
poco_ios_init(&_buf);
@@ -130,7 +130,7 @@ HTTPFixedLengthStreamBuf* HTTPFixedLengthIOS::rdbuf()
130130
Poco::MemoryPool HTTPFixedLengthInputStream::_pool(sizeof(HTTPFixedLengthInputStream));
131131

132132

133-
HTTPFixedLengthInputStream::HTTPFixedLengthInputStream(HTTPSession& session, std::streamsize length):
133+
HTTPFixedLengthInputStream::HTTPFixedLengthInputStream(HTTPSession& session, HTTPFixedLengthStreamBuf::ContentLength length):
134134
HTTPFixedLengthIOS(session, length, std::ios::in),
135135
std::istream(&_buf)
136136
{
@@ -162,7 +162,7 @@ void HTTPFixedLengthInputStream::operator delete(void* ptr)
162162
Poco::MemoryPool HTTPFixedLengthOutputStream::_pool(sizeof(HTTPFixedLengthOutputStream));
163163

164164

165-
HTTPFixedLengthOutputStream::HTTPFixedLengthOutputStream(HTTPSession& session, std::streamsize length):
165+
HTTPFixedLengthOutputStream::HTTPFixedLengthOutputStream(HTTPSession& session, HTTPFixedLengthStreamBuf::ContentLength length):
166166
HTTPFixedLengthIOS(session, length, std::ios::out),
167167
std::ostream(&_buf)
168168
{

Net/src/HTTPServerConnection.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,15 @@ void HTTPServerConnection::run()
105105
catch (Poco::Exception&)
106106
{
107107
if (!response.sent())
108-
sendErrorResponse(session, HTTPResponse::HTTP_INTERNAL_SERVER_ERROR);
108+
{
109+
try
110+
{
111+
sendErrorResponse(session, HTTPResponse::HTTP_INTERNAL_SERVER_ERROR);
112+
}
113+
catch (...)
114+
{
115+
}
116+
}
109117
throw;
110118
}
111119
}
@@ -140,7 +148,14 @@ void HTTPServerConnection::onServerStopped(const bool& abortCurrent)
140148
{
141149
try
142150
{
151+
// Note: On Windows, select() will not return if one of its socket is being
152+
// shut down. Therefore we have to call close(), which works better.
153+
// On other platforms, we do the more graceful thing.
154+
#if defined(_WIN32)
143155
socket().close();
156+
#else
157+
socket().shutdown();
158+
#endif
144159
}
145160
catch (...)
146161
{
@@ -152,7 +167,11 @@ void HTTPServerConnection::onServerStopped(const bool& abortCurrent)
152167

153168
try
154169
{
170+
#if defined(_WIN32)
155171
socket().close();
172+
#else
173+
socket().shutdown();
174+
#endif
156175
}
157176
catch (...)
158177
{

Net/src/HTTPServerRequestImpl.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535

3636

3737
#include "Poco/Net/HTTPServerRequestImpl.h"
38+
#include "Poco/Net/HTTPServerResponseImpl.h"
3839
#include "Poco/Net/HTTPServerSession.h"
3940
#include "Poco/Net/HTTPHeaderStream.h"
4041
#include "Poco/Net/HTTPStream.h"
@@ -54,12 +55,14 @@ namespace Net {
5455
const std::string HTTPServerRequestImpl::EXPECT("Expect");
5556

5657

57-
HTTPServerRequestImpl::HTTPServerRequestImpl(HTTPServerResponse& response, HTTPServerSession& session, HTTPServerParams* pParams):
58+
HTTPServerRequestImpl::HTTPServerRequestImpl(HTTPServerResponseImpl& response, HTTPServerSession& session, HTTPServerParams* pParams):
5859
_response(response),
5960
_session(session),
6061
_pStream(0),
6162
_pParams(pParams, true)
6263
{
64+
response.attachRequest(this);
65+
6366
HTTPHeaderInputStream hs(session);
6467
read(hs);
6568

@@ -69,8 +72,12 @@ HTTPServerRequestImpl::HTTPServerRequestImpl(HTTPServerResponse& response, HTTPS
6972

7073
if (getChunkedTransferEncoding())
7174
_pStream = new HTTPChunkedInputStream(session);
72-
else if (getContentLength() != HTTPMessage::UNKNOWN_CONTENT_LENGTH)
75+
else if (hasContentLength())
76+
#if defined(POCO_HAVE_INT64)
77+
_pStream = new HTTPFixedLengthInputStream(session, getContentLength64());
78+
#else
7379
_pStream = new HTTPFixedLengthInputStream(session, getContentLength());
80+
#endif
7481
else if (getMethod() == HTTPRequest::HTTP_GET || getMethod() == HTTPRequest::HTTP_HEAD)
7582
_pStream = new HTTPFixedLengthInputStream(session, 0);
7683
else

0 commit comments

Comments
 (0)