gzip_source_stream.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. // Copyright 2016 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. #ifndef NET_FILTER_GZIP_SOURCE_STREAM_H_
  5. #define NET_FILTER_GZIP_SOURCE_STREAM_H_
  6. #include <memory>
  7. #include <string>
  8. #include "net/base/net_export.h"
  9. #include "net/filter/filter_source_stream.h"
  10. #include "net/filter/gzip_header.h"
  11. typedef struct z_stream_s z_stream;
  12. namespace net {
  13. class IOBuffer;
  14. // GZipSourceStream applies gzip and deflate content encoding/decoding to a data
  15. // stream. As specified by HTTP 1.1, with gzip encoding the content is
  16. // wrapped with a gzip header, and with deflate encoding the content is in
  17. // a raw, headerless DEFLATE stream.
  18. //
  19. // Internally GZipSourceStream uses zlib inflate to do decoding.
  20. //
  21. class NET_EXPORT_PRIVATE GzipSourceStream : public FilterSourceStream {
  22. public:
  23. GzipSourceStream(const GzipSourceStream&) = delete;
  24. GzipSourceStream& operator=(const GzipSourceStream&) = delete;
  25. ~GzipSourceStream() override;
  26. // Creates a GzipSourceStream. Return nullptr if initialization fails.
  27. static std::unique_ptr<GzipSourceStream> Create(
  28. std::unique_ptr<SourceStream> previous,
  29. SourceStream::SourceType type);
  30. private:
  31. enum InputState {
  32. // Starts processing the input stream. Checks whether the stream is valid
  33. // and whether a fallback to plain data is needed.
  34. STATE_START,
  35. // Gzip header of the input stream is being processed.
  36. STATE_GZIP_HEADER,
  37. // Deflate responses may or may not have a zlib header. In this state until
  38. // enough has been inflated that this stream most likely has a zlib header,
  39. // or until a zlib header has been added. Data is appended to |replay_data_|
  40. // in case it needs to be replayed after adding a header.
  41. STATE_SNIFFING_DEFLATE_HEADER,
  42. // If a zlib header has to be added to the response, this state will replay
  43. // data passed to inflate before it was determined that no zlib header was
  44. // present.
  45. // See https://crbug.com/677001
  46. STATE_REPLAY_DATA,
  47. // The input stream is being decoded.
  48. STATE_COMPRESSED_BODY,
  49. // Gzip footer of the input stream is being processed.
  50. STATE_GZIP_FOOTER,
  51. // The end of the gzipped body has been reached. If any extra bytes are
  52. // received, just silently ignore them. Doing this, rather than failing the
  53. // request or passing the extra bytes alone with the rest of the response
  54. // body, matches the behavior of other browsers.
  55. STATE_IGNORING_EXTRA_BYTES,
  56. };
  57. GzipSourceStream(std::unique_ptr<SourceStream> previous,
  58. SourceStream::SourceType type);
  59. // Returns true if initialization is successful, false otherwise.
  60. // For instance, this method returns false if there is not enough memory or
  61. // if there is a version mismatch.
  62. bool Init();
  63. // SourceStream implementation
  64. std::string GetTypeAsString() const override;
  65. base::expected<size_t, Error> FilterData(IOBuffer* output_buffer,
  66. size_t output_buffer_size,
  67. IOBuffer* input_buffer,
  68. size_t input_buffer_size,
  69. size_t* consumed_bytes,
  70. bool upstream_end_reached) override;
  71. // Inserts a zlib header to the data stream before calling zlib inflate.
  72. // This is used to work around server bugs. The function returns true on
  73. // success.
  74. bool InsertZlibHeader();
  75. // The control block of zlib which actually does the decoding.
  76. // This data structure is initialized by Init and updated only by
  77. // FilterData(), with InsertZlibHeader() being the exception as a workaround.
  78. std::unique_ptr<z_stream> zlib_stream_;
  79. // While in STATE_SNIFFING_DEFLATE_HEADER, it may be determined that a zlib
  80. // header needs to be added, and all received data needs to be replayed. In
  81. // that case, this buffer holds the data to be replayed.
  82. std::string replay_data_;
  83. // Used to parse the gzip header in gzip stream.
  84. // It is used when the decoding mode is GZIP_SOURCE_STREAM_GZIP.
  85. GZipHeader gzip_header_;
  86. // Tracks how many bytes of gzip footer are yet to be filtered.
  87. size_t gzip_footer_bytes_left_ = 0;
  88. // Tracks the state of the input stream.
  89. InputState input_state_ = STATE_START;
  90. // Used when replaying data.
  91. InputState replay_state_ = STATE_COMPRESSED_BODY;
  92. };
  93. } // namespace net
  94. #endif // NET_FILTER_GZIP_SOURCE_STREAM_H__