1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #include "base/basictypes.h"
7 
8 #include "nsNetCID.h"
9 #include "nsNetUtil.h"
10 #include "nsSimpleNestedURI.h"
11 #include "nsIObjectInputStream.h"
12 #include "nsIObjectOutputStream.h"
13 
14 #include "mozilla/ipc/URIUtils.h"
15 
16 namespace mozilla {
17 namespace net {
18 
NS_IMPL_CLASSINFO(nsSimpleNestedURI,nullptr,nsIClassInfo::THREADSAFE,NS_SIMPLENESTEDURI_CID)19 NS_IMPL_CLASSINFO(nsSimpleNestedURI, nullptr, nsIClassInfo::THREADSAFE,
20                   NS_SIMPLENESTEDURI_CID)
21 // Empty CI getter. We only need nsIClassInfo for Serialization
22 NS_IMPL_CI_INTERFACE_GETTER0(nsSimpleNestedURI)
23 
24 NS_IMPL_ADDREF_INHERITED(nsSimpleNestedURI, nsSimpleURI)
25 NS_IMPL_RELEASE_INHERITED(nsSimpleNestedURI, nsSimpleURI)
26 NS_IMPL_QUERY_INTERFACE_CI_INHERITED(nsSimpleNestedURI, nsSimpleURI,
27                                      nsINestedURI)
28 
29 nsSimpleNestedURI::nsSimpleNestedURI(nsIURI* innerURI) : mInnerURI(innerURI) {
30   NS_ASSERTION(innerURI, "Must have inner URI");
31 }
32 
SetPathQueryRef(const nsACString & aPathQueryRef)33 nsresult nsSimpleNestedURI::SetPathQueryRef(const nsACString& aPathQueryRef) {
34   NS_ENSURE_TRUE(mInnerURI, NS_ERROR_NOT_INITIALIZED);
35 
36   nsCOMPtr<nsIURI> inner;
37   nsresult rv =
38       NS_MutateURI(mInnerURI).SetPathQueryRef(aPathQueryRef).Finalize(inner);
39   NS_ENSURE_SUCCESS(rv, rv);
40   rv = nsSimpleURI::SetPathQueryRef(aPathQueryRef);
41   NS_ENSURE_SUCCESS(rv, rv);
42   // If the regular SetPathQueryRef worked, also set it on the inner URI
43   mInnerURI = inner;
44   return NS_OK;
45 }
46 
SetQuery(const nsACString & aQuery)47 nsresult nsSimpleNestedURI::SetQuery(const nsACString& aQuery) {
48   NS_ENSURE_TRUE(mInnerURI, NS_ERROR_NOT_INITIALIZED);
49 
50   nsCOMPtr<nsIURI> inner;
51   nsresult rv = NS_MutateURI(mInnerURI).SetQuery(aQuery).Finalize(inner);
52   NS_ENSURE_SUCCESS(rv, rv);
53   rv = nsSimpleURI::SetQuery(aQuery);
54   NS_ENSURE_SUCCESS(rv, rv);
55   // If the regular SetQuery worked, also set it on the inner URI
56   mInnerURI = inner;
57   return NS_OK;
58 }
59 
SetRef(const nsACString & aRef)60 nsresult nsSimpleNestedURI::SetRef(const nsACString& aRef) {
61   NS_ENSURE_TRUE(mInnerURI, NS_ERROR_NOT_INITIALIZED);
62 
63   nsCOMPtr<nsIURI> inner;
64   nsresult rv = NS_MutateURI(mInnerURI).SetRef(aRef).Finalize(inner);
65   NS_ENSURE_SUCCESS(rv, rv);
66   rv = nsSimpleURI::SetRef(aRef);
67   NS_ENSURE_SUCCESS(rv, rv);
68   // If the regular SetRef worked, also set it on the inner URI
69   mInnerURI = inner;
70   return NS_OK;
71 }
72 
73 // nsISerializable
74 
75 NS_IMETHODIMP
Read(nsIObjectInputStream * aStream)76 nsSimpleNestedURI::Read(nsIObjectInputStream* aStream) {
77   MOZ_ASSERT_UNREACHABLE("Use nsIURIMutator.read() instead");
78   return NS_ERROR_NOT_IMPLEMENTED;
79 }
80 
ReadPrivate(nsIObjectInputStream * aStream)81 nsresult nsSimpleNestedURI::ReadPrivate(nsIObjectInputStream* aStream) {
82   nsresult rv = nsSimpleURI::ReadPrivate(aStream);
83   if (NS_FAILED(rv)) return rv;
84 
85   nsCOMPtr<nsISupports> supports;
86   rv = aStream->ReadObject(true, getter_AddRefs(supports));
87   if (NS_FAILED(rv)) return rv;
88 
89   mInnerURI = do_QueryInterface(supports, &rv);
90   if (NS_FAILED(rv)) return rv;
91 
92   return rv;
93 }
94 
95 NS_IMETHODIMP
Write(nsIObjectOutputStream * aStream)96 nsSimpleNestedURI::Write(nsIObjectOutputStream* aStream) {
97   nsCOMPtr<nsISerializable> serializable = do_QueryInterface(mInnerURI);
98   if (!serializable) {
99     // We can't serialize ourselves
100     return NS_ERROR_NOT_AVAILABLE;
101   }
102 
103   nsresult rv = nsSimpleURI::Write(aStream);
104   if (NS_FAILED(rv)) return rv;
105 
106   rv = aStream->WriteCompoundObject(mInnerURI, NS_GET_IID(nsIURI), true);
107   return rv;
108 }
109 
NS_IMETHODIMP_(void)110 NS_IMETHODIMP_(void)
111 nsSimpleNestedURI::Serialize(mozilla::ipc::URIParams& aParams) {
112   using namespace mozilla::ipc;
113 
114   SimpleNestedURIParams params;
115   URIParams simpleParams;
116 
117   nsSimpleURI::Serialize(simpleParams);
118   params.simpleParams() = simpleParams;
119 
120   SerializeURI(mInnerURI, params.innerURI());
121 
122   aParams = params;
123 }
124 
Deserialize(const mozilla::ipc::URIParams & aParams)125 bool nsSimpleNestedURI::Deserialize(const mozilla::ipc::URIParams& aParams) {
126   using namespace mozilla::ipc;
127 
128   if (aParams.type() != URIParams::TSimpleNestedURIParams) {
129     NS_ERROR("Received unknown parameters from the other process!");
130     return false;
131   }
132 
133   const SimpleNestedURIParams& params = aParams.get_SimpleNestedURIParams();
134   if (!nsSimpleURI::Deserialize(params.simpleParams())) return false;
135 
136   mInnerURI = DeserializeURI(params.innerURI());
137   return true;
138 }
139 
140 // nsINestedURI
141 
142 NS_IMETHODIMP
GetInnerURI(nsIURI ** aURI)143 nsSimpleNestedURI::GetInnerURI(nsIURI** aURI) {
144   NS_ENSURE_TRUE(mInnerURI, NS_ERROR_NOT_INITIALIZED);
145 
146   nsCOMPtr<nsIURI> uri = mInnerURI;
147   uri.forget(aURI);
148   return NS_OK;
149 }
150 
151 NS_IMETHODIMP
GetInnermostURI(nsIURI ** uri)152 nsSimpleNestedURI::GetInnermostURI(nsIURI** uri) {
153   return NS_ImplGetInnermostURI(this, uri);
154 }
155 
156 // nsSimpleURI overrides
157 /* virtual */
EqualsInternal(nsIURI * other,nsSimpleURI::RefHandlingEnum refHandlingMode,bool * result)158 nsresult nsSimpleNestedURI::EqualsInternal(
159     nsIURI* other, nsSimpleURI::RefHandlingEnum refHandlingMode, bool* result) {
160   *result = false;
161   NS_ENSURE_TRUE(mInnerURI, NS_ERROR_NOT_INITIALIZED);
162 
163   if (other) {
164     bool correctScheme;
165     nsresult rv = other->SchemeIs(mScheme.get(), &correctScheme);
166     NS_ENSURE_SUCCESS(rv, rv);
167 
168     if (correctScheme) {
169       nsCOMPtr<nsINestedURI> nest = do_QueryInterface(other);
170       if (nest) {
171         nsCOMPtr<nsIURI> otherInner;
172         rv = nest->GetInnerURI(getter_AddRefs(otherInner));
173         NS_ENSURE_SUCCESS(rv, rv);
174 
175         return (refHandlingMode == eHonorRef)
176                    ? otherInner->Equals(mInnerURI, result)
177                    : otherInner->EqualsExceptRef(mInnerURI, result);
178       }
179     }
180   }
181 
182   return NS_OK;
183 }
184 
185 /* virtual */
StartClone(nsSimpleURI::RefHandlingEnum refHandlingMode,const nsACString & newRef)186 nsSimpleURI* nsSimpleNestedURI::StartClone(
187     nsSimpleURI::RefHandlingEnum refHandlingMode, const nsACString& newRef) {
188   NS_ENSURE_TRUE(mInnerURI, nullptr);
189 
190   nsCOMPtr<nsIURI> innerClone;
191   nsresult rv = NS_OK;
192   if (refHandlingMode == eHonorRef) {
193     innerClone = mInnerURI;
194   } else if (refHandlingMode == eReplaceRef) {
195     rv = NS_GetURIWithNewRef(mInnerURI, newRef, getter_AddRefs(innerClone));
196   } else {
197     rv = NS_GetURIWithoutRef(mInnerURI, getter_AddRefs(innerClone));
198   }
199 
200   if (NS_FAILED(rv)) {
201     return nullptr;
202   }
203 
204   nsSimpleNestedURI* url = new nsSimpleNestedURI(innerClone);
205   SetRefOnClone(url, refHandlingMode, newRef);
206 
207   return url;
208 }
209 
210 // Queries this list of interfaces. If none match, it queries mURI.
NS_IMPL_NSIURIMUTATOR_ISUPPORTS(nsSimpleNestedURI::Mutator,nsIURISetters,nsIURIMutator,nsISerializable,nsINestedURIMutator)211 NS_IMPL_NSIURIMUTATOR_ISUPPORTS(nsSimpleNestedURI::Mutator, nsIURISetters,
212                                 nsIURIMutator, nsISerializable,
213                                 nsINestedURIMutator)
214 
215 NS_IMETHODIMP
216 nsSimpleNestedURI::Mutate(nsIURIMutator** aMutator) {
217   RefPtr<nsSimpleNestedURI::Mutator> mutator = new nsSimpleNestedURI::Mutator();
218   nsresult rv = mutator->InitFromURI(this);
219   if (NS_FAILED(rv)) {
220     return rv;
221   }
222   mutator.forget(aMutator);
223   return NS_OK;
224 }
225 
226 }  // namespace net
227 }  // namespace mozilla
228