std::ostream& HTTPClientSession::sendRequest(HTTPRequest& request)
{
	delete _pResponseStream;
	_pResponseStream = 0;

	bool keepAlive = getKeepAlive();
	if ((connected() && !keepAlive) || mustReconnect())
	{
		close();
		_mustReconnect = false;
	}
	try
	{
		if (!connected())
			reconnect();
		if (!keepAlive)
			request.setKeepAlive(false);
		if (!request.has(HTTPRequest::HOST))
			request.setHost(_host, _port);
		if (!_proxyHost.empty())
		{
			request.setURI(proxyRequestPrefix() + request.getURI());
			proxyAuthenticate(request);
		}
		_reconnect = keepAlive;
		_expectResponseBody = request.getMethod() != HTTPRequest::HTTP_HEAD;
		if (request.getChunkedTransferEncoding())
		{
			HTTPHeaderOutputStream hos(*this);
			request.write(hos);
			_pRequestStream = new HTTPChunkedOutputStream(*this);
		}
		else if (request.getContentLength() != HTTPMessage::UNKNOWN_CONTENT_LENGTH)
		{
			Poco::CountingOutputStream cs;
			request.write(cs);
			_pRequestStream = new HTTPFixedLengthOutputStream(*this, request.getContentLength() + cs.chars());
			request.write(*_pRequestStream);
		}
		else if (request.getMethod() != HTTPRequest::HTTP_PUT && request.getMethod() != HTTPRequest::HTTP_POST)
		{
			Poco::CountingOutputStream cs;
			request.write(cs);
			_pRequestStream = new HTTPFixedLengthOutputStream(*this, cs.chars());
			request.write(*_pRequestStream);
		}
		else
		{
			_pRequestStream = new HTTPOutputStream(*this);
			request.write(*_pRequestStream);
		}	
		_lastRequest.update();
		return *_pRequestStream;
	}
	catch (Exception&)
	{
		close();
		throw;
	}
}
void HTTPDigestCredentials::proxyAuthenticate(HTTPRequest& request, const HTTPResponse& response)
{
	proxyAuthenticate(request, HTTPAuthenticationParams(response));
}