diff options
Diffstat (limited to 'libs/tdlib/td/tdnet/td/net/HttpReader.h')
-rw-r--r-- | libs/tdlib/td/tdnet/td/net/HttpReader.h | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/libs/tdlib/td/tdnet/td/net/HttpReader.h b/libs/tdlib/td/tdnet/td/net/HttpReader.h new file mode 100644 index 0000000000..74067d1291 --- /dev/null +++ b/libs/tdlib/td/tdnet/td/net/HttpReader.h @@ -0,0 +1,108 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/net/HttpChunkedByteFlow.h" +#include "td/net/HttpContentLengthByteFlow.h" +#include "td/net/HttpQuery.h" + +#include "td/utils/buffer.h" +#include "td/utils/ByteFlow.h" +#include "td/utils/common.h" +#include "td/utils/GzipByteFlow.h" +#include "td/utils/port/FileFd.h" +#include "td/utils/Slice.h" +#include "td/utils/Status.h" +#include "td/utils/StringBuilder.h" + +#include <limits> + +namespace td { + +class HttpReader { + public: + void init(ChainBufferReader *input, size_t max_post_size = std::numeric_limits<size_t>::max(), + size_t max_files = 100); + Result<size_t> read_next(HttpQuery *query) TD_WARN_UNUSED_RESULT; // TODO move query to init + + HttpReader() = default; + HttpReader(const HttpReader &other) = delete; + HttpReader &operator=(const HttpReader &other) = delete; + HttpReader(HttpReader &&other) = delete; + HttpReader &operator=(HttpReader &&other) = delete; + ~HttpReader() { + if (!temp_file_.empty()) { + temp_file_.close(); + } + } + + static void delete_temp_file(CSlice file_name); + + private: + size_t max_post_size_; + size_t max_files_; + + enum { ReadHeaders, ReadContent, ReadContentToFile, ReadArgs, ReadMultipartFormData } state_; + size_t headers_read_length_; + size_t content_length_; + ChainBufferReader *input_; + ByteFlowSource flow_source_; + HttpChunkedByteFlow chunked_flow_; + GzipByteFlow gzip_flow_; + HttpContentLengthByteFlow content_length_flow_; + ByteFlowSink flow_sink_; + ChainBufferReader *content_; + + HttpQuery *query_; + Slice transfer_encoding_; + Slice content_encoding_; + Slice content_type_; + string content_type_lowercased_; + size_t total_parameters_length_; + size_t total_headers_length_; + + string boundary_; + size_t form_data_read_length_; + size_t form_data_skipped_length_; + enum { + SkipPrologue, + ReadPartHeaders, + ReadPartValue, + ReadFile, + CheckForLastBoundary, + SkipEpilogue + } form_data_parse_state_; + MutableSlice field_name_; + string file_field_name_; + string field_content_type_; + string file_name_; + FileFd temp_file_; + string temp_file_name_; + int64 file_size_; + + Result<size_t> split_header() TD_WARN_UNUSED_RESULT; + void process_header(MutableSlice header_name, MutableSlice header_value); + Result<bool> parse_multipart_form_data() TD_WARN_UNUSED_RESULT; + Status parse_url(MutableSlice url) TD_WARN_UNUSED_RESULT; + Status parse_parameters(MutableSlice parameters) TD_WARN_UNUSED_RESULT; + Status parse_json_parameters(MutableSlice parameters) TD_WARN_UNUSED_RESULT; + Status parse_head(MutableSlice head) TD_WARN_UNUSED_RESULT; + + Status open_temp_file(CSlice desired_file_name) TD_WARN_UNUSED_RESULT; + Status try_open_temp_file(Slice directory_name, CSlice desired_file_name) TD_WARN_UNUSED_RESULT; + Status save_file_part(BufferSlice &&file_part) TD_WARN_UNUSED_RESULT; + void close_temp_file(); + + static constexpr size_t MAX_CONTENT_SIZE = 150 << 20; // Some reasonable limit + static constexpr size_t MAX_TOTAL_PARAMETERS_LENGTH = 1 << 16; // Some reasonable limit + static constexpr size_t MAX_TOTAL_HEADERS_LENGTH = 1 << 18; // Some reasonable limit + static constexpr size_t MAX_BOUNDARY_LENGTH = 70; // As defined by RFC1341 + static constexpr int64 MAX_FILE_SIZE = 1500 << 20; // Telegram server file size limit + static constexpr const char TEMP_DIRECTORY_PREFIX[] = "tdlib-server-tmp"; +}; + +} // namespace td |