http_server_fuzzer.cc 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <fuzzer/FuzzedDataProvider.h>
  5. #include "base/check_op.h"
  6. #include "base/run_loop.h"
  7. #include "net/base/net_errors.h"
  8. #include "net/log/net_log.h"
  9. #include "net/log/test_net_log.h"
  10. #include "net/server/http_server.h"
  11. #include "net/socket/fuzzed_server_socket.h"
  12. #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
  13. namespace {
  14. class WaitTillHttpCloseDelegate : public net::HttpServer::Delegate {
  15. public:
  16. WaitTillHttpCloseDelegate(FuzzedDataProvider* data_provider,
  17. base::OnceClosure done_closure)
  18. : data_provider_(data_provider),
  19. done_closure_(std::move(done_closure)),
  20. action_flags_(data_provider_->ConsumeIntegral<uint8_t>()) {}
  21. WaitTillHttpCloseDelegate(const WaitTillHttpCloseDelegate&) = delete;
  22. WaitTillHttpCloseDelegate& operator=(const WaitTillHttpCloseDelegate&) =
  23. delete;
  24. void set_server(net::HttpServer* server) { server_ = server; }
  25. void OnConnect(int connection_id) override {
  26. if (!(action_flags_ & ACCEPT_CONNECTION))
  27. server_->Close(connection_id);
  28. }
  29. void OnHttpRequest(int connection_id,
  30. const net::HttpServerRequestInfo& info) override {
  31. if (!(action_flags_ & ACCEPT_MESSAGE)) {
  32. server_->Close(connection_id);
  33. return;
  34. }
  35. if (action_flags_ & REPLY_TO_MESSAGE) {
  36. server_->Send200(connection_id,
  37. data_provider_->ConsumeRandomLengthString(64),
  38. "text/html", TRAFFIC_ANNOTATION_FOR_TESTS);
  39. }
  40. }
  41. void OnWebSocketRequest(int connection_id,
  42. const net::HttpServerRequestInfo& info) override {
  43. if (action_flags_ & CLOSE_WEBSOCKET_RATHER_THAN_ACCEPT) {
  44. server_->Close(connection_id);
  45. return;
  46. }
  47. if (action_flags_ & ACCEPT_WEBSOCKET)
  48. server_->AcceptWebSocket(connection_id, info,
  49. TRAFFIC_ANNOTATION_FOR_TESTS);
  50. }
  51. void OnWebSocketMessage(int connection_id, std::string data) override {
  52. if (!(action_flags_ & ACCEPT_MESSAGE)) {
  53. server_->Close(connection_id);
  54. return;
  55. }
  56. if (action_flags_ & REPLY_TO_MESSAGE) {
  57. server_->SendOverWebSocket(connection_id,
  58. data_provider_->ConsumeRandomLengthString(64),
  59. TRAFFIC_ANNOTATION_FOR_TESTS);
  60. }
  61. }
  62. void OnClose(int connection_id) override {
  63. // In general, OnClose can be called more than once, but FuzzedServerSocket
  64. // only makes one connection, and it is the only socket of interest here.
  65. std::move(done_closure_).Run();
  66. }
  67. private:
  68. enum {
  69. ACCEPT_CONNECTION = 1,
  70. ACCEPT_MESSAGE = 2,
  71. REPLY_TO_MESSAGE = 4,
  72. ACCEPT_WEBSOCKET = 8,
  73. CLOSE_WEBSOCKET_RATHER_THAN_ACCEPT = 16
  74. };
  75. net::HttpServer* server_ = nullptr;
  76. FuzzedDataProvider* const data_provider_;
  77. base::OnceClosure done_closure_;
  78. const uint8_t action_flags_;
  79. };
  80. } // namespace
  81. // Fuzzer for HttpServer
  82. //
  83. // |data| is used to create a FuzzedServerSocket.
  84. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  85. // Including an observer; even though the recorded results aren't currently
  86. // used, it'll ensure the netlogging code is fuzzed as well.
  87. net::RecordingNetLogObserver net_log_observer;
  88. FuzzedDataProvider data_provider(data, size);
  89. std::unique_ptr<net::ServerSocket> server_socket(
  90. std::make_unique<net::FuzzedServerSocket>(&data_provider,
  91. net::NetLog::Get()));
  92. CHECK_EQ(net::OK,
  93. server_socket->ListenWithAddressAndPort("127.0.0.1", 80, 5));
  94. base::RunLoop run_loop;
  95. WaitTillHttpCloseDelegate delegate(&data_provider, run_loop.QuitClosure());
  96. net::HttpServer server(std::move(server_socket), &delegate);
  97. delegate.set_server(&server);
  98. run_loop.Run();
  99. return 0;
  100. }