| 
									
										
										
										
											2021-04-23 22:45:52 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <AK/FileStream.h>
 | 
					
						
							|  |  |  | #include <LibProtocol/Request.h>
 | 
					
						
							|  |  |  | #include <LibProtocol/RequestClient.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace Protocol { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-14 13:12:49 +00:00
										 |  |  | RequestClient::RequestClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket) | 
					
						
							|  |  |  |     : IPC::ServerConnection<RequestClientEndpoint, RequestServerEndpoint>(*this, move(socket)) | 
					
						
							| 
									
										
										
										
											2021-04-23 22:45:52 +02:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-28 00:06:52 +03:30
										 |  |  | void RequestClient::ensure_connection(URL const& url, ::RequestServer::CacheLevel cache_level) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     async_ensure_connection(url, cache_level); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-23 22:45:52 +02:00
										 |  |  | template<typename RequestHashMapTraits> | 
					
						
							| 
									
										
										
										
											2021-06-05 11:59:04 +02:00
										 |  |  | RefPtr<Request> RequestClient::start_request(String const& method, URL const& url, HashMap<String, String, RequestHashMapTraits> const& request_headers, ReadonlyBytes request_body) | 
					
						
							| 
									
										
										
										
											2021-04-23 22:45:52 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     IPC::Dictionary header_dictionary; | 
					
						
							|  |  |  |     for (auto& it : request_headers) | 
					
						
							|  |  |  |         header_dictionary.add(it.key, it.value); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-06 03:29:52 +04:30
										 |  |  |     auto body_result = ByteBuffer::copy(request_body); | 
					
						
							| 
									
										
										
										
											2022-01-20 17:47:39 +00:00
										 |  |  |     if (body_result.is_error()) | 
					
						
							| 
									
										
										
										
											2021-09-06 03:29:52 +04:30
										 |  |  |         return nullptr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto response = IPCProxy::start_request(method, url, header_dictionary, body_result.release_value()); | 
					
						
							| 
									
										
										
										
											2021-05-03 13:33:59 +02:00
										 |  |  |     auto request_id = response.request_id(); | 
					
						
							|  |  |  |     if (request_id < 0 || !response.response_fd().has_value()) | 
					
						
							| 
									
										
										
										
											2021-04-23 22:45:52 +02:00
										 |  |  |         return nullptr; | 
					
						
							| 
									
										
										
										
											2021-05-03 13:33:59 +02:00
										 |  |  |     auto response_fd = response.response_fd().value().take_fd(); | 
					
						
							| 
									
										
										
										
											2021-04-23 22:45:52 +02:00
										 |  |  |     auto request = Request::create_from_id({}, *this, request_id); | 
					
						
							|  |  |  |     request->set_request_fd({}, response_fd); | 
					
						
							|  |  |  |     m_requests.set(request_id, request); | 
					
						
							|  |  |  |     return request; | 
					
						
							| 
									
										
										
										
											2021-05-03 13:33:59 +02:00
										 |  |  |     return nullptr; | 
					
						
							| 
									
										
										
										
											2021-04-23 22:45:52 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool RequestClient::stop_request(Badge<Request>, Request& request) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!m_requests.contains(request.id())) | 
					
						
							|  |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2021-05-03 13:55:29 +02:00
										 |  |  |     return IPCProxy::stop_request(request.id()); | 
					
						
							| 
									
										
										
										
											2021-04-23 22:45:52 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool RequestClient::set_certificate(Badge<Request>, Request& request, String certificate, String key) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!m_requests.contains(request.id())) | 
					
						
							|  |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2021-05-03 13:55:29 +02:00
										 |  |  |     return IPCProxy::set_certificate(request.id(), move(certificate), move(key)); | 
					
						
							| 
									
										
										
										
											2021-04-23 22:45:52 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-02 19:54:34 +02:00
										 |  |  | void RequestClient::request_finished(i32 request_id, bool success, u32 total_size) | 
					
						
							| 
									
										
										
										
											2021-04-23 22:45:52 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     RefPtr<Request> request; | 
					
						
							| 
									
										
										
										
											2021-05-02 19:54:34 +02:00
										 |  |  |     if ((request = m_requests.get(request_id).value_or(nullptr))) { | 
					
						
							|  |  |  |         request->did_finish({}, success, total_size); | 
					
						
							| 
									
										
										
										
											2021-04-23 22:45:52 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-05-02 19:54:34 +02:00
										 |  |  |     m_requests.remove(request_id); | 
					
						
							| 
									
										
										
										
											2021-04-23 22:45:52 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-05 11:57:14 +02:00
										 |  |  | void RequestClient::request_progress(i32 request_id, Optional<u32> const& total_size, u32 downloaded_size) | 
					
						
							| 
									
										
										
										
											2021-04-23 22:45:52 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-05-02 19:54:34 +02:00
										 |  |  |     if (auto request = const_cast<Request*>(m_requests.get(request_id).value_or(nullptr))) { | 
					
						
							|  |  |  |         request->did_progress({}, total_size, downloaded_size); | 
					
						
							| 
									
										
										
										
											2021-04-23 22:45:52 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-05 11:57:14 +02:00
										 |  |  | void RequestClient::headers_became_available(i32 request_id, IPC::Dictionary const& response_headers, Optional<u32> const& status_code) | 
					
						
							| 
									
										
										
										
											2021-04-23 22:45:52 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-05-02 19:54:34 +02:00
										 |  |  |     if (auto request = const_cast<Request*>(m_requests.get(request_id).value_or(nullptr))) { | 
					
						
							| 
									
										
										
										
											2021-04-23 22:45:52 +02:00
										 |  |  |         HashMap<String, String, CaseInsensitiveStringTraits> headers; | 
					
						
							| 
									
										
										
										
											2021-05-02 19:54:34 +02:00
										 |  |  |         response_headers.for_each_entry([&](auto& name, auto& value) { headers.set(name, value); }); | 
					
						
							|  |  |  |         request->did_receive_headers({}, headers, status_code); | 
					
						
							| 
									
										
										
										
											2021-04-23 22:45:52 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-02 19:54:34 +02:00
										 |  |  | void RequestClient::certificate_requested(i32 request_id) | 
					
						
							| 
									
										
										
										
											2021-04-23 22:45:52 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-05-02 19:54:34 +02:00
										 |  |  |     if (auto request = const_cast<Request*>(m_requests.get(request_id).value_or(nullptr))) { | 
					
						
							| 
									
										
										
										
											2021-04-23 22:45:52 +02:00
										 |  |  |         request->did_request_certificates({}); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-05 11:59:04 +02:00
										 |  |  | template RefPtr<Protocol::Request> Protocol::RequestClient::start_request(String const& method, URL const&, HashMap<String, String> const& request_headers, ReadonlyBytes request_body); | 
					
						
							|  |  |  | template RefPtr<Protocol::Request> Protocol::RequestClient::start_request(String const& method, URL const&, HashMap<String, String, CaseInsensitiveStringTraits> const& request_headers, ReadonlyBytes request_body); |