1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set sw=2 ts=8 et tw=80 : */
3 :
4 : /* ***** BEGIN LICENSE BLOCK *****
5 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 : *
7 : * The contents of this file are subject to the Mozilla Public License Version
8 : * 1.1 (the "License"); you may not use this file except in compliance with
9 : * the License. You may obtain a copy of the License at
10 : * http://www.mozilla.org/MPL/
11 : *
12 : * Software distributed under the License is distributed on an "AS IS" basis,
13 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 : * for the specific language governing rights and limitations under the
15 : * License.
16 : *
17 : * The Original Code is mozilla.org code.
18 : *
19 : * The Initial Developer of the Original Code is
20 : * The Mozilla Foundation
21 : * Portions created by the Initial Developer are Copyright (C) 2010
22 : * the Initial Developer. All Rights Reserved.
23 : *
24 : * Contributor(s):
25 : * Alon Zakai <azakai@mozilla.com>
26 : * Josh Matthews <josh@joshmatthews.net>
27 : *
28 : * Alternatively, the contents of this file may be used under the terms of
29 : * either the GNU General Public License Version 2 or later (the "GPL"), or
30 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
31 : * in which case the provisions of the GPL or the LGPL are applicable instead
32 : * of those above. If you wish to allow use of your version of this file only
33 : * under the terms of either the GPL or the LGPL, and not to allow others to
34 : * use your version of this file under the terms of the MPL, indicate your
35 : * decision by deleting the provisions above and replace them with the notice
36 : * and other provisions required by the GPL or the LGPL. If you do not delete
37 : * the provisions above, a recipient may use your version of this file under
38 : * the terms of any one of the MPL, the GPL or the LGPL.
39 : *
40 : * ***** END LICENSE BLOCK ***** */
41 :
42 : #include "mozilla/net/FTPChannelParent.h"
43 : #include "nsFTPChannel.h"
44 : #include "nsNetUtil.h"
45 : #include "nsISupportsPriority.h"
46 : #include "nsIRedirectChannelRegistrar.h"
47 : #include "nsFtpProtocolHandler.h"
48 :
49 : #undef LOG
50 : #define LOG(args) PR_LOG(gFTPLog, PR_LOG_DEBUG, args)
51 :
52 : namespace mozilla {
53 : namespace net {
54 :
55 0 : FTPChannelParent::FTPChannelParent()
56 0 : : mIPCClosed(false)
57 : {
58 : nsIProtocolHandler* handler;
59 0 : CallGetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "ftp", &handler);
60 0 : NS_ASSERTION(handler, "no ftp handler");
61 0 : }
62 :
63 0 : FTPChannelParent::~FTPChannelParent()
64 : {
65 0 : gFtpHandler->Release();
66 0 : }
67 :
68 : void
69 0 : FTPChannelParent::ActorDestroy(ActorDestroyReason why)
70 : {
71 : // We may still have refcount>0 if the channel hasn't called OnStopRequest
72 : // yet, but we must not send any more msgs to child.
73 0 : mIPCClosed = true;
74 0 : }
75 :
76 : //-----------------------------------------------------------------------------
77 : // FTPChannelParent::nsISupports
78 : //-----------------------------------------------------------------------------
79 :
80 0 : NS_IMPL_ISUPPORTS4(FTPChannelParent,
81 : nsIStreamListener,
82 : nsIParentChannel,
83 : nsIInterfaceRequestor,
84 : nsIRequestObserver);
85 :
86 : //-----------------------------------------------------------------------------
87 : // FTPChannelParent::PFTPChannelParent
88 : //-----------------------------------------------------------------------------
89 :
90 : bool
91 0 : FTPChannelParent::RecvAsyncOpen(const IPC::URI& aURI,
92 : const PRUint64& aStartPos,
93 : const nsCString& aEntityID,
94 : const IPC::InputStream& aUploadStream)
95 : {
96 0 : nsCOMPtr<nsIURI> uri(aURI);
97 :
98 : #ifdef DEBUG
99 0 : nsCString uriSpec;
100 0 : uri->GetSpec(uriSpec);
101 0 : LOG(("FTPChannelParent RecvAsyncOpen [this=%x uri=%s]\n",
102 : this, uriSpec.get()));
103 : #endif
104 :
105 : nsresult rv;
106 0 : nsCOMPtr<nsIIOService> ios(do_GetIOService(&rv));
107 0 : if (NS_FAILED(rv))
108 0 : return SendFailedAsyncOpen(rv);
109 :
110 0 : nsCOMPtr<nsIChannel> chan;
111 0 : rv = NS_NewChannel(getter_AddRefs(chan), uri, ios);
112 0 : if (NS_FAILED(rv))
113 0 : return SendFailedAsyncOpen(rv);
114 :
115 0 : mChannel = static_cast<nsFtpChannel*>(chan.get());
116 :
117 0 : nsCOMPtr<nsIInputStream> upload(aUploadStream);
118 0 : if (upload) {
119 : // contentType and contentLength are ignored
120 0 : rv = mChannel->SetUploadStream(upload, EmptyCString(), 0);
121 0 : if (NS_FAILED(rv))
122 0 : return SendFailedAsyncOpen(rv);
123 : }
124 :
125 0 : rv = mChannel->ResumeAt(aStartPos, aEntityID);
126 0 : if (NS_FAILED(rv))
127 0 : return SendFailedAsyncOpen(rv);
128 :
129 0 : rv = mChannel->AsyncOpen(this, nsnull);
130 0 : if (NS_FAILED(rv))
131 0 : return SendFailedAsyncOpen(rv);
132 :
133 0 : return true;
134 : }
135 :
136 : bool
137 0 : FTPChannelParent::RecvConnectChannel(const PRUint32& channelId)
138 : {
139 : nsresult rv;
140 :
141 0 : LOG(("Looking for a registered channel [this=%p, id=%d]", this, channelId));
142 :
143 0 : nsCOMPtr<nsIChannel> channel;
144 0 : rv = NS_LinkRedirectChannels(channelId, this, getter_AddRefs(channel));
145 0 : if (NS_SUCCEEDED(rv))
146 0 : mChannel = static_cast<nsFtpChannel*>(channel.get());
147 :
148 0 : LOG((" found channel %p, rv=%08x", mChannel.get(), rv));
149 :
150 0 : return true;
151 : }
152 :
153 : bool
154 0 : FTPChannelParent::RecvCancel(const nsresult& status)
155 : {
156 0 : if (mChannel)
157 0 : mChannel->Cancel(status);
158 0 : return true;
159 : }
160 :
161 : bool
162 0 : FTPChannelParent::RecvSuspend()
163 : {
164 0 : if (mChannel)
165 0 : mChannel->Suspend();
166 0 : return true;
167 : }
168 :
169 : bool
170 0 : FTPChannelParent::RecvResume()
171 : {
172 0 : if (mChannel)
173 0 : mChannel->Resume();
174 0 : return true;
175 : }
176 :
177 : //-----------------------------------------------------------------------------
178 : // FTPChannelParent::nsIRequestObserver
179 : //-----------------------------------------------------------------------------
180 :
181 : NS_IMETHODIMP
182 0 : FTPChannelParent::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
183 : {
184 0 : LOG(("FTPChannelParent::OnStartRequest [this=%x]\n", this));
185 :
186 0 : nsFtpChannel* chan = static_cast<nsFtpChannel*>(aRequest);
187 : PRInt32 aContentLength;
188 0 : chan->GetContentLength(&aContentLength);
189 0 : nsCString contentType;
190 0 : chan->GetContentType(contentType);
191 0 : nsCString entityID;
192 0 : chan->GetEntityID(entityID);
193 : PRTime lastModified;
194 0 : chan->GetLastModifiedTime(&lastModified);
195 :
196 0 : if (mIPCClosed || !SendOnStartRequest(aContentLength, contentType,
197 0 : lastModified, entityID, chan->URI())) {
198 0 : return NS_ERROR_UNEXPECTED;
199 : }
200 :
201 0 : return NS_OK;
202 : }
203 :
204 : NS_IMETHODIMP
205 0 : FTPChannelParent::OnStopRequest(nsIRequest* aRequest,
206 : nsISupports* aContext,
207 : nsresult aStatusCode)
208 : {
209 0 : LOG(("FTPChannelParent::OnStopRequest: [this=%x status=%ul]\n",
210 : this, aStatusCode));
211 :
212 0 : if (mIPCClosed || !SendOnStopRequest(aStatusCode)) {
213 0 : return NS_ERROR_UNEXPECTED;
214 : }
215 :
216 0 : return NS_OK;
217 : }
218 :
219 : //-----------------------------------------------------------------------------
220 : // FTPChannelParent::nsIStreamListener
221 : //-----------------------------------------------------------------------------
222 :
223 : NS_IMETHODIMP
224 0 : FTPChannelParent::OnDataAvailable(nsIRequest* aRequest,
225 : nsISupports* aContext,
226 : nsIInputStream* aInputStream,
227 : PRUint32 aOffset,
228 : PRUint32 aCount)
229 : {
230 0 : LOG(("FTPChannelParent::OnDataAvailable [this=%x]\n", this));
231 :
232 0 : nsCString data;
233 0 : nsresult rv = NS_ReadInputStreamToString(aInputStream, data, aCount);
234 0 : if (NS_FAILED(rv))
235 0 : return rv;
236 :
237 0 : if (mIPCClosed || !SendOnDataAvailable(data, aOffset, aCount))
238 0 : return NS_ERROR_UNEXPECTED;
239 :
240 0 : return NS_OK;
241 : }
242 :
243 : //-----------------------------------------------------------------------------
244 : // FTPChannelParent::nsIParentChannel
245 : //-----------------------------------------------------------------------------
246 :
247 : NS_IMETHODIMP
248 0 : FTPChannelParent::Delete()
249 : {
250 0 : if (mIPCClosed || !SendDeleteSelf())
251 0 : return NS_ERROR_UNEXPECTED;
252 :
253 0 : return NS_OK;
254 : }
255 :
256 : //-----------------------------------------------------------------------------
257 : // FTPChannelParent::nsIInterfaceRequestor
258 : //-----------------------------------------------------------------------------
259 :
260 : NS_IMETHODIMP
261 0 : FTPChannelParent::GetInterface(const nsIID& uuid, void** result)
262 : {
263 0 : return QueryInterface(uuid, result);
264 : }
265 :
266 : } // namespace net
267 : } // namespace mozilla
268 :
|