1 /* -*- Mode: C++; tab-width: 2; 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 #ifndef nsSimpleURI_h__
7 #define nsSimpleURI_h__
8 
9 #include "mozilla/MemoryReporting.h"
10 #include "nsIURI.h"
11 #include "nsISerializable.h"
12 #include "nsString.h"
13 #include "nsIClassInfo.h"
14 #include "nsISizeOf.h"
15 #include "nsIURIMutator.h"
16 #include "nsISimpleURIMutator.h"
17 
18 namespace mozilla {
19 namespace net {
20 
21 #define NS_THIS_SIMPLEURI_IMPLEMENTATION_CID         \
22   { /* 0b9bb0c2-fee6-470b-b9b9-9fd9462b5e19 */       \
23     0x0b9bb0c2, 0xfee6, 0x470b, {                    \
24       0xb9, 0xb9, 0x9f, 0xd9, 0x46, 0x2b, 0x5e, 0x19 \
25     }                                                \
26   }
27 
28 class nsSimpleURI : public nsIURI, public nsISerializable, public nsISizeOf {
29  protected:
30   nsSimpleURI() = default;
31   virtual ~nsSimpleURI() = default;
32 
33  public:
34   NS_DECL_THREADSAFE_ISUPPORTS
35   NS_DECL_NSIURI
36   NS_DECL_NSISERIALIZABLE
37 
38   static already_AddRefed<nsSimpleURI> From(nsIURI* aURI);
39 
40   // nsSimpleURI methods:
41 
Equals(nsSimpleURI * aOther)42   bool Equals(nsSimpleURI* aOther) { return EqualsInternal(aOther, eHonorRef); }
43 
44   // nsISizeOf
45   // Among the sub-classes that inherit (directly or indirectly) from
46   // nsSimpleURI, measurement of the following members may be added later if
47   // DMD finds it is worthwhile:
48   // - nsJSURI: mBaseURI
49   // - nsSimpleNestedURI: mInnerURI
50   // - nsBlobURI: mPrincipal
51   virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
52   virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
53 
54  protected:
55   // enum used in a few places to specify how .ref attribute should be handled
56   enum RefHandlingEnum { eIgnoreRef, eHonorRef, eReplaceRef };
57 
58   virtual nsresult Clone(nsIURI** result);
59   virtual nsresult SetSpecInternal(const nsACString& aSpec,
60                                    bool aStripWhitespace = false);
61   virtual nsresult SetScheme(const nsACString& scheme);
62   virtual nsresult SetUserPass(const nsACString& input);
63   nsresult SetUsername(const nsACString& input);
64   virtual nsresult SetPassword(const nsACString& input);
65   virtual nsresult SetHostPort(const nsACString& aValue);
66   virtual nsresult SetHost(const nsACString& input);
67   virtual nsresult SetPort(int32_t port);
68   virtual nsresult SetPathQueryRef(const nsACString& aPath);
69   virtual nsresult SetRef(const nsACString& aRef);
70   virtual nsresult SetFilePath(const nsACString& aFilePath);
71   virtual nsresult SetQuery(const nsACString& aQuery);
72   virtual nsresult SetQueryWithEncoding(const nsACString& aQuery,
73                                         const Encoding* encoding);
74   nsresult ReadPrivate(nsIObjectInputStream* stream);
75 
76   // Helper to share code between Equals methods.
77   virtual nsresult EqualsInternal(nsIURI* other,
78                                   RefHandlingEnum refHandlingMode,
79                                   bool* result);
80 
81   // Helper to be used by inherited classes who want to test
82   // equality given an assumed nsSimpleURI.  This must NOT check
83   // the passed-in other for QI to our CID.
84   bool EqualsInternal(nsSimpleURI* otherUri, RefHandlingEnum refHandlingMode);
85 
86   // Used by StartClone (and versions of StartClone in subclasses) to
87   // handle the ref in the right way for clones.
88   void SetRefOnClone(nsSimpleURI* url, RefHandlingEnum refHandlingMode,
89                      const nsACString& newRef);
90 
91   // NOTE: This takes the refHandlingMode as an argument because
92   // nsSimpleNestedURI's specialized version needs to know how to clone
93   // its inner URI.
94   virtual nsSimpleURI* StartClone(RefHandlingEnum refHandlingMode,
95                                   const nsACString& newRef);
96 
97   // Helper to share code between Clone methods.
98   virtual nsresult CloneInternal(RefHandlingEnum refHandlingMode,
99                                  const nsACString& newRef, nsIURI** result);
100 
101   nsresult EscapeAndSetPathQueryRef(const nsACString& aPath);
102   nsresult SetPathQueryRefInternal(const nsACString& aPath);
103 
104   bool Deserialize(const mozilla::ipc::URIParams&);
105 
106   nsCString mScheme;
107   nsCString mPath;  // NOTE: mPath does not include ref, as an optimization
108   nsCString mRef;   // so that URIs with different refs can share string data.
109   nsCString
110       mQuery;  // so that URLs with different querys can share string data.
111   bool mIsRefValid{false};  // To distinguish between empty-ref and no-ref.
112   // To distinguish between empty-query and no-query.
113   bool mIsQueryValid{false};
114 
115  public:
116   class Mutator final : public nsIURIMutator,
117                         public BaseURIMutator<nsSimpleURI>,
118                         public nsISimpleURIMutator,
119                         public nsISerializable {
120     NS_DECL_ISUPPORTS
NS_FORWARD_SAFE_NSIURISETTERS_RET(mURI)121     NS_FORWARD_SAFE_NSIURISETTERS_RET(mURI)
122     NS_DEFINE_NSIMUTATOR_COMMON
123 
124     NS_IMETHOD
125     Write(nsIObjectOutputStream* aOutputStream) override {
126       return NS_ERROR_NOT_IMPLEMENTED;
127     }
128 
Read(nsIObjectInputStream * aStream)129     [[nodiscard]] NS_IMETHOD Read(nsIObjectInputStream* aStream) override {
130       return InitFromInputStream(aStream);
131     }
132 
SetSpecAndFilterWhitespace(const nsACString & aSpec,nsIURIMutator ** aMutator)133     [[nodiscard]] NS_IMETHOD SetSpecAndFilterWhitespace(
134         const nsACString& aSpec, nsIURIMutator** aMutator) override {
135       if (aMutator) {
136         *aMutator = do_AddRef(this).take();
137       }
138 
139       nsresult rv = NS_OK;
140       RefPtr<nsSimpleURI> uri = new nsSimpleURI();
141       rv = uri->SetSpecInternal(aSpec, /* filterWhitespace */ true);
142       if (NS_FAILED(rv)) {
143         return rv;
144       }
145       mURI = std::move(uri);
146       return NS_OK;
147     }
148 
149     explicit Mutator() = default;
150 
151    private:
152     virtual ~Mutator() = default;
153 
154     friend class nsSimpleURI;
155   };
156 
157   friend BaseURIMutator<nsSimpleURI>;
158 };
159 
160 }  // namespace net
161 }  // namespace mozilla
162 
163 #endif  // nsSimpleURI_h__
164