@@ -20,7 +20,7 @@ my %module_build_args = (
"Dancer Core Developers"
],
"dist_name" => "Dancer2",
- "dist_version" => "0.156001",
+ "dist_version" => "0.157000",
"license" => "perl",
"module_name" => "Dancer2",
"recommends" => {
@@ -59,10 +59,10 @@ my %module_build_args = (
"HTTP::Date" => 0,
"HTTP::Headers" => 0,
"HTTP::Server::PSGI" => 0,
+ "HTTP::Tiny" => 0,
"Hash::Merge::Simple" => 0,
"IO::File" => 0,
"JSON" => 0,
- "LWP::UserAgent" => 0,
"List::Util" => 0,
"MIME::Base64" => "3.13",
"MIME::Types" => 0,
@@ -115,19 +115,17 @@ my %module_build_args = (
"File::Temp" => "0.22",
"FindBin" => 0,
"HTTP::Body" => 0,
+ "HTTP::Cookies" => 0,
"HTTP::Request" => 0,
"HTTP::Request::Common" => 0,
"IO::Handle" => 0,
"IPC::Open3" => 0,
- "LWP::Protocol::PSGI" => "0.06",
"Plack::Response" => 0,
"Plack::Test" => 0,
"Test::Fatal" => 0,
"Test::Memory::Cycle" => "1.04",
"Test::MockTime" => 0,
"Test::More" => "0.92",
- "Test::Script" => 0,
- "Test::TCP" => "1.13",
"YAML" => 0,
"lib" => 0,
"perl" => "5.006",
@@ -144,11 +142,11 @@ my %fallback_build_requires = (
"File::Temp" => "0.22",
"FindBin" => 0,
"HTTP::Body" => 0,
+ "HTTP::Cookies" => 0,
"HTTP::Request" => 0,
"HTTP::Request::Common" => 0,
"IO::Handle" => 0,
"IPC::Open3" => 0,
- "LWP::Protocol::PSGI" => "0.06",
"Module::Build" => "0.3601",
"Plack::Response" => 0,
"Plack::Test" => 0,
@@ -156,8 +154,6 @@ my %fallback_build_requires = (
"Test::Memory::Cycle" => "1.04",
"Test::MockTime" => 0,
"Test::More" => "0.92",
- "Test::Script" => 0,
- "Test::TCP" => "1.13",
"YAML" => 0,
"lib" => 0,
"perl" => "5.006",
@@ -1,3 +1,31 @@
+0.157000 2014-12-14 18:23:33+01:00 Europe/Amsterdam
+
+ [ BUG FIXES ]
+ * GH #799: Set current request earlier so log formats using requests
+ will work. (Sawyer X)
+ * GH #650: Provide default environment to app for templating.
+ (Dávid Kovács, Chi Trinh)
+ * GH #800: Better portability code, for different Windows situations.
+ (Christian Walde)
+ * Less littering of the test directories with session files. (Sawyer X)
+
+ [ ENHANCEMENT ]
+ * GH #810: strict && warnings in the app.pl. (Sawyer X)
+ * Use to_app keyword in skeleton. (Sawyer X)
+ * GH #801: Under production, server tokens are disabled. (Sawyer X)
+ * GH #588, #779: Remove LWP::UserAgent in favor of HTTP::Tiny.
+ (Dávid Kovács, simbabque, Sawyer X)
+ * Remove all usages of Test::TCP in favor of Plack::Test. (Sawyer X)
+
+ [ DOCUMENTATION ]
+ * GH #802: Remove indication of warnings configuration option
+ and add explanation in migration document. (Sawyer X)
+ * GH #806: Link in main docs to the migration document. (Gabor Szabo)
+ * GH #807: Update migration document with more session data,
+ changes to app.pl, and Template::Toolkit configuration. (Gabor Szabo)
+ * GH #813: Update migration document with information on encoding and
+ usage of Plack::Request internally. (Gabor Szabo, Sawyer X)
+
0.156001 2014-12-08 23:03:43+01:00 Europe/Amsterdam
[ DOCUMENTATION ]
@@ -16,7 +16,6 @@ lib/Dancer2/CLI/Command/version.pm
lib/Dancer2/Config.pod
lib/Dancer2/Cookbook.pod
lib/Dancer2/Core.pm
-lib/Dancer2/Core/.Request.pm.swp
lib/Dancer2/Core/App.pm
lib/Dancer2/Core/Cookie.pm
lib/Dancer2/Core/DSL.pm
@@ -189,10 +188,13 @@ t/issues/gh-639/fails/issue.t
t/issues/gh-639/succeeds/.dancer
t/issues/gh-639/succeeds/config.yml
t/issues/gh-639/succeeds/issue.t
+t/issues/gh-650/gh-650.t
+t/issues/gh-650/views/environment_setting.tt
t/issues/gh-723.t
t/issues/gh-730.t
t/issues/gh-794.t
t/issues/gh-797.t
+t/issues/gh-799.t
t/lib/App1.pm
t/lib/App2.pm
t/lib/DancerPlugin.pm
@@ -209,7 +211,6 @@ t/log_die_before_hook.t
t/log_levels.t
t/logger.t
t/logger_console.t
-t/lwp-protocol-psgi.t
t/memory_cycles.t
t/mime.t
t/multi_apps.t
@@ -259,6 +260,14 @@ t/sessions/VINylQAATxmWhwaQwYTVls-P09SzyCsc.yml
t/sessions/VINziwAAUHovk3nfMmkf2GHI6RNrE38c.yml
t/sessions/VIOBYgAAZD-3UeYHGxJmpPkpI8hOgUvW.yml
t/sessions/VISIVwAASGBJcMXNsII2nVrChuLAP7pm.yml
+t/sessions/VIlt7wAAceLduiKWlnAkCQpsRFe9RwmE.yml
+t/sessions/VIltdAAAcGUtpuNeagm8uMqOmg1iO5BG.yml
+t/sessions/VIxX-gAAaW6BYt4htdZy0O9_g5J3WdHM.yml
+t/sessions/VIxY0wAAan1F1Maz4h8_pCnhMdtstSHX.yml
+t/sessions/VIxi3AAAfpilI1rk9Tg_5c29HVaYBclB.yml
+t/sessions/VIxiTQAAfYHVHQ5txQKuXTwZ7alch-Gc.yml
+t/sessions/VIxj4wAAAakb1qv0OYF9_oA_WrIqImY7.yml
+t/sessions/VIxkLgAABBzH8FV-MYjgAOQrJuLhWOkM.yml
t/shared_engines.t
t/template.t
t/template_default_tokens.t
@@ -70,10 +70,10 @@
"HTTP::Date" : "0",
"HTTP::Headers" : "0",
"HTTP::Server::PSGI" : "0",
+ "HTTP::Tiny" : "0",
"Hash::Merge::Simple" : "0",
"IO::File" : "0",
"JSON" : "0",
- "LWP::UserAgent" : "0",
"List::Util" : "0",
"MIME::Base64" : "3.13",
"MIME::Types" : "0",
@@ -130,19 +130,17 @@
"File::Temp" : "0.22",
"FindBin" : "0",
"HTTP::Body" : "0",
+ "HTTP::Cookies" : "0",
"HTTP::Request" : "0",
"HTTP::Request::Common" : "0",
"IO::Handle" : "0",
"IPC::Open3" : "0",
- "LWP::Protocol::PSGI" : "0.06",
"Plack::Response" : "0",
"Plack::Test" : "0",
"Test::Fatal" : "0",
"Test::Memory::Cycle" : "1.04",
"Test::MockTime" : "0",
"Test::More" : "0.92",
- "Test::Script" : "0",
- "Test::TCP" : "1.13",
"YAML" : "0",
"lib" : "0",
"perl" : "5.006",
@@ -154,231 +152,231 @@
"provides" : {
"Dancer2" : {
"file" : "lib/Dancer2.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::CLI" : {
"file" : "lib/Dancer2/CLI.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::CLI::Command::gen" : {
"file" : "lib/Dancer2/CLI/Command/gen.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::CLI::Command::version" : {
"file" : "lib/Dancer2/CLI/Command/version.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core" : {
"file" : "lib/Dancer2/Core.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::App" : {
"file" : "lib/Dancer2/Core/App.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::Cookie" : {
"file" : "lib/Dancer2/Core/Cookie.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::DSL" : {
"file" : "lib/Dancer2/Core/DSL.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::Dispatcher" : {
"file" : "lib/Dancer2/Core/Dispatcher.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::Error" : {
"file" : "lib/Dancer2/Core/Error.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::Factory" : {
"file" : "lib/Dancer2/Core/Factory.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::HTTP" : {
"file" : "lib/Dancer2/Core/HTTP.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::Hook" : {
"file" : "lib/Dancer2/Core/Hook.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::MIME" : {
"file" : "lib/Dancer2/Core/MIME.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::Request" : {
"file" : "lib/Dancer2/Core/Request.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::Request::Upload" : {
"file" : "lib/Dancer2/Core/Request/Upload.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::Response" : {
"file" : "lib/Dancer2/Core/Response.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::Role::ConfigReader" : {
"file" : "lib/Dancer2/Core/Role/ConfigReader.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::Role::DSL" : {
"file" : "lib/Dancer2/Core/Role/DSL.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::Role::Engine" : {
"file" : "lib/Dancer2/Core/Role/Engine.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::Role::Handler" : {
"file" : "lib/Dancer2/Core/Role/Handler.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::Role::HasLocation" : {
"file" : "lib/Dancer2/Core/Role/HasLocation.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::Role::Headers" : {
"file" : "lib/Dancer2/Core/Role/Headers.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::Role::Hookable" : {
"file" : "lib/Dancer2/Core/Role/Hookable.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::Role::Logger" : {
"file" : "lib/Dancer2/Core/Role/Logger.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::Role::Serializer" : {
"file" : "lib/Dancer2/Core/Role/Serializer.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::Role::SessionFactory" : {
"file" : "lib/Dancer2/Core/Role/SessionFactory.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::Role::SessionFactory::File" : {
"file" : "lib/Dancer2/Core/Role/SessionFactory/File.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::Role::StandardResponses" : {
"file" : "lib/Dancer2/Core/Role/StandardResponses.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::Role::Template" : {
"file" : "lib/Dancer2/Core/Role/Template.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::Route" : {
"file" : "lib/Dancer2/Core/Route.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::Runner" : {
"file" : "lib/Dancer2/Core/Runner.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::Session" : {
"file" : "lib/Dancer2/Core/Session.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::Time" : {
"file" : "lib/Dancer2/Core/Time.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Core::Types" : {
"file" : "lib/Dancer2/Core/Types.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::FileUtils" : {
"file" : "lib/Dancer2/FileUtils.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Handler::AutoPage" : {
"file" : "lib/Dancer2/Handler/AutoPage.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Handler::File" : {
"file" : "lib/Dancer2/Handler/File.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Logger::Capture" : {
"file" : "lib/Dancer2/Logger/Capture.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Logger::Capture::Trap" : {
"file" : "lib/Dancer2/Logger/Capture/Trap.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Logger::Console" : {
"file" : "lib/Dancer2/Logger/Console.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Logger::Diag" : {
"file" : "lib/Dancer2/Logger/Diag.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Logger::File" : {
"file" : "lib/Dancer2/Logger/File.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Logger::Note" : {
"file" : "lib/Dancer2/Logger/Note.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Logger::Null" : {
"file" : "lib/Dancer2/Logger/Null.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Plugin" : {
"file" : "lib/Dancer2/Plugin.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Serializer::Dumper" : {
"file" : "lib/Dancer2/Serializer/Dumper.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Serializer::JSON" : {
"file" : "lib/Dancer2/Serializer/JSON.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Serializer::Mutable" : {
"file" : "lib/Dancer2/Serializer/Mutable.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Serializer::YAML" : {
"file" : "lib/Dancer2/Serializer/YAML.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Session::Simple" : {
"file" : "lib/Dancer2/Session/Simple.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Session::YAML" : {
"file" : "lib/Dancer2/Session/YAML.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Template::Implementation::ForkedTiny" : {
"file" : "lib/Dancer2/Template/Implementation/ForkedTiny.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Template::Simple" : {
"file" : "lib/Dancer2/Template/Simple.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Template::TemplateToolkit" : {
"file" : "lib/Dancer2/Template/TemplateToolkit.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Template::Tiny" : {
"file" : "lib/Dancer2/Template/Tiny.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
},
"Dancer2::Test" : {
"file" : "lib/Dancer2/Test.pm",
- "version" : "0.156001"
+ "version" : "0.157000"
}
},
"release_status" : "stable",
@@ -395,6 +393,6 @@
"x_IRC" : "irc://irc.perl.org/#dancer",
"x_WebIRC" : "https://chat.mibbit.com/#dancer@irc.perl.org"
},
- "version" : "0.156001"
+ "version" : "0.157000"
}
@@ -9,11 +9,11 @@ build_requires:
File::Temp: 0.22
FindBin: 0
HTTP::Body: 0
+ HTTP::Cookies: 0
HTTP::Request: 0
HTTP::Request::Common: 0
IO::Handle: 0
IPC::Open3: 0
- LWP::Protocol::PSGI: 0.06
Module::Build: 0.3601
Plack::Response: 0
Plack::Test: 0
@@ -21,8 +21,6 @@ build_requires:
Test::Memory::Cycle: 1.04
Test::MockTime: 0
Test::More: 0.92
- Test::Script: 0
- Test::TCP: 1.13
YAML: 0
lib: 0
perl: 5.006
@@ -42,175 +40,175 @@ name: Dancer2
provides:
Dancer2:
file: lib/Dancer2.pm
- version: 0.156001
+ version: 0.157000
Dancer2::CLI:
file: lib/Dancer2/CLI.pm
- version: 0.156001
+ version: 0.157000
Dancer2::CLI::Command::gen:
file: lib/Dancer2/CLI/Command/gen.pm
- version: 0.156001
+ version: 0.157000
Dancer2::CLI::Command::version:
file: lib/Dancer2/CLI/Command/version.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core:
file: lib/Dancer2/Core.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::App:
file: lib/Dancer2/Core/App.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::Cookie:
file: lib/Dancer2/Core/Cookie.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::DSL:
file: lib/Dancer2/Core/DSL.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::Dispatcher:
file: lib/Dancer2/Core/Dispatcher.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::Error:
file: lib/Dancer2/Core/Error.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::Factory:
file: lib/Dancer2/Core/Factory.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::HTTP:
file: lib/Dancer2/Core/HTTP.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::Hook:
file: lib/Dancer2/Core/Hook.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::MIME:
file: lib/Dancer2/Core/MIME.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::Request:
file: lib/Dancer2/Core/Request.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::Request::Upload:
file: lib/Dancer2/Core/Request/Upload.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::Response:
file: lib/Dancer2/Core/Response.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::Role::ConfigReader:
file: lib/Dancer2/Core/Role/ConfigReader.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::Role::DSL:
file: lib/Dancer2/Core/Role/DSL.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::Role::Engine:
file: lib/Dancer2/Core/Role/Engine.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::Role::Handler:
file: lib/Dancer2/Core/Role/Handler.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::Role::HasLocation:
file: lib/Dancer2/Core/Role/HasLocation.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::Role::Headers:
file: lib/Dancer2/Core/Role/Headers.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::Role::Hookable:
file: lib/Dancer2/Core/Role/Hookable.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::Role::Logger:
file: lib/Dancer2/Core/Role/Logger.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::Role::Serializer:
file: lib/Dancer2/Core/Role/Serializer.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::Role::SessionFactory:
file: lib/Dancer2/Core/Role/SessionFactory.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::Role::SessionFactory::File:
file: lib/Dancer2/Core/Role/SessionFactory/File.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::Role::StandardResponses:
file: lib/Dancer2/Core/Role/StandardResponses.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::Role::Template:
file: lib/Dancer2/Core/Role/Template.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::Route:
file: lib/Dancer2/Core/Route.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::Runner:
file: lib/Dancer2/Core/Runner.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::Session:
file: lib/Dancer2/Core/Session.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::Time:
file: lib/Dancer2/Core/Time.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Core::Types:
file: lib/Dancer2/Core/Types.pm
- version: 0.156001
+ version: 0.157000
Dancer2::FileUtils:
file: lib/Dancer2/FileUtils.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Handler::AutoPage:
file: lib/Dancer2/Handler/AutoPage.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Handler::File:
file: lib/Dancer2/Handler/File.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Logger::Capture:
file: lib/Dancer2/Logger/Capture.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Logger::Capture::Trap:
file: lib/Dancer2/Logger/Capture/Trap.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Logger::Console:
file: lib/Dancer2/Logger/Console.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Logger::Diag:
file: lib/Dancer2/Logger/Diag.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Logger::File:
file: lib/Dancer2/Logger/File.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Logger::Note:
file: lib/Dancer2/Logger/Note.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Logger::Null:
file: lib/Dancer2/Logger/Null.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Plugin:
file: lib/Dancer2/Plugin.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Serializer::Dumper:
file: lib/Dancer2/Serializer/Dumper.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Serializer::JSON:
file: lib/Dancer2/Serializer/JSON.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Serializer::Mutable:
file: lib/Dancer2/Serializer/Mutable.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Serializer::YAML:
file: lib/Dancer2/Serializer/YAML.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Session::Simple:
file: lib/Dancer2/Session/Simple.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Session::YAML:
file: lib/Dancer2/Session/YAML.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Template::Implementation::ForkedTiny:
file: lib/Dancer2/Template/Implementation/ForkedTiny.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Template::Simple:
file: lib/Dancer2/Template/Simple.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Template::TemplateToolkit:
file: lib/Dancer2/Template/TemplateToolkit.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Template::Tiny:
file: lib/Dancer2/Template/Tiny.pm
- version: 0.156001
+ version: 0.157000
Dancer2::Test:
file: lib/Dancer2/Test.pm
- version: 0.156001
+ version: 0.157000
recommends:
CGI::Deurl::XS: 0
Crypt::URandom: 0
@@ -245,10 +243,10 @@ requires:
HTTP::Date: 0
HTTP::Headers: 0
HTTP::Server::PSGI: 0
+ HTTP::Tiny: 0
Hash::Merge::Simple: 0
IO::File: 0
JSON: 0
- LWP::UserAgent: 0
List::Util: 0
MIME::Base64: 3.13
MIME::Types: 0
@@ -293,4 +291,4 @@ resources:
bugtracker: https://github.com/PerlDancer/Dancer2/issues
homepage: http://perldancer.org/
repository: git://github.com/PerlDancer/Dancer2.git
-version: 0.156001
+version: 0.157000
@@ -54,10 +54,10 @@ my %WriteMakefileArgs = (
"HTTP::Date" => 0,
"HTTP::Headers" => 0,
"HTTP::Server::PSGI" => 0,
+ "HTTP::Tiny" => 0,
"Hash::Merge::Simple" => 0,
"IO::File" => 0,
"JSON" => 0,
- "LWP::UserAgent" => 0,
"List::Util" => 0,
"MIME::Base64" => "3.13",
"MIME::Types" => 0,
@@ -103,27 +103,25 @@ my %WriteMakefileArgs = (
"File::Temp" => "0.22",
"FindBin" => 0,
"HTTP::Body" => 0,
+ "HTTP::Cookies" => 0,
"HTTP::Request" => 0,
"HTTP::Request::Common" => 0,
"IO::Handle" => 0,
"IPC::Open3" => 0,
- "LWP::Protocol::PSGI" => "0.06",
"Plack::Response" => 0,
"Plack::Test" => 0,
"Test::Fatal" => 0,
"Test::Memory::Cycle" => "1.04",
"Test::MockTime" => 0,
"Test::More" => "0.92",
- "Test::Script" => 0,
- "Test::TCP" => "1.13",
"YAML" => 0,
"lib" => 0,
"utf8" => 0,
"vars" => 0
},
- "VERSION" => "0.156001",
+ "VERSION" => "0.157000",
"test" => {
- "TESTS" => "t/*.t t/classes/Dancer2-Core-Factory/*.t t/classes/Dancer2-Core-Hook/*.t t/classes/Dancer2-Core-Request/*.t t/classes/Dancer2-Core-Response/*.t t/classes/Dancer2-Core-Role-Engine/*.t t/classes/Dancer2-Core-Role-Handler/*.t t/classes/Dancer2-Core-Role-HasLocation/*.t t/classes/Dancer2-Core-Role-Headers/*.t t/classes/Dancer2-Core-Role-Serializer/*.t t/classes/Dancer2-Core-Role-StandardResponses/*.t t/classes/Dancer2-Core-Route/*.t t/classes/Dancer2-Core-Runner/*.t t/classes/Dancer2-Core/*.t t/classes/Dancer2/*.t t/dsl/*.t t/issues/*.t t/issues/gh-639/fails/*.t t/issues/gh-639/succeeds/*.t t/roles/*.t t/route-pod-coverage/*.t t/scope_problems/*.t t/template_tiny/*.t"
+ "TESTS" => "t/*.t t/classes/Dancer2-Core-Factory/*.t t/classes/Dancer2-Core-Hook/*.t t/classes/Dancer2-Core-Request/*.t t/classes/Dancer2-Core-Response/*.t t/classes/Dancer2-Core-Role-Engine/*.t t/classes/Dancer2-Core-Role-Handler/*.t t/classes/Dancer2-Core-Role-HasLocation/*.t t/classes/Dancer2-Core-Role-Headers/*.t t/classes/Dancer2-Core-Role-Serializer/*.t t/classes/Dancer2-Core-Role-StandardResponses/*.t t/classes/Dancer2-Core-Route/*.t t/classes/Dancer2-Core-Runner/*.t t/classes/Dancer2-Core/*.t t/classes/Dancer2/*.t t/dsl/*.t t/issues/*.t t/issues/gh-639/fails/*.t t/issues/gh-639/succeeds/*.t t/issues/gh-650/*.t t/roles/*.t t/route-pod-coverage/*.t t/scope_problems/*.t t/template_tiny/*.t"
}
);
@@ -152,18 +150,18 @@ my %FallbackPrereqs = (
"File::Temp" => "0.22",
"FindBin" => 0,
"HTTP::Body" => 0,
+ "HTTP::Cookies" => 0,
"HTTP::Date" => 0,
"HTTP::Headers" => 0,
"HTTP::Request" => 0,
"HTTP::Request::Common" => 0,
"HTTP::Server::PSGI" => 0,
+ "HTTP::Tiny" => 0,
"Hash::Merge::Simple" => 0,
"IO::File" => 0,
"IO::Handle" => 0,
"IPC::Open3" => 0,
"JSON" => 0,
- "LWP::Protocol::PSGI" => "0.06",
- "LWP::UserAgent" => 0,
"List::Util" => 0,
"MIME::Base64" => "3.13",
"MIME::Types" => 0,
@@ -199,8 +197,6 @@ my %FallbackPrereqs = (
"Test::Memory::Cycle" => "1.04",
"Test::MockTime" => 0,
"Test::More" => "0.92",
- "Test::Script" => 0,
- "Test::TCP" => "1.13",
"Try::Tiny" => 0,
"URI" => 0,
"URI::Escape" => 0,
@@ -1,13 +1,13 @@
# ABSTRACT: create new Dancer2 application
package Dancer2::CLI::Command::gen;
-$Dancer2::CLI::Command::gen::VERSION = '0.156001';
+$Dancer2::CLI::Command::gen::VERSION = '0.157000';
use strict;
use warnings;
use App::Cmd::Setup -command;
+use HTTP::Tiny;
use File::Find;
-use LWP::UserAgent;
use File::Path 'mkpath';
use File::Spec::Functions;
use File::ShareDir 'dist_dir';
@@ -259,12 +259,10 @@ Please check http://search.cpan.org/dist/Dancer2/ for updates.
sub _send_http_request {
my $url = shift;
- my $ua = LWP::UserAgent->new;
- $ua->timeout(5);
- $ua->env_proxy();
+ my $ua = HTTP::Tiny->new( timeout => 5 );
my $response = $ua->get($url);
- return $response->is_success ? $response->content : undef;
+ return $response->{'success'} ? $response->{'content'} : undef;
}
1;
@@ -281,7 +279,7 @@ Dancer2::CLI::Command::gen - create new Dancer2 application
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 AUTHOR
@@ -1,6 +1,6 @@
package Dancer2::CLI::Command::version;
# ABSTRACT: display version
-$Dancer2::CLI::Command::version::VERSION = '0.156001';
+$Dancer2::CLI::Command::version::VERSION = '0.157000';
use App::Cmd::Setup -command;
sub description { 'Display version of Dancer2' }
@@ -29,7 +29,7 @@ Dancer2::CLI::Command::version - display version
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 AUTHOR
@@ -1,6 +1,6 @@
package Dancer2::CLI;
# ABSTRACT: Dancer2 cli application
-$Dancer2::CLI::VERSION = '0.156001';
+$Dancer2::CLI::VERSION = '0.157000';
use App::Cmd::Setup -app;
1;
@@ -17,7 +17,7 @@ Dancer2::CLI - Dancer2 cli application
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 AUTHOR
@@ -1,6 +1,6 @@
package Dancer2::Config;
# ABSTRACT: Configure Dancer2 to suit your needs
-$Dancer2::Config::VERSION = '0.156001';
+$Dancer2::Config::VERSION = '0.157000';
__END__
=pod
@@ -13,7 +13,7 @@ Dancer2::Config - Configure Dancer2 to suit your needs
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -284,10 +284,6 @@ versions and the environment (or "dancefloor").
Conforms to the environment variable C<DANCER_STARTUP_INFO>.
-=head3 warnings (boolean)
-
-If set to true, tells Dancer2 to consider all warnings as blocking errors.
-
=head3 traces (boolean)
If set to true, Dancer2 will display full stack traces when a warning or a
@@ -1,6 +1,6 @@
package Dancer2::Cookbook;
# ABSTRACT: Example-driven quick-start to the Dancer2 web framework
-$Dancer2::Cookbook::VERSION = '0.156001';
+$Dancer2::Cookbook::VERSION = '0.157000';
__END__
=pod
@@ -13,7 +13,7 @@ Dancer2::Cookbook - Example-driven quick-start to the Dancer2 web framework
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
diff --git a/var/tmp/source/XSAWYERX/Dancer2-0.156001/Dancer2-0.156001/lib/Dancer2/Core/.Request.pm.swp b/var/tmp/source/XSAWYERX/Dancer2-0.156001/Dancer2-0.156001/lib/Dancer2/Core/.Request.pm.swp
deleted file mode 100644
index b7d14719..00000000
Binary files a/var/tmp/source/XSAWYERX/Dancer2-0.156001/Dancer2-0.156001/lib/Dancer2/Core/.Request.pm.swp and /dev/null differ
@@ -1,6 +1,6 @@
# ABSTRACT: encapsulation of Dancer2 packages
package Dancer2::Core::App;
-$Dancer2::Core::App::VERSION = '0.156001';
+$Dancer2::Core::App::VERSION = '0.157000';
use Moo;
use Carp 'croak';
use Scalar::Util 'blessed';
@@ -531,6 +531,7 @@ sub _build_default_config {
logger => ( $ENV{DANCER_LOGGER} || 'console' ),
views => ( $ENV{DANCER_VIEWS}
|| path( $self->config_location, 'views' ) ),
+ environment => $self->environment,
appdir => $self->location,
public_dir => $public,
static_handler => ( -d $public ),
@@ -1098,6 +1099,10 @@ DISPATCH:
my $http_method = lc $request->method;
my $path_info = $request->path_info;
+ # Add request to app and engines
+ $self->set_request($request);
+ $_->set_request( $request ) for $self->defined_engines;
+
$self->log( core => "looking for $http_method $path_info" );
ROUTE:
@@ -1111,10 +1116,6 @@ DISPATCH:
$request->_set_route_params($match);
- # Add request to app and engines
- $self->set_request($request);
- $_->set_request( $request ) for $self->defined_engines;
-
# Add session to app *if* we have a session and the request
# has the appropriate cookie header for _this_ app.
if ( my $sess = Dancer2->runner->{'internal_sessions'}{$cname} ) {
@@ -1311,7 +1312,7 @@ Dancer2::Core::App - encapsulation of Dancer2 packages
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Core::Cookie;
# ABSTRACT: A cookie representing class
-$Dancer2::Core::Cookie::VERSION = '0.156001';
+$Dancer2::Core::Cookie::VERSION = '0.157000';
use Moo;
use URI::Escape;
use Dancer2::Core::Types;
@@ -106,7 +106,7 @@ Dancer2::Core::Cookie - A cookie representing class
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 SYNOPSIS
@@ -1,7 +1,7 @@
# ABSTRACT: Dancer2's Domain Specific Language (DSL)
package Dancer2::Core::DSL;
-$Dancer2::Core::DSL::VERSION = '0.156001';
+$Dancer2::Core::DSL::VERSION = '0.157000';
use Moo;
use Carp;
use Class::Load 'load_class';
@@ -400,7 +400,7 @@ Dancer2::Core::DSL - Dancer2's Domain Specific Language (DSL)
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 FUNCTIONS
@@ -1,6 +1,6 @@
package Dancer2::Core::Dispatcher;
# ABSTRACT: Class for dispatching request to the appropriate route handler
-$Dancer2::Core::Dispatcher::VERSION = '0.156001';
+$Dancer2::Core::Dispatcher::VERSION = '0.157000';
use Moo;
use Dancer2::Core::Types;
@@ -70,7 +70,7 @@ Dancer2::Core::Dispatcher - Class for dispatching request to the appropriate rou
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 SYNOPSIS
@@ -1,6 +1,6 @@
package Dancer2::Core::Error;
# ABSTRACT: Class representing fatal errors
-$Dancer2::Core::Error::VERSION = '0.156001';
+$Dancer2::Core::Error::VERSION = '0.157000';
use Moo;
use Carp;
use Dancer2::Core::Types;
@@ -496,7 +496,7 @@ Dancer2::Core::Error - Class representing fatal errors
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 SYNOPSIS
@@ -1,6 +1,6 @@
package Dancer2::Core::Factory;
# ABSTRACT: Instantiate components by type and name
-$Dancer2::Core::Factory::VERSION = '0.156001';
+$Dancer2::Core::Factory::VERSION = '0.157000';
use Moo;
use Dancer2::Core;
use Class::Load 'try_load_class';
@@ -33,7 +33,7 @@ Dancer2::Core::Factory - Instantiate components by type and name
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 AUTHOR
@@ -1,7 +1,7 @@
# ABSTRACT: helper for rendering HTTP status codes for Dancer2
package Dancer2::Core::HTTP;
-$Dancer2::Core::HTTP::VERSION = '0.156001';
+$Dancer2::Core::HTTP::VERSION = '0.157000';
use strict;
use warnings;
@@ -134,7 +134,7 @@ Dancer2::Core::HTTP - helper for rendering HTTP status codes for Dancer2
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 FUNCTIONS
@@ -1,6 +1,6 @@
package Dancer2::Core::Hook;
# ABSTRACT: Manipulate hooks with Dancer2
-$Dancer2::Core::Hook::VERSION = '0.156001';
+$Dancer2::Core::Hook::VERSION = '0.157000';
use Moo;
use Dancer2::Core::Types;
use Carp;
@@ -51,7 +51,7 @@ Dancer2::Core::Hook - Manipulate hooks with Dancer2
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 SYNOPSIS
@@ -1,7 +1,7 @@
# ABSTRACT: Class to ease manipulation of MIME types
package Dancer2::Core::MIME;
-$Dancer2::Core::MIME::VERSION = '0.156001';
+$Dancer2::Core::MIME::VERSION = '0.157000';
use Moo;
use MIME::Types;
@@ -90,7 +90,7 @@ Dancer2::Core::MIME - Class to ease manipulation of MIME types
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 SYNOPSIS
@@ -1,6 +1,6 @@
package Dancer2::Core::Request::Upload;
# ABSTRACT: Class representing file upload requests
-$Dancer2::Core::Request::Upload::VERSION = '0.156001';
+$Dancer2::Core::Request::Upload::VERSION = '0.157000';
use Moo;
use Carp;
@@ -91,7 +91,7 @@ Dancer2::Core::Request::Upload - Class representing file upload requests
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -1,5 +1,5 @@
package Dancer2::Core::Request;
-$Dancer2::Core::Request::VERSION = '0.156001';
+$Dancer2::Core::Request::VERSION = '0.157000';
# ABSTRACT: Interface for accessing incoming requests
use Moo;
@@ -684,7 +684,7 @@ Dancer2::Core::Request - Interface for accessing incoming requests
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 SYNOPSIS
@@ -1,7 +1,7 @@
# ABSTRACT: Response object for Dancer2
package Dancer2::Core::Response;
-$Dancer2::Core::Response::VERSION = '0.156001';
+$Dancer2::Core::Response::VERSION = '0.157000';
use Moo;
use Encode;
@@ -206,7 +206,7 @@ Dancer2::Core::Response - Response object for Dancer2
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 ATTRIBUTES
@@ -1,6 +1,6 @@
# ABSTRACT: Config role for Dancer2 core objects
package Dancer2::Core::Role::ConfigReader;
-$Dancer2::Core::Role::ConfigReader::VERSION = '0.156001';
+$Dancer2::Core::Role::ConfigReader::VERSION = '0.157000';
use Moo::Role;
use File::Spec;
@@ -274,7 +274,7 @@ Dancer2::Core::Role::ConfigReader - Config role for Dancer2 core objects
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Core::Role::DSL;
# ABSTRACT: Role for DSL
-$Dancer2::Core::Role::DSL::VERSION = '0.156001';
+$Dancer2::Core::Role::DSL::VERSION = '0.157000';
use Moo::Role;
use Dancer2::Core::Types;
use Carp 'croak';
@@ -106,7 +106,7 @@ Dancer2::Core::Role::DSL - Role for DSL
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 AUTHOR
@@ -1,6 +1,6 @@
package Dancer2::Core::Role::Engine;
# ABSTRACT: Role for engines
-$Dancer2::Core::Role::Engine::VERSION = '0.156001';
+$Dancer2::Core::Role::Engine::VERSION = '0.157000';
use Moo::Role;
use Dancer2::Core::Types;
@@ -42,7 +42,7 @@ Dancer2::Core::Role::Engine - Role for engines
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Core::Role::Handler;
# ABSTRACT: Role for Handlers
-$Dancer2::Core::Role::Handler::VERSION = '0.156001';
+$Dancer2::Core::Role::Handler::VERSION = '0.157000';
use Moo::Role;
use Dancer2::Core::Types;
@@ -26,7 +26,7 @@ Dancer2::Core::Role::Handler - Role for Handlers
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 ATTRIBUTES
@@ -1,6 +1,6 @@
package Dancer2::Core::Role::HasLocation;
# ABSTRACT: Role for application location "guessing"
-$Dancer2::Core::Role::HasLocation::VERSION = '0.156001';
+$Dancer2::Core::Role::HasLocation::VERSION = '0.157000';
use Moo::Role;
use Dancer2::Core::Types;
use Dancer2::FileUtils;
@@ -17,6 +17,7 @@ has caller => (
isa => Str,
default => quote_sub( q{
my ( $caller, $script ) = CORE::caller;
+ $script = File::Spec->abs2rel( $script ) if File::Spec->file_name_is_absolute( $script );
$script;
} ),
);
@@ -87,7 +88,7 @@ Dancer2::Core::Role::HasLocation - Role for application location "guessing"
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 AUTHOR
@@ -1,7 +1,7 @@
# ABSTRACT: Role for handling headers
package Dancer2::Core::Role::Headers;
-$Dancer2::Core::Role::Headers::VERSION = '0.156001';
+$Dancer2::Core::Role::Headers::VERSION = '0.157000';
use Moo::Role;
use Dancer2::Core::Types;
use HTTP::Headers;
@@ -52,7 +52,7 @@ Dancer2::Core::Role::Headers - Role for handling headers
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Core::Role::Hookable;
# ABSTRACT: Role for hookable objects
-$Dancer2::Core::Role::Hookable::VERSION = '0.156001';
+$Dancer2::Core::Role::Hookable::VERSION = '0.157000';
use Moo::Role;
use Dancer2::Core;
use Dancer2::Core::Types;
@@ -156,7 +156,7 @@ Dancer2::Core::Role::Hookable - Role for hookable objects
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 AUTHOR
@@ -1,6 +1,6 @@
package Dancer2::Core::Role::Logger;
# ABSTRACT: Role for logger engines
-$Dancer2::Core::Role::Logger::VERSION = '0.156001';
+$Dancer2::Core::Role::Logger::VERSION = '0.157000';
use Dancer2::Core::Types;
use Moo::Role;
@@ -30,8 +30,9 @@ has auto_encoding_charset => (
);
has app_name => (
- is => 'ro',
- isa => Str,
+ is => 'ro',
+ isa => Str,
+ default => sub {'-'},
);
has log_format => (
@@ -87,7 +88,7 @@ sub format_message {
);
}
elsif ( $type eq 'h' ) {
- return $request->header( $block ) || '-';
+ return ( $request && $request->header($block) ) || '-';
}
else {
Carp::carp("{$block}$type not supported");
@@ -116,8 +117,10 @@ sub format_message {
m => sub {$message},
f => sub { $stack[1] || '-' },
l => sub { $stack[2] || '-' },
- h => sub { $request->remote_host || $request->address || '-' },
- i => sub { $request->id || '-' },
+ h => sub {
+ ( $request && $request->remote_host || $request->address ) || '-'
+ },
+ i => sub { ( $request && $request->id ) || '-' },
};
my $char_mapping = sub {
@@ -193,7 +196,7 @@ Dancer2::Core::Role::Logger - Role for logger engines
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Core::Role::Serializer;
# ABSTRACT: Role for Serializer engines
-$Dancer2::Core::Role::Serializer::VERSION = '0.156001';
+$Dancer2::Core::Role::Serializer::VERSION = '0.157000';
use Moo::Role;
use Try::Tiny;
use Dancer2::Core::Types;
@@ -91,7 +91,7 @@ Dancer2::Core::Role::Serializer - Role for Serializer engines
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -1,17 +1,14 @@
package Dancer2::Core::Role::SessionFactory::File;
-#ABSTRACT: Role for file-based session factories
-$Dancer2::Core::Role::SessionFactory::File::VERSION = '0.156001';
-use strict;
-use warnings;
+# ABSTRACT: Role for file-based session factories
+$Dancer2::Core::Role::SessionFactory::File::VERSION = '0.157000';
+use Moo::Role;
+with 'Dancer2::Core::Role::SessionFactory';
+
use Carp 'croak';
use Dancer2::Core::Types;
use Dancer2::FileUtils qw(path set_file_mode);
use Fcntl ':flock';
-use Moo::Role;
-
-with 'Dancer2::Core::Role::SessionFactory';
-
#--------------------------------------------------------------------------#
# Required by classes consuming this role
#--------------------------------------------------------------------------#
@@ -113,7 +110,7 @@ Dancer2::Core::Role::SessionFactory::File - Role for file-based session factorie
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -1,8 +1,9 @@
package Dancer2::Core::Role::SessionFactory;
-#ABSTRACT: Role for session factories
-$Dancer2::Core::Role::SessionFactory::VERSION = '0.156001';
-use strict;
-use warnings;
+# ABSTRACT: Role for session factories
+$Dancer2::Core::Role::SessionFactory::VERSION = '0.157000';
+use Moo::Role;
+with 'Dancer2::Core::Role::Engine';
+
use Carp 'croak';
use Class::Load 'try_load_class';
use Dancer2::Core::Session;
@@ -11,9 +12,6 @@ use Digest::SHA 'sha1';
use List::Util 'shuffle';
use MIME::Base64 'encode_base64url';
-use Moo::Role;
-with 'Dancer2::Core::Role::Engine';
-
sub supported_hooks {
qw/
engine.session.before_retrieve
@@ -260,7 +258,7 @@ Dancer2::Core::Role::SessionFactory - Role for session factories
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Core::Role::StandardResponses;
# ABSTRACT: Role to provide commonly used responses
-$Dancer2::Core::Role::StandardResponses::VERSION = '0.156001';
+$Dancer2::Core::Role::StandardResponses::VERSION = '0.157000';
use Moo::Role;
use Dancer2::Core::HTTP;
@@ -35,7 +35,7 @@ Dancer2::Core::Role::StandardResponses - Role to provide commonly used responses
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 METHODS
@@ -1,7 +1,7 @@
# ABSTRACT: Role for template engines
package Dancer2::Core::Role::Template;
-$Dancer2::Core::Role::Template::VERSION = '0.156001';
+$Dancer2::Core::Role::Template::VERSION = '0.157000';
use Dancer2::Core::Types;
use Dancer2::FileUtils qw'path';
use Carp 'croak';
@@ -223,7 +223,7 @@ Dancer2::Core::Role::Template - Role for template engines
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -1,10 +1,6 @@
-# ABSTRACT: Dancer2's route handler
-
package Dancer2::Core::Route;
-$Dancer2::Core::Route::VERSION = '0.156001';
-use strict;
-use warnings;
-
+# ABSTRACT: Dancer2's route handler
+$Dancer2::Core::Route::VERSION = '0.157000';
use Moo;
use Dancer2::Core::Types;
use Carp 'croak';
@@ -227,7 +223,7 @@ Dancer2::Core::Route - Dancer2's route handler
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 ATTRIBUTES
@@ -1,6 +1,6 @@
package Dancer2::Core::Runner;
# ABSTRACT: Top-layer class to start a dancer app
-$Dancer2::Core::Runner::VERSION = '0.156001';
+$Dancer2::Core::Runner::VERSION = '0.157000';
use Moo;
use Carp 'croak';
use Dancer2::Core::MIME;
@@ -93,7 +93,6 @@ sub _build_config {
return {
behind_proxy => 0,
apphandler => ( $ENV{DANCER_APPHANDLER} || 'Standalone' ),
- warnings => ( $ENV{DANCER_WARNINGS} || 0 ),
traces => ( $ENV{DANCER_TRACES} || 0 ),
host => ( $ENV{DANCER_SERVER} || '0.0.0.0' ),
port => ( $ENV{DANCER_PORT} || '3000' ),
@@ -260,7 +259,7 @@ Dancer2::Core::Runner - Top-layer class to start a dancer app
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 AUTHOR
@@ -1,9 +1,6 @@
package Dancer2::Core::Session;
-$Dancer2::Core::Session::VERSION = '0.156001';
-#ABSTRACT: class to represent any session object
-
-use strict;
-use warnings;
+# ABSTRACT: class to represent any session object
+$Dancer2::Core::Session::VERSION = '0.157000';
use Moo;
use Dancer2::Core::Types;
use Dancer2::Core::Time;
@@ -71,7 +68,7 @@ Dancer2::Core::Session - class to represent any session object
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Core::Time;
-#ABSTRACT: class to handle common helpers for time manipulations
-$Dancer2::Core::Time::VERSION = '0.156001';
+# ABSTRACT: class to handle common helpers for time manipulations
+$Dancer2::Core::Time::VERSION = '0.157000';
use Moo;
has seconds => (
@@ -134,7 +134,7 @@ Dancer2::Core::Time - class to handle common helpers for time manipulations
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 SYNOPSIS
@@ -1,6 +1,6 @@
package Dancer2::Core::Types;
# ABSTRACT: Moo types for Dancer2 core.
-$Dancer2::Core::Types::VERSION = '0.156001';
+$Dancer2::Core::Types::VERSION = '0.157000';
use strict;
use warnings;
use Scalar::Util 'blessed', 'looks_like_number';
@@ -148,7 +148,7 @@ Dancer2::Core::Types - Moo types for Dancer2 core.
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Core;
# ABSTRACT: Core libraries for Dancer2 2.0
-$Dancer2::Core::VERSION = '0.156001';
+$Dancer2::Core::VERSION = '0.157000';
use strict;
use warnings;
@@ -29,7 +29,7 @@ Dancer2::Core - Core libraries for Dancer2 2.0
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 FUNCTIONS
@@ -1,6 +1,6 @@
package Dancer2::FileUtils;
# ABSTRACT: File utility helpers
-$Dancer2::FileUtils::VERSION = '0.156001';
+$Dancer2::FileUtils::VERSION = '0.157000';
use strict;
use warnings;
@@ -101,7 +101,7 @@ Dancer2::FileUtils - File utility helpers
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 SYNOPSIS
@@ -1,6 +1,6 @@
package Dancer2::Handler::AutoPage;
# ABSTRACT: Class for handling the AutoPage feature
-$Dancer2::Handler::AutoPage::VERSION = '0.156001';
+$Dancer2::Handler::AutoPage::VERSION = '0.157000';
use Moo;
use Carp 'croak';
use Dancer2::Core::Types;
@@ -71,7 +71,7 @@ Dancer2::Handler::AutoPage - Class for handling the AutoPage feature
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Handler::File;
# ABSTRACT: class for handling file content rendering
-$Dancer2::Handler::File::VERSION = '0.156001';
+$Dancer2::Handler::File::VERSION = '0.157000';
use Carp 'croak';
use Moo;
use HTTP::Date;
@@ -82,14 +82,8 @@ sub code {
$path =~ s/^\Q$prefix\E//;
}
- my @tokens =
- File::Spec->splitdir( join '',
- ( File::Spec->splitpath($path) )[ 1, 2 ] );
- if ( grep $_ eq '..', @tokens ) {
- return $self->standard_response( $app, 403 );
- }
-
- my $file_path = path( $self->public_dir, @tokens );
+ my $file_path = $self->merge_paths( $path, $self->public_dir );
+ return $self->standard_response( $app, 403 ) if !defined $file_path;
if ( !-f $file_path ) {
$app->response->has_passed(1);
@@ -135,6 +129,24 @@ sub code {
};
}
+sub merge_paths {
+ my ( undef, $path, $public_dir ) = @_;
+
+ my ( $volume, $dirs, $file ) = File::Spec->splitpath( $path );
+ my @tokens = File::Spec->splitdir( "$dirs$file" );
+ my $updir = File::Spec->updir;
+ return if grep $_ eq $updir, @tokens;
+
+ my ( $pub_vol, $pub_dirs, $pub_file ) = File::Spec->splitpath( $public_dir );
+ my @pub_tokens = File::Spec->splitdir( "$pub_dirs$pub_file" );
+ return if length $volume and length $pub_vol and $volume ne $pub_vol;
+
+ my @final_vol = ( length $pub_vol ? $pub_vol : length $volume ? $volume : () );
+ my @file_path = ( @final_vol, @pub_tokens, @tokens );
+ my $file_path = path( @file_path );
+ return $file_path;
+}
+
1;
__END__
@@ -149,7 +161,7 @@ Dancer2::Handler::File - class for handling file content rendering
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 AUTHOR
@@ -1,6 +1,6 @@
package Dancer2::Logger::Capture::Trap;
# ABSTRACT: a place to store captured Dancer2 logs
-$Dancer2::Logger::Capture::Trap::VERSION = '0.156001';
+$Dancer2::Logger::Capture::Trap::VERSION = '0.157000';
use Moo;
use Dancer2::Core::Types;
@@ -11,8 +11,12 @@ has storage => (
);
sub store {
- my ( $self, $level, $message ) = @_;
- push @{ $self->storage }, { level => $level, message => $message };
+ my ( $self, $level, $message, $fmt_string ) = @_;
+ push @{ $self->storage }, {
+ level => $level,
+ message => $message,
+ formatted => $fmt_string,
+ };
}
sub read {
@@ -37,7 +41,7 @@ Dancer2::Logger::Capture::Trap - a place to store captured Dancer2 logs
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 SYNOPSIS
@@ -1,6 +1,6 @@
package Dancer2::Logger::Capture;
# ABSTRACT: Capture dancer logs
-$Dancer2::Logger::Capture::VERSION = '0.156001';
+$Dancer2::Logger::Capture::VERSION = '0.157000';
use Moo;
use Dancer2::Logger::Capture::Trap;
@@ -17,7 +17,10 @@ sub _build_trapper { Dancer2::Logger::Capture::Trap->new }
sub log {
my ( $self, $level, $message ) = @_;
- $self->trapper->store( $level => $message );
+ $self->trapper->store(
+ $level, $message, $self->format_message( $level => $message )
+ );
+
return;
}
@@ -35,7 +38,7 @@ Dancer2::Logger::Capture - Capture dancer logs
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 SYNOPSIS
@@ -1,6 +1,6 @@
package Dancer2::Logger::Console;
# ABSTRACT: Console logger
-$Dancer2::Logger::Console::VERSION = '0.156001';
+$Dancer2::Logger::Console::VERSION = '0.157000';
use Moo;
with 'Dancer2::Core::Role::Logger';
@@ -24,7 +24,7 @@ Dancer2::Logger::Console - Console logger
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Logger::Diag;
# ABSTRACT: Test::More diag() logging engine for Dancer2
-$Dancer2::Logger::Diag::VERSION = '0.156001';
+$Dancer2::Logger::Diag::VERSION = '0.157000';
use Moo;
use Test::More;
@@ -26,7 +26,7 @@ Dancer2::Logger::Diag - Test::More diag() logging engine for Dancer2
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Logger::File;
# ABSTRACT: file-based logging engine for Dancer2
-$Dancer2::Logger::File::VERSION = '0.156001';
+$Dancer2::Logger::File::VERSION = '0.157000';
use Carp 'carp';
use Moo;
use Dancer2::Core::Types;
@@ -111,7 +111,7 @@ Dancer2::Logger::File - file-based logging engine for Dancer2
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Logger::Note;
# ABSTRACT: Test::More note() logging engine for Dancer2
-$Dancer2::Logger::Note::VERSION = '0.156001';
+$Dancer2::Logger::Note::VERSION = '0.157000';
use Moo;
use Test::More;
@@ -26,7 +26,7 @@ Dancer2::Logger::Note - Test::More note() logging engine for Dancer2
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Logger::Null;
# ABSTRACT: Blackhole-like silent logging engine for Dancer2
-$Dancer2::Logger::Null::VERSION = '0.156001';
+$Dancer2::Logger::Null::VERSION = '0.157000';
use Moo;
with 'Dancer2::Core::Role::Logger';
@@ -20,7 +20,7 @@ Dancer2::Logger::Null - Blackhole-like silent logging engine for Dancer2
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Manual::Migration;
# ABSTRACT: Migrating from Dancer to Dancer2
-$Dancer2::Manual::Migration::VERSION = '0.156001';
+$Dancer2::Manual::Migration::VERSION = '0.157000';
use strict;
use warnings;
@@ -18,13 +18,47 @@ Dancer2::Manual::Migration - Migrating from Dancer to Dancer2
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 Migration from Dancer 1 to Dancer2
This document covers some changes that users will need to be aware of
while upgrading from L<Dancer> (version 1) to L<Dancer2>.
+=head2 Launcher script bin/app.pl
+
+The default launcher script C<bin/app.pl> in L<Dancer> looked like this:
+
+ #!/usr/bin/env perl
+ use Dancer;
+ use MyApp;
+ dance;
+
+In L<Dancer2> it looks like this:
+
+ #!/usr/bin/env perl
+
+ use strict;
+ use warnings;
+ use FindBin;
+ use lib "$FindBin::Bin/../lib";
+
+ use MyApp;
+ MyApp->to_app;
+
+So you need to remove the C<use Dancer;> part, replace the C<dance;> command
+by C<< MyApp->to_app; >> (where MyApp is the name of your application), and
+add the following lines:
+
+ use strict;
+ use warnings;
+ use FindBin;
+ use lib "$FindBin::Bin/../lib";
+
+There is a L<Dancer Advent Calendar|http://advent.perldancer.org> article
+L<< covering the C<to_app> keyword|http://advent.perldancer.org/2014/9 >>
+and its usage.
+
=head2 Apps
1. In L<Dancer2>, each module is a B<separate application> with its own
@@ -91,6 +125,36 @@ Thus, these modules can be used for speed improvement provided:
=back
+=head2 Request
+
+The request object (L<Dancer2::Core::Request>) is now deferring much of
+its code to L<Plack::Request> to be consistent with the known interface
+to L<PSGI> requests.
+
+Currently the following attributes pass directly to L<Plack::Request>:
+
+C<address>, C<remote_host>, C<protocol>, C<port>, C<method>, C<user>,
+C<request_uri>, C<script_name>, C<content_length>, C<content_type>,
+C<content_encoding>, C<referer>, and C<user_agent>.
+
+If previous attributes returned I<undef> for no value beforehand, they
+will return whatever L<Plack::Request> defines now, which just might be
+an empty list.
+
+For example:
+
+ my %data = (
+ referer => request->referer,
+ user_agent => request->user_agent,
+ );
+
+should be replaced by:
+
+ my %data = (
+ referer => request->referer || '',
+ user_agent => request->user_agent || '',
+ );
+
=head2 Plugins: plugin_setting
C<plugin_setting> returns the configuration of the plugin. It can only be
@@ -118,7 +182,6 @@ For example:
use strict;
use warnings;
-
use Test::More tests => 2;
use Plack::Test;
use HTTP::Request::Common;
@@ -203,11 +266,34 @@ server and reads the configuration options in your command line utilities.
=head2 Engines
-Engines now receive a logger that consumes L<Dancer2::Core::Role::Logger> in
-order to log errors. The attribute is called C<logger>.
+=over 4
+
+=item * Engines receive a logging callback
+
+Engines now receive a logging callback named C<log_cb>. Engines can use it
+to log anything in run-time, without having to worry about what logging
+engine is used.
+
+This is provided as a callback because the logger might be changed in
+run-time and we want engines to be able to always reach the current one
+without having a reference back to the core application object.
The logger engine doesn't have the attribute since it is the logger itself.
+=item * Engines handle encoding consistently
+
+All engines are now expected to handle encoding on their own. User code
+is expected to be in internal Perl representation.
+
+Therefore, all serializers, for example, should deserialize to the Perl
+representation. Templates, in turn, encode to UTF-8 if requested by the
+user, or by default.
+
+One side-effect of this is that C<from_yaml> will call L<YAML>'s C<Load>
+function with decoded input.
+
+=back
+
=head3 Serializers
You no longer need to implement the C<loaded> method. It is simply
@@ -215,6 +301,29 @@ unnecessary.
=head2 Configuration
+=head3 warnings
+
+The C<warnings> configuration option, along with the environment variable
+C<DANCER_WARNINGS>, have been removed and have no effect whatsoever.
+
+They were added when someone requested to be able to load Dancer without
+the L<warnings> pragma, which it adds, just like L<Moose>, L<Moo>, and
+other modules provide.
+
+If you want this to happen now (which you probably shouldn't be doing),
+you can always control it lexically:
+
+ use Dancer2;
+ no warnings;
+
+You can also use Dancer2 within a narrower scope:
+
+ { use Dancer2 }
+ use strict;
+ # warnings are not turned on
+
+However, having L<warnings> turned it is very recommended.
+
=head3 server_tokens
The configuration C<server_tokens> has been introduced in the reverse (but
@@ -222,6 +331,53 @@ more sensible, and Plack-compatible) form as C<no_server_tokens>.
C<DANCER_SERVER_TOKENS> changed to C<DANCER_NO_SERVER_TOKENS>.
+=head3 engines
+
+If you want to use Template::Toolkit instead of the built-in simple templating
+engine you used to enable the following line in the config.yml file.
+
+ template: "template_toolkit"
+
+That was enough to get started. The start_tag and end_tag it used were the same as in
+the simple template <% and %> respectively.
+
+If you wanted to further customize the Template::Toolkit you could also enable or add
+the following:
+
+ engines:
+ template_toolkit:
+ encoding: 'utf8'
+ start_tag: '[%'
+ end_tag: '%]'
+
+In Dancer 2 you can also enable Template::Toolkit with the same configuration option:
+
+ template: "template_toolkit"
+
+But the default start_tag and end_tag are now [% and %], so if you used the default in Dancer 1
+now you will have to explicitly change the start_tag and end_tag values.
+The configuration also got an extral level of depth. Under the C<engine> key there is a C<template>
+key and the C<template_toolkit> key comes below that. As in this example:
+
+ engines:
+ template:
+ template_toolkit:
+ start_tag: '<%'
+ end_tag: '%>'
+
+In a nutshell, if you used to have
+
+ template: "template_toolkit"
+
+You need to replace it with
+
+ template: "template_toolkit"
+ engines:
+ template:
+ template_toolkit:
+ start_tag: '<%'
+ end_tag: '%>'
+
=head2 Keywords
=head3 load
@@ -236,6 +392,11 @@ This keyword doesn't exist in Dancer2.
=head3 session
+In L<Dancer> a session was created and a cookie was sent just by rendering a page
+using the C<template> function. In L<Dancer2> one needs to actully set a value in
+a session object using the C<session> function in order to create the session
+and send the cookie.
+
The session keyword has multiple states:
=over 4
@@ -1,6 +1,6 @@
package Dancer2::Manual::Testing;
# ABSTRACT: Writing tests for Dancer2
-$Dancer2::Manual::Testing::VERSION = '0.156001';
+$Dancer2::Manual::Testing::VERSION = '0.157000';
use strict;
use warnings;
@@ -18,7 +18,7 @@ Dancer2::Manual::Testing - Writing tests for Dancer2
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 Basic application testing
@@ -1,6 +1,6 @@
# ABSTRACT: A gentle introduction to Dancer2
package Dancer2::Manual;
-$Dancer2::Manual::VERSION = '0.156001';
+$Dancer2::Manual::VERSION = '0.157000';
__END__
=pod
@@ -13,7 +13,7 @@ Dancer2::Manual - A gentle introduction to Dancer2
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -1611,6 +1611,10 @@ You can call it as a method on the class or as a DSL:
my $app = to_app;
+There is a
+L<Dancer Advent Calendar article|http://advent.perldancer.org/2014/9> covering
+this keyword and its usage further.
+
=head2 psgi_app
Provides the same functionality as C<to_app> but uses the deprecated
@@ -1,6 +1,6 @@
package Dancer2::Plugin;
# ABSTRACT: Extending Dancer2's DSL with plugins
-$Dancer2::Plugin::VERSION = '0.156001';
+$Dancer2::Plugin::VERSION = '0.157000';
use Moo::Role;
use Carp 'croak', 'carp';
use Dancer2::Core::DSL;
@@ -253,7 +253,7 @@ Dancer2::Plugin - Extending Dancer2's DSL with plugins
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Plugins;
# ABSTRACT: Recommended Dancer2 plugins
-$Dancer2::Plugins::VERSION = '0.156001';
+$Dancer2::Plugins::VERSION = '0.157000';
__END__
=pod
@@ -13,7 +13,7 @@ Dancer2::Plugins - Recommended Dancer2 plugins
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Policy;
# ABSTRACT: Dancer core and community policy and standards of conduct
-$Dancer2::Policy::VERSION = '0.156001';
+$Dancer2::Policy::VERSION = '0.157000';
use strict;
use warnings;
@@ -18,7 +18,7 @@ Dancer2::Policy - Dancer core and community policy and standards of conduct
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -1,7 +1,7 @@
# ABSTRACT: Serializer for handling Dumper data
package Dancer2::Serializer::Dumper;
-$Dancer2::Serializer::Dumper::VERSION = '0.156001';
+$Dancer2::Serializer::Dumper::VERSION = '0.157000';
use Moo;
use Carp 'croak';
use Data::Dumper;
@@ -53,7 +53,7 @@ Dancer2::Serializer::Dumper - Serializer for handling Dumper data
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Serializer::JSON;
# ABSTRACT: Serializer for handling JSON data
-$Dancer2::Serializer::JSON::VERSION = '0.156001';
+$Dancer2::Serializer::JSON::VERSION = '0.157000';
use Moo;
use JSON ();
@@ -55,7 +55,7 @@ Dancer2::Serializer::JSON - Serializer for handling JSON data
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Serializer::Mutable;
# ABSTRACT: Serialize and deserialize content based on HTTP header
-$Dancer2::Serializer::Mutable::VERSION = '0.156001';
+$Dancer2::Serializer::Mutable::VERSION = '0.157000';
use Moo;
use Carp 'croak';
use Encode;
@@ -104,7 +104,7 @@ Dancer2::Serializer::Mutable - Serialize and deserialize content based on HTTP h
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 SYNOPSIS
@@ -1,6 +1,6 @@
package Dancer2::Serializer::YAML;
# ABSTRACT: Serializer for handling YAML data
-$Dancer2::Serializer::YAML::VERSION = '0.156001';
+$Dancer2::Serializer::YAML::VERSION = '0.157000';
use Moo;
use Carp 'croak';
use Encode;
@@ -49,7 +49,7 @@ Dancer2::Serializer::YAML - Serializer for handling YAML data
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Session::Simple;
# ABSTRACT: in-memory session backend for Dancer2
-$Dancer2::Session::Simple::VERSION = '0.156001';
+$Dancer2::Session::Simple::VERSION = '0.157000';
use Moo;
use Dancer2::Core::Types;
use Carp;
@@ -49,7 +49,7 @@ Dancer2::Session::Simple - in-memory session backend for Dancer2
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -1,5 +1,5 @@
package Dancer2::Session::YAML;
-$Dancer2::Session::YAML::VERSION = '0.156001';
+$Dancer2::Session::YAML::VERSION = '0.157000';
# ABSTRACT: YAML-file-based session backend for Dancer2
use Moo;
@@ -39,7 +39,7 @@ Dancer2::Session::YAML - YAML-file-based session backend for Dancer2
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -1,5 +1,5 @@
package Dancer2::Template::Implementation::ForkedTiny;
-$Dancer2::Template::Implementation::ForkedTiny::VERSION = '0.156001';
+$Dancer2::Template::Implementation::ForkedTiny::VERSION = '0.157000';
# ABSTRACT: Dancer2 own implementation of Template::Tiny
use 5.00503;
@@ -229,7 +229,7 @@ Dancer2::Template::Implementation::ForkedTiny - Dancer2 own implementation of Te
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 SYNOPSIS
@@ -1,8 +1,6 @@
package Dancer2::Template::Simple;
# ABSTRACT: Pure Perl 5 template engine for Dancer2
-$Dancer2::Template::Simple::VERSION = '0.156001';
-use strict;
-use warnings;
+$Dancer2::Template::Simple::VERSION = '0.157000';
use Moo;
use Dancer2::FileUtils 'read_file_content';
@@ -156,7 +154,7 @@ Dancer2::Template::Simple - Pure Perl 5 template engine for Dancer2
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 SYNOPSIS
@@ -1,11 +1,9 @@
# ABSTRACT: Template toolkit engine for Dancer2
package Dancer2::Template::TemplateToolkit;
-$Dancer2::Template::TemplateToolkit::VERSION = '0.156001';
-use strict;
-use warnings;
-use Carp qw/croak/;
+$Dancer2::Template::TemplateToolkit::VERSION = '0.157000';
use Moo;
+use Carp qw/croak/;
use Dancer2::Core::Types;
use Template;
@@ -63,7 +61,7 @@ Dancer2::Template::TemplateToolkit - Template toolkit engine for Dancer2
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 SYNOPSIS
@@ -1,6 +1,6 @@
package Dancer2::Template::Tiny;
# ABSTRACT: Template::Tiny engine for Dancer2
-$Dancer2::Template::Tiny::VERSION = '0.156001';
+$Dancer2::Template::Tiny::VERSION = '0.157000';
use Moo;
use Carp qw/croak/;
use Dancer2::Core::Types;
@@ -50,7 +50,7 @@ Dancer2::Template::Tiny - Template::Tiny engine for Dancer2
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 SYNOPSIS
@@ -1,6 +1,6 @@
package Dancer2::Test;
# ABSTRACT: Useful routines for testing Dancer2 apps
-$Dancer2::Test::VERSION = '0.156001';
+$Dancer2::Test::VERSION = '0.157000';
use strict;
use warnings;
@@ -621,7 +621,7 @@ Dancer2::Test - Useful routines for testing Dancer2 apps
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 SYNOPSIS
@@ -1,6 +1,6 @@
package Dancer2::Tutorial;
# ABSTRACT: An example to get you dancing
-$Dancer2::Tutorial::VERSION = '0.156001';
+$Dancer2::Tutorial::VERSION = '0.157000';
__END__
=pod
@@ -13,7 +13,7 @@ Dancer2::Tutorial - An example to get you dancing
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 What is Dancer2?
@@ -1,6 +1,6 @@
package Dancer2;
# ABSTRACT: Lightweight yet powerful web application framework
-$Dancer2::VERSION = '0.156001';
+$Dancer2::VERSION = '0.157000';
use strict;
use warnings;
use List::Util 'first';
@@ -15,7 +15,7 @@ our $AUTHORITY = 'SUKRIA';
# set version in dist.ini now
# but we still need a basic version for
# the tests
-$Dancer2::VERSION ||= '0.156000'; # 2.156.0
+$Dancer2::VERSION ||= '0.157000';
our $runner;
@@ -118,7 +118,7 @@ Dancer2 - Lightweight yet powerful web application framework
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 DESCRIPTION
@@ -183,6 +183,11 @@ Refer to L<Dancer2::Plugins> for a partial list of available Dancer2
plugins. Note that although we try to keep this list up to date we
expect plugin authors to tell us about new modules.
+=item * Dancer2 Migration guide
+
+L<Dancer2::Manual::Migration> provides the most up-to-date instruction on
+how to convert a Dancer (1) based application to Dancer2.
+
=back
=head1 METHODS
@@ -33,7 +33,7 @@ dancer2 - Dancer2 command line interface
=head1 VERSION
-version 0.156001
+version 0.157000
=head1 SYNOPSIS
@@ -1,7 +1,9 @@
#!/usr/bin/env perl
+use strict;
+use warnings;
use FindBin;
use lib "$FindBin::Bin/../lib";
use [% appname %];
-[% appname %]->dance;
+[% appname %]->to_app;
@@ -12,6 +12,5 @@ warnings: 0
# hide errors
show_errors: 0
-# cache route resolution for maximum performance
-route_cache: 1
-
+# disable server tokens in production environments
+no_server_token: 1
@@ -55,10 +55,10 @@ do { my $x = {
'HTTP::Date' => '0',
'HTTP::Headers' => '0',
'HTTP::Server::PSGI' => '0',
+ 'HTTP::Tiny' => '0',
'Hash::Merge::Simple' => '0',
'IO::File' => '0',
'JSON' => '0',
- 'LWP::UserAgent' => '0',
'List::Util' => '0',
'MIME::Base64' => '3.13',
'MIME::Types' => '0',
@@ -115,19 +115,17 @@ do { my $x = {
'File::Temp' => '0.22',
'FindBin' => '0',
'HTTP::Body' => '0',
+ 'HTTP::Cookies' => '0',
'HTTP::Request' => '0',
'HTTP::Request::Common' => '0',
'IO::Handle' => '0',
'IPC::Open3' => '0',
- 'LWP::Protocol::PSGI' => '0.06',
'Plack::Response' => '0',
'Plack::Test' => '0',
'Test::Fatal' => '0',
'Test::Memory::Cycle' => '1.04',
'Test::MockTime' => '0',
'Test::More' => '0.92',
- 'Test::Script' => '0',
- 'Test::TCP' => '1.13',
'YAML' => '0',
'lib' => '0',
'perl' => '5.006',
@@ -171,10 +171,13 @@ my @files = (
't/issues/gh-639/succeeds/.dancer',
't/issues/gh-639/succeeds/config.yml',
't/issues/gh-639/succeeds/issue.t',
+ 't/issues/gh-650/gh-650.t',
+ 't/issues/gh-650/views/environment_setting.tt',
't/issues/gh-723.t',
't/issues/gh-730.t',
't/issues/gh-794.t',
't/issues/gh-797.t',
+ 't/issues/gh-799.t',
't/lib/App1.pm',
't/lib/App2.pm',
't/lib/DancerPlugin.pm',
@@ -191,7 +194,6 @@ my @files = (
't/log_levels.t',
't/logger.t',
't/logger_console.t',
- 't/lwp-protocol-psgi.t',
't/memory_cycles.t',
't/mime.t',
't/multi_apps.t',
@@ -239,6 +241,14 @@ my @files = (
't/sessions/VINziwAAUHovk3nfMmkf2GHI6RNrE38c.yml',
't/sessions/VIOBYgAAZD-3UeYHGxJmpPkpI8hOgUvW.yml',
't/sessions/VISIVwAASGBJcMXNsII2nVrChuLAP7pm.yml',
+ 't/sessions/VIlt7wAAceLduiKWlnAkCQpsRFe9RwmE.yml',
+ 't/sessions/VIltdAAAcGUtpuNeagm8uMqOmg1iO5BG.yml',
+ 't/sessions/VIxX-gAAaW6BYt4htdZy0O9_g5J3WdHM.yml',
+ 't/sessions/VIxY0wAAan1F1Maz4h8_pCnhMdtstSHX.yml',
+ 't/sessions/VIxi3AAAfpilI1rk9Tg_5c29HVaYBclB.yml',
+ 't/sessions/VIxiTQAAfYHVHQ5txQKuXTwZ7alch-Gc.yml',
+ 't/sessions/VIxj4wAAAakb1qv0OYF9_oA_WrIqImY7.yml',
+ 't/sessions/VIxkLgAABBzH8FV-MYjgAOQrJuLhWOkM.yml',
't/shared_engines.t',
't/template.t',
't/template_default_tokens.t',
@@ -1,8 +1,5 @@
-#!perl
-
use strict;
use warnings;
-
use Test::More tests => 32;
use Test::Fatal;
use Scalar::Util 'refaddr';
@@ -1,8 +1,5 @@
-#!perl
-
use strict;
use warnings;
-
use Dancer2::Core;
use Test::More tests => 4;
@@ -1,8 +1,5 @@
-#!perl
-
use strict;
use warnings;
-
use Test::More tests => 5;
use_ok('Dancer2::Core::Factory');
@@ -1,8 +1,5 @@
-#!perl
-
use strict;
use warnings;
-
use Test::More tests => 12;
use Test::Fatal;
@@ -1,8 +1,5 @@
-#!perl
-
use strict;
use warnings;
-
use Test::More tests => 9;
use Test::Fatal;
use Plack::Test;
@@ -1,8 +1,5 @@
-#!perl
-
use strict;
use warnings;
-
use Test::More tests => 3;
use Plack::Response;
use Dancer2::Core::Response;
@@ -1,8 +1,5 @@
-#!perl
-
use strict;
use warnings;
-
use Test::More tests => 4;
{
@@ -1,8 +1,5 @@
-#!perl
-
use strict;
use warnings;
-
use Test::More tests => 3;
{
@@ -1,8 +1,5 @@
-#!perl
-
use strict;
use warnings;
-
use File::Spec;
use File::Basename;
use Test::More tests => 11;
@@ -1,8 +1,5 @@
-#!perl
-
use strict;
use warnings;
-
use Test::More tests => 6;
{
@@ -1,8 +1,5 @@
-#!perl
-
use strict;
use warnings;
-
use Test::More tests => 5;
use Test::Fatal;
@@ -83,7 +80,7 @@ subtest 'Unsuccessful' => sub {
my $msg = $errors->[0];
isa_ok( $msg, 'HASH' );
- is( scalar keys %{$msg}, 2, 'Two items in the error' );
+ is( scalar keys %{$msg}, 3, 'Two items in the error' );
is( $msg->{'level'}, 'core', 'Correct level' );
like(
@@ -113,7 +110,7 @@ subtest 'Unsuccessful' => sub {
my $msg = $errors->[0];
isa_ok( $msg, 'HASH' );
- is( scalar keys %{$msg}, 2, 'Two items in the error' );
+ is( scalar keys %{$msg}, 3, 'Two items in the error' );
is( $msg->{'level'}, 'core', 'Correct level' );
like(
@@ -1,8 +1,5 @@
-#!perl
-
use strict;
use warnings;
-
use Test::More tests => 24;
{
@@ -1,7 +1,5 @@
-#!/usr/bin/perl
use strict;
use warnings;
-
use Test::More;
use Test::Fatal;
use Dancer2::Core::Route;
@@ -2,7 +2,6 @@ use strict;
use warnings;
use Test::More;
use Test::Fatal;
-
use Dancer2::Core::Request;
use Dancer2::Core::Route;
@@ -1,8 +1,5 @@
-#!perl
-
use strict;
use warnings;
-
use Test::More tests => 6;
use Dancer2::Core::Runner;
@@ -1,9 +1,6 @@
-#!perl
-
use strict;
use warnings;
-
-use Test::More tests => 41;
+use Test::More tests => 39;
use_ok('Dancer2::Core::Runner');
@@ -146,26 +143,6 @@ note 'Startup info';
);
}
-note 'Warnings';
-{
- my $runner = Dancer2::Core::Runner->new();
- is(
- $runner->config->{'warnings'},
- 0,
- 'Default warnings',
- );
-}
-
-{
- local $ENV{DANCER_WARNINGS} = 1;
- my $runner = Dancer2::Core::Runner->new();
- is(
- $runner->config->{'warnings'},
- 1,
- 'Successfully set warnings using DANCER_WARNINGS',
- );
-}
-
{
{
package App::Fake;
@@ -1,8 +1,5 @@
-#!perl
-
use strict;
use warnings;
-
use Test::More tests => 25;
use Plack::Test;
use HTTP::Request::Common;
@@ -196,6 +196,7 @@ note 'Check serialization errors'; {
is( scalar @{$errors}, 1, 'One error caught' );
my $msg = $errors->[0];
+ delete $msg->{'formatted'};
isa_ok( $msg, 'HASH' );
is( scalar keys %{$msg}, 2, 'Two items in the error' );
@@ -1,5 +1,3 @@
-#!perl
-
use strict;
use warnings;
use Test::More tests => 9;
@@ -1,5 +1,3 @@
-#!/usr/bin/env perl
-
# define a sample DSL extension that will be used in the rest of these test
# This extends Dancer2::Core::DSL but provides an extra keyword
#
@@ -1,6 +1,5 @@
use strict;
use warnings;
-
use Test::More;
use Plack::Test;
use HTTP::Request::Common;
@@ -1,6 +1,5 @@
use strict;
use warnings;
-
use Test::More;
use Plack::Test;
use HTTP::Request::Common;
@@ -1,8 +1,5 @@
-#!perl
-
use strict;
use warnings;
-
use Test::More tests => 4;
use Plack::Test;
use Plack::Request;
@@ -1,4 +1,3 @@
-#!perl
use strict;
use warnings;
use Plack::Test;
@@ -1,8 +1,5 @@
-#!perl
-
use strict;
use warnings;
-
use Test::More tests => 2;
use Plack::Test;
use HTTP::Request::Common;
@@ -1,6 +1,5 @@
use strict;
use warnings;
-
use Test::More tests=> 3;
use File::Temp qw/tempdir/;
use File::Spec;
@@ -1,8 +1,5 @@
-#!perl
-
use strict;
use warnings;
-
use Test::More tests => 1;
use Test::Fatal;
@@ -1,8 +1,5 @@
-#!perl
-
use strict;
use warnings;
-
use Test::More tests => 1;
use Test::Fatal;
@@ -0,0 +1,42 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use Test::More;
+use Plack::Test;
+use HTTP::Request::Common;
+
+{
+ package MyApp;
+
+ use Dancer2;
+
+ set template => 'template_toolkit';
+
+ get '/foo' => sub {
+ template 'environment_setting'
+ };
+ get '/bar' => sub {
+ set environment => 'development';
+ template 'environment_setting'
+ };
+}
+
+my $app = Dancer2->psgi_app;
+is( ref $app, 'CODE', 'Got app' );
+
+test_psgi $app, sub {
+ my $cb = shift;
+ my $res;
+
+ $res = $cb->(GET '/foo');
+ is $res->code, 200, 'Successful request';
+ like $res->content, qr/development/, 'Correct content';
+
+ $res = $cb->(GET '/bar');
+ is $res->code, 200, 'Successful request';
+ like $res->content, qr/development/, 'Correct content';
+};
+
+done_testing();
@@ -0,0 +1 @@
+[% settings.environment %]
@@ -1,5 +1,3 @@
-#!perl
-
use strict;
use warnings;
use Test::More tests => 4;
@@ -1,8 +1,5 @@
-#!perl
-
use strict;
use warnings;
-
use Test::More tests => 3;
use Plack::Test;
use HTTP::Request::Common;
@@ -0,0 +1,64 @@
+use strict;
+use warnings;
+use Test::More tests => 1;
+use Test::Fatal;
+use Plack::Test;
+use HTTP::Request::Common;
+
+{
+ package App;
+ use Dancer2;
+
+ set log => 'core';
+ set engines => {
+ logger => { Capture => { log_format => '%{x-test}h %i' } },
+ };
+
+ set logger => 'Capture';
+
+ get '/' => sub {
+ my $req = app->request;
+ ::isa_ok( $req, 'Dancer2::Core::Request' );
+
+ my $logger = app->engine('logger');
+ ::isa_ok( $logger, 'Dancer2::Logger::Capture' );
+ ::can_ok( $logger, 'format_message' );
+
+ my $trap = $logger->trapper;
+ ::isa_ok( $trap, 'Dancer2::Logger::Capture::Trap' );
+ my $msg = $trap->read;
+ ::is_deeply(
+ $msg,
+ [
+ {
+ level => 'core',
+ message => 'looking for get /',
+ formatted => "- 1\n",
+ },
+
+ {
+ level => 'core',
+ message => 'Entering hook core.app.before_request',
+ formatted => "- 1\n",
+ },
+ ],
+ 'Messages logged successfully',
+ );
+
+ ::can_ok( $logger, 'format_message' );
+ my $fmt_str = $logger->format_message(
+ $msg->[0]{'debug'}, $msg->[0]{'message'}
+ );
+
+ ::is( $fmt_str, "- 1\n", 'Correct formatted message created' );
+
+ return;
+ };
+}
+
+my $test = Plack::Test->create( App->to_app );
+
+subtest 'Logger can access request' => sub {
+ my $res = $test->request( GET '/' );
+ ok( $res->is_success, 'Successful request' );
+};
@@ -1,6 +1,5 @@
package t::lib::PluginWithImport;
-
-#ABSTRACT: a plugin that implement its own import method
+# ABSTRACT: a plugin that implement its own import method
=head1 DESCRIPTION
@@ -44,9 +44,19 @@ subtest 'log level and capture' => sub {
debug "I like pie.";
my $trap = dancer_app->engine('logger')->trapper;
- is_deeply $trap->read,
- [ { level => "warning", message => "Danger! Warning!" },
- { level => "info", message => "Tango, Foxtrot" },
+ my $msg = $trap->read;
+ delete $msg->[0]{'formatted'};
+ delete $msg->[1]{'formatted'};
+ is_deeply $msg,
+ [
+ {
+ level => "warning",
+ message => "Danger! Warning!",
+ },
+ {
+ level => "info",
+ message => "Tango, Foxtrot",
+ },
];
# each call to read cleans the trap
@@ -1,35 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use Test::More;
-use LWP::UserAgent;
-
-eval "use LWP::Protocol::PSGI";
-plan skip_all => "LWP::Protocol::PSGI is needed for this test" if $@;
-
-plan tests => 5;
-
-my $psgi_app = do {
- use Dancer2;
-
- set apphandler => 'PSGI';
-
- get '/search' => sub {
- my $q = param('q');
- is( $q, 'foo', 'Correct parameter to Google' );
- return 'bar';
- };
-
- dance;
-};
-
-# Register the $psgi_app to handle all LWP requests
-LWP::Protocol::PSGI->register($psgi_app);
-my $ua = LWP::UserAgent->new;
-isa_ok( $ua, 'LWP::UserAgent' );
-
-my $res = $ua->get("http://www.google.com/search?q=foo");
-isa_ok( $res, 'HTTP::Response' );
-
-ok( $res->is_success, 'Request is successful' );
-is( $res->content, 'bar', 'Correct response content' );
@@ -1,120 +1,86 @@
use strict;
use warnings;
use Test::More;
+use Plack::Test;
+use HTTP::Cookies;
+use HTTP::Request::Common;
+
+{
+ package App;
+ use Dancer2;
+
+ setting(
+ engines => {
+ session => {
+ Simple => {
+ cookie_name => 'dancer.sid',
+ cookie_path => '/foo',
+ cookie_duration => '1 hour',
+ is_http_only => 0, # will not show up in cookie
+ },
+ },
+ }
+ );
-use YAML;
-use Test::TCP 1.13;
-use File::Temp 0.22;
-use LWP::UserAgent;
-use HTTP::Date qw/str2time/;
-use File::Spec;
-
-sub extract_cookie {
- my ($res) = @_;
- my @cookies = $res->header('set-cookie');
- for my $c (@cookies) {
- next unless $c =~ /dancer\.sid/; # custom
- my @parts = split /;\s+/, $c;
- my %hash =
- map { my ( $k, $v ) = split /\s*=\s*/; $v ||= 1; ( lc($k), $v ) }
- @parts;
- $hash{expires} = str2time( $hash{expires} )
- if $hash{expires};
- return \%hash;
- }
- return;
-}
+ setting( session => 'Simple' );
-my $tempdir = File::Temp::tempdir( CLEANUP => 1, TMPDIR => 1 );
-
-for my $session_expires ( 3600, '1h', '1 hour' ) {
- Test::TCP::test_tcp(
- client => sub {
- my $port = shift;
-
- my $ua = LWP::UserAgent->new;
- $ua->cookie_jar( { file => "$tempdir/.cookies.txt" } );
-
- my ( $res, $cookie );
-
- # set value into session
- $res = $ua->get("http://127.0.0.1:$port/foo/set_session/larry");
- ok $res->is_success, "/foo/set_session/larry";
- $cookie = extract_cookie($res);
- my $err;
- ok $cookie, "session cookie set"
- or $err++;
- ok $cookie->{expires} - time > 3540,
- "cookie expiration is in future"
- or $err++;
- is $cookie->{domain}, '127.0.0.1', "cookie domain set"
- or $err++;
- is $cookie->{path}, '/foo', "cookie path set"
- or $err++;
- is $cookie->{httponly}, undef, "cookie has not set HttpOnly";
- diag explain $cookie
- if $err;
-
- # read value back
- $res = $ua->get("http://127.0.0.1:$port/foo/read_session");
- ok $res->is_success, "/foo/read_session";
- like $res->content, qr/name='larry'/, "session value looks good";
-
- File::Temp::cleanup();
- },
- server => sub {
- my $port = shift;
-
- use Dancer2;
-
- get '/has_session' => sub {
- return app->has_session;
- };
-
- get '/foo/set_session/*' => sub {
- my ($name) = splat;
- session name => $name;
- };
-
- get '/foo/read_session' => sub {
- my $name = session('name') || '';
- "name='$name'";
- };
-
- get '/foo/destroy_session' => sub {
- my $name = session('name') || '';
- app->destroy_session;
- return "destroyed='$name'";
- };
-
- setting appdir => $tempdir;
- setting(
- engines => {
- session => {
- Simple => {
- cookie_name => 'dancer.sid',
- cookie_domain => '127.0.0.1',
- cookie_path => '/foo',
- cookie_duration => $session_expires,
-## is_secure => 0, # can't easily test without https test server
- is_http_only => 0, # will not show up in cookie
- },
- },
- }
- );
- setting( session => 'Simple' );
-
- set(show_errors => 1,
- startup_info => 0,
- environment => 'production',
- port => $port
- );
-
- # we're overiding a RO attribute only for this test!
- Dancer2->runner->{'port'} = $port;
- start;
- },
- );
+ get '/has_session' => sub {
+ return app->has_session;
+ };
+
+ get '/foo/set_session/*' => sub {
+ my ($name) = splat;
+ session name => $name;
+ };
+
+ get '/foo/read_session' => sub {
+ my $name = session('name') || '';
+ "name='$name'";
+ };
+ get '/foo/destroy_session' => sub {
+ my $name = session('name') || '';
+ app->destroy_session;
+ return "destroyed='$name'";
+ };
}
+
+my $test = Plack::Test->create( App->to_app );
+my $url = 'http://localhost';
+
+my $jar = HTTP::Cookies->new;
+
+subtest 'Set session' => sub {
+ my $res = $test->request( GET "$url/foo/set_session/larry" );
+ ok( $res->is_success, '/foo/set_session/larry' );
+
+ $jar->extract_cookies($res);
+ ok( $jar->as_string, 'session cookie set' );
+
+ my ( $expires, $domain, $path, $opts );
+ my $cookie = $jar->scan( sub {
+ ( $expires, $domain, $path, $opts ) = @_[ 8, 4, 3 ];
+ } );
+
+ my $httponly = $opts->{'HttpOnly'};
+
+ ok $expires - time > 3540,
+ "cookie expiration is in future";
+
+ is $domain, 'localhost.local', "cookie domain set";
+ is $path, '/foo', "cookie path set";
+ is $httponly, undef, "cookie has not set HttpOnly";
+
+ # read value back
+};
+
+subtest 'Read session' => sub {
+ my $req = GET "$url/foo/read_session";
+ $jar->add_cookie_header($req);
+
+ my $res = $test->request($req);
+ ok $res->is_success, "/foo/read_session";
+ like $res->content, qr/name='larry'/, "session value looks good";
+};
+
done_testing;
@@ -1,109 +1,96 @@
use strict;
use warnings;
use Test::More;
-
use YAML;
-use Test::TCP 1.13;
-use File::Temp 0.22;
-use LWP::UserAgent;
-use File::Spec;
-
-my $tempdir = File::Temp::tempdir( CLEANUP => 1, TMPDIR => 1 );
+use Plack::Test;
+use HTTP::Cookies;
+use HTTP::Request::Common;
my @clients = qw(one two three);
-my @engines = qw(YAML Simple);
my $SESSION_DIR;
-if ( $ENV{DANCER_TEST_COOKIE} ) {
- push @engines, "cookie";
- setting( session_cookie_key => "secret/foo*@!" );
+{
+ package App;
+ use Dancer2;
+ my @to_destroy;
+
+ hook 'engine.session.before_destroy' => sub {
+ my $session = shift;
+ push @to_destroy, $session;
+ };
+
+ get '/set_session/*' => sub {
+ my ($name) = splat;
+ session name => $name;
+ };
+
+ get '/read_session' => sub {
+ my $name = session('name') || '';
+ "name='$name'";
+ };
+
+ get '/clear_session' => sub {
+ session name => undef;
+ return exists( session->data->{'name'} ) ? "failed" : "cleared";
+ };
+
+ get '/cleanup' => sub {
+ app->destroy_session;
+ return scalar(@to_destroy);
+ };
+
+ setting session => 'Simple';
+
+ set(
+ show_errors => 1,
+ environment => 'production',
+ );
}
-foreach my $engine (@engines) {
-
-
- note "Testing engine $engine";
- Test::TCP::test_tcp(
- client => sub {
- my $port = shift;
-
- foreach my $client (@clients) {
- my $ua = LWP::UserAgent->new;
- $ua->cookie_jar( { file => "$tempdir/.cookies.txt" } );
-
- my $res = $ua->get("http://127.0.0.1:$port/read_session");
- like $res->content, qr/name=''/,
- "empty session for client $client";
-
- $res = $ua->get("http://127.0.0.1:$port/set_session/$client");
- ok( $res->is_success, "set_session for client $client" );
-
- $res = $ua->get("http://127.0.0.1:$port/read_session");
- like $res->content, qr/name='$client'/,
- "session looks good for client $client";
-
- $res = $ua->get("http://127.0.0.1:$port/clear_session");
- like $res->content, qr/cleared/, "deleted session key";
-
- $res = $ua->get("http://127.0.0.1:$port/cleanup");
- ok( $res->is_success, "cleanup done for $client" );
-
- ok( $res->content, "session hook triggered" );
-
- }
-
- File::Temp::cleanup();
- },
- server => sub {
- my $port = shift;
-
- use Dancer2;
-
- my @to_destroy;
-
- hook 'engine.session.before_destroy' => sub {
- my $session = shift;
- push @to_destroy, $session;
- };
-
- get '/set_session/*' => sub {
- my ($name) = splat;
- session name => $name;
- };
-
- get '/read_session' => sub {
- my $name = session('name') || '';
- "name='$name'";
- };
-
- get '/clear_session' => sub {
- session name => undef;
- return exists( session->data->{name} ) ? "failed" : "cleared";
- };
-
- get '/cleanup' => sub {
- app->destroy_session;
- return scalar(@to_destroy);
- };
-
- setting appdir => $tempdir;
- setting(
- engines => {
- session => { $engine => { session_dir => 't/sessions' } }
- }
- );
- setting( session => $engine );
-
- set(show_errors => 1,
- startup_info => 0,
- environment => 'production',
- port => $port
- );
-
- # we're overiding a RO attribute only for this test!
- Dancer2->runner->{'port'} = $port;
- start;
- },
- );
+my $test = Plack::Test->create( App->to_app );
+my $url = "http://localhost";
+
+foreach my $client (@clients) {
+ my $jar = HTTP::Cookies->new;
+
+ subtest "[$client] Empty session" => sub {
+ my $res = $test->request( GET "$url/read_session" );
+ like $res->content, qr/name=''/,
+ "empty session for client $client";
+ $jar->extract_cookies($res);
+ };
+
+ subtest "[$client] set_session" => sub {
+ my $req = GET "$url/set_session/$client";
+ $jar->add_cookie_header($req);
+ my $res = $test->request($req);
+ ok( $res->is_success, "set_session for client $client" );
+ $jar->extract_cookies($res);
+ };
+
+ subtest "[$client] session for client" => sub {
+ my $req = GET "$url/read_session";
+ $jar->add_cookie_header($req);
+ my $res = $test->request($req);
+ like $res->content, qr/name='$client'/,
+ "session looks good for client $client";
+ $jar->extract_cookies($res);
+ };
+
+ subtest "[$client] delete session" => sub {
+ my $req = GET "$url/clear_session";
+ $jar->add_cookie_header($req);
+ my $res = $test->request($req);
+ like $res->content, qr/cleared/, "deleted session key";
+ };
+
+ subtest "[$client] cleanup" => sub {
+ my $req = GET "$url/cleanup";
+ $jar->add_cookie_header($req);
+ my $res = $test->request($req);
+ ok( $res->is_success, "cleanup done for $client" );
+ ok( $res->content, "session hook triggered" );
+ };
}
+
done_testing;
@@ -1,12 +1,9 @@
-use Test::More;
use strict;
use warnings;
-use LWP::UserAgent;
-use LWP::Protocol::PSGI;
-
-use File::Temp;
-
-my $tempdir = File::Temp::tempdir( CLEANUP => 1, TMPDIR => 1 );
+use Test::More;
+use Plack::Test;
+use HTTP::Cookies;
+use HTTP::Request::Common;
{
package Test::Forward::Single;
@@ -77,82 +74,99 @@ my $tempdir = File::Temp::tempdir( CLEANUP => 1, TMPDIR => 1 );
}
# base uri for all requests.
-my $base = "http://localhost:3000";
-
-note "Forwards within a single app"; {
- # Register single app as the handler for all LWP requests.
- LWP::Protocol::PSGI->register( Test::Forward::Single->to_app );
- my $ua = LWP::UserAgent->new;
- my $cookies_store = "$tempdir/.cookies.txt";
- $ua->cookie_jar( { file => $cookies_store } );
+my $base = 'http://localhost';
+
+subtest 'Forwards within a single app' => sub {
+ my $test = Plack::Test->create( Test::Forward::Single->to_app );
+ my $jar = HTTP::Cookies->new;
+
+ {
+ my $res = $test->request( GET "$base/main" );
+ is(
+ $res->content,
+ q{Single/main:Single/outer:Single/inner},
+ 'session value preserved after chained forwards',
+ );
+
+ $jar->extract_cookies($res);
+ }
+
+ {
+ my $req = GET "$base/inner";
+ $jar->add_cookie_header($req);
+
+ my $res = $test->request($req);
+ is(
+ $res->content,
+ q{Single/main:Single/outer:Single/inner},
+ 'session values preserved between calls',
+ );
+
+ $jar->extract_cookies($res);
+ }
+
+ {
+ my $req = GET "$base/clear";
+ $jar->add_cookie_header($req);
+
+ my $res = $test->request( GET "$base/clear" );
+ $jar->extract_cookies($res);
+ }
+
+ {
+ my $req = GET "$base/outer";
+ $jar->add_cookie_header($req);
+
+ my $res = $test->request( GET "$base/outer" );
+ is(
+ $res->content,
+ q{:Single/outer:Single/inner},
+ 'session value preserved after forward from route',
+ );
+
+ $jar->extract_cookies($res);
+ }
+};
+
+subtest 'Forwards between multiple apps using the same cookie name' => sub {
+ my $test = Plack::Test->create( Dancer2->psgi_app );
+ my $jar = HTTP::Cookies->new;
+
+ {
+ my $res = $test->request( GET "$base/same/main" );
+ is(
+ $res->content,
+ q{SameCookieName/main:Single/outer:Single/inner},
+ 'session value preserved after chained forwards between apps',
+ );
+
+ $jar->extract_cookies($res);
+ }
+
+ {
+ my $req = GET "$base/outer";
+ $jar->add_cookie_header($req);
+
+ my $res = $test->request($req);
+ is(
+ $res->content,
+ q{SameCookieName/main:Single/outer:Single/inner},
+ 'session value preserved after forward from route',
+ );
+ }
+};
+
+subtest 'Forwards between multiple apps using different cookie names' => sub {
+ my $test = Plack::Test->create( Dancer2->psgi_app );
+ my $jar = HTTP::Cookies->new;
+ my $res = $test->request( GET "$base/other/main" );
- my $res = $ua->get("$base/main");
- is(
- $res->content,
- q{Single/main:Single/outer:Single/inner},
- 'session value preserved after chained forwards',
- );
-
- $res = $ua->get("$base/inner");
- is(
- $res->content,
- q{Single/main:Single/outer:Single/inner},
- 'session values preserved between calls',
- );
-
- $res = $ua->get("$base/clear");
-
- $res = $ua->get("$base/outer");
- is(
- $res->content,
- q{:Single/outer:Single/inner},
- 'session value preserved after forward from route',
- );
-
- # cleanup.
- -e $cookies_store and unlink $cookies_store;
-}
-
-# Register all apps as the handler for all LWP requests.
-LWP::Protocol::PSGI->register( Dancer2->psgi_app );
-note "Forwards between multiple apps using the same cookie name"; {
- my $ua = LWP::UserAgent->new;
- my $cookies_store = "$tempdir/.cookies.txt";
- $ua->cookie_jar( { file => $cookies_store } );
-
- my $res = $ua->get("$base/same/main");
- is(
- $res->content,
- q{SameCookieName/main:Single/outer:Single/inner},
- 'session value preserved after chained forwards between apps',
- );
-
- $res = $ua->get("$base/outer");
- is(
- $res->content,
- q{SameCookieName/main:Single/outer:Single/inner},
- 'session value preserved after forward from route',
- );
-
- # cleanup.
- -e $cookies_store and unlink $cookies_store;
-}
-
-note "Forwards between multiple apps using different cookie names"; {
- my $ua = LWP::UserAgent->new;
- my $cookies_store = "$tempdir/.cookies.txt";
- $ua->cookie_jar( { file => $cookies_store } );
-
- my $res = $ua->get("$base/other/main");
is(
$res->content,
q{:Single/outer:Single/inner},
'session value only from forwarded app',
);
-
- # cleanup.
- -e $cookies_store and unlink $cookies_store;
-}
+};
# we need to make sure B doesn't override A when forwarding to C
# A -> B -> C
@@ -166,20 +180,16 @@ note "Forwards between multiple apps using different cookie names"; {
# if A -> Single, B -> OtherCookieName, C -> SameCookieName
# call A, create session, then forward to B, create session,
# then forward to C, check has values as in A and C
-note "Forwards between multiple apps using multiple different cookie names"; {
- my $ua = LWP::UserAgent->new;
- my $cookies_store = "$tempdir/.cookies.txt";
- $ua->cookie_jar( { file => $cookies_store } );
+subtest 'Forwards between multiple apps using multiple different cookie names' => sub {
+ my $test = Plack::Test->create( Dancer2->psgi_app );
+ my $jar = HTTP::Cookies->new;
+ my $res = $test->request( GET "$base/same/bad_chain" );
- my $res = $ua->get("$base/same/bad_chain");
is(
$res->content,
q{SameCookieName/bad_chain:Single/outer:Single/inner},
'session value only from apps with same session cookie name',
);
-
- # cleanup.
- -e $cookies_store and unlink $cookies_store;
-}
+};
done_testing;
@@ -1,16 +1,9 @@
use strict;
use warnings;
use Test::More;
-
-use File::Temp 0.22;
-use YAML;
-
-use LWP::UserAgent;
-
-eval "use LWP::Protocol::PSGI";
-plan skip_all => "LWP::Protocol::PSGI is needed for this test" if $@;
-
-my @engines = qw(Simple);
+use Plack::Test;
+use HTTP::Cookies;
+use HTTP::Request::Common;
my @hooks_to_test = qw(
engine.session.before_retrieve
@@ -25,143 +18,137 @@ my @hooks_to_test = qw(
engine.session.before_flush
engine.session.after_flush
);
-#we'll set a flag here when each hook is called. Then our test will then verify this
-my $test_flags = {};
-my $tempdir = File::Temp::tempdir( CLEANUP => 1, TMPDIR => 1 );
-#I need this to make sure it works with LWP::Protocol::PSGI See GH#447
-BEGIN {
- $ENV{DANCER_APPHANDLER} = 'PSGI';
-}
+# we'll set a flag here when each hook is called. Then our test will then verify this
+my $test_flags = {};
-sub get_app_for_engine {
- my $engine = shift;
+{
+ package App;
use Dancer2;
- #Possibly this doesn't seem to have a real effect. See GH#447
- setting apphandler => 'PSGI';
- setting appdir => $tempdir;
- setting(
- engines => { #we'll need this for YAML sessions
- session => { engine => {session_dir => 't/sessions'}}
- }
+ set(
+ show_errors => 1,
+ envoriment => 'production'
);
- set(show_errors => 1,
- startup_info => 0,
- envoriment => 'production'
- );
- setting(session => $engine);
+
+ setting( session => 'Simple' );
for my $hook (@hooks_to_test) {
hook $hook => sub {
- $test_flags->{$hook} ||= 0;
- $test_flags->{$hook}++;
+ $test_flags->{$hook} ||= 0;
+ $test_flags->{$hook}++;
}
}
get '/set_session' => sub {
- session foo => 'bar'; #setting causes a session flush
- return "ok";
+ session foo => 'bar'; #setting causes a session flush
+ return "ok";
};
+
get '/get_session' => sub {
- is session->read('foo'), 'bar', "Got the right session back";
- return "ok";
+ ::is session->read('foo'), 'bar', "Got the right session back";
+ return "ok";
};
+
get '/destroy_session' => sub {
- app->destroy_session;
- return "ok";
+ app->destroy_session;
+ return "ok";
};
#setup each hook again and test whether they return the correct type
#there is unfortunately quite some duplication here.
hook 'engine.session.before_create' => sub {
- my ($response) = @_;
- is ref($response), 'Dancer2::Core::Session',
- 'Correct response type returned in before_create';
+ my ($response) = @_;
+ ::isa_ok( $response, 'Dancer2::Core::Session' );
};
+
hook 'engine.session.after_create' => sub {
- my ($response) = @_;
- is ref($response), 'Dancer2::Core::Session',
- 'Correct response type returned in after_create';
+ my ($response) = @_;
+ ::isa_ok( $response, 'Dancer2::Core::Session' );
};
+
hook 'engine.session.after_retrieve' => sub {
- my ($response) = @_;
- is ref($response), 'Dancer2::Core::Session',
- 'Correct response type returned in after_retrieve';
+ my ($response) = @_;
+ ::isa_ok( $response, 'Dancer2::Core::Session' );
};
- #this returns dancer app. We'll register it with LWP::Protocol::PSGI
- dance;
}
-foreach my $engine (@engines) {
- note "Testing against $engine engine";
-
- $test_flags = {};
-
- #This will hijack lwp requests to localhost:3000 and send them to our dancer app
- LWP::Protocol::PSGI->register(get_app_for_engine($engine)); #if I set to hijack a particular <host:port> the connection is refused.
-
- my $ua = LWP::UserAgent->new;
- $ua->cookie_jar({file => "$tempdir/.cookies.$engine.txt"});
-
- my $r = $ua->get("http://localhost:3000/set_session");
- is $r->content, "ok", "set_session ran ok";
-
- #we verify whether the hooks were called correctly.
- subtest 'verify hooks for session create and session flush' => sub {
- is $test_flags->{'engine.session.before_create'}, 1, "session.before_create called";
- is $test_flags->{'engine.session.after_create'}, 1, "session.after_create called";
- is $test_flags->{'engine.session.before_flush'}, 1, "session.before_flush called";
- is $test_flags->{'engine.session.after_flush'}, 1, "session.after_flush called";
-
- is $test_flags->{'engine.session.before_retrieve'}, undef, "session.before_retrieve not called";
- is $test_flags->{'engine.session.after_retrieve'}, undef, "session.after_retrieve not called";
- is $test_flags->{'engine.session.before_destroy'}, undef, "session.before_destroy not called";
- is $test_flags->{'engine.session.after_destroy'}, undef, "session.after_destroy not called";
- };
-
- subtest 'verify Handler::File (static content) does not retrieve session' => sub {
- my $r = $ua->get("http://localhost:3000/file.txt");
-
- # These should not change from previous subtest
- is $test_flags->{'engine.session.before_create'}, 1, "session.before_create not called";
- is $test_flags->{'engine.session.after_create'}, 1, "session.after_create not called";
- is $test_flags->{'engine.session.before_retrieve'}, undef, "session.before_retrieve not called";
- is $test_flags->{'engine.session.after_retrieve'}, undef, "session.after_retrieve not called";
- };
-
- $r = $ua->get("http://localhost:3000/get_session");
- is $r->content, "ok", "get_session ran ok";
-
- subtest 'verify hooks for session retrieve' => sub {
- is $test_flags->{'engine.session.before_retrieve'}, 1, "session.before_retrieve called";
- is $test_flags->{'engine.session.after_retrieve'}, 1, "session.after_retrieve called";
-
- is $test_flags->{'engine.session.before_create'}, 1, "session.before_create not called";
- is $test_flags->{'engine.session.after_create'}, 1, "session.after_create not called";
- is $test_flags->{'engine.session.before_flush'}, 1, "session.before_flush not called";
- is $test_flags->{'engine.session.after_flush'}, 1, "session.after_flush not called";
- is $test_flags->{'engine.session.before_destroy'}, undef, "session.before_destroy not called";
- is $test_flags->{'engine.session.after_destroy'}, undef, "session.after_destroy not called";
- };
-
- $r = $ua->get("http://localhost:3000/destroy_session");
- is $r->content, "ok", "destroy_session ran ok";
-
- subtest 'verify session destroy hooks' => sub {
- is $test_flags->{'engine.session.before_destroy'}, 1, "session.before_destroy called";
- is $test_flags->{'engine.session.after_destroy'}, 1, "session.after_destroy called";
- #not sure if before and after retrieve should be called when the session is destroyed. But this happens.
- is $test_flags->{'engine.session.before_retrieve'}, 2, "session.before_retrieve called";
- is $test_flags->{'engine.session.after_retrieve'}, 2, "session.after_retrieve called";
-
- is $test_flags->{'engine.session.before_create'}, 1, "session.before_create not called";
- is $test_flags->{'engine.session.after_create'}, 1, "session.after_create not called";
- is $test_flags->{'engine.session.before_flush'}, 1, "session.before_flush not called";
- is $test_flags->{'engine.session.after_flush'}, 1, "session.after_flush not called";
- };
-
- File::Temp::cleanup();
-}
+my $test = Plack::Test->create( App->to_app );
+my $jar = HTTP::Cookies->new;
+my $url = "http://localhost";
+
+is_deeply( $test_flags, {}, 'Make sure flag hash is clear' );
+
+subtest set_session => sub {
+ my $res = $test->request( GET "$url/set_session" );
+ is $res->content, "ok", "set_session ran ok";
+ $jar->extract_cookies($res);
+};
+
+# we verify whether the hooks were called correctly.
+subtest 'verify hooks for session create and session flush' => sub {
+ is $test_flags->{'engine.session.before_create'}, 1, "session.before_create called";
+ is $test_flags->{'engine.session.after_create'}, 1, "session.after_create called";
+ is $test_flags->{'engine.session.before_flush'}, 1, "session.before_flush called";
+ is $test_flags->{'engine.session.after_flush'}, 1, "session.after_flush called";
+
+ is $test_flags->{'engine.session.before_retrieve'}, undef, "session.before_retrieve not called";
+ is $test_flags->{'engine.session.after_retrieve'}, undef, "session.after_retrieve not called";
+ is $test_flags->{'engine.session.before_destroy'}, undef, "session.before_destroy not called";
+ is $test_flags->{'engine.session.after_destroy'}, undef, "session.after_destroy not called";
+};
+
+subtest 'verify Handler::File (static content) does not retrieve session' => sub {
+ my $req = GET "$url/file.txt";
+ $jar->add_cookie_header($req);
+ my $res = $test->request($req);
+ $jar->extract_cookies($res);
+
+ # These should not change from previous subtest
+ is $test_flags->{'engine.session.before_create'}, 1, "session.before_create not called";
+ is $test_flags->{'engine.session.after_create'}, 1, "session.after_create not called";
+ is $test_flags->{'engine.session.before_retrieve'}, undef, "session.before_retrieve not called";
+ is $test_flags->{'engine.session.after_retrieve'}, undef, "session.after_retrieve not called";
+};
+
+subtest get_session => sub {
+ my $req = GET "$url/get_session";
+ $jar->add_cookie_header($req);
+ my $res = $test->request($req);
+ is $res->content, "ok", "get_session ran ok";
+ $jar->extract_cookies($res);
+};
+
+subtest 'verify hooks for session retrieve' => sub {
+ is $test_flags->{'engine.session.before_retrieve'}, 1, "session.before_retrieve called";
+ is $test_flags->{'engine.session.after_retrieve'}, 1, "session.after_retrieve called";
+
+ is $test_flags->{'engine.session.before_create'}, 1, "session.before_create not called";
+ is $test_flags->{'engine.session.after_create'}, 1, "session.after_create not called";
+ is $test_flags->{'engine.session.before_flush'}, 1, "session.before_flush not called";
+ is $test_flags->{'engine.session.after_flush'}, 1, "session.after_flush not called";
+ is $test_flags->{'engine.session.before_destroy'}, undef, "session.before_destroy not called";
+ is $test_flags->{'engine.session.after_destroy'}, undef, "session.after_destroy not called";
+};
+
+subtest destroy_session => sub {
+ my $req = GET "$url/destroy_session";
+ $jar->add_cookie_header($req);
+ my $res = $test->request($req);
+ is $res->content, "ok", "destroy_session ran ok";
+};
+
+subtest 'verify session destroy hooks' => sub {
+ is $test_flags->{'engine.session.before_destroy'}, 1, "session.before_destroy called";
+ is $test_flags->{'engine.session.after_destroy'}, 1, "session.after_destroy called";
+ #not sure if before and after retrieve should be called when the session is destroyed. But this happens.
+ is $test_flags->{'engine.session.before_retrieve'}, 2, "session.before_retrieve called";
+ is $test_flags->{'engine.session.after_retrieve'}, 2, "session.after_retrieve called";
+
+ is $test_flags->{'engine.session.before_create'}, 1, "session.before_create not called";
+ is $test_flags->{'engine.session.after_create'}, 1, "session.after_create not called";
+ is $test_flags->{'engine.session.before_flush'}, 1, "session.before_flush not called";
+ is $test_flags->{'engine.session.after_flush'}, 1, "session.after_flush not called";
+};
done_testing;
@@ -2,78 +2,78 @@ use strict;
use warnings;
use Test::More;
-use YAML;
-use Test::TCP 1.13;
-use File::Temp 0.22;
-use LWP::UserAgent;
-use HTTP::Date qw/str2time/;
-use File::Spec;
-
-my $tempdir = File::Temp::tempdir( CLEANUP => 1, TMPDIR => 1 );
-
-Test::TCP::test_tcp(
- client => sub {
- my $port = shift;
-
- my $ua = LWP::UserAgent->new;
- $ua->cookie_jar( { file => "$tempdir/.cookies.txt" } );
-
- my $res = $ua->get("http://127.0.0.1:$port/");
- ok $res->is_success;
- is $res->content, "session.name \n";
-
- $res = $ua->get("http://127.0.0.1:$port/set_session/test_name");
- ok $res->is_success;
- is $res->content, "session.name test_name\n";
-
- $res = $ua->get("http://127.0.0.1:$port/destroy_session");
- ok $res->is_success;
- is $res->content, "session.name \n";
-
- File::Temp::cleanup();
- },
- server => sub {
- my $port = shift;
-
- use Dancer2;
-
- get '/' => sub {
- template 'session_in_template'
- };
-
- get '/set_session/*' => sub {
- my ($name) = splat;
- session name => $name;
- template 'session_in_template';
- };
-
- get '/destroy_session' => sub {
- # Need to call the 'session' keyword, so app->setup_session
- # is called and the session attribute in the engines is populated
- my $name = session 'name';
- # Destroying the session should remove the session object from
- # all engines.
- app->destroy_session;
- template 'session_in_template';
- };
-
- setting appdir => $tempdir;
- setting(
- engines => {
- session => { 'Simple' => { session_dir => 't/sessions' } }
- }
- );
- setting( session => 'Simple' );
-
- set(show_errors => 1,
- startup_info => 0,
- environment => 'production',
- port => $port
- );
-
- # we're overiding a RO attribute only for this test!
- Dancer2->runner->{'port'} = $port;
- start;
- },
-);
-done_testing;
+use Plack::Test;
+use HTTP::Request::Common;
+use HTTP::Cookies;
+
+{
+ package TestApp;
+
+ use Dancer2;
+
+ get '/' => sub {
+ template 'session_in_template'
+ };
+
+ get '/set_session/*' => sub {
+ my ($name) = splat;
+ session name => $name;
+ template 'session_in_template';
+ };
+
+ get '/destroy_session' => sub {
+ # Need to call the 'session' keyword, so app->setup_session
+ # is called and the session attribute in the engines is populated
+ my $name = session 'name';
+ # Destroying the session should remove the session object from
+ # all engines.
+ app->destroy_session;
+ template 'session_in_template';
+ };
+
+ setting(
+ engines => {
+ session => { 'Simple' => { session_dir => 't/sessions' } }
+ }
+ );
+ setting( session => 'Simple' );
+}
+
+my $app = TestApp->to_app;
+is( ref $app, 'CODE', 'Got app' );
+
+my $test = Plack::Test->create($app);
+my $jar = HTTP::Cookies->new();
+
+{
+ my $res = $test->request( GET '/' );
+
+ ok $res->is_success, 'Successful request';
+ is $res->content, "session.name \n";
+
+ $jar->extract_cookies($res);
+}
+
+{
+ my $request = GET '/set_session/test_name';
+ $jar->add_cookie_header($request);
+
+ my $res = $test->request($request);
+ ok $res->is_success, 'Successful request';
+ is $res->content, "session.name test_name\n";
+
+ $jar->extract_cookies($res);
+}
+
+{
+ my $request = GET '/destroy_session';
+ $jar->add_cookie_header($request);
+
+ my $res = $test->request($request);
+ ok $res->is_success, 'Successful request';
+ is $res->content, "session.name \n";
+
+ $jar->extract_cookies($res);
+}
+
+done_testing();
@@ -1,180 +1,169 @@
use strict;
use warnings;
use Test::More;
-
-use YAML;
-use Test::TCP 1.13;
-use File::Temp 0.22;
-use LWP::UserAgent;
-use HTTP::Date qw/str2time/;
-use File::Spec;
-
-sub extract_cookie {
- my ($res) = @_;
- my @cookies = $res->header('set-cookie');
- for my $c (@cookies) {
- next unless $c =~ /dancer\.session/;
- my @parts = split /;\s+/, $c;
- my %hash =
- map { my ( $k, $v ) = split /\s*=\s*/; $v ||= 1; ( lc($k), $v ) }
- @parts;
- $hash{expires} = str2time( $hash{expires} )
- if $hash{expires};
- return \%hash;
- }
- return;
+use Plack::Test;
+use HTTP::Request::Common;
+use HTTP::Cookies;
+
+{
+ package App;
+ use Dancer2;
+
+ set session => 'Simple';
+ set show_errors => 1;
+
+ get '/no_session_data' => sub {
+ return "session not modified";
+ };
+
+ get '/set_session/*' => sub {
+ my ($name) = splat;
+ session name => $name;
+ };
+
+ get '/read_session' => sub {
+ my $name = session('name') || '';
+ "name='$name'";
+ };
+
+ get '/destroy_session' => sub {
+ my $name = session('name') || '';
+ app->destroy_session;
+ return "destroyed='$name'";
+ };
+
+ get '/churn_session' => sub {
+ app->destroy_session;
+ session name => 'damian';
+ return "churned";
+ };
}
-my $tempdir = File::Temp::tempdir( CLEANUP => 1, TMPDIR => 1 );
+my $url = 'http://localhost';
+my $jar = HTTP::Cookies->new();
+my $test = Plack::Test->create( App->to_app );
-my @engines = qw(YAML Simple);
+subtest 'No cookie set if session not referenced' => sub {
+ my $res = $test->request( GET "$url/no_session_data" );
+ ok $res->is_success, "/no_session_data"
+ or diag explain $res;
-if ( $ENV{DANCER_TEST_COOKIE} ) {
- push @engines, "cookie";
- setting( session_cookie_key => "secret/foo*@!" );
-}
+ $jar->extract_cookies($res);
+ ok( !$jar->as_string, 'No cookie set' );
+};
+
+subtest 'No empty session created if session read attempted' => sub {
+ my $res = $test->request( GET "$url/read_session" );
+ ok $res->is_success, "/read_session";
+
+ $jar->extract_cookies($res);
+ ok( !$jar->as_string, 'No cookie set' );
+};
+
+my $sid1;
+subtest 'Set value into session' => sub {
+ my $res = $test->request( GET "$url/set_session/larry" );
+ ok $res->is_success, "/set_session/larry";
+
+ $jar->extract_cookies($res);
+ ok( $jar->as_string, 'Cookie set' );
+
+ # extract SID
+ $jar->scan( sub { $sid1 = $_[2] } );
+ ok( $sid1, 'Got SID from cookie' );
+};
+
+subtest 'Read value back' => sub {
+ # read value back
+ my $req = GET "$url/read_session";
+ $jar->add_cookie_header($req);
+ my $res = $test->request($req);
+ ok $res->is_success, "/read_session";
+
+ $jar->clear;
+ ok( !$jar->as_string, 'Jar cleared' );
+
+ $jar->extract_cookies($res);
+ ok( $jar->as_string, 'session cookie set again' );
+ like $res->content, qr/name='larry'/, "session value looks good";
+};
+
+subtest 'Session cookie persists even if we do not touch sessions' => sub {
+ my $req = GET "$url/no_session_data";
+ $jar->add_cookie_header($req);
+
+ my $res = $test->request($req);
+ ok $res->is_success, "/no_session_data";
+
+ $jar->clear;
+ ok( !$jar->as_string, 'Jar cleared' );
+
+ $jar->extract_cookies($res);
+ ok( $jar->as_string, 'session cookie set again' );
+};
+
+subtest 'Destroy session and check that cookies expiration is set' => sub {
+ my $req = GET "$url/destroy_session";
+ $jar->add_cookie_header($req);
+
+ my $res = $test->request($req);
+ ok $res->is_success, "/destroy_session";
+
+ ok( $jar->as_string, 'We have a cookie before reading response' );
+ $jar->extract_cookies($res);
+ ok( ! $jar->as_string, 'Cookie was removed from jar' );
+};
+
+subtest 'Session cookie not sent after session destruction' => sub {
+ my $req = GET "$url/no_session_data";
+ $jar->add_cookie_header($req);
+
+ my $res = $test->request($req);
+ ok $res->is_success, "/no_session_data";
+
+ ok( !$jar->as_string, 'Jar is empty' );
+ $jar->extract_cookies($res);
+ ok( !$jar->as_string, 'Jar still empty (no new session cookie)' );
+};
+
+my $sid2;
+subtest 'Set value into session again' => sub {
+ my $res = $test->request( GET "$url/set_session/curly" );
+ ok $res->is_success, "/set_session/larry";
+
+ $jar->extract_cookies($res);
+ ok( $jar->as_string, 'session cookie set' );
+
+ # extract SID
+ $jar->scan( sub { $sid2 = $_[2] } );
+ isnt $sid2, $sid1, "New session has different ID";
+};
+
+subtest 'Destroy and create a session in one request' => sub {
+ my $req = GET "$url/churn_session";
+ $jar->add_cookie_header($req);
+
+ my $res = $test->request($req);
+ ok $res->is_success, "/churn_session";
+
+ $jar->extract_cookies($res);
+ ok( $jar->as_string, 'session cookie set' );
+
+ my $sid3;
+ $jar->scan( sub { $sid3 = $_[2] } );
+ isnt $sid3, $sid2, "Changed session has different ID";
+};
+
+subtest 'Read value back' => sub {
+ my $req = GET "$url/read_session";
+ $jar->add_cookie_header($req);
+
+ my $res = $test->request($req);
+ ok $res->is_success, "/read_session";
+
+ $jar->extract_cookies($res);
+ ok( $jar->as_string, "session cookie set" );
+ like $res->content, qr/name='damian'/, "session value looks good";
+};
-foreach my $engine (@engines) {
-
- note "Testing engine $engine";
- Test::TCP::test_tcp(
- client => sub {
- my $port = shift;
-
- my $ua = LWP::UserAgent->new;
- $ua->cookie_jar( { file => "$tempdir/.cookies.txt" } );
-
- # no session cookie set if session not referenced
- my $res = $ua->get("http://127.0.0.1:$port/no_session_data");
- ok $res->is_success, "/no_session_data"
- or diag explain $res;
- my $cookie = extract_cookie($res);
- ok !$cookie, "no cookie set"
- or diag explain $cookie;
-
- # no empty session created if session read attempted
- $res = $ua->get("http://127.0.0.1:$port/read_session");
- ok $res->is_success, "/read_session";
- $cookie = extract_cookie($res);
- ok !$cookie, "no cookie set"
- or diag explain $cookie;
-
- # set value into session
- $res = $ua->get("http://127.0.0.1:$port/set_session/larry");
- ok $res->is_success, "/set_session/larry";
- $cookie = extract_cookie($res);
- ok $cookie, "session cookie set"
- or diag explain $cookie;
- my $sid1 = $cookie->{"dancer.session"};
-
- # read value back
- $res = $ua->get("http://127.0.0.1:$port/read_session");
- ok $res->is_success, "/read_session";
- $cookie = extract_cookie($res);
- ok $cookie, "session cookie set"
- or diag explain $cookie;
- like $res->content, qr/name='larry'/, "session value looks good";
-
- # session cookie should persist even if we don't touch sessions
- $res = $ua->get("http://127.0.0.1:$port/no_session_data");
- ok $res->is_success, "/no_session_data";
- $cookie = extract_cookie($res);
- ok $cookie, "session cookie set"
- or diag explain $cookie;
-
- # destroy session and check that cookies expiration is set
- $res = $ua->get("http://127.0.0.1:$port/destroy_session");
- ok $res->is_success, "/destroy_session";
- $cookie = extract_cookie($res);
- ok $cookie, "session cookie set"
- or diag explain $cookie;
- is $cookie->{"dancer.session"}, $sid1, "correct cookie expired";
- ok $cookie->{expires} < time, "session cookie is expired";
-
- # shouldn't be sent session cookie after session destruction
- $res = $ua->get("http://127.0.0.1:$port/no_session_data");
- ok $res->is_success, "/no_session_data";
- $cookie = extract_cookie($res);
- ok !$cookie, "no cookie set"
- or diag explain $cookie;
-
- # set value into session again
- $res = $ua->get("http://127.0.0.1:$port/set_session/curly");
- ok $res->is_success, "/set_session/larry";
- $cookie = extract_cookie($res);
- ok $cookie, "session cookie set"
- or diag explain $cookie;
- my $sid2 = $cookie->{"dancer.session"};
- isnt $sid2, $sid1, "New session has different ID";
-
- # destroy and create a session in one request
- $res = $ua->get("http://127.0.0.1:$port/churn_session");
- ok $res->is_success, "/churn_session";
- $cookie = extract_cookie($res);
- ok $cookie, "session cookie set"
- or diag explain $cookie;
- my $sid3 = $cookie->{"dancer.session"};
- isnt $sid3, $sid2, "Changed session has different ID";
-
- # read value back
- $res = $ua->get("http://127.0.0.1:$port/read_session");
- ok $res->is_success, "/read_session";
- $cookie = extract_cookie($res);
- ok $cookie, "session cookie set"
- or diag explain $cookie;
- like $res->content, qr/name='damian'/, "session value looks good";
-
- File::Temp::cleanup();
- },
- server => sub {
- my $port = shift;
-
- use Dancer2;
-
- get '/no_session_data' => sub {
- return "session not modified";
- };
-
- get '/set_session/*' => sub {
- my ($name) = splat;
- session name => $name;
- };
-
- get '/read_session' => sub {
- my $name = session('name') || '';
- "name='$name'";
- };
-
- get '/destroy_session' => sub {
- my $name = session('name') || '';
- app->destroy_session;
- return "destroyed='$name'";
- };
-
- get '/churn_session' => sub {
- app->destroy_session;
- session name => 'damian';
- return "churned";
- };
-
- setting appdir => $tempdir;
- setting(
- engines => {
- session => { $engine => { session_dir => 't/sessions' } }
- }
- );
- setting( session => $engine );
-
- set(show_errors => 1,
- startup_info => 0,
- environment => 'production',
- port => $port
- );
-
- # we're overiding a RO attribute only for this test!
- Dancer2->runner->{'port'} = $port;
- start;
- },
- );
-}
done_testing;
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -1,54 +1,50 @@
use strict;
use warnings;
-
-use File::Spec;
-use File::Temp 0.22;
-use LWP::UserAgent;
use Test::More;
-use Test::TCP 1.13;
-use YAML;
-
-my $tempdir = File::Temp::tempdir( CLEANUP => 1, TMPDIR => 1 );
-
-Test::TCP::test_tcp(
- client => sub {
- my $port = shift;
-
- my $ua = LWP::UserAgent->new;
- $ua->cookie_jar( { file => "$tempdir/.cookies.txt" } );
-
- my $res = $ua->get("http://127.0.0.1:$port/main");
- like $res->content, qr{42}, "session is set in main";
-
- $res = $ua->get("http://127.0.0.1:$port/in_foo");
- like $res->content, qr{42}, "session is set in foo";
-
- my $engine = t::lib::Foo->dsl->engine('session');
- is $engine->{__marker__}, 1,
- "the session engine in subapp is the same";
-
- File::Temp::cleanup();
- },
- server => sub {
- my $port = shift;
-
- BEGIN {
- use Dancer2;
- set session => 'Simple';
- engine('session')->{'__marker__'} = 1;
- }
-
- use t::lib::Foo with => { session => engine('session') };
-
- get '/main' => sub {
- session( 'test' => 42 );
- };
-
- setting appdir => $tempdir;
- # we're overiding a RO attribute only for this test!
- Dancer2->runner->{'port'} = $port;
- start;
- },
-);
+use Plack::Test;
+use HTTP::Cookies;
+use HTTP::Request::Common;
+
+{
+ package App;
+
+ # call stuff before next use() statement
+ BEGIN {
+ use Dancer2;
+ set session => 'Simple';
+ engine('session')->{'__marker__'} = 1;
+ }
+
+ use t::lib::Foo with => { session => engine('session') };
+
+ get '/main' => sub {
+ session( 'test' => 42 );
+ };
+}
+
+my $jar = HTTP::Cookies->new;
+my $url = 'http://localhost';
+
+{
+ my $test = Plack::Test->create( App->to_app );
+ my $res = $test->request( GET "$url/main" );
+ like $res->content, qr{42}, "session is set in main";
+ $jar->extract_cookies($res);
+
+ ok( $jar->as_string, 'Got cookie' );
+}
+
+{
+ my $test = Plack::Test->create( t::lib::Foo->to_app );
+ my $req = GET "$url/in_foo";
+ $jar->add_cookie_header($req);
+
+ my $res = $test->request($req);
+ like $res->content, qr{42}, "session is set in foo";
+}
+
+my $engine = t::lib::Foo->dsl->engine('session');
+is $engine->{__marker__}, 1,
+ "the session engine in subapp is the same";
done_testing;