1c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko// Copyright 2015 The Android Open Source Project
2c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko//
3c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko// Licensed under the Apache License, Version 2.0 (the "License");
4c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko// you may not use this file except in compliance with the License.
5c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko// You may obtain a copy of the License at
6c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko//
7c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko//      http://www.apache.org/licenses/LICENSE-2.0
8c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko//
9c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko// Unless required by applicable law or agreed to in writing, software
10c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko// distributed under the License is distributed on an "AS IS" BASIS,
11c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko// See the License for the specific language governing permissions and
13c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko// limitations under the License.
14c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko
15c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko#include <libwebserv/request_utils.h>
16c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko
17c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko#include <base/bind.h>
1875d6da24dedcbc090d23de60c4f1637c3a54b392Alex Vakulenko#include <brillo/streams/memory_stream.h>
1975d6da24dedcbc090d23de60c4f1637c3a54b392Alex Vakulenko#include <brillo/streams/stream_utils.h>
20c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko#include <libwebserv/request.h>
21c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko#include <libwebserv/response.h>
22c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko
23c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenkonamespace libwebserv {
24c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko
25c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenkonamespace {
26c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko
27c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenkostruct RequestDataContainer {
28c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko  std::unique_ptr<Request> request;
29c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko  std::unique_ptr<Response> response;
30c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko  GetRequestDataSuccessCallback success_callback;
31c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko  GetRequestDataErrorCallback error_callback;
32c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko  std::vector<uint8_t> data;
33c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko};
34c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko
35c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenkovoid OnCopySuccess(std::shared_ptr<RequestDataContainer> container,
36016df0ac2e778e9ea9642415007fbbfe23cb152dChristopher Wiley                   brillo::StreamPtr /* in_stream */,
37016df0ac2e778e9ea9642415007fbbfe23cb152dChristopher Wiley                   brillo::StreamPtr out_stream,
38016df0ac2e778e9ea9642415007fbbfe23cb152dChristopher Wiley                   uint64_t /* size_copied */) {
39c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko  // Close/release the memory stream so we can work with underlying data buffer.
40c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko  out_stream->CloseBlocking(nullptr);
41c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko  out_stream.reset();
42c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko  container->success_callback.Run(std::move(container->request),
43c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko                                  std::move(container->response),
44c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko                                  std::move(container->data));
45c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko}
46c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko
47c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenkovoid OnCopyError(std::shared_ptr<RequestDataContainer> container,
48016df0ac2e778e9ea9642415007fbbfe23cb152dChristopher Wiley                 brillo::StreamPtr /* in_stream */,
49016df0ac2e778e9ea9642415007fbbfe23cb152dChristopher Wiley                 brillo::StreamPtr /* out_stream */,
5075d6da24dedcbc090d23de60c4f1637c3a54b392Alex Vakulenko                 const brillo::Error* error) {
51c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko  container->error_callback.Run(std::move(container->request),
52c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko                                std::move(container->response), error);
53c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko}
54c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko
55c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko}  // anonymous namespace
56c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko
57c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenkovoid GetRequestData(std::unique_ptr<Request> request,
58c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko                    std::unique_ptr<Response> response,
59c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko                    const GetRequestDataSuccessCallback& success_callback,
60c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko                    const GetRequestDataErrorCallback& error_callback) {
61c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko  auto container = std::make_shared<RequestDataContainer>();
62c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko  auto in_stream = request->GetDataStream();
63c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko  auto out_stream =
6475d6da24dedcbc090d23de60c4f1637c3a54b392Alex Vakulenko      brillo::MemoryStream::CreateRef(&container->data, nullptr);
65c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko  container->request = std::move(request);
66c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko  container->response = std::move(response);
67c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko  container->success_callback = success_callback;
68c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko  container->error_callback = error_callback;
6975d6da24dedcbc090d23de60c4f1637c3a54b392Alex Vakulenko  brillo::stream_utils::CopyData(std::move(in_stream), std::move(out_stream),
7075d6da24dedcbc090d23de60c4f1637c3a54b392Alex Vakulenko                                 base::Bind(&OnCopySuccess, container),
7175d6da24dedcbc090d23de60c4f1637c3a54b392Alex Vakulenko                                 base::Bind(&OnCopyError, container));
72c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko}
73c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko
74c70c04e8d1b3a3f0d27b0cf5710cb9d34b1e77b4Alex Vakulenko}  // namespace libwebserv
75