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:
parent
f58f72fa63
commit
afded714aa
|
@ -302,9 +302,20 @@ YCLASSIMP(MimeBody,GenObject)
|
||||||
MimeBody::MimeBody(const String& type)
|
MimeBody::MimeBody(const String& type)
|
||||||
: m_type("Content-Type",type)
|
: m_type("Content-Type",type)
|
||||||
{
|
{
|
||||||
|
m_type.toLower();
|
||||||
DDebug(DebugAll,"MimeBody::MimeBody('%s') [%p]",m_type.c_str(),this);
|
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()
|
MimeBody::~MimeBody()
|
||||||
{
|
{
|
||||||
DDebug(DebugAll,"MimeBody::~MimeBody() '%s' [%p]",m_type.c_str(),this);
|
DDebug(DebugAll,"MimeBody::~MimeBody() '%s' [%p]",m_type.c_str(),this);
|
||||||
|
@ -317,16 +328,19 @@ const DataBlock& MimeBody::getBody() const
|
||||||
return m_body;
|
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());
|
DDebug(DebugAll,"MimeBody::build(%p,%d,'%s')",buf,len,type.c_str());
|
||||||
if ((len <= 0) || !buf)
|
if ((len <= 0) || !buf)
|
||||||
return 0;
|
return 0;
|
||||||
if (type == "application/sdp")
|
String what = type;
|
||||||
|
what.toLower();
|
||||||
|
if (what == "application/sdp")
|
||||||
return new MimeSdpBody(type,buf,len);
|
return new MimeSdpBody(type,buf,len);
|
||||||
if (type == "application/dtmf-relay")
|
if (what == "application/dtmf-relay")
|
||||||
return new MimeLinesBody(type,buf,len);
|
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 MimeStringBody(type,buf,len);
|
||||||
return new MimeBinaryBody(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)
|
MimeSdpBody::MimeSdpBody(const String& type, const char* buf, int len)
|
||||||
: MimeBody(type)
|
: MimeBody(type)
|
||||||
{
|
{
|
||||||
while (len > 0) {
|
buildLines(buf,len);
|
||||||
String* line = getUnfoldedLine(buf,len);
|
}
|
||||||
int eq = line->find('=');
|
|
||||||
if (eq > 0)
|
MimeSdpBody::MimeSdpBody(const MimeHeaderLine& type, const char* buf, int len)
|
||||||
m_lines.append(new NamedString(line->substr(0,eq),line->substr(eq+1)));
|
: MimeBody(type)
|
||||||
line->destruct();
|
{
|
||||||
}
|
buildLines(buf,len);
|
||||||
}
|
}
|
||||||
|
|
||||||
MimeSdpBody::MimeSdpBody(const MimeSdpBody& original)
|
MimeSdpBody::MimeSdpBody(const MimeSdpBody& original)
|
||||||
|
@ -480,6 +494,18 @@ const NamedString* MimeSdpBody::getNextLine(const NamedString* line) const
|
||||||
return 0;
|
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)
|
YCLASSIMP(MimeBinaryBody,MimeBody)
|
||||||
|
|
||||||
|
@ -489,6 +515,12 @@ MimeBinaryBody::MimeBinaryBody(const String& type, const char* buf, int len)
|
||||||
m_body.assign((void*)buf,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)
|
MimeBinaryBody::MimeBinaryBody(const MimeBinaryBody& original)
|
||||||
: MimeBody(original.getType())
|
: 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)
|
MimeStringBody::MimeStringBody(const MimeStringBody& original)
|
||||||
: MimeBody(original.getType()), m_text(original.m_text)
|
: 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));
|
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)
|
MimeLinesBody::MimeLinesBody(const MimeLinesBody& original)
|
||||||
: MimeBody(original.getType())
|
: MimeBody(original.getType())
|
||||||
{
|
{
|
||||||
|
|
|
@ -383,7 +383,6 @@ bool SIPMessage::parse(const char* buf, int len)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
line->destruct();
|
line->destruct();
|
||||||
String content;
|
|
||||||
int clen = -1;
|
int clen = -1;
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
line = MimeBody::getUnfoldedLine(buf,len);
|
line = MimeBody::getUnfoldedLine(buf,len);
|
||||||
|
@ -416,11 +415,7 @@ bool SIPMessage::parse(const char* buf, int len)
|
||||||
else
|
else
|
||||||
header.append(new MimeHeaderLine(name,*line));
|
header.append(new MimeHeaderLine(name,*line));
|
||||||
|
|
||||||
if (content.null() && (name &= "Content-Type")) {
|
if ((clen < 0) && (name &= "Content-Length"))
|
||||||
content = *line;
|
|
||||||
content.toLower();
|
|
||||||
}
|
|
||||||
else if ((clen < 0) && (name &= "Content-Length"))
|
|
||||||
clen = line->toInteger(-1,10);
|
clen = line->toInteger(-1,10);
|
||||||
else if ((m_cseq < 0) && (name &= "CSeq")) {
|
else if ((m_cseq < 0) && (name &= "CSeq")) {
|
||||||
String seq = *line;
|
String seq = *line;
|
||||||
|
@ -440,7 +435,23 @@ bool SIPMessage::parse(const char* buf, int len)
|
||||||
len = clen;
|
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",
|
DDebug(DebugAll,"SIPMessage::parse %d header lines, body %p",
|
||||||
header.count(),body);
|
header.count(),body);
|
||||||
return true;
|
return true;
|
||||||
|
|
93
yatemime.h
93
yatemime.h
|
@ -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
|
* @short Abstract MIME data holder
|
||||||
*/
|
*/
|
||||||
class YATE_API MimeBody : public GenObject
|
class YATE_API MimeBody : public GenObject
|
||||||
|
@ -232,6 +235,27 @@ public:
|
||||||
inline const MimeHeaderLine& getType() const
|
inline const MimeHeaderLine& getType() const
|
||||||
{ return m_type; }
|
{ 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
|
* Retrive the binary encoding of this MIME body
|
||||||
* @return Block of binary data
|
* @return Block of binary data
|
||||||
|
@ -239,7 +263,7 @@ public:
|
||||||
const DataBlock& getBody() const;
|
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
|
* @return True if this body holds a SDP
|
||||||
*/
|
*/
|
||||||
virtual bool isSDP() const
|
virtual bool isSDP() const
|
||||||
|
@ -262,11 +286,11 @@ public:
|
||||||
* Method to build a MIME body from a type and data buffer
|
* Method to build a MIME body from a type and data buffer
|
||||||
* @param buf Pointer to buffer of data
|
* @param buf Pointer to buffer of data
|
||||||
* @param len Length of data in buffer
|
* @param len Length of data in buffer
|
||||||
* @param type Name of the MIME type/subtype, must be lower case.
|
* @param type The header line declaring the body's content.
|
||||||
* This is the whole content type line, including the parameters
|
* Usually this is a Content-Type header line
|
||||||
* @return Newly allocated MIME body or NULL if type is unknown
|
* @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
|
* Utility method, returns an unfolded line and advances the pointer
|
||||||
|
@ -278,11 +302,20 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Constructor to be used only by derived classes
|
* Constructor to be used only by derived classes.
|
||||||
* @param type Name of the MIME type/subtype, must be lower case
|
* Converts the MIME type string to lower case
|
||||||
|
* @param type The value of the Content-Type header line
|
||||||
*/
|
*/
|
||||||
MimeBody(const String& type);
|
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
|
* Method that is called internally to build the binary encoded body
|
||||||
*/
|
*/
|
||||||
|
@ -293,6 +326,11 @@ protected:
|
||||||
*/
|
*/
|
||||||
mutable DataBlock m_body;
|
mutable DataBlock m_body;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Additional body headers (other then Content-Type)
|
||||||
|
*/
|
||||||
|
ObjList m_headers;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MimeHeaderLine m_type; // Content type header line
|
MimeHeaderLine m_type; // Content type header line
|
||||||
};
|
};
|
||||||
|
@ -317,6 +355,14 @@ public:
|
||||||
*/
|
*/
|
||||||
MimeSdpBody(const String& type, const char* buf, int len);
|
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
|
* Destructor
|
||||||
*/
|
*/
|
||||||
|
@ -383,6 +429,9 @@ protected:
|
||||||
virtual void buildBody() const;
|
virtual void buildBody() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Build the lines from a data buffer
|
||||||
|
void buildLines(const char* buf, int len);
|
||||||
|
|
||||||
ObjList m_lines;
|
ObjList m_lines;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -395,12 +444,20 @@ class YATE_API MimeBinaryBody : public MimeBody
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor from block of data
|
* Constructor from block of data
|
||||||
|
* @param type Name of the specific MIME type/subtype
|
||||||
* @param buf Pointer to buffer of data
|
* @param buf Pointer to buffer of data
|
||||||
* @param len Length of data in buffer
|
* @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);
|
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
|
* Destructor
|
||||||
*/
|
*/
|
||||||
|
@ -440,12 +497,20 @@ class YATE_API MimeStringBody : public MimeBody
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor from block of data
|
* Constructor from block of data
|
||||||
|
* @param type Name of the specific MIME type/subtype
|
||||||
* @param buf Pointer to buffer of data
|
* @param buf Pointer to buffer of data
|
||||||
* @param len Length of data in buffer
|
* @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);
|
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
|
* Destructor
|
||||||
*/
|
*/
|
||||||
|
@ -495,12 +560,20 @@ class YATE_API MimeLinesBody : public MimeBody
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor from block of data
|
* Constructor from block of data
|
||||||
|
* @param type Name of the specific MIME type/subtype
|
||||||
* @param buf Pointer to buffer of data
|
* @param buf Pointer to buffer of data
|
||||||
* @param len Length of data in buffer
|
* @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);
|
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
|
* Destructor
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue