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