netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,712 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +#include "nsWyciwyg.h"
     1.9 +
    1.10 +#include "base/compiler_specific.h"
    1.11 +
    1.12 +#include "mozilla/net/ChannelEventQueue.h"
    1.13 +#include "WyciwygChannelChild.h"
    1.14 +#include "mozilla/dom/TabChild.h"
    1.15 +
    1.16 +#include "nsCharsetSource.h"
    1.17 +#include "nsStringStream.h"
    1.18 +#include "nsNetUtil.h"
    1.19 +#include "nsISerializable.h"
    1.20 +#include "nsSerializationHelper.h"
    1.21 +#include "nsIProgressEventSink.h"
    1.22 +#include "mozilla/ipc/URIUtils.h"
    1.23 +#include "SerializedLoadContext.h"
    1.24 +
    1.25 +using namespace mozilla::ipc;
    1.26 +
    1.27 +namespace mozilla {
    1.28 +namespace net {
    1.29 +
    1.30 +NS_IMPL_ISUPPORTS(WyciwygChannelChild,
    1.31 +                  nsIRequest,
    1.32 +                  nsIChannel,
    1.33 +                  nsIWyciwygChannel,
    1.34 +                  nsIPrivateBrowsingChannel)
    1.35 +
    1.36 +
    1.37 +WyciwygChannelChild::WyciwygChannelChild()
    1.38 +  : mStatus(NS_OK)
    1.39 +  , mIsPending(false)
    1.40 +  , mCanceled(false)
    1.41 +  , mLoadFlags(LOAD_NORMAL)
    1.42 +  , mContentLength(-1)
    1.43 +  , mCharsetSource(kCharsetUninitialized)
    1.44 +  , mState(WCC_NEW)
    1.45 +  , mIPCOpen(false)
    1.46 +  , mSentAppData(false)
    1.47 +{
    1.48 +  LOG(("Creating WyciwygChannelChild @%x\n", this));
    1.49 +  mEventQ = new ChannelEventQueue(NS_ISUPPORTS_CAST(nsIWyciwygChannel*, this));
    1.50 +}
    1.51 +
    1.52 +WyciwygChannelChild::~WyciwygChannelChild()
    1.53 +{
    1.54 +  LOG(("Destroying WyciwygChannelChild @%x\n", this));
    1.55 +}
    1.56 +
    1.57 +void
    1.58 +WyciwygChannelChild::AddIPDLReference()
    1.59 +{
    1.60 +  NS_ABORT_IF_FALSE(!mIPCOpen, "Attempt to retain more than one IPDL reference");
    1.61 +  mIPCOpen = true;
    1.62 +  AddRef();
    1.63 +}
    1.64 +
    1.65 +void
    1.66 +WyciwygChannelChild::ReleaseIPDLReference()
    1.67 +{
    1.68 +  NS_ABORT_IF_FALSE(mIPCOpen, "Attempt to release nonexistent IPDL reference");
    1.69 +  mIPCOpen = false;
    1.70 +  Release();
    1.71 +}
    1.72 +
    1.73 +nsresult
    1.74 +WyciwygChannelChild::Init(nsIURI* uri)
    1.75 +{
    1.76 +  NS_ENSURE_ARG_POINTER(uri);
    1.77 +
    1.78 +  mState = WCC_INIT;
    1.79 +
    1.80 +  mURI = uri;
    1.81 +  mOriginalURI = uri;
    1.82 +
    1.83 +  URIParams serializedUri;
    1.84 +  SerializeURI(uri, serializedUri);
    1.85 +
    1.86 +  SendInit(serializedUri);
    1.87 +  return NS_OK;
    1.88 +}
    1.89 +
    1.90 +//-----------------------------------------------------------------------------
    1.91 +// WyciwygChannelChild::PWyciwygChannelChild
    1.92 +//-----------------------------------------------------------------------------
    1.93 +
    1.94 +class WyciwygStartRequestEvent : public ChannelEvent
    1.95 +{
    1.96 +public:
    1.97 +  WyciwygStartRequestEvent(WyciwygChannelChild* child,
    1.98 +                           const nsresult& statusCode,
    1.99 +                           const int64_t& contentLength,
   1.100 +                           const int32_t& source,
   1.101 +                           const nsCString& charset,
   1.102 +                           const nsCString& securityInfo)
   1.103 +  : mChild(child), mStatusCode(statusCode), mContentLength(contentLength),
   1.104 +    mSource(source), mCharset(charset), mSecurityInfo(securityInfo) {}
   1.105 +  void Run() { mChild->OnStartRequest(mStatusCode, mContentLength, mSource,
   1.106 +                                     mCharset, mSecurityInfo); }
   1.107 +private:
   1.108 +  WyciwygChannelChild* mChild;
   1.109 +  nsresult mStatusCode;
   1.110 +  int64_t mContentLength;
   1.111 +  int32_t mSource;
   1.112 +  nsCString mCharset;
   1.113 +  nsCString mSecurityInfo;
   1.114 +};
   1.115 +
   1.116 +bool
   1.117 +WyciwygChannelChild::RecvOnStartRequest(const nsresult& statusCode,
   1.118 +                                        const int64_t& contentLength,
   1.119 +                                        const int32_t& source,
   1.120 +                                        const nsCString& charset,
   1.121 +                                        const nsCString& securityInfo)
   1.122 +{
   1.123 +  if (mEventQ->ShouldEnqueue()) {
   1.124 +    mEventQ->Enqueue(new WyciwygStartRequestEvent(this, statusCode,
   1.125 +                                                 contentLength, source,
   1.126 +                                                 charset, securityInfo));
   1.127 +  } else {
   1.128 +    OnStartRequest(statusCode, contentLength, source, charset, securityInfo);
   1.129 +  }
   1.130 +  return true;
   1.131 +}
   1.132 +
   1.133 +void
   1.134 +WyciwygChannelChild::OnStartRequest(const nsresult& statusCode,
   1.135 +                                    const int64_t& contentLength,
   1.136 +                                    const int32_t& source,
   1.137 +                                    const nsCString& charset,
   1.138 +                                    const nsCString& securityInfo)
   1.139 +{
   1.140 +  LOG(("WyciwygChannelChild::RecvOnStartRequest [this=%p]\n", this));
   1.141 +
   1.142 +  mState = WCC_ONSTART;
   1.143 +
   1.144 +  mStatus = statusCode;
   1.145 +  mContentLength = contentLength;
   1.146 +  mCharsetSource = source;
   1.147 +  mCharset = charset;
   1.148 +
   1.149 +  if (!securityInfo.IsEmpty()) {
   1.150 +    NS_DeserializeObject(securityInfo, getter_AddRefs(mSecurityInfo));
   1.151 +  }
   1.152 +
   1.153 +  AutoEventEnqueuer ensureSerialDispatch(mEventQ);
   1.154 +
   1.155 +  nsresult rv = mListener->OnStartRequest(this, mListenerContext);
   1.156 +  if (NS_FAILED(rv))
   1.157 +    Cancel(rv);
   1.158 +}
   1.159 +
   1.160 +class WyciwygDataAvailableEvent : public ChannelEvent
   1.161 +{
   1.162 +public:
   1.163 +  WyciwygDataAvailableEvent(WyciwygChannelChild* child,
   1.164 +                            const nsCString& data,
   1.165 +                            const uint64_t& offset)
   1.166 +  : mChild(child), mData(data), mOffset(offset) {}
   1.167 +  void Run() { mChild->OnDataAvailable(mData, mOffset); }
   1.168 +private:
   1.169 +  WyciwygChannelChild* mChild;
   1.170 +  nsCString mData;
   1.171 +  uint64_t mOffset;
   1.172 +};
   1.173 +
   1.174 +bool
   1.175 +WyciwygChannelChild::RecvOnDataAvailable(const nsCString& data,
   1.176 +                                         const uint64_t& offset)
   1.177 +{
   1.178 +  if (mEventQ->ShouldEnqueue()) {
   1.179 +    mEventQ->Enqueue(new WyciwygDataAvailableEvent(this, data, offset));
   1.180 +  } else {
   1.181 +    OnDataAvailable(data, offset);
   1.182 +  }
   1.183 +  return true;
   1.184 +}
   1.185 +
   1.186 +void
   1.187 +WyciwygChannelChild::OnDataAvailable(const nsCString& data,
   1.188 +                                     const uint64_t& offset)
   1.189 +{
   1.190 +  LOG(("WyciwygChannelChild::RecvOnDataAvailable [this=%p]\n", this));
   1.191 +
   1.192 +  if (mCanceled)
   1.193 +    return;
   1.194 +
   1.195 +  mState = WCC_ONDATA;
   1.196 +
   1.197 +  // NOTE: the OnDataAvailable contract requires the client to read all the data
   1.198 +  // in the inputstream.  This code relies on that ('data' will go away after
   1.199 +  // this function).  Apparently the previous, non-e10s behavior was to actually
   1.200 +  // support only reading part of the data, allowing later calls to read the
   1.201 +  // rest.
   1.202 +  nsCOMPtr<nsIInputStream> stringStream;
   1.203 +  nsresult rv = NS_NewByteInputStream(getter_AddRefs(stringStream),
   1.204 +                                      data.get(),
   1.205 +                                      data.Length(),
   1.206 +                                      NS_ASSIGNMENT_DEPEND);
   1.207 +  if (NS_FAILED(rv)) {
   1.208 +    Cancel(rv);
   1.209 +    return;
   1.210 +  }
   1.211 +
   1.212 +  AutoEventEnqueuer ensureSerialDispatch(mEventQ);
   1.213 +  
   1.214 +  rv = mListener->OnDataAvailable(this, mListenerContext,
   1.215 +                                  stringStream, offset, data.Length());
   1.216 +  if (NS_FAILED(rv))
   1.217 +    Cancel(rv);
   1.218 +
   1.219 +  if (mProgressSink && NS_SUCCEEDED(rv) && !(mLoadFlags & LOAD_BACKGROUND))
   1.220 +    mProgressSink->OnProgress(this, nullptr, offset + data.Length(),
   1.221 +                              uint64_t(mContentLength));
   1.222 +}
   1.223 +
   1.224 +class WyciwygStopRequestEvent : public ChannelEvent
   1.225 +{
   1.226 +public:
   1.227 +  WyciwygStopRequestEvent(WyciwygChannelChild* child,
   1.228 +                          const nsresult& statusCode)
   1.229 +  : mChild(child), mStatusCode(statusCode) {}
   1.230 +  void Run() { mChild->OnStopRequest(mStatusCode); }
   1.231 +private:
   1.232 +  WyciwygChannelChild* mChild;
   1.233 +  nsresult mStatusCode;
   1.234 +};
   1.235 +
   1.236 +bool
   1.237 +WyciwygChannelChild::RecvOnStopRequest(const nsresult& statusCode)
   1.238 +{
   1.239 +  if (mEventQ->ShouldEnqueue()) {
   1.240 +    mEventQ->Enqueue(new WyciwygStopRequestEvent(this, statusCode));
   1.241 +  } else {
   1.242 +    OnStopRequest(statusCode);
   1.243 +  }
   1.244 +  return true;
   1.245 +}
   1.246 +
   1.247 +void
   1.248 +WyciwygChannelChild::OnStopRequest(const nsresult& statusCode)
   1.249 +{
   1.250 +  LOG(("WyciwygChannelChild::RecvOnStopRequest [this=%p status=%u]\n",
   1.251 +           this, statusCode));
   1.252 +
   1.253 +  { // We need to ensure that all IPDL message dispatching occurs
   1.254 +    // before we delete the protocol below
   1.255 +    AutoEventEnqueuer ensureSerialDispatch(mEventQ);
   1.256 +
   1.257 +    mState = WCC_ONSTOP;
   1.258 +
   1.259 +    mIsPending = false;
   1.260 +
   1.261 +    if (!mCanceled)
   1.262 +      mStatus = statusCode;
   1.263 +
   1.264 +    mListener->OnStopRequest(this, mListenerContext, statusCode);
   1.265 +
   1.266 +    mListener = 0;
   1.267 +    mListenerContext = 0;
   1.268 +
   1.269 +    if (mLoadGroup)
   1.270 +      mLoadGroup->RemoveRequest(this, nullptr, mStatus);
   1.271 +
   1.272 +    mCallbacks = 0;
   1.273 +    mProgressSink = 0;
   1.274 +  }
   1.275 +
   1.276 +  if (mIPCOpen)
   1.277 +    PWyciwygChannelChild::Send__delete__(this);
   1.278 +}
   1.279 +
   1.280 +class WyciwygCancelEvent : public ChannelEvent
   1.281 +{
   1.282 + public:
   1.283 +  WyciwygCancelEvent(WyciwygChannelChild* child, const nsresult& status)
   1.284 +  : mChild(child)
   1.285 +  , mStatus(status) {}
   1.286 +
   1.287 +  void Run() { mChild->CancelEarly(mStatus); }
   1.288 + private:
   1.289 +  WyciwygChannelChild* mChild;
   1.290 +  nsresult mStatus;
   1.291 +};
   1.292 +
   1.293 +bool
   1.294 +WyciwygChannelChild::RecvCancelEarly(const nsresult& statusCode)
   1.295 +{
   1.296 +  if (mEventQ->ShouldEnqueue()) {
   1.297 +    mEventQ->Enqueue(new WyciwygCancelEvent(this, statusCode));
   1.298 +  } else {
   1.299 +    CancelEarly(statusCode);
   1.300 +  }
   1.301 +  return true;
   1.302 +}
   1.303 +
   1.304 +void WyciwygChannelChild::CancelEarly(const nsresult& statusCode)
   1.305 +{
   1.306 +  LOG(("WyciwygChannelChild::CancelEarly [this=%p]\n", this));
   1.307 +  
   1.308 +  if (mCanceled)
   1.309 +    return;
   1.310 +
   1.311 +  mCanceled = true;
   1.312 +  mStatus = statusCode;
   1.313 +  
   1.314 +  mIsPending = false;
   1.315 +  if (mLoadGroup)
   1.316 +    mLoadGroup->RemoveRequest(this, nullptr, mStatus);
   1.317 +
   1.318 +  if (mListener) {
   1.319 +    mListener->OnStartRequest(this, mListenerContext);
   1.320 +    mListener->OnStopRequest(this, mListenerContext, mStatus);
   1.321 +  }
   1.322 +  mListener = nullptr;
   1.323 +  mListenerContext = nullptr;
   1.324 +
   1.325 +  if (mIPCOpen)
   1.326 +    PWyciwygChannelChild::Send__delete__(this);
   1.327 +}
   1.328 +
   1.329 +//-----------------------------------------------------------------------------
   1.330 +// nsIRequest
   1.331 +//-----------------------------------------------------------------------------
   1.332 +
   1.333 +/* readonly attribute AUTF8String name; */
   1.334 +NS_IMETHODIMP
   1.335 +WyciwygChannelChild::GetName(nsACString & aName)
   1.336 +{
   1.337 +  return mURI->GetSpec(aName);
   1.338 +}
   1.339 +
   1.340 +/* boolean isPending (); */
   1.341 +NS_IMETHODIMP
   1.342 +WyciwygChannelChild::IsPending(bool *aIsPending)
   1.343 +{
   1.344 +  *aIsPending = mIsPending;
   1.345 +  return NS_OK;
   1.346 +}
   1.347 +
   1.348 +/* readonly attribute nsresult status; */
   1.349 +NS_IMETHODIMP
   1.350 +WyciwygChannelChild::GetStatus(nsresult *aStatus)
   1.351 +{
   1.352 +  *aStatus = mStatus;
   1.353 +  return NS_OK;
   1.354 +}
   1.355 +
   1.356 +/* void cancel (in nsresult aStatus); */
   1.357 +NS_IMETHODIMP
   1.358 +WyciwygChannelChild::Cancel(nsresult aStatus)
   1.359 +{
   1.360 +  if (mCanceled)
   1.361 +    return NS_OK;
   1.362 +
   1.363 +  mCanceled = true;
   1.364 +  mStatus = aStatus;
   1.365 +  if (mIPCOpen)
   1.366 +    SendCancel(aStatus);
   1.367 +  return NS_OK;
   1.368 +}
   1.369 +
   1.370 +/* void suspend (); */
   1.371 +NS_IMETHODIMP
   1.372 +WyciwygChannelChild::Suspend()
   1.373 +{
   1.374 +  return NS_ERROR_NOT_IMPLEMENTED;
   1.375 +}
   1.376 +
   1.377 +/* void resume (); */
   1.378 +NS_IMETHODIMP
   1.379 +WyciwygChannelChild::Resume()
   1.380 +{
   1.381 +  return NS_ERROR_NOT_IMPLEMENTED;
   1.382 +}
   1.383 +
   1.384 +/* attribute nsILoadGroup loadGroup; */
   1.385 +NS_IMETHODIMP
   1.386 +WyciwygChannelChild::GetLoadGroup(nsILoadGroup * *aLoadGroup)
   1.387 +{
   1.388 +  *aLoadGroup = mLoadGroup;
   1.389 +  NS_IF_ADDREF(*aLoadGroup);
   1.390 +  return NS_OK;
   1.391 +}
   1.392 +NS_IMETHODIMP
   1.393 +WyciwygChannelChild::SetLoadGroup(nsILoadGroup * aLoadGroup)
   1.394 +{
   1.395 +  if (!CanSetLoadGroup(aLoadGroup)) {
   1.396 +    return NS_ERROR_FAILURE;
   1.397 +  }
   1.398 +
   1.399 +  mLoadGroup = aLoadGroup;
   1.400 +  NS_QueryNotificationCallbacks(mCallbacks,
   1.401 +                                mLoadGroup,
   1.402 +                                NS_GET_IID(nsIProgressEventSink),
   1.403 +                                getter_AddRefs(mProgressSink));
   1.404 +  return NS_OK;
   1.405 +}
   1.406 +
   1.407 +/* attribute nsLoadFlags loadFlags; */
   1.408 +NS_IMETHODIMP
   1.409 +WyciwygChannelChild::GetLoadFlags(nsLoadFlags *aLoadFlags)
   1.410 +{
   1.411 +  *aLoadFlags = mLoadFlags;
   1.412 +  return NS_OK;
   1.413 +}
   1.414 +NS_IMETHODIMP
   1.415 +WyciwygChannelChild::SetLoadFlags(nsLoadFlags aLoadFlags)
   1.416 +{
   1.417 +  mLoadFlags = aLoadFlags;
   1.418 +  return NS_OK;
   1.419 +}
   1.420 +
   1.421 +
   1.422 +//-----------------------------------------------------------------------------
   1.423 +// nsIChannel
   1.424 +//-----------------------------------------------------------------------------
   1.425 +
   1.426 +/* attribute nsIURI originalURI; */
   1.427 +NS_IMETHODIMP
   1.428 +WyciwygChannelChild::GetOriginalURI(nsIURI * *aOriginalURI)
   1.429 +{
   1.430 +  *aOriginalURI = mOriginalURI;
   1.431 +  NS_ADDREF(*aOriginalURI);
   1.432 +  return NS_OK;
   1.433 +}
   1.434 +NS_IMETHODIMP
   1.435 +WyciwygChannelChild::SetOriginalURI(nsIURI * aOriginalURI)
   1.436 +{
   1.437 +  NS_ENSURE_TRUE(mState == WCC_INIT, NS_ERROR_UNEXPECTED);
   1.438 +
   1.439 +  NS_ENSURE_ARG_POINTER(aOriginalURI);
   1.440 +  mOriginalURI = aOriginalURI;
   1.441 +  return NS_OK;
   1.442 +}
   1.443 +
   1.444 +/* readonly attribute nsIURI URI; */
   1.445 +NS_IMETHODIMP
   1.446 +WyciwygChannelChild::GetURI(nsIURI * *aURI)
   1.447 +{
   1.448 +  *aURI = mURI;
   1.449 +  NS_IF_ADDREF(*aURI);
   1.450 +  return NS_OK;
   1.451 +}
   1.452 +
   1.453 +/* attribute nsISupports owner; */
   1.454 +NS_IMETHODIMP
   1.455 +WyciwygChannelChild::GetOwner(nsISupports * *aOwner)
   1.456 +{
   1.457 +  NS_PRECONDITION(mOwner, "Must have a principal!");
   1.458 +  NS_ENSURE_STATE(mOwner);
   1.459 +
   1.460 +  NS_ADDREF(*aOwner = mOwner);
   1.461 +  return NS_OK;
   1.462 +}
   1.463 +NS_IMETHODIMP
   1.464 +WyciwygChannelChild::SetOwner(nsISupports * aOwner)
   1.465 +{
   1.466 +  mOwner = aOwner;
   1.467 +  return NS_OK;
   1.468 +}
   1.469 +
   1.470 +/* attribute nsIInterfaceRequestor notificationCallbacks; */
   1.471 +NS_IMETHODIMP
   1.472 +WyciwygChannelChild::GetNotificationCallbacks(nsIInterfaceRequestor * *aCallbacks)
   1.473 +{
   1.474 +  *aCallbacks = mCallbacks;
   1.475 +  NS_IF_ADDREF(*aCallbacks);
   1.476 +  return NS_OK;
   1.477 +}
   1.478 +NS_IMETHODIMP
   1.479 +WyciwygChannelChild::SetNotificationCallbacks(nsIInterfaceRequestor * aCallbacks)
   1.480 +{
   1.481 +  if (!CanSetCallbacks(aCallbacks)) {
   1.482 +    return NS_ERROR_FAILURE;
   1.483 +  }
   1.484 +
   1.485 +  mCallbacks = aCallbacks;
   1.486 +  NS_QueryNotificationCallbacks(mCallbacks,
   1.487 +                                mLoadGroup,
   1.488 +                                NS_GET_IID(nsIProgressEventSink),
   1.489 +                                getter_AddRefs(mProgressSink));
   1.490 +  return NS_OK;
   1.491 +}
   1.492 +
   1.493 +/* readonly attribute nsISupports securityInfo; */
   1.494 +NS_IMETHODIMP
   1.495 +WyciwygChannelChild::GetSecurityInfo(nsISupports * *aSecurityInfo)
   1.496 +{
   1.497 +  NS_IF_ADDREF(*aSecurityInfo = mSecurityInfo);
   1.498 +
   1.499 +  return NS_OK;
   1.500 +}
   1.501 +
   1.502 +/* attribute ACString contentType; */
   1.503 +NS_IMETHODIMP
   1.504 +WyciwygChannelChild::GetContentType(nsACString & aContentType)
   1.505 +{
   1.506 +  aContentType.AssignLiteral(WYCIWYG_TYPE);
   1.507 +  return NS_OK;
   1.508 +}
   1.509 +NS_IMETHODIMP
   1.510 +WyciwygChannelChild::SetContentType(const nsACString & aContentType)
   1.511 +{
   1.512 +  return NS_ERROR_NOT_IMPLEMENTED;
   1.513 +}
   1.514 +
   1.515 +/* attribute ACString contentCharset; */
   1.516 +NS_IMETHODIMP
   1.517 +WyciwygChannelChild::GetContentCharset(nsACString & aContentCharset)
   1.518 +{
   1.519 +  aContentCharset.Assign("UTF-16");
   1.520 +  return NS_OK;
   1.521 +}
   1.522 +NS_IMETHODIMP
   1.523 +WyciwygChannelChild::SetContentCharset(const nsACString & aContentCharset)
   1.524 +{
   1.525 +  return NS_ERROR_NOT_IMPLEMENTED;
   1.526 +}
   1.527 +
   1.528 +NS_IMETHODIMP
   1.529 +WyciwygChannelChild::GetContentDisposition(uint32_t *aContentDisposition)
   1.530 +{
   1.531 +  return NS_ERROR_NOT_AVAILABLE;
   1.532 +}
   1.533 +
   1.534 +NS_IMETHODIMP
   1.535 +WyciwygChannelChild::SetContentDisposition(uint32_t aContentDisposition)
   1.536 +{
   1.537 +  return NS_ERROR_NOT_AVAILABLE;
   1.538 +}
   1.539 +
   1.540 +NS_IMETHODIMP
   1.541 +WyciwygChannelChild::GetContentDispositionFilename(nsAString &aContentDispositionFilename)
   1.542 +{
   1.543 +  return NS_ERROR_NOT_AVAILABLE;
   1.544 +}
   1.545 +
   1.546 +NS_IMETHODIMP
   1.547 +WyciwygChannelChild::SetContentDispositionFilename(const nsAString &aContentDispositionFilename)
   1.548 +{
   1.549 +  return NS_ERROR_NOT_AVAILABLE;
   1.550 +}
   1.551 +
   1.552 +NS_IMETHODIMP
   1.553 +WyciwygChannelChild::GetContentDispositionHeader(nsACString &aContentDispositionHeader)
   1.554 +{
   1.555 +  return NS_ERROR_NOT_AVAILABLE;
   1.556 +}
   1.557 +
   1.558 +/* attribute int64_t contentLength; */
   1.559 +NS_IMETHODIMP
   1.560 +WyciwygChannelChild::GetContentLength(int64_t *aContentLength)
   1.561 +{
   1.562 +  return NS_ERROR_NOT_IMPLEMENTED;
   1.563 +}
   1.564 +NS_IMETHODIMP
   1.565 +WyciwygChannelChild::SetContentLength(int64_t aContentLength)
   1.566 +{
   1.567 +  return NS_ERROR_NOT_IMPLEMENTED;
   1.568 +}
   1.569 +
   1.570 +/* nsIInputStream open (); */
   1.571 +NS_IMETHODIMP
   1.572 +WyciwygChannelChild::Open(nsIInputStream **_retval)
   1.573 +{
   1.574 +  return NS_ERROR_NOT_IMPLEMENTED;
   1.575 +}
   1.576 +
   1.577 +static mozilla::dom::TabChild*
   1.578 +GetTabChild(nsIChannel* aChannel)
   1.579 +{
   1.580 +  nsCOMPtr<nsITabChild> iTabChild;
   1.581 +  NS_QueryNotificationCallbacks(aChannel, iTabChild);
   1.582 +  return iTabChild ? static_cast<mozilla::dom::TabChild*>(iTabChild.get()) : nullptr;
   1.583 +}
   1.584 +
   1.585 +/* void asyncOpen (in nsIStreamListener aListener, in nsISupports aContext); */
   1.586 +NS_IMETHODIMP
   1.587 +WyciwygChannelChild::AsyncOpen(nsIStreamListener *aListener, nsISupports *aContext)
   1.588 +{
   1.589 +  LOG(("WyciwygChannelChild::AsyncOpen [this=%p]\n", this));
   1.590 +
   1.591 +  // The only places creating wyciwyg: channels should be
   1.592 +  // HTMLDocument::OpenCommon and session history.  Both should be setting an
   1.593 +  // owner.
   1.594 +  NS_PRECONDITION(mOwner, "Must have a principal");
   1.595 +  NS_ENSURE_STATE(mOwner);
   1.596 +
   1.597 +  NS_ENSURE_ARG_POINTER(aListener);
   1.598 +  NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
   1.599 +
   1.600 +  mListener = aListener;
   1.601 +  mListenerContext = aContext;
   1.602 +  mIsPending = true;
   1.603 +
   1.604 +  if (mLoadGroup)
   1.605 +    mLoadGroup->AddRequest(this, nullptr);
   1.606 +
   1.607 +  URIParams originalURI;
   1.608 +  SerializeURI(mOriginalURI, originalURI);
   1.609 +
   1.610 +  mozilla::dom::TabChild* tabChild = GetTabChild(this);
   1.611 +  if (MissingRequiredTabChild(tabChild, "wyciwyg")) {
   1.612 +    return NS_ERROR_ILLEGAL_VALUE;
   1.613 +  }
   1.614 +
   1.615 +  SendAsyncOpen(originalURI, mLoadFlags, IPC::SerializedLoadContext(this), tabChild);
   1.616 +
   1.617 +  mSentAppData = true;
   1.618 +  mState = WCC_OPENED;
   1.619 +
   1.620 +  return NS_OK;
   1.621 +}
   1.622 +
   1.623 +//-----------------------------------------------------------------------------
   1.624 +// nsIWyciwygChannel
   1.625 +//-----------------------------------------------------------------------------
   1.626 +
   1.627 +/* void writeToCacheEntry (in AString aData); */
   1.628 +NS_IMETHODIMP
   1.629 +WyciwygChannelChild::WriteToCacheEntry(const nsAString & aData)
   1.630 +{
   1.631 +  NS_ENSURE_TRUE((mState == WCC_INIT) ||
   1.632 +                 (mState == WCC_ONWRITE), NS_ERROR_UNEXPECTED);
   1.633 +
   1.634 +  if (!mSentAppData) {
   1.635 +    mozilla::dom::TabChild* tabChild = GetTabChild(this);
   1.636 +    SendAppData(IPC::SerializedLoadContext(this), tabChild);
   1.637 +    mSentAppData = true;
   1.638 +  }
   1.639 +
   1.640 +  SendWriteToCacheEntry(PromiseFlatString(aData));
   1.641 +  mState = WCC_ONWRITE;
   1.642 +  return NS_OK;
   1.643 +}
   1.644 +
   1.645 +/* void closeCacheEntry (in nsresult reason); */
   1.646 +NS_IMETHODIMP
   1.647 +WyciwygChannelChild::CloseCacheEntry(nsresult reason)
   1.648 +{
   1.649 +  NS_ENSURE_TRUE(mState == WCC_ONWRITE, NS_ERROR_UNEXPECTED);
   1.650 +
   1.651 +  SendCloseCacheEntry(reason);
   1.652 +  mState = WCC_ONCLOSED;
   1.653 +
   1.654 +  if (mIPCOpen)
   1.655 +    PWyciwygChannelChild::Send__delete__(this);
   1.656 +
   1.657 +  return NS_OK;
   1.658 +}
   1.659 +
   1.660 +/* void setSecurityInfo (in nsISupports aSecurityInfo); */
   1.661 +NS_IMETHODIMP
   1.662 +WyciwygChannelChild::SetSecurityInfo(nsISupports *aSecurityInfo)
   1.663 +{
   1.664 +  mSecurityInfo = aSecurityInfo;
   1.665 +
   1.666 +  if (mSecurityInfo) {
   1.667 +    nsCOMPtr<nsISerializable> serializable = do_QueryInterface(mSecurityInfo);
   1.668 +    if (serializable) {
   1.669 +      nsCString secInfoStr;
   1.670 +      NS_SerializeToString(serializable, secInfoStr);
   1.671 +      SendSetSecurityInfo(secInfoStr);
   1.672 +    }
   1.673 +    else {
   1.674 +      NS_WARNING("Can't serialize security info");
   1.675 +    }
   1.676 +  }
   1.677 +
   1.678 +  return NS_OK;
   1.679 +}
   1.680 +
   1.681 +/* void setCharsetAndSource (in long aSource, in ACString aCharset); */
   1.682 +NS_IMETHODIMP
   1.683 +WyciwygChannelChild::SetCharsetAndSource(int32_t aSource, const nsACString & aCharset)
   1.684 +{
   1.685 +  // mState == WCC_ONSTART when reading from the channel
   1.686 +  // mState == WCC_INIT when writing to the cache
   1.687 +  NS_ENSURE_TRUE((mState == WCC_ONSTART) ||
   1.688 +                 (mState == WCC_INIT), NS_ERROR_UNEXPECTED);
   1.689 +
   1.690 +  mCharsetSource = aSource;
   1.691 +  mCharset = aCharset;
   1.692 +
   1.693 +  // TODO ensure that nsWyciwygChannel in the parent has still the cache entry
   1.694 +  SendSetCharsetAndSource(mCharsetSource, mCharset);
   1.695 +  return NS_OK;
   1.696 +}
   1.697 +
   1.698 +/* ACString getCharsetAndSource (out long aSource); */
   1.699 +NS_IMETHODIMP
   1.700 +WyciwygChannelChild::GetCharsetAndSource(int32_t *aSource, nsACString & _retval)
   1.701 +{
   1.702 +  NS_ENSURE_TRUE((mState == WCC_ONSTART) ||
   1.703 +                 (mState == WCC_ONDATA) ||
   1.704 +                 (mState == WCC_ONSTOP), NS_ERROR_NOT_AVAILABLE);
   1.705 +
   1.706 +  if (mCharsetSource == kCharsetUninitialized)
   1.707 +    return NS_ERROR_NOT_AVAILABLE;
   1.708 +
   1.709 +  *aSource = mCharsetSource;
   1.710 +  _retval = mCharset;
   1.711 +  return NS_OK;
   1.712 +}
   1.713 +
   1.714 +//------------------------------------------------------------------------------
   1.715 +}} // mozilla::net

mercurial