summaryrefslogtreecommitdiff
path: root/test/storage
diff options
context:
space:
mode:
Diffstat (limited to 'test/storage')
-rw-r--r--test/storage/cache_response.cpp5
-rw-r--r--test/storage/cache_revalidate.cpp17
-rw-r--r--test/storage/directory_reading.cpp7
-rw-r--r--test/storage/file_reading.cpp17
-rw-r--r--test/storage/http_cancel.cpp14
-rw-r--r--test/storage/http_coalescing.cpp4
-rw-r--r--test/storage/http_environment.cpp54
-rw-r--r--test/storage/http_error.cpp18
-rw-r--r--test/storage/http_header_parsing.cpp10
-rw-r--r--test/storage/http_load.cpp6
-rw-r--r--test/storage/http_noloop.cpp5
-rw-r--r--test/storage/http_other_loop.cpp5
-rw-r--r--test/storage/http_reading.cpp17
-rwxr-xr-xtest/storage/server.js7
14 files changed, 148 insertions, 38 deletions
diff --git a/test/storage/cache_response.cpp b/test/storage/cache_response.cpp
index a0b5ba31c1..ac0dc4c565 100644
--- a/test/storage/cache_response.cpp
+++ b/test/storage/cache_response.cpp
@@ -14,8 +14,9 @@ TEST_F(Storage, CacheResponse) {
DefaultFileSource fs(&cache, uv_default_loop());
const Resource resource { Resource::Unknown, "http://127.0.0.1:3000/cache" };
+ auto &env = *static_cast<const Environment *>(nullptr);
- fs.request(resource, uv_default_loop(), [&](const Response &res) {
+ fs.request(resource, uv_default_loop(), env, [&](const Response &res) {
EXPECT_EQ(Response::Successful, res.status);
EXPECT_EQ("Response 1", res.data);
EXPECT_LT(0, res.expires);
@@ -23,7 +24,7 @@ TEST_F(Storage, CacheResponse) {
EXPECT_EQ("", res.etag);
EXPECT_EQ("", res.message);
- fs.request(resource, uv_default_loop(), [&, res](const Response &res2) {
+ fs.request(resource, uv_default_loop(), env, [&, res](const Response &res2) {
EXPECT_EQ(res.status, res2.status);
EXPECT_EQ(res.data, res2.data);
EXPECT_EQ(res.expires, res2.expires);
diff --git a/test/storage/cache_revalidate.cpp b/test/storage/cache_revalidate.cpp
index 530b7325b5..bd32042b94 100644
--- a/test/storage/cache_revalidate.cpp
+++ b/test/storage/cache_revalidate.cpp
@@ -15,8 +15,10 @@ TEST_F(Storage, CacheRevalidate) {
SQLiteCache cache(":memory:");
DefaultFileSource fs(&cache);
+ auto &env = *static_cast<const Environment *>(nullptr);
+
const Resource revalidateSame { Resource::Unknown, "http://127.0.0.1:3000/revalidate-same" };
- fs.request(revalidateSame, uv_default_loop(), [&](const Response &res) {
+ fs.request(revalidateSame, uv_default_loop(), env, [&](const Response &res) {
EXPECT_EQ(Response::Successful, res.status);
EXPECT_EQ("Response", res.data);
EXPECT_EQ(0, res.expires);
@@ -24,7 +26,7 @@ TEST_F(Storage, CacheRevalidate) {
EXPECT_EQ("snowfall", res.etag);
EXPECT_EQ("", res.message);
- fs.request(revalidateSame, uv_default_loop(), [&, res](const Response &res2) {
+ fs.request(revalidateSame, uv_default_loop(), env, [&, res](const Response &res2) {
EXPECT_EQ(Response::Successful, res2.status);
EXPECT_EQ("Response", res2.data);
// We use this to indicate that a 304 reply came back.
@@ -38,8 +40,9 @@ TEST_F(Storage, CacheRevalidate) {
});
});
- const Resource revalidateModified { Resource::Unknown, "http://127.0.0.1:3000/revalidate-modified" };
- fs.request(revalidateModified, uv_default_loop(), [&](const Response &res) {
+ const Resource revalidateModified{ Resource::Unknown,
+ "http://127.0.0.1:3000/revalidate-modified" };
+ fs.request(revalidateModified, uv_default_loop(), env, [&](const Response &res) {
EXPECT_EQ(Response::Successful, res.status);
EXPECT_EQ("Response", res.data);
EXPECT_EQ(0, res.expires);
@@ -47,7 +50,7 @@ TEST_F(Storage, CacheRevalidate) {
EXPECT_EQ("", res.etag);
EXPECT_EQ("", res.message);
- fs.request(revalidateModified, uv_default_loop(), [&, res](const Response &res2) {
+ fs.request(revalidateModified, uv_default_loop(), env, [&, res](const Response &res2) {
EXPECT_EQ(Response::Successful, res2.status);
EXPECT_EQ("Response", res2.data);
// We use this to indicate that a 304 reply came back.
@@ -61,7 +64,7 @@ TEST_F(Storage, CacheRevalidate) {
});
const Resource revalidateEtag { Resource::Unknown, "http://127.0.0.1:3000/revalidate-etag" };
- fs.request(revalidateEtag, uv_default_loop(), [&](const Response &res) {
+ fs.request(revalidateEtag, uv_default_loop(), env, [&](const Response &res) {
EXPECT_EQ(Response::Successful, res.status);
EXPECT_EQ("Response 1", res.data);
EXPECT_EQ(0, res.expires);
@@ -69,7 +72,7 @@ TEST_F(Storage, CacheRevalidate) {
EXPECT_EQ("response-1", res.etag);
EXPECT_EQ("", res.message);
- fs.request(revalidateEtag, uv_default_loop(), [&, res](const Response &res2) {
+ fs.request(revalidateEtag, uv_default_loop(), env, [&, res](const Response &res2) {
EXPECT_EQ(Response::Successful, res2.status);
EXPECT_EQ("Response 2", res2.data);
EXPECT_EQ(0, res2.expires);
diff --git a/test/storage/directory_reading.cpp b/test/storage/directory_reading.cpp
index 3ee4dd1721..a955648462 100644
--- a/test/storage/directory_reading.cpp
+++ b/test/storage/directory_reading.cpp
@@ -15,7 +15,10 @@ TEST_F(Storage, AssetReadDirectory) {
DefaultFileSource fs(nullptr, uv_default_loop());
#endif
- fs.request({ Resource::Unknown, "asset://TEST_DATA/fixtures/storage" }, uv_default_loop(), [&](const Response &res) {
+ auto &env = *static_cast<const Environment *>(nullptr);
+
+ fs.request({ Resource::Unknown, "asset://TEST_DATA/fixtures/storage" }, uv_default_loop(),
+ env, [&](const Response &res) {
EXPECT_EQ(Response::Error, res.status);
EXPECT_EQ(0ul, res.data.size());
EXPECT_EQ(0, res.expires);
@@ -24,7 +27,7 @@ TEST_F(Storage, AssetReadDirectory) {
#ifdef MBGL_ASSET_ZIP
EXPECT_EQ("No such file", res.message);
#elif MBGL_ASSET_FS
- EXPECT_EQ("illegal operation on a directory", res.message);
+ EXPECT_EQ("illegal operation on a directory", res.message);
#endif
ReadDirectory.finish();
});
diff --git a/test/storage/file_reading.cpp b/test/storage/file_reading.cpp
index 7e14fdcb15..cca072b27a 100644
--- a/test/storage/file_reading.cpp
+++ b/test/storage/file_reading.cpp
@@ -16,9 +16,10 @@ TEST_F(Storage, AssetEmptyFile) {
DefaultFileSource fs(nullptr, uv_default_loop());
#endif
- fs.request({ Resource::Unknown, "asset://TEST_DATA/fixtures/storage/empty" },
- uv_default_loop(),
- [&](const Response &res) {
+ auto &env = *static_cast<const Environment *>(nullptr);
+
+ fs.request({ Resource::Unknown, "asset://TEST_DATA/fixtures/storage/empty" }, uv_default_loop(),
+ env, [&](const Response &res) {
EXPECT_EQ(Response::Successful, res.status);
EXPECT_EQ(0ul, res.data.size());
EXPECT_EQ(0, res.expires);
@@ -42,9 +43,10 @@ TEST_F(Storage, AssetNonEmptyFile) {
DefaultFileSource fs(nullptr, uv_default_loop());
#endif
+ auto &env = *static_cast<const Environment *>(nullptr);
+
fs.request({ Resource::Unknown, "asset://TEST_DATA/fixtures/storage/nonempty" },
- uv_default_loop(),
- [&](const Response &res) {
+ uv_default_loop(), env, [&](const Response &res) {
EXPECT_EQ(Response::Successful, res.status);
EXPECT_EQ(16ul, res.data.size());
EXPECT_EQ(0, res.expires);
@@ -69,9 +71,10 @@ TEST_F(Storage, AssetNonExistentFile) {
DefaultFileSource fs(nullptr, uv_default_loop());
#endif
+ auto &env = *static_cast<const Environment *>(nullptr);
+
fs.request({ Resource::Unknown, "asset://TEST_DATA/fixtures/storage/does_not_exist" },
- uv_default_loop(),
- [&](const Response &res) {
+ uv_default_loop(), env, [&](const Response &res) {
EXPECT_EQ(Response::Error, res.status);
EXPECT_EQ(0ul, res.data.size());
EXPECT_EQ(0, res.expires);
diff --git a/test/storage/http_cancel.cpp b/test/storage/http_cancel.cpp
index 7e485ec42d..d0dac8ccdb 100644
--- a/test/storage/http_cancel.cpp
+++ b/test/storage/http_cancel.cpp
@@ -14,9 +14,11 @@ TEST_F(Storage, HTTPCancel) {
DefaultFileSource fs(nullptr, uv_default_loop());
- auto req = fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test" }, uv_default_loop(), [&](const Response &) {
- ADD_FAILURE() << "Callback should not be called";
- });
+ auto &env = *static_cast<const Environment *>(nullptr);
+
+ auto req =
+ fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test" }, uv_default_loop(), env,
+ [&](const Response &) { ADD_FAILURE() << "Callback should not be called"; });
fs.cancel(req);
HTTPCancel.finish();
@@ -31,11 +33,13 @@ TEST_F(Storage, HTTPCancelMultiple) {
DefaultFileSource fs(nullptr, uv_default_loop());
+ auto &env = *static_cast<const Environment *>(nullptr);
const Resource resource { Resource::Unknown, "http://127.0.0.1:3000/test" };
- auto req2 = fs.request(resource, uv_default_loop(), [&](const Response &) {
+
+ auto req2 = fs.request(resource, uv_default_loop(), env, [&](const Response &) {
ADD_FAILURE() << "Callback should not be called";
});
- fs.request(resource, uv_default_loop(), [&](const Response &res) {
+ fs.request(resource, uv_default_loop(), env, [&](const Response &res) {
EXPECT_EQ(Response::Successful, res.status);
EXPECT_EQ("Hello World!", res.data);
EXPECT_EQ(0, res.expires);
diff --git a/test/storage/http_coalescing.cpp b/test/storage/http_coalescing.cpp
index 592c65f8d6..9eaea70e11 100644
--- a/test/storage/http_coalescing.cpp
+++ b/test/storage/http_coalescing.cpp
@@ -14,6 +14,8 @@ TEST_F(Storage, HTTPCoalescing) {
DefaultFileSource fs(nullptr, uv_default_loop());
+ auto &env = *static_cast<const Environment *>(nullptr);
+
static const Response *reference = nullptr;
const auto complete = [&](const Response &res) {
@@ -41,7 +43,7 @@ TEST_F(Storage, HTTPCoalescing) {
const Resource resource { Resource::Unknown, "http://127.0.0.1:3000/test" };
for (int i = 0; i < total; i++) {
- fs.request(resource, uv_default_loop(), complete);
+ fs.request(resource, uv_default_loop(), env, complete);
}
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
diff --git a/test/storage/http_environment.cpp b/test/storage/http_environment.cpp
new file mode 100644
index 0000000000..efd7b78ad4
--- /dev/null
+++ b/test/storage/http_environment.cpp
@@ -0,0 +1,54 @@
+#include "storage.hpp"
+
+#include <uv.h>
+
+#include <mbgl/storage/default_file_source.hpp>
+#include <mbgl/storage/network_status.hpp>
+
+#include <cmath>
+
+TEST_F(Storage, HTTPCancelEnvironment) {
+ SCOPED_TEST(HTTPRetainedEnvironment)
+ SCOPED_TEST(HTTPCanceledEnvironment)
+
+ using namespace mbgl;
+
+ DefaultFileSource fs(nullptr, uv_default_loop());
+
+ // Create two fake environment pointers. The FileSource implementation treats these as opaque
+ // pointers and doesn't reach into them.
+ auto &env1 = *reinterpret_cast<const Environment *>(1);
+ auto &env2 = *reinterpret_cast<const Environment *>(2);
+
+ const Resource resource { Resource::Unknown, "http://127.0.0.1:3000/delayed" };
+
+ // Environment 1
+ fs.request(resource, uv_default_loop(), env1, [&](const Response &res) {
+ // This environment gets aborted below. This means the request is marked as failing and
+ // will return an error here.
+ EXPECT_EQ(Response::Error, res.status);
+ EXPECT_EQ("", res.data);
+ EXPECT_EQ(0, res.expires);
+ EXPECT_EQ(0, res.modified);
+ EXPECT_EQ("", res.etag);
+ EXPECT_EQ("Environment is terminating", res.message);
+ HTTPCanceledEnvironment.finish();
+ });
+
+ // Environment 2
+ fs.request(resource, uv_default_loop(), env2, [&](const Response &res) {
+ // The same request as above, but in a different environment which doesn't get aborted. This
+ // means the request should succeed.
+ EXPECT_EQ(Response::Successful, res.status);
+ EXPECT_EQ("Response", res.data);
+ EXPECT_EQ(0, res.expires);
+ EXPECT_EQ(0, res.modified);
+ EXPECT_EQ("", res.etag);
+ EXPECT_EQ("", res.message);
+ HTTPRetainedEnvironment.finish();
+ });
+
+ fs.abort(env1);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+}
diff --git a/test/storage/http_error.cpp b/test/storage/http_error.cpp
index 498f1eae6b..abaeff5396 100644
--- a/test/storage/http_error.cpp
+++ b/test/storage/http_error.cpp
@@ -22,9 +22,12 @@ TEST_F(Storage, HTTPError) {
DefaultFileSource fs(nullptr, uv_default_loop());
+ auto &env = *static_cast<const Environment *>(nullptr);
+
auto start = uv_hrtime();
- fs.request({ Resource::Unknown, "http://127.0.0.1:3000/temporary-error" }, uv_default_loop(), [&](const Response &res) {
+ fs.request({ Resource::Unknown, "http://127.0.0.1:3000/temporary-error" }, uv_default_loop(),
+ env, [&](const Response &res) {
const auto duration = double(uv_hrtime() - start) / 1e9;
EXPECT_LT(1, duration) << "Backoff timer didn't wait 1 second";
EXPECT_GT(1.2, duration) << "Backoff timer fired too late";
@@ -38,13 +41,21 @@ TEST_F(Storage, HTTPError) {
HTTPTemporaryError.finish();
});
- fs.request({ Resource::Unknown, "http://127.0.0.1:3001/" }, uv_default_loop(), [&](const Response &res) {
+ fs.request({ Resource::Unknown, "http://127.0.0.1:3001/" }, uv_default_loop(), env,
+ [&](const Response &res) {
const auto duration = double(uv_hrtime() - start) / 1e9;
// 1.5 seconds == 4 retries, with a 500ms timeout (see above).
EXPECT_LT(1.5, duration) << "Resource wasn't retried the correct number of times";
EXPECT_GT(1.7, duration) << "Resource wasn't retried the correct number of times";
EXPECT_EQ(Response::Error, res.status);
- EXPECT_TRUE(res.message == "Couldn't connect to server: couldn't connect to host" || res.message == "The operation couldn’t be completed. (NSURLErrorDomain error -1004.)") << res.message;
+#ifdef MBGL_HTTP_NSURL
+ EXPECT_STREQ(res.message.c_str(), "The operation couldn’t be completed. (NSURLErrorDomain error -1004.)");
+#elif MBGL_HTTP_CURL
+ const std::string prefix { "Couldn't connect to server: " };
+ EXPECT_STREQ(prefix.c_str(), res.message.substr(0, prefix.size()).c_str()) << "Full message is: \"" << res.message << "\"";
+#else
+ FAIL();
+#endif
EXPECT_EQ("", res.data);
EXPECT_EQ(0, res.expires);
EXPECT_EQ(0, res.modified);
@@ -52,7 +63,6 @@ TEST_F(Storage, HTTPError) {
HTTPConnectionError.finish();
});
-
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
uv_timer_stop(&statusChange);
diff --git a/test/storage/http_header_parsing.cpp b/test/storage/http_header_parsing.cpp
index 655348c877..271460387c 100644
--- a/test/storage/http_header_parsing.cpp
+++ b/test/storage/http_header_parsing.cpp
@@ -14,7 +14,11 @@ TEST_F(Storage, HTTPHeaderParsing) {
DefaultFileSource fs(nullptr, uv_default_loop());
- fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test?modified=1420794326&expires=1420797926&etag=foo" }, uv_default_loop(), [&](const Response &res) {
+ auto &env = *static_cast<const Environment *>(nullptr);
+
+ fs.request({ Resource::Unknown,
+ "http://127.0.0.1:3000/test?modified=1420794326&expires=1420797926&etag=foo" },
+ uv_default_loop(), env, [&](const Response &res) {
EXPECT_EQ(Response::Successful, res.status);
EXPECT_EQ("Hello World!", res.data);
EXPECT_EQ(1420797926, res.expires);
@@ -24,11 +28,11 @@ TEST_F(Storage, HTTPHeaderParsing) {
HTTPExpiresTest.finish();
});
-
int64_t now = std::chrono::duration_cast<std::chrono::seconds>(
std::chrono::system_clock::now().time_since_epoch()).count();
- fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test?cachecontrol=max-age=120" }, uv_default_loop(), [&](const Response &res) {
+ fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test?cachecontrol=max-age=120" },
+ uv_default_loop(), env, [&](const Response &res) {
EXPECT_EQ(Response::Successful, res.status);
EXPECT_EQ("Hello World!", res.data);
EXPECT_GT(2, std::abs(res.expires - now - 120)) << "Expiration date isn't about 120 seconds in the future";
diff --git a/test/storage/http_load.cpp b/test/storage/http_load.cpp
index fff662da29..2680daf93b 100644
--- a/test/storage/http_load.cpp
+++ b/test/storage/http_load.cpp
@@ -11,13 +11,17 @@ TEST_F(Storage, HTTPLoad) {
DefaultFileSource fs(nullptr, uv_default_loop());
+ auto &env = *static_cast<const Environment *>(nullptr);
+
const int concurrency = 50;
const int max = 10000;
int number = 1;
std::function<void()> req = [&]() {
const auto current = number++;
- fs.request({ Resource::Unknown, std::string("http://127.0.0.1:3000/load/") + std::to_string(current) }, uv_default_loop(), [&, current](const Response &res) {
+ fs.request({ Resource::Unknown,
+ std::string("http://127.0.0.1:3000/load/") + std::to_string(current) },
+ uv_default_loop(), env, [&, current](const Response &res) {
EXPECT_EQ(Response::Successful, res.status);
EXPECT_EQ(std::string("Request ") + std::to_string(current), res.data);
EXPECT_EQ(0, res.expires);
diff --git a/test/storage/http_noloop.cpp b/test/storage/http_noloop.cpp
index c71fd0bc26..cd4ebeb2c4 100644
--- a/test/storage/http_noloop.cpp
+++ b/test/storage/http_noloop.cpp
@@ -12,6 +12,8 @@ TEST_F(Storage, HTTPNoLoop) {
DefaultFileSource fs(nullptr);
+ auto &env = *static_cast<const Environment *>(nullptr);
+
const auto mainThread = uv_thread_self();
// Async handle that keeps the main loop alive until the thread finished
@@ -20,7 +22,8 @@ TEST_F(Storage, HTTPNoLoop) {
uv::close(as);
});
- fs.request({ Resource::Unknown, "http://127.0.0.1:3000/temporary-error" }, [&](const Response &res) {
+ fs.request({ Resource::Unknown, "http://127.0.0.1:3000/temporary-error" }, nullptr, env,
+ [&](const Response &res) {
EXPECT_NE(uv_thread_self(), mainThread) << "Response was called in the same thread";
EXPECT_EQ(Response::Successful, res.status);
EXPECT_EQ("Hello World!", res.data);
diff --git a/test/storage/http_other_loop.cpp b/test/storage/http_other_loop.cpp
index 06cc6f7476..9ad673cf79 100644
--- a/test/storage/http_other_loop.cpp
+++ b/test/storage/http_other_loop.cpp
@@ -12,7 +12,10 @@ TEST_F(Storage, HTTPOtherLoop) {
// This file source launches a separate thread to do the processing.
DefaultFileSource fs(nullptr);
- fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test" }, uv_default_loop(), [&](const Response &res) {
+ auto &env = *static_cast<const Environment *>(nullptr);
+
+ fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test" }, uv_default_loop(), env,
+ [&](const Response &res) {
EXPECT_EQ(Response::Successful, res.status);
EXPECT_EQ("Hello World!", res.data);
EXPECT_EQ(0, res.expires);
diff --git a/test/storage/http_reading.cpp b/test/storage/http_reading.cpp
index ad87db15ff..a6a5775825 100644
--- a/test/storage/http_reading.cpp
+++ b/test/storage/http_reading.cpp
@@ -12,9 +12,12 @@ TEST_F(Storage, HTTPReading) {
DefaultFileSource fs(nullptr, uv_default_loop());
+ auto &env = *static_cast<const Environment *>(nullptr);
+
const auto mainThread = uv_thread_self();
- fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test" }, uv_default_loop(), [&](const Response &res) {
+ fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test" }, uv_default_loop(), env,
+ [&](const Response &res) {
EXPECT_EQ(uv_thread_self(), mainThread);
EXPECT_EQ(Response::Successful, res.status);
EXPECT_EQ("Hello World!", res.data);
@@ -25,7 +28,8 @@ TEST_F(Storage, HTTPReading) {
HTTPTest.finish();
});
- fs.request({ Resource::Unknown, "http://127.0.0.1:3000/doesnotexist" }, uv_default_loop(), [&](const Response &res) {
+ fs.request({ Resource::Unknown, "http://127.0.0.1:3000/doesnotexist" }, uv_default_loop(),
+ env, [&](const Response &res) {
EXPECT_EQ(uv_thread_self(), mainThread);
EXPECT_EQ(Response::Error, res.status);
EXPECT_EQ("HTTP status code 404", res.message);
@@ -45,7 +49,10 @@ TEST_F(Storage, HTTPNoCallback) {
DefaultFileSource fs(nullptr, uv_default_loop());
- fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test" }, uv_default_loop(), nullptr);
+ auto &env = *static_cast<const Environment *>(nullptr);
+
+ fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test" }, uv_default_loop(), env,
+ nullptr);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
@@ -59,7 +66,9 @@ TEST_F(Storage, HTTPNoCallbackNoLoop) {
DefaultFileSource fs(nullptr, uv_default_loop());
- fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test" }, nullptr);
+ auto &env = *static_cast<const Environment *>(nullptr);
+
+ fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test" }, env, nullptr);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
diff --git a/test/storage/server.js b/test/storage/server.js
index 33d5a82985..1ee5363196 100755
--- a/test/storage/server.js
+++ b/test/storage/server.js
@@ -85,6 +85,13 @@ app.get('/temporary-error', function(req, res) {
temporaryErrorCounter++;
});
+app.get('/delayed', function(req, res) {
+ setTimeout(function() {
+ res.status(200).send('Response');
+ }, 200);
+});
+
+
app.get('/load/:number(\\d+)', function(req, res) {
res.send('Request ' + req.params.number);
});