Ton

Форк
0
/
http-inbound-connection.cpp 
114 строк · 3.5 Кб
1
/*
2
    This file is part of TON Blockchain Library.
3

4
    TON Blockchain Library is free software: you can redistribute it and/or modify
5
    it under the terms of the GNU Lesser General Public License as published by
6
    the Free Software Foundation, either version 2 of the License, or
7
    (at your option) any later version.
8

9
    TON Blockchain Library is distributed in the hope that it will be useful,
10
    but WITHOUT ANY WARRANTY; without even the implied warranty of
11
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
    GNU Lesser General Public License for more details.
13

14
    You should have received a copy of the GNU Lesser General Public License
15
    along with TON Blockchain Library.  If not, see <http://www.gnu.org/licenses/>.
16

17
    Copyright 2019-2020 Telegram Systems LLP
18
*/
19
#include "http-inbound-connection.h"
20
#include "td/utils/misc.h"
21

22
namespace ton {
23

24
namespace http {
25

26
void HttpInboundConnection::send_client_error() {
27
  static const auto s =
28
      "HTTP/1.0 400 Bad Request\r\n"
29
      "Connection: Close\r\n"
30
      "Content-length: 0\r\n"
31
      "\r\n";
32
  buffered_fd_.output_buffer().append(td::Slice(s, strlen(s)));
33
  close_after_write_ = true;
34
  loop();
35
}
36

37
void HttpInboundConnection::send_server_error() {
38
  static const auto s =
39
      "HTTP/1.1 502 Bad Gateway\r\n"
40
      "Connection: keep-alive\r\n"
41
      "Content-length: 0\r\n"
42
      "\r\n";
43
  buffered_fd_.output_buffer().append(td::Slice(s, strlen(s)));
44
  loop();
45
}
46

47
void HttpInboundConnection::send_proxy_error(td::Status error) {
48
  if (error.code() == ErrorCode::timeout) {
49
    static const auto s =
50
        "HTTP/1.1 504 Gateway Timeout\r\n"
51
        "Connection: keep-alive\r\n"
52
        "Content-length: 0\r\n"
53
        "\r\n";
54
    buffered_fd_.output_buffer().append(td::Slice(s, strlen(s)));
55
  } else {
56
    static const auto s =
57
        "HTTP/1.1 502 Bad Gateway\r\n"
58
        "Connection: keep-alive\r\n"
59
        "Content-length: 0\r\n"
60
        "\r\n";
61
    buffered_fd_.output_buffer().append(td::Slice(s, strlen(s)));
62
  }
63
  loop();
64
}
65

66
td::Status HttpInboundConnection::receive(td::ChainBufferReader &input) {
67
  if (reading_payload_) {
68
    return receive_payload(input);
69
  }
70

71
  if (!cur_request_ && !read_next_request_) {
72
    return td::Status::OK();
73
  }
74

75
  while (!cur_request_ || !cur_request_->check_parse_header_completed()) {
76
    bool exit_loop;
77
    auto R = HttpRequest::parse(std::move(cur_request_), cur_line_, exit_loop, input);
78
    if (R.is_error()) {
79
      send_client_error();
80
      return td::Status::OK();
81
    }
82
    cur_request_ = R.move_as_ok();
83
    if (exit_loop) {
84
      return td::Status::OK();
85
    }
86
  }
87

88
  auto payload = cur_request_->create_empty_payload().move_as_ok();
89
  auto P = td::PromiseCreator::lambda(
90
      [SelfId = actor_id(this)](td::Result<std::pair<std::unique_ptr<HttpResponse>, std::shared_ptr<HttpPayload>>> R) {
91
        if (R.is_ok()) {
92
          auto a = R.move_as_ok();
93
          td::actor::send_closure(SelfId, &HttpInboundConnection::send_answer, std::move(a.first), std::move(a.second));
94
        } else {
95
          td::actor::send_closure(SelfId, &HttpInboundConnection::send_proxy_error, R.move_as_error());
96
        }
97
      });
98
  http_callback_->receive_request(std::move(cur_request_), payload, std::move(P));
99
  read_payload(std::move(payload));
100

101
  return td::Status::OK();
102
}
103

104
void HttpInboundConnection::send_answer(std::unique_ptr<HttpResponse> response, std::shared_ptr<HttpPayload> payload) {
105
  CHECK(payload);
106
  response->store_http(buffered_fd_.output_buffer());
107

108
  write_payload(std::move(payload));
109
  loop();
110
}
111

112
}  // namespace http
113

114
}  // namespace ton
115

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.