Goes through the url and returns a dictionary of fields.

    For example:

    img/photos/2008/05/12/WIZARDS_0034_05022035_r329x151.jpg?e315d4515574cec417b1845392ba687dd98c17ce

    actions:       [('r', '329x151')]
    parent_dir:    img/photos/2008/05/12/
    ext:           jpg
    base_filename: WIZARDS_0034_05022035
    security_hash: e315d4515574cec417b1845392ba687dd98c17ce
    requested_path /path/to/media_root/img/photos/2008/05/12/WIZARDS_0034_05022035_r329x151.jpg
    original_file: /path/to/media_root/img/photos/2008/05/12/WIZARDS_0034_05022035.jpg
    is_external:   False

    The ``document_root`` parameter overrides the ``BASE_PATH`` setting.

def process_url(url, server_name="", document_root=None, check_security=True):
    """
    Goes through the url and returns a dictionary of fields.

    For example:

    img/photos/2008/05/12/WIZARDS_0034_05022035_r329x151.jpg?e315d4515574cec417b1845392ba687dd98c17ce

    actions:       [('r', '329x151')]
    parent_dir:    img/photos/2008/05/12/
    ext:           jpg
    base_filename: WIZARDS_0034_05022035
    security_hash: e315d4515574cec417b1845392ba687dd98c17ce
    requested_path /path/to/media_root/img/photos/2008/05/12/WIZARDS_0034_05022035_r329x151.jpg
    original_file: /path/to/media_root/img/photos/2008/05/12/WIZARDS_0034_05022035.jpg
    is_external:   False

    The ``document_root`` parameter overrides the ``BASE_PATH`` setting.
    """
    from .network import Http404
    from settings import (BASE_PATH, ORIG_BASE_PATH, USE_VHOSTS, VHOST_DOC_BASE, EXTERNAL_PREFIX)

    try:
        request_uri, security_hash = url.split("?", 1)
    except ValueError:
        request_uri, security_hash = url, ""

    external_prefix = EXTERNAL_PREFIX
    is_external = request_uri.startswith(external_prefix)
    resolved_uri = resolve_request_path(request_uri)
    resolved_uri = resolved_uri.lstrip("/")
    resolved_uri = urllib.unquote(resolved_uri)
    if is_external:
        external_url = urllib.unquote(resolved_uri.replace(external_prefix.lstrip("/"), ''))
        resolved_uri = resolved_uri.replace("http://", '').replace('https://', '')
    else:
        external_url = ''

    base_path = document_root or BASE_PATH
    orig_base_path = ORIG_BASE_PATH or base_path

    if USE_VHOSTS:
        if not os.path.exists(os.path.join(BASE_PATH, server_name)):
            raise Http404("Bad server: %s" % server_name)
        parts = (base_path, server_name, VHOST_DOC_BASE,
                 resolved_uri)
        requested_path = os.path.join(*parts)
    else:
        path = os.path.join(base_path, resolved_uri)
        if base_path.startswith('s3://'):
            requested_path = path
        else:
            requested_path = os.path.abspath(path)

    if not requested_path.startswith(base_path):
        # Apparently, there was an attempt to put some directory traversal
        # hacks into the path. (../../../vulnerable_file.exe)
        raise Http404("Unknown file path.")

    parent_dir, requested_file = os.path.split(resolved_uri)
    base_filename, ext = os.path.splitext(requested_file)

    base_file_name, action_tuples = parse_action_tuples(requested_file)

    if USE_VHOSTS:
        original_file = os.path.join(orig_base_path, server_name, parent_dir, base_file_name + ext)
    else:
        original_file = os.path.join(orig_base_path, parent_dir, base_file_name + ext)

    base_uri = os.path.dirname(resolved_uri)
    original_uri = urlparse.urljoin(base_uri, base_filename + ext)

    if original_file.startswith(u's3://'):
        from filesystem import s3
        original_is_missing = not s3.file_exists(original_file)
    else:
        original_is_missing = not os.path.exists(original_file)

    if original_is_missing and is_external:
        try:
            download_url(external_url, original_file)
        except Exception as e:
            msg = "Error downloading external URL: %s" % e
            raise Http404(msg)
    elif original_is_missing:
        msg = "Original file does not exist. %r %r" % (url, original_file, )
        raise Http404(msg)
    if check_security and action_tuples and not is_valid_security(action_tuples, security_hash):
        raise Http404("Invalid security token.")
    output = {
        'actions': action_tuples,
        'parent_dir': parent_dir,
        'ext': ext,
        'base_filename': base_filename,
        'security_hash': security_hash,
        'requested_file': requested_path,
        'original_file': original_file,
        'orignial_uri': original_uri,
        'is_external': is_external,
        'external_url': external_url,
    }
    logger.debug("Processed {0} into {1}".format(url, str(output)))
    return output