2021-03-30 03:52:29 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set sw=2 ts=8 et tw=80 : */
|
|
|
|
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#ifndef mozilla_net_OpaqueResponseUtils_h
|
|
|
|
#define mozilla_net_OpaqueResponseUtils_h
|
|
|
|
|
2021-07-16 01:04:24 +03:00
|
|
|
#include "nsIContentPolicy.h"
|
2022-10-27 22:18:11 +03:00
|
|
|
#include "nsIStreamListener.h"
|
2022-11-14 19:11:46 +03:00
|
|
|
#include "nsUnknownDecoder.h"
|
|
|
|
#include "nsMimeTypes.h"
|
|
|
|
#include "nsIHttpChannel.h"
|
2021-07-16 01:04:24 +03:00
|
|
|
|
2022-10-27 22:18:11 +03:00
|
|
|
#include "mozilla/Variant.h"
|
|
|
|
#include "mozilla/Logging.h"
|
2021-07-16 01:04:24 +03:00
|
|
|
|
2022-10-27 22:18:11 +03:00
|
|
|
#include "nsCOMPtr.h"
|
|
|
|
#include "nsString.h"
|
|
|
|
#include "nsTArray.h"
|
2021-03-30 03:52:29 +03:00
|
|
|
|
2022-10-27 22:18:11 +03:00
|
|
|
class nsIContentSniffer;
|
|
|
|
static mozilla::LazyLogModule gORBLog("ORB");
|
|
|
|
|
|
|
|
namespace mozilla::net {
|
|
|
|
|
|
|
|
class HttpBaseChannel;
|
2021-03-30 03:52:31 +03:00
|
|
|
class nsHttpResponseHead;
|
|
|
|
|
2021-12-10 18:31:08 +03:00
|
|
|
enum class OpaqueResponseBlockedReason : uint32_t {
|
|
|
|
ALLOWED_SAFE_LISTED,
|
|
|
|
BLOCKED_BLOCKLISTED_NEVER_SNIFFED,
|
|
|
|
BLOCKED_206_AND_BLOCKLISTED,
|
|
|
|
BLOCKED_NOSNIFF_AND_EITHER_BLOCKLISTED_OR_TEXTPLAIN,
|
|
|
|
BLOCKED_SHOULD_SNIFF
|
|
|
|
};
|
2021-03-30 03:52:29 +03:00
|
|
|
|
2021-12-10 18:31:08 +03:00
|
|
|
OpaqueResponseBlockedReason GetOpaqueResponseBlockedReason(
|
|
|
|
const nsHttpResponseHead& aResponseHead);
|
2021-03-30 03:52:29 +03:00
|
|
|
|
2021-03-30 03:52:30 +03:00
|
|
|
// Returns a tuple of (rangeStart, rangeEnd, rangeTotal) from the input range
|
|
|
|
// header string if succeed.
|
|
|
|
Result<std::tuple<int64_t, int64_t, int64_t>, nsresult>
|
|
|
|
ParseContentRangeHeaderString(const nsAutoCString& aRangeStr);
|
|
|
|
|
2021-03-30 03:52:31 +03:00
|
|
|
bool IsFirstPartialResponse(nsHttpResponseHead& aResponseHead);
|
2022-10-27 22:18:11 +03:00
|
|
|
|
|
|
|
void LogORBError(nsILoadInfo* aLoadInfo, nsIURI* aURI);
|
|
|
|
|
|
|
|
class OpaqueResponseBlocker final : public nsIStreamListener {
|
|
|
|
enum class State { Sniffing, Allowed, Blocked };
|
|
|
|
|
|
|
|
public:
|
|
|
|
NS_DECL_THREADSAFE_ISUPPORTS
|
|
|
|
NS_DECL_NSIREQUESTOBSERVER
|
|
|
|
NS_DECL_NSISTREAMLISTENER;
|
|
|
|
|
|
|
|
OpaqueResponseBlocker(nsIStreamListener* aNext, HttpBaseChannel* aChannel);
|
|
|
|
|
|
|
|
void AllowResponse();
|
|
|
|
void BlockResponse(HttpBaseChannel* aChannel, nsresult aReason);
|
2022-11-14 19:11:46 +03:00
|
|
|
|
2022-10-27 22:18:11 +03:00
|
|
|
private:
|
|
|
|
virtual ~OpaqueResponseBlocker() = default;
|
|
|
|
|
|
|
|
void MaybeORBSniff(nsIRequest* aRequest);
|
|
|
|
|
|
|
|
void ResolveAndSendPending(HttpBaseChannel* aChannel, State aState,
|
|
|
|
nsresult aStatus);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIStreamListener> mNext;
|
|
|
|
|
|
|
|
State mState = State::Sniffing;
|
|
|
|
nsresult mStatus = NS_OK;
|
|
|
|
bool mCheckIsOpaqueResponseAllowedAfterSniff = true;
|
|
|
|
};
|
|
|
|
|
2022-11-14 19:11:46 +03:00
|
|
|
class nsCompressedAudioVideoImageDetector : public nsUnknownDecoder {
|
|
|
|
const std::function<void(void*, const uint8_t*, uint32_t)> mCallback;
|
|
|
|
|
|
|
|
public:
|
|
|
|
nsCompressedAudioVideoImageDetector(
|
|
|
|
nsIStreamListener* aListener,
|
|
|
|
std::function<void(void*, const uint8_t*, uint32_t)>&& aCallback)
|
|
|
|
: nsUnknownDecoder(aListener), mCallback(aCallback) {}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
virtual void DetermineContentType(nsIRequest* aRequest) override {
|
|
|
|
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aRequest);
|
|
|
|
if (!httpChannel) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* testData = mBuffer;
|
|
|
|
uint32_t testDataLen = mBufferLen;
|
|
|
|
// Check if data are compressed.
|
|
|
|
nsAutoCString decodedData;
|
|
|
|
|
|
|
|
// ConvertEncodedData is always called only on a single thread for each
|
|
|
|
// instance of an object.
|
|
|
|
nsresult rv = ConvertEncodedData(aRequest, mBuffer, mBufferLen);
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
MutexAutoLock lock(mMutex);
|
|
|
|
decodedData = mDecodedData;
|
|
|
|
}
|
|
|
|
if (!decodedData.IsEmpty()) {
|
|
|
|
testData = decodedData.get();
|
|
|
|
testDataLen = std::min<uint32_t>(decodedData.Length(), 512u);
|
|
|
|
}
|
|
|
|
|
|
|
|
mCallback(httpChannel, (const uint8_t*)testData, testDataLen);
|
|
|
|
|
|
|
|
nsAutoCString contentType;
|
|
|
|
rv = httpChannel->GetContentType(contentType);
|
|
|
|
|
|
|
|
MutexAutoLock lock(mMutex);
|
|
|
|
if (!contentType.IsEmpty()) {
|
|
|
|
mContentType = contentType;
|
|
|
|
} else {
|
|
|
|
mContentType = UNKNOWN_CONTENT_TYPE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2022-10-27 22:18:11 +03:00
|
|
|
} // namespace mozilla::net
|
2021-03-30 03:52:29 +03:00
|
|
|
|
|
|
|
#endif // mozilla_net_OpaqueResponseUtils_h
|