r3570 - in trunk/libmsip: include/libmsip source source/headers source/messages
erik at minisip.org
erik at minisip.org
Fri Mar 28 17:13:13 CET 2008
Author: erik
Date: 2008-03-28 17:13:12 +0100 (Fri, 28 Mar 2008)
New Revision: 3570
Modified:
trunk/libmsip/include/libmsip/SipUtils.h
trunk/libmsip/source/SipLayerTransport.cxx
trunk/libmsip/source/SipUtils.cxx
trunk/libmsip/source/headers/SipHeader.cxx
trunk/libmsip/source/messages/SipMessage.cxx
Log:
* Bug fix for parsing short form or strange format "Content-Length" values
in the transport layer.
The Content-Length header is special since we find and parse it
before the "real" parsing is started. We need the length value
so that we can find the end of the message.
"\nContent-Length: " was the only supported format. Now we support
any format. Examples:
"\nContent-Length :
100"
"\nl :
123"
* Fixed problem with content type introduced recently.
* Fixed bug when parsing the following kind of (strange) header:
"name: ;"
Modified: trunk/libmsip/include/libmsip/SipUtils.h
===================================================================
--- trunk/libmsip/include/libmsip/SipUtils.h 2008-03-18 15:12:34 UTC (rev 3569)
+++ trunk/libmsip/include/libmsip/SipUtils.h 2008-03-28 16:13:12 UTC (rev 3570)
@@ -34,6 +34,7 @@
static bool startsWith(std::string line, std::string part);
+ static int findEndOfHeader(const char *buf, unsigned bufSize, int &startIndex);
static int findEndOfHeader(const std::string &s, int &startIndex);
Modified: trunk/libmsip/source/SipLayerTransport.cxx
===================================================================
--- trunk/libmsip/source/SipLayerTransport.cxx 2008-03-18 15:12:34 UTC (rev 3569)
+++ trunk/libmsip/source/SipLayerTransport.cxx 2008-03-28 16:13:12 UTC (rev 3570)
@@ -35,6 +35,7 @@
#include<winsock2.h>
#endif
+#include<libmsip/SipUtils.h>
#include<libmsip/SipResponse.h>
#include<libmsip/SipRequest.h>
#include<libmsip/SipException.h>
@@ -248,31 +249,47 @@
length += BUFFER_UNIT;
}
-uint32_t SipMessageParser::findContentLength(){
- uint32_t i = 0;
- const char * contentLengthString = "\nContent-Length: ";
+/**
+ * Purpose: Used to find content length value (both long and short ("l:")
+ * form is supported).
+ */
+static int32_t findIntHeaderValue(char*buf, uint32_t buflen, string hName){
+ hName = "\n"+hName;
+ uint32_t nlen = hName.length();
- for( i = 0; i + 17 < index; i++ ){
- if( strNCaseCmp( contentLengthString, (char *)(buffer + i) , 17 ) == 0 ){
- uint32_t j = 0;
- string num;
-
- while( i + j + 17 < index && (buffer[i+j+17] == ' ' || buffer[i+j+17] == '\t') ){
- j++;
- }
-
- for( ; i + 17 + j < index ; j++ ){
- if( buffer[i+j+17] >= '0' && buffer[i+j+18] <= '9' ){
- num += buffer[i+j+17];
- }
- else break;
- }
- return atoi( num.c_str() );
+ //search whole buffer on each position
+ for (int i=0; i+nlen < buflen; i++){
+ if( strNCaseCmp( hName.c_str(), (char *)(buf + i) , nlen ) == 0 ){
+ uint32_t hnend = i+nlen;
+ while (hnend<buflen&& isWS(buf[hnend] ) )
+ hnend++;
+ //Break if not content length header (for example
+ //on header "Content-Length-Somethingelse:")
+ if (buf[hnend]!=':')
+ continue;
+
+ hnend++;
+
+ int tmpi=i;
+ uint32_t hend = SipUtils::findEndOfHeader((const char*)buf,buflen,tmpi);
+ uint32_t valstart=hnend;
+ while (valstart < hend && isWS(buf[valstart]))
+ valstart++;
+ return atoi(buf+valstart);
}
}
- return 0;
+ return -1;
}
+uint32_t SipMessageParser::findContentLength(){
+ int32_t clen = findIntHeaderValue((char*)buffer, index, "Content-Length");
+ if (clen<0)
+ clen = findIntHeaderValue((char*)buffer, index, "l");
+ if (clen<0)
+ clen=0;
+ return clen;
+}
+
class StreamThreadData : public InputReadyHandler{
public:
StreamThreadData( MRef<StreamSocket*>,
Modified: trunk/libmsip/source/SipUtils.cxx
===================================================================
--- trunk/libmsip/source/SipUtils.cxx 2008-03-18 15:12:34 UTC (rev 3569)
+++ trunk/libmsip/source/SipUtils.cxx 2008-03-28 16:13:12 UTC (rev 3570)
@@ -43,7 +43,14 @@
}
int SipUtils::findEndOfHeader(const string &buf, int &startIndex){
- unsigned bufSize = (unsigned)buf.size();
+ return findEndOfHeader(buf.c_str(), (unsigned)buf.size(), startIndex);
+}
+
+/**
+ * @startIndex will be adjusted to the start of the header (i.e.
+ * incremented past any whitespace).
+ */
+int SipUtils::findEndOfHeader(const char *buf, unsigned bufSize, int &startIndex){
int endi=bufSize;
unsigned i;
int parserState=0; // Parser states:
@@ -89,7 +96,7 @@
return i-3;
}
-/* alt. impl. that might be easier to understand
+/* alt. impl. that might be easier to understand (left here for documentation purposes)
switch (parserState){
case 0:
switch (c){
Modified: trunk/libmsip/source/headers/SipHeader.cxx
===================================================================
--- trunk/libmsip/source/headers/SipHeader.cxx 2008-03-18 15:12:34 UTC (rev 3569)
+++ trunk/libmsip/source/headers/SipHeader.cxx 2008-03-28 16:13:12 UTC (rev 3570)
@@ -223,7 +223,8 @@
if( ht == "ACCEPT-CONTACT" ) {
value_params = split(values[i],true,'\n');
- value_zero = value_params[0];
+ if (value_params.size()>0)
+ value_zero = value_params[0];
// cerr<<"valueline.substr(2): "+valueline.substr(2)<<endl;
} else if( ht == "CONTACT" ) {
size_t ltPos = values[i].find( '<' );
@@ -241,7 +242,8 @@
';' );
} else { //if there is no < or >, then just split into parameters ...
value_params = split(values[i],true,';');
- value_zero = value_params[0];
+ if (value_params.size()>0)
+ value_zero = value_params[0];
}
} else if( ht == "FROM" ||
ht == "TO" ||
@@ -260,11 +262,13 @@
';' );
} else { //if there is no < or >, then just split into parameters ...
value_params = split(values[i],true,';');
- value_zero = value_params[0];
+ if (value_params.size()>0)
+ value_zero = value_params[0];
}
} else {
value_params = split(values[i],true,paramSeparator);
- value_zero = value_params[0];
+ if (value_params.size()>0)
+ value_zero = value_params[0];
}
// cerr << "PARSER: Header type is: "<< headerType << endl;
Modified: trunk/libmsip/source/messages/SipMessage.cxx
===================================================================
--- trunk/libmsip/source/messages/SipMessage.cxx 2008-03-18 15:12:34 UTC (rev 3569)
+++ trunk/libmsip/source/messages/SipMessage.cxx 2008-03-28 16:13:12 UTC (rev 3570)
@@ -264,11 +264,13 @@
SipMessageContentFactoryFuncPtr contentFactory = contentFactories.getFactory( contentType );
if (contentFactory){
MRef<SipMessageContent*> smcref = contentFactory(contentbuf, contentType );
+ setContent( smcref );
+ }else{
setContent( new SipMessageContentUnknown( contentbuf, contentType ));
}
}else{
- merr << "WARNING: Sip message has content, but no content type! Content ignored."<< endl;
+ merr << "WARNING: unknown content type"<<endl;
setContent( new SipMessageContentUnknown( contentbuf, "unknown" ));
}
}
More information about the Minisip-devel
mailing list