porting rev.1894 to trunk

This commit is contained in:
Aleksandar Fabijanic
2012-07-27 02:01:39 +00:00
parent 348ca08e7a
commit 03ddca58f5
13 changed files with 168 additions and 46 deletions

View File

@@ -223,11 +223,15 @@ std::ostream& HTTPClientSession::sendRequest(HTTPRequest& request)
request.write(hos);
_pRequestStream = new HTTPChunkedOutputStream(*this);
}
else if (request.getContentLength() != HTTPMessage::UNKNOWN_CONTENT_LENGTH)
else if (request.hasContentLength())
{
Poco::CountingOutputStream cs;
request.write(cs);
#if POCO_HAVE_INT64
_pRequestStream = new HTTPFixedLengthOutputStream(*this, request.getContentLength64() + cs.chars());
#else
_pRequestStream = new HTTPFixedLengthOutputStream(*this, request.getContentLength() + cs.chars());
#endif
request.write(*_pRequestStream);
}
else if (request.getMethod() != HTTPRequest::HTTP_PUT && request.getMethod() != HTTPRequest::HTTP_POST)
@@ -284,12 +288,16 @@ std::istream& HTTPClientSession::receiveResponse(HTTPResponse& response)
_mustReconnect = getKeepAlive() && !response.getKeepAlive();
if (!_expectResponseBody)
if (!_expectResponseBody || response.getStatus() < 200 || response.getStatus() == HTTPResponse::HTTP_NO_CONTENT || response.getStatus() == HTTPResponse::HTTP_NOT_MODIFIED)
_pResponseStream = new HTTPFixedLengthInputStream(*this, 0);
else if (response.getChunkedTransferEncoding())
_pResponseStream = new HTTPChunkedInputStream(*this);
else if (response.getContentLength() != HTTPMessage::UNKNOWN_CONTENT_LENGTH)
else if (response.hasContentLength())
#if defined(POCO_HAVE_INT64)
_pResponseStream = new HTTPFixedLengthInputStream(*this, response.getContentLength64());
#else
_pResponseStream = new HTTPFixedLengthInputStream(*this, response.getContentLength());
#endif
else
_pResponseStream = new HTTPInputStream(*this);

View File

@@ -50,7 +50,7 @@ namespace Net {
//
HTTPFixedLengthStreamBuf::HTTPFixedLengthStreamBuf(HTTPSession& session, std::streamsize length, openmode mode):
HTTPFixedLengthStreamBuf::HTTPFixedLengthStreamBuf(HTTPSession& session, ContentLength length, openmode mode):
HTTPBasicStreamBuf(HTTPBufferAllocator::BUFFER_SIZE, mode),
_session(session),
_length(length),
@@ -70,7 +70,7 @@ int HTTPFixedLengthStreamBuf::readFromDevice(char* buffer, std::streamsize lengt
if (_count < _length)
{
if (_count + length > _length)
length = _length - _count;
length = static_cast<std::streamsize>(_length - _count);
n = _session.read(buffer, length);
if (n > 0) _count += n;
}
@@ -84,7 +84,7 @@ int HTTPFixedLengthStreamBuf::writeToDevice(const char* buffer, std::streamsize
if (_count < _length)
{
if (_count + length > _length)
length = _length - _count;
length = static_cast<std::streamsize>(_length - _count);
n = _session.write(buffer, length);
if (n > 0) _count += n;
}
@@ -97,7 +97,7 @@ int HTTPFixedLengthStreamBuf::writeToDevice(const char* buffer, std::streamsize
//
HTTPFixedLengthIOS::HTTPFixedLengthIOS(HTTPSession& session, std::streamsize length, HTTPFixedLengthStreamBuf::openmode mode):
HTTPFixedLengthIOS::HTTPFixedLengthIOS(HTTPSession& session, HTTPFixedLengthStreamBuf::ContentLength length, HTTPFixedLengthStreamBuf::openmode mode):
_buf(session, length, mode)
{
poco_ios_init(&_buf);
@@ -130,7 +130,7 @@ HTTPFixedLengthStreamBuf* HTTPFixedLengthIOS::rdbuf()
Poco::MemoryPool HTTPFixedLengthInputStream::_pool(sizeof(HTTPFixedLengthInputStream));
HTTPFixedLengthInputStream::HTTPFixedLengthInputStream(HTTPSession& session, std::streamsize length):
HTTPFixedLengthInputStream::HTTPFixedLengthInputStream(HTTPSession& session, HTTPFixedLengthStreamBuf::ContentLength length):
HTTPFixedLengthIOS(session, length, std::ios::in),
std::istream(&_buf)
{
@@ -162,7 +162,7 @@ void HTTPFixedLengthInputStream::operator delete(void* ptr)
Poco::MemoryPool HTTPFixedLengthOutputStream::_pool(sizeof(HTTPFixedLengthOutputStream));
HTTPFixedLengthOutputStream::HTTPFixedLengthOutputStream(HTTPSession& session, std::streamsize length):
HTTPFixedLengthOutputStream::HTTPFixedLengthOutputStream(HTTPSession& session, HTTPFixedLengthStreamBuf::ContentLength length):
HTTPFixedLengthIOS(session, length, std::ios::out),
std::ostream(&_buf)
{

View File

@@ -105,7 +105,15 @@ void HTTPServerConnection::run()
catch (Poco::Exception&)
{
if (!response.sent())
sendErrorResponse(session, HTTPResponse::HTTP_INTERNAL_SERVER_ERROR);
{
try
{
sendErrorResponse(session, HTTPResponse::HTTP_INTERNAL_SERVER_ERROR);
}
catch (...)
{
}
}
throw;
}
}
@@ -140,7 +148,14 @@ void HTTPServerConnection::onServerStopped(const bool& abortCurrent)
{
try
{
// Note: On Windows, select() will not return if one of its socket is being
// shut down. Therefore we have to call close(), which works better.
// On other platforms, we do the more graceful thing.
#if defined(_WIN32)
socket().close();
#else
socket().shutdown();
#endif
}
catch (...)
{
@@ -152,7 +167,11 @@ void HTTPServerConnection::onServerStopped(const bool& abortCurrent)
try
{
#if defined(_WIN32)
socket().close();
#else
socket().shutdown();
#endif
}
catch (...)
{

View File

@@ -35,6 +35,7 @@
#include "Poco/Net/HTTPServerRequestImpl.h"
#include "Poco/Net/HTTPServerResponseImpl.h"
#include "Poco/Net/HTTPServerSession.h"
#include "Poco/Net/HTTPHeaderStream.h"
#include "Poco/Net/HTTPStream.h"
@@ -54,12 +55,14 @@ namespace Net {
const std::string HTTPServerRequestImpl::EXPECT("Expect");
HTTPServerRequestImpl::HTTPServerRequestImpl(HTTPServerResponse& response, HTTPServerSession& session, HTTPServerParams* pParams):
HTTPServerRequestImpl::HTTPServerRequestImpl(HTTPServerResponseImpl& response, HTTPServerSession& session, HTTPServerParams* pParams):
_response(response),
_session(session),
_pStream(0),
_pParams(pParams, true)
{
response.attachRequest(this);
HTTPHeaderInputStream hs(session);
read(hs);
@@ -69,8 +72,12 @@ HTTPServerRequestImpl::HTTPServerRequestImpl(HTTPServerResponse& response, HTTPS
if (getChunkedTransferEncoding())
_pStream = new HTTPChunkedInputStream(session);
else if (getContentLength() != HTTPMessage::UNKNOWN_CONTENT_LENGTH)
else if (hasContentLength())
#if defined(POCO_HAVE_INT64)
_pStream = new HTTPFixedLengthInputStream(session, getContentLength64());
#else
_pStream = new HTTPFixedLengthInputStream(session, getContentLength());
#endif
else if (getMethod() == HTTPRequest::HTTP_GET || getMethod() == HTTPRequest::HTTP_HEAD)
_pStream = new HTTPFixedLengthInputStream(session, 0);
else

View File

@@ -35,6 +35,7 @@
#include "Poco/Net/HTTPServerResponseImpl.h"
#include "Poco/Net/HTTPServerRequestImpl.h"
#include "Poco/Net/HTTPServerSession.h"
#include "Poco/Net/HTTPHeaderStream.h"
#include "Poco/Net/HTTPStream.h"
@@ -66,6 +67,7 @@ namespace Net {
HTTPServerResponseImpl::HTTPServerResponseImpl(HTTPServerSession& session):
_session(session),
_pRequest(0),
_pStream(0)
{
}
@@ -88,17 +90,31 @@ std::ostream& HTTPServerResponseImpl::send()
{
poco_assert (!_pStream);
if (getChunkedTransferEncoding())
if (_pRequest && _pRequest->getMethod() == HTTPRequest::HTTP_HEAD ||
getStatus() < 200 ||
getStatus() == HTTPResponse::HTTP_NO_CONTENT ||
getStatus() == HTTPResponse::HTTP_NOT_MODIFIED)
{
Poco::CountingOutputStream cs;
write(cs);
_pStream = new HTTPFixedLengthOutputStream(_session, cs.chars());
write(*_pStream);
}
else if (getChunkedTransferEncoding())
{
HTTPHeaderOutputStream hs(_session);
write(hs);
_pStream = new HTTPChunkedOutputStream(_session);
}
else if (getContentLength() != HTTPMessage::UNKNOWN_CONTENT_LENGTH)
else if (hasContentLength())
{
Poco::CountingOutputStream cs;
write(cs);
#if defined(POCO_HAVE_INT64)
_pStream = new HTTPFixedLengthOutputStream(_session, getContentLength64() + cs.chars());
#else
_pStream = new HTTPFixedLengthOutputStream(_session, getContentLength() + cs.chars());
#endif
write(*_pStream);
}
else
@@ -132,7 +148,10 @@ void HTTPServerResponseImpl::sendFile(const std::string& path, const std::string
{
_pStream = new HTTPHeaderOutputStream(_session);
write(*_pStream);
StreamCopier::copyStream(istr, *_pStream);
if (_pRequest && _pRequest->getMethod() != HTTPRequest::HTTP_HEAD)
{
StreamCopier::copyStream(istr, *_pStream);
}
}
else throw OpenFileException(path);
}
@@ -147,7 +166,10 @@ void HTTPServerResponseImpl::sendBuffer(const void* pBuffer, std::size_t length)
_pStream = new HTTPHeaderOutputStream(_session);
write(*_pStream);
_pStream->write(static_cast<const char*>(pBuffer), static_cast<std::streamsize>(length));
if (_pRequest && _pRequest->getMethod() != HTTPRequest::HTTP_HEAD)
{
_pStream->write(static_cast<const char*>(pBuffer), static_cast<std::streamsize>(length));
}
}

View File

@@ -523,6 +523,7 @@ bool SocketImpl::poll(const Poco::Timespan& timeout, int mode)
FD_SET(sockfd, &fdExcept);
}
Poco::Timespan remainingTime(timeout);
int errorCode;
int rc;
do
{
@@ -531,7 +532,7 @@ bool SocketImpl::poll(const Poco::Timespan& timeout, int mode)
tv.tv_usec = (long) remainingTime.useconds();
Poco::Timestamp start;
rc = ::select(int(sockfd) + 1, &fdRead, &fdWrite, &fdExcept, &tv);
if (rc < 0 && lastError() == POCO_EINTR)
if (rc < 0 && (errorCode = lastError()) == POCO_EINTR)
{
Poco::Timestamp end;
Poco::Timespan waited = end - start;
@@ -541,8 +542,8 @@ bool SocketImpl::poll(const Poco::Timespan& timeout, int mode)
remainingTime = 0;
}
}
while (rc < 0 && lastError() == POCO_EINTR);
if (rc < 0) error();
while (rc < 0 && errorCode == POCO_EINTR);
if (rc < 0) error(errorCode);
return rc > 0;
#endif // POCO_HAVE_FD_EPOLL