Menu Developer Moovweb University

Develop Locally: Project Configuration

Moovweb includes several features to ensure a proper website configuration. This includes settings for proper source site mapping, environment variable access, and HTTP header/cookie management.


moov_config.json

The moov_config.json file is used to configure project options. Like the extension suggests, this file follows the JSON syntax. To enable any of the configuration options below, just add them as JSON properties accordingly:

{
  "moovweb_project_format_version": "2.0.0",
  "domain_model": "subdomain",
  "taskrunner": {
    "on_project_start_command": "node ./tasks/start",
    "on_deploy_command": "node ./tasks/deploy",
    "on_request_command": "node ./tasks/request"
  },
  "layers": ["minify-js", "minify-css", "live-reload"],
  "host_map": [
    "$.igadgetcommerce.com => www.igadgetcommerce.com",
    "$.igadgetcommerce.com => igadgetcommerce.com"
  ]
}

The primary setting we’re concerned with is host_map. This setting takes an array of strings signifying what source sites your Moovweb domains should retrieve responses from when traveling upstream, as well as how to rewrite applicable subdomain URLs. For our iGadgetCommerce project, these references were already set up as soon as we generated the project earlier in the course.

moov_config.json has several other options that are outside of the scope of this course, so we have parted them into a separate document all about moov_config.json.


Environment Variables

The Moovweb SDK server automatically sets several environment variables in each project. These variables are typically HTTP headers and config parameters. You can use these variables in your transformations. Environment variables are found in the global env object.

The most frequently used are env.path (for the path a user visits) and env.status (for the status code reflecting a success, error, or redirect). The env variable is often used with regards to mapping pages (e.g. fns.constructPageType() in scripts/custom_functions.js) to specify transformation based on the page URL.

tmp data

A tmp/messages directory gets generated when you first run your project, and this directory will grow over time. It stores data about all requests made to your site, including HTTP logs for incoming and outgoing responses and requests, as well as environment variables available to you in your MoovJS code. This can become very useful during the development and debugging processes.

You might have noticed in your Dashboard Logs that each line is prefixed with a response ID (formatted as a date/time followed by a two-character code). This corresponds to the directory in tmp/messages containing all the appropriate request, response, and environment information.

Individual directories contain a final-env.json file, which is comprised of the the final returned env object.

Example Environment Variables

Here’s an example of a final-env.json file.

{
 "__catch_all__": ".moovapp.com",
 "accept_encoding": "gzip,deflate",
 "all_set_cookies": "lastVisitedCategory=2; path=/; domain=.igadgetcommerce.com::MWDELIM::",
 "asset_host": "//mlocal.igadgetcommerce.com/_moovweb_local_assets_/",
 "cache_control": "no-store, no-cache, must-revalidate, post-check=0, pre-check=0",
 "connection": "close",
 "content_type": "text/html; charset=UTF-8",
 "cookie": "fornax_anonymousId=8853212a-f635-4960-8f34-67e5cbd12497;",
 "date": "Tue, 07 Jul 2015 19:13:19 GMT",
 "device_stylesheet": "main",
 "expires": "Thu, 19 Nov 1981 08:52:00 GMT",
 "host": "mlocal.igadgetcommerce.com",
 "method": "GET",
 "path": "/shop-iphone/",
 "pragma": "no-cache",
 "secure": "false",
 "server": "nginx",
 "set_cookie": "lastVisitedCategory=2; path=/; domain=.igadgetcommerce.com",
 "source_host": "igadgetcommerce.com",
 "source_host_no_port": "igadgetcommerce.com",
 "status": "200",
 "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.81 Safari/537.36",
 "vary": "Accept-Encoding",
 "x_bc_is_ha": "1"
}

Note that you can get the user agent of the request from env.user_agent. (You can also use Modes to route experiences based on user agent, which will be discussed in a later lesson.)


HTTP Headers

You have limited ability to modify HTTP response headers by standard property assignment, using moov_stdlib’s fns.export().

Location

Use this export variable to change a response into a redirect, or to modify the location of a response that is already a redirect. These can be relative or absolute URLs and can even point outside of your source site.

fns.export("Location", "https://www.bing.com");

Location Header

Setting this export variable will automatically change a 200 status code to a 302. However it won’t change the status code if it is something other than a 200 (like a 404 or 500).

Content-Type

The Content-Type variable can affect only the type and subtype (e.g., “text/html”) of the content and not the parameters (e.g., “charset=ISO-8859-4”). The Content-Type header must already exist.

fns.export("Content-Type", "application/json");

Cache-Time

This is the only export variable that doesn’t correspond exactly to an HTTP response header. That’s because it sets multiple HTTP response headers.

The Cache-Time export variable sets the amount of time the page should be cached for. This should only be used when the transformed page has been made more cache-able than the original page.

It works by removing all caching headers (Cache-Control, Pragma, Expires), and then adding back in a Cache-Control header. The time is specified in seconds as in the Cache-Control max-age parameter.

fns.export("Cache-Time", "1200");

The above example indicates that the page should be cached for 20 minutes (1200 seconds). It would set a Cache-Control header like this:

Cache-Control: public, max-age=1200

Cookies

The host_map is also used to rewrite the Set-Cookie header of HTTP responses issued by the upstream server. Cookie rewriting works as follows:

  1. Cookie domains are set from right-to-left according to the host_map. Take this host_map for example:

    ...
    "host_map": [
      "$.example.com => www.example.com",
      "$.dup.example.com => www.example.com",
      "$.search.example.com => search.example.com"
    ]
    ...
    

    The right-hand side of the host_map will match the first occurrence of “www.example.com” and set the default cookie domain to “.example.com” using the left-hand side matching rule.

  2. The rewritten cookie domain uses the least restrictive domain between the two domains listed in the matching host_map rule. Here’s a cookie issued by the upstream server:

    Set-Cookie: flash=; Domain=www.example.com; expires=Fri, 07-Sep-2012 01:57:35 GMT; Path=/; httponly
    

    Notice the currently specified upstream cookie domain: “www.example.com”. The matching host_map rule yields the rewritten cookie domain: “.example.com”. So the cookie domain is rewritten to “.example.com” because that is the least restrictive between the two.

    So, in this case, the rewritten cookie looks like:

    Set-Cookie: flash=; Domain=.example.com; expires=Fri, 07-Sep-2012 01:57:35 GMT; Path=/; httponly
    

Rewritten Cookie

What is this all for?

While developing and debugging, you may need to reference the www. source site. If the source site uses cookie functionality to store session information, it would be useful if your session persists across both your mobile environment and your personal desktop experience. For example, if you log into an account on mobile while developing on your local mobile environment, you should expect that if you went back to review the desktop design, you should still be logged in. Using a least restrictive domain will allow this to happen.

What if the two domains aren’t comparable?

For example, the upstream cookie domain is “bad.example.com”, but the host_map rule yields “good.example.com”.

...
"host_map": [
  "$.good.example.com => bad.example.com"
]
...

Because there is no least restrictive domain between “bad.example.com” and “good.example.com”, the Moovweb SDK will rewrite the cookie domain following the host_map rule. The resulting cookie domain will be “$.good.example.com”, where “$” is the host variable.

By default, the upstream hostname will be used as the domain for all cookies when unspecified.

If the initial page request is under a catchall domain (for example “.moovapp.com”), we append “.moovapp.com” to the end of the chosen cookie domain.

Adding Cookies

If you need to add a new cookie to the page, you can use moov_stdlib’s fns.addCookie().

fns.addCookie = function(name, value, domain, path, expires, secure, httpOnly);

Read more about the usage of secure and httponly on Wikipedia.

You’re allowed to stop short if you know you’ll only need to fill out the first few arguments. For example:

fns.addCookie("favoriteDog", "joe", ".igadgetcommerce.com");

The above will set a cookie favoriteDog with the value joe and the upstream domain would be .igadgetcommerce.com.

As mentioned earlier, the domain of a cookie is rewritten using the least restrictive domain between the two domains listed in the matching host_map rule. This allows for cookies set by the transformed site to be shared with the origin site. This way, the user’s context is sustained even if they decide to visit the source site after having done some work on the transformed site.

However, there may be times when you would want to prevent cookie sharing between the the source site and the transformed site. For those rare cases, you can use the strict cookie rewriting mode.

To enable strict cookie rewriting mode, you can add the following rule to your moov_config.json file:

...
"cookie_rewrite_mode": "strict"
...

With this set in your moov_config.json, cookie domains will now be rewritten to use strictly the transformed domain name and won’t be sharable by the source site.