AWS HTTP API - same request but different response in Python Requests vs Dart HTTPDifference between append vs. extend list methods in PythonHow do I manually fire HTTP POST requests with Firefox or Chrome?Direct Upload to S3 from the browser with Authorization Signature Ver 4How to generate Signature in AWS from JavaWS eb init missing equal-sign errorGetting “SignatureDoesNotMatch” error with delete Bucket Replication operation in Amazon s3Unexpected response status: 401 while accessing X-Amz-Target: Logs_20181106.GetLogEvents in AWSCall rest api to push data to kinesis using pythonAWS Signature is IncorrectPut Object requests with Object Lock parameters require AWS Signature Version 4

Am I breaking OOP practice with this architecture?

Is it acceptable for a professor to tell male students to not think that they are smarter than female students?

ssTTsSTtRrriinInnnnNNNIiinngg

Is it possible to create a QR code using text?

How to tell a function to use the default argument values?

Watching something be piped to a file live with tail

How dangerous is XSS?

One verb to replace 'be a member of' a club

How did the Super Star Destroyer Executor get destroyed exactly?

Venezuelan girlfriend wants to travel the USA to be with me. What is the process?

Why no variance term in Bayesian logistic regression?

Can I run a new neutral wire to repair a broken circuit?

Ambiguity in the definition of entropy

Why was the shrinking from 8″ made only to 5.25″ and not smaller (4″ or less)?

A friend helped me with a presentation – plagiarism or not?

How can saying a song's name be a copyright violation?

Can we compute the area of a quadrilateral with one right angle when we only know the lengths of any three sides?

Can a virus destroy the BIOS of a modern computer?

What does “the session was packed” mean in this context?

Is the myth that if you can play one instrument, you can learn another instrument with ease true?

How much of data wrangling is a data scientist's job?

What does the expression "A Mann!" means

How would I stat a creature to be immune to everything but the Magic Missile spell? (just for fun)

What is a romance in Latin?



AWS HTTP API - same request but different response in Python Requests vs Dart HTTP


Difference between append vs. extend list methods in PythonHow do I manually fire HTTP POST requests with Firefox or Chrome?Direct Upload to S3 from the browser with Authorization Signature Ver 4How to generate Signature in AWS from JavaWS eb init missing equal-sign errorGetting “SignatureDoesNotMatch” error with delete Bucket Replication operation in Amazon s3Unexpected response status: 401 while accessing X-Amz-Target: Logs_20181106.GetLogEvents in AWSCall rest api to push data to kinesis using pythonAWS Signature is IncorrectPut Object requests with Object Lock parameters require AWS Signature Version 4













3















I am trying to use AWS DynamoDB in a Flutter app, and given the lack of an official AWS SDK for Dart I am forced to use the low level HTTP REST API.



The method for signing an AWS HTTP request is quite tedious, but using an AWS supplied sample as a guide, I was able to convert the Python to Dart pretty much line-for-line relatively easily. The end result was both sets of code producing the same auth signatures.



My issue came when I actually went to sent the request. The Python works as expected but sending a POST with Dart's HTTP package gives the error




The request signature we calculated does not match the signature you
provided. Check your AWS Secret Access Key and signing method. Consult
the service documentation for details.




I'll spare you the actual code for generating the auth signature, as the issue can be replicated simply by sending the same request hard-coded. See the Python and Dart code below.



Note: A valid response will return




Signature expired: 20190307T214900Z is now earlier than
20190307T215809Z (20190307T221309Z - 15 min.)




as the request signature uses current date and is only valid for 15 mins.



*****PYTHON CODE*****



import requests

headers = 'Content-Type':'application/json',
'X-Amz-Date':'20190307T214900Z',
'X-Amz-Target':'DynamoDB_20120810.GetItem',
'Authorization':'AWS4-HMAC-SHA256 Credential=AKIAJFZWA7QQAQT474EQ/20190307/ap-southeast-2/dynamodb/aws4_request, SignedHeaders=content-type;host;x-amz-date;x-amz-target, Signature=297c5a03c59db6da45bfe2fda6017f89a0a1b2ab6da2bb6e0d838ca40be84320'

endpoint = 'https://dynamodb.ap-southeast-2.amazonaws.com/'
request_parameters = '"TableName": "player-exports","Key": "exportId": "S": "HG1T"'

r = requests.post(endpoint, data=request_parameters, headers=headers)

print('Response status: %dn' % r.status_code)
print('Response body: %sn' % r.text)


*****DART CODE*****



import 'package:http/http.dart' as http;

void main(List<String> arguments) async

var headers = 'Content-Type':'application/json',
'X-Amz-Date':'20190307T214900Z',
'X-Amz-Target':'DynamoDB_20120810.GetItem',
'Authorization':'AWS4-HMAC-SHA256 Credential=AKIAJFZWA7QQAQT474EQ/20190307/ap-southeast-2/dynamodb/aws4_request, SignedHeaders=content-type;host;x-amz-date;x-amz-target, Signature=297c5a03c59db6da45bfe2fda6017f89a0a1b2ab6da2bb6e0d838ca40be84320';

var endpoint = 'https://dynamodb.ap-southeast-2.amazonaws.com/';
var request_parameters = '"TableName": "player-exports","Key": "exportId": "S": "HG1T"';

http.post(endpoint, body: request_parameters, headers: headers).then((response)
print("Response status: $response.statusCode");
print("Response body: $response.body");
);



The endpoint, headers and body are literally copy and pasted between the two sets of code.



Is there some nuance to how Dart HTTP works that I am missing here? Is there some map/string/json conversion of the headers or request_paramaters happening?



One thing I did note is that in the AWS provided example it states




For DynamoDB, the request can include any headers, but MUST include
"host", "x-amz-date", "x-amz-target", "content-type", and
"Authorization". Except for the authorization header, the headers must
be included in the canonical_headers and signed_headers values, as
noted earlier. Order here is not significant. Python note: The 'host'
header is added automatically by the Python 'requests' library.




But



a) When I add 'Host':'dynamodb.ap-southeast-2.amazonaws.com' to the headers in the Dart code I get the same result



and



b) If I look at r.request.headers after the Python requests returns, I can see that it has added a few new headers (Content-Length etc) automatically, but "Host" isn't one of them.



Any ideas why the seemingly same HTTP request works for Python Requests but not Dart HTTP?










share|improve this question


























    3















    I am trying to use AWS DynamoDB in a Flutter app, and given the lack of an official AWS SDK for Dart I am forced to use the low level HTTP REST API.



    The method for signing an AWS HTTP request is quite tedious, but using an AWS supplied sample as a guide, I was able to convert the Python to Dart pretty much line-for-line relatively easily. The end result was both sets of code producing the same auth signatures.



    My issue came when I actually went to sent the request. The Python works as expected but sending a POST with Dart's HTTP package gives the error




    The request signature we calculated does not match the signature you
    provided. Check your AWS Secret Access Key and signing method. Consult
    the service documentation for details.




    I'll spare you the actual code for generating the auth signature, as the issue can be replicated simply by sending the same request hard-coded. See the Python and Dart code below.



    Note: A valid response will return




    Signature expired: 20190307T214900Z is now earlier than
    20190307T215809Z (20190307T221309Z - 15 min.)




    as the request signature uses current date and is only valid for 15 mins.



    *****PYTHON CODE*****



    import requests

    headers = 'Content-Type':'application/json',
    'X-Amz-Date':'20190307T214900Z',
    'X-Amz-Target':'DynamoDB_20120810.GetItem',
    'Authorization':'AWS4-HMAC-SHA256 Credential=AKIAJFZWA7QQAQT474EQ/20190307/ap-southeast-2/dynamodb/aws4_request, SignedHeaders=content-type;host;x-amz-date;x-amz-target, Signature=297c5a03c59db6da45bfe2fda6017f89a0a1b2ab6da2bb6e0d838ca40be84320'

    endpoint = 'https://dynamodb.ap-southeast-2.amazonaws.com/'
    request_parameters = '"TableName": "player-exports","Key": "exportId": "S": "HG1T"'

    r = requests.post(endpoint, data=request_parameters, headers=headers)

    print('Response status: %dn' % r.status_code)
    print('Response body: %sn' % r.text)


    *****DART CODE*****



    import 'package:http/http.dart' as http;

    void main(List<String> arguments) async

    var headers = 'Content-Type':'application/json',
    'X-Amz-Date':'20190307T214900Z',
    'X-Amz-Target':'DynamoDB_20120810.GetItem',
    'Authorization':'AWS4-HMAC-SHA256 Credential=AKIAJFZWA7QQAQT474EQ/20190307/ap-southeast-2/dynamodb/aws4_request, SignedHeaders=content-type;host;x-amz-date;x-amz-target, Signature=297c5a03c59db6da45bfe2fda6017f89a0a1b2ab6da2bb6e0d838ca40be84320';

    var endpoint = 'https://dynamodb.ap-southeast-2.amazonaws.com/';
    var request_parameters = '"TableName": "player-exports","Key": "exportId": "S": "HG1T"';

    http.post(endpoint, body: request_parameters, headers: headers).then((response)
    print("Response status: $response.statusCode");
    print("Response body: $response.body");
    );



    The endpoint, headers and body are literally copy and pasted between the two sets of code.



    Is there some nuance to how Dart HTTP works that I am missing here? Is there some map/string/json conversion of the headers or request_paramaters happening?



    One thing I did note is that in the AWS provided example it states




    For DynamoDB, the request can include any headers, but MUST include
    "host", "x-amz-date", "x-amz-target", "content-type", and
    "Authorization". Except for the authorization header, the headers must
    be included in the canonical_headers and signed_headers values, as
    noted earlier. Order here is not significant. Python note: The 'host'
    header is added automatically by the Python 'requests' library.




    But



    a) When I add 'Host':'dynamodb.ap-southeast-2.amazonaws.com' to the headers in the Dart code I get the same result



    and



    b) If I look at r.request.headers after the Python requests returns, I can see that it has added a few new headers (Content-Length etc) automatically, but "Host" isn't one of them.



    Any ideas why the seemingly same HTTP request works for Python Requests but not Dart HTTP?










    share|improve this question
























      3












      3








      3








      I am trying to use AWS DynamoDB in a Flutter app, and given the lack of an official AWS SDK for Dart I am forced to use the low level HTTP REST API.



      The method for signing an AWS HTTP request is quite tedious, but using an AWS supplied sample as a guide, I was able to convert the Python to Dart pretty much line-for-line relatively easily. The end result was both sets of code producing the same auth signatures.



      My issue came when I actually went to sent the request. The Python works as expected but sending a POST with Dart's HTTP package gives the error




      The request signature we calculated does not match the signature you
      provided. Check your AWS Secret Access Key and signing method. Consult
      the service documentation for details.




      I'll spare you the actual code for generating the auth signature, as the issue can be replicated simply by sending the same request hard-coded. See the Python and Dart code below.



      Note: A valid response will return




      Signature expired: 20190307T214900Z is now earlier than
      20190307T215809Z (20190307T221309Z - 15 min.)




      as the request signature uses current date and is only valid for 15 mins.



      *****PYTHON CODE*****



      import requests

      headers = 'Content-Type':'application/json',
      'X-Amz-Date':'20190307T214900Z',
      'X-Amz-Target':'DynamoDB_20120810.GetItem',
      'Authorization':'AWS4-HMAC-SHA256 Credential=AKIAJFZWA7QQAQT474EQ/20190307/ap-southeast-2/dynamodb/aws4_request, SignedHeaders=content-type;host;x-amz-date;x-amz-target, Signature=297c5a03c59db6da45bfe2fda6017f89a0a1b2ab6da2bb6e0d838ca40be84320'

      endpoint = 'https://dynamodb.ap-southeast-2.amazonaws.com/'
      request_parameters = '"TableName": "player-exports","Key": "exportId": "S": "HG1T"'

      r = requests.post(endpoint, data=request_parameters, headers=headers)

      print('Response status: %dn' % r.status_code)
      print('Response body: %sn' % r.text)


      *****DART CODE*****



      import 'package:http/http.dart' as http;

      void main(List<String> arguments) async

      var headers = 'Content-Type':'application/json',
      'X-Amz-Date':'20190307T214900Z',
      'X-Amz-Target':'DynamoDB_20120810.GetItem',
      'Authorization':'AWS4-HMAC-SHA256 Credential=AKIAJFZWA7QQAQT474EQ/20190307/ap-southeast-2/dynamodb/aws4_request, SignedHeaders=content-type;host;x-amz-date;x-amz-target, Signature=297c5a03c59db6da45bfe2fda6017f89a0a1b2ab6da2bb6e0d838ca40be84320';

      var endpoint = 'https://dynamodb.ap-southeast-2.amazonaws.com/';
      var request_parameters = '"TableName": "player-exports","Key": "exportId": "S": "HG1T"';

      http.post(endpoint, body: request_parameters, headers: headers).then((response)
      print("Response status: $response.statusCode");
      print("Response body: $response.body");
      );



      The endpoint, headers and body are literally copy and pasted between the two sets of code.



      Is there some nuance to how Dart HTTP works that I am missing here? Is there some map/string/json conversion of the headers or request_paramaters happening?



      One thing I did note is that in the AWS provided example it states




      For DynamoDB, the request can include any headers, but MUST include
      "host", "x-amz-date", "x-amz-target", "content-type", and
      "Authorization". Except for the authorization header, the headers must
      be included in the canonical_headers and signed_headers values, as
      noted earlier. Order here is not significant. Python note: The 'host'
      header is added automatically by the Python 'requests' library.




      But



      a) When I add 'Host':'dynamodb.ap-southeast-2.amazonaws.com' to the headers in the Dart code I get the same result



      and



      b) If I look at r.request.headers after the Python requests returns, I can see that it has added a few new headers (Content-Length etc) automatically, but "Host" isn't one of them.



      Any ideas why the seemingly same HTTP request works for Python Requests but not Dart HTTP?










      share|improve this question














      I am trying to use AWS DynamoDB in a Flutter app, and given the lack of an official AWS SDK for Dart I am forced to use the low level HTTP REST API.



      The method for signing an AWS HTTP request is quite tedious, but using an AWS supplied sample as a guide, I was able to convert the Python to Dart pretty much line-for-line relatively easily. The end result was both sets of code producing the same auth signatures.



      My issue came when I actually went to sent the request. The Python works as expected but sending a POST with Dart's HTTP package gives the error




      The request signature we calculated does not match the signature you
      provided. Check your AWS Secret Access Key and signing method. Consult
      the service documentation for details.




      I'll spare you the actual code for generating the auth signature, as the issue can be replicated simply by sending the same request hard-coded. See the Python and Dart code below.



      Note: A valid response will return




      Signature expired: 20190307T214900Z is now earlier than
      20190307T215809Z (20190307T221309Z - 15 min.)




      as the request signature uses current date and is only valid for 15 mins.



      *****PYTHON CODE*****



      import requests

      headers = 'Content-Type':'application/json',
      'X-Amz-Date':'20190307T214900Z',
      'X-Amz-Target':'DynamoDB_20120810.GetItem',
      'Authorization':'AWS4-HMAC-SHA256 Credential=AKIAJFZWA7QQAQT474EQ/20190307/ap-southeast-2/dynamodb/aws4_request, SignedHeaders=content-type;host;x-amz-date;x-amz-target, Signature=297c5a03c59db6da45bfe2fda6017f89a0a1b2ab6da2bb6e0d838ca40be84320'

      endpoint = 'https://dynamodb.ap-southeast-2.amazonaws.com/'
      request_parameters = '"TableName": "player-exports","Key": "exportId": "S": "HG1T"'

      r = requests.post(endpoint, data=request_parameters, headers=headers)

      print('Response status: %dn' % r.status_code)
      print('Response body: %sn' % r.text)


      *****DART CODE*****



      import 'package:http/http.dart' as http;

      void main(List<String> arguments) async

      var headers = 'Content-Type':'application/json',
      'X-Amz-Date':'20190307T214900Z',
      'X-Amz-Target':'DynamoDB_20120810.GetItem',
      'Authorization':'AWS4-HMAC-SHA256 Credential=AKIAJFZWA7QQAQT474EQ/20190307/ap-southeast-2/dynamodb/aws4_request, SignedHeaders=content-type;host;x-amz-date;x-amz-target, Signature=297c5a03c59db6da45bfe2fda6017f89a0a1b2ab6da2bb6e0d838ca40be84320';

      var endpoint = 'https://dynamodb.ap-southeast-2.amazonaws.com/';
      var request_parameters = '"TableName": "player-exports","Key": "exportId": "S": "HG1T"';

      http.post(endpoint, body: request_parameters, headers: headers).then((response)
      print("Response status: $response.statusCode");
      print("Response body: $response.body");
      );



      The endpoint, headers and body are literally copy and pasted between the two sets of code.



      Is there some nuance to how Dart HTTP works that I am missing here? Is there some map/string/json conversion of the headers or request_paramaters happening?



      One thing I did note is that in the AWS provided example it states




      For DynamoDB, the request can include any headers, but MUST include
      "host", "x-amz-date", "x-amz-target", "content-type", and
      "Authorization". Except for the authorization header, the headers must
      be included in the canonical_headers and signed_headers values, as
      noted earlier. Order here is not significant. Python note: The 'host'
      header is added automatically by the Python 'requests' library.




      But



      a) When I add 'Host':'dynamodb.ap-southeast-2.amazonaws.com' to the headers in the Dart code I get the same result



      and



      b) If I look at r.request.headers after the Python requests returns, I can see that it has added a few new headers (Content-Length etc) automatically, but "Host" isn't one of them.



      Any ideas why the seemingly same HTTP request works for Python Requests but not Dart HTTP?







      python amazon-web-services dart python-requests http-post






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Mar 7 at 22:38









      BGHBGH

      448




      448






















          1 Answer
          1






          active

          oldest

          votes


















          0














          Ok this is resolved now. My issue was in part a massive user-error. I was using a new IDE and when I generated the hardcoded example I provided I was actually still executing the previous file. Stupid, stupid, stupid.



          But...



          I was able to sort out the actual issue that caused me raise the question in the first place. I found that if you set the content type to "application/json" in the headers, the dart HTTP package automatically appends "; charset=utf-8". Because this value is part of the auth signature, when AWS encodes the values from the header to compare to the user-generated signature, they don't match.



          The fix is simply to ensure that when you are setting the header content-type, make sure that you manually set it to "application/json; charset=utf-8" and not "application/json".



          Found a bit more discussion about this "bug" after the fact here.






          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "1"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55053940%2faws-http-api-same-request-but-different-response-in-python-requests-vs-dart-ht%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0














            Ok this is resolved now. My issue was in part a massive user-error. I was using a new IDE and when I generated the hardcoded example I provided I was actually still executing the previous file. Stupid, stupid, stupid.



            But...



            I was able to sort out the actual issue that caused me raise the question in the first place. I found that if you set the content type to "application/json" in the headers, the dart HTTP package automatically appends "; charset=utf-8". Because this value is part of the auth signature, when AWS encodes the values from the header to compare to the user-generated signature, they don't match.



            The fix is simply to ensure that when you are setting the header content-type, make sure that you manually set it to "application/json; charset=utf-8" and not "application/json".



            Found a bit more discussion about this "bug" after the fact here.






            share|improve this answer



























              0














              Ok this is resolved now. My issue was in part a massive user-error. I was using a new IDE and when I generated the hardcoded example I provided I was actually still executing the previous file. Stupid, stupid, stupid.



              But...



              I was able to sort out the actual issue that caused me raise the question in the first place. I found that if you set the content type to "application/json" in the headers, the dart HTTP package automatically appends "; charset=utf-8". Because this value is part of the auth signature, when AWS encodes the values from the header to compare to the user-generated signature, they don't match.



              The fix is simply to ensure that when you are setting the header content-type, make sure that you manually set it to "application/json; charset=utf-8" and not "application/json".



              Found a bit more discussion about this "bug" after the fact here.






              share|improve this answer

























                0












                0








                0







                Ok this is resolved now. My issue was in part a massive user-error. I was using a new IDE and when I generated the hardcoded example I provided I was actually still executing the previous file. Stupid, stupid, stupid.



                But...



                I was able to sort out the actual issue that caused me raise the question in the first place. I found that if you set the content type to "application/json" in the headers, the dart HTTP package automatically appends "; charset=utf-8". Because this value is part of the auth signature, when AWS encodes the values from the header to compare to the user-generated signature, they don't match.



                The fix is simply to ensure that when you are setting the header content-type, make sure that you manually set it to "application/json; charset=utf-8" and not "application/json".



                Found a bit more discussion about this "bug" after the fact here.






                share|improve this answer













                Ok this is resolved now. My issue was in part a massive user-error. I was using a new IDE and when I generated the hardcoded example I provided I was actually still executing the previous file. Stupid, stupid, stupid.



                But...



                I was able to sort out the actual issue that caused me raise the question in the first place. I found that if you set the content type to "application/json" in the headers, the dart HTTP package automatically appends "; charset=utf-8". Because this value is part of the auth signature, when AWS encodes the values from the header to compare to the user-generated signature, they don't match.



                The fix is simply to ensure that when you are setting the header content-type, make sure that you manually set it to "application/json; charset=utf-8" and not "application/json".



                Found a bit more discussion about this "bug" after the fact here.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Mar 11 at 23:41









                BGHBGH

                448




                448





























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55053940%2faws-http-api-same-request-but-different-response-in-python-requests-vs-dart-ht%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    1928 у кіно

                    Захаров Федір Захарович

                    Ель Греко