Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 : *
3 : * This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #include "nsContentUtils.h"
8 : #include "nsWyciwyg.h"
9 : #include "nsWyciwygChannel.h"
10 : #include "nsWyciwygProtocolHandler.h"
11 : #include "nsNetCID.h"
12 : #include "nsServiceManagerUtils.h"
13 : #include "plstr.h"
14 : #include "nsIObserverService.h"
15 : #include "nsIURI.h"
16 :
17 : #include "mozilla/net/NeckoChild.h"
18 :
19 : using namespace mozilla::net;
20 : #include "mozilla/net/WyciwygChannelChild.h"
21 :
22 : ////////////////////////////////////////////////////////////////////////////////
23 :
24 0 : nsWyciwygProtocolHandler::nsWyciwygProtocolHandler()
25 : {
26 0 : LOG(("Creating nsWyciwygProtocolHandler [this=%p].\n", this));
27 0 : }
28 :
29 0 : nsWyciwygProtocolHandler::~nsWyciwygProtocolHandler()
30 : {
31 0 : LOG(("Deleting nsWyciwygProtocolHandler [this=%p]\n", this));
32 0 : }
33 :
34 0 : NS_IMPL_ISUPPORTS(nsWyciwygProtocolHandler,
35 : nsIProtocolHandler)
36 :
37 : ////////////////////////////////////////////////////////////////////////////////
38 : // nsIProtocolHandler methods:
39 : ////////////////////////////////////////////////////////////////////////////////
40 :
41 : NS_IMETHODIMP
42 0 : nsWyciwygProtocolHandler::GetScheme(nsACString &result)
43 : {
44 0 : result = "wyciwyg";
45 0 : return NS_OK;
46 : }
47 :
48 : NS_IMETHODIMP
49 0 : nsWyciwygProtocolHandler::GetDefaultPort(int32_t *result)
50 : {
51 0 : return NS_ERROR_NOT_AVAILABLE;
52 : }
53 :
54 : NS_IMETHODIMP
55 0 : nsWyciwygProtocolHandler::AllowPort(int32_t port, const char *scheme, bool *_retval)
56 : {
57 : // don't override anything.
58 0 : *_retval = false;
59 0 : return NS_OK;
60 : }
61 :
62 : NS_IMETHODIMP
63 0 : nsWyciwygProtocolHandler::NewURI(const nsACString &aSpec,
64 : const char *aCharset, // ignored
65 : nsIURI *aBaseURI,
66 : nsIURI **result)
67 : {
68 : nsresult rv;
69 :
70 0 : nsCOMPtr<nsIURI> url = do_CreateInstance(NS_SIMPLEURI_CONTRACTID, &rv);
71 0 : NS_ENSURE_SUCCESS(rv, rv);
72 :
73 0 : rv = url->SetSpec(aSpec);
74 0 : NS_ENSURE_SUCCESS(rv, rv);
75 :
76 0 : url.forget(result);
77 :
78 0 : return rv;
79 : }
80 :
81 : NS_IMETHODIMP
82 0 : nsWyciwygProtocolHandler::NewChannel2(nsIURI* url,
83 : nsILoadInfo* aLoadInfo,
84 : nsIChannel** result)
85 : {
86 0 : if (mozilla::net::IsNeckoChild())
87 0 : mozilla::net::NeckoChild::InitNeckoChild();
88 :
89 0 : NS_ENSURE_ARG_POINTER(url);
90 : nsresult rv;
91 :
92 0 : nsCOMPtr<nsIWyciwygChannel> channel;
93 0 : if (IsNeckoChild()) {
94 0 : NS_ENSURE_TRUE(gNeckoChild != nullptr, NS_ERROR_FAILURE);
95 :
96 0 : ContentChild* cc = static_cast<ContentChild*>(gNeckoChild->Manager());
97 0 : if (cc->IsShuttingDown()) {
98 0 : return NS_ERROR_FAILURE;
99 : }
100 :
101 : nsCOMPtr<nsIEventTarget> target =
102 0 : nsContentUtils::GetEventTargetByLoadInfo(aLoadInfo,
103 0 : mozilla::TaskCategory::Other);
104 0 : WyciwygChannelChild *wcc = new WyciwygChannelChild(target);
105 :
106 0 : if (!wcc)
107 0 : return NS_ERROR_OUT_OF_MEMORY;
108 :
109 0 : channel = wcc;
110 0 : rv = wcc->Init(url);
111 0 : if (NS_FAILED(rv))
112 0 : PWyciwygChannelChild::Send__delete__(wcc);
113 : } else
114 : {
115 : // If original channel used https, make sure PSM is initialized
116 : // (this may be first channel to load during a session restore)
117 0 : nsAutoCString path;
118 0 : rv = url->GetPath(path);
119 0 : NS_ENSURE_SUCCESS(rv, rv);
120 0 : int32_t slashIndex = path.FindChar('/', 2);
121 0 : if (slashIndex == kNotFound)
122 0 : return NS_ERROR_FAILURE;
123 0 : if (path.Length() < (uint32_t)slashIndex + 1 + 5)
124 0 : return NS_ERROR_FAILURE;
125 0 : if (!PL_strncasecmp(path.get() + slashIndex + 1, "https", 5))
126 0 : net_EnsurePSMInit();
127 :
128 0 : nsWyciwygChannel *wc = new nsWyciwygChannel();
129 0 : channel = wc;
130 0 : rv = wc->Init(url);
131 : }
132 :
133 0 : if (NS_FAILED(rv))
134 0 : return rv;
135 :
136 : // set the loadInfo on the new channel
137 0 : rv = channel->SetLoadInfo(aLoadInfo);
138 0 : if (NS_FAILED(rv)) {
139 0 : return rv;
140 : }
141 :
142 0 : channel.forget(result);
143 0 : return NS_OK;
144 : }
145 :
146 : NS_IMETHODIMP
147 0 : nsWyciwygProtocolHandler::NewChannel(nsIURI* url, nsIChannel* *result)
148 : {
149 0 : return NewChannel2(url, nullptr, result);
150 : }
151 :
152 : NS_IMETHODIMP
153 0 : nsWyciwygProtocolHandler::GetProtocolFlags(uint32_t *result)
154 : {
155 : // Should this be an an nsINestedURI? We don't really want random webpages
156 : // loading these URIs...
157 :
158 : // Note that using URI_INHERITS_SECURITY_CONTEXT here is OK -- untrusted code
159 : // is not allowed to link to wyciwyg URIs and users shouldn't be able to get
160 : // at them, and nsDocShell::InternalLoad forbids non-history loads of these
161 : // URIs. And when loading from history we end up using the principal from
162 : // the history entry, which we put there ourselves, so all is ok.
163 0 : *result = URI_NORELATIVE | URI_NOAUTH | URI_DANGEROUS_TO_LOAD |
164 : URI_INHERITS_SECURITY_CONTEXT;
165 0 : return NS_OK;
166 : }
|