bool pollStatus()
	{
		if (!hasSessionCookie())
		{
			return false;
		}

		sImportGetPending = true;

		std::string url = getInventoryImportURL();

		url += sImportId.asString();

		// Make the headers for the post
		AIHTTPHeaders headers;
		headers.addHeader("Accept", "*/*");
		headers.addHeader("Cookie", sMarketplaceCookie);
		headers.addHeader("Content-Type", "application/llsd+xml");
		headers.addHeader("User-Agent", LLViewerMedia::getCurrentUserAgent());

		if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
		{
			llinfos << " SLM GET: " << url << llendl;
		}

		slmGetTimer.start();
		LLHTTPClient::get(url, new LLImportGetResponder(), headers);

		return true;
	}
// static
void LLWebProfile::uploadImage(LLPointer<LLImageFormatted> image, const std::string& caption, bool add_location)
{
	// Get upload configuration data.
	std::string config_url(getProfileURL(LLStringUtil::null) + "snapshots/s3_upload_config");
	config_url += "?caption=" + LLURI::escape(caption);
	config_url += "&add_loc=" + std::string(add_location ? "1" : "0");

	LL_DEBUGS("Snapshots") << "Requesting " << config_url << LL_ENDL;
	AIHTTPHeaders headers;
	headers.addHeader("Accept", "*/*");
	headers.addHeader("Cookie", LLWebProfile::getAuthCookie());
	headers.addHeader("User-Agent", LLViewerMedia::getCurrentUserAgent());
	LLHTTPClient::get(config_url, new LLWebProfileResponders::ConfigResponder(image), headers);
}
	bool triggerImport()
	{
		if (!hasSessionCookie())
		{
			return false;
		}

		sImportId = LLSD::emptyMap();
		sImportInProgress = true;
		sImportPostPending = true;
		sImportResultStatus = MarketplaceErrorCodes::IMPORT_PROCESSING;
		sImportResults = LLSD::emptyMap();

		std::string url = getInventoryImportURL();

		// Make the headers for the post
		AIHTTPHeaders headers;
		headers.addHeader("Accept", "*/*");
		headers.addHeader("Connection", "Keep-Alive");
		headers.addHeader("Cookie", sMarketplaceCookie);
		headers.addHeader("Content-Type", "application/xml");
		headers.addHeader("User-Agent", LLViewerMedia::getCurrentUserAgent());

		if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
		{
			llinfos << " SLM POST: " << url << llendl;
		}

		slmPostTimer.start();
		LLHTTPClient::post(url, LLSD(), new LLImportPostResponder(), headers);

		return true;
	}
	/*virtual*/ void completedHeaders(void)
	{
		// Server abuses 303 status; Curl can't handle it because it tries to resent
		// the just uploaded data, which fails
		// (CURLE_SEND_FAIL_REWIND: Send failed since rewinding of the data stream failed).
		// Handle it manually.
		if (mStatus == HTTP_SEE_OTHER)
		{
			AIHTTPHeaders headers;
			headers.addHeader("Accept", "*/*");
			headers.addHeader("Cookie", LLWebProfile::getAuthCookie());
			headers.addHeader("User-Agent", LLViewerMedia::getCurrentUserAgent());
			std::string redir_url;
			mReceivedHeaders.getFirstValue("location", redir_url);
			LL_DEBUGS("Snapshots") << "Got redirection URL: " << redir_url << LL_ENDL;
			LLHTTPClient::get(redir_url, new LLWebProfileResponders::PostImageRedirectResponder, headers);
		}
		else
		{
			LL_WARNS() << "Unexpected POST status: " << mStatus << " " << mReason << LL_ENDL;
			LL_DEBUGS("Snapshots") << "received_headers: [" << mReceivedHeaders << "]" << LL_ENDL;
			LLWebProfile::reportImageUploadStatus(false);
		}
	}
// static
void LLWebProfile::post(LLPointer<LLImageFormatted> image, const LLSD& config, const std::string& url)
{
	if (dynamic_cast<LLImagePNG*>(image.get()) == 0)
	{
		LL_WARNS() << "Image to upload is not a PNG" << LL_ENDL;
		llassert(dynamic_cast<LLImagePNG*>(image.get()) != 0);
		return;
	}

	const std::string boundary = "----------------------------0123abcdefab";

	AIHTTPHeaders headers;
	headers.addHeader("Accept", "*/*");
	headers.addHeader("Cookie", LLWebProfile::getAuthCookie());
	headers.addHeader("User-Agent", LLViewerMedia::getCurrentUserAgent());
	headers.addHeader("Content-Type", "multipart/form-data; boundary=" + boundary);

	std::ostringstream body;

	// *NOTE: The order seems to matter.
	body	<< "--" << boundary << "\r\n"
			<< "Content-Disposition: form-data; name=\"key\"\r\n\r\n"
			<< config["key"].asString() << "\r\n";

	body	<< "--" << boundary << "\r\n"
			<< "Content-Disposition: form-data; name=\"AWSAccessKeyId\"\r\n\r\n"
			<< config["AWSAccessKeyId"].asString() << "\r\n";

	body	<< "--" << boundary << "\r\n"
			<< "Content-Disposition: form-data; name=\"acl\"\r\n\r\n"
			<< config["acl"].asString() << "\r\n";

	body	<< "--" << boundary << "\r\n"
			<< "Content-Disposition: form-data; name=\"Content-Type\"\r\n\r\n"
			<< config["Content-Type"].asString() << "\r\n";

	body	<< "--" << boundary << "\r\n"
			<< "Content-Disposition: form-data; name=\"policy\"\r\n\r\n"
			<< config["policy"].asString() << "\r\n";

	body	<< "--" << boundary << "\r\n"
			<< "Content-Disposition: form-data; name=\"signature\"\r\n\r\n"
			<< config["signature"].asString() << "\r\n";

	body	<< "--" << boundary << "\r\n"
			<< "Content-Disposition: form-data; name=\"success_action_redirect\"\r\n\r\n"
			<< config["success_action_redirect"].asString() << "\r\n";

	body	<< "--" << boundary << "\r\n"
			<< "Content-Disposition: form-data; name=\"file\"; filename=\"snapshot.png\"\r\n"
			<< "Content-Type: image/png\r\n\r\n";
	size_t const body_size = body.str().size();

	std::ostringstream footer;
	footer << "\r\n--" << boundary << "--\r\n";
	size_t const footer_size = footer.str().size();

	size_t size = body_size + image->getDataSize() + footer_size;
	// postRaw() takes ownership of the buffer and releases it later.
	U8* data = new U8 [size];
	memcpy(data, body.str().data(), body_size);
	// Insert the image data.
	memcpy(data + body_size, image->getData(), image->getDataSize());
	memcpy(data + body_size + image->getDataSize(), footer.str().data(), footer_size);

	// Send request, successful upload will trigger posting metadata.
	LLHTTPClient::postRaw(url, data, size, new LLWebProfileResponders::PostImageResponder(), headers/*,*/ DEBUG_CURLIO_PARAM(debug_off), no_keep_alive);
}