Commit e92255a0 authored by Kenton Varda's avatar Kenton Varda Committed by GitHub

Merge pull request #491 from sandstorm-io/url

Actually add URL library to makefiles
parents a833fd79 39622d77
...@@ -159,6 +159,7 @@ includekjstd_HEADERS = \ ...@@ -159,6 +159,7 @@ includekjstd_HEADERS = \
includekjcompat_HEADERS = \ includekjcompat_HEADERS = \
src/kj/compat/gtest.h \ src/kj/compat/gtest.h \
src/kj/compat/url.h \
src/kj/compat/http.h src/kj/compat/http.h
includecapnp_HEADERS = \ includecapnp_HEADERS = \
...@@ -249,6 +250,7 @@ libkj_async_la_SOURCES= \ ...@@ -249,6 +250,7 @@ libkj_async_la_SOURCES= \
libkj_http_la_LIBADD = libkj-async.la libkj.la $(ASYNC_LIBS) $(PTHREAD_LIBS) libkj_http_la_LIBADD = libkj-async.la libkj.la $(ASYNC_LIBS) $(PTHREAD_LIBS)
libkj_http_la_LDFLAGS = -release $(SO_VERSION) -no-undefined libkj_http_la_LDFLAGS = -release $(SO_VERSION) -no-undefined
libkj_http_la_SOURCES= \ libkj_http_la_SOURCES= \
src/kj/compat/url.c++ \
src/kj/compat/http.c++ src/kj/compat/http.c++
endif !LITE_MODE endif !LITE_MODE
...@@ -417,6 +419,7 @@ heavy_tests = \ ...@@ -417,6 +419,7 @@ heavy_tests = \
src/kj/parse/common-test.c++ \ src/kj/parse/common-test.c++ \
src/kj/parse/char-test.c++ \ src/kj/parse/char-test.c++ \
src/kj/std/iostream-test.c++ \ src/kj/std/iostream-test.c++ \
src/kj/compat/url-test.c++ \
src/kj/compat/http-test.c++ \ src/kj/compat/http-test.c++ \
src/capnp/canonicalize-test.c++ \ src/capnp/canonicalize-test.c++ \
src/capnp/capability-test.c++ \ src/capnp/capability-test.c++ \
......
...@@ -130,9 +130,11 @@ endif() ...@@ -130,9 +130,11 @@ endif()
# kj-http ====================================================================== # kj-http ======================================================================
set(kj-http_sources set(kj-http_sources
compat/url.c++
compat/http.c++ compat/http.c++
) )
set(kj-http_headers set(kj-http_headers
compat/url.h
compat/http.h compat/http.h
) )
if(NOT CAPNP_LITE) if(NOT CAPNP_LITE)
...@@ -181,6 +183,7 @@ if(BUILD_TESTING) ...@@ -181,6 +183,7 @@ if(BUILD_TESTING)
threadlocal-pthread-test.c++ threadlocal-pthread-test.c++
parse/common-test.c++ parse/common-test.c++
parse/char-test.c++ parse/char-test.c++
compat/url-test.c++
compat/http-test.c++ compat/http-test.c++
) )
target_link_libraries(kj-heavy-tests kj-http kj-async kj-test kj) target_link_libraries(kj-heavy-tests kj-http kj-async kj-test kj)
......
...@@ -272,14 +272,15 @@ KJ_TEST("URL relative paths") { ...@@ -272,14 +272,15 @@ KJ_TEST("URL relative paths") {
KJ_TEST("URL for HTTP request") { KJ_TEST("URL for HTTP request") {
{ {
Url url = Url::parse("https://bob:1234@capnproto.org/foo/bar?baz=qux#corge"); Url url = Url::parse("https://bob:1234@capnproto.org/foo/bar?baz=qux#corge");
KJ_EXPECT(url.toString(Url::GENERAL) == "https://bob:1234@capnproto.org/foo/bar?baz=qux#corge"); KJ_EXPECT(url.toString(Url::REMOTE_HREF) ==
"https://bob:1234@capnproto.org/foo/bar?baz=qux#corge");
KJ_EXPECT(url.toString(Url::HTTP_PROXY_REQUEST) == "https://capnproto.org/foo/bar?baz=qux"); KJ_EXPECT(url.toString(Url::HTTP_PROXY_REQUEST) == "https://capnproto.org/foo/bar?baz=qux");
KJ_EXPECT(url.toString(Url::HTTP_REQUEST) == "/foo/bar?baz=qux"); KJ_EXPECT(url.toString(Url::HTTP_REQUEST) == "/foo/bar?baz=qux");
} }
{ {
Url url = Url::parse("https://capnproto.org"); Url url = Url::parse("https://capnproto.org");
KJ_EXPECT(url.toString(Url::GENERAL) == "https://capnproto.org"); KJ_EXPECT(url.toString(Url::REMOTE_HREF) == "https://capnproto.org");
KJ_EXPECT(url.toString(Url::HTTP_PROXY_REQUEST) == "https://capnproto.org"); KJ_EXPECT(url.toString(Url::HTTP_PROXY_REQUEST) == "https://capnproto.org");
KJ_EXPECT(url.toString(Url::HTTP_REQUEST) == "/"); KJ_EXPECT(url.toString(Url::HTTP_REQUEST) == "/");
} }
......
...@@ -148,7 +148,7 @@ Maybe<Url> Url::tryParse(StringPtr text, Context context) { ...@@ -148,7 +148,7 @@ Maybe<Url> Url::tryParse(StringPtr text, Context context) {
auto authority = split(text, END_AUTHORITY); auto authority = split(text, END_AUTHORITY);
KJ_IF_MAYBE(userpass, trySplit(authority, '@')) { KJ_IF_MAYBE(userpass, trySplit(authority, '@')) {
if (context != GENERAL) { if (context != REMOTE_HREF) {
// No user/pass allowed here. // No user/pass allowed here.
return nullptr; return nullptr;
} }
...@@ -210,7 +210,7 @@ Maybe<Url> Url::tryParse(StringPtr text, Context context) { ...@@ -210,7 +210,7 @@ Maybe<Url> Url::tryParse(StringPtr text, Context context) {
} }
if (text.startsWith("#")) { if (text.startsWith("#")) {
if (context != GENERAL) { if (context != REMOTE_HREF) {
// No fragment allowed here. // No fragment allowed here.
return nullptr; return nullptr;
} }
...@@ -376,7 +376,7 @@ String Url::toString(Context context) const { ...@@ -376,7 +376,7 @@ String Url::toString(Context context) const {
chars.addAll(scheme); chars.addAll(scheme);
chars.addAll(StringPtr("://")); chars.addAll(StringPtr("://"));
if (context == GENERAL) { if (context == REMOTE_HREF) {
KJ_IF_MAYBE(user, userInfo) { KJ_IF_MAYBE(user, userInfo) {
chars.addAll(encodeUriComponent(user->username)); chars.addAll(encodeUriComponent(user->username));
KJ_IF_MAYBE(pass, user->password) { KJ_IF_MAYBE(pass, user->password) {
...@@ -422,7 +422,7 @@ String Url::toString(Context context) const { ...@@ -422,7 +422,7 @@ String Url::toString(Context context) const {
} }
} }
if (context == GENERAL) { if (context == REMOTE_HREF) {
KJ_IF_MAYBE(f, fragment) { KJ_IF_MAYBE(f, fragment) {
chars.add('#'); chars.add('#');
chars.addAll(encodeUriComponent(*f)); chars.addAll(encodeUriComponent(*f));
......
...@@ -28,6 +28,10 @@ ...@@ -28,6 +28,10 @@
namespace kj { namespace kj {
struct Url { struct Url {
// Represents a URL (or, more accurately, a URI, but whatever).
//
// Can be parsed from a string and composed back into a string.
String scheme; String scheme;
// E.g. "http", "https". // E.g. "http", "https".
...@@ -65,12 +69,21 @@ struct Url { ...@@ -65,12 +69,21 @@ struct Url {
Url() = default; Url() = default;
Url(Url&&) = default; Url(Url&&) = default;
~Url() noexcept(false); ~Url() noexcept(false);
Url& operator=(Url&&) = default;
inline Url(String&& scheme, Maybe<UserInfo>&& userInfo, String&& host, Array<String>&& path,
bool hasTrailingSlash, Array<QueryParam>&& query, Maybe<String>&& fragment)
: scheme(kj::mv(scheme)), userInfo(kj::mv(userInfo)), host(kj::mv(host)), path(kj::mv(path)),
hasTrailingSlash(hasTrailingSlash), query(kj::mv(query)), fragment(kj::mv(fragment)) {}
// TODO(cleanup): This constructor is only here to support brace initialization in C++11. It
// should be removed once we upgrade to C++14.
Url clone() const; Url clone() const;
enum Context { enum Context {
GENERAL, REMOTE_HREF,
// The full URL. // A link to a remote resource. Requires an authority (hostname) section, hence this will
// reject things like "mailto:" and "data:". This is the default context.
HTTP_PROXY_REQUEST, HTTP_PROXY_REQUEST,
// The URL to place in the first line of an HTTP proxy request. This includes scheme, host, // The URL to place in the first line of an HTTP proxy request. This includes scheme, host,
...@@ -80,13 +93,16 @@ struct Url { ...@@ -80,13 +93,16 @@ struct Url {
HTTP_REQUEST HTTP_REQUEST
// The path to place in the first line of a regular HTTP request. This includes only the path // The path to place in the first line of a regular HTTP request. This includes only the path
// and query. Scheme, user, host, and fragment are omitted. // and query. Scheme, user, host, and fragment are omitted.
// TODO(someday): Add context(s) that supports things like "mailto:", "data:", "blob:". These
// don't have an authority section.
}; };
kj::String toString(Context context = GENERAL) const; kj::String toString(Context context = REMOTE_HREF) const;
// Convert the URL to a string. // Convert the URL to a string.
static Url parse(StringPtr text, Context context = GENERAL); static Url parse(StringPtr text, Context context = REMOTE_HREF);
static Maybe<Url> tryParse(StringPtr text, Context context = GENERAL); static Maybe<Url> tryParse(StringPtr text, Context context = REMOTE_HREF);
// Parse an absolute URL. // Parse an absolute URL.
Url parseRelative(StringPtr relative) const; Url parseRelative(StringPtr relative) const;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment