void Application::clearAttributeHeaders(SPRequest& request) const { if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) { for (vector< pair<string,string> >::const_iterator i = m_unsetHeaders.begin(); i!=m_unsetHeaders.end(); ++i) request.clearHeader(i->first.c_str(), i->second.c_str()); return; } m_lock->rdlock(); if (m_unsetHeaders.empty()) { // No headers yet, so we have to request them from the remote half. m_lock->unlock(); m_lock->wrlock(); if (m_unsetHeaders.empty()) { SharedLock wrlock(m_lock, false); string addr=string(getId()) + "::getHeaders::Application"; DDF out,in = DDF(addr.c_str()); DDFJanitor jin(in),jout(out); out = getServiceProvider().getListenerService()->send(in); if (out.islist()) { DDF header = out.first(); while (header.isstring()) { m_unsetHeaders.push_back(pair<string,string>(header.name(),header.string())); header = out.next(); } } } else { m_lock->unlock(); } m_lock->rdlock(); } // Now holding read lock. SharedLock unsetLock(m_lock, false); for (vector< pair<string,string> >::const_iterator i = m_unsetHeaders.begin(); i!=m_unsetHeaders.end(); ++i) request.clearHeader(i->first.c_str(), i->second.c_str()); }
DDF SocketListener::send(const DDF& in) { #ifdef _DEBUG NDC ndc("send"); #endif log->debug("sending message (%s)", in.name() ? in.name() : "unnamed"); // Serialize data for transmission. ostringstream os; os << in; string ostr(os.str()); // Loop on the RPC in case we lost contact the first time through #ifdef WIN32 u_long len; #else uint32_t len; #endif int retry = 1; SocketListener::ShibSocket sock; while (retry >= 0) { sock = m_socketpool->get(); int outlen = ostr.length(); len = htonl(outlen); if (send(sock,(char*)&len,sizeof(len)) != sizeof(len) || send(sock,ostr.c_str(),outlen) != outlen) { log_error(); this->close(sock); if (retry) retry--; else throw ListenerException("Failure sending remoted message ($1).", params(1,in.name())); } else { // SUCCESS. retry = -1; } } log->debug("send completed, reading response message"); // Read the message. if (recv(sock,(char*)&len,sizeof(len)) != sizeof(len)) { log->error("error reading size of output message"); this->close(sock); throw ListenerException("Failure receiving response to remoted message ($1).", params(1,in.name())); } len = ntohl(len); char buf[16384]; int size_read; stringstream is; while (len && (size_read = recv(sock, buf, sizeof(buf))) > 0) { is.write(buf, size_read); len -= size_read; } if (len) { log->error("error reading output message from socket"); this->close(sock); throw ListenerException("Failure receiving response to remoted message ($1).", params(1,in.name())); } m_socketpool->put(sock); // Unmarshall data. DDF out; is >> out; // Check for exception to unmarshall and throw, otherwise return. if (out.isstring() && out.name() && !strcmp(out.name(),"exception")) { // Reconstitute exception object. DDFJanitor jout(out); XMLToolingException* except=NULL; try { except=XMLToolingException::fromString(out.string()); log->error("remoted message returned an error: %s", except->what()); } catch (XMLToolingException& e) { log->error("caught XMLToolingException while building the XMLToolingException: %s", e.what()); log->error("XML was: %s", out.string()); throw ListenerException("Remote call failed with an unparsable exception."); } auto_ptr<XMLToolingException> wrapper(except); wrapper->raise(); } return out; }