Added MIME body constructors from a header line. Adjusted SIP message parser to handle this.

git-svn-id: http://voip.null.ro/svn/yate@1607 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
marian 2008-01-09 11:32:35 +00:00
parent f58f72fa63
commit afded714aa
3 changed files with 156 additions and 28 deletions

View File

@ -302,9 +302,20 @@ YCLASSIMP(MimeBody,GenObject)
MimeBody::MimeBody(const String& type)
: m_type("Content-Type",type)
{
m_type.toLower();
DDebug(DebugAll,"MimeBody::MimeBody('%s') [%p]",m_type.c_str(),this);
}
// Build from header line
// Make sure the name of the header line is correct
MimeBody::MimeBody(const MimeHeaderLine& type)
: m_type(type,"Content-Type")
{
m_type.toLower();
DDebug(DebugAll,"MimeBody::MimeBody('%s','%s') [%p]",
m_type.name().c_str(),m_type.c_str(),this);
}
MimeBody::~MimeBody()
{
DDebug(DebugAll,"MimeBody::~MimeBody() '%s' [%p]",m_type.c_str(),this);
@ -317,16 +328,19 @@ const DataBlock& MimeBody::getBody() const
return m_body;
}
MimeBody* MimeBody::build(const char* buf, int len, const String& type)
// Method to build a MIME body from a type and data buffer
MimeBody* MimeBody::build(const char* buf, int len, const MimeHeaderLine& type)
{
DDebug(DebugAll,"MimeBody::build(%p,%d,'%s')",buf,len,type.c_str());
if ((len <= 0) || !buf)
return 0;
if (type == "application/sdp")
String what = type;
what.toLower();
if (what == "application/sdp")
return new MimeSdpBody(type,buf,len);
if (type == "application/dtmf-relay")
if (what == "application/dtmf-relay")
return new MimeLinesBody(type,buf,len);
if (type.startsWith("text/") || (type == "application/dtmf"))
if (what.startsWith("text/") || (what == "application/dtmf"))
return new MimeStringBody(type,buf,len);
return new MimeBinaryBody(type,buf,len);
}
@ -408,13 +422,13 @@ MimeSdpBody::MimeSdpBody()
MimeSdpBody::MimeSdpBody(const String& type, const char* buf, int len)
: MimeBody(type)
{
while (len > 0) {
String* line = getUnfoldedLine(buf,len);
int eq = line->find('=');
if (eq > 0)
m_lines.append(new NamedString(line->substr(0,eq),line->substr(eq+1)));
line->destruct();
}
buildLines(buf,len);
}
MimeSdpBody::MimeSdpBody(const MimeHeaderLine& type, const char* buf, int len)
: MimeBody(type)
{
buildLines(buf,len);
}
MimeSdpBody::MimeSdpBody(const MimeSdpBody& original)
@ -480,6 +494,18 @@ const NamedString* MimeSdpBody::getNextLine(const NamedString* line) const
return 0;
}
// Build the lines from a data buffer
void MimeSdpBody::buildLines(const char* buf, int len)
{
while (len > 0) {
String* line = getUnfoldedLine(buf,len);
int eq = line->find('=');
if (eq > 0)
m_lines.append(new NamedString(line->substr(0,eq),line->substr(eq+1)));
line->destruct();
}
}
YCLASSIMP(MimeBinaryBody,MimeBody)
@ -489,6 +515,12 @@ MimeBinaryBody::MimeBinaryBody(const String& type, const char* buf, int len)
m_body.assign((void*)buf,len);
}
MimeBinaryBody::MimeBinaryBody(const MimeHeaderLine& type, const char* buf, int len)
: MimeBody(type)
{
m_body.assign((void*)buf,len);
}
MimeBinaryBody::MimeBinaryBody(const MimeBinaryBody& original)
: MimeBody(original.getType())
{
@ -518,6 +550,11 @@ MimeStringBody::MimeStringBody(const String& type, const char* buf, int len)
{
}
MimeStringBody::MimeStringBody(const MimeHeaderLine& type, const char* buf, int len)
: MimeBody(type), m_text(buf,len)
{
}
MimeStringBody::MimeStringBody(const MimeStringBody& original)
: MimeBody(original.getType()), m_text(original.m_text)
{
@ -548,6 +585,13 @@ MimeLinesBody::MimeLinesBody(const String& type, const char* buf, int len)
m_lines.append(getUnfoldedLine(buf,len));
}
MimeLinesBody::MimeLinesBody(const MimeHeaderLine& type, const char* buf, int len)
: MimeBody(type)
{
while (len > 0)
m_lines.append(getUnfoldedLine(buf,len));
}
MimeLinesBody::MimeLinesBody(const MimeLinesBody& original)
: MimeBody(original.getType())
{

View File

@ -383,7 +383,6 @@ bool SIPMessage::parse(const char* buf, int len)
return false;
}
line->destruct();
String content;
int clen = -1;
while (len > 0) {
line = MimeBody::getUnfoldedLine(buf,len);
@ -416,11 +415,7 @@ bool SIPMessage::parse(const char* buf, int len)
else
header.append(new MimeHeaderLine(name,*line));
if (content.null() && (name &= "Content-Type")) {
content = *line;
content.toLower();
}
else if ((clen < 0) && (name &= "Content-Length"))
if ((clen < 0) && (name &= "Content-Length"))
clen = line->toInteger(-1,10);
else if ((m_cseq < 0) && (name &= "CSeq")) {
String seq = *line;
@ -440,7 +435,23 @@ bool SIPMessage::parse(const char* buf, int len)
len = clen;
}
}
body = MimeBody::build(buf,len,content);
const MimeHeaderLine* cType = getHeader("Content-Type");
if (cType)
body = MimeBody::build(buf,len,*cType);
// Move extra Content- header lines to body
if (body) {
ListIterator iter(header);
for (GenObject* o = 0; (o = iter.get());) {
MimeHeaderLine* line = static_cast<MimeHeaderLine*>(o);
if (!line->startsWith("Content-",false,true) || (*line &= "Content-Length"))
continue;
// Delete Content-Type and move all other lines to body
bool delobj = (line == cType);
header.remove(o,delobj);
if (!delobj)
body->appendHdr(line);
}
}
DDebug(DebugAll,"SIPMessage::parse %d header lines, body %p",
header.count(),body);
return true;

View File

@ -207,7 +207,10 @@ public:
};
/**
* Abstract base class for holding Multipurpose Internet Mail Extensions data
* Abstract base class for holding Multipurpose Internet Mail Extensions data.
* Keeps a Content-Type header line with body type and parameters and
* any additional header lines the body may have.
* The body type contains lower case characters.
* @short Abstract MIME data holder
*/
class YATE_API MimeBody : public GenObject
@ -232,6 +235,27 @@ public:
inline const MimeHeaderLine& getType() const
{ return m_type; }
/**
* Retrive the additional headers of this MIME body (other then Content-Type)
* @return The list of header lines of this MIME body
*/
inline const ObjList& headers() const
{ return m_headers; }
/**
* Append an additional header line to this body
* @param hdr The header line to append
*/
inline void appendHdr(MimeHeaderLine* hdr)
{ if (hdr) m_headers.append(hdr); }
/**
* Remove an additional header line from this body
* @param hdr The header line to remove
*/
inline void removeHdr(MimeHeaderLine* hdr)
{ if (hdr) m_headers.remove(hdr); }
/**
* Retrive the binary encoding of this MIME body
* @return Block of binary data
@ -239,7 +263,7 @@ public:
const DataBlock& getBody() const;
/**
* Check if this body is an Session Description Protocol
* Check if this body is a Session Description Protocol
* @return True if this body holds a SDP
*/
virtual bool isSDP() const
@ -262,11 +286,11 @@ public:
* Method to build a MIME body from a type and data buffer
* @param buf Pointer to buffer of data
* @param len Length of data in buffer
* @param type Name of the MIME type/subtype, must be lower case.
* This is the whole content type line, including the parameters
* @param type The header line declaring the body's content.
* Usually this is a Content-Type header line
* @return Newly allocated MIME body or NULL if type is unknown
*/
static MimeBody* build(const char* buf, int len, const String& type);
static MimeBody* build(const char* buf, int len, const MimeHeaderLine& type);
/**
* Utility method, returns an unfolded line and advances the pointer
@ -278,11 +302,20 @@ public:
protected:
/**
* Constructor to be used only by derived classes
* @param type Name of the MIME type/subtype, must be lower case
* Constructor to be used only by derived classes.
* Converts the MIME type string to lower case
* @param type The value of the Content-Type header line
*/
MimeBody(const String& type);
/**
* Constructor to be used only by derived classes.
* Builds this body from a header line.
* Converts the MIME type string to lower case
* @param type The content type header line
*/
MimeBody(const MimeHeaderLine& type);
/**
* Method that is called internally to build the binary encoded body
*/
@ -293,6 +326,11 @@ protected:
*/
mutable DataBlock m_body;
/**
* Additional body headers (other then Content-Type)
*/
ObjList m_headers;
private:
MimeHeaderLine m_type; // Content type header line
};
@ -317,6 +355,14 @@ public:
*/
MimeSdpBody(const String& type, const char* buf, int len);
/**
* Constructor from block of data
* @param type The content type header line
* @param buf Pointer to buffer of data
* @param len Length of data in buffer
*/
MimeSdpBody(const MimeHeaderLine& type, const char* buf, int len);
/**
* Destructor
*/
@ -383,6 +429,9 @@ protected:
virtual void buildBody() const;
private:
// Build the lines from a data buffer
void buildLines(const char* buf, int len);
ObjList m_lines;
};
@ -395,12 +444,20 @@ class YATE_API MimeBinaryBody : public MimeBody
public:
/**
* Constructor from block of data
* @param type Name of the specific MIME type/subtype
* @param buf Pointer to buffer of data
* @param len Length of data in buffer
* @param type Name of the specific MIME type/subtype
*/
MimeBinaryBody(const String& type, const char* buf, int len);
/**
* Constructor from block of data
* @param type The content type header line
* @param buf Pointer to buffer of data
* @param len Length of data in buffer
*/
MimeBinaryBody(const MimeHeaderLine& type, const char* buf, int len);
/**
* Destructor
*/
@ -440,12 +497,20 @@ class YATE_API MimeStringBody : public MimeBody
public:
/**
* Constructor from block of data
* @param type Name of the specific MIME type/subtype
* @param buf Pointer to buffer of data
* @param len Length of data in buffer
* @param type Name of the specific MIME type/subtype
*/
MimeStringBody(const String& type, const char* buf, int len = -1);
/**
* Constructor from block of data
* @param type The content type header line
* @param buf Pointer to buffer of data
* @param len Length of data in buffer
*/
MimeStringBody(const MimeHeaderLine& type, const char* buf, int len = -1);
/**
* Destructor
*/
@ -495,12 +560,20 @@ class YATE_API MimeLinesBody : public MimeBody
public:
/**
* Constructor from block of data
* @param type Name of the specific MIME type/subtype
* @param buf Pointer to buffer of data
* @param len Length of data in buffer
* @param type Name of the specific MIME type/subtype
*/
MimeLinesBody(const String& type, const char* buf, int len);
/**
* Constructor from block of data
* @param type The content type header line
* @param buf Pointer to buffer of data
* @param len Length of data in buffer
*/
MimeLinesBody(const MimeHeaderLine& type, const char* buf, int len);
/**
* Destructor
*/