britzl / aws-sdk-lua

Auto generated AWS SDK for Lua
Apache License 2.0
39 stars 10 forks source link

Better parsing xml #11

Closed scambra closed 4 years ago

scambra commented 4 years ago

xml.parse returns a table where each tag is a table with keys label and xarg, which is not easy to process. For example, rest_xml is not processing correctly parsed xml, and it passes data.Message as error message, but data.Message is nil.

I got this xml returned by AWS:

<?xml version="1.0" encoding="UTF-8"?>
<Error>
  <Code>SignatureDoesNotMatch</Code>
  <Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message> 
  <AWSAccessKeyId>...</AWSAccessKeyId>
  <StringToSign>...</StringToSign>
  <SignatureProvided>...</SignatureProvided>
  <StringToSignBytes>...</StringToSignBytes>
  <CanonicalRequest>PUT
/bucket/%7BKey%20%7D

host:s3.us-west-1.amazonaws.com
x-amz-content-sha256:...
x-amz-date:20200311T112559Z

host;x-amz-content-sha256;x-amz-date
...</CanonicalRequest>
  <CanonicalRequestBytes>...</CanonicalRequestBytes> 
 <RequestId>C1EA16669B3928D1</RequestId>
 <HostId>...</HostId>
</Error>

And it's parsed into this table:

{ '<?xml version="1.0" encoding="UTF-8"?>\n', { { 'SignatureDoesNotMatch', 
      label = 'Code',                                                                                                                                                                                               
      xarg = {}                                                                                                                                                                                                     
    }, {                                                                                                                                                                                                            
      [[The request signature we calculated does not match the signature you provided.                                                                                                                              
       Check your key and signing method.]],                                                                                                                                                                        
      label = 'Message',                                                                                                                                                                                            
      xarg = {}                                                                                                                                                                                                     
    }, { '...',                                                                                                                                                                                    
      label = 'AWSAccessKeyId',                                                                                                                                                                                     
      xarg = {}                                                                                                                                                                                                     
    }, {                                                                                                                                                                                                            
      [[...]],                                                                                                                                                 
      label = 'StringToSign',                                                                                                                                                                                       
      xarg = {}                                                                                                                                                                                                     
    }, { '...',                                                                                                                                        
      label = 'SignatureProvided',                                                                                                                                                                                  
      xarg = {}                                                                                                                                                                                                     
    }, {                                                                                                                                                                                                            
      [[...]],                                                                                                                                                                                                           
      label = 'StringToSignBytes',                                                                                                                                                                                  
      xarg = {}                                                                                                                                                                                                     
    }, {                                                                                                                                                                                                            
      [[PUT\n/bucket/%7BKey%20%7D\n\nhost:s3.us-west-1.amazonaws.c                                                                                                                              
      om\nx-amz-content-sha256:...b7852b855\nx-amz-date:20200311T112
      024Z\n\nhost;x-amz-content-sha256;x-amz-date\n...]],                                                                                                                                           
      label = 'CanonicalRequest',                                                                                                                                                                                   
      xarg = {}                                                                                                                                                                                                     
    }, {                                                                                                                                                                                                            
      [[...]], 
      label = 'CanonicalRequestBytes',
      xarg = {} 
    }, { 'CE53FBD4244582FD', 
      label = 'RequestId',
      xarg = {} 
    }, { 
      '...', 
      label = 'HostId',
      xarg = {} 
    }, 
    label = 'Error',
    xarg = {} 
  } }

So rest_xml methods should look for table containing 'Message' label, and return first element, because data.Message is nil.

I have replaced utils/xml.lua with https://github.com/manoelcampos/xml2lua, using xmlhandler.tree and returns this table:

{ 
  Error = {                                                                                                                                                                                                         
    AWSAccessKeyId = '...',                                                                                                                                                                        
    CanonicalRequest =                                                                                                                                                                                              
    [[PUT\n/bucket/%7BKey%20%7D\n\nhost:s3.us-west-1.amazonaws.c                                                                                                                                
    om\nx-amz-content-sha256:...                                                                                                                                
    b7852b855\nx-amz-date:20200311T121331Z\n\nhost;x-amz-content-sha256;x-amz-date\n                                                                                                                                
    ...]],                                                                                                                                             
    CanonicalRequestBytes = [[...]],                                                                                                                                                                                                          
    Code = 'SignatureDoesNotMatch',                                                                                                                                                                                 
    HostId = '...',                                                                                                                                 
    Message =                                                                                                                                                                                                       
    [[The request signature we calculated does not match the signature you provided.                                                                                                                                
     Check your key and signing method.]],                                                                                                                                                                          
    RequestId = '364792E4C01ACE78',                                                                                                                                                                                 
    SignatureProvided = '...',                                                                                                                                             
    StringToSign = [[...]],                                                                                                                                                   
    StringToSignBytes = [[...]]                                                                                                                                                                                                              
  }                                                                                                                                                                                                                 
}

I guess this structure is similar to structure returned by json handlers. And rest_xml may pass data.Error.Message.

I don't know what should be second parameter for callback, currently is data.__type which has no value in xml, and I don't know what value is in json handler.

Would you agree replacing current xml parser with xml2lua?

britzl commented 4 years ago

Yes, the XML parser wasn't really that great. I don't quite remember why I didn't search for a better one! It does make sense to replace the current xml parser. Please go ahead and provide a PR!

PS I appreciate the contributions! I'm happy to see that it has some use for others.

scambra commented 4 years ago

Should I copy files from xml2lua, or just use it and user would install xml2lua and aws-sdk-lua?

britzl commented 4 years ago

I would suggest that you copy xml2lua.lua and XmlParser.lua and add a note here: https://github.com/britzl/aws-sdk-lua#third-party-code-used