mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-23 00:07:59 +02:00
porting rev.1894 to trunk
This commit is contained in:
@@ -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);
|
||||
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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 (...)
|
||||
{
|
||||
|
@@ -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
|
||||
|
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user