static void request(const std::string &url, LLURLRequest::ERequestAction method, BodyData *body, HippoRestHandler *handler, float timeout) { if (!LLHTTPClient::hasPump()) { // !!! responder->completed(U32_MAX, "No pump", LLSD()); return; } LLPumpIO::chain_t chain; LLURLRequest *req = new LLURLRequest(method, url); req->checkRootCertificate(true); /* // Insert custom headers if the caller sent any if (headers.isMap()) { 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()); } } */ if ((method != LLURLRequest::HTTP_PUT) && (method != LLURLRequest::HTTP_POST)) { std::string accept = "Accept: "; accept += handler->getAcceptMimeType(); req->addHeader(accept.c_str()); } req->setCallback(new HippoRestComplete(handler)); if ((method == LLURLRequest::HTTP_PUT) || (method == LLURLRequest::HTTP_POST)) { std::string content = "Content-Type: "; content += body->getContentMimeType(); req->addHeader(content.c_str()); chain.push_back(LLIOPipe::ptr_t(body)); } chain.push_back(LLIOPipe::ptr_t(req)); LLHTTPClient::getPump().addChain(chain, timeout); }
std::string makeRequest( const std::string& name, const std::string& httpRequest, bool timeout = false) { LLPipeStringInjector* injector = new LLPipeStringInjector(httpRequest); LLPipeStringExtractor* extractor = new LLPipeStringExtractor(); apr_pool_t* pool; apr_pool_create(&pool, NULL); LLPumpIO* pump; pump = new LLPumpIO(pool); LLPumpIO::chain_t chain; LLSD context; chain.push_back(LLIOPipe::ptr_t(injector)); LLIOHTTPServer::createPipe(chain, mRoot, LLSD()); chain.push_back(LLIOPipe::ptr_t(extractor)); pump->addChain(chain, DEFAULT_CHAIN_EXPIRY_SECS); pumpPipe(pump, 10); if(mResponse.notNull() && (! timeout)) { mResponse->result(mResult); mResponse = NULL; } pumpPipe(pump, 10); std::string httpResult = extractor->string(); chain.clear(); delete pump; apr_pool_destroy(pool); if(mResponse.notNull() && timeout) { mResponse->result(mResult); mResponse = NULL; } return httpResult; }
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); }
// virtual LLIOPipe::EStatus LLIOServerSocket::process_impl( const LLChannelDescriptors& channels, buffer_ptr_t& buffer, bool& eos, LLSD& context, LLPumpIO* pump) { LL_RECORD_BLOCK_TIME(FTM_PROCESS_SERVER_SOCKET); PUMP_DEBUG; if(!pump) { LL_WARNS() << "Need a pump for server socket." << LL_ENDL; return STATUS_ERROR; } if(!mInitialized) { PUMP_DEBUG; // This segment sets up the pump so that we do not call // process again until we have an incoming read, aka connect() // from a remote host. LL_DEBUGS() << "Initializing poll descriptor for LLIOServerSocket." << LL_ENDL; apr_pollfd_t poll_fd; poll_fd.p = NULL; poll_fd.desc_type = APR_POLL_SOCKET; poll_fd.reqevents = APR_POLLIN; poll_fd.rtnevents = 0x0; poll_fd.desc.s = mListenSocket->getSocket(); poll_fd.client_data = NULL; pump->setConditional(this, &poll_fd); mInitialized = true; return STATUS_OK; } // we are initialized, and told to process, so we must have a // socket waiting for a connection. LL_DEBUGS() << "accepting socket" << LL_ENDL; PUMP_DEBUG; apr_status_t status; LLSocket::ptr_t llsocket(LLSocket::create(status, mListenSocket)); //EStatus rv = STATUS_ERROR; if(llsocket && status == APR_SUCCESS) { PUMP_DEBUG; apr_sockaddr_t* remote_addr; apr_socket_addr_get(&remote_addr, APR_REMOTE, llsocket->getSocket()); char* remote_host_string; apr_sockaddr_ip_get(&remote_host_string, remote_addr); LLSD context; context["remote-host"] = remote_host_string; context["remote-port"] = remote_addr->port; LLPumpIO::chain_t chain; chain.push_back(LLIOPipe::ptr_t(new LLIOSocketReader(llsocket))); if(mReactor->build(chain, context)) { chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(llsocket))); pump->addChain(chain, mResponseTimeout); } else { LL_WARNS() << "Unable to build reactor to socket." << LL_ENDL; } } else { char buf[256]; LL_WARNS() << "Unable to accept linden socket: " << apr_strerror(status, buf, sizeof(buf)) << LL_ENDL; } PUMP_DEBUG; // This needs to always return success, lest it get removed from // the pump. return STATUS_OK; }
// virtual LLIOPipe::EStatus LLIOServerSocket::process_impl( const LLChannelDescriptors& channels, buffer_ptr_t& buffer, bool& eos, LLSD& context, LLPumpIO* pump) { PUMP_DEBUG; LLMemType m1(LLMemType::MTYPE_IO_TCP); if(!pump) { llwarns << "Need a pump for server socket." << llendl; return STATUS_ERROR; } if(!mInitialized) { PUMP_DEBUG; // This segment sets up the pump so that we do not call // process again until we have an incoming read, aka connect() // from a remote host. lldebugs << "Initializing poll descriptor for LLIOServerSocket." << llendl; apr_pollfd_t poll_fd; poll_fd.p = NULL; poll_fd.desc_type = APR_POLL_SOCKET; poll_fd.reqevents = APR_POLLIN; poll_fd.rtnevents = 0x0; poll_fd.desc.s = mListenSocket->getSocket(); poll_fd.client_data = NULL; pump->setConditional(this, &poll_fd); mInitialized = true; return STATUS_OK; } // we are initialized, and told to process, so we must have a // socket waiting for a connection. lldebugs << "accepting socket" << llendl; PUMP_DEBUG; apr_pool_t* new_pool = NULL; apr_status_t status = apr_pool_create(&new_pool, mPool); apr_socket_t* socket = NULL; status = apr_socket_accept( &socket, mListenSocket->getSocket(), new_pool); LLSocket::ptr_t llsocket(LLSocket::create(socket, new_pool)); //EStatus rv = STATUS_ERROR; if(llsocket) { PUMP_DEBUG; apr_sockaddr_t* remote_addr; apr_socket_addr_get(&remote_addr, APR_REMOTE, socket); char* remote_host_string; apr_sockaddr_ip_get(&remote_host_string, remote_addr); LLSD context; context["remote-host"] = remote_host_string; context["remote-port"] = remote_addr->port; LLPumpIO::chain_t chain; chain.push_back(LLIOPipe::ptr_t(new LLIOSocketReader(llsocket))); if(mReactor->build(chain, context)) { chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(llsocket))); pump->addChain(chain, mResponseTimeout); status = STATUS_OK; } else { llwarns << "Unable to build reactor to socket." << llendl; } } else { llwarns << "Unable to create linden socket." << llendl; } PUMP_DEBUG; // This needs to always return success, lest it get removed from // the pump. return STATUS_OK; }
// virtual LLIOPipe::EStatus LLSDRPCClient::process_impl( const LLChannelDescriptors& channels, buffer_ptr_t& buffer, bool& eos, LLSD& context, LLPumpIO* pump) { PUMP_DEBUG; LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT); if((STATE_NONE == mState) || (!pump)) { // You should have called the call() method already. return STATUS_PRECONDITION_NOT_MET; } EStatus rv = STATUS_DONE; switch(mState) { case STATE_READY: { PUMP_DEBUG; // lldebugs << "LLSDRPCClient::process_impl STATE_READY" << llendl; buffer->append( channels.out(), (U8*)mRequest.c_str(), mRequest.length()); context[CONTEXT_DEST_URI_SD_LABEL] = mURI; mState = STATE_WAITING_FOR_RESPONSE; break; } case STATE_WAITING_FOR_RESPONSE: { PUMP_DEBUG; // The input channel has the sd response in it. //lldebugs << "LLSDRPCClient::process_impl STATE_WAITING_FOR_RESPONSE" // << llendl; LLBufferStream resp(channels, buffer.get()); LLSD sd; LLSDSerialize::fromNotation(sd, resp, buffer->count(channels.in())); LLSDRPCResponse* response = (LLSDRPCResponse*)mResponse.get(); if (!response) { mState = STATE_DONE; break; } response->extractResponse(sd); if(EPBQ_PROCESS == mQueue) { LLPumpIO::chain_t chain; chain.push_back(mResponse); pump->addChain(chain, DEFAULT_CHAIN_EXPIRY_SECS); } else { pump->respond(mResponse.get()); } mState = STATE_DONE; break; } case STATE_DONE: default: PUMP_DEBUG; llinfos << "invalid state to process" << llendl; rv = STATUS_ERROR; break; } return rv; }
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); }