Bug 1795082 - Part 2/2: Drop post-processing from getURL() r=zombie
[gecko.git] / netwerk / protocol / http / nsHttpResponseHead.h
blob9caf92b3e12e06974fdfff5fe4236cbc1570514d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef nsHttpResponseHead_h__
7 #define nsHttpResponseHead_h__
9 #include "nsHttpHeaderArray.h"
10 #include "nsHttp.h"
11 #include "nsString.h"
12 #include "mozilla/RecursiveMutex.h"
14 #ifdef Status
15 /* Xlib headers insist on this for some reason... Nuke it because
16 it'll override our member name */
17 typedef Status __StatusTmp;
18 # undef Status
19 typedef __StatusTmp Status;
20 #endif
22 class nsIHttpHeaderVisitor;
24 // This needs to be forward declared here so we can include only this header
25 // without also including PHttpChannelParams.h
26 namespace IPC {
27 template <typename>
28 struct ParamTraits;
29 } // namespace IPC
31 namespace mozilla {
32 namespace net {
34 //-----------------------------------------------------------------------------
35 // nsHttpResponseHead represents the status line and headers from an HTTP
36 // response.
37 //-----------------------------------------------------------------------------
39 class nsHttpResponseHead {
40 public:
41 nsHttpResponseHead() = default;
43 nsHttpResponseHead(const nsHttpResponseHead& aOther);
44 nsHttpResponseHead& operator=(const nsHttpResponseHead& aOther);
46 void Enter() const MOZ_CAPABILITY_ACQUIRE(mRecursiveMutex) {
47 mRecursiveMutex.Lock();
49 void Exit() const MOZ_CAPABILITY_RELEASE(mRecursiveMutex) {
50 mRecursiveMutex.Unlock();
52 void AssertMutexOwned() const { mRecursiveMutex.AssertCurrentThreadIn(); }
54 HttpVersion Version();
55 uint16_t Status() const;
56 void StatusText(nsACString& aStatusText);
57 int64_t ContentLength();
58 void ContentType(nsACString& aContentType) const;
59 void ContentCharset(nsACString& aContentCharset);
60 bool Public();
61 bool Private();
62 bool NoStore();
63 bool NoCache();
64 bool Immutable();
65 /**
66 * Full length of the entity. For byte-range requests, this may be larger
67 * than ContentLength(), which will only represent the requested part of the
68 * entity.
70 int64_t TotalEntitySize();
72 [[nodiscard]] nsresult SetHeader(const nsACString& h, const nsACString& v,
73 bool m = false);
74 [[nodiscard]] nsresult SetHeader(const nsHttpAtom& h, const nsACString& v,
75 bool m = false);
76 [[nodiscard]] nsresult GetHeader(const nsHttpAtom& h, nsACString& v) const;
77 void ClearHeader(const nsHttpAtom& h);
78 void ClearHeaders();
79 bool HasHeaderValue(const nsHttpAtom& h, const char* v);
80 bool HasHeader(const nsHttpAtom& h) const;
82 void SetContentType(const nsACString& s);
83 void SetContentCharset(const nsACString& s);
84 void SetContentLength(int64_t);
86 // write out the response status line and headers as a single text block,
87 // optionally pruning out transient headers (ie. headers that only make
88 // sense the first time the response is handled).
89 // Both functions append to the string supplied string.
90 void Flatten(nsACString&, bool pruneTransients);
91 void FlattenNetworkOriginalHeaders(nsACString& buf);
93 // The next 2 functions parse flattened response head and original net
94 // headers. They are used when we are reading an entry from the cache.
96 // To keep proper order of the original headers we MUST call
97 // ParseCachedOriginalHeaders FIRST and then ParseCachedHead.
99 // block must be null terminated.
100 [[nodiscard]] nsresult ParseCachedHead(const char* block);
101 [[nodiscard]] nsresult ParseCachedOriginalHeaders(char* block);
103 // parse the status line.
104 nsresult ParseStatusLine(const nsACString& line);
106 // parse a header line.
107 [[nodiscard]] nsresult ParseHeaderLine(const nsACString& line);
109 // cache validation support methods
110 [[nodiscard]] nsresult ComputeFreshnessLifetime(uint32_t*);
111 [[nodiscard]] nsresult ComputeCurrentAge(uint32_t now, uint32_t requestTime,
112 uint32_t* result);
113 bool MustValidate();
114 bool MustValidateIfExpired();
116 // return true if the response contains a valid Cache-control:
117 // stale-while-revalidate and |now| is less than or equal |expiration +
118 // stale-while-revalidate|. Otherwise false.
119 bool StaleWhileRevalidate(uint32_t now, uint32_t expiration);
121 // returns true if the server appears to support byte range requests.
122 bool IsResumable();
124 // returns true if the Expires header has a value in the past relative to the
125 // value of the Date header.
126 bool ExpiresInPast();
128 // update headers...
129 void UpdateHeaders(nsHttpResponseHead* aOther);
131 // reset the response head to it's initial state
132 void Reset();
134 [[nodiscard]] nsresult GetLastModifiedValue(uint32_t* result);
136 bool operator==(const nsHttpResponseHead& aOther) const;
138 // Using this function it is possible to itereate through all headers
139 // automatically under one lock.
140 [[nodiscard]] nsresult VisitHeaders(nsIHttpHeaderVisitor* visitor,
141 nsHttpHeaderArray::VisitorFilter filter);
142 [[nodiscard]] nsresult GetOriginalHeader(const nsHttpAtom& aHeader,
143 nsIHttpHeaderVisitor* aVisitor);
145 bool HasContentType() const;
146 bool HasContentCharset();
147 bool GetContentTypeOptionsHeader(nsACString& aOutput);
149 private:
150 [[nodiscard]] nsresult SetHeader_locked(const nsHttpAtom& atom,
151 const nsACString& h,
152 const nsACString& v, bool m = false)
153 MOZ_REQUIRES(mRecursiveMutex);
154 void AssignDefaultStatusText() MOZ_REQUIRES(mRecursiveMutex);
155 void ParseVersion(const char*) MOZ_REQUIRES(mRecursiveMutex);
156 void ParseCacheControl(const char*) MOZ_REQUIRES(mRecursiveMutex);
157 void ParsePragma(const char*) MOZ_REQUIRES(mRecursiveMutex);
158 // Parses a content-length header-value as described in
159 // https://fetch.spec.whatwg.org/#content-length-header
160 nsresult ParseResponseContentLength(const nsACString& aHeaderStr)
161 MOZ_REQUIRES(mRecursiveMutex);
163 nsresult ParseStatusLine_locked(const nsACString& line)
164 MOZ_REQUIRES(mRecursiveMutex);
165 [[nodiscard]] nsresult ParseHeaderLine_locked(const nsACString& line,
166 bool originalFromNetHeaders)
167 MOZ_REQUIRES(mRecursiveMutex);
169 // these return failure if the header does not exist.
170 [[nodiscard]] nsresult ParseDateHeader(const nsHttpAtom& header,
171 uint32_t* result) const
172 MOZ_REQUIRES(mRecursiveMutex);
173 [[nodiscard]] nsresult GetAgeValue(uint32_t* result);
174 [[nodiscard]] nsresult GetMaxAgeValue(uint32_t* result);
175 [[nodiscard]] nsresult GetStaleWhileRevalidateValue(uint32_t* result);
176 [[nodiscard]] nsresult GetDateValue(uint32_t* result);
177 [[nodiscard]] nsresult GetExpiresValue(uint32_t* result);
179 bool ExpiresInPast_locked() const MOZ_REQUIRES(mRecursiveMutex);
180 [[nodiscard]] nsresult GetAgeValue_locked(uint32_t* result) const
181 MOZ_REQUIRES(mRecursiveMutex);
182 [[nodiscard]] nsresult GetExpiresValue_locked(uint32_t* result) const
183 MOZ_REQUIRES(mRecursiveMutex);
184 [[nodiscard]] nsresult GetMaxAgeValue_locked(uint32_t* result) const
185 MOZ_REQUIRES(mRecursiveMutex);
186 [[nodiscard]] nsresult GetStaleWhileRevalidateValue_locked(
187 uint32_t* result) const MOZ_REQUIRES(mRecursiveMutex);
189 [[nodiscard]] nsresult GetDateValue_locked(uint32_t* result) const
190 MOZ_REQUIRES(mRecursiveMutex) {
191 return ParseDateHeader(nsHttp::Date, result);
194 [[nodiscard]] nsresult GetLastModifiedValue_locked(uint32_t* result) const
195 MOZ_REQUIRES(mRecursiveMutex) {
196 return ParseDateHeader(nsHttp::Last_Modified, result);
199 bool NoCache_locked() const MOZ_REQUIRES(mRecursiveMutex) {
200 // We ignore Pragma: no-cache if Cache-Control is set.
201 MOZ_ASSERT_IF(mCacheControlNoCache, mHasCacheControl);
202 return mHasCacheControl ? mCacheControlNoCache : mPragmaNoCache;
205 private:
206 // All members must be copy-constructable and assignable
207 nsHttpHeaderArray mHeaders MOZ_GUARDED_BY(mRecursiveMutex);
208 HttpVersion mVersion MOZ_GUARDED_BY(mRecursiveMutex){HttpVersion::v1_1};
209 uint16_t mStatus MOZ_GUARDED_BY(mRecursiveMutex){200};
210 nsCString mStatusText MOZ_GUARDED_BY(mRecursiveMutex);
211 int64_t mContentLength MOZ_GUARDED_BY(mRecursiveMutex){-1};
212 nsCString mContentType MOZ_GUARDED_BY(mRecursiveMutex);
213 nsCString mContentCharset MOZ_GUARDED_BY(mRecursiveMutex);
214 bool mHasCacheControl MOZ_GUARDED_BY(mRecursiveMutex){false};
215 bool mCacheControlPublic MOZ_GUARDED_BY(mRecursiveMutex){false};
216 bool mCacheControlPrivate MOZ_GUARDED_BY(mRecursiveMutex){false};
217 bool mCacheControlNoStore MOZ_GUARDED_BY(mRecursiveMutex){false};
218 bool mCacheControlNoCache MOZ_GUARDED_BY(mRecursiveMutex){false};
219 bool mCacheControlImmutable MOZ_GUARDED_BY(mRecursiveMutex){false};
220 bool mCacheControlStaleWhileRevalidateSet MOZ_GUARDED_BY(mRecursiveMutex){
221 false};
222 uint32_t mCacheControlStaleWhileRevalidate MOZ_GUARDED_BY(mRecursiveMutex){0};
223 bool mCacheControlMaxAgeSet MOZ_GUARDED_BY(mRecursiveMutex){false};
224 uint32_t mCacheControlMaxAge MOZ_GUARDED_BY(mRecursiveMutex){0};
225 bool mPragmaNoCache MOZ_GUARDED_BY(mRecursiveMutex){false};
227 // We are using RecursiveMutex instead of a Mutex because VisitHeader
228 // function calls nsIHttpHeaderVisitor::VisitHeader while under lock.
229 mutable RecursiveMutex mRecursiveMutex{"nsHttpResponseHead.mRecursiveMutex"};
230 // During VisitHeader we sould not allow call to SetHeader.
231 bool mInVisitHeaders MOZ_GUARDED_BY(mRecursiveMutex){false};
233 friend struct IPC::ParamTraits<nsHttpResponseHead>;
236 } // namespace net
237 } // namespace mozilla
239 #endif // nsHttpResponseHead_h__