mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-19 20:18:09 +00:00
Merge remote-tracking branch 'origin/dev_content_cpp' into dev_chatroom_list_subscription
This commit is contained in:
commit
d7fcc06dd0
21 changed files with 264 additions and 79 deletions
|
|
@ -446,3 +446,7 @@ const char * sal_body_handler_get_header(const SalBodyHandler *body_handler, con
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const belle_sip_list_t* sal_body_handler_get_headers(const SalBodyHandler *body_handler) {
|
||||
return belle_sip_body_handler_get_headers(BELLE_SIP_BODY_HANDLER(body_handler));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "content/content.h"
|
||||
#include "content/content-type.h"
|
||||
#include "content/header/header-param.h"
|
||||
#include "content/header/header.h"
|
||||
#include "content/content-manager.h"
|
||||
#include "content/file-content.h"
|
||||
#include "content/file-transfer-content.h"
|
||||
|
|
@ -259,6 +260,13 @@ static LinphoneContent * linphone_content_new_with_body_handler(SalBodyHandler *
|
|||
belle_sip_free(body);
|
||||
}
|
||||
|
||||
belle_sip_list_t *headers = (belle_sip_list_t *)sal_body_handler_get_headers(body_handler);
|
||||
while (headers) {
|
||||
belle_sip_header_t *cHeader = BELLE_SIP_HEADER(headers->data);
|
||||
LinphonePrivate::Header header = LinphonePrivate::Header(belle_sip_header_get_name(cHeader), belle_sip_header_get_unparsed_value(cHeader));
|
||||
L_GET_CPP_PTR_FROM_C_OBJECT(content)->addHeader(header);
|
||||
headers = headers->next;
|
||||
}
|
||||
if (sal_body_handler_get_encoding(body_handler)) linphone_content_set_encoding(content, sal_body_handler_get_encoding(body_handler));
|
||||
}
|
||||
|
||||
|
|
@ -307,12 +315,7 @@ SalBodyHandler * sal_body_handler_from_content(const LinphoneContent *content) {
|
|||
}
|
||||
|
||||
for (const auto &header : L_GET_CPP_PTR_FROM_C_OBJECT(content)->getHeaders()) {
|
||||
belle_sip_header_t *additionalHeader = BELLE_SIP_HEADER(
|
||||
belle_sip_header_create(
|
||||
header.first.c_str(),
|
||||
header.second.c_str()
|
||||
)
|
||||
);
|
||||
belle_sip_header_t *additionalHeader = belle_sip_header_parse(header.asString().c_str());
|
||||
belle_sip_body_handler_add_header(BELLE_SIP_BODY_HANDLER(body_handler), additionalHeader);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -650,6 +650,7 @@ SalBodyHandler * sal_body_handler_get_part(const SalBodyHandler *body_handler, i
|
|||
const belle_sip_list_t * sal_body_handler_get_parts(const SalBodyHandler *body_handler);
|
||||
SalBodyHandler * sal_body_handler_find_part_by_header(const SalBodyHandler *body_handler, const char *header_name, const char *header_value);
|
||||
const char * sal_body_handler_get_header(const SalBodyHandler *body_handler, const char *header_name);
|
||||
const belle_sip_list_t* sal_body_handler_get_headers(const SalBodyHandler *body_handler);
|
||||
|
||||
/*this function parses a document with key=value pairs separated by new lines, and extracts the value for a given key*/
|
||||
int sal_lines_get_value(const char *data, const char *key, char *value, size_t value_size);
|
||||
|
|
|
|||
|
|
@ -582,7 +582,7 @@ LinphoneReason ChatMessagePrivate::receive () {
|
|||
foundSupportContentType = true;
|
||||
break;
|
||||
} else
|
||||
lError() << "Unsupported content-type: " << c->getContentType().asString();
|
||||
lError() << "Unsupported content-type: " << c->getContentType();
|
||||
}
|
||||
|
||||
if (!foundSupportContentType) {
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ ChatMessageModifier::Result CpimChatMessageModifier::decode (const shared_ptr<Ch
|
|||
content = message->getContents().front();
|
||||
|
||||
if (content->getContentType() != ContentType::Cpim) {
|
||||
lError() << "[CPIM] Message is not CPIM but " << content->getContentType().asString();
|
||||
lError() << "[CPIM] Message is not CPIM but " << content->getContentType();
|
||||
return ChatMessageModifier::Result::Skipped;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "chat/chat-message/chat-message.h"
|
||||
#include "content/content-type.h"
|
||||
#include "content/header/header.h"
|
||||
#include "content/content-manager.h"
|
||||
#include "content/file-transfer-content.h"
|
||||
|
||||
|
|
@ -55,8 +56,8 @@ ChatMessageModifier::Result MultipartChatMessageModifier::decode (const shared_p
|
|||
content->setContentType(c.getContentType());
|
||||
content->setContentDisposition(c.getContentDisposition());
|
||||
content->setContentEncoding(c.getContentEncoding());
|
||||
for (const pair<string, string> &pair : c.getHeaders()) {
|
||||
content->addHeader(pair.first, pair.second);
|
||||
for (const Header &header : c.getHeaders()) {
|
||||
content->addHeader(header);
|
||||
}
|
||||
content->setBodyFromUtf8(c.getBodyAsUtf8String());
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ void RemoteConferenceListEventHandler::notifyReceived (const Content *notifyCont
|
|||
continue;
|
||||
}
|
||||
|
||||
const string &cid = content.getHeaderValue("Content-Id");
|
||||
const string &cid = content.getHeader("Content-Id").getValue();
|
||||
if (cid.empty())
|
||||
continue;
|
||||
|
||||
|
|
|
|||
|
|
@ -29,13 +29,15 @@
|
|||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
class Header;
|
||||
|
||||
class ContentPrivate : public ClonableObjectPrivate {
|
||||
private:
|
||||
std::vector<char> body;
|
||||
ContentType contentType;
|
||||
ContentDisposition contentDisposition;
|
||||
std::string contentEncoding;
|
||||
std::list<std::pair<std::string, std::string>> headers;
|
||||
std::list<Header> headers;
|
||||
|
||||
const std::list<std::pair<std::string, std::string>>::const_iterator findHeader (const std::string &headerName) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -147,6 +147,7 @@ bool ContentType::setType (const string &type) {
|
|||
L_D();
|
||||
if (type.find('/') == string::npos) {
|
||||
d->type = Utils::stringToLower(type);
|
||||
setValue(d->type + "/" + d->subType);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -161,6 +162,7 @@ bool ContentType::setSubType (const string &subType) {
|
|||
L_D();
|
||||
if (subType.find('/') == string::npos) {
|
||||
d->subType = Utils::stringToLower(subType);
|
||||
setValue(d->type + "/" + d->subType);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -176,19 +178,6 @@ bool ContentType::isValid () const {
|
|||
return !d->type.empty() && !d->subType.empty();
|
||||
}
|
||||
|
||||
string ContentType::asString () const {
|
||||
L_D();
|
||||
if (isValid()) {
|
||||
string asString = d->type + "/" + d->subType;
|
||||
for (auto it = std::begin(getParameters()); it!=std::end(getParameters()); ++it) {
|
||||
HeaderParam param = *it;
|
||||
asString += param.asString();
|
||||
}
|
||||
return asString;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
bool ContentType::isMultipart() const {
|
||||
return getType() == "multipart";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,8 +58,6 @@ public:
|
|||
const std::string &getSubType () const;
|
||||
bool setSubType (const std::string &subType);
|
||||
|
||||
std::string asString () const;
|
||||
|
||||
bool isMultipart() const;
|
||||
|
||||
static bool isFile (const ContentType &contentType);
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "content-p.h"
|
||||
#include "content-type.h"
|
||||
#include "header/header.h"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
|
|
@ -32,14 +33,6 @@ using namespace std;
|
|||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
const list<pair<string, string>>::const_iterator ContentPrivate::findHeader (const string &headerName) const {
|
||||
return findIf(headers, [&headerName](const pair<string, string> &pair) {
|
||||
return pair.first == headerName;
|
||||
});
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
||||
Content::Content () : ClonableObject(*new ContentPrivate) {}
|
||||
|
|
@ -205,28 +198,42 @@ bool Content::isFileTransfer () const {
|
|||
void Content::addHeader (const string &headerName, const string &headerValue) {
|
||||
L_D();
|
||||
removeHeader(headerName);
|
||||
d->headers.push_back(make_pair(headerName, headerValue));
|
||||
Header header = Header(headerName, headerValue);
|
||||
d->headers.push_back(header);
|
||||
}
|
||||
|
||||
const list<pair<string, string>> &Content::getHeaders () const {
|
||||
void Content::addHeader (const Header &header) {
|
||||
L_D();
|
||||
removeHeader(header.getName());
|
||||
d->headers.push_back(header);
|
||||
}
|
||||
|
||||
const list<Header> &Content::getHeaders () const {
|
||||
L_D();
|
||||
return d->headers;
|
||||
}
|
||||
|
||||
const Header &Content::getHeader (const string &headerName) const {
|
||||
L_D();
|
||||
list<Header>::const_iterator it = findHeader(headerName);
|
||||
if (it != d->headers.cend()) {
|
||||
return *it;
|
||||
}
|
||||
return Utils::getEmptyConstRefObject<Header>();
|
||||
}
|
||||
|
||||
void Content::removeHeader (const string &headerName) {
|
||||
L_D();
|
||||
auto it = d->findHeader(headerName);
|
||||
auto it = findHeader(headerName);
|
||||
if (it != d->headers.cend())
|
||||
d->headers.remove(*it);
|
||||
}
|
||||
|
||||
const string &Content::getHeaderValue (const string &headerName) const {
|
||||
list<Header>::const_iterator Content::findHeader (const string &headerName) const {
|
||||
L_D();
|
||||
auto it = d->findHeader(headerName);
|
||||
if (it != d->headers.cend())
|
||||
return (*it).second;
|
||||
|
||||
return Utils::getEmptyConstRefObject<string>();
|
||||
return findIf(d->headers, [&headerName](const Header &header) {
|
||||
return header.getName() == headerName;
|
||||
});
|
||||
}
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ LINPHONE_BEGIN_NAMESPACE
|
|||
class ContentDisposition;
|
||||
class ContentType;
|
||||
class ContentPrivate;
|
||||
class Header;
|
||||
|
||||
class LINPHONE_PUBLIC Content : public ClonableObject, public AppDataContainer {
|
||||
public:
|
||||
|
|
@ -76,10 +77,12 @@ public:
|
|||
virtual bool isFile () const;
|
||||
virtual bool isFileTransfer () const;
|
||||
|
||||
const std::list<std::pair<std::string, std::string>> &getHeaders () const;
|
||||
const std::list<Header> &getHeaders () const;
|
||||
const Header &getHeader (const std::string &headerName) const;
|
||||
void addHeader (const std::string &headerName, const std::string &headerValue);
|
||||
void addHeader (const Header &header);
|
||||
void removeHeader (const std::string &headerName);
|
||||
const std::string &getHeaderValue (const std::string &headerName) const;
|
||||
std::list<Header>::const_iterator findHeader (const std::string &headerName) const;
|
||||
|
||||
protected:
|
||||
explicit Content (ContentPrivate &p);
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ LINPHONE_BEGIN_NAMESPACE
|
|||
|
||||
class HeaderPrivate : public ClonableObjectPrivate {
|
||||
private:
|
||||
std::string name;
|
||||
std::string value;
|
||||
std::list<HeaderParam> parameters;
|
||||
L_DECLARE_PUBLIC(Header);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "linphone/utils/utils.h"
|
||||
#include "linphone/utils/algorithm.h"
|
||||
|
||||
|
|
@ -31,22 +33,93 @@ LINPHONE_BEGIN_NAMESPACE
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
Header::Header(HeaderPrivate &p) : ClonableObject(p) {
|
||||
Header::Header(HeaderPrivate &p) : ClonableObject(p) {}
|
||||
|
||||
Header::Header() : ClonableObject(*new HeaderPrivate) {}
|
||||
|
||||
Header::Header (const string &name, const string &value) : ClonableObject(*new HeaderPrivate) {
|
||||
setName(name);
|
||||
|
||||
size_t posParam = value.find(";");
|
||||
if (posParam == string::npos) {
|
||||
setValue(value);
|
||||
return;
|
||||
}
|
||||
|
||||
string parsedValue = value.substr(0, posParam);
|
||||
string params = value.substr(posParam + 1);
|
||||
string token;
|
||||
do {
|
||||
posParam = params.find(";");
|
||||
if (posParam == string::npos) {
|
||||
token = params;
|
||||
} else {
|
||||
token = params.substr(0, posParam);
|
||||
}
|
||||
addParameter(HeaderParam(token));
|
||||
params.erase(0, posParam + 1);
|
||||
} while (posParam != std::string::npos);
|
||||
|
||||
setValue(parsedValue);
|
||||
}
|
||||
|
||||
void Header::cleanParameters() {
|
||||
Header::Header (const string &name, const string &value, const list<HeaderParam> ¶ms) : Header(name, value) {
|
||||
addParameters(params);
|
||||
}
|
||||
|
||||
Header::Header (const Header &other) : Header(other.getName(), other.getValue(), other.getParameters()) {}
|
||||
|
||||
Header &Header::operator= (const Header &other) {
|
||||
if (this != &other) {
|
||||
setName(other.getName());
|
||||
setValue(other.getValue());
|
||||
cleanParameters();
|
||||
addParameters(other.getParameters());
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Header::operator== (const Header &other) const {
|
||||
return getName() == other.getName() &&
|
||||
getValue() == other.getValue();
|
||||
}
|
||||
|
||||
bool Header::operator!= (const Header &other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
void Header::setName (const string &name) {
|
||||
L_D();
|
||||
d->name = name;
|
||||
}
|
||||
|
||||
string Header::getName () const {
|
||||
L_D();
|
||||
return d->name;
|
||||
}
|
||||
|
||||
void Header::setValue (const string &value) {
|
||||
L_D();
|
||||
d->value = value;
|
||||
}
|
||||
|
||||
string Header::getValue () const {
|
||||
L_D();
|
||||
return d->value;
|
||||
}
|
||||
|
||||
void Header::cleanParameters () {
|
||||
L_D();
|
||||
d->parameters.clear();
|
||||
}
|
||||
|
||||
const std::list<HeaderParam> &Header::getParameters () const {
|
||||
const list<HeaderParam> &Header::getParameters () const {
|
||||
L_D();
|
||||
|
||||
return d->parameters;
|
||||
}
|
||||
|
||||
void Header::addParameter (const std::string ¶mName, const std::string ¶mValue) {
|
||||
void Header::addParameter (const string ¶mName, const string ¶mValue) {
|
||||
addParameter(HeaderParam(paramName, paramValue));
|
||||
}
|
||||
|
||||
|
|
@ -56,14 +129,14 @@ void Header::addParameter (const HeaderParam ¶m) {
|
|||
d->parameters.push_back(param);
|
||||
}
|
||||
|
||||
void Header::addParameters(const std::list<HeaderParam> ¶ms) {
|
||||
void Header::addParameters(const list<HeaderParam> ¶ms) {
|
||||
for (auto it = std::begin(params); it!=std::end(params); ++it) {
|
||||
HeaderParam param = *it;
|
||||
addParameter(param.getName(), param.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
void Header::removeParameter (const std::string ¶mName) {
|
||||
void Header::removeParameter (const string ¶mName) {
|
||||
L_D();
|
||||
auto it = findParameter(paramName);
|
||||
if (it != d->parameters.cend())
|
||||
|
|
@ -74,20 +147,37 @@ void Header::removeParameter (const HeaderParam ¶m) {
|
|||
removeParameter(param.getName());
|
||||
}
|
||||
|
||||
std::list<HeaderParam>::const_iterator Header::findParameter (const std::string ¶mName) const {
|
||||
list<HeaderParam>::const_iterator Header::findParameter (const string ¶mName) const {
|
||||
L_D();
|
||||
return findIf(d->parameters, [¶mName](const HeaderParam ¶m) {
|
||||
return param.getName() == paramName;
|
||||
});
|
||||
}
|
||||
|
||||
const HeaderParam &Header::getParameter (const std::string ¶mName) const {
|
||||
const HeaderParam &Header::getParameter (const string ¶mName) const {
|
||||
L_D();
|
||||
std::list<HeaderParam>::const_iterator it = findParameter(paramName);
|
||||
list<HeaderParam>::const_iterator it = findParameter(paramName);
|
||||
if (it != d->parameters.cend()) {
|
||||
return *it;
|
||||
}
|
||||
return Utils::getEmptyConstRefObject<HeaderParam>();
|
||||
}
|
||||
|
||||
string Header::asString () const {
|
||||
stringstream asString;
|
||||
if (!getName().empty()) {
|
||||
asString << getName() << ":";
|
||||
}
|
||||
asString << getValue();
|
||||
for (const auto ¶m : getParameters()) {
|
||||
asString << param.asString();
|
||||
}
|
||||
return asString.str();
|
||||
}
|
||||
|
||||
ostream &operator<<(ostream& stream, const Header& header) {
|
||||
stream << header.asString();
|
||||
return stream;
|
||||
}
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
|
@ -33,7 +33,23 @@ class HeaderParam;
|
|||
|
||||
class LINPHONE_PUBLIC Header : public ClonableObject {
|
||||
public:
|
||||
void cleanParameters();
|
||||
Header ();
|
||||
Header (const std::string &name, const std::string &value);
|
||||
Header (const std::string &name, const std::string &value, const std::list<HeaderParam> ¶ms);
|
||||
Header (const Header &other);
|
||||
|
||||
Header &operator= (const Header &other);
|
||||
|
||||
bool operator== (const Header &other) const;
|
||||
bool operator!= (const Header &other) const;
|
||||
|
||||
void setName (const std::string &name);
|
||||
std::string getName () const;
|
||||
|
||||
void setValue (const std::string &value);
|
||||
std::string getValue () const;
|
||||
|
||||
void cleanParameters ();
|
||||
const std::list<HeaderParam> &getParameters () const;
|
||||
void addParameter (const std::string ¶mName, const std::string ¶mValue);
|
||||
void addParameter (const HeaderParam ¶m);
|
||||
|
|
@ -43,6 +59,9 @@ public:
|
|||
std::list<HeaderParam>::const_iterator findParameter (const std::string ¶mName) const;
|
||||
const HeaderParam &getParameter (const std::string ¶mName) const;
|
||||
|
||||
std::string asString () const;
|
||||
friend std::ostream &operator<<(std::ostream&, const Header&);
|
||||
|
||||
protected:
|
||||
explicit Header (HeaderPrivate &p);
|
||||
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ set(SOURCE_FILES_C
|
|||
set(SOURCE_FILES_CXX
|
||||
clonable-object-tester.cpp
|
||||
conference-event-tester.cpp
|
||||
content-manager-tester.cpp
|
||||
contents-tester.cpp
|
||||
cpim-tester.cpp
|
||||
main-db-tester.cpp
|
||||
multipart-tester.cpp
|
||||
|
|
|
|||
|
|
@ -21,8 +21,10 @@
|
|||
#include "content/content-manager.h"
|
||||
#include "content/content-type.h"
|
||||
#include "content/content.h"
|
||||
#include "content/header/header-param.h"
|
||||
#include "liblinphone_tester.h"
|
||||
#include "tester_utils.h"
|
||||
#include "logger/logger.h"
|
||||
|
||||
using namespace LinphonePrivate;
|
||||
using namespace std;
|
||||
|
|
@ -60,6 +62,7 @@ static const char* source_multipart = \
|
|||
" </p1:person>" \
|
||||
"</presence>" \
|
||||
"-----------------------------14737809831466499882746641449\r\n" \
|
||||
"Content-Encoding: b64\r\n" \
|
||||
"Content-Type: application/pidf+xml;charset=\"UTF-8\"\r\n\r\n" \
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>" \
|
||||
"<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"sip:+XXXXXXXXXX@sip.linphone.org;user=phone\" xmlns:p1=\"urn:ietf:params:xml:ns:pidf:data-model\">" \
|
||||
|
|
@ -77,6 +80,7 @@ static const char* source_multipart = \
|
|||
" </p1:person>" \
|
||||
"</presence>" \
|
||||
"-----------------------------14737809831466499882746641449\r\n" \
|
||||
"Content-Id: toto;param1=value1;param2;param3=value3\r\n" \
|
||||
"Content-Type: application/pidf+xml;charset=\"UTF-8\"\r\n\r\n" \
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>" \
|
||||
"<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"sip:+ZZZZZZZZZZ@sip.linphone.org;user=phone\" xmlns:p1=\"urn:ietf:params:xml:ns:pidf:data-model\">" \
|
||||
|
|
@ -97,8 +101,8 @@ static const char* source_multipart = \
|
|||
|
||||
static const char* generated_multipart = \
|
||||
"-----------------------------14737809831466499882746641449\r\n" \
|
||||
"Content-Type: application/rlmi+xml;charset=\"UTF-8\"\r\n\r\n" \
|
||||
"Content-Length:582" \
|
||||
"Content-Type: application/rlmi+xml;charset=\"UTF-8\"\r\n" \
|
||||
"Content-Length:582\r\n\r\n" \
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>" \
|
||||
"<list xmlns=\"urn:ietf:params:xml:ns:rlmi\" fullState=\"false\" uri=\"sip:rls@sip.linphone.org\" version=\"1\">" \
|
||||
" <resource uri=\"sip:+YYYYYYYYYY@sip.linphone.org;user=phone\">" \
|
||||
|
|
@ -112,8 +116,8 @@ static const char* generated_multipart = \
|
|||
" </resource>" \
|
||||
"</list>" \
|
||||
"-----------------------------14737809831466499882746641449\r\n" \
|
||||
"Content-Type: application/pidf+xml;charset=\"UTF-8\"\r\n\r\n" \
|
||||
"Content-Length:561" \
|
||||
"Content-Type: application/pidf+xml;charset=\"UTF-8\"\r\n" \
|
||||
"Content-Length:561\r\n\r\n" \
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>" \
|
||||
"<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"sip:+YYYYYYYYYY@sip.linphone.org;user=phone\" xmlns:p1=\"urn:ietf:params:xml:ns:pidf:data-model\">" \
|
||||
" <tuple id=\"qmht-9\">" \
|
||||
|
|
@ -130,8 +134,9 @@ static const char* generated_multipart = \
|
|||
" </p1:person>" \
|
||||
"</presence>" \
|
||||
"-----------------------------14737809831466499882746641449\r\n" \
|
||||
"Content-Type: application/pidf+xml;charset=\"UTF-8\"\r\n\r\n" \
|
||||
"Content-Length:561" \
|
||||
"Content-Encoding:b64\r\n" \
|
||||
"Content-Type: application/pidf+xml;charset=\"UTF-8\"\r\n" \
|
||||
"Content-Length:561\r\n\r\n" \
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>" \
|
||||
"<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"sip:+XXXXXXXXXX@sip.linphone.org;user=phone\" xmlns:p1=\"urn:ietf:params:xml:ns:pidf:data-model\">" \
|
||||
" <tuple id=\"szohvt\">" \
|
||||
|
|
@ -148,8 +153,9 @@ static const char* generated_multipart = \
|
|||
" </p1:person>" \
|
||||
"</presence>" \
|
||||
"-----------------------------14737809831466499882746641449\r\n" \
|
||||
"Content-Type: application/pidf+xml;charset=\"UTF-8\"\r\n\r\n" \
|
||||
"Content-Length:546" \
|
||||
"Content-Id:toto;param1=value1;param2;param3=value3\r\n" \
|
||||
"Content-Type: application/pidf+xml;charset=\"UTF-8\"\r\n" \
|
||||
"Content-Length:546\r\n\r\n" \
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>" \
|
||||
"<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"sip:+ZZZZZZZZZZ@sip.linphone.org;user=phone\" xmlns:p1=\"urn:ietf:params:xml:ns:pidf:data-model\">" \
|
||||
" <tuple id=\"oc3e08\">" \
|
||||
|
|
@ -292,6 +298,7 @@ void multipart_to_list () {
|
|||
ms_message("\n\n----- Original part 3 -----");
|
||||
ms_message("%s", originalStr3.c_str());
|
||||
BC_ASSERT_TRUE(originalStr3 == generatedStr3);
|
||||
BC_ASSERT_TRUE(content3.getHeader("Content-Encoding").getValue() == "b64");
|
||||
|
||||
Content content4 = contents.front();
|
||||
contents.pop_front();
|
||||
|
|
@ -310,6 +317,10 @@ void multipart_to_list () {
|
|||
ms_message("\n\n----- Original part 4 -----");
|
||||
ms_message("%s", originalStr4.c_str());
|
||||
BC_ASSERT_TRUE(originalStr4 == generatedStr4);
|
||||
BC_ASSERT_TRUE(content4.getHeader("Content-Id").getValue() == "toto");
|
||||
BC_ASSERT_TRUE(content4.getHeader("Content-Id").getParameter("param1").getValue() == "value1");
|
||||
BC_ASSERT_TRUE(content4.getHeader("Content-Id").getParameter("param2").getValue().empty());
|
||||
BC_ASSERT_TRUE(content4.getHeader("Content-Id").getParameter("param3").getValue() == "value3");
|
||||
}
|
||||
|
||||
void list_to_multipart () {
|
||||
|
|
@ -325,8 +336,14 @@ void list_to_multipart () {
|
|||
content2.setContentType(contentType);
|
||||
Content content3;
|
||||
content3.setBody(part3);
|
||||
content3.addHeader("Content-Encoding", "b64");
|
||||
content3.setContentType(contentType);
|
||||
Content content4;
|
||||
Header header = Header("Content-Id", "toto");
|
||||
header.addParameter("param1", "value1");
|
||||
header.addParameter("param2", "");
|
||||
header.addParameter("param3", "value3");
|
||||
content4.addHeader(header);
|
||||
content4.setBody(part4);
|
||||
content4.setContentType(contentType);
|
||||
list<Content *> contents = {&content1, &content2, &content3, &content4};
|
||||
|
|
@ -353,24 +370,66 @@ void list_to_multipart () {
|
|||
}
|
||||
|
||||
static void content_type_parsing(void) {
|
||||
const string type = "message/external-body;access-type=URL;URL=\"https://www.linphone.org/img/linphone-open-source-voip-projectX2.png\"";
|
||||
string type = "message/external-body;access-type=URL;URL=\"https://www.linphone.org/img/linphone-open-source-voip-projectX2.png\"";
|
||||
ContentType contentType = ContentType(type);
|
||||
BC_ASSERT_STRING_EQUAL("message", contentType.getType().c_str());
|
||||
BC_ASSERT_STRING_EQUAL("external-body", contentType.getSubType().c_str());
|
||||
BC_ASSERT_STRING_EQUAL("URL", contentType.getParameter("access-type").getValue().c_str());
|
||||
BC_ASSERT_STRING_EQUAL("\"https://www.linphone.org/img/linphone-open-source-voip-projectX2.png\"", contentType.getParameter("URL").getValue().c_str());
|
||||
BC_ASSERT_STRING_EQUAL("", contentType.getParameter("boundary").getValue().c_str());
|
||||
BC_ASSERT_EQUAL(2, contentType.getParameters().size(), int, "%d");
|
||||
lInfo() << "Content-Type is " << contentType;
|
||||
BC_ASSERT_TRUE(type == contentType.asString());
|
||||
|
||||
type = "multipart/mixed;boundary=-----------------------------14737809831466499882746641450";
|
||||
contentType = ContentType(type);
|
||||
BC_ASSERT_STRING_EQUAL("multipart", contentType.getType().c_str());
|
||||
BC_ASSERT_STRING_EQUAL("mixed", contentType.getSubType().c_str());
|
||||
BC_ASSERT_STRING_EQUAL("-----------------------------14737809831466499882746641450", contentType.getParameter("boundary").getValue().c_str());
|
||||
BC_ASSERT_STRING_EQUAL("", contentType.getParameter("access-type").getValue().c_str());
|
||||
BC_ASSERT_EQUAL(1, contentType.getParameters().size(), int, "%d");
|
||||
lInfo() << "Content-Type is " << contentType;
|
||||
BC_ASSERT_TRUE(type == contentType.asString());
|
||||
|
||||
type = "plain/text";
|
||||
contentType = ContentType(type);
|
||||
BC_ASSERT_STRING_EQUAL("plain", contentType.getType().c_str());
|
||||
BC_ASSERT_STRING_EQUAL("text", contentType.getSubType().c_str());
|
||||
BC_ASSERT_STRING_EQUAL("", contentType.getParameter("boundary").getValue().c_str());
|
||||
BC_ASSERT_EQUAL(0, contentType.getParameters().size(), int, "%d");
|
||||
lInfo() << "Content-Type is " << contentType;
|
||||
BC_ASSERT_TRUE(type == contentType.asString());
|
||||
}
|
||||
|
||||
test_t content_manager_tests[] = {
|
||||
static void content_header_parsing(void) {
|
||||
string value = "toto;param1=value1;param2;param3=value3";
|
||||
Header header = Header("Content-Id", value);
|
||||
BC_ASSERT_TRUE(header.getValue() == "toto");
|
||||
BC_ASSERT_TRUE(header.getParameter("param1").getValue() == "value1");
|
||||
BC_ASSERT_TRUE(header.getParameter("param2").getValue().empty());
|
||||
BC_ASSERT_TRUE(header.getParameter("param3").getValue() == "value3");
|
||||
BC_ASSERT_EQUAL(3, header.getParameters().size(), int, "%d");
|
||||
BC_ASSERT_STRING_EQUAL("", header.getParameter("encoding").getValue().c_str());
|
||||
|
||||
value = "b64";
|
||||
header = Header("Content-Encoding", value);
|
||||
BC_ASSERT_TRUE(header.getValue() == value);
|
||||
BC_ASSERT_EQUAL(0, header.getParameters().size(), int, "%d");
|
||||
BC_ASSERT_STRING_EQUAL("", header.getParameter("access-type").getValue().c_str());
|
||||
}
|
||||
|
||||
test_t contents_tests[] = {
|
||||
TEST_NO_TAG("Multipart to list", multipart_to_list),
|
||||
TEST_NO_TAG("List to multipart", list_to_multipart),
|
||||
TEST_NO_TAG("Content type parsing", content_type_parsing)
|
||||
TEST_NO_TAG("Content type parsing", content_type_parsing),
|
||||
TEST_NO_TAG("Content header parsing", content_header_parsing)
|
||||
};
|
||||
|
||||
test_suite_t content_manager_test_suite = {
|
||||
"Content manager",
|
||||
test_suite_t contents_test_suite = {
|
||||
"Contents",
|
||||
nullptr,
|
||||
nullptr,
|
||||
liblinphone_tester_before_each,
|
||||
liblinphone_tester_after_each,
|
||||
sizeof(content_manager_tests) / sizeof(content_manager_tests[0]), content_manager_tests
|
||||
sizeof(contents_tests) / sizeof(contents_tests[0]), contents_tests
|
||||
};
|
||||
|
|
@ -45,7 +45,7 @@ extern test_suite_t call_video_test_suite;
|
|||
extern test_suite_t clonable_object_test_suite;
|
||||
extern test_suite_t conference_event_test_suite;
|
||||
extern test_suite_t conference_test_suite;
|
||||
extern test_suite_t content_manager_test_suite;
|
||||
extern test_suite_t contents_test_suite;
|
||||
extern test_suite_t cpim_test_suite;
|
||||
extern test_suite_t dtmf_test_suite;
|
||||
extern test_suite_t event_test_suite;
|
||||
|
|
|
|||
|
|
@ -2294,15 +2294,19 @@ void text_message_with_custom_content_type_and_lime(void) {
|
|||
|
||||
|
||||
static int im_encryption_engine_process_incoming_message_cb(LinphoneImEncryptionEngine *engine, LinphoneChatRoom *room, LinphoneChatMessage *msg) {
|
||||
ms_debug("IM encryption process incoming message with content type %s", linphone_chat_message_get_content_type(msg));
|
||||
if (linphone_chat_message_get_content_type(msg)) {
|
||||
if (strcmp(linphone_chat_message_get_content_type(msg), "cipher/b64") == 0) {
|
||||
size_t b64Size = 0;
|
||||
unsigned char *output;
|
||||
bctbx_base64_decode(NULL, &b64Size, (unsigned char *)linphone_chat_message_get_text(msg), strlen(linphone_chat_message_get_text(msg)));
|
||||
const char *data = linphone_chat_message_get_text(msg);
|
||||
ms_debug("IM encryption process incoming message crypted message is %s", data);
|
||||
bctbx_base64_decode(NULL, &b64Size, (unsigned char *)data, strlen(data));
|
||||
output = (unsigned char *)ms_malloc(b64Size+1),
|
||||
bctbx_base64_decode(output, &b64Size, (unsigned char *)linphone_chat_message_get_text(msg), strlen(linphone_chat_message_get_text(msg)));
|
||||
bctbx_base64_decode(output, &b64Size, (unsigned char *)data, strlen(data));
|
||||
output[b64Size] = '\0';
|
||||
linphone_chat_message_set_text(msg, (char *)output);
|
||||
ms_debug("IM encryption process incoming message decrypted message is %s", output);
|
||||
ms_free(output);
|
||||
linphone_chat_message_set_content_type(msg, "text/plain");
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -430,8 +430,10 @@ static void test_presence_list_base(bool_t enable_compression) {
|
|||
lcs = bctbx_list_append(lcs, pauline->lc);
|
||||
|
||||
wait_for_list(lcs, &laure->stat.number_of_NotifyPresenceReceived, 2, 4000);
|
||||
BC_ASSERT_EQUAL(laure->stat.number_of_NotifyPresenceReceived, 2, int, "%d");
|
||||
BC_ASSERT_EQUAL(linphone_friend_list_get_expected_notification_version(linphone_core_get_default_friend_list(laure->lc)), 1, int, "%d");
|
||||
BC_ASSERT_GREATER(laure->stat.number_of_NotifyPresenceReceived, 2, int, "%d");
|
||||
BC_ASSERT_LOWER(laure->stat.number_of_NotifyPresenceReceived, 3, int, "%d");
|
||||
BC_ASSERT_GREATER(linphone_friend_list_get_expected_notification_version(linphone_core_get_default_friend_list(laure->lc)), 1, int, "%d");
|
||||
BC_ASSERT_LOWER(linphone_friend_list_get_expected_notification_version(linphone_core_get_default_friend_list(laure->lc)), 2, int, "%d");
|
||||
lf = linphone_friend_list_find_friend_by_address(linphone_core_get_default_friend_list(laure->lc), get_identity_address(marie));
|
||||
if (!BC_ASSERT_PTR_NOT_NULL(lf)) goto end;
|
||||
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusBusy, int, "%d");
|
||||
|
|
@ -485,7 +487,8 @@ static void test_presence_list_base(bool_t enable_compression) {
|
|||
/* The number of PresenceReceived events can be 3 or 4 here. TODO: ideally it should always be 3. */
|
||||
BC_ASSERT_GREATER(laure->stat.number_of_NotifyPresenceReceived, 3, int, "%d");
|
||||
BC_ASSERT_LOWER(laure->stat.number_of_NotifyPresenceReceived, 4, int, "%d");
|
||||
BC_ASSERT_EQUAL(linphone_friend_list_get_expected_notification_version(linphone_core_get_default_friend_list(laure->lc)), 2, int, "%d");
|
||||
BC_ASSERT_GREATER(linphone_friend_list_get_expected_notification_version(linphone_core_get_default_friend_list(laure->lc)), 2, int, "%d");
|
||||
BC_ASSERT_LOWER(linphone_friend_list_get_expected_notification_version(linphone_core_get_default_friend_list(laure->lc)), 3, int, "%d");
|
||||
lf = linphone_friend_list_find_friend_by_address(linphone_core_get_default_friend_list(laure->lc), get_identity_address(marie));
|
||||
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOnThePhone, int, "%d");
|
||||
|
||||
|
|
|
|||
|
|
@ -604,7 +604,7 @@ void liblinphone_tester_add_suites() {
|
|||
bc_tester_add_suite(&stun_test_suite);
|
||||
bc_tester_add_suite(&event_test_suite);
|
||||
bc_tester_add_suite(&conference_event_test_suite);
|
||||
bc_tester_add_suite(&content_manager_test_suite);
|
||||
bc_tester_add_suite(&contents_test_suite);
|
||||
bc_tester_add_suite(&flexisip_test_suite);
|
||||
bc_tester_add_suite(&remote_provisioning_test_suite);
|
||||
bc_tester_add_suite(&quality_reporting_test_suite);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue