1/*
2 * Copyright 2010-2017 Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Christophe Huriaux, c.huriaux@gmail.com
7 *		Adrien Destugues, pulkomandy@pulkomandy.tk
8 */
9
10
11#include <UrlProtocolAsynchronousListener.h>
12
13#include <new>
14
15#include <AppKit.h>
16#include <Archivable.h>
17#include <Debug.h>
18#include <String.h>
19#include <UrlResult.h>
20
21using namespace BPrivate::Network;
22
23
24extern const char* kUrlProtocolMessageType;
25extern const char* kUrlProtocolCaller;
26
27
28BUrlProtocolAsynchronousListener::BUrlProtocolAsynchronousListener(
29	bool transparent)
30	:
31	BHandler("UrlProtocolAsynchronousListener"),
32	BUrlProtocolListener(),
33	fSynchronousListener(NULL)
34{
35	if (be_app->Lock()) {
36		be_app->AddHandler(this);
37		be_app->Unlock();
38	} else
39		PRINT(("Cannot lock be_app\n"));
40
41	if (transparent) {
42		fSynchronousListener
43			= new(std::nothrow) BUrlProtocolDispatchingListener(this);
44	}
45}
46
47
48BUrlProtocolAsynchronousListener::~BUrlProtocolAsynchronousListener()
49{
50	if (be_app->Lock()) {
51		be_app->RemoveHandler(this);
52		be_app->Unlock();
53	}
54	delete fSynchronousListener;
55}
56
57
58// #pragma mark Synchronous listener access
59
60
61BUrlProtocolListener*
62BUrlProtocolAsynchronousListener::SynchronousListener()
63{
64	return fSynchronousListener;
65}
66
67
68void
69BUrlProtocolAsynchronousListener::MessageReceived(BMessage* message)
70{
71	if (message->what != B_URL_PROTOCOL_NOTIFICATION) {
72		BHandler::MessageReceived(message);
73		return;
74	}
75
76	BUrlRequest* caller;
77	if (message->FindPointer(kUrlProtocolCaller, (void**)&caller) != B_OK)
78		return;
79
80	int8 notification;
81	if (message->FindInt8(kUrlProtocolMessageType, &notification) != B_OK)
82		return;
83
84	switch (notification) {
85		case B_URL_PROTOCOL_CONNECTION_OPENED:
86			ConnectionOpened(caller);
87			break;
88
89		case B_URL_PROTOCOL_HOSTNAME_RESOLVED:
90			{
91				const char* ip;
92				message->FindString("url:ip", &ip);
93
94				HostnameResolved(caller, ip);
95			}
96			break;
97
98		case B_URL_PROTOCOL_RESPONSE_STARTED:
99			ResponseStarted(caller);
100			break;
101
102		case B_URL_PROTOCOL_HEADERS_RECEIVED:
103			HeadersReceived(caller);
104			break;
105
106		case B_URL_PROTOCOL_BYTES_WRITTEN:
107			{
108				size_t bytesWritten = message->FindInt32("url:bytesWritten");
109
110				BytesWritten(caller, bytesWritten);
111			}
112			break;
113
114		case B_URL_PROTOCOL_DOWNLOAD_PROGRESS:
115			{
116				off_t bytesReceived;
117				off_t bytesTotal;
118				message->FindInt64("url:bytesReceived", &bytesReceived);
119				message->FindInt64("url:bytesTotal", &bytesTotal);
120
121				DownloadProgress(caller, bytesReceived, bytesTotal);
122			}
123			break;
124
125		case B_URL_PROTOCOL_UPLOAD_PROGRESS:
126			{
127				off_t bytesSent;
128				off_t bytesTotal;
129				message->FindInt64("url:bytesSent", &bytesSent);
130				message->FindInt64("url:bytesTotal", &bytesTotal);
131
132				UploadProgress(caller, bytesSent, bytesTotal);
133			}
134			break;
135
136		case B_URL_PROTOCOL_REQUEST_COMPLETED:
137			{
138				bool success;
139				message->FindBool("url:success", &success);
140
141				RequestCompleted(caller, success);
142			}
143			break;
144
145		case B_URL_PROTOCOL_DEBUG_MESSAGE:
146			{
147				BUrlProtocolDebugMessage type
148					= (BUrlProtocolDebugMessage)message->FindInt32("url:type");
149				BString text = message->FindString("url:text");
150
151				DebugMessage(caller, type, text);
152			}
153			break;
154
155		case B_URL_PROTOCOL_CERTIFICATE_VERIFICATION_FAILED:
156			{
157				const char* error = message->FindString("url:error");
158				BCertificate* certificate;
159				message->FindPointer("url:certificate", (void**)&certificate);
160				bool result = CertificateVerificationFailed(caller,
161					*certificate, error);
162
163				BMessage reply;
164				reply.AddBool("url:continue", result);
165				message->SendReply(&reply);
166			}
167			break;
168
169		default:
170			PRINT(("BUrlProtocolAsynchronousListener: Unknown notification %d\n",
171				notification));
172			break;
173	}
174}
175