reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
ServerPublication.cxx
Go to the documentation of this file.
10
11#include <utility>
12
13using namespace resip;
14
15ServerPublication::ServerPublication(DialogUsageManager& dum,
16 const Data& etag,
17 const SipMessage& msg)
18 : BaseUsage(dum),
19 mLastResponse(std::make_shared<SipMessage>()),
20 mEtag(etag),
21 mEventType(msg.header(h_Event).value()),
22 mDocumentKey(msg.header(h_RequestLine).uri().getAor()),
23 mTimerSeq(0)
24{
25}
26
28{
29 mDum.mServerPublications.erase(getEtag());
30}
31
37
38const Data&
40{
41 return mEtag;
42}
43
44const Data&
46{
47 return mDocumentKey;
48}
49
50Data
52{
53 return mLastRequest.header(h_From).uri().getAor();
54}
55
56void
58{
59 Data key = mEventType + mDocumentKey;
60 std::pair<DialogUsageManager::ServerSubscriptions::iterator,DialogUsageManager::ServerSubscriptions::iterator> subs;
61 subs = mDum.mServerSubscriptions.equal_range(key);
62
64 if (handler)
65 {
66 for (DialogUsageManager::ServerSubscriptions::iterator i = subs.first; i != subs.second; ++i)
67 {
68 handler->onPublished(i->second->getHandle(),
69 getHandle(),
70 mLastBody.mContents.get(),
71 mLastBody.mAttributes.get());
72 }
73 }
74 mLastBody.mContents.reset();
75 mLastBody.mAttributes.reset();
76}
77
78
79std::shared_ptr<SipMessage>
81{
82 Helper::makeResponse(*mLastResponse, mLastRequest, statusCode);
83 mLastResponse->header(h_Expires).value() = mExpires;
84
85 return mLastResponse;
86}
87
88std::shared_ptr<SipMessage>
90{
91 Helper::makeResponse(*mLastResponse, mLastRequest, statusCode);
92 mLastResponse->header(h_Expires).value() = mExpires;
93 return mLastResponse;
94}
95
96void
98{
99 delete this;
100}
101
102void
104{
105 resip_assert(msg.isRequest());
107 mLastRequest = msg;
108 mExpires = 3600; //bad
109 if (msg.exists(h_Expires))
110 {
111 mExpires = msg.header(h_Expires).value();
112 }
113 if (msg.exists(h_SIPIfMatch))
114 {
115 if (mExpires == 0)
116 {
117 handler->onRemoved(getHandle(), mEtag, msg, mExpires);
118 Helper::makeResponse(*mLastResponse, mLastRequest, 200);
119 mLastResponse->header(h_Expires).value() = mExpires;
120 mDum.send(mLastResponse);
121
122 if (mDum.mPublicationPersistenceManager)
123 {
124 // Remove document from persistence manager
125 mDum.mPublicationPersistenceManager->removeDocument(mEventType, mDocumentKey, mEtag, Timer::getTimeSecs());
126 }
127 // Notify all matching subscriptions removal - by sending a null body
129
130 delete this;
131 return;
132 }
133 mLastBody = Helper::extractFromPkcs7(msg, *mDum.getSecurity());
134 if (msg.getContents())
135 {
136 handler->onUpdate(getHandle(), mEtag, msg,
137 mLastBody.mContents.get(),
138 mLastBody.mAttributes.get(),
139 mExpires);
140 }
141 else
142 {
143 handler->onRefresh(getHandle(), mEtag, msg,
144 mLastBody.mContents.get(),
145 mLastBody.mAttributes.get(),
146 mExpires);
147 }
148 }
149 else
150 {
151 if (mExpires == 0)
152 {
153 // This can happen if we receive an unpublish after startup with an e-tag.
154 // We will then 412 the request. The sender will likely resend with no e-tag
155 // and we will end up here. There is nothing really to do. The sender is
156 // essentially unpublishing a publication we don't have, so we can just ignore it.
157 Helper::makeResponse(*mLastResponse, mLastRequest, 200);
158 mLastResponse->header(h_Expires).value() = mExpires;
159 mDum.send(mLastResponse);
160 delete this;
161 return;
162 }
163 mLastBody = Helper::extractFromPkcs7(msg, *mDum.getSecurity());
164 handler->onInitial(getHandle(), mEtag, msg,
165 mLastBody.mContents.get(),
166 mLastBody.mAttributes.get(),
167 mExpires);
168 }
169}
170
171void
173{
174 // If this timer expires with a matching seq - it indicates the publisher didn't
175 // rePUBLISH within the expiry time and the publication has expired.
176 if (msg.seq() == mTimerSeq)
177 {
179 handler->onExpired(getHandle(), mEtag);
180
181 if (mDum.mPublicationPersistenceManager)
182 {
183 // Remove document from persistence manager
184 mDum.mPublicationPersistenceManager->removeDocument(mEventType, mDocumentKey, mEtag, Timer::getTimeSecs());
185 }
186
187 delete this;
188 }
189}
190
191void
192ServerPublication::send(std::shared_ptr<SipMessage> response)
193{
194 resip_assert(response->isResponse());
195 response->header(h_SIPETag).value() = mEtag;
196 mDum.send(response);
197 if (response->header(h_StatusLine).statusCode() >= 300)
198 {
199 delete this;
200 }
201 else
202 {
203 uint32_t expires = response->header(h_Expires).value(); // ServerPublicationHandler may have changed expiration time
204 mDum.addTimer(DumTimeout::Publication, expires, getBaseHandle(), ++mTimerSeq);
205
206 if (mDum.mPublicationPersistenceManager)
207 {
208 // Add document to persistence manager
210 mDum.mPublicationPersistenceManager->addUpdateDocument(mEventType, mDocumentKey, mEtag, now + expires, mLastBody.mContents.get(), mLastBody.mAttributes.get());
211 }
212
213 // If we don't have a contents then it was a refresh (note: Unpublishes don't go through here)
214 if (mLastBody.mContents)
215 {
216 // Notify all matching subscriptions of new document
217 // Note: we do this after all uses of mLastBody, since calling this will release the contents stored in mLastBody
219 }
220 }
221}
222
224ServerPublication::dump(EncodeStream& strm) const
225{
226 strm << "ServerPublication " << mDocumentKey << " " << mEventType;
227 return strm;
228}
229
230
231/* ====================================================================
232 * The Vovida Software License, Version 1.0
233 *
234 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
235 *
236 * Redistribution and use in source and binary forms, with or without
237 * modification, are permitted provided that the following conditions
238 * are met:
239 *
240 * 1. Redistributions of source code must retain the above copyright
241 * notice, this list of conditions and the following disclaimer.
242 *
243 * 2. Redistributions in binary form must reproduce the above copyright
244 * notice, this list of conditions and the following disclaimer in
245 * the documentation and/or other materials provided with the
246
247 * distribution.
248 *
249 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
250 * and "Vovida Open Communication Application Library (VOCAL)" must
251 * not be used to endorse or promote products derived from this
252 * software without prior written permission. For written
253 * permission, please contact vocal@vovida.org.
254 *
255 * 4. Products derived from this software may not be called "VOCAL", nor
256 * may "VOCAL" appear in their name, without prior written
257 * permission of Vovida Networks, Inc.
258 *
259 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
260 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
261 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
262 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
263 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
264 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
265 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
266 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
267 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
268 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
269 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
270 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
271 * DAMAGE.
272 *
273 * ====================================================================
274 *
275 * This software consists of voluntary contributions made by Vovida
276 * Networks, Inc. and many individuals on behalf of Vovida Networks,
277 * Inc. For more information on Vovida Networks, Inc., please see
278 * <http://www.vovida.org/>.
279 *
280 */
#define resip_assert(x)
This file needs to work for both C and C++ code.
static Data getAor(const Data &filename, const Security::PEMType &pemType)
Definition Security.cxx:94
BaseUsageHandle getBaseHandle() const
Definition BaseUsage.cxx:36
DialogUsageManager & mDum
Definition BaseUsage.hxx:43
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
Definition Data.hxx:90
void send(std::shared_ptr< SipMessage > request)
ServerPublicationHandler * getServerPublicationHandler(const Data &eventType)
ServerSubscriptionHandler * getServerSubscriptionHandler(const Data &eventType)
unsigned int seq() const
static ContentsSecAttrs extractFromPkcs7(const SipMessage &message, Security &security)
Definition Helper.cxx:2124
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.
Definition Helper.cxx:412
virtual void addUpdateDocument(const PubDocument &document)=0
virtual bool removeDocument(const Data &eventType, const Data &documentKey, const Data &eTag, uint64_t lastUpdated, bool syncPublication=false)=0
const Uri & uri() const
virtual void onRemoved(ServerPublicationHandle, const Data &etag, const SipMessage &pub, uint32_t expires)=0
virtual void onUpdate(ServerPublicationHandle, const Data &etag, const SipMessage &pub, const Contents *contents, const SecurityAttributes *attrs, uint32_t expires)=0
virtual void onExpired(ServerPublicationHandle, const Data &etag)=0
virtual void onInitial(ServerPublicationHandle, const Data &etag, const SipMessage &pub, const Contents *contents, const SecurityAttributes *attrs, uint32_t expires)=0
virtual void onRefresh(ServerPublicationHandle, const Data &etag, const SipMessage &pub, const Contents *contents, const SecurityAttributes *attrs, uint32_t expires)=0
std::shared_ptr< SipMessage > accept(int statusCode=200)
std::shared_ptr< SipMessage > reject(int responseCode)
virtual EncodeStream & dump(EncodeStream &strm) const
virtual void dispatch(const SipMessage &msg)
const Data & getEtag() const
void send(std::shared_ptr< SipMessage > response)
Handle< ServerPublication > ServerPublicationHandle
ServerPublicationHandle getHandle()
const Data & getDocumentKey() const
virtual void onPublished(ServerSubscriptionHandle associated, ServerPublicationHandle publication, const Contents *contents, const SecurityAttributes *attrs)
Represents a SIP message.
bool isRequest() const
Returns true if message is a request, false otherwise.
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.
bool exists(const HeaderBase &headerType) const
Returns true if the given header field is present, false otherwise.
static uint64_t getTimeSecs()
Returns the current clock time in seconds.
Definition Timer.hxx:78
Data getAor() const
Definition Uri.cxx:1095
dcm! – add UnusedChecking(_enum) below;
StatusLineType h_StatusLine
Definition Headers.cxx:348
unsigned long long uint64_t
Definition Stun.hxx:39
unsigned int uint32_t
Definition Stun.hxx:34
RequestLineType h_RequestLine
Definition Headers.cxx:347
#define EncodeStream
std::unique_ptr< Contents > mContents
Definition Helper.hxx:607
std::unique_ptr< SecurityAttributes > mAttributes
Definition Helper.hxx:608