mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-29 09:09:21 +00:00
Add Content-Disposition header for IMDN messages.
This commit is contained in:
parent
5ab6c928f2
commit
94e53a4e22
12 changed files with 71 additions and 40 deletions
|
|
@ -26,8 +26,8 @@
|
|||
#include "chat/chat-room/chat-room-id.h"
|
||||
#include "chat/modifier/file-transfer-chat-message-modifier.h"
|
||||
#include "chat/notification/imdn.h"
|
||||
#include "content/content-type.h"
|
||||
#include "content/content.h"
|
||||
#include "content/content-type.h"
|
||||
#include "content/file-content.h"
|
||||
#include "content/file-transfer-content.h"
|
||||
#include "db/main-db.h"
|
||||
|
|
|
|||
|
|
@ -33,17 +33,15 @@
|
|||
#include "chat/chat-room/real-time-text-chat-room.h"
|
||||
#include "chat/modifier/cpim-chat-message-modifier.h"
|
||||
#include "chat/modifier/encryption-chat-message-modifier.h"
|
||||
#include "chat/modifier/file-transfer-chat-message-modifier.h"
|
||||
#include "chat/modifier/multipart-chat-message-modifier.h"
|
||||
#include "chat/notification/imdn.h"
|
||||
#include "conference/participant.h"
|
||||
#include "conference/participant-imdn-state.h"
|
||||
#include "content/file-content.h"
|
||||
#include "content/content-disposition.h"
|
||||
#include "content/header/header-param.h"
|
||||
#include "content/content.h"
|
||||
#include "core/core.h"
|
||||
#include "core/core-p.h"
|
||||
#include "logger/logger.h"
|
||||
#include "chat/notification/imdn.h"
|
||||
#include "sip-tools/sip-headers.h"
|
||||
|
||||
#include "ortp/b64.h"
|
||||
|
|
@ -462,6 +460,7 @@ void ChatMessagePrivate::sendImdn (Imdn::Type imdnType, LinphoneReason reason) {
|
|||
shared_ptr<ChatMessage> msg = q->getChatRoom()->createChatMessage();
|
||||
|
||||
Content *content = new Content();
|
||||
content->setContentDisposition(ContentDisposition::Notification);
|
||||
content->setContentType(ContentType::Imdn);
|
||||
content->setBody(Imdn::createXml(imdnId, time, imdnType, reason));
|
||||
msg->addContent(content);
|
||||
|
|
@ -773,13 +772,16 @@ void ChatMessagePrivate::send () {
|
|||
|
||||
auto msgOp = dynamic_cast<SalMessageOpInterface *>(op);
|
||||
if (!externalBodyUrl.empty()) {
|
||||
char *content_type = ms_strdup_printf("message/external-body;access-type=URL;URL=\"%s\"", externalBodyUrl.c_str());
|
||||
msgOp->send_message(content_type, NULL);
|
||||
ms_free(content_type);
|
||||
} else if (internalContent.getContentType().isValid()) {
|
||||
msgOp->send_message(internalContent.getContentType().asString().c_str(), internalContent.getBodyAsUtf8String().c_str());
|
||||
Content content;
|
||||
ContentType contentType(ContentType::ExternalBody);
|
||||
contentType.addParameter("access-type", "URL");
|
||||
contentType.addParameter("URL", "\"" + externalBodyUrl + "\"");
|
||||
content.setContentType(contentType);
|
||||
msgOp->sendMessage(content);
|
||||
} else {
|
||||
msgOp->send_message(ContentType::PlainText.asString().c_str(), internalContent.getBodyAsUtf8String().c_str());
|
||||
if (!internalContent.getContentType().isValid())
|
||||
internalContent.setContentType(ContentType::PlainText);
|
||||
msgOp->sendMessage(internalContent);
|
||||
}
|
||||
|
||||
// Restore FileContents and remove FileTransferContents
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ public:
|
|||
private:
|
||||
struct Message {
|
||||
Message (const std::string &from, const ContentType &contentType, const std::string &text, const SalCustomHeader *salCustomHeaders)
|
||||
: fromAddr(from)
|
||||
: fromAddr(from)
|
||||
{
|
||||
content.setContentType(contentType);
|
||||
if (!text.empty())
|
||||
|
|
|
|||
|
|
@ -20,8 +20,9 @@
|
|||
#include "address/address.h"
|
||||
#include "chat/chat-message/chat-message-p.h"
|
||||
#include "chat/cpim/cpim.h"
|
||||
#include "content/content-type.h"
|
||||
#include "content/content.h"
|
||||
#include "content/content-disposition.h"
|
||||
#include "content/content-type.h"
|
||||
#include "logger/logger.h"
|
||||
|
||||
#include "cpim-chat-message-modifier.h"
|
||||
|
|
@ -59,6 +60,12 @@ ChatMessageModifier::Result CpimChatMessageModifier::encode (const shared_ptr<Ch
|
|||
content = message->getContents().front();
|
||||
}
|
||||
|
||||
if (content->getContentDisposition().isValid()) {
|
||||
Cpim::GenericHeader contentDispositionHeader;
|
||||
contentDispositionHeader.setName("Content-Disposition");
|
||||
contentDispositionHeader.setValue(content->getContentDisposition().asString());
|
||||
cpimMessage.addContentHeader(contentDispositionHeader);
|
||||
}
|
||||
Cpim::GenericHeader contentTypeHeader;
|
||||
contentTypeHeader.setName("Content-Type");
|
||||
contentTypeHeader.setValue(content->getContentType().asString());
|
||||
|
|
@ -100,10 +107,11 @@ ChatMessageModifier::Result CpimChatMessageModifier::decode (const shared_ptr<Ch
|
|||
Cpim::Message::HeaderList l = cpimMessage->getContentHeaders();
|
||||
if (l) {
|
||||
for (const auto &header : *l.get()) {
|
||||
if (header->getName() == "Content-Type") {
|
||||
if (header->getName() == "Content-Disposition") {
|
||||
newContent.setContentDisposition(ContentDisposition(header->getValue()));
|
||||
} else if (header->getName() == "Content-Type") {
|
||||
contentTypeFound = true;
|
||||
newContent.setContentType(ContentType(header->getValue()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ public:
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
const ContentDisposition ContentDisposition::Notification("notification");
|
||||
const ContentDisposition ContentDisposition::RecipientList("recipient-list");
|
||||
const ContentDisposition ContentDisposition::RecipientListHistory("recipient-list-history; handling=optional");
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ public:
|
|||
|
||||
std::string asString () const;
|
||||
|
||||
static const ContentDisposition Notification;
|
||||
static const ContentDisposition RecipientList;
|
||||
static const ContentDisposition RecipientListHistory;
|
||||
|
||||
|
|
|
|||
|
|
@ -1530,10 +1530,11 @@ void SalCallOp::process_notify(const belle_sip_request_event_t *event, belle_sip
|
|||
}
|
||||
}
|
||||
|
||||
int SalCallOp::send_message(const char* content_type, const char *msg) {
|
||||
if (!this->dialog) return -1;
|
||||
belle_sip_request_t* req=belle_sip_dialog_create_queued_request(this->dialog,"MESSAGE");
|
||||
prepare_message_request(req, content_type, msg);
|
||||
int SalCallOp::sendMessage (const Content &content) {
|
||||
if (!this->dialog)
|
||||
return -1;
|
||||
belle_sip_request_t *req = belle_sip_dialog_create_queued_request(this->dialog, "MESSAGE");
|
||||
prepareMessageRequest(req, content);
|
||||
return send_request(req);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ public:
|
|||
void set_sdp_handling(SalOpSDPHandling handling);
|
||||
|
||||
// Implementation of SalMessageOpInterface
|
||||
int send_message(const char* content_type, const char *msg) override;
|
||||
int sendMessage (const Content &content) override;
|
||||
int reply(SalReason reason) override {return SalOp::reply_message(reason);}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -20,17 +20,49 @@
|
|||
#ifndef _L_SAL_MESSAGE_OP_INTERFACE_H_
|
||||
#define _L_SAL_MESSAGE_OP_INTERFACE_H_
|
||||
|
||||
#include <ctime>
|
||||
|
||||
#include "content/content.h"
|
||||
#include "content/content-type.h"
|
||||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
class SalMessageOpInterface {
|
||||
public:
|
||||
virtual ~SalMessageOpInterface() = default;
|
||||
|
||||
virtual int send_message(const char* content_type, const char *msg) = 0;
|
||||
virtual int sendMessage (const Content &content) = 0;
|
||||
virtual int reply(SalReason reason) = 0;
|
||||
|
||||
protected:
|
||||
void prepare_message_request(belle_sip_request_t *req, const char* content_type, const char *msg);
|
||||
void prepareMessageRequest (belle_sip_request_t *req, const Content &content) {
|
||||
time_t curtime = std::time(nullptr);
|
||||
belle_sip_message_add_header(
|
||||
BELLE_SIP_MESSAGE(req),
|
||||
BELLE_SIP_HEADER(belle_sip_header_date_create_from_time(&curtime))
|
||||
);
|
||||
const ContentType &contentType = content.getContentType();
|
||||
std::string contentTypeStr = std::string(BELLE_SIP_CONTENT_TYPE ": ") + contentType.asString();
|
||||
belle_sip_message_add_header(
|
||||
BELLE_SIP_MESSAGE(req),
|
||||
BELLE_SIP_HEADER(belle_sip_header_content_type_parse(contentTypeStr.c_str()))
|
||||
);
|
||||
if (content.isEmpty()) {
|
||||
belle_sip_message_add_header(
|
||||
BELLE_SIP_MESSAGE(req),
|
||||
BELLE_SIP_HEADER(belle_sip_header_content_length_create(0))
|
||||
);
|
||||
} else {
|
||||
std::string body = content.getBodyAsUtf8String();
|
||||
size_t contentLength = body.size();
|
||||
belle_sip_message_add_header(
|
||||
BELLE_SIP_MESSAGE(req),
|
||||
BELLE_SIP_HEADER(belle_sip_header_content_length_create(contentLength))
|
||||
);
|
||||
belle_sip_message_set_body(BELLE_SIP_MESSAGE(req), body.c_str(), contentLength);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -77,27 +77,13 @@ void SalMessageOp::fill_cbs() {
|
|||
this->type=Type::Message;
|
||||
}
|
||||
|
||||
void SalMessageOpInterface::prepare_message_request(belle_sip_request_t *req, const char* content_type, const char *msg) {
|
||||
char content_type_raw[256];
|
||||
size_t content_length = msg?strlen(msg):0;
|
||||
time_t curtime = ms_time(NULL);
|
||||
snprintf(content_type_raw,sizeof(content_type_raw),BELLE_SIP_CONTENT_TYPE ": %s",content_type);
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_content_type_parse(content_type_raw)));
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_content_length_create(content_length)));
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_date_create_from_time(&curtime)));
|
||||
if (msg){
|
||||
/*don't call set_body() with null argument because it resets content type and content length*/
|
||||
belle_sip_message_set_body(BELLE_SIP_MESSAGE(req), msg, content_length);
|
||||
}
|
||||
}
|
||||
|
||||
int SalMessageOp::send_message(const char* content_type, const char *msg) {
|
||||
int SalMessageOp::sendMessage (const Content &content) {
|
||||
fill_cbs();
|
||||
this->dir = Dir::Outgoing;
|
||||
belle_sip_request_t *req = build_request("MESSAGE");
|
||||
if (!req)
|
||||
return -1;
|
||||
prepare_message_request(req, content_type, msg);
|
||||
prepareMessageRequest(req, content);
|
||||
return send_request(req);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class SalMessageOp: public SalOp, public SalMessageOpInterface {
|
|||
public:
|
||||
SalMessageOp(Sal *sal): SalOp(sal) {}
|
||||
|
||||
int send_message(const char* content_type, const char *msg) override;
|
||||
int sendMessage (const Content &content) override;
|
||||
int reply(SalReason reason) override {return SalOp::reply_message(reason);}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -1040,7 +1040,7 @@ void SalOp::process_incoming_message(const belle_sip_request_event_t *event) {
|
|||
salmsg.url = ms_strdup(belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type),"URL")+1); /* skip first "*/
|
||||
((char*)salmsg.url)[url_length-2]='\0'; /*remove trailing "*/
|
||||
}
|
||||
|
||||
|
||||
salmsg.message_id=message_id;
|
||||
salmsg.time=date ? belle_sip_header_date_get_time(date) : time(NULL);
|
||||
this->root->callbacks.message_received(this,&salmsg);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue