// 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, 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); req->checkRootCertificate(true); // Insert custom headers is 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()); } } // 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"); } } 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) { 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_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); status = STATUS_OK; } else { llwarns << "Unable to build reactor to socket." << llendl; } } else { char buf[256]; llwarns << "Unable to accept linden socket: " << apr_strerror(status, buf, sizeof(buf)) << llendl; } PUMP_DEBUG; // This needs to always return success, lest it get removed from // the pump. return STATUS_OK; }