From 51ccfb874ece51a0bdd08226d190ddf86a6013fd Mon Sep 17 00:00:00 2001 From: George Hazan Date: Fri, 13 Jan 2023 18:22:12 +0300 Subject: Jabber: ability to autoload files passed via HTTP Upload instead of writing messages with URLs --- protocols/JabberG/src/jabber_byte.cpp | 2 +- protocols/JabberG/src/jabber_byte.h | 2 +- protocols/JabberG/src/jabber_file.cpp | 23 ++++++++++++++++++ protocols/JabberG/src/jabber_ft.cpp | 4 ++-- protocols/JabberG/src/jabber_ibb.cpp | 2 +- protocols/JabberG/src/jabber_ibb.h | 2 +- protocols/JabberG/src/jabber_opt.cpp | 1 + protocols/JabberG/src/jabber_proto.cpp | 4 ++++ protocols/JabberG/src/jabber_proto.h | 5 ++-- protocols/JabberG/src/jabber_thread.cpp | 41 +++++++++++++++++---------------- 10 files changed, 58 insertions(+), 28 deletions(-) (limited to 'protocols/JabberG') diff --git a/protocols/JabberG/src/jabber_byte.cpp b/protocols/JabberG/src/jabber_byte.cpp index 060b10ee6c..518155ebe8 100644 --- a/protocols/JabberG/src/jabber_byte.cpp +++ b/protocols/JabberG/src/jabber_byte.cpp @@ -718,7 +718,7 @@ int CJabberProto::ByteReceiveParse(HNETLIBCONN hConn, JABBER_BYTE_TRANSFER *jbt, break; case JBT_RECVING: - bytesReceived = (this->*jbt->pfnRecv)(hConn, jbt->ft, buffer, datalen); + bytesReceived = (this->*jbt->pfnRecv)(jbt->ft, buffer, datalen); if (bytesReceived < 0) jbt->state = JBT_ERROR; else if (bytesReceived == 0) diff --git a/protocols/JabberG/src/jabber_byte.h b/protocols/JabberG/src/jabber_byte.h index 5de0be588c..57a7da40d1 100644 --- a/protocols/JabberG/src/jabber_byte.h +++ b/protocols/JabberG/src/jabber_byte.h @@ -46,7 +46,7 @@ struct JABBER_BYTE_TRANSFER : public MZeroedObject TiXmlDocument doc; TiXmlElement *iqNode; bool (CJabberProto::*pfnSend)(HNETLIBCONN hConn, filetransfer *ft); - int (CJabberProto::*pfnRecv)(HNETLIBCONN hConn, filetransfer *ft, char* buffer, int datalen); + int (CJabberProto::*pfnRecv)(filetransfer *ft, char* buffer, int datalen); void (CJabberProto::*pfnFinal)(bool success, filetransfer *ft); filetransfer *ft; diff --git a/protocols/JabberG/src/jabber_file.cpp b/protocols/JabberG/src/jabber_file.cpp index f39cbbdf32..8bedca6f28 100644 --- a/protocols/JabberG/src/jabber_file.cpp +++ b/protocols/JabberG/src/jabber_file.cpp @@ -27,6 +27,29 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define JABBER_NETWORK_BUFFER_SIZE 2048 +void __cdecl CJabberProto::FileReceiveHttpThread(filetransfer *ft) +{ + NETLIBHTTPREQUEST req = {}; + req.cbSize = sizeof(req); + req.requestType = REQUEST_GET; + req.szUrl = ft->httpPath; + + NLHR_PTR pResp(Netlib_HttpTransaction(m_hNetlibUser, &req)); + if (pResp && pResp->resultCode == 200) { + ft->std.currentFileSize = pResp->cbSize; + ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, ft); + + FtReceive(ft, pResp->pData, pResp->cbSize); + + ft->complete(); + } + else ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft); + + delete ft; +} + +///////////////////////////////////////////////////////////////////////////////////////// + void __cdecl CJabberProto::FileReceiveThread(filetransfer *ft) { ThreadData info(this, nullptr); diff --git a/protocols/JabberG/src/jabber_ft.cpp b/protocols/JabberG/src/jabber_ft.cpp index 0329d16747..e566695947 100644 --- a/protocols/JabberG/src/jabber_ft.cpp +++ b/protocols/JabberG/src/jabber_ft.cpp @@ -456,7 +456,7 @@ void CJabberProto::FtHandleSiRequest(const TiXmlElement *iqNode) ft->std.szCurrentFile.w = mir_utf8decodeW(filename); ft->std.totalBytes = ft->std.currentFileSize = filesize; - PROTORECVFILE pre = { 0 }; + PROTORECVFILE pre = {}; pre.fileCount = 1; pre.timestamp = time(0); pre.files.a = &filename; @@ -603,7 +603,7 @@ bool CJabberProto::FtHandleIbbRequest(const TiXmlElement *iqNode, bool bOpen) return false; } -int CJabberProto::FtReceive(HNETLIBCONN, filetransfer *ft, char* buffer, int datalen) +int CJabberProto::FtReceive(filetransfer *ft, char* buffer, int datalen) { if (ft->create() == -1) return -1; diff --git a/protocols/JabberG/src/jabber_ibb.cpp b/protocols/JabberG/src/jabber_ibb.cpp index 67ba5ba2c9..5b40a005d5 100644 --- a/protocols/JabberG/src/jabber_ibb.cpp +++ b/protocols/JabberG/src/jabber_ibb.cpp @@ -185,7 +185,7 @@ bool CJabberProto::OnIbbRecvdData(const char *data, const char *sid, const char if (decodedData == nullptr) return false; - (this->*item->jibb->pfnRecv)(nullptr, item->ft, decodedData, (int)length); + (this->*item->jibb->pfnRecv)(item->ft, decodedData, (int)length); item->jibb->dwTransferredSize += (uint32_t)length; return true; } diff --git a/protocols/JabberG/src/jabber_ibb.h b/protocols/JabberG/src/jabber_ibb.h index f620b52ba4..91c6d32fe7 100644 --- a/protocols/JabberG/src/jabber_ibb.h +++ b/protocols/JabberG/src/jabber_ibb.h @@ -40,7 +40,7 @@ struct JABBER_IBB_TRANSFER bool bStreamClosed; uint16_t wPacketId; bool (CJabberProto::*pfnSend)(int blocksize, filetransfer *ft); - int (CJabberProto::*pfnRecv)(HNETLIBCONN hConn, filetransfer *ft, char* buffer, int datalen); + int (CJabberProto::*pfnRecv)(filetransfer *ft, char* buffer, int datalen); void (CJabberProto::*pfnFinal)(bool success, filetransfer *ft); filetransfer *ft; }; diff --git a/protocols/JabberG/src/jabber_opt.cpp b/protocols/JabberG/src/jabber_opt.cpp index c7e85211cd..b164bb84cb 100644 --- a/protocols/JabberG/src/jabber_opt.cpp +++ b/protocols/JabberG/src/jabber_opt.cpp @@ -717,6 +717,7 @@ public: m_options.AddOption(LPGENW("Other"), LPGENW("Show transport agents on contact list"), m_proto->m_bShowTransport); m_options.AddOption(LPGENW("Other"), LPGENW("Automatically add contact when accept authorization"), m_proto->m_bAutoAdd); m_options.AddOption(LPGENW("Other"), LPGENW("Automatically accept authorization requests"), m_proto->m_bAutoAcceptAuthorization); + m_options.AddOption(LPGENW("Other"), LPGENW("Automatically download files passed via HTTP Upload"), m_proto->m_bAutoLoadOOB); m_options.AddOption(LPGENW("Other"), LPGENW("Fix incorrect timestamps in incoming messages"), m_proto->m_bFixIncorrectTimestamps); m_options.AddOption(LPGENW("Other"), LPGENW("Enable XMPP link processing (requires AssocMgr)"), m_proto->m_bProcessXMPPLinks); m_options.AddOption(LPGENW("Other"), LPGENW("Embrace picture URLs with [img]"), m_proto->m_bEmbraceUrls); diff --git a/protocols/JabberG/src/jabber_proto.cpp b/protocols/JabberG/src/jabber_proto.cpp index 3811becab3..4fb6dbf5a9 100644 --- a/protocols/JabberG/src/jabber_proto.cpp +++ b/protocols/JabberG/src/jabber_proto.cpp @@ -86,6 +86,7 @@ CJabberProto::CJabberProto(const char *aProtoName, const wchar_t *aUserName) : m_bAutoJoinBookmarks(this, "AutoJoinBookmarks", true), m_bAutoJoinConferences(this, "AutoJoinConferences", false), m_bAutoJoinHidden(this, "AutoJoinHidden", true), + m_bAutoLoadOOB(this, "AutoLoadOOB", true), m_bAutosaveNotes(this, "AutosaveNotes", false), m_bBsDirect(this, "BsDirect", true), m_bBsDirectManual(this, "BsDirectManual", false), @@ -526,6 +527,9 @@ HANDLE CJabberProto::FileAllow(MCONTACT /*hContact*/, HANDLE hTransfer, const wc case FT_OOB: ForkThread((MyThreadFunc)&CJabberProto::FileReceiveThread, ft); break; + case FT_HTTP: + ForkThread((MyThreadFunc)&CJabberProto::FileReceiveHttpThread, ft); + break; case FT_BYTESTREAM: FtAcceptSiRequest(ft); break; diff --git a/protocols/JabberG/src/jabber_proto.h b/protocols/JabberG/src/jabber_proto.h index 6037019f46..cf27af0ea8 100644 --- a/protocols/JabberG/src/jabber_proto.h +++ b/protocols/JabberG/src/jabber_proto.h @@ -193,6 +193,7 @@ struct CJabberProto : public PROTO, public IJabberInterface CMOption m_bAutoJoinBookmarks; CMOption m_bAutoJoinConferences; CMOption m_bAutoJoinHidden; + CMOption m_bAutoLoadOOB; CMOption m_bAutosaveNotes; CMOption m_bBsDirect; CMOption m_bBsDirectManual; @@ -503,6 +504,7 @@ struct CJabberProto : public PROTO, public IJabberInterface void __cdecl FileReceiveThread(filetransfer *ft); void __cdecl FileServerThread(filetransfer *ft); + void __cdecl FileReceiveHttpThread(filetransfer *ft); void FtCancel(filetransfer *ft); void FtInitiate(filetransfer *ft); @@ -607,7 +609,7 @@ struct CJabberProto : public PROTO, public IJabberInterface bool FtIbbSend(int blocksize, filetransfer *ft); bool FtSend(HNETLIBCONN hConn, filetransfer *ft); void FtSendFinal(bool success, filetransfer *ft); - int FtReceive(HNETLIBCONN hConn, filetransfer *ft, char* buffer, int datalen); + int FtReceive(filetransfer *ft, char* buffer, int datalen); void FtReceiveFinal(bool success, filetransfer *ft); //---- jabber_iqid.cpp --------------------------------------------------------------- @@ -755,7 +757,6 @@ struct CJabberProto : public PROTO, public IJabberInterface void __cdecl BasicSearchThread(struct JABBER_SEARCH_BASIC *jsb); void __cdecl GetAwayMsgThread(void* hContact); - void __cdecl SendMessageAckThread(void* hContact); MCONTACT AddToListByJID(const char *newJid, uint32_t flags); diff --git a/protocols/JabberG/src/jabber_thread.cpp b/protocols/JabberG/src/jabber_thread.cpp index 0ad67e79dd..a088f16c12 100644 --- a/protocols/JabberG/src/jabber_thread.cpp +++ b/protocols/JabberG/src/jabber_thread.cpp @@ -1330,32 +1330,33 @@ void CJabberProto::OnProcessMessage(const TiXmlElement *node, ThreadData *info) szMessage += tempstring; } } - else if (!mir_strcmp(pszXmlns, JABBER_FEAT_OOB2)) { + else if (!mir_strcmp(pszXmlns, JABBER_FEAT_OOB2) && m_bAutoLoadOOB) { if (auto *url = XmlGetChildText(xNode, "url")) { - DBEVENTINFO dbei = {}; - dbei.szModule = Proto_GetBaseAccountName(hContact); - dbei.timestamp = msgTime; - dbei.eventType = EVENTTYPE_FILE; - dbei.flags = DBEF_UTF; - //if (pre->dwFlags & PREF_CREATEREAD) - dbei.flags |= DBEF_READ; - + // create incoming file transfer instead of writing message CMStringA szName; const char *b = strrchr(url, '/') + 1; while (*b != 0 && *b != '#' && *b != '?') szName.AppendChar(*b++); - - auto *szDescr = XmlGetChildText(xNode, "desc"); - - CMStringA szBlob(FORMAT, "%c%c%c%c", 0, 0, 0, 0); - szBlob.AppendFormat("%s%c", szName.c_str(), 0); - szBlob.AppendFormat("%s%c", szDescr ? szDescr : "", 0); - szBlob.AppendFormat("%s%c", url, 0); - - dbei.cbBlob = szBlob.GetLength(); - dbei.pBlob = (uint8_t*)szBlob.GetBuffer(); - db_event_add(hContact, &dbei); + auto *pszName = szName.c_str(); + + filetransfer *ft = new filetransfer(this, 0); + ft->jid = mir_strdup(from); + ft->std.hContact = hContact; + ft->type = FT_HTTP; + ft->httpPath = mir_strdup(url); + ft->std.totalFiles = 1; + ft->std.szCurrentFile.w = mir_utf8decodeW(szName); + + PROTORECVFILE pre = {}; + pre.fileCount = 1; + pre.timestamp = time(0); + pre.files.a = &pszName; + pre.lParam = (LPARAM)ft; + pre.descr.a = XmlGetChildText(xNode, "desc"); + ProtoChainRecvFile(ft->std.hContact, &pre); + return; } + else debugLogA("No URL in OOB file transfer, ignoring"); } else if (!mir_strcmp(pszXmlns, JABBER_FEAT_MUC_USER)) { auto *inviteNode = XmlFirstChild(xNode, "invite"); -- cgit v1.2.3