Added mime multipart class. Removed useless mime isup class.
git-svn-id: http://voip.null.ro/svn/yate@1618 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
3e65136bd3
commit
7931834b73
316
engine/Mime.cpp
316
engine/Mime.cpp
|
@ -20,6 +20,7 @@
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
#include "yatemime.h"
|
#include "yatemime.h"
|
||||||
|
|
||||||
using namespace TelEngine;
|
using namespace TelEngine;
|
||||||
|
@ -208,6 +209,17 @@ int MimeHeaderLine::findSep(const char* str, char sep, int offs)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build a string from a list of MIME header lines
|
||||||
|
void MimeHeaderLine::buildHeaders(String& buf, const ObjList& headers)
|
||||||
|
{
|
||||||
|
for (ObjList* o = headers.skipNull(); o; o = o->skipNext()) {
|
||||||
|
MimeHeaderLine* hdr = static_cast<MimeHeaderLine*>(o->get());
|
||||||
|
String line;
|
||||||
|
hdr->buildLine(line);
|
||||||
|
buf << line << "\r\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MimeAuthLine
|
* MimeAuthLine
|
||||||
|
@ -322,7 +334,7 @@ MimeBody::~MimeBody()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find an additional header line by its name
|
// Find an additional header line by its name
|
||||||
MimeHeaderLine* MimeBody::findHdr(const char* name, const MimeHeaderLine* start) const
|
MimeHeaderLine* MimeBody::findHdr(const String& name, const MimeHeaderLine* start) const
|
||||||
{
|
{
|
||||||
ObjList* o = m_headers.skipNull();
|
ObjList* o = m_headers.skipNull();
|
||||||
if (!o)
|
if (!o)
|
||||||
|
@ -389,8 +401,8 @@ MimeBody* MimeBody::build(const char* buf, int len, const MimeHeaderLine& type)
|
||||||
return new MimeLinesBody(type,buf,len);
|
return new MimeLinesBody(type,buf,len);
|
||||||
if (what.startsWith("text/") || (what == "application/dtmf"))
|
if (what.startsWith("text/") || (what == "application/dtmf"))
|
||||||
return new MimeStringBody(type,buf,len);
|
return new MimeStringBody(type,buf,len);
|
||||||
if (what == "application/isup")
|
if (what.startsWith("multipart/"))
|
||||||
return new MimeIsupBody(type,buf,len);
|
return new MimeMultipartBody(type,buf,len);
|
||||||
return new MimeBinaryBody(type,buf,len);
|
return new MimeBinaryBody(type,buf,len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,6 +473,269 @@ String* MimeBody::getUnfoldedLine(const char*& buf, int& len)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MimeMultipartBody
|
||||||
|
*/
|
||||||
|
YCLASSIMP(MimeMultipartBody,MimeBody)
|
||||||
|
|
||||||
|
// Constructor to build an empty multipart body
|
||||||
|
MimeMultipartBody::MimeMultipartBody(const char* subtype, const char* boundary)
|
||||||
|
: MimeBody((subtype && *subtype) ? (String("multipart/") + subtype) : "multipart/mixed")
|
||||||
|
{
|
||||||
|
String b = boundary;
|
||||||
|
if (b.null())
|
||||||
|
b << (int)::random() << "_" << (unsigned int)Time::now();
|
||||||
|
if (b.length() > 70)
|
||||||
|
b = b.substr(0,70);
|
||||||
|
setParam("boundary",b);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructor from block of data
|
||||||
|
MimeMultipartBody::MimeMultipartBody(const String& type, const char* buf, int len)
|
||||||
|
: MimeBody(type)
|
||||||
|
{
|
||||||
|
parse(buf,len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructor from block of data
|
||||||
|
MimeMultipartBody::MimeMultipartBody(const MimeHeaderLine& type, const char* buf, int len)
|
||||||
|
: MimeBody(type)
|
||||||
|
{
|
||||||
|
parse(buf,len);
|
||||||
|
}
|
||||||
|
|
||||||
|
MimeMultipartBody::~MimeMultipartBody()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy constructor
|
||||||
|
MimeMultipartBody::MimeMultipartBody(const MimeMultipartBody& original)
|
||||||
|
: MimeBody(original.getType())
|
||||||
|
{
|
||||||
|
for (ObjList* o = original.m_bodies.skipNull(); o; o = o->skipNext()) {
|
||||||
|
MimeBody* body = static_cast<MimeBody*>(o->get());
|
||||||
|
m_bodies.append(body->clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find a body. Enclosed multiparts are also searched for the requested body
|
||||||
|
MimeBody* MimeMultipartBody::findBody(const String& content, MimeBody** start) const
|
||||||
|
{
|
||||||
|
MimeBody* localStart = start ? *start : 0;
|
||||||
|
Debug(DebugNote,"MimeMultipartBody::findBody(%s,%p) [%p]",
|
||||||
|
content.c_str(),localStart,this);
|
||||||
|
for (ObjList* o = m_bodies.skipNull(); o; o = o->skipNext()) {
|
||||||
|
MimeBody* body = static_cast<MimeBody*>(o->get());
|
||||||
|
// Start point was found
|
||||||
|
if (!localStart) {
|
||||||
|
if (content == body->getType())
|
||||||
|
return body;
|
||||||
|
if (body->isMultipart()) {
|
||||||
|
body = (static_cast<MimeMultipartBody*>(body))->findBody(content);
|
||||||
|
if (body)
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Reset starting point if found
|
||||||
|
if (body == localStart)
|
||||||
|
localStart = 0;
|
||||||
|
// Check inside multiparts for starting point or requested body
|
||||||
|
if (body->isMultipart()) {
|
||||||
|
body = (static_cast<MimeMultipartBody*>(body))->findBody(content,&localStart);
|
||||||
|
if (body)
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (start)
|
||||||
|
*start = localStart;
|
||||||
|
Debug(DebugNote,"MimeMultipartBody::findBody(). Not found%s [%p]",
|
||||||
|
localStart?"":". Found start point",this);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Duplicate this MIME body
|
||||||
|
MimeBody* MimeMultipartBody::clone() const
|
||||||
|
{
|
||||||
|
return new MimeMultipartBody(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method that is called internally to build the binary encoded body
|
||||||
|
void MimeMultipartBody::buildBody() const
|
||||||
|
{
|
||||||
|
const NamedString* b = getParam("boundary");
|
||||||
|
String boundary = "\r\n--";
|
||||||
|
if (b)
|
||||||
|
boundary << *b;
|
||||||
|
|
||||||
|
ObjList* o = m_bodies.skipNull();
|
||||||
|
if (o)
|
||||||
|
for (; o; o = o->skipNext()) {
|
||||||
|
MimeBody* body = static_cast<MimeBody*>(o->get());
|
||||||
|
String hdr = "\r\n";
|
||||||
|
body->buildHeaders(hdr);
|
||||||
|
// Build it
|
||||||
|
m_body += boundary;
|
||||||
|
m_body += hdr;
|
||||||
|
m_body += body->getBody();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_body += boundary;
|
||||||
|
// Add termination boundary
|
||||||
|
boundary << "--\r\n";
|
||||||
|
m_body += boundary;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse a data buffer and append any valid body to this multipart
|
||||||
|
// Ignore prolog, epilog and invalid bodies
|
||||||
|
void MimeMultipartBody::parse(const char* buf, int len)
|
||||||
|
{
|
||||||
|
DDebug(DebugAll,"MimeMultipartBody::parse(%p,%d,'%s') [%p]",
|
||||||
|
buf,len,getType().c_str(),this);
|
||||||
|
if (!buf || len <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const NamedString* b = getParam("boundary");
|
||||||
|
String boundary = "\r\n--";
|
||||||
|
if (b)
|
||||||
|
boundary << *b;
|
||||||
|
// RFC 2046 pg. 22: Remove trailing blanks from boundary
|
||||||
|
unsigned int i = boundary.length() - 1;
|
||||||
|
for (const char* d = boundary.c_str(); i > 3; i--)
|
||||||
|
if (d[i] != ' ' && d[i] != '\t')
|
||||||
|
break;
|
||||||
|
if (i != boundary.length() - 1)
|
||||||
|
boundary.assign(boundary.c_str(),i + 1);
|
||||||
|
if (boundary.length() < 5)
|
||||||
|
DDebug(DebugMild,"MimeMultipartBody::parse(). Boundary is empty [%p]",this);
|
||||||
|
|
||||||
|
bool endData;
|
||||||
|
// Find first boundary: ignore the data before it
|
||||||
|
// The first boundary might not contain the CRLF at beginning
|
||||||
|
findBoundary(buf,len,boundary.c_str() + 2,boundary.length()-2,endData);
|
||||||
|
|
||||||
|
XDebug(DebugAll,"Searching for bodies len=%d [%p]",len,this);
|
||||||
|
|
||||||
|
// Parse for bodies
|
||||||
|
while (!endData) {
|
||||||
|
const char* start = buf;
|
||||||
|
int l = findBoundary(buf,len,boundary.c_str(),boundary.length(),endData);
|
||||||
|
if (l <= 0)
|
||||||
|
continue;
|
||||||
|
XDebug(DebugInfo,"Found %d body data [%p]",l,this);
|
||||||
|
// Get body headers
|
||||||
|
ObjList hdr;
|
||||||
|
MimeHeaderLine* cType = 0;
|
||||||
|
while (l) {
|
||||||
|
String* line = MimeBody::getUnfoldedLine(start,l);
|
||||||
|
// Found end of headers
|
||||||
|
if (line->null()) {
|
||||||
|
TelEngine::destruct(line);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
int col = line->find(':');
|
||||||
|
// Check if this is a valid header line
|
||||||
|
if (col <= 0) {
|
||||||
|
TelEngine::destruct(line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String name = line->substr(0,col);
|
||||||
|
name.trimBlanks();
|
||||||
|
if (!name) {
|
||||||
|
TelEngine::destruct(line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
*line >> ":";
|
||||||
|
line->trimBlanks();
|
||||||
|
DDebug(DebugAll,"MimeMultipartBody::parse() header='%s' value='%s'",
|
||||||
|
name.c_str(),line->c_str());
|
||||||
|
MimeHeaderLine* ct = new MimeHeaderLine(name,*line);
|
||||||
|
hdr.append(ct);
|
||||||
|
if (name &= "Content-Type")
|
||||||
|
cType = ct;
|
||||||
|
TelEngine::destruct(line);
|
||||||
|
}
|
||||||
|
// Append body to list and move extra headers to it
|
||||||
|
MimeBody* body = cType ? MimeBody::build(buf,len,*cType) : 0;
|
||||||
|
if (!body) {
|
||||||
|
XDebug(DebugNote,"Failed to build body%s [%p]",
|
||||||
|
cType?"":": Content-Type header is missing",this);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
m_bodies.append(body);
|
||||||
|
XDebug(DebugInfo,"Body '%s' created. Adding %u additional headers [%p]",
|
||||||
|
cType->c_str(),hdr.count() - 1,this);
|
||||||
|
ListIterator iter(hdr);
|
||||||
|
for (GenObject* o = 0; (o = iter.get());) {
|
||||||
|
MimeHeaderLine* line = static_cast<MimeHeaderLine*>(o);
|
||||||
|
if (line == cType)
|
||||||
|
continue;
|
||||||
|
hdr.remove(o,false);
|
||||||
|
body->appendHdr(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse input buffer for first body boundary or data end
|
||||||
|
// Advance buffer pass the boundary line and decrease the buffer length
|
||||||
|
// Set endData to true if a final boundary was found or the end of the
|
||||||
|
// buffer was reached
|
||||||
|
// Return the length of data before the found boundary
|
||||||
|
int MimeMultipartBody::findBoundary(const char*& buf, int& len,
|
||||||
|
const char* boundary, unsigned int bLen, bool& endData)
|
||||||
|
{
|
||||||
|
if (len <= 0) {
|
||||||
|
endData = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
endData = false;
|
||||||
|
unsigned int l = len;
|
||||||
|
int bodyLen = 0;
|
||||||
|
|
||||||
|
while (l) {
|
||||||
|
// Skip until the first char of boundary
|
||||||
|
for (; l >= bLen && *buf != boundary[0]; l--, buf++)
|
||||||
|
bodyLen++;
|
||||||
|
// Check if we have enough data for boundary
|
||||||
|
if (l < bLen) {
|
||||||
|
bodyLen += l;
|
||||||
|
buf += l;
|
||||||
|
l = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Check boundary
|
||||||
|
unsigned int n = 0;
|
||||||
|
for(; n < bLen && *buf == boundary[n]; n++, buf++, l--)
|
||||||
|
;
|
||||||
|
// Not found
|
||||||
|
if (n < bLen) {
|
||||||
|
bodyLen += n;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Check end of data
|
||||||
|
if (l > 2 && buf[0] == '-' && buf[1] == '-') {
|
||||||
|
buf += 2;
|
||||||
|
len -= 2;
|
||||||
|
endData = true;
|
||||||
|
}
|
||||||
|
// Skip until the end of line or data
|
||||||
|
for (; l > 1; buf++, l--)
|
||||||
|
if (buf[0] == '\r' && buf[1] == '\n') {
|
||||||
|
buf += 2;
|
||||||
|
len -= 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = l;
|
||||||
|
if (!len)
|
||||||
|
endData = true;
|
||||||
|
return bodyLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MimeSdpBody
|
* MimeSdpBody
|
||||||
*/
|
*/
|
||||||
|
@ -598,41 +873,6 @@ MimeBody* MimeBinaryBody::clone() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MimeIsupBody
|
|
||||||
*/
|
|
||||||
YCLASSIMP(MimeIsupBody,MimeBinaryBody)
|
|
||||||
|
|
||||||
MimeIsupBody::MimeIsupBody()
|
|
||||||
: MimeBinaryBody(String("application/isup"),0,0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
MimeIsupBody::MimeIsupBody(const String& type, const char* buf, int len)
|
|
||||||
: MimeBinaryBody(type,buf,len)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
MimeIsupBody::MimeIsupBody(const MimeHeaderLine& type, const char* buf, int len)
|
|
||||||
: MimeBinaryBody(type,buf,len)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
MimeIsupBody::MimeIsupBody(const MimeIsupBody& original)
|
|
||||||
: MimeBinaryBody(original)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
MimeIsupBody::~MimeIsupBody()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
MimeBody* MimeIsupBody::clone() const
|
|
||||||
{
|
|
||||||
return new MimeIsupBody(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MimeStringBody
|
* MimeStringBody
|
||||||
*/
|
*/
|
||||||
|
|
213
yatemime.h
213
yatemime.h
|
@ -148,7 +148,7 @@ public:
|
||||||
static String quote(const String& str);
|
static String quote(const String& str);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility function to find a separator not in "quotes" or inside <uri>.
|
* Utility function to find a separator not in "quotes" or inside \<uri\>.
|
||||||
* @param str Input string used to find the separator.
|
* @param str Input string used to find the separator.
|
||||||
* @param sep The separator to find.
|
* @param sep The separator to find.
|
||||||
* @param offs Starting offset in input string.
|
* @param offs Starting offset in input string.
|
||||||
|
@ -156,6 +156,15 @@ public:
|
||||||
*/
|
*/
|
||||||
static int findSep(const char* str, char sep, int offs = 0);
|
static int findSep(const char* str, char sep, int offs = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build a string from a list of MIME header lines.
|
||||||
|
* Add a CR/LF terminator after each line
|
||||||
|
* @param buf Destination string
|
||||||
|
* @param headers The list with the header lines
|
||||||
|
* @param eoln Header line separator
|
||||||
|
*/
|
||||||
|
static void buildHeaders(String& buf, const ObjList& headers);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ObjList m_params; // Header list of parameters
|
ObjList m_params; // Header list of parameters
|
||||||
char m_separator; // Parameter separator
|
char m_separator; // Parameter separator
|
||||||
|
@ -252,9 +261,10 @@ public:
|
||||||
/**
|
/**
|
||||||
* Remove an additional header line from this body
|
* Remove an additional header line from this body
|
||||||
* @param hdr The header line to remove
|
* @param hdr The header line to remove
|
||||||
|
* @param delobj True to delete the header, false to remove from list without deleting it
|
||||||
*/
|
*/
|
||||||
inline void removeHdr(MimeHeaderLine* hdr)
|
inline void removeHdr(MimeHeaderLine* hdr, bool delobj = true)
|
||||||
{ if (hdr) m_headers.remove(hdr); }
|
{ if (hdr) m_headers.remove(hdr,delobj); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find an additional header line by its name. The names are compared case insensitive
|
* Find an additional header line by its name. The names are compared case insensitive
|
||||||
|
@ -262,7 +272,18 @@ public:
|
||||||
* @param start The starting point in the list. 0 to start from the beginning
|
* @param start The starting point in the list. 0 to start from the beginning
|
||||||
* @return Pointer to MimeHeaderLine or 0 if not found
|
* @return Pointer to MimeHeaderLine or 0 if not found
|
||||||
*/
|
*/
|
||||||
MimeHeaderLine* findHdr(const char* name, const MimeHeaderLine* start = 0) const;
|
MimeHeaderLine* findHdr(const String& name, const MimeHeaderLine* start = 0) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build a string with this body's header lines
|
||||||
|
* @param buf Destination string
|
||||||
|
* @param eoln Header line separator
|
||||||
|
*/
|
||||||
|
inline void buildHeaders(String& buf) {
|
||||||
|
m_type.buildLine(buf);
|
||||||
|
buf << "\r\n";
|
||||||
|
MimeHeaderLine::buildHeaders(buf,m_headers);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replace the value of an existing parameter or add a new one
|
* Replace the value of an existing parameter or add a new one
|
||||||
|
@ -293,7 +314,8 @@ public:
|
||||||
const NamedString* getParam(const char* name, const char* header = 0) const;
|
const NamedString* getParam(const char* name, const char* header = 0) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrive the binary encoding of this MIME body
|
* Retrive the binary encoding of this MIME body. Build the body if empty.
|
||||||
|
* The body doesn't contain the Content-Type header or the additional headers
|
||||||
* @return Block of binary data
|
* @return Block of binary data
|
||||||
*/
|
*/
|
||||||
const DataBlock& getBody() const;
|
const DataBlock& getBody() const;
|
||||||
|
@ -371,6 +393,126 @@ private:
|
||||||
MimeHeaderLine m_type; // Content type header line
|
MimeHeaderLine m_type; // Content type header line
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An object holding the bodies of a multipart MIME
|
||||||
|
* @short MIME multipart container
|
||||||
|
*/
|
||||||
|
class YATE_API MimeMultipartBody : public MimeBody
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor to build an empty multipart body
|
||||||
|
* @param subtype The multipart subtype
|
||||||
|
* @param boundary The string used as separator for enclosed bodies.
|
||||||
|
* A random one will be created if missing. The length will be truncated
|
||||||
|
* to 70 if this value is exceeded
|
||||||
|
*/
|
||||||
|
MimeMultipartBody(const char* subtype = "mixed", const char* boundary = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor from block of data
|
||||||
|
* @param type The value of the Content-Type header line
|
||||||
|
* @param buf Pointer to buffer of data
|
||||||
|
* @param len Length of data in buffer
|
||||||
|
*/
|
||||||
|
MimeMultipartBody(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
|
||||||
|
*/
|
||||||
|
MimeMultipartBody(const MimeHeaderLine& type, const char* buf, int len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~MimeMultipartBody();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of bodies enclosed contained in this multipart
|
||||||
|
* @return The list of bodies enclosed contained in this multipart
|
||||||
|
*/
|
||||||
|
inline const ObjList& bodies() const
|
||||||
|
{ return m_bodies; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append a body to this multipart
|
||||||
|
* @param body The body to append
|
||||||
|
*/
|
||||||
|
inline void appendBody(MimeBody* body)
|
||||||
|
{ if (body) m_bodies.append(body); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a body from this multipart
|
||||||
|
* @param body The body to remove
|
||||||
|
* @param delobj True to delete the body, false to remove from list without deleting it
|
||||||
|
*/
|
||||||
|
inline void removeBody(MimeBody* body, bool delobj = true)
|
||||||
|
{ if (body) m_bodies.remove(body,delobj); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a body. Enclosed multiparts are also searched for the requested body
|
||||||
|
* @param name The value of the body to find. Must be lower case
|
||||||
|
* @param start The starting point in the list. 0 to start from the beginning.
|
||||||
|
* Be aware that this parameter is used internally to search within enclosed
|
||||||
|
* multipart bodies and set to 0 when the starting point is found
|
||||||
|
* @return Pointer to MimeBody or 0 if not found
|
||||||
|
*/
|
||||||
|
MimeBody* findBody(const String& content, MimeBody** start = 0) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RTTI method, get a pointer to a derived class given the class name
|
||||||
|
* @param name Name of the class we are asking for
|
||||||
|
* @return Pointer to the requested class or NULL if this object doesn't implement it
|
||||||
|
*/
|
||||||
|
virtual void* getObject(const String& name) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if this body is multipart (can hold other MIME bodies)
|
||||||
|
* @return True if this body is multipart
|
||||||
|
*/
|
||||||
|
virtual bool isMultipart() const
|
||||||
|
{ return true; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Duplicate this MIME body
|
||||||
|
* @return Copy of this MIME body
|
||||||
|
*/
|
||||||
|
virtual MimeBody* clone() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Copy constructor
|
||||||
|
*/
|
||||||
|
MimeMultipartBody(const MimeMultipartBody& original);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that is called internally to build the binary encoded body
|
||||||
|
*/
|
||||||
|
virtual void buildBody() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a data buffer and append any valid body to this multipart
|
||||||
|
* Ignore prolog, epilog and invalid bodies
|
||||||
|
* @param buf Pointer to buffer of data
|
||||||
|
* @param len Length of data in buffer
|
||||||
|
*/
|
||||||
|
void parse(const char* buf, int len);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Parse input buffer for first body boundary or data end
|
||||||
|
// Advance buffer pass the boundary line and decrease the buffer length
|
||||||
|
// Set endData to true if a final boundary was found or the end of the
|
||||||
|
// buffer was reached
|
||||||
|
// Return the length of data before the found boundary
|
||||||
|
int findBoundary(const char*& buf, int& len,
|
||||||
|
const char* boundary, unsigned int bLen, bool& endData);
|
||||||
|
|
||||||
|
ObjList m_bodies; // The list of bodies contained in this multipart
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An object holding the lines of an application/sdp MIME type
|
* An object holding the lines of an application/sdp MIME type
|
||||||
* @short MIME for application/sdp
|
* @short MIME for application/sdp
|
||||||
|
@ -385,7 +527,7 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor from block of data
|
* Constructor from block of data
|
||||||
* @param type Name of the MIME type/subtype, should be "application/sdp"
|
* @param type The value of the Content-Type header line
|
||||||
* @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
|
||||||
*/
|
*/
|
||||||
|
@ -480,7 +622,7 @@ 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 type The value of the Content-Type header line
|
||||||
* @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
|
||||||
*/
|
*/
|
||||||
|
@ -524,59 +666,6 @@ protected:
|
||||||
virtual void buildBody() const;
|
virtual void buildBody() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* An object holding a binary block of an ISUP message
|
|
||||||
* @short MIME for application/isup
|
|
||||||
*/
|
|
||||||
class YATE_API MimeIsupBody : public MimeBinaryBody
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*/
|
|
||||||
MimeIsupBody();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor from block of data
|
|
||||||
* @param type The line containing the Content-Type header value
|
|
||||||
* @param buf Pointer to buffer of data
|
|
||||||
* @param len Length of data in buffer
|
|
||||||
*/
|
|
||||||
MimeIsupBody(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
|
|
||||||
*/
|
|
||||||
MimeIsupBody(const MimeHeaderLine& type, const char* buf, int len);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor
|
|
||||||
*/
|
|
||||||
virtual ~MimeIsupBody();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* RTTI method, get a pointer to a derived class given the class name
|
|
||||||
* @param name Name of the class we are asking for
|
|
||||||
* @return Pointer to the requested class or NULL if this object doesn't implement it
|
|
||||||
*/
|
|
||||||
virtual void* getObject(const String& name) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Duplicate this MIME body
|
|
||||||
* @return Copy of this MIME body - a new MimeIsupBody
|
|
||||||
*/
|
|
||||||
virtual MimeBody* clone() const;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/**
|
|
||||||
* Copy constructor
|
|
||||||
*/
|
|
||||||
MimeIsupBody(const MimeIsupBody& original);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An object holding MIME data as just one text string
|
* An object holding MIME data as just one text string
|
||||||
* @short MIME for one text string
|
* @short MIME for one text string
|
||||||
|
@ -586,7 +675,7 @@ 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 type The value of the Content-Type header line
|
||||||
* @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
|
||||||
*/
|
*/
|
||||||
|
@ -649,7 +738,7 @@ 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 type The value of the Content-Type header line
|
||||||
* @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
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue