File: controllable_http_response.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (155 lines) | stat: -rw-r--r-- 6,031 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef NET_TEST_EMBEDDED_TEST_SERVER_CONTROLLABLE_HTTP_RESPONSE_H_
#define NET_TEST_EMBEDDED_TEST_SERVER_CONTROLLABLE_HTTP_RESPONSE_H_

#include <memory>
#include <string>
#include <vector>

#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "base/sequence_checker.h"
#include "base/task/single_thread_task_runner.h"
#include "net/http/http_status_code.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"

namespace net::test_server {

// A response that can be manually controlled on the current test thread. It is
// used for waiting for a connection, sending data and closing it. It will
// handle only **one** request with the matching |relative_url|. In the case of
// multiple ControllableHttpResponses for the same path, they're used in the
// order they were created.
//
// If |relative_url_is_prefix| is true, |relative_url| is only compared against
// the start of the URL being requested, which allows matching against (possibly
// variable) query strings, for instance.
class ControllableHttpResponse {
 public:
  ControllableHttpResponse(EmbeddedTestServer* embedded_test_server,
                           const std::string& relative_url,
                           bool relative_url_is_prefix = false);

  ControllableHttpResponse(const ControllableHttpResponse&) = delete;
  ControllableHttpResponse& operator=(const ControllableHttpResponse&) = delete;

  ~ControllableHttpResponse();

  // These method are intented to be used in order.
  // 1) Wait for the response to be requested.
  void WaitForRequest();

  // 2) Send raw response data in response to a request.
  //    May be called several time.
  void Send(const std::string& bytes);

  // Same as 2) but with more specific parameters.
  void Send(net::HttpStatusCode http_status,
            const std::string& content_type = std::string("text/html"),
            const std::string& content = std::string(),
            const std::vector<std::string>& cookies = {},
            const std::vector<std::string>& extra_headers = {});

  // 3) Notify there are no more data to be sent and close the socket.
  void Done();

  // Returns the HttpRequest after a call to WaitForRequest.
  const HttpRequest* http_request() const { return http_request_.get(); }

  // Returns whether or not the request has been received yet.
  bool has_received_request();

 private:
  friend class ControllableHttpResponseManager;

  enum class State { WAITING_FOR_REQUEST, READY_TO_SEND_DATA, DONE };

  ControllableHttpResponse(scoped_refptr<base::SingleThreadTaskRunner>
                               embedded_test_server_task_runner,
                           base::WeakPtr<HttpResponseDelegate> delegate,
                           std::unique_ptr<HttpRequest> http_request);

  void OnRequest(std::unique_ptr<HttpRequest> http_request,
                 scoped_refptr<base::SingleThreadTaskRunner>
                     embedded_test_server_task_runner,
                 base::WeakPtr<HttpResponseDelegate> delegate);

  static std::unique_ptr<HttpResponse> RequestHandler(
      base::WeakPtr<ControllableHttpResponse> controller,
      scoped_refptr<base::SingleThreadTaskRunner> controller_task_runner,
      bool* available,
      const std::string& relative_url,
      bool relative_url_is_prefix,
      const HttpRequest& request);

  State state_ = State::WAITING_FOR_REQUEST;
  base::RunLoop loop_;
  scoped_refptr<base::SingleThreadTaskRunner> embedded_test_server_task_runner_;
  base::WeakPtr<HttpResponseDelegate> delegate_;
  std::unique_ptr<HttpRequest> http_request_;

  SEQUENCE_CHECKER(sequence_checker_);

  base::WeakPtrFactory<ControllableHttpResponse> weak_ptr_factory_{this};
};

// Utility class enabling multiple ControllableHttpResponse call on same path.
// Usage:
// void SetUpOnMainThread() override {
//   slow_response_manager_ =
//   std::make_unique<net::test_server::ControllableHttpResponseManager>(
//    embedded_test_server(), "/image_slow.png");
//   ASSERT_TRUE(embedded_test_server()->Start());
// }
// IN_PROC_BROWSER_TEST_F(Foo, Bar) {
//   for(int i=0;i < 2; i++) {
//     auto slow_response = slow_response_manager_->WaitForRequest();
//     slow_response->Send(net::HTTP_OK, "image/png", "image_body");
//     slow_response->Done();
//   }
// }
class ControllableHttpResponseManager {
 public:
  ControllableHttpResponseManager(EmbeddedTestServer* embedded_test_server,
                                  const std::string& relative_url,
                                  bool relative_url_is_prefix = false);

  ControllableHttpResponseManager(const ControllableHttpResponseManager&) =
      delete;
  ControllableHttpResponseManager& operator=(
      const ControllableHttpResponseManager&) = delete;

  ~ControllableHttpResponseManager();

  std::unique_ptr<ControllableHttpResponse> WaitForRequest();

 private:
  static std::unique_ptr<HttpResponse> RequestHandler(
      base::WeakPtr<ControllableHttpResponseManager> controller,
      scoped_refptr<base::SingleThreadTaskRunner> controller_task_runner,
      const std::string& relative_url,
      bool relative_url_is_prefix,
      const HttpRequest& request);

  void OnRequest(std::unique_ptr<HttpRequest> http_request,
                 scoped_refptr<base::SingleThreadTaskRunner>
                     embedded_test_server_task_runner,
                 base::WeakPtr<HttpResponseDelegate> delegate);

  std::unique_ptr<ControllableHttpResponse> current_response_;
  std::unique_ptr<base::RunLoop> loop_;

  SEQUENCE_CHECKER(sequence_checker_);

  base::WeakPtrFactory<ControllableHttpResponseManager> weak_ptr_factory_{this};
};

}  // namespace net::test_server

#endif  //  NET_TEST_EMBEDDED_TEST_SERVER_CONTROLLABLE_HTTP_RESPONSE_H_