summaryrefslogtreecommitdiffstats
path: root/netwerk/protocol/http/HttpTransactionParent.h
blob: 2707075a24061c75eece69d42c1eb48cf7b574d9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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 HttpTransactionParent_h__
#define HttpTransactionParent_h__

#include "mozilla/Atomics.h"
#include "mozilla/Mutex.h"
#include "mozilla/net/HttpTransactionShell.h"
#include "mozilla/net/NeckoChannelParams.h"
#include "mozilla/net/PHttpTransactionParent.h"
#include "nsCOMPtr.h"
#include "nsHttp.h"
#include "nsIRequest.h"
#include "nsIThreadRetargetableRequest.h"
#include "nsITransport.h"
#include "nsITransportSecurityInfo.h"

namespace mozilla::net {

class ChannelEventQueue;
class nsHttpConnectionInfo;

#define HTTP_TRANSACTION_PARENT_IID                  \
  {                                                  \
    0xb83695cb, 0xc24b, 0x4c53, {                    \
      0x85, 0x9b, 0x77, 0x77, 0x3e, 0xc5, 0x44, 0xe5 \
    }                                                \
  }

// HttpTransactionParent plays the role of nsHttpTransaction and delegates the
// work to the nsHttpTransaction in socket process.
class HttpTransactionParent final : public PHttpTransactionParent,
                                    public HttpTransactionShell,
                                    public nsIRequest,
                                    public nsIThreadRetargetableRequest {
 public:
  NS_DECL_THREADSAFE_ISUPPORTS
  NS_DECL_HTTPTRANSACTIONSHELL
  NS_DECL_NSIREQUEST
  NS_DECL_NSITHREADRETARGETABLEREQUEST
  NS_DECLARE_STATIC_IID_ACCESSOR(HTTP_TRANSACTION_PARENT_IID)

  explicit HttpTransactionParent(bool aIsDocumentLoad);

  void ActorDestroy(ActorDestroyReason aWhy) override;

  mozilla::ipc::IPCResult RecvOnStartRequest(
      const nsresult& aStatus, const Maybe<nsHttpResponseHead>& aResponseHead,
      nsITransportSecurityInfo* aSecurityInfo, const bool& aProxyConnectFailed,
      const TimingStructArgs& aTimings,
      const int32_t& aProxyConnectResponseCode,
      nsTArray<uint8_t>&& aDataForSniffer, const Maybe<nsCString>& aAltSvcUsed,
      const bool& aDataToChildProcess, const bool& aRestarted,
      const uint32_t& aHTTPSSVCReceivedStage, const bool& aSupportsHttp3,
      const nsIRequest::TRRMode& aMode, const TRRSkippedReason& aSkipReason);
  mozilla::ipc::IPCResult RecvOnTransportStatus(
      const nsresult& aStatus, const int64_t& aProgress,
      const int64_t& aProgressMax,
      Maybe<NetworkAddressArg>&& aNetworkAddressArg);
  mozilla::ipc::IPCResult RecvOnDataAvailable(const nsCString& aData,
                                              const uint64_t& aOffset,
                                              const uint32_t& aCount);
  mozilla::ipc::IPCResult RecvOnStopRequest(
      const nsresult& aStatus, const bool& aResponseIsComplete,
      const int64_t& aTransferSize, const TimingStructArgs& aTimings,
      const Maybe<nsHttpHeaderArray>& responseTrailers,
      Maybe<TransactionObserverResult>&& aTransactionObserverResult,
      const TimeStamp& aLastActiveTabOptHit, const uint32_t& aCaps,
      const HttpConnectionInfoCloneArgs& aArgs);
  mozilla::ipc::IPCResult RecvOnInitFailed(const nsresult& aStatus);

  mozilla::ipc::IPCResult RecvOnH2PushStream(const uint32_t& aPushedStreamId,
                                             const nsCString& aResourceUrl,
                                             const nsCString& aRequestString);
  mozilla::ipc::IPCResult RecvEarlyHint(const nsCString& aValue,
                                        const nsACString& aReferrerPolicy,
                                        const nsACString& aCSPHeader);

  virtual mozilla::TimeStamp GetPendingTime() override;

  already_AddRefed<nsIEventTarget> GetNeckoTarget();

  void SetSniffedTypeToChannel(
      nsInputStreamPump::PeekSegmentFun aCallTypeSniffers,
      nsIChannel* aChannel);

  void SetRedirectTimestamp(TimeStamp aRedirectStart, TimeStamp aRedirectEnd) {
    mRedirectStart = aRedirectStart;
    mRedirectEnd = aRedirectEnd;
  }

 private:
  virtual ~HttpTransactionParent();

  void GetStructFromInfo(nsHttpConnectionInfo* aInfo,
                         HttpConnectionInfoCloneArgs& aArgs);
  void DoOnStartRequest(
      const nsresult& aStatus, const Maybe<nsHttpResponseHead>& aResponseHead,
      nsITransportSecurityInfo* aSecurityInfo, const bool& aProxyConnectFailed,
      const TimingStructArgs& aTimings,
      const int32_t& aProxyConnectResponseCode,
      nsTArray<uint8_t>&& aDataForSniffer, const Maybe<nsCString>& aAltSvcUsed,
      const bool& aDataToChildProcess, const bool& aRestarted,
      const uint32_t& aHTTPSSVCReceivedStage, const bool& aSupportsHttp3,
      const nsIRequest::TRRMode& aMode, const TRRSkippedReason& aSkipReason);
  void DoOnDataAvailable(const nsCString& aData, const uint64_t& aOffset,
                         const uint32_t& aCount);
  void DoOnStopRequest(
      const nsresult& aStatus, const bool& aResponseIsComplete,
      const int64_t& aTransferSize, const TimingStructArgs& aTimings,
      const Maybe<nsHttpHeaderArray>& responseTrailers,
      Maybe<TransactionObserverResult>&& aTransactionObserverResult,
      const uint32_t& aCaps, nsHttpConnectionInfo* aConnInfo);
  void DoNotifyListener();
  void ContinueDoNotifyListener();
  // Get event target for ODA.
  already_AddRefed<nsISerialEventTarget> GetODATarget();
  void CancelOnMainThread(nsresult aRv);
  void HandleAsyncAbort();

  nsCOMPtr<nsITransportEventSink> mEventsink;
  nsCOMPtr<nsIStreamListener> mChannel;
  nsCOMPtr<nsISerialEventTarget> mTargetThread;
  nsCOMPtr<nsISerialEventTarget> mODATarget;
  Mutex mEventTargetMutex MOZ_UNANNOTATED{
      "HttpTransactionParent::EventTargetMutex"};
  nsCOMPtr<nsITransportSecurityInfo> mSecurityInfo;
  UniquePtr<nsHttpResponseHead> mResponseHead;
  UniquePtr<nsHttpHeaderArray> mResponseTrailers;
  RefPtr<ChannelEventQueue> mEventQ;

  bool mResponseIsComplete{false};
  int64_t mTransferSize{0};
  int64_t mRequestSize{0};
  bool mIsHttp3Used = false;
  bool mProxyConnectFailed{false};
  Atomic<bool, ReleaseAcquire> mCanceled{false};
  Atomic<nsresult, ReleaseAcquire> mStatus{NS_OK};
  int32_t mSuspendCount{0};
  bool mResponseHeadTaken{false};
  bool mResponseTrailersTaken{false};
  bool mOnStartRequestCalled{false};
  bool mOnStopRequestCalled{false};
  bool mResolvedByTRR{false};
  nsIRequest::TRRMode mEffectiveTRRMode{nsIRequest::TRR_DEFAULT_MODE};
  TRRSkippedReason mTRRSkipReason{nsITRRSkipReason::TRR_UNSET};
  bool mEchConfigUsed = false;
  int32_t mProxyConnectResponseCode{0};
  uint64_t mChannelId{0};
  bool mDataSentToChildProcess{false};
  bool mIsDocumentLoad;
  bool mRestarted{false};
  Atomic<uint32_t, ReleaseAcquire> mCaps{0};
  TimeStamp mRedirectStart;
  TimeStamp mRedirectEnd;

  NetAddr mSelfAddr;
  NetAddr mPeerAddr;
  TimingStruct mTimings;
  TimeStamp mDomainLookupStart;
  TimeStamp mDomainLookupEnd;
  TransactionObserverFunc mTransactionObserver;
  OnPushCallback mOnPushCallback;
  nsTArray<uint8_t> mDataForSniffer;
  std::function<void()> mCallOnResume;
  uint32_t mHTTPSSVCReceivedStage{};
  RefPtr<nsHttpConnectionInfo> mConnInfo;
  bool mSupportsHTTP3 = false;
};

NS_DEFINE_STATIC_IID_ACCESSOR(HttpTransactionParent,
                              HTTP_TRANSACTION_PARENT_IID)

}  // namespace mozilla::net

#endif  // nsHttpTransactionParent_h__