Search code examples
pythonamazon-web-servicesboto3amazon-sqsmd5

Boto3 SQS MD5OfMessageBody


How does a python/boto3 sqs client get the MD5OfMessageBody? Is this generated by the client or received by the server? For example:

{
  "response": {
    "MD5OfMessageBody": "d73e2ed0c3817b077da8f9571426fb23",
    "MessageId": "69c3463d-0f60-4a1a-94d7-fb2949953b35",
    "ResponseMetadata": {
      "HTTPHeaders": {
        "access-control-allow-headers": "authorization,cache-control,content-length,content-md5,content-type,etag,location,x-amz-acl,x-amz-content-sha256,x-amz-date,x-amz-request-id,x-amz-security-token,x-amz-tagging,x-amz-target,x-amz-user-agent,x-amz-version-id,x-amzn-requestid,x-localstack-target,amz-sdk-invocation-id,amz-sdk-request",
        "access-control-allow-methods": "HEAD,GET,PUT,POST,DELETE,OPTIONS,PATCH",
        "access-control-allow-origin": "*",
        "access-control-expose-headers": "etag,x-amz-version-id",
        "connection": "close",
        "content-length": "396",
        "content-type": "text/xml",
        "date": "Fri, 04 Aug 2023 11:26:40 GMT",
        "server": "hypercorn-h11"
      },
      "HTTPStatusCode": 200,
      "RequestId": "2834eec8-a1e4-4be3-b51f-127fe2e50205",
      "RetryAttempts": 0
    }
  }
}

I can't see anything in the Boto3 client that seems to do this, but there's some MD5 init checks, it sounds like this is an actual response from SQS?


Solution

  • This is part of the response, created by the service.

    The SQS SendMessage API creates the MD5OfMessageBody attribute, an MD5 digest of the non-URL-encoded message body string.

    You can use this attribute to verify that Amazon SQS received the message correctly. Amazon SQS URL-decodes the message before creating the MD5 digest.

    The below example demonstrates how to locally calculate the MD5 of a message and compare it with the MD5 returned by SQS:

    import boto3
    import hashlib
    
    # Create message and calculate MD5
    message = 'Hello World!'
    client_side_md5 = hashlib.md5(message.encode()).hexdigest()
    print(f'MD5 calculated locally: {client_side_md5}')
    
    
    # Send message to SQS and get server-side MD5 from response
    sqs = boto3.resource('sqs')
    queue = sqs.get_queue_by_name(QueueName='Fulfilment-Service-Queue')
    response = queue.send_message(MessageBody=message)
    service_side_md5 = response['MD5OfMessageBody']
    print(f'MD5 calculated by SQS:  {service_side_md5}')
    
    # Check if they match
    if client_side_md5 == service_side_md5:
        print(f'Transmission succeeded.')
    else:
        print(f'Error in transmission.')