def generate_canonical_request(method, parsed_url, headers, content_sha256):
    """
    Generate canonical request.

    :param method: HTTP method.
    :param parsed_url: Parsed url is input from :func:`urlsplit`
    :param headers: HTTP header dictionary.
    :param content_sha256: Content sha256 used in canonical request.
    """
    content_sha256 = str(content_sha256)
    lines = [method, parsed_url.path]
    split_query = parsed_url.query.split('&')
    split_query.sort()
    for i in range(0, len(split_query)):
        if len(split_query[i]) > 0 and '=' not in split_query[i]:
            split_query[i] += '='
    query = '&'.join(split_query)
    lines.append(query)
    signed_headers = []
    header_lines = []
    for header in headers:
        value = headers[header]
        value = str(value).strip()
        header = header.lower().strip()
        signed_headers.append(header)
        header_lines.append(header.lower().strip() + ':' + str(value))
    signed_headers.sort()
    header_lines.sort()
    lines = lines + header_lines
    lines.append('')
    lines.append(';'.join(signed_headers))
    lines.append(str(content_sha256))
    return '\n'.join(lines)
