# Buggy code
def update_s3(method, path, data, headers, response=None, return_forward_info=False):
    if return_forward_info:
        modified_data = None

        # If this request contains streaming v4 authentication signatures, strip them from the message
        # Related isse: https://github.com/atlassian/localstack/issues/98
        # TODO we should evaluate whether to replace moto s3 with scality/S3:
        # https://github.com/scality/S3/issues/237
        if headers.get("x-amz-content-sha256") == "STREAMING-AWS4-HMAC-SHA256-PAYLOAD":
            modified_data = strip_chunk_signatures(data)

        # persist this API call to disk
        persistence.record("s3", method, path, data, headers)

        parsed = urlparse.urlparse(path)
        query = parsed.query
        path = parsed.path
        bucket = path.split("/")[1]
        query_map = urlparse.parse_qs(query)
        if method == "PUT" and (query == "notification" or "notification" in query_map):
            tree = ET.fromstring(data)
            queue_config = tree.find("{%s}QueueConfiguration" % XMLNS_S3)
            if len(queue_config):
                S3_NOTIFICATIONS[bucket] = {
                    "Id": get_xml_text(queue_config, "Id"),
                    "Event": get_xml_text(queue_config, "Event", ns=XMLNS_S3),
                    "Queue": get_xml_text(queue_config, "Queue", ns=XMLNS_S3),
                    "Topic": get_xml_text(queue_config, "Topic", ns=XMLNS_S3),
                    "CloudFunction": get_xml_text(
                        queue_config, "CloudFunction", ns=XMLNS_S3
                    ),
                }
        if query == "cors" or "cors" in query_map:
            if method == "GET":
                return get_cors(bucket)
            if method == "PUT":
                return set_cors(bucket, data)
            if method == "DELETE":
                return delete_cors(bucket)

        if modified_data:
            return Request(data=modified_data, headers=headers)
        return True

    # get subscribers and send bucket notifications
    if method in ("PUT", "DELETE") and "/" in path[1:]:
        parts = path[1:].split("/", 1)
        bucket_name = parts[0]
        object_path = "/%s" % parts[1]
        send_notifications(method, bucket_name, object_path)
    # append CORS headers to response
    if response:
        parsed = urlparse.urlparse(path)
        bucket_name = parsed.path.split("/")[0]
        append_cors_headers(
            bucket_name,
            request_method=method,
            request_headers=headers,
            response=response,
        )


# Traceback (ResponseParserError)
ERROR:localstack.mock.generic_proxy:Error forwarding request: Traceback (most recent call last):
File "/opt/code/localstack/localstack/mock/generic_proxy.py", line 88, in forward
data=data, headers=self.headers, return_forward_info=True)
File "/opt/code/localstack/localstack/mock/proxy/sns_listener.py", line 37, in update_sns
queue_url = aws_stack.get_sqs_queue_url(queue_name)
File "/opt/code/localstack/localstack/utils/aws/aws_stack.py", line 285, in get_sqs_queue_url
response = client.get_queue_url(QueueName=queue_name)
File "/opt/code/localstack/.venv/lib/python2.7/site-packages/botocore/client.py", line 253, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/opt/code/localstack/.venv/lib/python2.7/site-packages/botocore/client.py", line 531, in _make_api_call
operation_model, request_dict)
File "/opt/code/localstack/.venv/lib/python2.7/site-packages/botocore/endpoint.py", line 141, in make_request
return self._send_request(request_dict, operation_model)
File "/opt/code/localstack/.venv/lib/python2.7/site-packages/botocore/endpoint.py", line 168, in _send_request
request, operation_model, attempts)
File "/opt/code/localstack/.venv/lib/python2.7/site-packages/botocore/endpoint.py", line 233, in _get_response
response_dict, operation_model.output_shape)
File "/opt/code/localstack/.venv/lib/python2.7/site-packages/botocore/parsers.py", line 210, in parse
parsed = self._do_error_parse(response, shape)
File "/opt/code/localstack/.venv/lib/python2.7/site-packages/botocore/parsers.py", line 438, in _do_error_parse
root = self._parse_xml_string_to_dom(xml_contents)
File "/opt/code/localstack/.venv/lib/python2.7/site-packages/botocore/parsers.py", line 390, in _parse_xml_string_to_dom
"invalid XML received:\n%s" % (e, xml_string))
ResponseParserError: Unable to parse response (syntax error: line 1, column 54), invalid XML received:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>500 Internal Server Error</title>
<h1>Internal Server Error</h1>
<p>The server encountered an internal error and was unable to complete your request.  Either the server is overloaded or there is an error in the application.</p>

# Fixed code
def update_s3(method, path, data, headers, response=None, return_forward_info=False):
    if return_forward_info:
        modified_data = None

        # If this request contains streaming v4 authentication signatures, strip them from the message
        # Related isse: https://github.com/atlassian/localstack/issues/98
        # TODO we should evaluate whether to replace moto s3 with scality/S3:
        # https://github.com/scality/S3/issues/237
        if headers.get("x-amz-content-sha256") == "STREAMING-AWS4-HMAC-SHA256-PAYLOAD":
            modified_data = strip_chunk_signatures(data)

        # persist this API call to disk
        persistence.record("s3", method, path, data, headers)

        parsed = urlparse.urlparse(path)
        query = parsed.query
        path = parsed.path
        bucket = path.split("/")[1]
        query_map = urlparse.parse_qs(query)
        if method == "PUT" and (query == "notification" or "notification" in query_map):
            tree = ET.fromstring(data)
            queue_config = tree.find("{%s}QueueConfiguration" % XMLNS_S3)
            if len(queue_config):
                S3_NOTIFICATIONS[bucket] = {
                    "Id": get_xml_text(queue_config, "Id"),
                    "Event": get_xml_text(queue_config, "Event", ns=XMLNS_S3),
                    "Queue": get_xml_text(queue_config, "Queue", ns=XMLNS_S3),
                    "Topic": get_xml_text(queue_config, "Topic", ns=XMLNS_S3),
                    "CloudFunction": get_xml_text(
                        queue_config, "CloudFunction", ns=XMLNS_S3
                    ),
                }
        if query == "cors" or "cors" in query_map:
            if method == "GET":
                return get_cors(bucket)
            if method == "PUT":
                return set_cors(bucket, data)
            if method == "DELETE":
                return delete_cors(bucket)

        if modified_data:
            return Request(data=modified_data, headers=headers, method=method)
        return True

    # get subscribers and send bucket notifications
    if method in ("PUT", "DELETE") and "/" in path[1:]:
        parts = path[1:].split("/", 1)
        bucket_name = parts[0]
        object_path = "/%s" % parts[1]
        send_notifications(method, bucket_name, object_path)
    # append CORS headers to response
    if response:
        parsed = urlparse.urlparse(path)
        bucket_name = parsed.path.split("/")[0]
        append_cors_headers(
            bucket_name,
            request_method=method,
            request_headers=headers,
            response=response,
        )