ClientConnection.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/Badge.h>
  7. #include <RequestServer/ClientConnection.h>
  8. #include <RequestServer/Protocol.h>
  9. #include <RequestServer/Request.h>
  10. #include <RequestServer/RequestClientEndpoint.h>
  11. namespace RequestServer {
  12. static HashMap<int, RefPtr<ClientConnection>> s_connections;
  13. ClientConnection::ClientConnection(NonnullRefPtr<Core::LocalSocket> socket, int client_id)
  14. : IPC::ClientConnection<RequestClientEndpoint, RequestServerEndpoint>(*this, move(socket), client_id)
  15. {
  16. s_connections.set(client_id, *this);
  17. }
  18. ClientConnection::~ClientConnection()
  19. {
  20. }
  21. void ClientConnection::die()
  22. {
  23. s_connections.remove(client_id());
  24. if (s_connections.is_empty())
  25. Core::EventLoop::current().quit(0);
  26. }
  27. Messages::RequestServer::IsSupportedProtocolResponse ClientConnection::handle(const Messages::RequestServer::IsSupportedProtocol& message)
  28. {
  29. bool supported = Protocol::find_by_name(message.protocol().to_lowercase());
  30. return supported;
  31. }
  32. Messages::RequestServer::StartRequestResponse ClientConnection::handle(const Messages::RequestServer::StartRequest& message)
  33. {
  34. const auto& url = message.url();
  35. if (!url.is_valid()) {
  36. dbgln("StartRequest: Invalid URL requested: '{}'", url);
  37. return { -1, Optional<IPC::File> {} };
  38. }
  39. auto* protocol = Protocol::find_by_name(url.protocol());
  40. if (!protocol) {
  41. dbgln("StartRequest: No protocol handler for URL: '{}'", url);
  42. return { -1, Optional<IPC::File> {} };
  43. }
  44. auto request = protocol->start_request(*this, message.method(), url, message.request_headers().entries(), message.request_body());
  45. if (!request) {
  46. dbgln("StartRequest: Protocol handler failed to start request: '{}'", url);
  47. return { -1, Optional<IPC::File> {} };
  48. }
  49. auto id = request->id();
  50. auto fd = request->request_fd();
  51. m_requests.set(id, move(request));
  52. return { id, IPC::File(fd, IPC::File::CloseAfterSending) };
  53. }
  54. Messages::RequestServer::StopRequestResponse ClientConnection::handle(const Messages::RequestServer::StopRequest& message)
  55. {
  56. auto* request = const_cast<Request*>(m_requests.get(message.request_id()).value_or(nullptr));
  57. bool success = false;
  58. if (request) {
  59. request->stop();
  60. m_requests.remove(message.request_id());
  61. success = true;
  62. }
  63. return success;
  64. }
  65. void ClientConnection::did_receive_headers(Badge<Request>, Request& request)
  66. {
  67. IPC::Dictionary response_headers;
  68. for (auto& it : request.response_headers())
  69. response_headers.add(it.key, it.value);
  70. post_message(Messages::RequestClient::HeadersBecameAvailable(request.id(), move(response_headers), request.status_code()));
  71. }
  72. void ClientConnection::did_finish_request(Badge<Request>, Request& request, bool success)
  73. {
  74. VERIFY(request.total_size().has_value());
  75. post_message(Messages::RequestClient::RequestFinished(request.id(), success, request.total_size().value()));
  76. m_requests.remove(request.id());
  77. }
  78. void ClientConnection::did_progress_request(Badge<Request>, Request& request)
  79. {
  80. post_message(Messages::RequestClient::RequestProgress(request.id(), request.total_size(), request.downloaded_size()));
  81. }
  82. void ClientConnection::did_request_certificates(Badge<Request>, Request& request)
  83. {
  84. post_message(Messages::RequestClient::CertificateRequested(request.id()));
  85. }
  86. void ClientConnection::handle(const Messages::RequestServer::Greet&)
  87. {
  88. }
  89. Messages::RequestServer::SetCertificateResponse ClientConnection::handle(const Messages::RequestServer::SetCertificate& message)
  90. {
  91. auto* request = const_cast<Request*>(m_requests.get(message.request_id()).value_or(nullptr));
  92. bool success = false;
  93. if (request) {
  94. request->set_certificate(message.certificate(), message.key());
  95. success = true;
  96. }
  97. return success;
  98. }
  99. }