<commit_before>Scopes
======

.. image:: http://www.bdoubliees.com/journalspirou/sfigures6/schtroumpfs/s11.jpg

Request
-------

Kinds of params
~~~~~~~~~~~~~~~

There are 2 kinds of request params: textual params and file upload params (binary).

There are 3 kinds of textual params, of type ``scala.collection.mutable.Map[String, List[String]]``:

1. ``uriParams``: params after the ? mark in the URL, example: http://example.com/blah?x=1&y=2
2. ``bodyParams``: params in POST request body
3. ``pathParams``: params embedded in the URL, example: ``@GET("/articles/:id/:title")``

These params are merged in the above order as ``textParams``
(from 1 to 3, the latter will override the former).

``fileUploadParams`` is of type scala.collection.mutable.Map[String, List[`FileUpload <https://github.com/netty/netty/blob/master/src/main/java/org/jboss/netty/handler/codec/http/FileUpload.java>`_]].

Accesing params
~~~~~~~~~~~~~~~

From an action, you can access the above params directly, or you can use
accessor methods.

To access ``textParams``:

* ``param("x")``: returns ``String``, throws exception if x does not exist
* ``params("x")``: returns ``List[String]``, throws exception if x does not exist
* ``paramo("x")``: returns ``Option[String]``
* ``paramso("x")``: returns ``Option[List[String]]``

You can convert text params to other types (Int, Long, Fload, Double) automatically
by using ``param[Int]("x")``, ``params[Int]("x")`` etc. To convert text params to more types,
override `convertText <https://github.com/ngocdaothanh/xitrum/blob/master/src/main/scala/xitrum/scope/request/ParamAccess.scala>`_.

For file upload: ``param[FileUpload]("x")``, ``params[FileUpload]("x")`` etc.

RequestVar
~~~~~~~~~~

To pass things around when processing a request (e.g. from action to view or layout)
in the typesafe way, you should use RequestVar.

RVar.scala

::

  import xitrum.RequestVar

  object RVar {
    object title extends RequestVar[String]
  }

AppAction.scala

::

  import xitrum.Action
  import xitrum.view.DocType

  trait AppAction extends Action {
    override def layout = DocType.xhtmlTransitional(
      <html>
        <head>
          {antiCSRFMeta}
          {xitrumCSS}
          <title>{if (RVar.title.isDefined) "My Site - " + RVar.title.get else "My Site"}</title>
        </head>
        <body>
          {renderedView}
          {jsAtBottom}
        </body>
      </html>
    )
  }

ShowAction.scala

::

  class ShowAction extends AppAction {
    override def execute {
      val (title, body) = ...  // Get from DB
      RVar.title.set(title)
      renderView(body)
    }
  }

Cookie
------

Inside an action, you can use ``cookies``. It is a subclass of Java's `TreeSet <http://download.oracle.com/javase/6/docs/api/java/util/TreeSet.html>`_
that contains `Cookie <https://github.com/netty/netty/blob/master/src/main/java/org/jboss/netty/handler/codec/http/Cookie.java>`_.
It is basically a normal TreeSet with an additional ``get`` method to lookup a cookie:

::

  cookies.get("myCookie") match {
    case None         => ...
    case Some(string) => ...
  }

To add a cookie, create an instance of `DefaultCookie <https://github.com/netty/netty/blob/master/src/main/java/org/jboss/netty/handler/codec/http/DefaultCookie.java>`_
and add it to ``cookies``:

::

  val cookie = new DefaultCookie("myCookie", "String value")
  cookies.add(cookie)

Remember that there's no way for the server to directly delete a cookie on browsers.
Instead, to delete immediately set max age to 0. To delete when the browser closes windows,
set max age to -1.

Session
-------

In your actions, you can use ``session``. It is an instance of
``scala.collection.mutable.Map[String, Any]``. Things in ``session`` must be
serializable.

resetSession
~~~~~~~~~~~~

`One line of code will protect you from session fixation <http://guides.rubyonrails.org/security.html#session-fixation>`_.

Read the link above to know about session fixation. To prevent session fixation
attack, in the action that lets users login, call ``resetSession``.

::

  class LoginAction extends Action {
    override def execute {
      ...
      resetSession  // Reset first before doing anything else with the session
      session("username") = username
    }
  }

To log users out, also call ``resetSession``.

SessionVar<commit_msg>Internet Explorer does not support "max-age"<commit_after>Scopes
======

.. image:: http://www.bdoubliees.com/journalspirou/sfigures6/schtroumpfs/s11.jpg

Request
-------

Kinds of params
~~~~~~~~~~~~~~~

There are 2 kinds of request params: textual params and file upload params (binary).

There are 3 kinds of textual params, of type ``scala.collection.mutable.Map[String, List[String]]``:

1. ``uriParams``: params after the ? mark in the URL, example: http://example.com/blah?x=1&y=2
2. ``bodyParams``: params in POST request body
3. ``pathParams``: params embedded in the URL, example: ``@GET("/articles/:id/:title")``

These params are merged in the above order as ``textParams``
(from 1 to 3, the latter will override the former).

``fileUploadParams`` is of type scala.collection.mutable.Map[String, List[`FileUpload <https://github.com/netty/netty/blob/master/src/main/java/org/jboss/netty/handler/codec/http/FileUpload.java>`_]].

Accesing params
~~~~~~~~~~~~~~~

From an action, you can access the above params directly, or you can use
accessor methods.

To access ``textParams``:

* ``param("x")``: returns ``String``, throws exception if x does not exist
* ``params("x")``: returns ``List[String]``, throws exception if x does not exist
* ``paramo("x")``: returns ``Option[String]``
* ``paramso("x")``: returns ``Option[List[String]]``

You can convert text params to other types (Int, Long, Fload, Double) automatically
by using ``param[Int]("x")``, ``params[Int]("x")`` etc. To convert text params to more types,
override `convertText <https://github.com/ngocdaothanh/xitrum/blob/master/src/main/scala/xitrum/scope/request/ParamAccess.scala>`_.

For file upload: ``param[FileUpload]("x")``, ``params[FileUpload]("x")`` etc.

RequestVar
~~~~~~~~~~

To pass things around when processing a request (e.g. from action to view or layout)
in the typesafe way, you should use RequestVar.

RVar.scala

::

  import xitrum.RequestVar

  object RVar {
    object title extends RequestVar[String]
  }

AppAction.scala

::

  import xitrum.Action
  import xitrum.view.DocType

  trait AppAction extends Action {
    override def layout = DocType.xhtmlTransitional(
      <html>
        <head>
          {antiCSRFMeta}
          {xitrumCSS}
          <title>{if (RVar.title.isDefined) "My Site - " + RVar.title.get else "My Site"}</title>
        </head>
        <body>
          {renderedView}
          {jsAtBottom}
        </body>
      </html>
    )
  }

ShowAction.scala

::

  class ShowAction extends AppAction {
    override def execute {
      val (title, body) = ...  // Get from DB
      RVar.title.set(title)
      renderView(body)
    }
  }

Cookie
------

Inside an action, you can use ``cookies``. It is a subclass of Java's `TreeSet <http://download.oracle.com/javase/6/docs/api/java/util/TreeSet.html>`_
that contains `Cookie <https://github.com/netty/netty/blob/master/src/main/java/org/jboss/netty/handler/codec/http/Cookie.java>`_.
It is basically a normal TreeSet with an additional ``get`` method to lookup a cookie:

::

  cookies.get("myCookie") match {
    case None         => ...
    case Some(string) => ...
  }

To add a cookie, create an instance of `DefaultCookie <https://github.com/netty/netty/blob/master/src/main/java/org/jboss/netty/handler/codec/http/DefaultCookie.java>`_
and add it to ``cookies``:

::

  val cookie = new DefaultCookie("myCookie", "String value")
  cookies.add(cookie)

Remember that there's no way for the server to directly delete a cookie on browsers.
Instead, to delete immediately set max age to 0. To delete when the browser closes windows,
set max age to -1.

Note that `Internet Explorer does not support "max-age" <http://mrcoles.com/blog/cookies-max-age-vs-expires/>`_,
but Netty detects and outputs either "max-age" or "expires" properly. Don't worry!

Session
-------

In your actions, you can use ``session``. It is an instance of
``scala.collection.mutable.Map[String, Any]``. Things in ``session`` must be
serializable.

resetSession
~~~~~~~~~~~~

`One line of code will protect you from session fixation <http://guides.rubyonrails.org/security.html#session-fixation>`_.

Read the link above to know about session fixation. To prevent session fixation
attack, in the action that lets users login, call ``resetSession``.

::

  class LoginAction extends Action {
    override def execute {
      ...
      resetSession  // Reset first before doing anything else with the session
      session("username") = username
    }
  }

To log users out, also call ``resetSession``.

SessionVar
{'fraction_non_alphanumeric': 0.14475461503827106, 'fraction_numerical': 0.003376857271499325, 'mean_word_length': 3.691129883843717, 'pattern_counts': {'":': 0, '<': 32, '<?xml version=': 0, '>': 36, 'https://': 8, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1594140', 'n_tokens_mistral': 2828, 'n_tokens_neox': 2725, 'n_words': 883}