1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
23 * Darin Fisher <darin@netscape.com> (original author)
25 * Alternatively, the contents of this file may be used under the terms of
26 * either the GNU General Public License Version 2 or later (the "GPL"), or
27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
39 #ifndef nsStandardURL_h__
40 #define nsStandardURL_h__
43 #include "nsDependentString.h"
44 #include "nsDependentSubstring.h"
45 #include "nsISerializable.h"
46 #include "nsIFileURL.h"
47 #include "nsIStandardURL.h"
49 #include "nsIURLParser.h"
50 #include "nsIUnicodeEncoder.h"
51 #include "nsIObserver.h"
52 #include "nsIIOService.h"
54 #include "nsURLHelper.h"
55 #include "nsIClassInfo.h"
57 class nsIBinaryInputStream
;
58 class nsIBinaryOutputStream
;
60 class nsICharsetConverterManager
;
63 //-----------------------------------------------------------------------------
64 // standard URL implementation
65 //-----------------------------------------------------------------------------
67 class nsStandardURL
: public nsIFileURL
68 , public nsIStandardURL
69 , public nsISerializable
77 NS_DECL_NSISTANDARDURL
78 NS_DECL_NSISERIALIZABLE
82 nsStandardURL(PRBool aSupportsFileURL
= PR_FALSE
);
83 virtual ~nsStandardURL();
85 static void InitGlobalObjects();
86 static void ShutdownGlobalObjects();
88 public: /* internal -- HPUX compiler can't handle this being private */
90 // location and length of an url segment relative to mSpec
97 URLSegment() : mPos(0), mLen(-1) {}
98 URLSegment(PRUint32 pos
, PRInt32 len
) : mPos(pos
), mLen(len
) {}
99 void Reset() { mPos
= 0; mLen
= -1; }
105 class nsPrefObserver
: public nsIObserver
113 friend class nsPrefObserver
;
116 // URL segment encoder : performs charset conversion and URL escaping.
118 class nsSegmentEncoder
121 nsSegmentEncoder(const char *charset
);
123 // Encode the given segment if necessary, and return the length of
124 // the encoded segment. The encoded segment is appended to |buf|
125 // if and only if encoding is required.
126 PRInt32
EncodeSegmentCount(const char *str
,
127 const URLSegment
&segment
,
132 // Encode the given string if necessary, and return a reference to
133 // the encoded string. Returns a reference to |buf| if encoding
134 // is required. Otherwise, a reference to |str| is returned.
135 const nsACString
&EncodeSegment(const nsASingleFragmentCString
&str
,
137 nsAFlatCString
&buf
);
139 PRBool
InitUnicodeEncoder();
141 const char* mCharset
; // Caller should keep this alive for
142 // the life of the segment encoder
143 nsCOMPtr
<nsIUnicodeEncoder
> mEncoder
;
145 friend class nsSegmentEncoder
;
148 virtual nsStandardURL
* StartClone();
150 // Helper for subclass implementation of GetFile(). Subclasses that map
151 // URIs to files in a special way should implement this method. It should
152 // ensure that our mFile is initialized, if it's possible.
153 virtual nsresult
EnsureFile();
156 PRInt32
Port() { return mPort
== -1 ? mDefaultPort
: mPort
; }
159 void InvalidateCache(PRBool invalidateCachedFile
= PR_TRUE
);
161 PRBool
EscapeIPv6(const char *host
, nsCString
&result
);
162 PRBool
NormalizeIDN(const nsCSubstring
&host
, nsCString
&result
);
163 void CoalescePath(netCoalesceFlags coalesceFlag
, char *path
);
165 PRUint32
AppendSegmentToBuf(char *, PRUint32
, const char *, URLSegment
&, const nsCString
*esc
=nsnull
, PRBool useEsc
= PR_FALSE
);
166 PRUint32
AppendToBuf(char *, PRUint32
, const char *, PRUint32
);
168 nsresult
BuildNormalizedSpec(const char *spec
);
170 PRBool
SegmentIs(const URLSegment
&s1
, const char *val
, PRBool ignoreCase
= PR_FALSE
);
171 PRBool
SegmentIs(const char* spec
, const URLSegment
&s1
, const char *val
, PRBool ignoreCase
= PR_FALSE
);
172 PRBool
SegmentIs(const URLSegment
&s1
, const char *val
, const URLSegment
&s2
, PRBool ignoreCase
= PR_FALSE
);
174 PRInt32
ReplaceSegment(PRUint32 pos
, PRUint32 len
, const char *val
, PRUint32 valLen
);
175 PRInt32
ReplaceSegment(PRUint32 pos
, PRUint32 len
, const nsACString
&val
);
177 nsresult
ParseURL(const char *spec
, PRInt32 specLen
);
178 nsresult
ParsePath(const char *spec
, PRUint32 pathPos
, PRInt32 pathLen
= -1);
180 char *AppendToSubstring(PRUint32 pos
, PRInt32 len
, const char *tail
, PRInt32 tailLen
= -1);
182 // dependent substring helpers
183 const nsDependentCSubstring
Segment(PRUint32 pos
, PRInt32 len
); // see below
184 const nsDependentCSubstring
Segment(const URLSegment
&s
) { return Segment(s
.mPos
, s
.mLen
); }
186 // dependent substring getters
187 const nsDependentCSubstring
Prepath(); // see below
188 const nsDependentCSubstring
Scheme() { return Segment(mScheme
); }
189 const nsDependentCSubstring
Userpass(PRBool includeDelim
= PR_FALSE
); // see below
190 const nsDependentCSubstring
Username() { return Segment(mUsername
); }
191 const nsDependentCSubstring
Password() { return Segment(mPassword
); }
192 const nsDependentCSubstring
Hostport(); // see below
193 const nsDependentCSubstring
Host(); // see below
194 const nsDependentCSubstring
Path() { return Segment(mPath
); }
195 const nsDependentCSubstring
Filepath() { return Segment(mFilepath
); }
196 const nsDependentCSubstring
Directory() { return Segment(mDirectory
); }
197 const nsDependentCSubstring
Filename(); // see below
198 const nsDependentCSubstring
Basename() { return Segment(mBasename
); }
199 const nsDependentCSubstring
Extension() { return Segment(mExtension
); }
200 const nsDependentCSubstring
Param() { return Segment(mParam
); }
201 const nsDependentCSubstring
Query() { return Segment(mQuery
); }
202 const nsDependentCSubstring
Ref() { return Segment(mRef
); }
204 // shift the URLSegments to the right by diff
205 void ShiftFromAuthority(PRInt32 diff
) { mAuthority
.mPos
+= diff
; ShiftFromUsername(diff
); }
206 void ShiftFromUsername(PRInt32 diff
) { mUsername
.mPos
+= diff
; ShiftFromPassword(diff
); }
207 void ShiftFromPassword(PRInt32 diff
) { mPassword
.mPos
+= diff
; ShiftFromHost(diff
); }
208 void ShiftFromHost(PRInt32 diff
) { mHost
.mPos
+= diff
; ShiftFromPath(diff
); }
209 void ShiftFromPath(PRInt32 diff
) { mPath
.mPos
+= diff
; ShiftFromFilepath(diff
); }
210 void ShiftFromFilepath(PRInt32 diff
) { mFilepath
.mPos
+= diff
; ShiftFromDirectory(diff
); }
211 void ShiftFromDirectory(PRInt32 diff
) { mDirectory
.mPos
+= diff
; ShiftFromBasename(diff
); }
212 void ShiftFromBasename(PRInt32 diff
) { mBasename
.mPos
+= diff
; ShiftFromExtension(diff
); }
213 void ShiftFromExtension(PRInt32 diff
) { mExtension
.mPos
+= diff
; ShiftFromParam(diff
); }
214 void ShiftFromParam(PRInt32 diff
) { mParam
.mPos
+= diff
; ShiftFromQuery(diff
); }
215 void ShiftFromQuery(PRInt32 diff
) { mQuery
.mPos
+= diff
; ShiftFromRef(diff
); }
216 void ShiftFromRef(PRInt32 diff
) { mRef
.mPos
+= diff
; }
218 // fastload helper functions
219 nsresult
ReadSegment(nsIBinaryInputStream
*, URLSegment
&);
220 nsresult
WriteSegment(nsIBinaryOutputStream
*, const URLSegment
&);
222 static void PrefsChanged(nsIPrefBranch
*prefs
, const char *pref
);
224 // mSpec contains the normalized version of the URL spec (UTF-8 encoded).
226 PRInt32 mDefaultPort
;
229 // url parts (relative to mSpec)
231 URLSegment mAuthority
;
232 URLSegment mUsername
;
233 URLSegment mPassword
;
236 URLSegment mFilepath
;
237 URLSegment mDirectory
;
238 URLSegment mBasename
;
239 URLSegment mExtension
;
244 nsCString mOriginCharset
;
245 nsCOMPtr
<nsIURLParser
> mParser
;
247 // mFile is protected so subclasses can access it directly
249 nsCOMPtr
<nsIFile
> mFile
; // cached result for nsIFileURL::GetFile
252 char *mHostA
; // cached result for nsIURI::GetHostA
260 PRUint32 mHostEncoding
: 2; // eEncoding_xxx
261 PRUint32 mSpecEncoding
: 2; // eEncoding_xxx
262 PRUint32 mURLType
: 2; // nsIStandardURL::URLTYPE_xxx
263 PRUint32 mMutable
: 1; // nsIStandardURL::mutable
264 PRUint32 mSupportsFileURL
: 1; // QI to nsIFileURL?
266 // global objects. don't use COMPtr as its destructor will cause a
267 // coredump if we leak it.
268 static nsIIDNService
*gIDN
;
269 static nsICharsetConverterManager
*gCharsetMgr
;
270 static PRBool gInitialized
;
271 static PRBool gEscapeUTF8
;
272 static PRBool gAlwaysEncodeInUTF8
;
273 static PRBool gEncodeQueryInUTF8
;
276 #define NS_THIS_STANDARDURL_IMPL_CID \
277 { /* b8e3e97b-1ccd-4b45-af5a-79596770f5d7 */ \
281 {0xaf, 0x5a, 0x79, 0x59, 0x67, 0x70, 0xf5, 0xd7} \
284 //-----------------------------------------------------------------------------
285 // Dependent substring getters
286 //-----------------------------------------------------------------------------
288 inline const nsDependentCSubstring
289 nsStandardURL::Segment(PRUint32 pos
, PRInt32 len
)
295 return Substring(mSpec
, pos
, PRUint32(len
));
298 inline const nsDependentCSubstring
299 nsStandardURL::Prepath()
302 if (mAuthority
.mLen
>= 0)
303 len
= mAuthority
.mPos
+ mAuthority
.mLen
;
304 return Substring(mSpec
, 0, len
);
307 inline const nsDependentCSubstring
308 nsStandardURL::Userpass(int includeDelim
)
310 PRUint32 pos
=0, len
=0;
311 // if there is no username, then there can be no password
312 if (mUsername
.mLen
> 0) {
313 pos
= mUsername
.mPos
;
314 len
= mUsername
.mLen
;
315 if (mPassword
.mLen
>= 0)
316 len
+= (mPassword
.mLen
+ 1);
320 return Substring(mSpec
, pos
, len
);
323 inline const nsDependentCSubstring
324 nsStandardURL::Hostport()
326 PRUint32 pos
=0, len
=0;
327 if (mAuthority
.mLen
> 0) {
329 len
= mAuthority
.mPos
+ mAuthority
.mLen
- pos
;
331 return Substring(mSpec
, pos
, len
);
334 inline const nsDependentCSubstring
335 nsStandardURL::Host()
337 PRUint32 pos
=0, len
=0;
338 if (mHost
.mLen
> 0) {
341 if (mSpec
.CharAt(pos
) == '[' && mSpec
.CharAt(pos
+ len
- 1) == ']') {
346 return Substring(mSpec
, pos
, len
);
349 inline const nsDependentCSubstring
350 nsStandardURL::Filename()
352 PRUint32 pos
=0, len
=0;
353 // if there is no basename, then there can be no extension
354 if (mBasename
.mLen
> 0) {
355 pos
= mBasename
.mPos
;
356 len
= mBasename
.mLen
;
357 if (mExtension
.mLen
>= 0)
358 len
+= (mExtension
.mLen
+ 1);
360 return Substring(mSpec
, pos
, len
);
363 #endif // nsStandardURL_h__