summaryrefslogtreecommitdiff
path: root/netwerk/protocol/ftp/FTPChannelChild.h
blob: f68b85a72d4541488534b4324dbde02b22aea2c7 (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
/* -*- 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_FTPChannelChild_h
#define mozilla_net_FTPChannelChild_h

#include "mozilla/UniquePtr.h"
#include "mozilla/net/PFTPChannelChild.h"
#include "mozilla/net/ChannelEventQueue.h"
#include "nsBaseChannel.h"
#include "nsIFTPChannel.h"
#include "nsIUploadChannel.h"
#include "nsIProxiedChannel.h"
#include "nsIResumableChannel.h"
#include "nsIChildChannel.h"
#include "nsIDivertableChannel.h"

#include "nsIStreamListener.h"
#include "PrivateBrowsingChannel.h"

namespace mozilla {
namespace net {

// This class inherits logic from nsBaseChannel that is not needed for an
// e10s child channel, but it works.  At some point we could slice up
// nsBaseChannel and have a new class that has only the common logic for
// nsFTPChannel/FTPChannelChild.

class FTPChannelChild final : public PFTPChannelChild
                            , public nsBaseChannel
                            , public nsIFTPChannel
                            , public nsIUploadChannel
                            , public nsIResumableChannel
                            , public nsIProxiedChannel
                            , public nsIChildChannel
                            , public nsIDivertableChannel
{
public:
  typedef ::nsIStreamListener nsIStreamListener;

  NS_DECL_ISUPPORTS_INHERITED
  NS_DECL_NSIFTPCHANNEL
  NS_DECL_NSIUPLOADCHANNEL
  NS_DECL_NSIRESUMABLECHANNEL
  NS_DECL_NSIPROXIEDCHANNEL
  NS_DECL_NSICHILDCHANNEL
  NS_DECL_NSIDIVERTABLECHANNEL

  NS_IMETHOD Cancel(nsresult status) override;
  NS_IMETHOD Suspend() override;
  NS_IMETHOD Resume() override;

  explicit FTPChannelChild(nsIURI* uri);

  void AddIPDLReference();
  void ReleaseIPDLReference();

  NS_IMETHOD AsyncOpen(nsIStreamListener* listener, nsISupports* aContext) override;

  // Note that we handle this ourselves, overriding the nsBaseChannel
  // default behavior, in order to be e10s-friendly.
  NS_IMETHOD IsPending(bool* result) override;

  nsresult OpenContentStream(bool async,
                             nsIInputStream** stream,
                             nsIChannel** channel) override;

  bool IsSuspended();

  void FlushedForDiversion();

protected:
  virtual ~FTPChannelChild();

  bool RecvOnStartRequest(const nsresult& aChannelStatus,
                          const int64_t& aContentLength,
                          const nsCString& aContentType,
                          const PRTime& aLastModified,
                          const nsCString& aEntityID,
                          const URIParams& aURI) override;
  bool RecvOnDataAvailable(const nsresult& channelStatus,
                           const nsCString& data,
                           const uint64_t& offset,
                           const uint32_t& count) override;
  bool RecvOnStopRequest(const nsresult& channelStatus,
                         const nsCString &aErrorMsg,
                         const bool &aUseUTF8) override;
  bool RecvFailedAsyncOpen(const nsresult& statusCode) override;
  bool RecvFlushedForDiversion() override;
  bool RecvDivertMessages() override;
  bool RecvDeleteSelf() override;

  void DoOnStartRequest(const nsresult& aChannelStatus,
                        const int64_t& aContentLength,
                        const nsCString& aContentType,
                        const PRTime& aLastModified,
                        const nsCString& aEntityID,
                        const URIParams& aURI);
  void DoOnDataAvailable(const nsresult& channelStatus,
                         const nsCString& data,
                         const uint64_t& offset,
                         const uint32_t& count);
  void MaybeDivertOnData(const nsCString& data,
                         const uint64_t& offset,
                         const uint32_t& count);
  void MaybeDivertOnStop(const nsresult& statusCode);
  void DoOnStopRequest(const nsresult& statusCode,
                       const nsCString &aErrorMsg,
                       bool aUseUTF8);
  void DoFailedAsyncOpen(const nsresult& statusCode);
  void DoDeleteSelf();

  friend class FTPStartRequestEvent;
  friend class FTPDataAvailableEvent;
  friend class MaybeDivertOnDataFTPEvent;
  friend class FTPStopRequestEvent;
  friend class MaybeDivertOnStopFTPEvent;
  friend class FTPFailedAsyncOpenEvent;
  friend class FTPDeleteSelfEvent;

private:
  nsCOMPtr<nsIInputStream> mUploadStream;

  bool mIPCOpen;
  RefPtr<ChannelEventQueue> mEventQ;

  // If nsUnknownDecoder is involved we queue onDataAvailable (and possibly
  // OnStopRequest) so that we can divert them if needed when the listener's
  // OnStartRequest is finally called
  nsTArray<UniquePtr<ChannelEvent>> mUnknownDecoderEventQ;
  bool mUnknownDecoderInvolved;

  bool mCanceled;
  uint32_t mSuspendCount;
  bool mIsPending;

  PRTime mLastModifiedTime;
  uint64_t mStartPos;
  nsCString mEntityID;

  // Once set, OnData and possibly OnStop will be diverted to the parent.
  bool mDivertingToParent;
  // Once set, no OnStart/OnData/OnStop callbacks should be received from the
  // parent channel, nor dequeued from the ChannelEventQueue.
  bool mFlushedForDiversion;
  // Set if SendSuspend is called. Determines if SendResume is needed when
  // diverting callbacks to parent.
  bool mSuspendSent;
};

inline bool
FTPChannelChild::IsSuspended()
{
  return mSuspendCount != 0;
}

} // namespace net
} // namespace mozilla

#endif // mozilla_net_FTPChannelChild_h