change unless blocks to if not blocks
Merge pull request #151 from dagolden/topic/fix-unless-blocks

change unless blocks to if not blocks

We need a PerlCritic policy for this one ;)
Delete session data key when value set to undef

Without a way to delete session data, sessions can only grow until
expired.

This patch deletes the key from the session data hash if the value is
set to undef.  Querying a non-existent key returns undef, so deleting a
key has the same effective result as setting it to undef with the added
benefit of shrinking the session.

Documentation of these behaviors and a test are included.
rename Dancer::Session::* to Dancer::SessionFactory::*
Move session_dir default to YAML session class

Session directories are a concept specific to file-based sessions.
It doesn't belong in the Core::Role::Config class.
Revise SessionFactory implentation API

Instead of handing off entire session objects to _flush, only the
id and data hashrefs are handed off.  This ensures that session object
attributes are not serialized.

Likewise, _retrieve now needs only to return a data hashref, which
SessionFactory will instantiate into a new object with *current*
session_config settings.  This ensures things like expiration time
are reset correctly.
Simple SessionFactory should delete during destory
allow session objects to destroy themselves
Move cookie_name into SessionFactory

This eliminates the hard-coded 'dancer.session' cookie name
in Dancer::Core::Context.
Set session cookie after request, not before

This ensures that cookie based sessions have a chance to flush
data into the session cookie value before the cookie is set.

This also attempts to only set a session cookie if one existed
or if a session has been referenced.
added test for session lifecycle
improve has_session predicate

Replaces the standard 'has_session' predicate with one that is only true
if a session engine has been defined and either a session has been
retrieved or created or a session cookie was retrieved in the request.

If this is true, calling $context->session returns a session that
previously existed.  If false, calling $context->session creates a new
session (and subsequent has_session() calls are true) or dies if a
session engine is not defined.
Remove creation_time attribute from core Session class

The 'creation_time' attribute is unused and the semantics are not
defined.

Expiration time in the Session class is cookie expiration time,
which may or may not be the same as session expiration, since cookie
expiration is under the control of the user.

If creation_time were a required field that session factories were
mandated to create and preserve on session retrieval, then it could be
used to help establish an independent session duration limit, but this
is not currently the case.

If session duration limits are desired, it is probably better for
applications to develop their own logic using data stored within
the session.

Depending on the nature of the session backend, session factories
could independently track creation time for use in offline
session expiration and disk/memory recovery, but this does not
require an attribute within the core Session class.
Move session cookie management to SessionFactory

This commit moves cookie generation from Dancer::Core::Session
to Dancer::Core::Role::SessionFactory and moves universal
session cookie configuration parameters as well.

The rationale is that SessionFactories should manage implementation
details, such as knowing how cookies are set and retrieved, and should
have configuration that applies to all sessions (such as 'is_secure').

Dancer::Core::Session objects can then purely represent the specific
details of a *specific* session: the ID, the data, and the expiration.
cleanup Dancer::Core::Session

Groups attributes together, fixes documentation and removes trailing
spaces.
Fix documentation of SessionFactory

Changes POD headers to head2 for consistency.

Clarifies return values required by C<_sessions>.
flush sessions properly during create()
ensure retrieved sessions have correct data hash
Moved session destruction to context

Sessions are now destroyed via the context object.  This is necessary
because sessions are managed in multiple places and need synchronized
behavior.

In addition to destroying the session via the factory, when a session is
destroyed we need to expire the existing session cookie and send it
back in the response, but only if another session does not replace it.

Likewise, once a session is destroyed, we must ignore the existing
request session cookie and not attempt to retrieve it again.

As a side benefit of this change, Dancer::Core::Session objects no
longer need a link back to their factory, which makes for cleaner
design.

This commit includes more extensive session lifecycle tests.
replace unless block with if not block