netwerk/base/src/nsStandardURL.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef nsStandardURL_h__
michael@0 7 #define nsStandardURL_h__
michael@0 8
michael@0 9 #include "nsString.h"
michael@0 10 #include "nsISerializable.h"
michael@0 11 #include "nsIFileURL.h"
michael@0 12 #include "nsIStandardURL.h"
michael@0 13 #include "nsIUnicodeEncoder.h"
michael@0 14 #include "nsIObserver.h"
michael@0 15 #include "nsCOMPtr.h"
michael@0 16 #include "nsURLHelper.h"
michael@0 17 #include "nsIClassInfo.h"
michael@0 18 #include "nsISizeOf.h"
michael@0 19 #include "prclist.h"
michael@0 20 #include "mozilla/Attributes.h"
michael@0 21 #include "mozilla/MemoryReporting.h"
michael@0 22 #include "nsIIPCSerializableURI.h"
michael@0 23
michael@0 24 #ifdef NS_BUILD_REFCNT_LOGGING
michael@0 25 #define DEBUG_DUMP_URLS_AT_SHUTDOWN
michael@0 26 #endif
michael@0 27
michael@0 28 class nsIBinaryInputStream;
michael@0 29 class nsIBinaryOutputStream;
michael@0 30 class nsIIDNService;
michael@0 31 class nsICharsetConverterManager;
michael@0 32 class nsIPrefBranch;
michael@0 33 class nsIFile;
michael@0 34 class nsIURLParser;
michael@0 35
michael@0 36 //-----------------------------------------------------------------------------
michael@0 37 // standard URL implementation
michael@0 38 //-----------------------------------------------------------------------------
michael@0 39
michael@0 40 class nsStandardURL : public nsIFileURL
michael@0 41 , public nsIStandardURL
michael@0 42 , public nsISerializable
michael@0 43 , public nsIClassInfo
michael@0 44 , public nsISizeOf
michael@0 45 , public nsIIPCSerializableURI
michael@0 46 {
michael@0 47 public:
michael@0 48 NS_DECL_ISUPPORTS
michael@0 49 NS_DECL_NSIURI
michael@0 50 NS_DECL_NSIURL
michael@0 51 NS_DECL_NSIFILEURL
michael@0 52 NS_DECL_NSISTANDARDURL
michael@0 53 NS_DECL_NSISERIALIZABLE
michael@0 54 NS_DECL_NSICLASSINFO
michael@0 55 NS_DECL_NSIMUTABLE
michael@0 56 NS_DECL_NSIIPCSERIALIZABLEURI
michael@0 57
michael@0 58 // nsISizeOf
michael@0 59 virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
michael@0 60 virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
michael@0 61
michael@0 62 nsStandardURL(bool aSupportsFileURL = false);
michael@0 63 virtual ~nsStandardURL();
michael@0 64
michael@0 65 static void InitGlobalObjects();
michael@0 66 static void ShutdownGlobalObjects();
michael@0 67
michael@0 68 public: /* internal -- HPUX compiler can't handle this being private */
michael@0 69 //
michael@0 70 // location and length of an url segment relative to mSpec
michael@0 71 //
michael@0 72 struct URLSegment
michael@0 73 {
michael@0 74 uint32_t mPos;
michael@0 75 int32_t mLen;
michael@0 76
michael@0 77 URLSegment() : mPos(0), mLen(-1) {}
michael@0 78 URLSegment(uint32_t pos, int32_t len) : mPos(pos), mLen(len) {}
michael@0 79 void Reset() { mPos = 0; mLen = -1; }
michael@0 80 // Merge another segment following this one to it if they're contiguous
michael@0 81 // Assumes we have something like "foo;bar" where this object is 'foo' and right
michael@0 82 // is 'bar'.
michael@0 83 void Merge(const nsCString &spec, const char separator, const URLSegment &right) {
michael@0 84 if (mLen >= 0 &&
michael@0 85 *(spec.get() + mPos + mLen) == separator &&
michael@0 86 mPos + mLen + 1 == right.mPos) {
michael@0 87 mLen += 1 + right.mLen;
michael@0 88 }
michael@0 89 }
michael@0 90 };
michael@0 91
michael@0 92 //
michael@0 93 // Pref observer
michael@0 94 //
michael@0 95 class nsPrefObserver MOZ_FINAL : public nsIObserver
michael@0 96 {
michael@0 97 public:
michael@0 98 NS_DECL_ISUPPORTS
michael@0 99 NS_DECL_NSIOBSERVER
michael@0 100
michael@0 101 nsPrefObserver() { }
michael@0 102 };
michael@0 103 friend class nsPrefObserver;
michael@0 104
michael@0 105 //
michael@0 106 // URL segment encoder : performs charset conversion and URL escaping.
michael@0 107 //
michael@0 108 class nsSegmentEncoder
michael@0 109 {
michael@0 110 public:
michael@0 111 nsSegmentEncoder(const char *charset);
michael@0 112
michael@0 113 // Encode the given segment if necessary, and return the length of
michael@0 114 // the encoded segment. The encoded segment is appended to |buf|
michael@0 115 // if and only if encoding is required.
michael@0 116 int32_t EncodeSegmentCount(const char *str,
michael@0 117 const URLSegment &segment,
michael@0 118 int16_t mask,
michael@0 119 nsAFlatCString &buf,
michael@0 120 bool& appended,
michael@0 121 uint32_t extraLen = 0);
michael@0 122
michael@0 123 // Encode the given string if necessary, and return a reference to
michael@0 124 // the encoded string. Returns a reference to |buf| if encoding
michael@0 125 // is required. Otherwise, a reference to |str| is returned.
michael@0 126 const nsACString &EncodeSegment(const nsASingleFragmentCString &str,
michael@0 127 int16_t mask,
michael@0 128 nsAFlatCString &buf);
michael@0 129 private:
michael@0 130 bool InitUnicodeEncoder();
michael@0 131
michael@0 132 const char* mCharset; // Caller should keep this alive for
michael@0 133 // the life of the segment encoder
michael@0 134 nsCOMPtr<nsIUnicodeEncoder> mEncoder;
michael@0 135 };
michael@0 136 friend class nsSegmentEncoder;
michael@0 137
michael@0 138 protected:
michael@0 139 // enum used in a few places to specify how .ref attribute should be handled
michael@0 140 enum RefHandlingEnum {
michael@0 141 eIgnoreRef,
michael@0 142 eHonorRef
michael@0 143 };
michael@0 144
michael@0 145 // Helper to share code between Equals and EqualsExceptRef
michael@0 146 // NOTE: *not* virtual, because no one needs to override this so far...
michael@0 147 nsresult EqualsInternal(nsIURI* unknownOther,
michael@0 148 RefHandlingEnum refHandlingMode,
michael@0 149 bool* result);
michael@0 150
michael@0 151 virtual nsStandardURL* StartClone();
michael@0 152
michael@0 153 // Helper to share code between Clone methods.
michael@0 154 nsresult CloneInternal(RefHandlingEnum aRefHandlingMode,
michael@0 155 nsIURI** aClone);
michael@0 156
michael@0 157 // Helper for subclass implementation of GetFile(). Subclasses that map
michael@0 158 // URIs to files in a special way should implement this method. It should
michael@0 159 // ensure that our mFile is initialized, if it's possible.
michael@0 160 // returns NS_ERROR_NO_INTERFACE if the url does not map to a file
michael@0 161 virtual nsresult EnsureFile();
michael@0 162
michael@0 163 private:
michael@0 164 int32_t Port() { return mPort == -1 ? mDefaultPort : mPort; }
michael@0 165
michael@0 166 void Clear();
michael@0 167 void InvalidateCache(bool invalidateCachedFile = true);
michael@0 168
michael@0 169 bool EscapeIPv6(const char *host, nsCString &result);
michael@0 170 bool NormalizeIDN(const nsCSubstring &host, nsCString &result);
michael@0 171 void CoalescePath(netCoalesceFlags coalesceFlag, char *path);
michael@0 172
michael@0 173 uint32_t AppendSegmentToBuf(char *, uint32_t, const char *, URLSegment &, const nsCString *esc=nullptr, bool useEsc = false);
michael@0 174 uint32_t AppendToBuf(char *, uint32_t, const char *, uint32_t);
michael@0 175
michael@0 176 nsresult BuildNormalizedSpec(const char *spec);
michael@0 177
michael@0 178 bool SegmentIs(const URLSegment &s1, const char *val, bool ignoreCase = false);
michael@0 179 bool SegmentIs(const char* spec, const URLSegment &s1, const char *val, bool ignoreCase = false);
michael@0 180 bool SegmentIs(const URLSegment &s1, const char *val, const URLSegment &s2, bool ignoreCase = false);
michael@0 181
michael@0 182 int32_t ReplaceSegment(uint32_t pos, uint32_t len, const char *val, uint32_t valLen);
michael@0 183 int32_t ReplaceSegment(uint32_t pos, uint32_t len, const nsACString &val);
michael@0 184
michael@0 185 nsresult ParseURL(const char *spec, int32_t specLen);
michael@0 186 nsresult ParsePath(const char *spec, uint32_t pathPos, int32_t pathLen = -1);
michael@0 187
michael@0 188 char *AppendToSubstring(uint32_t pos, int32_t len, const char *tail);
michael@0 189
michael@0 190 // dependent substring helpers
michael@0 191 const nsDependentCSubstring Segment(uint32_t pos, int32_t len); // see below
michael@0 192 const nsDependentCSubstring Segment(const URLSegment &s) { return Segment(s.mPos, s.mLen); }
michael@0 193
michael@0 194 // dependent substring getters
michael@0 195 const nsDependentCSubstring Prepath(); // see below
michael@0 196 const nsDependentCSubstring Scheme() { return Segment(mScheme); }
michael@0 197 const nsDependentCSubstring Userpass(bool includeDelim = false); // see below
michael@0 198 const nsDependentCSubstring Username() { return Segment(mUsername); }
michael@0 199 const nsDependentCSubstring Password() { return Segment(mPassword); }
michael@0 200 const nsDependentCSubstring Hostport(); // see below
michael@0 201 const nsDependentCSubstring Host(); // see below
michael@0 202 const nsDependentCSubstring Path() { return Segment(mPath); }
michael@0 203 const nsDependentCSubstring Filepath() { return Segment(mFilepath); }
michael@0 204 const nsDependentCSubstring Directory() { return Segment(mDirectory); }
michael@0 205 const nsDependentCSubstring Filename(); // see below
michael@0 206 const nsDependentCSubstring Basename() { return Segment(mBasename); }
michael@0 207 const nsDependentCSubstring Extension() { return Segment(mExtension); }
michael@0 208 const nsDependentCSubstring Query() { return Segment(mQuery); }
michael@0 209 const nsDependentCSubstring Ref() { return Segment(mRef); }
michael@0 210
michael@0 211 // shift the URLSegments to the right by diff
michael@0 212 void ShiftFromAuthority(int32_t diff) { mAuthority.mPos += diff; ShiftFromUsername(diff); }
michael@0 213 void ShiftFromUsername(int32_t diff) { mUsername.mPos += diff; ShiftFromPassword(diff); }
michael@0 214 void ShiftFromPassword(int32_t diff) { mPassword.mPos += diff; ShiftFromHost(diff); }
michael@0 215 void ShiftFromHost(int32_t diff) { mHost.mPos += diff; ShiftFromPath(diff); }
michael@0 216 void ShiftFromPath(int32_t diff) { mPath.mPos += diff; ShiftFromFilepath(diff); }
michael@0 217 void ShiftFromFilepath(int32_t diff) { mFilepath.mPos += diff; ShiftFromDirectory(diff); }
michael@0 218 void ShiftFromDirectory(int32_t diff) { mDirectory.mPos += diff; ShiftFromBasename(diff); }
michael@0 219 void ShiftFromBasename(int32_t diff) { mBasename.mPos += diff; ShiftFromExtension(diff); }
michael@0 220 void ShiftFromExtension(int32_t diff) { mExtension.mPos += diff; ShiftFromQuery(diff); }
michael@0 221 void ShiftFromQuery(int32_t diff) { mQuery.mPos += diff; ShiftFromRef(diff); }
michael@0 222 void ShiftFromRef(int32_t diff) { mRef.mPos += diff; }
michael@0 223
michael@0 224 // fastload helper functions
michael@0 225 nsresult ReadSegment(nsIBinaryInputStream *, URLSegment &);
michael@0 226 nsresult WriteSegment(nsIBinaryOutputStream *, const URLSegment &);
michael@0 227
michael@0 228 static void PrefsChanged(nsIPrefBranch *prefs, const char *pref);
michael@0 229
michael@0 230 void FindHostLimit(nsACString::const_iterator& aStart,
michael@0 231 nsACString::const_iterator& aEnd);
michael@0 232
michael@0 233 // mSpec contains the normalized version of the URL spec (UTF-8 encoded).
michael@0 234 nsCString mSpec;
michael@0 235 int32_t mDefaultPort;
michael@0 236 int32_t mPort;
michael@0 237
michael@0 238 // url parts (relative to mSpec)
michael@0 239 URLSegment mScheme;
michael@0 240 URLSegment mAuthority;
michael@0 241 URLSegment mUsername;
michael@0 242 URLSegment mPassword;
michael@0 243 URLSegment mHost;
michael@0 244 URLSegment mPath;
michael@0 245 URLSegment mFilepath;
michael@0 246 URLSegment mDirectory;
michael@0 247 URLSegment mBasename;
michael@0 248 URLSegment mExtension;
michael@0 249 URLSegment mQuery;
michael@0 250 URLSegment mRef;
michael@0 251
michael@0 252 nsCString mOriginCharset;
michael@0 253 nsCOMPtr<nsIURLParser> mParser;
michael@0 254
michael@0 255 // mFile is protected so subclasses can access it directly
michael@0 256 protected:
michael@0 257 nsCOMPtr<nsIFile> mFile; // cached result for nsIFileURL::GetFile
michael@0 258
michael@0 259 private:
michael@0 260 char *mHostA; // cached result for nsIURI::GetHostA
michael@0 261
michael@0 262 enum {
michael@0 263 eEncoding_Unknown,
michael@0 264 eEncoding_ASCII,
michael@0 265 eEncoding_UTF8
michael@0 266 };
michael@0 267
michael@0 268 uint32_t mHostEncoding : 2; // eEncoding_xxx
michael@0 269 uint32_t mSpecEncoding : 2; // eEncoding_xxx
michael@0 270 uint32_t mURLType : 2; // nsIStandardURL::URLTYPE_xxx
michael@0 271 uint32_t mMutable : 1; // nsIStandardURL::mutable
michael@0 272 uint32_t mSupportsFileURL : 1; // QI to nsIFileURL?
michael@0 273
michael@0 274 // global objects. don't use COMPtr as its destructor will cause a
michael@0 275 // coredump if we leak it.
michael@0 276 static nsIIDNService *gIDN;
michael@0 277 static char gHostLimitDigits[];
michael@0 278 static nsICharsetConverterManager *gCharsetMgr;
michael@0 279 static bool gInitialized;
michael@0 280 static bool gEscapeUTF8;
michael@0 281 static bool gAlwaysEncodeInUTF8;
michael@0 282 static bool gEncodeQueryInUTF8;
michael@0 283
michael@0 284 public:
michael@0 285 #ifdef DEBUG_DUMP_URLS_AT_SHUTDOWN
michael@0 286 PRCList mDebugCList;
michael@0 287 void PrintSpec() const { printf(" %s\n", mSpec.get()); }
michael@0 288 #endif
michael@0 289 };
michael@0 290
michael@0 291 #define NS_THIS_STANDARDURL_IMPL_CID \
michael@0 292 { /* b8e3e97b-1ccd-4b45-af5a-79596770f5d7 */ \
michael@0 293 0xb8e3e97b, \
michael@0 294 0x1ccd, \
michael@0 295 0x4b45, \
michael@0 296 {0xaf, 0x5a, 0x79, 0x59, 0x67, 0x70, 0xf5, 0xd7} \
michael@0 297 }
michael@0 298
michael@0 299 //-----------------------------------------------------------------------------
michael@0 300 // Dependent substring getters
michael@0 301 //-----------------------------------------------------------------------------
michael@0 302
michael@0 303 inline const nsDependentCSubstring
michael@0 304 nsStandardURL::Segment(uint32_t pos, int32_t len)
michael@0 305 {
michael@0 306 if (len < 0) {
michael@0 307 pos = 0;
michael@0 308 len = 0;
michael@0 309 }
michael@0 310 return Substring(mSpec, pos, uint32_t(len));
michael@0 311 }
michael@0 312
michael@0 313 inline const nsDependentCSubstring
michael@0 314 nsStandardURL::Prepath()
michael@0 315 {
michael@0 316 uint32_t len = 0;
michael@0 317 if (mAuthority.mLen >= 0)
michael@0 318 len = mAuthority.mPos + mAuthority.mLen;
michael@0 319 return Substring(mSpec, 0, len);
michael@0 320 }
michael@0 321
michael@0 322 inline const nsDependentCSubstring
michael@0 323 nsStandardURL::Userpass(bool includeDelim)
michael@0 324 {
michael@0 325 uint32_t pos=0, len=0;
michael@0 326 // if there is no username, then there can be no password
michael@0 327 if (mUsername.mLen > 0) {
michael@0 328 pos = mUsername.mPos;
michael@0 329 len = mUsername.mLen;
michael@0 330 if (mPassword.mLen >= 0)
michael@0 331 len += (mPassword.mLen + 1);
michael@0 332 if (includeDelim)
michael@0 333 len++;
michael@0 334 }
michael@0 335 return Substring(mSpec, pos, len);
michael@0 336 }
michael@0 337
michael@0 338 inline const nsDependentCSubstring
michael@0 339 nsStandardURL::Hostport()
michael@0 340 {
michael@0 341 uint32_t pos=0, len=0;
michael@0 342 if (mAuthority.mLen > 0) {
michael@0 343 pos = mHost.mPos;
michael@0 344 len = mAuthority.mPos + mAuthority.mLen - pos;
michael@0 345 }
michael@0 346 return Substring(mSpec, pos, len);
michael@0 347 }
michael@0 348
michael@0 349 inline const nsDependentCSubstring
michael@0 350 nsStandardURL::Host()
michael@0 351 {
michael@0 352 uint32_t pos=0, len=0;
michael@0 353 if (mHost.mLen > 0) {
michael@0 354 pos = mHost.mPos;
michael@0 355 len = mHost.mLen;
michael@0 356 if (mSpec.CharAt(pos) == '[' && mSpec.CharAt(pos + len - 1) == ']') {
michael@0 357 pos++;
michael@0 358 len -= 2;
michael@0 359 }
michael@0 360 }
michael@0 361 return Substring(mSpec, pos, len);
michael@0 362 }
michael@0 363
michael@0 364 inline const nsDependentCSubstring
michael@0 365 nsStandardURL::Filename()
michael@0 366 {
michael@0 367 uint32_t pos=0, len=0;
michael@0 368 // if there is no basename, then there can be no extension
michael@0 369 if (mBasename.mLen > 0) {
michael@0 370 pos = mBasename.mPos;
michael@0 371 len = mBasename.mLen;
michael@0 372 if (mExtension.mLen >= 0)
michael@0 373 len += (mExtension.mLen + 1);
michael@0 374 }
michael@0 375 return Substring(mSpec, pos, len);
michael@0 376 }
michael@0 377
michael@0 378 #endif // nsStandardURL_h__

mercurial