gecko-dev/netwerk/base/MozURL.h

140 lines
5.1 KiB
C++

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozURL_h__
#define mozURL_h__
#include "mozilla/UniquePtr.h"
extern "C" {
struct rusturl;
}
namespace mozilla {
namespace net {
// This class provides a thread-safe, immutable URL parser.
// As long as there is RefPtr to the object, you may use it on any thread.
// The constructor is private. One can instantiate the object by
// calling the Init() method as such:
//
// RefPtr<MozURL> url;
// nsAutoCString href("http://example.com/path?query#ref");
// nsresult rv = MozURL::Init(getter_AddRefs(url), href);
// if (NS_SUCCEEDED(rv)) { /* use url */ }
//
// When changing the URL is needed, you need to call the Mutate() method.
// This gives you a Mutator object, on which you can perform setter operations.
// Calling Finalize() on the Mutator will result in a new MozURL and a status
// code. If any of the setter operations failed, it will be reflected in the
// status code, and a null MozURL.
//
// Note: In the case of a domain name containing non-ascii characters,
// GetSpec and GetHostname will return the IDNA(punycode) version of the host.
// Also note that for now, MozURL only supports the UTF-8 charset.
class MozURL final
{
public:
static nsresult Init(MozURL** aURL, const nsACString& aSpec,
const MozURL* aBaseURL = nullptr);
nsresult GetScheme(nsACString& aScheme);
nsresult GetSpec(nsACString& aSpec);
nsresult GetUsername(nsACString& aUser);
nsresult GetPassword(nsACString& aPassword);
// Will return the hostname of URL. If the hostname is an IPv6 address,
// it will be enclosed in square brackets, such as `[::1]`
nsresult GetHostname(nsACString& aHost);
// If the URL's port number is equal to the default port, will only return the
// hostname, otherwise it will return a string of the form `{host}:{port}`
// See: https://url.spec.whatwg.org/#default-port
nsresult GetHostPort(nsACString& aHostPort);
// Will return the port number, if specified, or -1
nsresult GetPort(int32_t* aPort);
nsresult GetFilePath(nsACString& aPath);
nsresult GetQuery(nsACString& aQuery);
nsresult GetRef(nsACString& aRef);
nsresult GetOrigin(nsACString& aOrigin);
private:
explicit MozURL(rusturl* rawPtr)
: mURL(rawPtr)
{
}
virtual ~MozURL() {}
struct FreeRustURL
{
void operator()(rusturl* aPtr);
};
mozilla::UniquePtr<rusturl, FreeRustURL> mURL;
public:
class MOZ_STACK_CLASS Mutator
{
public:
// Calling this method will result in the creation of a new MozURL that
// adopts the mutator's mURL.
// If any of the setters failed with an error code, that error code will be
// returned here. It will also return an error code if Finalize is called
// more than once on the Mutator.
nsresult Finalize(MozURL** aURL);
// These setter methods will return a reference to `this` so that you may
// chain setter operations as such:
//
// RefPtr<MozURL> url2;
// nsresult rv = url->Mutate().SetHostname(NS_LITERAL_CSTRING("newhost"))
// .SetFilePath(NS_LITERAL_CSTRING("new/file/path"))
// .Finalize(getter_AddRefs(url2));
// if (NS_SUCCEEDED(rv)) { /* use url2 */ }
Mutator& SetScheme(const nsACString& aScheme);
Mutator& SetUsername(const nsACString& aUser);
Mutator& SetPassword(const nsACString& aPassword);
Mutator& SetHostname(const nsACString& aHost);
Mutator& SetHostPort(const nsACString& aHostPort);
Mutator& SetFilePath(const nsACString& aPath);
Mutator& SetQuery(const nsACString& aQuery);
Mutator& SetRef(const nsACString& aRef);
Mutator& SetPort(int32_t aPort);
// This method returns the status code of the setter operations.
// If any of the setters failed, it will return the code of the first error
// that occured. If none of the setters failed, it will return NS_OK.
// This method is useful to avoid doing expensive operations when the result
// would not be used because an error occurred. For example:
//
// RefPtr<MozURL> url2;
// MozURL::Mutator mut = url->Mutate();
// mut.SetScheme("!@#$"); // this would fail
// if (NS_SUCCEDED(mut.GetStatus())) {
// nsAutoCString host(ExpensiveComputing());
// rv = mut.SetHostname(host).Finalize(getter_AddRefs(url2));
// }
// if (NS_SUCCEEDED(rv)) { /* use url2 */ }
nsresult GetStatus() { return mStatus; }
private:
explicit Mutator(MozURL* url);
mozilla::UniquePtr<rusturl, FreeRustURL> mURL;
bool mFinalized;
nsresult mStatus;
friend class MozURL;
};
Mutator Mutate() { return Mutator(this); }
// These are used to avoid inheriting from nsISupports
public:
NS_IMETHOD_(MozExternalRefCountType) AddRef(void);
NS_IMETHOD_(MozExternalRefCountType) Release(void);
typedef mozilla::TrueType HasThreadSafeRefCnt;
protected:
::mozilla::ThreadSafeAutoRefCnt mRefCnt;
NS_DECL_OWNINGTHREAD
};
} // namespace net
} // namespace mozilla
#endif // mozURL_h__