rewriteUrl method

String rewriteUrl(
  1. String internalPath, {
  2. bool? includeSession,
})

Convert an internal path to an external path.

An internal path is one that starts with "~/". This method converts that to a path that can be used outside of the application (e.g. written in a HTML HREF attribute). If there is a session and session cookies are not being used, URL rewriting is performed (i.e. the session identifier is added as a query parameter).

For sessions to be preserved when cookies are not being used, all paths referencing the application's pages must be processed by this method. If a link is not processed, then the URL rewriting does not occur and the session will not be preserved.

The concept of an internal path serves two purposes. The main purpose is to try to force all paths through this method; making it more difficult to forget to rewrite the URL. The second purpose is to make it easy to change the path to the entire application by changing the Server.basePath of the server.

A good way to check if all paths are internal URLs that have been properly processed is to change the Server.basePath and test if the application still functions properly. If there are broken links, then those links were not defined as internal paths processed through this method.

The includeSession parameter indicates if the session is added as a query parameter. The default value of "null" causes it to be only added if there is a session and cookies are not being used. If it is false, it is never added. There is no good reason to ever use it with true.

The includeSession should be left as true in all situations, except when used for the "method" attribute of a HTML form element. In that situation, set it to false and use Request.sessionHiddenInputElement to preserve the session.

If the internalPath has any query parameters, they will be included in the result. So it is not just a pure path, but a path with optional query parameters.

Note: this method is on the request object, even though it ultimately affects the HTTP response. This is because the request object carries the context for the request and the response. The session is a part of that context.

See also ura.

Implementation

String rewriteUrl(String internalPath, {bool? includeSession}) {
  if (!internalPath.startsWith('~/')) {
    throw ArgumentError.value(
        internalPath, 'internalPath', 'rewriteUrl: does not start with "~/"');
  }

  final buf = StringBuffer(server._basePath);

  // Start with the base path

  if (!server._basePath.endsWith('/')) {
    buf.write('/');
  }

  // Add the path segments

  if (internalPath != '~/') {
    buf.write(internalPath.substring(2)); // without leading '~/'
  }

  // Add state preserving query parameter (if needed)

  final _session = session;

  if (_session == null ||
      (_sessionUsingCookies && includeSession != true) ||
      includeSession == false) {
    // Don't include the extra query parameter, because:
    // - there is no session to preserve;
    // - there is a session, but cookies are being used to preserve the
    //   session (and includeSession is not explicitly true); or
    // - invoker explicitly asked to not include it.
    return buf.toString();
  } else {
    // Append extra query parameter to preserve session
    final result = buf.toString();
    final separator = (result.contains('?')) ? '&' : '?';
    return '$result$separator${_server.sessionParamName}=${_session.id}';
  }
  //} else {
  // Simulated request
  // return internalPath;
  //}
}