Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set sw=2 ts=8 et tw=80 : */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #if !defined (__nsHTTPCompressConv__h__)
8 : #define __nsHTTPCompressConv__h__ 1
9 :
10 : #include "nsIStreamConverter.h"
11 : #include "nsICompressConvStats.h"
12 : #include "nsIThreadRetargetableStreamListener.h"
13 : #include "nsCOMPtr.h"
14 : #include "nsAutoPtr.h"
15 : #include "mozilla/Atomics.h"
16 : #include "mozilla/Mutex.h"
17 :
18 : #include "zlib.h"
19 :
20 : // brotli includes
21 : #undef assert
22 : #include "assert.h"
23 : #include "state.h"
24 :
25 : class nsIStringInputStream;
26 :
27 : #define NS_HTTPCOMPRESSCONVERTER_CID \
28 : { \
29 : /* 66230b2b-17fa-4bd3-abf4-07986151022d */ \
30 : 0x66230b2b, \
31 : 0x17fa, \
32 : 0x4bd3, \
33 : {0xab, 0xf4, 0x07, 0x98, 0x61, 0x51, 0x02, 0x2d} \
34 : }
35 :
36 :
37 : #define HTTP_DEFLATE_TYPE "deflate"
38 : #define HTTP_GZIP_TYPE "gzip"
39 : #define HTTP_X_GZIP_TYPE "x-gzip"
40 : #define HTTP_COMPRESS_TYPE "compress"
41 : #define HTTP_X_COMPRESS_TYPE "x-compress"
42 : #define HTTP_BROTLI_TYPE "br"
43 : #define HTTP_IDENTITY_TYPE "identity"
44 : #define HTTP_UNCOMPRESSED_TYPE "uncompressed"
45 :
46 : namespace mozilla {
47 : namespace net {
48 :
49 : typedef enum {
50 : HTTP_COMPRESS_GZIP,
51 : HTTP_COMPRESS_DEFLATE,
52 : HTTP_COMPRESS_COMPRESS,
53 : HTTP_COMPRESS_BROTLI,
54 : HTTP_COMPRESS_IDENTITY
55 : } CompressMode;
56 :
57 : class BrotliWrapper
58 : {
59 : public:
60 0 : BrotliWrapper()
61 0 : : mTotalOut(0)
62 : , mStatus(NS_OK)
63 0 : , mBrotliStateIsStreamEnd(false)
64 : {
65 0 : BrotliStateInit(&mState);
66 0 : }
67 0 : ~BrotliWrapper()
68 0 : {
69 0 : BrotliStateCleanup(&mState);
70 0 : }
71 :
72 : BrotliState mState;
73 : Atomic<size_t, Relaxed> mTotalOut;
74 : nsresult mStatus;
75 : Atomic<bool, Relaxed> mBrotliStateIsStreamEnd;
76 :
77 : nsIRequest *mRequest;
78 : nsISupports *mContext;
79 : uint64_t mSourceOffset;
80 : };
81 :
82 : class nsHTTPCompressConv
83 : : public nsIStreamConverter
84 : , public nsICompressConvStats
85 : , public nsIThreadRetargetableStreamListener
86 : {
87 : public:
88 : // nsISupports methods
89 : NS_DECL_THREADSAFE_ISUPPORTS
90 : NS_DECL_NSIREQUESTOBSERVER
91 : NS_DECL_NSISTREAMLISTENER
92 : NS_DECL_NSICOMPRESSCONVSTATS
93 : NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
94 :
95 : // nsIStreamConverter methods
96 : NS_DECL_NSISTREAMCONVERTER
97 :
98 : nsHTTPCompressConv ();
99 :
100 : private:
101 : virtual ~nsHTTPCompressConv ();
102 :
103 : nsCOMPtr<nsIStreamListener> mListener; // this guy gets the converted data via his OnDataAvailable ()
104 : Atomic<CompressMode, Relaxed> mMode;
105 :
106 : unsigned char *mOutBuffer;
107 : unsigned char *mInpBuffer;
108 :
109 : uint32_t mOutBufferLen;
110 : uint32_t mInpBufferLen;
111 :
112 : nsAutoPtr<BrotliWrapper> mBrotli;
113 :
114 : nsCOMPtr<nsIStringInputStream> mStream;
115 :
116 : static nsresult
117 : BrotliHandler(nsIInputStream *stream, void *closure, const char *dataIn,
118 : uint32_t, uint32_t avail, uint32_t *countRead);
119 :
120 : nsresult do_OnDataAvailable (nsIRequest *request, nsISupports *aContext,
121 : uint64_t aSourceOffset, const char *buffer,
122 : uint32_t aCount);
123 :
124 : bool mCheckHeaderDone;
125 : Atomic<bool> mStreamEnded;
126 : bool mStreamInitialized;
127 : bool mDummyStreamInitialised;
128 : bool mFailUncleanStops;
129 :
130 : z_stream d_stream;
131 : unsigned mLen, hMode, mSkipCount, mFlags;
132 :
133 : uint32_t check_header (nsIInputStream *iStr, uint32_t streamLen, nsresult *rv);
134 :
135 : Atomic<uint32_t, Relaxed> mDecodedDataLength;
136 :
137 : mutable mozilla::Mutex mMutex;
138 : };
139 :
140 : } // namespace net
141 : } // namespace mozilla
142 :
143 : #endif
|