/[resiprocate]/branches/b-directory-reorg/sip/resiprocate/SipFrag.cxx
ViewVC logotype

Contents of /branches/b-directory-reorg/sip/resiprocate/SipFrag.cxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5271 - (show annotations) (download)
Thu Aug 18 23:43:07 2005 UTC (14 years, 3 months ago) by jason
File size: 8265 byte(s)
new directory reorg proposal
1 #if defined(HAVE_CONFIG_H)
2 #include "resiprocate/config.hxx"
3 #endif
4
5 #include "resiprocate/MsgHeaderScanner.hxx"
6 #include "resiprocate/SipFrag.hxx"
7 #include "resiprocate/SipMessage.hxx"
8 #include "resiprocate/os/Logger.hxx"
9 #include "resiprocate/os/ParseBuffer.hxx"
10 #include "resiprocate/os/WinLeakCheck.hxx"
11
12 using namespace resip;
13 using namespace std;
14
15 #define RESIPROCATE_SUBSYSTEM Subsystem::SIP
16
17 bool
18 SipFrag::init()
19 {
20 static ContentsFactory<SipFrag> factory;
21 (void)factory;
22 return true;
23 }
24
25 SipFrag::SipFrag(const Mime& contentsType)
26 : Contents(contentsType),
27 mMessage(new SipMessage())
28 {}
29
30 SipFrag::SipFrag(HeaderFieldValue* hfv, const Mime& contentsType)
31 : Contents(hfv, contentsType),
32 mMessage(0)
33 {
34 }
35
36 SipFrag::SipFrag(const SipFrag& rhs)
37 : Contents(rhs),
38 mMessage(rhs.mMessage ? new SipMessage(*rhs.mMessage) : 0)
39 {
40 }
41
42 SipFrag::~SipFrag()
43 {
44 delete mMessage;
45 }
46
47 SipFrag&
48 SipFrag::operator=(const SipFrag& rhs)
49 {
50 if (this != &rhs)
51 {
52 Contents::operator=(rhs);
53 delete mMessage;
54 if (rhs.mMessage)
55 {
56 mMessage = new SipMessage(*rhs.mMessage);
57 }
58 else
59 {
60 mMessage = 0;
61 }
62 }
63
64 return *this;
65 }
66
67 Contents*
68 SipFrag::clone() const
69 {
70 return new SipFrag(*this);
71 }
72
73 const Mime&
74 SipFrag::getStaticType()
75 {
76 static Mime type("message", "sipfrag");
77 //static Mime type("application", "sipfrag");
78 return type;
79 }
80
81 SipMessage&
82 SipFrag::message()
83 {
84 checkParsed();
85 return *mMessage;
86 }
87
88 const SipMessage&
89 SipFrag::message() const
90 {
91 checkParsed();
92 return *mMessage;
93 }
94
95 std::ostream&
96 SipFrag::encodeParsed(std::ostream& str) const
97 {
98 mMessage->encodeSipFrag(str);
99
100 return str;
101 }
102
103 bool
104 SipFrag::hasStartLine(char* buffer, int size)
105 {
106 #if 0
107 //!dcm! -- this probably inefficient, but the SIP grammer makes this very
108 //difficult. Better here than in the MsgHeaderScanner. There's also proabably a
109 //way to make a header that matches the requestLine check which isn't a
110 //request line.
111
112 ParseBuffer pbCheck(buffer, size);
113 pbCheck.skipWhitespace(); //gratuitous?
114
115 //!dcm! -- could extend to SIP/2.0, but nobody should start a hname with SIP/
116 if ((pbCheck.end() - pbCheck.position()) > 4 &&
117 strncmp(pbCheck.position(), "SIP/", 4) == 0)
118 {
119 return true;
120 }
121 else
122 {
123 pbCheck.skipToChars(Symbols::CRLF);
124 if (pbCheck.eof())
125 {
126 //false positive, let MsgHeaderScanner sort the exact error out
127 return true;
128 }
129
130 pbCheck.skipBackToChar(Symbols::SPACE[0]);
131 if (pbCheck.position() == pbCheck.start())
132 {
133 return false;
134 }
135
136 if ((pbCheck.end() - pbCheck.position()) > 4 &&
137 strncmp(pbCheck.position(), "SIP/", 4) == 0)
138 {
139 return true;
140 }
141 else
142 {
143 return false;
144 }
145 }
146 #else
147 //!dcm! -- better approach, remove above if this is proven to be correct
148 ParseBuffer pbCheck(buffer, size);
149 pbCheck.skipWhitespace(); //gratuitous?
150 pbCheck.skipToOneOf(" \t:\r\n");
151 while(!pbCheck.eof())
152 {
153 switch(*pbCheck.position())
154 {
155 case ':':
156 return false;
157 case ' ':
158 case '\t':
159 pbCheck.skipChar();
160 break;
161 case '\r':
162 case '\n':
163 return false;
164 default:
165 return true;
166 }
167 }
168 return true; //false positive, let MsgHeaderScanner sort the exact error out
169 #endif
170 }
171
172 void
173 SipFrag::parse(ParseBuffer& pb)
174 {
175 // DebugLog(<< "SipFrag::parse: " << pb.position());
176
177 mMessage = new SipMessage();
178
179 pb.assertNotEof();
180 const char *constBuffer = pb.position();
181 char *buffer = const_cast<char *>(constBuffer);
182
183 size_t size = pb.end() - pb.position();
184
185 // !ah! removed size check .. process() cannot process more
186 // than size bytes of the message.
187
188
189 MsgHeaderScanner msgHeaderScanner;
190 msgHeaderScanner.prepareForFrag(mMessage, hasStartLine(buffer, size));
191 enum { sentinelLength = 4 }; // Two carriage return / line feed pairs.
192 char saveTermCharArray[sentinelLength];
193 char *termCharArray = buffer + size;
194 saveTermCharArray[0] = termCharArray[0];
195 saveTermCharArray[1] = termCharArray[1];
196 saveTermCharArray[2] = termCharArray[2];
197 saveTermCharArray[3] = termCharArray[3];
198 termCharArray[0] = '\r';
199 termCharArray[1] = '\n';
200 termCharArray[2] = '\r';
201 termCharArray[3] = '\n';
202 char *scanTermCharPtr;
203 MsgHeaderScanner::ScanChunkResult scanChunkResult =
204 msgHeaderScanner.scanChunk(buffer,
205 size + sentinelLength,
206 &scanTermCharPtr);
207 termCharArray[0] = saveTermCharArray[0];
208 termCharArray[1] = saveTermCharArray[1];
209 termCharArray[2] = saveTermCharArray[2];
210 termCharArray[3] = saveTermCharArray[3];
211 // !dlb! not at all clear what to do here
212 // see: "// tests end of message problem (MsgHeaderScanner?)"
213 // in test/testSipFrag.cxx
214 if (false && scanChunkResult != MsgHeaderScanner::scrEnd)
215 {
216 CerrLog(<< "not MsgHeaderScanner::scrEnd");
217 pb.fail(__FILE__, __LINE__);
218 }
219 else
220 {
221 size_t used = scanTermCharPtr - buffer;
222
223 // !ah! I think this is broken .. if we are UDP then the
224 // remainder is the SigFrag, not the Content-Length... ??
225 if (mMessage->exists(h_ContentLength))
226 {
227 mMessage->setBody(scanTermCharPtr,
228 static_cast<int>(size - used));
229 }
230 else
231 {
232 // !ah! So the headers weren't complete. Why are we here?
233 // !dlb!
234 if (mMessage->exists(h_ContentLength))
235 {
236 pb.reset(buffer + used);
237 pb.skipChars(Symbols::CRLF);
238 mMessage->setBody(pb.position(),int(pb.end()-pb.position()) );
239 }
240 }
241 pb.reset(pb.end());
242 }
243 }
244
245 /* ====================================================================
246 * The Vovida Software License, Version 1.0
247 *
248 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
249 *
250 * Redistribution and use in source and binary forms, with or without
251 * modification, are permitted provided that the following conditions
252 * are met:
253 *
254 * 1. Redistributions of source code must retain the above copyright
255 * notice, this list of conditions and the following disclaimer.
256 *
257 * 2. Redistributions in binary form must reproduce the above copyright
258 * notice, this list of conditions and the following disclaimer in
259 * the documentation and/or other materials provided with the
260 * distribution.
261 *
262 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
263 * and "Vovida Open Communication Application Library (VOCAL)" must
264 * not be used to endorse or promote products derived from this
265 * software without prior written permission. For written
266 * permission, please contact vocal@vovida.org.
267 *
268 * 4. Products derived from this software may not be called "VOCAL", nor
269 * may "VOCAL" appear in their name, without prior written
270 * permission of Vovida Networks, Inc.
271 *
272 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
273 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
274 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
275 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
276 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
277 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
278 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
279 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
280 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
281 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
282 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
283 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
284 * DAMAGE.
285 *
286 * ====================================================================
287 *
288 * This software consists of voluntary contributions made by Vovida
289 * Networks, Inc. and many individuals on behalf of Vovida Networks,
290 * Inc. For more information on Vovida Networks, Inc., please see
291 * <http://www.vovida.org/>.
292 *
293 */

Properties

Name Value
svn:eol-style LF

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27