Backed out changeset 437540429de2 (bug 1800618) for causing build bustages on ObliviousHttpChannel.h CLOSED TREE

This commit is contained in:
Cristian Tuns 2023-01-20 14:15:45 -05:00
parent ccf56a7a6b
commit 4a1af53f22
15 changed files with 20 additions and 1167 deletions

View File

@ -21,10 +21,9 @@ class TRR;
class DNSUtils final {
private:
friend class NetworkConnectivityService;
friend class ODoHService;
friend class ObliviousHttpService;
friend class TRR;
friend class NetworkConnectivityService;
static nsresult CreateChannelHelper(nsIURI* aUri, nsIChannel** aResult);
};

View File

@ -1,51 +0,0 @@
/* -*- 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/. */
#include "BinaryHttpRequest.h"
namespace mozilla::net {
NS_IMPL_ISUPPORTS(BinaryHttpRequest, nsIBinaryHttpRequest)
NS_IMETHODIMP BinaryHttpRequest::GetMethod(nsACString& aMethod) {
aMethod.Assign(mMethod);
return NS_OK;
}
NS_IMETHODIMP BinaryHttpRequest::GetScheme(nsACString& aScheme) {
aScheme.Assign(mScheme);
return NS_OK;
}
NS_IMETHODIMP BinaryHttpRequest::GetAuthority(nsACString& aAuthority) {
aAuthority.Assign(mAuthority);
return NS_OK;
}
NS_IMETHODIMP BinaryHttpRequest::GetPath(nsACString& aPath) {
aPath.Assign(mPath);
return NS_OK;
}
NS_IMETHODIMP BinaryHttpRequest::GetHeaderNames(
nsTArray<nsCString>& aHeaderNames) {
aHeaderNames.Assign(mHeaderNames);
return NS_OK;
}
NS_IMETHODIMP BinaryHttpRequest::GetHeaderValues(
nsTArray<nsCString>& aHeaderValues) {
aHeaderValues.Assign(mHeaderValues);
return NS_OK;
}
NS_IMETHODIMP BinaryHttpRequest::GetContent(nsTArray<uint8_t>& aContent) {
aContent.Assign(mContent);
return NS_OK;
}
} // namespace mozilla::net

View File

@ -1,48 +0,0 @@
/* -*- 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_BinaryHttpRequest_h
#define mozilla_net_BinaryHttpRequest_h
#include "nsIBinaryHttp.h"
#include "nsString.h"
namespace mozilla::net {
class BinaryHttpRequest final : public nsIBinaryHttpRequest {
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIBINARYHTTPREQUEST
BinaryHttpRequest(const nsACString& aMethod, const nsACString& aScheme,
const nsACString& aAuthority, const nsACString& aPath,
nsTArray<nsCString>&& aHeaderNames,
nsTArray<nsCString>&& aHeaderValues,
nsTArray<uint8_t>&& aContent)
: mMethod(aMethod),
mScheme(aScheme),
mAuthority(aAuthority),
mPath(aPath),
mHeaderNames(std::move(aHeaderNames)),
mHeaderValues(std::move(aHeaderValues)),
mContent(std::move(aContent)) {}
private:
~BinaryHttpRequest() = default;
const nsAutoCString mMethod;
const nsAutoCString mScheme;
const nsAutoCString mAuthority;
const nsAutoCString mPath;
const nsTArray<nsCString> mHeaderNames;
const nsTArray<nsCString> mHeaderValues;
const nsTArray<uint8_t> mContent;
};
} // namespace mozilla::net
#endif // mozilla_net_BinaryHttpRequest_h

View File

@ -1,729 +0,0 @@
/* -*- 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/. */
#include "ObliviousHttpChannel.h"
#include "BinaryHttpRequest.h"
#include "nsIHttpHeaderVisitor.h"
#include "nsStringStream.h"
namespace mozilla::net {
NS_IMPL_ISUPPORTS(ObliviousHttpChannel, nsIHttpChannel, nsIIdentChannel,
nsIChannel, nsIRequest, nsIRequestObserver, nsIStreamListener,
nsIUploadChannel2)
ObliviousHttpChannel::ObliviousHttpChannel(
nsIURI* targetURI, const nsTArray<uint8_t>& encodedConfig,
nsIHttpChannel* innerChannel)
: mTargetURI(targetURI),
mEncodedConfig(encodedConfig.Clone()),
mInnerChannel(innerChannel) {
LOG(("ObliviousHttpChannel ctor [this=%p]", this));
MOZ_ASSERT(mInnerChannel);
}
ObliviousHttpChannel::~ObliviousHttpChannel() {
LOG(("ObliviousHttpChannel dtor [this=%p]", this));
}
//-----------------------------------------------------------------------------
// ObliviousHttpChannel::nsIHttpChannel
//-----------------------------------------------------------------------------
NS_IMETHODIMP
ObliviousHttpChannel::GetTopLevelContentWindowId(uint64_t* aWindowId) {
return mInnerChannel->GetTopLevelContentWindowId(aWindowId);
}
NS_IMETHODIMP
ObliviousHttpChannel::SetTopLevelContentWindowId(uint64_t aWindowId) {
return mInnerChannel->SetTopLevelContentWindowId(aWindowId);
}
NS_IMETHODIMP
ObliviousHttpChannel::GetTopBrowsingContextId(uint64_t* aWindowId) {
return mInnerChannel->GetTopBrowsingContextId(aWindowId);
}
NS_IMETHODIMP
ObliviousHttpChannel::SetTopBrowsingContextId(uint64_t aId) {
return mInnerChannel->SetTopBrowsingContextId(aId);
}
NS_IMETHODIMP
ObliviousHttpChannel::GetTransferSize(uint64_t* aTransferSize) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
ObliviousHttpChannel::GetRequestSize(uint64_t* aRequestSize) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
ObliviousHttpChannel::GetDecodedBodySize(uint64_t* aDecodedBodySize) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
ObliviousHttpChannel::GetRequestMethod(nsACString& aRequestMethod) {
aRequestMethod.Assign(mMethod);
return NS_OK;
}
NS_IMETHODIMP
ObliviousHttpChannel::SetRequestMethod(const nsACString& aRequestMethod) {
mMethod.Assign(aRequestMethod);
return NS_OK;
}
NS_IMETHODIMP
ObliviousHttpChannel::GetReferrerInfo(nsIReferrerInfo** aReferrerInfo) {
return mInnerChannel->GetReferrerInfo(aReferrerInfo);
}
NS_IMETHODIMP
ObliviousHttpChannel::SetReferrerInfo(nsIReferrerInfo* aReferrerInfo) {
return mInnerChannel->SetReferrerInfo(aReferrerInfo);
}
NS_IMETHODIMP
ObliviousHttpChannel::SetReferrerInfoWithoutClone(
nsIReferrerInfo* aReferrerInfo) {
return mInnerChannel->SetReferrerInfoWithoutClone(aReferrerInfo);
}
NS_IMETHODIMP
ObliviousHttpChannel::GetRequestHeader(const nsACString& aHeader,
nsACString& _retval) {
_retval.Truncate();
auto value = mHeaders.Lookup(aHeader);
if (!value) {
return NS_ERROR_NOT_AVAILABLE;
}
_retval.Assign(*value);
return NS_OK;
}
NS_IMETHODIMP
ObliviousHttpChannel::SetRequestHeader(const nsACString& aHeader,
const nsACString& aValue, bool aMerge) {
mHeaders.WithEntryHandle(aHeader, [&aValue, aMerge](auto&& entry) {
if (!entry) {
entry.Insert(aValue);
return;
}
if (!aMerge) {
entry.Update(aValue);
return;
}
nsAutoCString newValue(*entry);
newValue.AppendLiteral(", ");
newValue.Append(aValue);
entry.Update(newValue);
});
return NS_OK;
}
NS_IMETHODIMP
ObliviousHttpChannel::SetNewReferrerInfo(
const nsACString& aUrl, nsIReferrerInfo::ReferrerPolicyIDL aPolicy,
bool aSendReferrer) {
return mInnerChannel->SetNewReferrerInfo(aUrl, aPolicy, aSendReferrer);
}
NS_IMETHODIMP
ObliviousHttpChannel::SetEmptyRequestHeader(const nsACString& aHeader) {
return SetRequestHeader(aHeader, EmptyCString(), false);
}
NS_IMETHODIMP
ObliviousHttpChannel::VisitRequestHeaders(nsIHttpHeaderVisitor* aVisitor) {
for (auto iter = mHeaders.ConstIter(); !iter.Done(); iter.Next()) {
nsresult rv = aVisitor->VisitHeader(iter.Key(), iter.Data());
if (NS_FAILED(rv)) {
return rv;
}
}
return NS_OK;
}
NS_IMETHODIMP
ObliviousHttpChannel::VisitNonDefaultRequestHeaders(
nsIHttpHeaderVisitor* aVisitor) {
return mInnerChannel->VisitNonDefaultRequestHeaders(aVisitor);
}
NS_IMETHODIMP
ObliviousHttpChannel::GetAllowSTS(bool* aAllowSTS) {
return mInnerChannel->GetAllowSTS(aAllowSTS);
}
NS_IMETHODIMP
ObliviousHttpChannel::SetAllowSTS(bool aAllowSTS) {
return mInnerChannel->SetAllowSTS(aAllowSTS);
}
NS_IMETHODIMP
ObliviousHttpChannel::GetRedirectionLimit(uint32_t* aRedirectionLimit) {
return mInnerChannel->GetRedirectionLimit(aRedirectionLimit);
}
NS_IMETHODIMP
ObliviousHttpChannel::SetRedirectionLimit(uint32_t aRedirectionLimit) {
return mInnerChannel->SetRedirectionLimit(aRedirectionLimit);
}
NS_IMETHODIMP
ObliviousHttpChannel::GetResponseStatus(uint32_t* aResponseStatus) {
if (!mBinaryHttpResponse) {
return NS_ERROR_NOT_AVAILABLE;
}
uint16_t responseStatus;
nsresult rv = mBinaryHttpResponse->GetStatus(&responseStatus);
if (NS_FAILED(rv)) {
return rv;
}
*aResponseStatus = responseStatus;
return NS_OK;
}
NS_IMETHODIMP
ObliviousHttpChannel::GetResponseStatusText(nsACString& aResponseStatusText) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
ObliviousHttpChannel::GetRequestSucceeded(bool* aRequestSucceeded) {
uint32_t responseStatus;
nsresult rv = GetResponseStatus(&responseStatus);
if (NS_FAILED(rv)) {
return rv;
}
*aRequestSucceeded = (responseStatus / 100) == 2;
return NS_OK;
}
NS_IMETHODIMP
ObliviousHttpChannel::GetIsMainDocumentChannel(bool* aValue) {
return mInnerChannel->GetIsMainDocumentChannel(aValue);
}
NS_IMETHODIMP
ObliviousHttpChannel::SetIsMainDocumentChannel(bool aValue) {
return mInnerChannel->SetIsMainDocumentChannel(aValue);
}
NS_IMETHODIMP
ObliviousHttpChannel::GetResponseHeader(const nsACString& header,
nsACString& _retval) {
if (!mBinaryHttpResponse) {
return NS_ERROR_NOT_AVAILABLE;
}
nsTArray<nsCString> responseHeaderNames;
nsTArray<nsCString> responseHeaderValues;
nsresult rv = mBinaryHttpResponse->GetHeaderNames(responseHeaderNames);
if (NS_FAILED(rv)) {
return rv;
}
rv = mBinaryHttpResponse->GetHeaderValues(responseHeaderValues);
if (NS_FAILED(rv)) {
return rv;
}
for (size_t i = 0;
i < responseHeaderNames.Length() && i < responseHeaderValues.Length();
i++) {
if (responseHeaderNames[i].EqualsIgnoreCase(header)) {
_retval.Assign(responseHeaderValues[i]);
return NS_OK;
}
}
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
ObliviousHttpChannel::SetResponseHeader(const nsACString& header,
const nsACString& value, bool merge) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
ObliviousHttpChannel::VisitResponseHeaders(nsIHttpHeaderVisitor* aVisitor) {
if (!mBinaryHttpResponse) {
return NS_ERROR_NOT_AVAILABLE;
}
nsTArray<nsCString> responseHeaderNames;
nsTArray<nsCString> responseHeaderValues;
nsresult rv = mBinaryHttpResponse->GetHeaderNames(responseHeaderNames);
if (NS_FAILED(rv)) {
return rv;
}
rv = mBinaryHttpResponse->GetHeaderValues(responseHeaderValues);
if (NS_FAILED(rv)) {
return rv;
}
for (size_t i = 0;
i < responseHeaderNames.Length() && i < responseHeaderValues.Length();
i++) {
rv = aVisitor->VisitHeader(responseHeaderNames[i], responseHeaderValues[i]);
if (NS_FAILED(rv)) {
return rv;
}
}
return rv;
}
NS_IMETHODIMP
ObliviousHttpChannel::GetOriginalResponseHeader(
const nsACString& header, nsIHttpHeaderVisitor* aVisitor) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
ObliviousHttpChannel::VisitOriginalResponseHeaders(
nsIHttpHeaderVisitor* aVisitor) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
ObliviousHttpChannel::ShouldStripRequestBodyHeader(const nsACString& aMethod,
bool* aResult) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
ObliviousHttpChannel::IsNoStoreResponse(bool* _retval) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
ObliviousHttpChannel::IsNoCacheResponse(bool* _retval) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
ObliviousHttpChannel::IsPrivateResponse(bool* _retval) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
ObliviousHttpChannel::RedirectTo(nsIURI* aNewURI) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
ObliviousHttpChannel::UpgradeToSecure() { return NS_ERROR_NOT_IMPLEMENTED; }
NS_IMETHODIMP
ObliviousHttpChannel::GetRequestContextID(uint64_t* _retval) {
return mInnerChannel->GetRequestContextID(_retval);
}
NS_IMETHODIMP
ObliviousHttpChannel::SetRequestContextID(uint64_t rcID) {
return mInnerChannel->SetRequestContextID(rcID);
}
NS_IMETHODIMP
ObliviousHttpChannel::GetProtocolVersion(nsACString& aProtocolVersion) {
return mInnerChannel->GetProtocolVersion(aProtocolVersion);
}
NS_IMETHODIMP
ObliviousHttpChannel::GetEncodedBodySize(uint64_t* aEncodedBodySize) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
ObliviousHttpChannel::LogBlockedCORSRequest(const nsAString& aMessage,
const nsACString& aCategory) {
return mInnerChannel->LogBlockedCORSRequest(aMessage, aCategory);
}
NS_IMETHODIMP
ObliviousHttpChannel::LogMimeTypeMismatch(const nsACString& aMessageName,
bool aWarning, const nsAString& aURL,
const nsAString& aContentType) {
return mInnerChannel->LogMimeTypeMismatch(aMessageName, aWarning, aURL,
aContentType);
}
void ObliviousHttpChannel::SetSource(
mozilla::UniquePtr<mozilla::ProfileChunkedBuffer> aSource) {
// NS_ERROR_NOT_IMPLEMENTED
}
//-----------------------------------------------------------------------------
// ObliviousHttpChannel::nsIChannel
//-----------------------------------------------------------------------------
NS_IMETHODIMP
ObliviousHttpChannel::GetOriginalURI(nsIURI** aOriginalURI) {
return mInnerChannel->GetOriginalURI(aOriginalURI);
}
NS_IMETHODIMP
ObliviousHttpChannel::SetOriginalURI(nsIURI* aOriginalURI) {
return mInnerChannel->SetOriginalURI(aOriginalURI);
}
NS_IMETHODIMP
ObliviousHttpChannel::GetURI(nsIURI** aURI) {
*aURI = do_AddRef(mTargetURI).take();
return NS_OK;
}
NS_IMETHODIMP
ObliviousHttpChannel::GetOwner(nsISupports** aOwner) {
return mInnerChannel->GetOwner(aOwner);
}
NS_IMETHODIMP
ObliviousHttpChannel::SetOwner(nsISupports* aOwner) {
return mInnerChannel->SetOwner(aOwner);
}
NS_IMETHODIMP
ObliviousHttpChannel::GetNotificationCallbacks(
nsIInterfaceRequestor** aNotificationCallbacks) {
return mInnerChannel->GetNotificationCallbacks(aNotificationCallbacks);
}
NS_IMETHODIMP
ObliviousHttpChannel::SetNotificationCallbacks(
nsIInterfaceRequestor* aNotificationCallbacks) {
return mInnerChannel->SetNotificationCallbacks(aNotificationCallbacks);
}
NS_IMETHODIMP
ObliviousHttpChannel::GetSecurityInfo(
nsITransportSecurityInfo** aSecurityInfo) {
return mInnerChannel->GetSecurityInfo(aSecurityInfo);
}
NS_IMETHODIMP
ObliviousHttpChannel::GetContentType(nsACString& aContentType) {
return mInnerChannel->GetContentType(aContentType);
}
NS_IMETHODIMP
ObliviousHttpChannel::SetContentType(const nsACString& aContentType) {
return mInnerChannel->SetContentType(aContentType);
}
NS_IMETHODIMP
ObliviousHttpChannel::GetContentCharset(nsACString& aContentCharset) {
return mInnerChannel->GetContentCharset(aContentCharset);
}
NS_IMETHODIMP
ObliviousHttpChannel::SetContentCharset(const nsACString& aContentCharset) {
return mInnerChannel->SetContentCharset(aContentCharset);
}
NS_IMETHODIMP
ObliviousHttpChannel::GetContentLength(int64_t* aContentLength) {
return mInnerChannel->GetContentLength(aContentLength);
}
NS_IMETHODIMP
ObliviousHttpChannel::SetContentLength(int64_t aContentLength) {
return mInnerChannel->SetContentLength(aContentLength);
}
NS_IMETHODIMP
ObliviousHttpChannel::Open(nsIInputStream** aStream) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
ObliviousHttpChannel::AsyncOpen(nsIStreamListener* aListener) {
LOG(("ObliviousHttpChannel::AsyncOpen [this=%p, listener=%p]", this,
aListener));
mStreamListener = aListener;
nsresult rv = mInnerChannel->SetRequestMethod("POST"_ns);
if (NS_FAILED(rv)) {
return rv;
}
rv = mInnerChannel->SetRequestHeader("Content-Type"_ns,
"message/ohttp-req"_ns, false);
if (NS_FAILED(rv)) {
return rv;
}
nsAutoCString scheme;
rv = mTargetURI->GetScheme(scheme);
if (NS_FAILED(rv)) {
return rv;
}
nsAutoCString authority;
rv = mTargetURI->GetHostPort(authority);
if (NS_FAILED(rv)) {
return rv;
}
nsAutoCString path;
rv = mTargetURI->GetPathQueryRef(path);
if (NS_FAILED(rv)) {
return rv;
}
nsTArray<nsCString> headerNames;
nsTArray<nsCString> headerValues;
for (auto iter = mHeaders.ConstIter(); !iter.Done(); iter.Next()) {
headerNames.AppendElement(iter.Key());
headerValues.AppendElement(iter.Data());
}
nsCOMPtr<nsIBinaryHttp> bhttp(
do_GetService("@mozilla.org/network/binary-http;1"));
nsCOMPtr<nsIBinaryHttpRequest> bhttpRequest(new BinaryHttpRequest(
mMethod, scheme, authority, path, std::move(headerNames),
std::move(headerValues), std::move(mContent)));
nsTArray<uint8_t> encodedRequest;
rv = bhttp->EncodeRequest(bhttpRequest, encodedRequest);
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIObliviousHttp> obliviousHttp(
do_GetService("@mozilla.org/network/oblivious-http;1"));
if (!obliviousHttp) {
return NS_ERROR_FAILURE;
}
rv = obliviousHttp->EncapsulateRequest(mEncodedConfig, encodedRequest,
getter_AddRefs(mEncapsulatedRequest));
if (NS_FAILED(rv)) {
return rv;
}
nsTArray<uint8_t> encRequest;
rv = mEncapsulatedRequest->GetEncRequest(encRequest);
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIUploadChannel2> uploadChannel(do_QueryInterface(mInnerChannel));
if (!uploadChannel) {
return NS_ERROR_UNEXPECTED;
}
nsCOMPtr<nsIInputStream> uploadStream;
uint32_t streamLength = encRequest.Length();
rv = NS_NewByteInputStream(getter_AddRefs(uploadStream),
std::move(encRequest));
if (NS_FAILED(rv)) {
return rv;
}
rv = uploadChannel->ExplicitSetUploadStream(
uploadStream, "message/ohttp-req"_ns, streamLength, "POST"_ns, false);
if (NS_FAILED(rv)) {
return rv;
}
return mInnerChannel->AsyncOpen(this);
}
NS_IMETHODIMP
ObliviousHttpChannel::GetCanceled(bool* aCanceled) {
return mInnerChannel->GetCanceled(aCanceled);
}
NS_IMETHODIMP
ObliviousHttpChannel::GetContentDisposition(uint32_t* aContentDisposition) {
return mInnerChannel->GetContentDisposition(aContentDisposition);
}
NS_IMETHODIMP
ObliviousHttpChannel::SetContentDisposition(uint32_t aContentDisposition) {
return mInnerChannel->SetContentDisposition(aContentDisposition);
}
NS_IMETHODIMP
ObliviousHttpChannel::GetContentDispositionFilename(
nsAString& aContentDispositionFilename) {
return mInnerChannel->GetContentDispositionFilename(
aContentDispositionFilename);
}
NS_IMETHODIMP
ObliviousHttpChannel::SetContentDispositionFilename(
const nsAString& aContentDispositionFilename) {
return mInnerChannel->SetContentDispositionFilename(
aContentDispositionFilename);
}
NS_IMETHODIMP
ObliviousHttpChannel::GetContentDispositionHeader(
nsACString& aContentDispositionHeader) {
return mInnerChannel->GetContentDispositionHeader(aContentDispositionHeader);
}
NS_IMETHODIMP
ObliviousHttpChannel::GetLoadInfo(nsILoadInfo** aLoadInfo) {
return mInnerChannel->GetLoadInfo(aLoadInfo);
}
NS_IMETHODIMP
ObliviousHttpChannel::SetLoadInfo(nsILoadInfo* aLoadInfo) {
return mInnerChannel->SetLoadInfo(aLoadInfo);
}
NS_IMETHODIMP
ObliviousHttpChannel::GetIsDocument(bool* aIsDocument) {
return mInnerChannel->GetIsDocument(aIsDocument);
}
//-----------------------------------------------------------------------------
// ObliviousHttpChannel::nsIStreamListener
//-----------------------------------------------------------------------------
NS_IMETHODIMP
ObliviousHttpChannel::OnDataAvailable(nsIRequest* aRequest,
nsIInputStream* aStream, uint64_t aOffset,
uint32_t aCount) {
LOG(
("ObliviousHttpChannel::OnDataAvailable [this=%p, request=%p, stream=%p, "
"offset=%" PRIu64 ", count=%u]",
this, aRequest, aStream, aOffset, aCount));
if (aOffset != 0) {
return NS_ERROR_INVALID_ARG;
}
size_t oldLength = mRawResponse.Length();
size_t newLength = oldLength + aCount;
if (newLength < oldLength) { // i.e., overflow
return NS_ERROR_FAILURE;
}
mRawResponse.SetCapacity(newLength);
mRawResponse.SetLengthAndRetainStorage(newLength);
void* dest = mRawResponse.Elements() + oldLength;
uint64_t written = 0;
nsresult rv = NS_ReadInputStreamToBuffer(aStream, &dest, aCount, &written);
if (NS_FAILED(rv)) {
return rv;
}
if (written != aCount) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
//-----------------------------------------------------------------------------
// ObliviousHttpChannel::nsIRequestObserver
//-----------------------------------------------------------------------------
NS_IMETHODIMP
ObliviousHttpChannel::OnStartRequest(nsIRequest* aRequest) {
LOG(("ObliviousHttpChannel::OnStartRequest [this=%p, request=%p]", this,
aRequest));
return mStreamListener->OnStartRequest(aRequest);
}
NS_IMETHODIMP
ObliviousHttpChannel::OnStopRequest(nsIRequest* aRequest,
nsresult aStatusCode) {
LOG(("ObliviousHttpChannel::OnStopRequest [this=%p, request=%p, status=%u]",
this, aRequest, aStatusCode));
nsCOMPtr<nsIObliviousHttp> obliviousHttp(
do_GetService("@mozilla.org/network/oblivious-http;1"));
if (!obliviousHttp) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIObliviousHttpClientResponse> response;
nsresult rv = mEncapsulatedRequest->GetResponse(getter_AddRefs(response));
if (NS_FAILED(rv)) {
return rv;
}
nsTArray<uint8_t> decapsulated;
rv = response->Decapsulate(mRawResponse, decapsulated);
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIBinaryHttp> bhttp(
do_GetService("@mozilla.org/network/binary-http;1"));
if (!bhttp) {
return NS_ERROR_FAILURE;
}
rv = bhttp->DecodeResponse(decapsulated, getter_AddRefs(mBinaryHttpResponse));
if (NS_FAILED(rv)) {
return rv;
}
nsTArray<uint8_t> content;
rv = mBinaryHttpResponse->GetContent(content);
if (NS_FAILED(rv)) {
return rv;
}
if (content.Length() > std::numeric_limits<uint32_t>::max()) {
return NS_ERROR_FAILURE;
}
uint32_t contentLength = (uint32_t)content.Length();
if (contentLength > 0) {
nsCOMPtr<nsIInputStream> contentStream;
rv = NS_NewByteInputStream(getter_AddRefs(contentStream),
std::move(content));
if (NS_FAILED(rv)) {
return rv;
}
rv = mStreamListener->OnDataAvailable(aRequest, contentStream, 0,
contentLength);
if (NS_FAILED(rv)) {
return rv;
}
}
rv = mStreamListener->OnStopRequest(aRequest, aStatusCode);
if (NS_FAILED(rv)) {
return rv;
}
mInnerChannel = nullptr;
mEncapsulatedRequest = nullptr;
mStreamListener = nullptr;
return NS_OK;
}
//-----------------------------------------------------------------------------
// ObliviousHttpChannel::nsIUploadChannel2
//-----------------------------------------------------------------------------
NS_IMETHODIMP ObliviousHttpChannel::ExplicitSetUploadStream(
nsIInputStream* aStream, const nsACString& aContentType,
int64_t aContentLength, const nsACString& aMethod, bool aStreamHasHeaders) {
if (aMethod != "POST"_ns || aStreamHasHeaders) {
return NS_ERROR_INVALID_ARG;
}
mMethod.Assign(aMethod);
uint64_t available;
if (aContentLength < 0) {
nsresult rv = aStream->Available(&available);
if (NS_FAILED(rv)) {
return rv;
}
} else {
available = aContentLength;
}
if (available > std::numeric_limits<int64_t>::max()) {
return NS_ERROR_FAILURE;
}
mContent.SetCapacity(available);
mContent.SetLengthAndRetainStorage(available);
void* dest = mContent.Elements();
uint64_t written = 0;
nsresult rv =
NS_ReadInputStreamToBuffer(aStream, &dest, (int64_t)available, &written);
if (NS_FAILED(rv)) {
return rv;
}
if (written != available) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP ObliviousHttpChannel::GetUploadStreamHasHeaders(
bool* aUploadStreamHasHeaders) {
*aUploadStreamHasHeaders = false;
return NS_OK;
}
NS_IMETHODIMP ObliviousHttpChannel::CloneUploadStream(
int64_t* aContentLength, nsIInputStream** _retval) {
return NS_ERROR_NOT_IMPLEMENTED;
}
} // namespace mozilla::net

View File

@ -1,57 +0,0 @@
/* -*- 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_ObliviousHttpChannel_h
#define mozilla_net_ObliviousHttpChannel_h
#include "nsHashtablesFwd.h"
#include "nsIBinaryHttp.h"
#include "nsIHttpChannel.h"
#include "nsIObliviousHttp.h"
#include "nsIUploadChannel2.h"
namespace mozilla::net {
class ObliviousHttpChannel final : public nsIHttpChannel,
public nsIStreamListener,
public nsIUploadChannel2 {
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSICHANNEL
NS_DECL_NSIHTTPCHANNEL
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIUPLOADCHANNEL2
ObliviousHttpChannel(nsIURI* targetURI,
const nsTArray<uint8_t>& encodedConfig,
nsIHttpChannel* innerChannel);
NS_FORWARD_NSIREQUEST(mInnerChannel->)
NS_FORWARD_NSIIDENTCHANNEL(mInnerChannel->)
protected:
~ObliviousHttpChannel();
nsCOMPtr<nsIURI> mTargetURI;
nsTArray<uint8_t> mEncodedConfig;
nsCString mMethod{"GET"_ns};
nsTHashMap<nsCStringHashKey, nsCString> mHeaders;
nsTArray<uint8_t> mContent;
nsCOMPtr<nsIHttpChannel> mInnerChannel;
nsCOMPtr<nsIObliviousHttpClientRequest> mEncapsulatedRequest;
nsTArray<uint8_t> mRawResponse;
nsCOMPtr<nsIBinaryHttpResponse> mBinaryHttpResponse;
nsCOMPtr<nsIStreamListener> mStreamListener;
};
} // namespace mozilla::net
#endif // mozilla_net_ObliviousHttpChannel_h

View File

@ -1,37 +0,0 @@
/* -*- 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/. */
#include "ObliviousHttpService.h"
#include "DNSUtils.h"
#include "ObliviousHttpChannel.h"
namespace mozilla::net {
NS_IMPL_ISUPPORTS(ObliviousHttpService, nsIObliviousHttpService)
NS_IMETHODIMP
ObliviousHttpService::NewChannel(nsIURI* relayURI, nsIURI* targetURI,
const nsTArray<uint8_t>& encodedConfig,
nsIChannel** result) {
nsCOMPtr<nsIChannel> innerChannel;
nsresult rv =
DNSUtils::CreateChannelHelper(relayURI, getter_AddRefs(innerChannel));
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIHttpChannel> innerHttpChannel(do_QueryInterface(innerChannel));
if (!innerHttpChannel) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIChannel> obliviousHttpChannel(
new ObliviousHttpChannel(targetURI, encodedConfig, innerHttpChannel));
obliviousHttpChannel.forget(result);
return NS_OK;
}
} // namespace mozilla::net

View File

@ -1,26 +0,0 @@
/* -*- 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_ObliviousHttpService_h
#define mozilla_net_ObliviousHttpService_h
#include "nsIObliviousHttp.h"
namespace mozilla::net {
class ObliviousHttpService final : public nsIObliviousHttpService {
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIOBLIVIOUSHTTPSERVICE
private:
~ObliviousHttpService() = default;
};
} // namespace mozilla::net
#endif // mozilla_net_ObliviousHttpService_h

View File

@ -239,7 +239,7 @@ impl BinaryHttp {
if header_names.len() != header_values.len() {
return Err(NS_ERROR_INVALID_ARG);
}
for (name, value) in header_names.iter().zip(header_values.iter()) {
for (name, value) in header_values.iter().zip(header_names.iter()) {
message.put_header(name.to_vec(), value.to_vec());
}
let mut content = ThinVec::new();

View File

@ -23,11 +23,4 @@ Classes = [
'headers': ['/netwerk/protocol/http/oblivious_http/src/oblivious_http.h'],
'legacy_constructor': 'oblivious_http_constructor',
},
{
'cid': '{b1f08d56-fca6-4290-9500-d5168dc9d8c3}',
'contract_ids': ['@mozilla.org/network/oblivious-http-service;1'],
'interfaces': ['nsIObliviousHttpService'],
'type': 'mozilla::net::ObliviousHttpService',
'headers': ['/netwerk/protocol/http/ObliviousHttpService.h'],
},
]

View File

@ -93,7 +93,6 @@ UNIFIED_SOURCES += [
"BackgroundChannelRegistrar.cpp",
"BackgroundDataBridgeChild.cpp",
"BackgroundDataBridgeParent.cpp",
"BinaryHttpRequest.cpp",
"CacheControlParser.cpp",
"CachePushChecker.cpp",
"ConnectionDiagnostics.cpp",
@ -152,8 +151,6 @@ UNIFIED_SOURCES += [
"nsServerTiming.cpp",
"NullHttpChannel.cpp",
"NullHttpTransaction.cpp",
"ObliviousHttpChannel.cpp",
"ObliviousHttpService.cpp",
"OpaqueResponseUtils.cpp",
"ParentChannelListener.cpp",
"PendingTransactionInfo.cpp",

View File

@ -5,9 +5,6 @@
#include "nsISupports.idl"
interface nsIChannel;
interface nsIURI;
[scriptable, builtinclass, uuid(f2a4aaa4-046a-439e-beef-893b15a90cff)]
interface nsIObliviousHttpClientResponse : nsISupports {
// Decrypt an encrypted response ("enc_response" in the RFC).
@ -65,9 +62,3 @@ interface nsIObliviousHttp : nsISupports
nsIObliviousHttpServer server();
};
[scriptable, builtinclass, uuid(b1f08d56-fca6-4290-9500-d5168dc9d8c3)]
interface nsIObliviousHttpService : nsISupports
{
nsIChannel newChannel(in nsIURI relayURI, in nsIURI targetURI, in Array<octet> encodedConfig);
};

View File

@ -457,18 +457,3 @@ function hexStringToBytes(hex) {
}
return bytes;
}
function stringToBytes(str) {
return Array.from(str, chr => chr.charCodeAt(0));
}
function BinaryHttpResponse(status, headerNames, headerValues, content) {
this.status = status;
this.headerNames = headerNames;
this.headerValues = headerValues;
this.content = content;
}
BinaryHttpResponse.prototype = {
QueryInterface: ChromeUtils.generateQI(["nsIBinaryHttpResponse"]),
};

View File

@ -6,6 +6,10 @@
// Unit tests for the binary http bindings.
// Tests basic encoding and decoding of requests and responses.
function stringToBytes(str) {
return Array.from(str, chr => chr.charCodeAt(0));
}
function BinaryHttpRequest(
method,
scheme,
@ -28,6 +32,17 @@ BinaryHttpRequest.prototype = {
QueryInterface: ChromeUtils.generateQI(["nsIBinaryHttpRequest"]),
};
function BinaryHttpResponse(status, headerNames, headerValues, content) {
this.status = status;
this.headerNames = headerNames;
this.headerValues = headerValues;
this.content = content;
}
BinaryHttpResponse.prototype = {
QueryInterface: ChromeUtils.generateQI(["nsIBinaryHttpResponse"]),
};
function test_encode_request() {
let bhttp = Cc["@mozilla.org/network/binary-http;1"].getService(
Ci.nsIBinaryHttp
@ -192,7 +207,9 @@ function test_encode_response() {
);
let encoded = bhttp.encodeResponse(response);
let expected = hexStringToBytes(
"0141a2180c636f6e74656e742d747970650a746578742f706c61696e0c49276d206120746561706f7400"
"0141a2180a746578742f706c61696e0c" +
"636f6e74656e742d747970650c49276d" +
"206120746561706f7400"
);
deepEqual(encoded, expected);

View File

@ -1,180 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* https://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
function bytesToString(bytes) {
return String.fromCharCode.apply(null, bytes);
}
class ObliviousHttpTestRequest {
constructor(method, uri, headers, content) {
this.method = method;
this.uri = uri;
this.headers = headers;
this.content = content;
}
}
class ObliviousHttpTestResponse {
constructor(status, headers, content) {
this.status = status;
this.headers = headers;
this.content = content;
}
}
class ObliviousHttpTestCase {
constructor(request, response) {
this.request = request;
this.response = response;
}
}
add_task(async function test_oblivious_http() {
let testcases = [
new ObliviousHttpTestCase(
new ObliviousHttpTestRequest(
"GET",
NetUtil.newURI("https://example.com"),
{ "X-Some-Header": "header value" },
""
),
new ObliviousHttpTestResponse(200, {}, "Hello, World!")
),
new ObliviousHttpTestCase(
new ObliviousHttpTestRequest(
"POST",
NetUtil.newURI("http://example.test"),
{ "X-Some-Header": "header value", "X-Some-Other-Header": "25" },
"Posting some content..."
),
new ObliviousHttpTestResponse(
418,
{ "X-Teapot": "teapot" },
"I'm a teapot"
)
),
];
for (let testcase of testcases) {
await run_one_testcase(testcase);
}
});
async function run_one_testcase(testcase) {
let ohttp = Cc["@mozilla.org/network/oblivious-http;1"].getService(
Ci.nsIObliviousHttp
);
let ohttpServer = ohttp.server();
let httpServer = new HttpServer();
httpServer.registerPathHandler("/", function(request, response) {
let inputStream = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(
Ci.nsIScriptableInputStream
);
inputStream.init(request.bodyInputStream);
let requestBody = inputStream.readBytes(inputStream.available());
let ohttpResponse = ohttpServer.decapsulate(stringToBytes(requestBody));
let bhttp = Cc["@mozilla.org/network/binary-http;1"].getService(
Ci.nsIBinaryHttp
);
let decodedRequest = bhttp.decodeRequest(ohttpResponse.request);
equal(decodedRequest.method, testcase.request.method);
equal(decodedRequest.scheme, testcase.request.uri.scheme);
equal(decodedRequest.authority, testcase.request.uri.hostPort);
equal(decodedRequest.path, testcase.request.uri.pathQueryRef);
for (
let i = 0;
i < decodedRequest.headerNames.length &&
i < decodedRequest.headerValues.length;
i++
) {
equal(
decodedRequest.headerValues[i],
testcase.request.headers[decodedRequest.headerNames[i]]
);
}
equal(bytesToString(decodedRequest.content), testcase.request.content);
let responseHeaderNames = ["content-type"];
let responseHeaderValues = ["text/plain"];
for (let headerName of Object.keys(testcase.response.headers)) {
responseHeaderNames.push(headerName);
responseHeaderValues.push(testcase.response.headers[headerName]);
}
let binaryResponse = new BinaryHttpResponse(
testcase.response.status,
responseHeaderNames,
responseHeaderValues,
stringToBytes(testcase.response.content)
);
let responseBytes = bhttp.encodeResponse(binaryResponse);
let encResponse = ohttpResponse.encapsulate(responseBytes);
response.setStatusLine(request.httpVersion, 200, "OK");
response.setHeader("Content-Type", "message/ohttp-res", false);
response.write(bytesToString(encResponse));
});
httpServer.start(-1);
let ohttpService = Cc[
"@mozilla.org/network/oblivious-http-service;1"
].getService(Ci.nsIObliviousHttpService);
let relayURI = NetUtil.newURI(
`http://localhost:${httpServer.identity.primaryPort}/`
);
let obliviousHttpChannel = ohttpService
.newChannel(relayURI, testcase.request.uri, ohttpServer.encodedConfig)
.QueryInterface(Ci.nsIHttpChannel);
for (let headerName of Object.keys(testcase.request.headers)) {
obliviousHttpChannel.setRequestHeader(
headerName,
testcase.request.headers[headerName],
false
);
}
if (testcase.request.method == "POST") {
let uploadChannel = obliviousHttpChannel.QueryInterface(
Ci.nsIUploadChannel2
);
ok(uploadChannel);
let bodyStream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(
Ci.nsIStringInputStream
);
bodyStream.setData(
testcase.request.content,
testcase.request.content.length
);
uploadChannel.explicitSetUploadStream(
bodyStream,
null,
-1,
testcase.request.method,
false
);
}
let response = await new Promise((resolve, reject) => {
NetUtil.asyncFetch(obliviousHttpChannel, function(inputStream, result) {
let scriptableInputStream = Cc[
"@mozilla.org/scriptableinputstream;1"
].createInstance(Ci.nsIScriptableInputStream);
scriptableInputStream.init(inputStream);
let responseBody = scriptableInputStream.readBytes(
inputStream.available()
);
resolve(responseBody);
});
});
equal(response, testcase.response.content);
for (let headerName of Object.keys(testcase.response.headers)) {
equal(
obliviousHttpChannel.getResponseHeader(headerName),
testcase.response.headers[headerName]
);
}
await new Promise((resolve, reject) => {
httpServer.stop(resolve);
});
}

View File

@ -728,7 +728,6 @@ skip-if =
os == 'win' && msix # https://bugzilla.mozilla.org/show_bug.cgi?id=1808049
run-sequentially = http3server
[test_bhttp.js]
[test_oblivious_http.js]
[test_ohttp.js]
[test_websocket_500k.js]
skip-if = verify