url_pipe_loader.cc 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // Copyright (c) 2019 GitHub, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #include "shell/browser/net/url_pipe_loader.h"
  5. #include <utility>
  6. #include "mojo/public/cpp/bindings/pending_remote.h"
  7. #include "mojo/public/cpp/system/string_data_source.h"
  8. #include "services/network/public/cpp/shared_url_loader_factory.h"
  9. #include "services/network/public/mojom/url_response_head.mojom.h"
  10. namespace electron {
  11. URLPipeLoader::URLPipeLoader(
  12. scoped_refptr<network::SharedURLLoaderFactory> factory,
  13. std::unique_ptr<network::ResourceRequest> request,
  14. mojo::PendingReceiver<network::mojom::URLLoader> loader,
  15. mojo::PendingRemote<network::mojom::URLLoaderClient> client,
  16. const net::NetworkTrafficAnnotationTag& annotation,
  17. base::DictionaryValue upload_data)
  18. : url_loader_(this, std::move(loader)), client_(std::move(client)) {
  19. url_loader_.set_disconnect_handler(base::BindOnce(
  20. &URLPipeLoader::NotifyComplete, base::Unretained(this), net::ERR_FAILED));
  21. // PostTask since it might destruct.
  22. base::SequencedTaskRunnerHandle::Get()->PostTask(
  23. FROM_HERE,
  24. base::BindOnce(&URLPipeLoader::Start, weak_factory_.GetWeakPtr(), factory,
  25. std::move(request), annotation, std::move(upload_data)));
  26. }
  27. URLPipeLoader::~URLPipeLoader() = default;
  28. void URLPipeLoader::Start(
  29. scoped_refptr<network::SharedURLLoaderFactory> factory,
  30. std::unique_ptr<network::ResourceRequest> request,
  31. const net::NetworkTrafficAnnotationTag& annotation,
  32. base::DictionaryValue upload_data) {
  33. loader_ = network::SimpleURLLoader::Create(std::move(request), annotation);
  34. loader_->SetOnResponseStartedCallback(base::BindOnce(
  35. &URLPipeLoader::OnResponseStarted, weak_factory_.GetWeakPtr()));
  36. // TODO(zcbenz): The old protocol API only supports string as upload data,
  37. // we should seek to support more types in future.
  38. std::string content_type, data;
  39. if (upload_data.GetString("contentType", &content_type) &&
  40. upload_data.GetString("data", &data))
  41. loader_->AttachStringForUpload(data, content_type);
  42. loader_->DownloadAsStream(factory.get(), this);
  43. }
  44. void URLPipeLoader::NotifyComplete(int result) {
  45. client_->OnComplete(network::URLLoaderCompletionStatus(result));
  46. delete this;
  47. }
  48. void URLPipeLoader::OnResponseStarted(
  49. const GURL& final_url,
  50. const network::mojom::URLResponseHead& response_head) {
  51. mojo::ScopedDataPipeProducerHandle producer;
  52. mojo::ScopedDataPipeConsumerHandle consumer;
  53. MojoResult rv = mojo::CreateDataPipe(nullptr, producer, consumer);
  54. if (rv != MOJO_RESULT_OK) {
  55. NotifyComplete(net::ERR_INSUFFICIENT_RESOURCES);
  56. return;
  57. }
  58. producer_ = std::make_unique<mojo::DataPipeProducer>(std::move(producer));
  59. client_->OnReceiveResponse(response_head.Clone());
  60. client_->OnStartLoadingResponseBody(std::move(consumer));
  61. }
  62. void URLPipeLoader::OnWrite(base::OnceClosure resume, MojoResult result) {
  63. if (result == MOJO_RESULT_OK)
  64. std::move(resume).Run();
  65. else
  66. NotifyComplete(net::ERR_FAILED);
  67. }
  68. void URLPipeLoader::OnDataReceived(base::StringPiece string_piece,
  69. base::OnceClosure resume) {
  70. producer_->Write(
  71. std::make_unique<mojo::StringDataSource>(
  72. string_piece, mojo::StringDataSource::AsyncWritingMode::
  73. STRING_MAY_BE_INVALIDATED_BEFORE_COMPLETION),
  74. base::BindOnce(&URLPipeLoader::OnWrite, weak_factory_.GetWeakPtr(),
  75. std::move(resume)));
  76. }
  77. void URLPipeLoader::OnRetry(base::OnceClosure start_retry) {
  78. NOTREACHED();
  79. }
  80. void URLPipeLoader::OnComplete(bool success) {
  81. NotifyComplete(loader_->NetError());
  82. }
  83. } // namespace electron