summaryrefslogtreecommitdiff
path: root/protocols/SkypeWeb/src/skype_files.cpp
blob: 59312c60ecb724fadc73c94c0f49b02b9a8316b3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include "stdafx.h"

#define FILETRANSFER_FAILED(fup) { ProtoBroadcastAck(fup->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)fup); delete fup; fup = nullptr;} 

HANDLE CSkypeProto::SendFile(MCONTACT hContact, const wchar_t *szDescription, wchar_t **ppszFiles)
{
	if (IsOnline()) {
		CFileUploadParam *fup = new CFileUploadParam(hContact, szDescription, ppszFiles);
		ForkThread(&CSkypeProto::SendFileThread, (void*)fup);
		return (HANDLE)fup;
	}
	return INVALID_HANDLE_VALUE;
}

void CSkypeProto::SendFileThread(void *p)
{
	CFileUploadParam *fup = (CFileUploadParam *)p;
	if (!IsOnline()) {
		FILETRANSFER_FAILED(fup);
		return;
	}
	if (!fup->IsAccess()) {
		FILETRANSFER_FAILED(fup);
		return;
	}

	ProtoBroadcastAck(fup->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, (HANDLE)fup);
	T2Utf uszFileName(fup->tszFileName);
	SendRequest(new ASMObjectCreateRequest(li, CMStringA(FORMAT, "%d:%s", isChatRoom(fup->hContact) ? 19 : 8, Contacts[fup->hContact]), strrchr((const char*)uszFileName + 1, '\\')), &CSkypeProto::OnASMObjectCreated, fup);
}

void CSkypeProto::OnASMObjectCreated(const NETLIBHTTPREQUEST *response, void *arg)
{
	CFileUploadParam *fup = (CFileUploadParam*)arg;
	if (response && response->pData) {
		JSONNode node = JSONNode::parse((char*)response->pData);
		std::string strObjectId = node["id"].as_string();
		fup->uid = mir_strdup(strObjectId.c_str());
		FILE *pFile = _wfopen(fup->tszFileName, L"rb");
		if (pFile == nullptr) return;

		fseek(pFile, 0, SEEK_END);
		long lFileLen = ftell(pFile);

		if (lFileLen < 1) {
			fclose(pFile);
			return;
		}

		fseek(pFile, 0, SEEK_SET);

		mir_ptr<BYTE> pData((BYTE*)mir_alloc(lFileLen));
		long lBytes = (long)fread(pData, sizeof(BYTE), lFileLen, pFile);

		if (lBytes != lFileLen) {
			fclose(pFile);
			FILETRANSFER_FAILED(fup);
			return;
		}
		fup->size = lBytes;
		ProtoBroadcastAck(fup->hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, (HANDLE)fup);
		SendRequest(new ASMObjectUploadRequest(li, strObjectId.c_str(), pData, lBytes), &CSkypeProto::OnASMObjectUploaded, fup);
		fclose(pFile);
	}
}

void CSkypeProto::OnASMObjectUploaded(const NETLIBHTTPREQUEST *response, void *arg)
{
	CFileUploadParam *fup = (CFileUploadParam*)arg;
	if (response == nullptr) {
		FILETRANSFER_FAILED(fup);
		return;
	}

	wchar_t *tszFile = wcsrchr(fup->tszFileName, L'\\') + 1;

	HXML xml = xmlCreateNode(L"URIObject", nullptr, 0);
	xmlAddChild(xml, L"Title", tszFile);
	xmlAddChild(xml, L"Description", fup->tszDesc);
	HXML xmlA = xmlAddChild(xml, L"a", CMStringW(FORMAT, L"https://login.skype.com/login/sso?go=webclient.xmm&docid=%s", _A2T(fup->uid)));
	xmlAddAttr(xmlA, L"href", CMStringW(FORMAT, L"https://login.skype.com/login/sso?go=webclient.xmm&docid=%s", _A2T(fup->uid)));
	HXML xmlOrigName = xmlAddChild(xml, L"OriginalName", nullptr);
	xmlAddAttr(xmlOrigName, L"v", tszFile);
	HXML xmlSize = xmlAddChild(xml, L"FileSize", nullptr);
	xmlAddAttr(xmlSize, L"v", CMStringW(FORMAT, L"%d", fup->size));

	xmlAddAttr(xml, L"Type", L"File.1");
	xmlAddAttr(xml, L"uri", CMStringW(FORMAT, L"https://api.asm.skype.com/v1/objects/%s", _A2T(fup->uid)));
	xmlAddAttr(xml, L"url_thumbnail", CMStringW(FORMAT, L"https://api.asm.skype.com/v1/objects/%s/views/thumbnail", _A2T(fup->uid)));

	SendRequest(new SendMessageRequest(Contacts[fup->hContact], time(NULL), T2Utf(ptrW(xmlToString(xml, nullptr))), li, "RichText/Media_GenericFile"));
	xmlDestroyNode(xml);
	ProtoBroadcastAck(fup->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, (HANDLE)fup);
	delete fup;
}