url_pipe_loader.cc 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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::Value::Dict 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::Value::Dict 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 = upload_data.FindString("contentType");
  39. std::string* data = upload_data.FindString("data");
  40. if (content_type && 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(), std::move(consumer));
  60. }
  61. void URLPipeLoader::OnWrite(base::OnceClosure resume, MojoResult result) {
  62. if (result == MOJO_RESULT_OK)
  63. std::move(resume).Run();
  64. else
  65. NotifyComplete(net::ERR_FAILED);
  66. }
  67. void URLPipeLoader::OnDataReceived(base::StringPiece string_piece,
  68. base::OnceClosure resume) {
  69. producer_->Write(
  70. std::make_unique<mojo::StringDataSource>(
  71. string_piece, mojo::StringDataSource::AsyncWritingMode::
  72. STRING_MAY_BE_INVALIDATED_BEFORE_COMPLETION),
  73. base::BindOnce(&URLPipeLoader::OnWrite, weak_factory_.GetWeakPtr(),
  74. std::move(resume)));
  75. }
  76. void URLPipeLoader::OnRetry(base::OnceClosure start_retry) {
  77. NOTREACHED();
  78. }
  79. void URLPipeLoader::OnComplete(bool success) {
  80. NotifyComplete(loader_->NetError());
  81. }
  82. } // namespace electron