static void request(
	const std::string& url,
	LLURLRequest::ERequestAction method,
	Injector* body_injector,
	LLCurl::ResponderPtr responder,
	const F32 timeout = HTTP_REQUEST_EXPIRY_SECS,
	const LLSD& headers = LLSD()
    )
{
	if (!LLHTTPClient::hasPump())
	{
		responder->completed(U32_MAX, "No pump", LLSD());
		return;
	}
	LLPumpIO::chain_t chain;

	LLURLRequest* req = new LLURLRequest(method, url);
	if(!req->isValid())//failed
	{
		delete req ;
		return ;
	}

	req->setSSLVerifyCallback(LLHTTPClient::getCertVerifyCallback(), (void *)req);

	
	lldebugs << LLURLRequest::actionAsVerb(method) << " " << url << " "
		<< headers << llendl;

	// Insert custom headers if the caller sent any
	if (headers.isMap())
	{
		if (headers.has("Cookie"))
		{
			req->allowCookies();
		}

        LLSD::map_const_iterator iter = headers.beginMap();
        LLSD::map_const_iterator end  = headers.endMap();

        for (; iter != end; ++iter)
        {
            std::ostringstream header;
            //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)
			static const std::string PRAGMA("Pragma");
			if ((iter->first == PRAGMA) && (iter->second.asString().empty()))
            {
                req->useProxy(false);
            }
            header << iter->first << ": " << iter->second.asString() ;
            lldebugs << "header = " << header.str() << llendl;
            req->addHeader(header.str().c_str());
        }
    }

	// 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 != LLURLRequest::HTTP_PUT && method != LLURLRequest::HTTP_POST )
	{
		static const std::string ACCEPT("Accept");
		if(!headers.has(ACCEPT))
		{
			req->addHeader("Accept: application/llsd+xml");
		}
	}

	if (responder)
	{
		responder->setURL(url);
	}

	req->setCallback(new LLHTTPClientURLAdaptor(responder));

	if (method == LLURLRequest::HTTP_POST  &&  gMessageSystem)
	{
		req->addHeader(llformat("X-SecondLife-UDP-Listen-Port: %d",
								gMessageSystem->mPort).c_str());
   	}

	if (method == LLURLRequest::HTTP_PUT || method == LLURLRequest::HTTP_POST)
	{
		static const std::string CONTENT_TYPE("Content-Type");
		if(!headers.has(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(
				llformat(
					"Content-Type: %s",
					body_injector->contentType()).c_str());
		}
   		chain.push_back(LLIOPipe::ptr_t(body_injector));
	}

	chain.push_back(LLIOPipe::ptr_t(req));

	theClientPump->addChain(chain, timeout);
}
Example #2
0
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);
	}

	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));
	}

	static U64 request_id = 0;
	++request_id;
	req->setCallback(new LLHTTPClientURLAdaptor(responder, request_id));

	chain.push_back(LLIOPipe::ptr_t(req));

	theClientPump->addChain(chain, timeout);
}