Suppress "Expect:" header for POST and PUT. No longer use CURLOPT_COPYPOSTFIELDS.
For POST and PUT, libcurl adds by default a "Expect: 100-continue" header and wait for the server to reply with a 100 response. However, since the server never does that (LL comment in the code "I'm not sure what it means") it's up to libcurl to continue anyway after a while and that part is apparently bugged, causing people not to be able to login sometimes. But suppressing the header, libcurl doesn't wait for it and we worked around this bug. The commit introduces a much improved CurlEasyRequest::setPost method that enforces the above for POST, but that also no longer uses CURLOPT_COPYPOSTFIELDS (but CURLOPT_POSTFIELDS), no longer making a copy of the body of what we are going to send to the server. Instead it uses a new object, derived from AIPostField, to keep track of this data and to dispose of it once the transaction is complete (and no sooner). Copied from llcorehttp, we now also always set a "Connection: keep-alive" and "Keep-alive: 300" header for POST. This was already done for texture downloads (HttpOpRequest), but now we do it always :p. Might need to be changed in the future, but currently those headers are ignored by the server anyway.
This commit is contained in:
@@ -101,7 +101,7 @@ bool Request::post(std::string const& url, headers_t const& headers, std::string
|
||||
llassert_always(success); // AIFIXME: Maybe throw an error.
|
||||
if (!success)
|
||||
return false;
|
||||
buffered_easy_request_w->setPost(NULL, bytes);
|
||||
buffered_easy_request_w->setPost(bytes);
|
||||
buffered_easy_request_w->addHeader("Content-Type: application/octet-stream");
|
||||
buffered_easy_request_w->finalizeRequest(url);
|
||||
|
||||
@@ -129,7 +129,7 @@ bool Request::post(std::string const& url, headers_t const& headers, LLSD const&
|
||||
LLBufferStream buffer_stream(buffer_w->sChannels, buffer_w->getInput().get());
|
||||
LLSDSerialize::toXML(data, buffer_stream);
|
||||
S32 bytes = buffer_w->getInput()->countAfter(buffer_w->sChannels.out(), NULL);
|
||||
buffered_easy_request_w->setPost(NULL, bytes);
|
||||
buffered_easy_request_w->setPost(bytes);
|
||||
buffered_easy_request_w->addHeader("Content-Type: application/llsd+xml");
|
||||
buffered_easy_request_w->finalizeRequest(url);
|
||||
|
||||
|
||||
@@ -168,8 +168,6 @@ public:
|
||||
LLCurl::TransferInfo mTransferInfo;
|
||||
|
||||
std::string mURI;
|
||||
char* mRequestText;
|
||||
int mRequestTextSize;
|
||||
|
||||
std::string mProxyAddress;
|
||||
|
||||
@@ -200,7 +198,6 @@ LLXMLRPCTransaction::Impl::Impl(const std::string& uri,
|
||||
: mCurlEasyRequestStateMachinePtr(NULL),
|
||||
mStatus(LLXMLRPCTransaction::StatusNotStarted),
|
||||
mURI(uri),
|
||||
mRequestText(0),
|
||||
mResponse(0)
|
||||
{
|
||||
init(request, useGzip);
|
||||
@@ -212,7 +209,6 @@ LLXMLRPCTransaction::Impl::Impl(const std::string& uri,
|
||||
: mCurlEasyRequestStateMachinePtr(NULL),
|
||||
mStatus(LLXMLRPCTransaction::StatusNotStarted),
|
||||
mURI(uri),
|
||||
mRequestText(0),
|
||||
mResponse(0)
|
||||
{
|
||||
XMLRPC_REQUEST request = XMLRPC_RequestNew();
|
||||
@@ -223,8 +219,13 @@ LLXMLRPCTransaction::Impl::Impl(const std::string& uri,
|
||||
init(request, useGzip);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Store pointer to data allocated with XMLRPC_REQUEST_ToXML and call XMLRPC_Free to free it upon destruction.
|
||||
class AIXMLRPCData : public AIPostField
|
||||
{
|
||||
public:
|
||||
AIXMLRPCData(char const* allocated_data) : AIPostField(allocated_data) { }
|
||||
/*virtual*/ ~AIXMLRPCData() { XMLRPC_Free(const_cast<char*>(mData)); mData = NULL; }
|
||||
};
|
||||
|
||||
void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip)
|
||||
{
|
||||
@@ -259,12 +260,11 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip)
|
||||
curlEasyRequest_w->setoptString(CURLOPT_ENCODING, "");
|
||||
}
|
||||
|
||||
mRequestText = XMLRPC_REQUEST_ToXML(request, &mRequestTextSize);
|
||||
if (mRequestText)
|
||||
int requestTextSize;
|
||||
char* requestText = XMLRPC_REQUEST_ToXML(request, &requestTextSize);
|
||||
if (requestText)
|
||||
{
|
||||
Dout(dc::curl, "Writing " << mRequestTextSize << " bytes: \"" << libcwd::buf2str(mRequestText, mRequestTextSize) << "\".");;
|
||||
curlEasyRequest_w->setopt(CURLOPT_POSTFIELDSIZE, mRequestTextSize);
|
||||
curlEasyRequest_w->setoptString(CURLOPT_COPYPOSTFIELDS, mRequestText);
|
||||
curlEasyRequest_w->setPost(new AIXMLRPCData(requestText), requestTextSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -298,11 +298,6 @@ LLXMLRPCTransaction::Impl::~Impl()
|
||||
{
|
||||
XMLRPC_RequestFree(mResponse, 1);
|
||||
}
|
||||
|
||||
if (mRequestText)
|
||||
{
|
||||
XMLRPC_Free(mRequestText);
|
||||
}
|
||||
}
|
||||
|
||||
bool LLXMLRPCTransaction::Impl::is_finished(void) const
|
||||
|
||||
Reference in New Issue
Block a user