MAINT-5507: Remove HTTPClient and related cruft.

master
Rider Linden 2015-09-14 11:15:23 -07:00
parent f2da6ec2ac
commit 97236a42ca
30 changed files with 7 additions and 1360 deletions

View File

@ -48,7 +48,6 @@ set(llmessage_SOURCE_FILES
llexperiencecache.cpp
llfiltersd2xmlrpc.cpp
llhost.cpp
llhttpclient.cpp
llhttpconstants.cpp
llhttpnode.cpp
llhttpsdhandler.cpp
@ -140,8 +139,6 @@ set(llmessage_HEADER_FILES
llfiltersd2xmlrpc.h
llfollowcamparams.h
llhost.h
llhttpclient.h
llhttpclientinterface.h
llhttpconstants.h
llhttpnode.h
llhttpnodeadapter.h

View File

@ -46,6 +46,10 @@ using namespace LLCore;
namespace LLCoreHttpUtil
{
const F32 HTTP_REQUEST_EXPIRY_SECS = 60.0f;
void logMessageSuccess(std::string logAuth, std::string url, std::string message)
{
LL_INFOS() << logAuth << " Success '" << message << "' for " << url << LL_ENDL;

View File

@ -57,6 +57,7 @@
///
namespace LLCoreHttpUtil
{
extern const F32 HTTP_REQUEST_EXPIRY_SECS;
/// Attempt to convert a response object's contents to LLSD.
/// It is expected that the response body will be of non-zero

View File

@ -26,7 +26,6 @@
#include "llexperiencecache.h"
#include "llavatarname.h"
#include "llhttpclient.h"
#include "llsdserialize.h"
#include "llcoros.h"
#include "lleventcoro.h"

View File

@ -1,677 +0,0 @@
/**
* @file llhttpclient.cpp
* @brief Implementation of classes for making HTTP requests.
*
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include <openssl/x509_vfy.h>
#include "llhttpclient.h"
#include "llassetstorage.h"
#include "lliopipe.h"
#include "llurlrequest.h"
#include "llbufferstream.h"
#include "llsdserialize.h"
#include "llvfile.h"
#include "llvfs.h"
#include "lluri.h"
#include "message.h"
#include "httpcommon.h"
#include "httprequest.h"
#include "httpoptions.h"
#include <curl/curl.h>
const F32 HTTP_REQUEST_EXPIRY_SECS = 60.0f;
LLURLRequest::SSLCertVerifyCallback LLHTTPClient::mCertVerifyCallback = NULL;
////////////////////////////////////////////////////////////////////////////
// Responder class moved to LLCurl
namespace
{
class LLHTTPClientURLAdaptor : public LLURLRequestComplete
{
public:
LLHTTPClientURLAdaptor(LLCurl::ResponderPtr responder)
: LLURLRequestComplete(), mResponder(responder), mStatus(HTTP_INTERNAL_ERROR),
mReason("LLURLRequest complete w/no status")
{
}
~LLHTTPClientURLAdaptor()
{
}
virtual void httpStatus(S32 status, const std::string& reason)
{
LLURLRequestComplete::httpStatus(status,reason);
mStatus = status;
mReason = reason;
}
virtual void complete(const LLChannelDescriptors& channels,
const buffer_ptr_t& buffer)
{
// *TODO: Re-interpret mRequestStatus codes?
// Would like to detect curl errors, such as
// connection errors, write erros, etc.
if (mResponder.get())
{
mResponder->setResult(mStatus, mReason);
mResponder->completedRaw(channels, buffer);
}
}
virtual void header(const std::string& header, const std::string& value)
{
if (mResponder.get())
{
mResponder->setResponseHeader(header, value);
}
}
private:
LLCurl::ResponderPtr mResponder;
S32 mStatus;
std::string mReason;
};
class Injector : public LLIOPipe
{
public:
virtual const std::string& contentType() = 0;
};
class LLSDInjector : public Injector
{
public:
LLSDInjector(const LLSD& sd) : mSD(sd) {}
virtual ~LLSDInjector() {}
const std::string& contentType() { return HTTP_CONTENT_LLSD_XML; }
virtual EStatus process_impl(const LLChannelDescriptors& channels,
buffer_ptr_t& buffer, bool& eos, LLSD& context, LLPumpIO* pump)
{
LLBufferStream ostream(channels, buffer.get());
LLSDSerialize::toXML(mSD, ostream);
eos = true;
return STATUS_DONE;
}
const LLSD mSD;
};
class RawInjector : public Injector
{
public:
RawInjector(const U8* data, S32 size) : mData(data), mSize(size) {}
virtual ~RawInjector() {delete [] mData;}
const std::string& contentType() { return HTTP_CONTENT_OCTET_STREAM; }
virtual EStatus process_impl(const LLChannelDescriptors& channels,
buffer_ptr_t& buffer, bool& eos, LLSD& context, LLPumpIO* pump)
{
LLBufferStream ostream(channels, buffer.get());
ostream.write((const char *)mData, mSize); // hopefully chars are always U8s
eos = true;
return STATUS_DONE;
}
const U8* mData;
S32 mSize;
};
class FileInjector : public Injector
{
public:
FileInjector(const std::string& filename) : mFilename(filename) {}
virtual ~FileInjector() {}
const std::string& contentType() { return HTTP_CONTENT_OCTET_STREAM; }
virtual EStatus process_impl(const LLChannelDescriptors& channels,
buffer_ptr_t& buffer, bool& eos, LLSD& context, LLPumpIO* pump)
{
LLBufferStream ostream(channels, buffer.get());
llifstream fstream(mFilename.c_str(), std::iostream::binary | std::iostream::out);
if(fstream.is_open())
{
fstream.seekg(0, std::ios::end);
U32 fileSize = (U32)fstream.tellg();
fstream.seekg(0, std::ios::beg);
std::vector<char> fileBuffer(fileSize);
fstream.read(&fileBuffer[0], fileSize);
ostream.write(&fileBuffer[0], fileSize);
fstream.close();
eos = true;
return STATUS_DONE;
}
return STATUS_ERROR;
}
const std::string mFilename;
};
class VFileInjector : public Injector
{
public:
VFileInjector(const LLUUID& uuid, LLAssetType::EType asset_type) : mUUID(uuid), mAssetType(asset_type) {}
virtual ~VFileInjector() {}
const std::string& contentType() { return HTTP_CONTENT_OCTET_STREAM; }
virtual EStatus process_impl(const LLChannelDescriptors& channels,
buffer_ptr_t& buffer, bool& eos, LLSD& context, LLPumpIO* pump)
{
LLBufferStream ostream(channels, buffer.get());
LLVFile vfile(gVFS, mUUID, mAssetType, LLVFile::READ);
S32 fileSize = vfile.getSize();
U8* fileBuffer;
fileBuffer = new U8 [fileSize];
vfile.read(fileBuffer, fileSize);
ostream.write((char*)fileBuffer, fileSize);
delete [] fileBuffer;
eos = true;
return STATUS_DONE;
}
const LLUUID mUUID;
LLAssetType::EType mAssetType;
};
LLPumpIO* theClientPump = NULL;
}
void LLHTTPClient::setCertVerifyCallback(LLURLRequest::SSLCertVerifyCallback callback)
{
LLHTTPClient::mCertVerifyCallback = callback;
}
static void request(
const std::string& url,
EHTTPMethod method,
Injector* body_injector,
LLCurl::ResponderPtr responder,
const F32 timeout = HTTP_REQUEST_EXPIRY_SECS,
const LLSD& headers = LLSD(),
bool follow_redirects = true
)
{
if (!LLHTTPClient::hasPump())
{
if (responder)
{
responder->completeResult(HTTP_INTERNAL_ERROR, "No pump");
}
delete body_injector;
return;
}
LLPumpIO::chain_t chain;
LLURLRequest* req = new LLURLRequest(method, url, follow_redirects);
if(!req->isValid())//failed
{
if (responder)
{
responder->completeResult(HTTP_INTERNAL_CURL_ERROR, "Internal Error - curl failure");
}
delete req;
delete body_injector;
return;
}
req->setSSLVerifyCallback(LLHTTPClient::getCertVerifyCallback(), (void *)req);
LL_DEBUGS("LLHTTPClient") << httpMethodAsVerb(method) << " " << url << " " << headers << LL_ENDL;
// Insert custom headers if the caller sent any
if (headers.isMap())
{
if (headers.has(HTTP_OUT_HEADER_COOKIE))
{
req->allowCookies();
}
LLSD::map_const_iterator iter = headers.beginMap();
LLSD::map_const_iterator end = headers.endMap();
for (; iter != end; ++iter)
{
//if the header is "Pragma" with no value
//the caller intends to force libcurl to drop
//the Pragma header it so gratuitously inserts
//Before inserting the header, force libcurl
//to not use the proxy (read: llurlrequest.cpp)
if ((iter->first == HTTP_OUT_HEADER_PRAGMA) && (iter->second.asString().empty()))
{
req->useProxy(false);
}
LL_DEBUGS("LLHTTPClient") << "header = " << iter->first
<< ": " << iter->second.asString() << LL_ENDL;
req->addHeader(iter->first, iter->second.asString());
}
}
// Check to see if we have already set Accept or not. If no one
// set it, set it to application/llsd+xml since that's what we
// almost always want.
if( method != HTTP_PUT && method != HTTP_POST )
{
if(!headers.has(HTTP_OUT_HEADER_ACCEPT))
{
req->addHeader(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_LLSD_XML);
}
}
if (responder)
{
responder->setURL(url);
responder->setHTTPMethod(method);
}
req->setCallback(new LLHTTPClientURLAdaptor(responder));
if (method == HTTP_POST && gMessageSystem)
{
req->addHeader("X-SecondLife-UDP-Listen-Port", llformat("%d",
gMessageSystem->mPort));
}
if (method == HTTP_PUT || method == HTTP_POST || method == HTTP_PATCH)
{
if(!headers.has(HTTP_OUT_HEADER_CONTENT_TYPE))
{
// If the Content-Type header was passed in, it has
// already been added as a header through req->addHeader
// in the loop above. We defer to the caller's wisdom, but
// if they did not specify a Content-Type, then ask the
// injector.
req->addHeader(HTTP_OUT_HEADER_CONTENT_TYPE, body_injector->contentType());
}
chain.push_back(LLIOPipe::ptr_t(body_injector));
}
chain.push_back(LLIOPipe::ptr_t(req));
theClientPump->addChain(chain, timeout);
}
void LLHTTPClient::getByteRange(
const std::string& url,
S32 offset,
S32 bytes,
ResponderPtr responder,
const LLSD& hdrs,
const F32 timeout,
bool follow_redirects /* = true */)
{
LLSD headers = hdrs;
if(offset > 0 || bytes > 0)
{
std::string range = llformat("bytes=%d-%d", offset, offset+bytes-1);
headers[HTTP_OUT_HEADER_RANGE] = range;
}
request(url,HTTP_GET, NULL, responder, timeout, headers, follow_redirects);
}
void LLHTTPClient::head(
const std::string& url,
ResponderPtr responder,
const LLSD& headers,
const F32 timeout,
bool follow_redirects /* = true */)
{
request(url, HTTP_HEAD, NULL, responder, timeout, headers, follow_redirects);
}
void LLHTTPClient::get(const std::string& url, ResponderPtr responder, const LLSD& headers, const F32 timeout,
bool follow_redirects /* = true */)
{
request(url, HTTP_GET, NULL, responder, timeout, headers, follow_redirects);
}
void LLHTTPClient::getHeaderOnly(const std::string& url, ResponderPtr responder, const LLSD& headers,
const F32 timeout, bool follow_redirects /* = true */)
{
request(url, HTTP_HEAD, NULL, responder, timeout, headers, follow_redirects);
}
void LLHTTPClient::getHeaderOnly(const std::string& url, ResponderPtr responder, const F32 timeout,
bool follow_redirects /* = true */)
{
getHeaderOnly(url, responder, LLSD(), timeout, follow_redirects);
}
void LLHTTPClient::get(const std::string& url, const LLSD& query, ResponderPtr responder, const LLSD& headers,
const F32 timeout, bool follow_redirects /* = true */)
{
LLURI uri;
uri = LLURI::buildHTTP(url, LLSD::emptyArray(), query);
get(uri.asString(), responder, headers, timeout, follow_redirects);
}
// A simple class for managing data returned from a curl http request.
class LLHTTPBuffer
{
public:
LLHTTPBuffer() { }
static size_t curl_write( void *ptr, size_t size, size_t nmemb, void *user_data)
{
LLHTTPBuffer* self = (LLHTTPBuffer*)user_data;
size_t bytes = (size * nmemb);
self->mBuffer.append((char*)ptr,bytes);
return nmemb;
}
LLSD asLLSD()
{
LLSD content;
if (mBuffer.empty()) return content;
std::istringstream istr(mBuffer);
LLSDSerialize::fromXML(content, istr);
return content;
}
const std::string& asString()
{
return mBuffer;
}
private:
std::string mBuffer;
};
// These calls are blocking! This is usually bad, unless you're a dataserver. Then it's awesome.
/**
@brief does a blocking request on the url, returning the data or bad status.
@param url URI to verb on.
@param method the verb to hit the URI with.
@param body the body of the call (if needed - for instance not used for GET and DELETE, but is for POST and PUT)
@param headers HTTP headers to use for the request.
@param timeout Curl timeout to use. Defaults to 5. Rationale:
Without this timeout, blockingGet() calls have been observed to take
up to 90 seconds to complete. Users of blockingGet() already must
check the HTTP return code for validity, so this will not introduce
new errors. A 5 second timeout will succeed > 95% of the time (and
probably > 99% of the time) based on my statistics. JC
@returns an LLSD map: {status: integer, body: map}
*/
static LLSD blocking_request(
const std::string& url,
EHTTPMethod method,
const LLSD& body,
const LLSD& headers = LLSD(),
const F32 timeout = 5
)
{
LL_DEBUGS() << "blockingRequest of " << url << LL_ENDL;
char curl_error_buffer[CURL_ERROR_SIZE] = "\0";
CURL* curlp = LLCurl::newEasyHandle();
llassert_always(curlp != NULL) ;
LLHTTPBuffer http_buffer;
std::string body_str;
// other request method checks root cert first, we skip?
// Apply configured proxy settings
LLProxy::getInstance()->applyProxySettings(curlp);
// * Set curl handle options
curl_easy_setopt(curlp, CURLOPT_NOSIGNAL, 1); // don't use SIGALRM for timeouts
curl_easy_setopt(curlp, CURLOPT_TIMEOUT, timeout); // seconds, see warning at top of function.
curl_easy_setopt(curlp, CURLOPT_WRITEFUNCTION, LLHTTPBuffer::curl_write);
curl_easy_setopt(curlp, CURLOPT_WRITEDATA, &http_buffer);
curl_easy_setopt(curlp, CURLOPT_URL, url.c_str());
curl_easy_setopt(curlp, CURLOPT_ERRORBUFFER, curl_error_buffer);
// * Setup headers (don't forget to free them after the call!)
curl_slist* headers_list = NULL;
if (headers.isMap())
{
LLSD::map_const_iterator iter = headers.beginMap();
LLSD::map_const_iterator end = headers.endMap();
for (; iter != end; ++iter)
{
std::ostringstream header;
header << iter->first << ": " << iter->second.asString() ;
LL_DEBUGS() << "header = " << header.str() << LL_ENDL;
headers_list = curl_slist_append(headers_list, header.str().c_str());
}
}
// * Setup specific method / "verb" for the URI (currently only GET and POST supported + poppy)
if (method == HTTP_GET)
{
curl_easy_setopt(curlp, CURLOPT_HTTPGET, 1);
}
else if (method == HTTP_POST)
{
curl_easy_setopt(curlp, CURLOPT_POST, 1);
//serialize to ostr then copy to str - need to because ostr ptr is unstable :(
std::ostringstream ostr;
LLSDSerialize::toXML(body, ostr);
body_str = ostr.str();
curl_easy_setopt(curlp, CURLOPT_POSTFIELDS, body_str.c_str());
//copied from PHP libs, correct?
headers_list = curl_slist_append(headers_list,
llformat("%s: %s", HTTP_OUT_HEADER_CONTENT_TYPE.c_str(), HTTP_CONTENT_LLSD_XML.c_str()).c_str());
// copied from llurlrequest.cpp
// it appears that apache2.2.3 or django in etch is busted. If
// we do not clear the expect header, we get a 500. May be
// limited to django/mod_wsgi.
headers_list = curl_slist_append(headers_list, llformat("%s:", HTTP_OUT_HEADER_EXPECT.c_str()).c_str());
}
// * Do the action using curl, handle results
LL_DEBUGS() << "HTTP body: " << body_str << LL_ENDL;
headers_list = curl_slist_append(headers_list,
llformat("%s: %s", HTTP_OUT_HEADER_ACCEPT.c_str(), HTTP_CONTENT_LLSD_XML.c_str()).c_str());
CURLcode curl_result = curl_easy_setopt(curlp, CURLOPT_HTTPHEADER, headers_list);
if ( curl_result != CURLE_OK )
{
LL_INFOS() << "Curl is hosed - can't add headers" << LL_ENDL;
}
LLSD response = LLSD::emptyMap();
S32 curl_success = curl_easy_perform(curlp);
S32 http_status = HTTP_INTERNAL_ERROR;
curl_easy_getinfo(curlp, CURLINFO_RESPONSE_CODE, &http_status);
response["status"] = http_status;
// if we get a non-404 and it's not a 200 OR maybe it is but you have error bits,
if ( http_status != HTTP_NOT_FOUND && (http_status != HTTP_OK || curl_success != 0) )
{
// We expect 404s, don't spam for them.
LL_WARNS() << "CURL REQ URL: " << url << LL_ENDL;
LL_WARNS() << "CURL REQ METHOD TYPE: " << method << LL_ENDL;
LL_WARNS() << "CURL REQ HEADERS: " << headers.asString() << LL_ENDL;
LL_WARNS() << "CURL REQ BODY: " << body_str << LL_ENDL;
LL_WARNS() << "CURL HTTP_STATUS: " << http_status << LL_ENDL;
LL_WARNS() << "CURL ERROR: " << curl_error_buffer << LL_ENDL;
LL_WARNS() << "CURL ERROR BODY: " << http_buffer.asString() << LL_ENDL;
response["body"] = http_buffer.asString();
}
else
{
response["body"] = http_buffer.asLLSD();
LL_DEBUGS() << "CURL response: " << http_buffer.asString() << LL_ENDL;
}
if(headers_list)
{ // free the header list
curl_slist_free_all(headers_list);
}
// * Cleanup
LLCurl::deleteEasyHandle(curlp);
return response;
}
LLSD LLHTTPClient::blockingGet(const std::string& url)
{
return blocking_request(url, HTTP_GET, LLSD());
}
LLSD LLHTTPClient::blockingPost(const std::string& url, const LLSD& body)
{
return blocking_request(url, HTTP_POST, body);
}
void LLHTTPClient::put(
const std::string& url,
const LLSD& body,
ResponderPtr responder,
const LLSD& headers,
const F32 timeout)
{
request(url, HTTP_PUT, new LLSDInjector(body), responder, timeout, headers);
}
void LLHTTPClient::patch(
const std::string& url,
const LLSD& body,
ResponderPtr responder,
const LLSD& headers,
const F32 timeout)
{
request(url, HTTP_PATCH, new LLSDInjector(body), responder, timeout, headers);
}
void LLHTTPClient::putRaw(
const std::string& url,
const U8* data,
S32 size,
ResponderPtr responder,
const LLSD& headers,
const F32 timeout)
{
request(url, HTTP_PUT, new RawInjector(data, size), responder, timeout, headers);
}
void LLHTTPClient::post(
const std::string& url,
const LLSD& body,
ResponderPtr responder,
const LLSD& headers,
const F32 timeout)
{
request(url, HTTP_POST, new LLSDInjector(body), responder, timeout, headers);
}
void LLHTTPClient::postRaw(
const std::string& url,
const U8* data,
S32 size,
ResponderPtr responder,
const LLSD& headers,
const F32 timeout)
{
request(url, HTTP_POST, new RawInjector(data, size), responder, timeout, headers);
}
void LLHTTPClient::postFile(
const std::string& url,
const std::string& filename,
ResponderPtr responder,
const LLSD& headers,
const F32 timeout)
{
request(url, HTTP_POST, new FileInjector(filename), responder, timeout, headers);
}
void LLHTTPClient::postFile(
const std::string& url,
const LLUUID& uuid,
LLAssetType::EType asset_type,
ResponderPtr responder,
const LLSD& headers,
const F32 timeout)
{
request(url, HTTP_POST, new VFileInjector(uuid, asset_type), responder, timeout, headers);
}
// static
void LLHTTPClient::del(
const std::string& url,
ResponderPtr responder,
const LLSD& headers,
const F32 timeout)
{
request(url, HTTP_DELETE, NULL, responder, timeout, headers);
}
// static
void LLHTTPClient::move(
const std::string& url,
const std::string& destination,
ResponderPtr responder,
const LLSD& hdrs,
const F32 timeout)
{
LLSD headers = hdrs;
headers[HTTP_OUT_HEADER_DESTINATION] = destination;
request(url, HTTP_MOVE, NULL, responder, timeout, headers);
}
// static
void LLHTTPClient::copy(
const std::string& url,
const std::string& destination,
ResponderPtr responder,
const LLSD& hdrs,
const F32 timeout)
{
LLSD headers = hdrs;
headers[HTTP_OUT_HEADER_DESTINATION] = destination;
request(url, HTTP_COPY, NULL, responder, timeout, headers);
}
void LLHTTPClient::setPump(LLPumpIO& pump)
{
theClientPump = &pump;
}
bool LLHTTPClient::hasPump()
{
return theClientPump != NULL;
}

View File

@ -1,201 +0,0 @@
/**
* @file llhttpclient.h
* @brief Declaration of classes for making HTTP client requests.
*
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLHTTPCLIENT_H
#define LL_LLHTTPCLIENT_H
/**
* These classes represent the HTTP client framework.
*/
#include <string>
#include <boost/intrusive_ptr.hpp>
#include <openssl/x509_vfy.h>
#include "llurlrequest.h"
#include "llassettype.h"
#include "llcurl.h"
#include "lliopipe.h"
extern const F32 HTTP_REQUEST_EXPIRY_SECS;
class LLUUID;
class LLPumpIO;
class LLSD;
class LLHTTPClient
{
public:
// class Responder moved to LLCurl
// For convenience
typedef LLCurl::Responder Responder;
typedef LLCurl::ResponderPtr ResponderPtr;
/** @name non-blocking API */
//@{
static void head(
const std::string& url,
ResponderPtr,
const LLSD& headers = LLSD(),
const F32 timeout=HTTP_REQUEST_EXPIRY_SECS,
bool follow_redirects = true);
static void getByteRange(const std::string& url, S32 offset, S32 bytes, ResponderPtr,
const LLSD& headers=LLSD(), const F32 timeout=HTTP_REQUEST_EXPIRY_SECS,
bool follow_redirects = true);
static void get(const std::string& url, ResponderPtr, const LLSD& headers = LLSD(),
const F32 timeout=HTTP_REQUEST_EXPIRY_SECS, bool follow_redirects = true);
static void get(const std::string& url, const LLSD& query, ResponderPtr, const LLSD& headers = LLSD(),
const F32 timeout=HTTP_REQUEST_EXPIRY_SECS, bool follow_redirects = true);
static void put(
const std::string& url,
const LLSD& body,
ResponderPtr,
const LLSD& headers = LLSD(),
const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
static void putRaw(
const std::string& url,
const U8* data,
S32 size,
ResponderPtr responder,
const LLSD& headers = LLSD(),
const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
static void patch(
const std::string& url,
const LLSD& body,
ResponderPtr,
const LLSD& headers = LLSD(),
const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
static void getHeaderOnly(const std::string& url, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS,
bool follow_redirects = true);
static void getHeaderOnly(const std::string& url, ResponderPtr, const LLSD& headers,
const F32 timeout=HTTP_REQUEST_EXPIRY_SECS, bool follow_redirects = true);
static void post(
const std::string& url,
const LLSD& body,
ResponderPtr,
const LLSD& headers = LLSD(),
const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
/** Takes ownership of data and deletes it when sent */
static void postRaw(
const std::string& url,
const U8* data,
S32 size,
ResponderPtr responder,
const LLSD& headers = LLSD(),
const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
static void postFile(
const std::string& url,
const std::string& filename,
ResponderPtr,
const LLSD& headers = LLSD(),
const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
static void postFile(
const std::string& url,
const LLUUID& uuid,
LLAssetType::EType asset_type,
ResponderPtr responder,
const LLSD& headers = LLSD(),
const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
static void del(
const std::string& url,
ResponderPtr responder,
const LLSD& headers = LLSD(),
const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
///< sends a DELETE method, but we can't call it delete in c++
/**
* @brief Send a MOVE webdav method
*
* @param url The complete serialized (and escaped) url to get.
* @param destination The complete serialized destination url.
* @param responder The responder that will handle the result.
* @param headers A map of key:value headers to pass to the request
* @param timeout The number of seconds to give the server to respond.
*/
static void move(
const std::string& url,
const std::string& destination,
ResponderPtr responder,
const LLSD& headers = LLSD(),
const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
/**
* @brief Send a COPY webdav method
*
* @param url The complete serialized (and escaped) url to get.
* @param destination The complete serialized destination url.
* @param responder The responder that will handle the result.
* @param headers A map of key:value headers to pass to the request
* @param timeout The number of seconds to give the server to respond.
*/
static void copy(
const std::string& url,
const std::string& destination,
ResponderPtr responder,
const LLSD& headers = LLSD(),
const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
//@}
/**
* @brief Blocking HTTP get that returns an LLSD map of status and body.
*
* @param url the complete serialized (and escaped) url to get
* @return An LLSD of { 'status':status, 'body':payload }
*/
static LLSD blockingGet(const std::string& url);
/**
* @brief Blocking HTTP POST that returns an LLSD map of status and body.
*
* @param url the complete serialized (and escaped) url to get
* @param body the LLSD post body
* @return An LLSD of { 'status':status (an int), 'body':payload (an LLSD) }
*/
static LLSD blockingPost(const std::string& url, const LLSD& body);
static void setPump(LLPumpIO& pump);
///< must be called before any of the above calls are made
static bool hasPump();
static void setCertVerifyCallback(LLURLRequest::SSLCertVerifyCallback callback);
static LLURLRequest::SSLCertVerifyCallback getCertVerifyCallback() { return mCertVerifyCallback; }
protected:
static LLURLRequest::SSLCertVerifyCallback mCertVerifyCallback;
};
#endif // LL_LLHTTPCLIENT_H

View File

@ -1,45 +0,0 @@
/**
* @file llhttpclientinterface.h
* @brief
*
* $LicenseInfo:firstyear=2008&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLHTTPCLIENTINTERFACE_H
#define LL_LLHTTPCLIENTINTERFACE_H
#include "linden_common.h"
#include "llcurl.h"
#include <string>
// class LLHTTPClientInterface
// {
// public:
// virtual ~LLHTTPClientInterface() {}
// virtual void get(const std::string& url, LLCurl::ResponderPtr responder) = 0;
// virtual void get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers) = 0;
// virtual void put(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder) = 0;
// };
#endif // LL_LLHTTPCLIENTINTERFACE_H

View File

@ -50,7 +50,6 @@
#include "lldir.h"
#include "llerror.h"
#include "llfasttimer.h"
#include "llhttpclient.h"
#include "llhttpnodeadapter.h"
#include "llmd5.h"
#include "llmessagebuilder.h"

View File

@ -2224,7 +2224,6 @@ if (LL_TESTS)
# llmediadataclient.cpp
lllogininstance.cpp
# llremoteparcelrequest.cpp
# lltranslate.cpp
llviewerhelputil.cpp
llversioninfo.cpp
llworldmap.cpp
@ -2245,12 +2244,6 @@ if (LL_TESTS)
${CURL_LIBRARIES}
)
# set_source_files_properties(
# lltranslate.cpp
# PROPERTIES
# LL_TEST_ADDITIONAL_LIBRARIES "${test_libs}"
# )
set_source_files_properties(
llmediadataclient.cpp
PROPERTIES

View File

@ -380,7 +380,7 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest());
LLCore::HttpHeaders::ptr_t httpHeaders;
httpOptions->setTimeout(HTTP_REQUEST_EXPIRY_SECS);
httpOptions->setTimeout(LLCoreHttpUtil::HTTP_REQUEST_EXPIRY_SECS);
LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL;

View File

@ -32,7 +32,6 @@
#include <set>
#include <string>
#include "llcurl.h"
#include "llhttpclient.h"
#include "llhttpretrypolicy.h"
#include "llviewerinventory.h"
#include "llcorehttputil.h"

View File

@ -1160,8 +1160,6 @@ bool LLAppViewer::init()
{
LLNotificationsUtil::add("CorruptedProtectedDataStore");
}
LLHTTPClient::setCertVerifyCallback(secapiSSLCertVerifyCallback);
gGLActive = FALSE;
@ -1315,7 +1313,6 @@ bool LLAppViewer::mainLoop()
// Create IO Pump to use for HTTP Requests.
gServicePump = new LLPumpIO(gAPRPoolp);
LLHTTPClient::setPump(*gServicePump);
LLCurl::setCAFile(gDirUtilp->getCAFile());
// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated.

View File

@ -27,7 +27,6 @@
#ifndef LL_LLEVENTPOLL_H
#define LL_LLEVENTPOLL_H
#include "llhttpclient.h"
#include "boost/move/unique_ptr.hpp"
namespace boost

View File

@ -36,7 +36,6 @@
#include "llexpandabletextbox.h"
#include "llexperiencecache.h"
#include "llfloaterreg.h"
#include "llhttpclient.h"
#include "lllayoutstack.h"
#include "lllineeditor.h"
#include "llnotificationsutil.h"

View File

@ -32,7 +32,6 @@
#include "llevents.h"
#include "llexperiencecache.h"
#include "llfloaterregioninfo.h"
#include "llhttpclient.h"
#include "llnotificationsutil.h"
#include "llpanelexperiencelog.h"
#include "llpanelexperiencepicker.h"

View File

@ -41,7 +41,6 @@
#include "llui.h"
#include "message.h"
#include "roles_constants.h"
#include "llhttpclient.h"
#include "lltransactiontypes.h"
#include "llstatusbar.h"
#include "lleconomy.h"

View File

@ -30,7 +30,6 @@
#include "llagent.h"
#include "llbufferstream.h"
#include "llhttpclient.h"
#include "llinventoryfunctions.h"
#include "llinventoryobserver.h"
#include "llnotificationsutil.h"

View File

@ -38,6 +38,7 @@
#include "httpoptions.h"
#include "httpheaders.h"
#include "httphandler.h"
#include "llthread.h"
#define LLCONVEXDECOMPINTER_STATIC 1

View File

@ -42,7 +42,6 @@
#include "llviewercontrol.h"
#include "llfloater.h"
#include "lltrans.h"
#include "llhttpclient.h" // *TODO: Rider, remove when converting
#define BTN_FIND "find"
#define BTN_OK "ok_btn"

View File

@ -31,7 +31,6 @@
#include "lluictrlfactory.h"
#include "roles_constants.h"
#include "llhttpclient.h"
#include "llagent.h"
#include "llviewerregion.h"
#include "llflatlistview.h"

View File

@ -32,7 +32,6 @@
#include <openssl/evp.h>
#include <openssl/err.h>
#include <map>
#include "llhttpclient.h"
@ -99,46 +98,6 @@ std::ostream& operator <<(std::ostream& s, const LLCredential& cred)
return s << (std::string)cred;
}
// secapiSSLCertVerifyCallback
// basic callback called when a cert verification is requested.
// calls SECAPI to validate the context
// not initialized in the above initialization function, due to unit tests
// see llappviewer
int secapiSSLCertVerifyCallback(X509_STORE_CTX *ctx, void *param)
{
LLURLRequest *req = (LLURLRequest *)param;
LLPointer<LLCertificateStore> store = gSecAPIHandler->getCertificateStore("");
LLPointer<LLCertificateChain> chain = gSecAPIHandler->getCertificateChain(ctx);
LLSD validation_params = LLSD::emptyMap();
LLURI uri(req->getURL());
validation_params[CERT_HOSTNAME] = uri.hostName();
try
{
// we rely on libcurl to validate the hostname, as libcurl does more extensive validation
// leaving our hostname validation call mechanism for future additions with respect to
// OS native (Mac keyring, windows CAPI) validation.
store->validate(VALIDATION_POLICY_SSL & (~VALIDATION_POLICY_HOSTNAME), chain, validation_params);
}
catch (LLCertValidationTrustException& cert_exception)
{
LL_WARNS("AppInit") << "Cert not trusted: " << cert_exception.getMessage() << LL_ENDL;
return 0;
}
catch (LLCertException& cert_exception)
{
LL_WARNS("AppInit") << "cert error " << cert_exception.getMessage() << LL_ENDL;
return 0;
}
catch (...)
{
LL_WARNS("AppInit") << "cert error " << LL_ENDL;
return 0;
}
return 1;
}
LLSD LLCredential::getLoginParams()
{
LLSD result = LLSD::emptyMap();

View File

@ -489,7 +489,4 @@ void registerSecHandler(const std::string& handler_type,
extern LLPointer<LLSecAPIHandler> gSecAPIHandler;
int secapiSSLCertVerifyCallback(X509_STORE_CTX *ctx, void *param);
#endif // LL_SECAPI_H

View File

@ -37,7 +37,6 @@
#include "llfloatersidepanelcontainer.h"
#include "llfoldertype.h"
#include "llfolderview.h"
#include "llhttpclient.h"
#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
#include "llinventorymodel.h"

View File

@ -112,7 +112,6 @@
#include "llgroupmgr.h"
#include "llhudeffecttrail.h"
#include "llhudmanager.h"
#include "llhttpclient.h"
#include "llimagebmp.h"
#include "llinventorybridge.h"
#include "llinventorymodel.h"

View File

@ -574,25 +574,3 @@ LLTranslationAPIHandler& LLTranslate::getHandler(EService service)
return bing;
}
// static
void LLTranslate::sendRequest(const std::string& url, LLHTTPClient::ResponderPtr responder)
{
static const float REQUEST_TIMEOUT = 5;
static LLSD sHeader;
if (!sHeader.size())
{
std::string user_agent = llformat("%s %d.%d.%d (%d)",
LLVersionInfo::getChannel().c_str(),
LLVersionInfo::getMajor(),
LLVersionInfo::getMinor(),
LLVersionInfo::getPatch(),
LLVersionInfo::getBuild());
sHeader.insert(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_TEXT_PLAIN);
sHeader.insert(HTTP_OUT_HEADER_USER_AGENT, user_agent);
}
LLHTTPClient::get(url, responder, sHeader, REQUEST_TIMEOUT);
}

View File

@ -27,7 +27,6 @@
#ifndef LL_LLTRANSLATE_H
#define LL_LLTRANSLATE_H
#include "llhttpclient.h"
#include "llbufferstream.h"
#include <boost/function.hpp>
@ -95,7 +94,6 @@ public :
private:
static LLTranslationAPIHandler& getPreferredHandler();
static LLTranslationAPIHandler& getHandler(EService service);
static void sendRequest(const std::string& url, LLHTTPClient::ResponderPtr responder);
};
#endif

View File

@ -28,7 +28,6 @@
#define LL_LLUPLOADFLOATEROBSERVERS_H
#include "llfloater.h"
#include "llhttpclient.h"
#include "llhandle.h"
class LLUploadPermissionsObserver

View File

@ -66,7 +66,6 @@
// linden libraries
#include "lleconomy.h"
#include "llhttpclient.h"
#include "llnotificationsutil.h"
#include "llsdserialize.h"
#include "llsdutil.h"

View File

@ -34,7 +34,6 @@
#include "llavatarnamecache.h" // name lookup cap url
#include "llfloaterreg.h"
#include "llmath.h"
#include "llhttpclient.h"
#include "llregionflags.h"
#include "llregionhandle.h"
#include "llsurface.h"

View File

@ -1,340 +0,0 @@
/**
* @file lltranslate_test.cpp
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "../test/lltut.h"
#include "../lltranslate.h"
#include "../llversioninfo.h"
#include "../llviewercontrol.h"
#include "llbufferstream.h"
#include "lltrans.h"
#include "llui.h"
#include "../../llmessage/llhttpconstants.cpp"
static const std::string GOOGLE_VALID_RESPONSE1 =
"{\
\"data\": {\
\"translations\": [\
{\
\"translatedText\": \"привет\",\
\"detectedSourceLanguage\": \"es\"\
}\
]\
}\
}";
static const std::string GOOGLE_VALID_RESPONSE2 =
"{\
\"data\": {\
\"translations\": [\
{\
\"translatedText\": \"привет\"\
}\
]\
}\
}\
";
static const std::string GOOGLE_VALID_RESPONSE3 =
"{\
\"error\": {\
\"errors\": [\
{\
\"domain\": \"global\",\
\"reason\": \"invalid\",\
\"message\": \"Invalid Value\"\
}\
],\
\"code\": 400,\
\"message\": \"Invalid Value\"\
}\
}";
static const std::string BING_VALID_RESPONSE1 =
"<string xmlns=\"http://schemas.microsoft.com/2003/10/Serialization/\">Привет</string>";
static const std::string BING_VALID_RESPONSE2 =
"<html><body><h1>Argument Exception</h1><p>Method: Translate()</p><p>Parameter: </p>\
<p>Message: 'from' must be a valid language</p><code></code>\
<p>message id=3743.V2_Rest.Translate.58E8454F</p></body></html>";
static const std::string BING_VALID_RESPONSE3 =
"<html><body><h1>Argument Exception</h1><p>Method: Translate()</p>\
<p>Parameter: appId</p><p>Message: Invalid appId&#xD;\nParameter name: appId</p>\
<code></code><p>message id=3737.V2_Rest.Translate.56016759</p></body></html>";
namespace tut
{
class translate_test
{
protected:
void test_translation(
LLTranslationAPIHandler& handler,
int status, const std::string& resp,
const std::string& exp_trans, const std::string& exp_lang, const std::string& exp_err)
{
std::string translation, detected_lang, err_msg;
bool rc = handler.parseResponse(status, resp, translation, detected_lang, err_msg);
ensure_equals("rc", rc, (status == 200));
ensure_equals("err_msg", err_msg, exp_err);
ensure_equals("translation", translation, exp_trans);
ensure_equals("detected_lang", detected_lang, exp_lang);
}
LLGoogleTranslationHandler mGoogle;
LLBingTranslationHandler mBing;
};
typedef test_group<translate_test> translate_test_group_t;
typedef translate_test_group_t::object translate_test_object_t;
tut::translate_test_group_t tut_translate("LLTranslate");
template<> template<>
void translate_test_object_t::test<1>()
{
test_translation(mGoogle, 200, GOOGLE_VALID_RESPONSE1, "привет", "es", "");
}
template<> template<>
void translate_test_object_t::test<2>()
{
test_translation(mGoogle, 200, GOOGLE_VALID_RESPONSE2, "привет", "", "");
}
template<> template<>
void translate_test_object_t::test<3>()
{
test_translation(mGoogle, 400, GOOGLE_VALID_RESPONSE3, "", "", "Invalid Value");
}
template<> template<>
void translate_test_object_t::test<4>()
{
test_translation(mGoogle, 400,
"",
"", "", "* Line 1, Column 1\n Syntax error: value, object or array expected.\n");
}
template<> template<>
void translate_test_object_t::test<5>()
{
test_translation(mGoogle, 400,
"[]",
"", "", "");
}
template<> template<>
void translate_test_object_t::test<6>()
{
test_translation(mGoogle, 400,
"{\"oops\": \"invalid\"}",
"", "", "");
}
template<> template<>
void translate_test_object_t::test<7>()
{
test_translation(mGoogle, 400,
"{\"data\": {}}",
"", "", "");
}
template<> template<>
void translate_test_object_t::test<8>()
{
test_translation(mGoogle, 400,
"{\"data\": { \"translations\": [ {} ] }}",
"", "", "");
}
template<> template<>
void translate_test_object_t::test<9>()
{
test_translation(mGoogle, 400,
"{\"data\": { \"translations\": [ { \"translatedTextZZZ\": \"привет\", \"detectedSourceLanguageZZZ\": \"es\" } ] }}",
"", "", "");
}
template<> template<>
void translate_test_object_t::test<10>()
{
test_translation(mBing, 200, BING_VALID_RESPONSE1, "Привет", "", "");
}
template<> template<>
void translate_test_object_t::test<11>()
{
test_translation(mBing, 400, BING_VALID_RESPONSE2, "", "", "'from' must be a valid language");
}
template<> template<>
void translate_test_object_t::test<12>()
{
test_translation(mBing, 400, BING_VALID_RESPONSE3, "", "", "Invalid appId\nParameter name: appId");
}
template<> template<>
void translate_test_object_t::test<13>()
{
test_translation(mBing, 200,
"Привет</string>",
"Привет", "", "");
}
template<> template<>
void translate_test_object_t::test<14>()
{
test_translation(mBing, 200,
"<string xmlns=\"http://schemas.microsoft.com/2003/10/Serialization/\">Привет",
"Привет", "", "");
}
template<> template<>
void translate_test_object_t::test<15>()
{
test_translation(mBing, 200,
"Привет",
"Привет", "", "");
}
template<> template<>
void translate_test_object_t::test<16>()
{
test_translation(mBing, 400,
"Message: some error</p>",
"", "", "some error");
}
template<> template<>
void translate_test_object_t::test<17>()
{
test_translation(mBing, 400,
"Message: some error",
"", "", "some error");
}
template<> template<>
void translate_test_object_t::test<18>()
{
test_translation(mBing, 400,
"some error</p>",
"", "", "some error");
}
template<> template<>
void translate_test_object_t::test<19>()
{
test_translation(mBing, 400,
"some error",
"", "", "some error");
}
template<> template<>
void translate_test_object_t::test<20>()
{
std::string url;
mBing.getTranslateURL(url, "en", "es", "hi");
ensure_equals("bing URL", url,
"http://api.microsofttranslator.com/v2/Http.svc/Translate?appId=dummy&text=hi&to=es&from=en");
}
template<> template<>
void translate_test_object_t::test<21>()
{
std::string url;
mBing.getTranslateURL(url, "", "es", "hi");
ensure_equals("bing URL", url,
"http://api.microsofttranslator.com/v2/Http.svc/Translate?appId=dummy&text=hi&to=es");
}
template<> template<>
void translate_test_object_t::test<22>()
{
std::string url;
mGoogle.getTranslateURL(url, "en", "es", "hi");
ensure_equals("google URL", url,
"https://www.googleapis.com/language/translate/v2?key=dummy&q=hi&target=es&source=en");
}
template<> template<>
void translate_test_object_t::test<23>()
{
std::string url;
mGoogle.getTranslateURL(url, "", "es", "hi");
ensure_equals("google URL", url,
"https://www.googleapis.com/language/translate/v2?key=dummy&q=hi&target=es");
}
}
//== Misc stubs ===============================================================
LLControlGroup gSavedSettings("test");
std::string LLUI::getLanguage() { return "en"; }
std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args) { return "dummy"; }
LLControlGroup::LLControlGroup(const std::string& name) : LLInstanceTracker<LLControlGroup, std::string>(name) {}
std::string LLControlGroup::getString(const std::string& name) { return "dummy"; }
LLControlGroup::~LLControlGroup() {}
LLCurl::Responder::Responder() {}
void LLCurl::Responder::httpFailure() { }
void LLCurl::Responder::httpSuccess() { }
void LLCurl::Responder::httpCompleted() { }
void LLCurl::Responder::completedRaw(LLChannelDescriptors const &,boost::shared_ptr<LLBufferArray> const &) { }
LLCurl::Responder::~Responder() {}
void LLHTTPClient::get(const std::string&, const LLSD&, ResponderPtr, const LLSD&, const F32, bool) {}
void LLHTTPClient::get(const std::string&, LLPointer<LLCurl::Responder>, const LLSD&, const F32, bool) {}
LLBufferStream::LLBufferStream(const LLChannelDescriptors& channels, LLBufferArray* buffer)
: std::iostream(&mStreamBuf), mStreamBuf(channels, buffer) {}
LLBufferStream::~LLBufferStream() {}
LLBufferStreamBuf::LLBufferStreamBuf(const LLChannelDescriptors&, LLBufferArray*) {}
#if( LL_WINDOWS || __GNUC__ > 2)
LLBufferStreamBuf::pos_type LLBufferStreamBuf::seekoff(
off_type off,
std::ios::seekdir way,
std::ios::openmode which)
#else
streampos LLBufferStreamBuf::seekoff(
streamoff off,
std::ios::seekdir way,
std::ios::openmode which)
#endif
{ return 0; }
int LLBufferStreamBuf::sync() {return 0;}
int LLBufferStreamBuf::underflow() {return 0;}
int LLBufferStreamBuf::overflow(int) {return 0;}
LLBufferStreamBuf::~LLBufferStreamBuf() {}
S32 LLVersionInfo::getBuild() { return 0; }
const std::string& LLVersionInfo::getChannel() {static std::string dummy; return dummy;}
S32 LLVersionInfo::getMajor() { return 0; }
S32 LLVersionInfo::getMinor() { return 0; }
S32 LLVersionInfo::getPatch() { return 0; }