summaryrefslogtreecommitdiffstats
path: root/netwerk/protocol/http/TLSTransportLayer.h
diff options
context:
space:
mode:
Diffstat (limited to 'netwerk/protocol/http/TLSTransportLayer.h')
-rw-r--r--netwerk/protocol/http/TLSTransportLayer.h169
1 files changed, 169 insertions, 0 deletions
diff --git a/netwerk/protocol/http/TLSTransportLayer.h b/netwerk/protocol/http/TLSTransportLayer.h
new file mode 100644
index 0000000000..986b56174a
--- /dev/null
+++ b/netwerk/protocol/http/TLSTransportLayer.h
@@ -0,0 +1,169 @@
+/* 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 TLSTransportLayer_h__
+#define TLSTransportLayer_h__
+
+#include "nsSocketTransportService2.h"
+#include "nsIInterfaceRequestor.h"
+#include "nsISocketTransport.h"
+#include "nsIAsyncInputStream.h"
+#include "nsIAsyncOutputStream.h"
+#include "prio.h"
+
+namespace mozilla::net {
+
+// TLSTransportLayer will provide a secondary TLS layer. It will be added as a
+// layer between nsHttpConnection and nsSocketTransport.
+// The mSocketTransport, mSocketIn, and mSocketOut of nsHttpConnection will be
+// replaced by TLSTransportLayer.
+//
+// The input path of reading data from a socket is shown below.
+// nsHttpConnection::OnSocketReadable
+// nsHttpConnection::OnWriteSegment
+// nsHttpConnection::mSocketIn->Read
+// TLSTransportLayer::InputStreamWrapper::Read
+// TLSTransportLayer::InputInternal
+// TLSTransportLayer::InputStreamWrapper::ReadDirectly
+// nsSocketInputStream::Read
+//
+// The output path of writing data to a socket is shown below.
+// nsHttpConnection::OnSocketWritable
+// nsHttpConnection::OnReadSegment
+// TLSTransportLayer::OutputStreamWrapper::Write
+// TLSTransportLayer::OutputInternal
+// TLSTransportLayer::OutputStreamWrapper::WriteDirectly
+// nsSocketOutputStream::Write
+
+// 9d6a3bc6-1f90-41d0-9b02-33ccd169052b
+#define NS_TLSTRANSPORTLAYER_IID \
+ { \
+ 0x9d6a3bc6, 0x1f90, 0x41d0, { \
+ 0x9b, 0x02, 0x33, 0xcc, 0xd1, 0x69, 0x05, 0x2b \
+ } \
+ }
+
+class TLSTransportLayer final : public nsISocketTransport,
+ public nsIInputStreamCallback,
+ public nsIOutputStreamCallback {
+ public:
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_TLSTRANSPORTLAYER_IID)
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSITRANSPORT
+ NS_DECL_NSISOCKETTRANSPORT
+ NS_DECL_NSIINPUTSTREAMCALLBACK
+ NS_DECL_NSIOUTPUTSTREAMCALLBACK
+
+ explicit TLSTransportLayer(nsISocketTransport* aTransport,
+ nsIAsyncInputStream* aInputStream,
+ nsIAsyncOutputStream* aOutputStream,
+ nsIInputStreamCallback* aOwner);
+ bool Init(const char* aTLSHost, int32_t aTLSPort);
+ already_AddRefed<nsIAsyncInputStream> GetInputStreamWrapper() {
+ nsCOMPtr<nsIAsyncInputStream> stream = &mSocketInWrapper;
+ return stream.forget();
+ }
+ already_AddRefed<nsIAsyncOutputStream> GetOutputStreamWrapper() {
+ nsCOMPtr<nsIAsyncOutputStream> stream = &mSocketOutWrapper;
+ return stream.forget();
+ }
+
+ bool HasDataToRecv();
+
+ void ReleaseOwner() { mOwner = nullptr; }
+
+ private:
+ class InputStreamWrapper : public nsIAsyncInputStream {
+ public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSIINPUTSTREAM
+ NS_DECL_NSIASYNCINPUTSTREAM
+
+ explicit InputStreamWrapper(nsIAsyncInputStream* aInputStream,
+ TLSTransportLayer* aTransport);
+
+ nsresult ReadDirectly(char* buf, uint32_t count, uint32_t* countRead);
+ nsresult Status() { return mStatus; }
+ void SetStatus(nsresult aStatus) { mStatus = aStatus; }
+
+ private:
+ friend class TLSTransportLayer;
+ virtual ~InputStreamWrapper() = default;
+ nsresult ReturnDataFromBuffer(char* buf, uint32_t count,
+ uint32_t* countRead);
+
+ nsCOMPtr<nsIAsyncInputStream> mSocketIn;
+
+ nsresult mStatus{NS_OK};
+ // The lifetime of InputStreamWrapper and OutputStreamWrapper are bound to
+ // TLSTransportLayer, so using |mTransport| as a raw pointer should be safe.
+ TLSTransportLayer* MOZ_OWNING_REF mTransport;
+ };
+
+ class OutputStreamWrapper : public nsIAsyncOutputStream {
+ public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSIOUTPUTSTREAM
+ NS_DECL_NSIASYNCOUTPUTSTREAM
+
+ explicit OutputStreamWrapper(nsIAsyncOutputStream* aOutputStream,
+ TLSTransportLayer* aTransport);
+
+ nsresult WriteDirectly(const char* buf, uint32_t count,
+ uint32_t* countWritten);
+ nsresult Status() { return mStatus; }
+ void SetStatus(nsresult aStatus) { mStatus = aStatus; }
+
+ private:
+ friend class TLSTransportLayer;
+ virtual ~OutputStreamWrapper() = default;
+ static nsresult WriteFromSegments(nsIInputStream*, void*, const char*,
+ uint32_t offset, uint32_t count,
+ uint32_t* countRead);
+
+ nsCOMPtr<nsIAsyncOutputStream> mSocketOut;
+
+ nsresult mStatus{NS_OK};
+ TLSTransportLayer* MOZ_OWNING_REF mTransport;
+ };
+
+ virtual ~TLSTransportLayer();
+
+ nsISocketTransport* Transport() { return mSocketTransport; }
+
+ int32_t OutputInternal(const char* aBuf, int32_t aAmount);
+ int32_t InputInternal(char* aBuf, int32_t aAmount);
+
+ static PRStatus GetPeerName(PRFileDesc* fd, PRNetAddr* addr);
+ static PRStatus GetSocketOption(PRFileDesc* fd, PRSocketOptionData* aOpt);
+ static PRStatus SetSocketOption(PRFileDesc* fd,
+ const PRSocketOptionData* data);
+ static int32_t Write(PRFileDesc* fd, const void* buf, int32_t amount);
+ static int32_t Read(PRFileDesc* fd, void* buf, int32_t amount);
+ static int32_t Send(PRFileDesc* fd, const void* buf, int32_t amount,
+ int flags, PRIntervalTime timeout);
+ static int32_t Recv(PRFileDesc* fd, void* buf, int32_t amount, int flags,
+ PRIntervalTime timeout);
+ static PRStatus Close(PRFileDesc* fd);
+ static int16_t Poll(PRFileDesc* fd, int16_t in_flags, int16_t* out_flags);
+
+ nsCOMPtr<nsISocketTransport> mSocketTransport;
+ InputStreamWrapper mSocketInWrapper;
+ OutputStreamWrapper mSocketOutWrapper;
+ nsCOMPtr<nsITLSSocketControl> mTLSSocketControl;
+ nsCOMPtr<nsIInputStreamCallback> mInputCallback;
+ nsCOMPtr<nsIOutputStreamCallback> mOutputCallback;
+ PRFileDesc* mFD{nullptr};
+ nsCOMPtr<nsIInputStreamCallback> mOwner;
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(TLSTransportLayer, NS_TLSTRANSPORTLAYER_IID)
+
+} // namespace mozilla::net
+
+inline nsISupports* ToSupports(mozilla::net::TLSTransportLayer* aTransport) {
+ return static_cast<nsISocketTransport*>(aTransport);
+}
+
+#endif