1#if defined(HAVE_CONFIG_H)
20#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO
26#define SILO_CLEANUP_PERIOD 86400
57 virtual EncodeStream&
encode(EncodeStream& strm)
const { strm <<
"AsyncDrainSiloMessage(aor=" <<
mAor <<
")";
return strm; }
65 mSiloStore(config.getDataStore()->mSiloStore),
67 mMimeTypeFilterRegex(0),
68 mExpirationTime(config.getConfigUnsignedLong(
"MessageSiloExpirationTime", 2592000 )),
69 mAddDateHeader(config.getConfigBool(
"MessageSiloAddDateHeader", true)),
70 mMaxContentLength(config.getConfigUnsignedLong(
"MessageSiloMaxContentLength", 4096)),
71 mSuccessStatusCode(config.getConfigUnsignedShort(
"MessageSiloSuccessStatusCode", 202)),
72 mFilteredMimeTypeStatusCode(config.getConfigUnsignedShort(
"MessageSiloFilteredMimeTypeStatusCode", 200)),
73 mFailureStatusCode(config.getConfigUnsignedShort(
"MessageSiloFailureStatusCode", 480)),
74 mLastSiloCleanupTime(time(0))
76 Data destFilterRegex = config.
getConfigData(
"MessageSiloDestFilterRegex",
"",
false);
77 Data mimeTypeFilterRegex = config.
getConfigData(
"MessageSiloMimeTypeFilterRegex",
"application\\/im\\-iscomposing\\+xml",
false);
78 if(!destFilterRegex.
empty())
86 mDestFilterRegex =
new std::regex(destFilterRegex.
c_str(), std::regex_constants::ECMAScript | std::regex_constants::nosubs);
88 catch (std::regex_error&)
90 delete mDestFilterRegex;
91 ErrLog( <<
"MessageSilo has invalid destination filter regular expression: " << destFilterRegex);
95 if(!mimeTypeFilterRegex.
empty())
103 mMimeTypeFilterRegex=
new std::regex(mimeTypeFilterRegex.
c_str(), std::regex_constants::ECMAScript | std::regex_constants::nosubs);
105 catch (std::regex_error&)
107 delete mMimeTypeFilterRegex;
108 ErrLog( <<
"MessageSilo has invalid mime-type filter regular expression: " << mimeTypeFilterRegex);
109 mMimeTypeFilterRegex = 0;
119 delete mDestFilterRegex;
120 mDestFilterRegex = 0;
122 if(mMimeTypeFilterRegex)
124 delete mMimeTypeFilterRegex;
125 mMimeTypeFilterRegex = 0;
132 DebugLog(<<
"Monkey handling request: " << *
this <<
"; reqcontext = " << context);
140 if(originalRequest.
method() == MESSAGE &&
151 std::unique_ptr<ApplicationMessage> async_ptr(async);
166 if (mMimeTypeFilterRegex)
170 if(std::regex_search(async->
mMimeType.
c_str(), *mMimeTypeFilterRegex))
173 DebugLog( <<
" MESSAGE not silo'd due to Mime-Type filter: " << async->
mMimeType);
174 if(mFilteredMimeTypeStatusCode == 0)
190 if (mDestFilterRegex)
194 if(std::regex_search(async->
mDestUri.
c_str(), *mDestFilterRegex))
197 DebugLog( <<
" MESSAGE not silo'd due to destination filter: " << async->
mDestUri);
213 InfoLog(<<
"Message was Silo'd responding with a " << mSuccessStatusCode);
254 time_t now = time(0);
259 AbstractDb::SiloRecordList::iterator siloIt = recordList.begin();
260 for(; siloIt != recordList.end(); siloIt++)
262 DebugLog(<<
"DrainSilo: Dest=" << siloIt->mDestUri <<
", Source=" << siloIt->mSourceUri <<
", Datetime=" <<
Data::from(
DateCategory(siloIt->mOriginalSentTime)) <<
", MimeType=" << siloIt->mMimeType <<
", Body=" << siloIt->mMessageBody);
265 if((
unsigned long)(now - siloIt->mOriginalSentTime) <= mExpirationTime)
276 std::unique_ptr<SipMessage> msg(
new SipMessage);
280 msg->header(h_To) =
NameAddr(siloIt->mDestUri);
281 msg->header(h_MaxForwards).value() = 20;
282 msg->header(h_CSeq).method() = MESSAGE;
283 msg->header(h_CSeq).sequence() = 1;
284 msg->header(h_From) =
NameAddr(siloIt->mSourceUri);
288 msg->header(h_Vias).push_back(via);
293 msg->header(h_Routes).append(rec.
mSipPath);
299 msg->header(h_Date) =
DateCategory(siloIt->mOriginalSentTime);
316 HeaderFieldValue hfv(siloIt->mMessageBody.data(), siloIt->mMessageBody.size());
321 msg->setContents(&contents);
348 std::unique_ptr<ApplicationMessage> async_ptr(async);
#define SILO_CLEANUP_PERIOD
AsyncAddToSiloMessage(AsyncProcessor &proc, const resip::Data &tid, resip::TransactionUser *passedtu)
virtual EncodeStream & encode(EncodeStream &strm) const
output the entire message to stream
virtual EncodeStream & encode(EncodeStream &strm) const
output the entire message to stream
AsyncDrainSiloMessage(AsyncProcessor &proc, const resip::Data &tid, resip::TransactionUser *passedtu)
ContactList mRequestContacts
std::vector< SiloRecord > SiloRecordList
resip::Dispatcher * mAsyncDispatcher
MessageSilo(ProxyConfig &config, resip::Dispatcher *asyncDispatcher)
virtual processor_action_t process(RequestContext &)
virtual bool onAdd(resip::ServerRegistrationHandle, const resip::SipMessage ®)
Called when one or more contacts are added.
virtual bool asyncProcess(AsyncProcessorMessage *msg)
virtual const resip::Data & getTransactionId() const
resip::SipMessage & getOriginalRequest()
Returns the SipMessage associated with the server transaction.
ResponseContext & getResponseContext()
void sendResponse(resip::SipMessage &response)
resip::Data getTransactionId() const
void deleteSiloRecord(time_t originalSendTime, const resip::Data &tid)
void cleanupExpiredSiloRecords(uint64_t now, unsigned long expirationTime)
bool addMessage(const resip::Data &destUri, const resip::Data &sourceUri, time_t originalSendTime, const resip::Data &tid, const resip::Data &mimeType, const resip::Data &messageBody)
bool getSiloRecords(const resip::Data &uri, AbstractDb::SiloRecordList &recordList)
resip::Data getConfigData(const resip::Data &name, const resip::Data &defaultValue, bool useDefaultIfEmpty=false) const
Base class for all SIP body types.
virtual Data getBodyData() const
const Mime & getType() const
getter for mime type of message
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
static const Data Empty
Constant that represents a zero-length data.
const char * c_str() const
Returns a null-terminated string representing.
bool empty() const noexcept
Checks whether the Data is empty.
size_type size() const noexcept
Returns the number of bytes in this Data.
static Data from(const T &x)
Converts from arbitrary other type to Data.
Represents the "SIP-date" element in the RFC 3261 grammar.
A generic thread-bank class.
virtual bool post(std::unique_ptr< resip::ApplicationMessage > &work)
Posts a message to this thread bank.
static const int tagSize
bytes in to-tag& from-tag, should prob. live somewhere else
static Data computeTag(int numBytes)
static void makeResponse(SipMessage &response, const SipMessage &request, int responseCode, const Data &reason=Data::Empty, const Data &hostname=Data::Empty, const Data &warning=Data::Empty)
Make a response to a provided request.
static Data computeCallId()
Represents the "media-type" element in the RFC 3261 grammar.
virtual void parse(ParseBuffer &pb)
Represents the "name-addr" and the "addr-spec" elements in the RFC 3261 grammar.
void remove(const Param< NameAddr > ¶mType)
Provides string-parsing functionality with protection from buffer overflow.
bool empty() const
return true or false indicating whether the mParsers vector is empty or not
SIP body type for holding plain contents (MIME content-type text/plain).
Represents the "Request-Line" element in the RFC 3261 grammar.
Represents a SIP message.
Contents * getContents() const
Retrieves the body of a SIP message.
const RequestLine & header(const RequestLineType &l) const
Returns the RequestLine. This is only valid for request messages.
resip::MethodTypes method() const
returns the method type of the message
void send(const SipMessage &msg, TransactionUser *tu=0)
allows a TU to send a message
The base-class for an RFC 3261 Transaction User.
FlowKey mFlowKey
This is a (largely) opaque key that subclasses of Transport will use to help record/find flows.
Data getAOR(bool addPort) const
Represents the "via-parm" element in the RFC 3261 grammar.
This Class is used to implement a primitive form of RPC using loose XML formatting.
dcm! – add UnusedChecking(_enum) below;
RequestLineType h_RequestLine
std::list< ContactInstanceRecord > ContactList
unsigned __int64 uint64_t