SlideShare uma empresa Scribd logo
1 de 27
Weekly Code Drop:
  Connecting to Amazon S3
        Part 1 of 3
   Formulating the S3 Request
     Jason Hayes Christensen
         jasonc411.com




July 11 Weekly Code Drop
●   Amazon S3 is a cloud-storage technology from
     Amazon Web Services, LLC.
●   Cloud storage can help overcome the storage
     limitations of mobile architectures.
●   There is a cost to using S3, so the applications
     that use S3 to augment storage should have
     a business model that accounts for these
     costs.
●   Pricing Information:
         http://aws.amazon.com/s3/#pricing


      July 11 Weekly Code Drop
●   Detailed S3 documentation can be accessed
     at:
    http://developer.amazonwebservices.com/connect/entry.jspaexternalID=123&categoryID=48

●   We are not using any of the existing S3 libs.
●   This is a 4-part set of presentations that show
     how to develop for S3 from the ground up.
●   The focus of this particular presentation is how
     to augment the headers of the HTTP REST
     request for authentication in virtual hosted
     mode.
          –   Using NSURL and NSMutableURLRequest.


         July 11 Weekly Code Drop
●   First, we will be using the ehmacauth
      functionality from the July 4 code drop.
       –   Note that a memory leak was fixed and the
            download site is updated.
●   We create the “StringToSign” in this example.
●   The “StringToSign” is defined on page 13 of the
     S3 Developers Guide 20060301 as:
             StringToSign = HTTP-Verb +
             "n" +
              Content-MD5 + "n" +
              Content-Type + "n" +
              Date + "n" +
              CanonicalizedAmzHeaders +
              CanonicalizedResource;



       July 11 Weekly Code Drop
●   Remember, we are using virtual hosted mode,
     this means that we address a bucket as:
          <bucketName>.s3.amazonaws.com
●   The “resource” is the file name, it is specified
     as the path on the server when using virtual
     hosted mode:
    mybucket.s3.amazonaws.com/myresource.wav

●   This model is nice because we do not have to
     determine what part of the file path is the
     bucket vs. the resource.


       July 11 Weekly Code Drop
●   Let's define a new class that will modify the
     headers of the outbound URL Request.
●   This class adds S3 headers to an existing
     NSMutableURLRequest.
●   This class is named S3HTTPRequestHeaders.
●   The one initializer for this class is:
- (id)initForBucket:(NSString*) bucket

 andResource:(NSString*) resource;

●   To avoid any specific coupling, the bucket and
      resource names are broken out.

       July 11 Weekly Code Drop
●   This initializer simply sets up the member
     variables, including the start of the auth token:

- (id) initForBucket:(NSString*) bucket

 andResource:(NSString*) resource

{

    _bucket = bucket;

    _resource = resource;

    _authToken = [NSString stringWithFormat:@"AWS %@:", kPublicKey];

    _amzDate = NO;

    return self;

}




          July 11 Weekly Code Drop
●   Dates are key to the request process.
●   First of all, a request's date can differ by no
      more than 15 minutes from the time it is
      received by the Amazon servers.
●   Second, if the date in the StringToSign is
     different than the date Amazon receives in
     the request header it will not authenticate.
●   Watch for issues that affect the date header;
     for instance some proxies can modify Date
     header slightly.
       –   In this case use X-Amz-Date header.


       July 11 Weekly Code Drop
●   Date header formatting must meet the RFC
         1123 standard( http://ietf.org/rfc/rfc1123.txt )
    ●   To do this we use NSDateFormatter.
             –   This allows us to both read and stream string
                  representations of the Date header.
- (NSString*)currentRFC1123DateTime:(NSDate*) date

{

    NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init]     autorelease];

        [dateFormatter setFormatterBehavior: NSDateFormatterBehavior10_4];

        [dateFormatter setDateFormat:@"EEE, dd MMM yyyy HH:mm:ss ZZ"];

        [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];

    return [dateFormatter stringFromDate:date];

}




             July 11 Weekly Code Drop
●   Modifying a header is simple, here we update
         the HTTP Date header by calling:
               –    NSMutableURLRequest setValue:
                     forHTTPHeaderField:.
- (void) appendDateHeader:(NSMutableURLRequest*) request

                        date:(NSDate*) date

                   useAmzDate:(Boolean) amzDate;


{
[request setValue:[self currentRFC1123DateTime:date] forHTTPHeaderField:@"Date"];


if(amzDate){

[request setValue:[self currentRFC1123DateTime:date] forHTTPHeaderField:@"X-Amz-Date"];


_amzDate = amzDate;}


}




               July 11 Weekly Code Drop
●   Since we are using virtualized host mode, we
          have to modify the host header, this again is
          very simple using the NSHttpURLRequest
          setValue:forHTTPHeaderField:.
- (void) appendHostHeader:(NSMutableURLRequest*) request

{

[request setValue:[NSString stringWithFormat:@"%@.%@", _bucket, kHost]

             forHTTPHeaderField:@"Host"];

}




          July 11 Weekly Code Drop
●   Next we will add the canonicalizedResource.
 ●   Directly from page 14 of the developers guide:
1 Start with the empty string ("").
2 If the request specif es a bucket using the HTTP Host header (virtual hosted-
                      i
    style), append the bucket name preceded by a "/" (e.g., "/bucketname").
    For path-style requests and requests that don't address a bucket, do
    nothing. For more information on virtual hosted-style requests, see Virtual
    Hosting of Buckets (p. 25).
3 Append the path part of the un-decoded HTTP Request-URI, up-to but not
   including the query string.
4 If the request addresses a sub-resource, like ?location, ?acl, or ?
    torrent, append the sub-resource including question mark.




        July 11 Weekly Code Drop
●    Because we break out the resource and bucket
          separately in the initializer for
          S3HTTPRequestHeaders, this ends up being
          very simple.
- (NSString*)canonicalizedResource:(NSURLRequest*) request

{

        NSMutableString* canonResource = [[[NSMutableString alloc] initWithString:@"/"]
        autorelease];

        if(_bucket != nil)

          [canonResource appendFormat:@"%@", _bucket];

        if(_resource != nil)

          [canonResource appendFormat:@"%@", _resource];

        return canonResource;

}




             July 11 Weekly Code Drop
●   The most obscure part of the “StringToSign” for
     new devs are the canonicalizedAmzHeaders.
●   These headers all have the prefix X-Amz-
●   They are used to communicate application
     specific information in the REST request.
●   One caveat: multiple headers of the same
     name are not supported by
     NSHTTPUrlRequest.
●   Therefore our demo code just concatenates
     the headers after sorting them.


       July 11 Weekly Code Drop
●   Directly from pp 14-15 of the Developers
     Guide:
1 Convert each HTTP header name to lower-case. For example, 'X-Amz-Date'
   becomes 'x- amz-date'.
2 Sort the collection of headers lexicographically by header name.
3 Combine header f elds with the same name into one "header-name:comma-
                  i
   separated-value-list" pair as prescribed by RFC 2616, section 4.2, without
   any white-space between values. For example, the two metadata headers
   'x-amz-meta-username: fred' and 'x- amz-meta-username:
   barney' would be combined into the single header 'x-amz-meta-
   username: fred,barney'.
4 "Un-fold" long headers that span multiple lines (as allowed by RFC 2616,
   section 4.2) by replacing the folding white-space (including new-line) by a
   single space.




        July 11 Weekly Code Drop
●   CanonicalizedAmzHeaders Process Cont.
5 Trim any white-space around the colon in the header. For example, the
   header 'x-amz- meta-username: fred,barney' would become 'x-
   amz-meta-username:fred,barney'
6 Finally, append a new-line (U+000A) to each canonicalized header in the
   resulting list. Construct the CanonicalizedResource element by
   concatenating all headers in this list into a single string


●   Since our utility class NSHTTPUrlRequest
      does not support multiple entries of the same
      header, and removes whitespace, we have
      simplified the code for the demo.


        July 11 Weekly Code Drop
●    First, we have to sort the headers
              –   to do this we grab the array of keys and sort
                   them using NSString's
                   caseInsensitiveCompare.
- (NSString*)canonicalizedAmzHeaders:(NSURLRequest*) request

{

        NSMutableString* ret = [[[NSMutableString alloc] init] autorelease];

        NSDictionary* dict = [request allHTTPHeaderFields];

        NSArray* keys = [[dict allKeys]
        sortedArrayUsingSelector:@selector(caseInsensitiveCompare:) ];




             July 11 Weekly Code Drop
●    Next we iterate over the array of keys looking
          for keys with the header X-Amz
    ●    When we find one we append it and its value to
          the return string.
for(id header in keys)

{

        NSString* str = [(NSString*)header lowercaseString];

        if([str hasPrefix:@"x-amz"])

        [ret appendFormat:@"%@:%@n", str, (NSString*)[dict objectForKey:header]];

}

return ret;

}




              July 11 Weekly Code Drop
●   Finally we have all the information we need for
      the StringToSign so we add the authorization
      header.
●   We sign the string with our private key, then
     pass the public key, and the signature to S3
     in the Authorization header.
●   The string has the format:
    “AWS <PublicKey>:<Signature>”




      July 11 Weekly Code Drop
●     OK, a final look at setting up the StringToSign
 ●     Let's setup a mutable string and grab the
        standard headers that make up the string.
NSMutableString* s2s = [[[NSMutableString alloc]

                    initWithFormat:@"%@n", [request HTTPMethod]] autorelease];

NSString* contentMD5 =    [request valueForHTTPHeaderField:@"content-md5"];

NSString* contentType = [request valueForHTTPHeaderField:@"content-type"];

NSString* date = [request valueForHTTPHeaderField:@"date"];

//We can't append null strings, so we do the following check on each header

if(contentMD5 != nil)

     [s2s appendFormat:@"%@n", contentMD5];

else

     [s2s appendString:@"n"];




          July 11 Weekly Code Drop
●   Next we append the canonicalized headers,
         push out a debug string, and return the
         string.
[s2s appendString:[self canonicalizedAmzHeaders:request]];

[s2s appendString:[self canonicalizedResource:request]];

NSLog(@"************ String to Sign follows *******************");

NSLog(s2s);

NSLog(@"************ End String To Sign ***********************");



return s2s;

}




          July 11 Weekly Code Drop
●   Finally we sign the string, this should look
          familiar from last weeks code drop.
- (void) appendAuthorizationHeader:(NSMutableURLRequest*) request

{

NSString* stringToSign = [self createStringToSign:request];

NSString* authToken = [NSString stringWithFormat:@"%@:%@",

            _authToken,

            [EncodedHMACToken createEncodedHMACToken:kPrivateKey

                                             message:stringToSign

                                       signatureType:kSHA1

                                              forURI:NO]];

    [request setValue:authToken

          forHTTPHeaderField:@"Authorization"];

}




           July 11 Weekly Code Drop
●   At this point, we should be good to go. The
     NSMutableURLRequest has the appropriate
     headers to make the invocation.
●   From this point, to make a request, you will
      have to setup your own S3 Account.
●   See page 9 of the Getting Started Guide for S3
     accessible at:
http://developer.amazonwebservices.com/connect/entry.jspaexternalID=123&categoryID=48




        July 11 Weekly Code Drop
●   In summary
      –   Unit test are included
      –   To this point, we are able to use the outlined
            tests in the developers guide on pp. 14-19
      –   The first three lines of each test are just staged
           for right now, in the actual requests they will
           be more formalized.
      –   As always, code is accessible at
           jasonc411.com's downloads pages.
      –   July 18 WCD should go out mid-week.



      July 11 Weekly Code Drop
●   Upcoming Code Drops:
      –   Part 2 Processing a Response
      –   Part 3 Creating the libS3 Functional interface
      –   Part 4 Using S3 with the iAudioNotebook.
                     Hope all is well,
                         jason h christensen (on Twitter: jasonc411)
                         founder
                         jasonc411.com
                         software architecture
                             technical research
                                 technical thought leadership




      July 11 Weekly Code Drop
●   Signatures Slide 1 EHMACAUTH files
    SHA1(Base64Encoder.h)= 848aa02c301987ab116e5228e8437816191c68f8
●   SHA1(Base64Encoder.m)= b494db4979f5e001a954d9559e73175b3adfd426
●   SHA1(EncodedHMACToken.h)= a9709162247ded70311e69d5233dc8994cb511f1
●   SHA1(EncodedHMACToken.m)= 3bd9b592455920476eff5bb931dc4ac7cbf1e18f
●   SHA1(base64HMACTests-Info.plist)= 6b31f761a5a58d61c06282778fa005410bdbbe37
●   SHA1(base64HMACTests.h)= be22db6b5528ed65856568ce0e1658b3b12997dd
●   SHA1(base64HMACTests.m)= fd4b7dce4519ff11cd0942d8bb9075b8d96229c4
●   SHA1(ehmacauth_Prefix.pch)= 7c43d1c65c49c85da9a73643fe6032f2bbf95c2a
●   SHA1(ehmacauth.xcodeproj/project.pbxproj)= cd287838fcd106a55dddfa1477719acc0a798898




         July 11 Weekly Code Drop
●   Signatures Slide 2 S3HTTPRequestHeaders
      and Tests
    SHA1(S3HTTPRequestHeaders.h)= baaabcf47147758ef9b9bc51de9fef650a5c5767
●   SHA1(S3HTTPRequestHeaders.m)= ce5e49cac2d19e430cc9b49373aa6129c121c093
●   SHA1(S3Tests-Info.plist)= 6b31f761a5a58d61c06282778fa005410bdbbe37
●   SHA1(S3_Prefix.pch)= 7c43d1c65c49c85da9a73643fe6032f2bbf95c2a
●   SHA1(libS3RequestTests.h)= f52cd50b70cca323549f1f0f148d94b3934a3849
●   SHA1(libS3RequestTests.m)= aa2e08ce3e7f1d700360bad587e612e17b6e890d
●   SHA1(S3.xcodeproj/project.pbxproj)= ff7f3b41e08ddd5dd3405e74887112ce5c072616




         July 11 Weekly Code Drop

Mais conteúdo relacionado

Mais procurados

ETL With Cassandra Streaming Bulk Loading
ETL With Cassandra Streaming Bulk LoadingETL With Cassandra Streaming Bulk Loading
ETL With Cassandra Streaming Bulk Loadingalex_araujo
 
Rank Your Results with PostgreSQL Full Text Search (from PGConf2015)
Rank Your Results with PostgreSQL Full Text Search (from PGConf2015)Rank Your Results with PostgreSQL Full Text Search (from PGConf2015)
Rank Your Results with PostgreSQL Full Text Search (from PGConf2015)Jamey Hanson
 
Новые возможности полнотекстового поиска в PostgreSQL / Олег Бартунов (Postgr...
Новые возможности полнотекстового поиска в PostgreSQL / Олег Бартунов (Postgr...Новые возможности полнотекстового поиска в PostgreSQL / Олег Бартунов (Postgr...
Новые возможности полнотекстового поиска в PostgreSQL / Олег Бартунов (Postgr...Ontico
 
MongoDB - Aggregation Pipeline
MongoDB - Aggregation PipelineMongoDB - Aggregation Pipeline
MongoDB - Aggregation PipelineJason Terpko
 
Introduction to Redis
Introduction to RedisIntroduction to Redis
Introduction to RedisKnoldus Inc.
 
Pgbr 2013 postgres on aws
Pgbr 2013   postgres on awsPgbr 2013   postgres on aws
Pgbr 2013 postgres on awsEmanuel Calvo
 
Sharding in MongoDB 4.2 #what_is_new
 Sharding in MongoDB 4.2 #what_is_new Sharding in MongoDB 4.2 #what_is_new
Sharding in MongoDB 4.2 #what_is_newAntonios Giannopoulos
 
Cassandra Community Webinar: Back to Basics with CQL3
Cassandra Community Webinar: Back to Basics with CQL3Cassandra Community Webinar: Back to Basics with CQL3
Cassandra Community Webinar: Back to Basics with CQL3DataStax
 
Simple search with elastic search
Simple search with elastic searchSimple search with elastic search
Simple search with elastic searchmarkstory
 
NoSQL and SQL Anti Patterns
NoSQL and SQL Anti PatternsNoSQL and SQL Anti Patterns
NoSQL and SQL Anti PatternsGleicon Moraes
 
Back to Basics, webinar 2: La tua prima applicazione MongoDB
Back to Basics, webinar 2: La tua prima applicazione MongoDBBack to Basics, webinar 2: La tua prima applicazione MongoDB
Back to Basics, webinar 2: La tua prima applicazione MongoDBMongoDB
 
MongoDB's New Aggregation framework
MongoDB's New Aggregation frameworkMongoDB's New Aggregation framework
MongoDB's New Aggregation frameworkChris Westin
 
MongoDB Quick Reference Card
MongoDB Quick Reference CardMongoDB Quick Reference Card
MongoDB Quick Reference CardJeremy Taylor
 
Elasticsearch 설치 및 기본 활용
Elasticsearch 설치 및 기본 활용Elasticsearch 설치 및 기본 활용
Elasticsearch 설치 및 기본 활용종민 김
 

Mais procurados (20)

ETL With Cassandra Streaming Bulk Loading
ETL With Cassandra Streaming Bulk LoadingETL With Cassandra Streaming Bulk Loading
ETL With Cassandra Streaming Bulk Loading
 
Full Text Search in PostgreSQL
Full Text Search in PostgreSQLFull Text Search in PostgreSQL
Full Text Search in PostgreSQL
 
Rank Your Results with PostgreSQL Full Text Search (from PGConf2015)
Rank Your Results with PostgreSQL Full Text Search (from PGConf2015)Rank Your Results with PostgreSQL Full Text Search (from PGConf2015)
Rank Your Results with PostgreSQL Full Text Search (from PGConf2015)
 
9.4json
9.4json9.4json
9.4json
 
Full Text Search In PostgreSQL
Full Text Search In PostgreSQLFull Text Search In PostgreSQL
Full Text Search In PostgreSQL
 
Новые возможности полнотекстового поиска в PostgreSQL / Олег Бартунов (Postgr...
Новые возможности полнотекстового поиска в PostgreSQL / Олег Бартунов (Postgr...Новые возможности полнотекстового поиска в PostgreSQL / Олег Бартунов (Postgr...
Новые возможности полнотекстового поиска в PostgreSQL / Олег Бартунов (Postgr...
 
MongoDB - Aggregation Pipeline
MongoDB - Aggregation PipelineMongoDB - Aggregation Pipeline
MongoDB - Aggregation Pipeline
 
Introduction to Redis
Introduction to RedisIntroduction to Redis
Introduction to Redis
 
Scala+data
Scala+dataScala+data
Scala+data
 
Sharded cluster tutorial
Sharded cluster tutorialSharded cluster tutorial
Sharded cluster tutorial
 
Pgbr 2013 postgres on aws
Pgbr 2013   postgres on awsPgbr 2013   postgres on aws
Pgbr 2013 postgres on aws
 
Sharding in MongoDB 4.2 #what_is_new
 Sharding in MongoDB 4.2 #what_is_new Sharding in MongoDB 4.2 #what_is_new
Sharding in MongoDB 4.2 #what_is_new
 
Cassandra Community Webinar: Back to Basics with CQL3
Cassandra Community Webinar: Back to Basics with CQL3Cassandra Community Webinar: Back to Basics with CQL3
Cassandra Community Webinar: Back to Basics with CQL3
 
Simple search with elastic search
Simple search with elastic searchSimple search with elastic search
Simple search with elastic search
 
NoSQL and SQL Anti Patterns
NoSQL and SQL Anti PatternsNoSQL and SQL Anti Patterns
NoSQL and SQL Anti Patterns
 
Back to Basics, webinar 2: La tua prima applicazione MongoDB
Back to Basics, webinar 2: La tua prima applicazione MongoDBBack to Basics, webinar 2: La tua prima applicazione MongoDB
Back to Basics, webinar 2: La tua prima applicazione MongoDB
 
MongoDB's New Aggregation framework
MongoDB's New Aggregation frameworkMongoDB's New Aggregation framework
MongoDB's New Aggregation framework
 
MongoDB Quick Reference Card
MongoDB Quick Reference CardMongoDB Quick Reference Card
MongoDB Quick Reference Card
 
MongoDB
MongoDBMongoDB
MongoDB
 
Elasticsearch 설치 및 기본 활용
Elasticsearch 설치 및 기본 활용Elasticsearch 설치 및 기본 활용
Elasticsearch 설치 및 기본 활용
 

Semelhante a Connecting to Amazon S3 Weekly Code Drop

Mongodb in-anger-boston-rb-2011
Mongodb in-anger-boston-rb-2011Mongodb in-anger-boston-rb-2011
Mongodb in-anger-boston-rb-2011bostonrb
 
Scylla Summit 2016: Analytics Show Time - Spark and Presto Powered by Scylla
Scylla Summit 2016: Analytics Show Time - Spark and Presto Powered by ScyllaScylla Summit 2016: Analytics Show Time - Spark and Presto Powered by Scylla
Scylla Summit 2016: Analytics Show Time - Spark and Presto Powered by ScyllaScyllaDB
 
Spark Summit EU talk by Ross Lawley
Spark Summit EU talk by Ross LawleySpark Summit EU talk by Ross Lawley
Spark Summit EU talk by Ross LawleySpark Summit
 
How To Connect Spark To Your Own Datasource
How To Connect Spark To Your Own DatasourceHow To Connect Spark To Your Own Datasource
How To Connect Spark To Your Own DatasourceMongoDB
 
Introduction to pygments
Introduction to pygmentsIntroduction to pygments
Introduction to pygmentsroskakori
 
06 response-headers
06 response-headers06 response-headers
06 response-headerssnopteck
 
Cassandra Java APIs Old and New – A Comparison
Cassandra Java APIs Old and New – A ComparisonCassandra Java APIs Old and New – A Comparison
Cassandra Java APIs Old and New – A Comparisonshsedghi
 
AWS Hadoop and PIG and overview
AWS Hadoop and PIG and overviewAWS Hadoop and PIG and overview
AWS Hadoop and PIG and overviewDan Morrill
 
Introduction to Apache Tajo: Data Warehouse for Big Data
Introduction to Apache Tajo: Data Warehouse for Big DataIntroduction to Apache Tajo: Data Warehouse for Big Data
Introduction to Apache Tajo: Data Warehouse for Big DataGruter
 
ASP.Net Presentation Part2
ASP.Net Presentation Part2ASP.Net Presentation Part2
ASP.Net Presentation Part2Neeraj Mathur
 
Pdf tech deep dive 42 paris
Pdf tech deep dive 42 parisPdf tech deep dive 42 paris
Pdf tech deep dive 42 parisLaure Vergeron
 
Elasticsearch And Ruby [RuPy2012]
Elasticsearch And Ruby [RuPy2012]Elasticsearch And Ruby [RuPy2012]
Elasticsearch And Ruby [RuPy2012]Karel Minarik
 
(BDT205) Your First Big Data Application On AWS
(BDT205) Your First Big Data Application On AWS(BDT205) Your First Big Data Application On AWS
(BDT205) Your First Big Data Application On AWSAmazon Web Services
 
Sqlxml vs xquery
Sqlxml vs xquerySqlxml vs xquery
Sqlxml vs xqueryAmol Pujari
 
IQPC Canada XML 2001: How to Use XML Parsing to Enhance Electronic Communication
IQPC Canada XML 2001: How to Use XML Parsing to Enhance Electronic CommunicationIQPC Canada XML 2001: How to Use XML Parsing to Enhance Electronic Communication
IQPC Canada XML 2001: How to Use XML Parsing to Enhance Electronic CommunicationTed Leung
 
KubeCon EU 2016: Templatized Application Configuration on OpenShift and Kuber...
KubeCon EU 2016: Templatized Application Configuration on OpenShift and Kuber...KubeCon EU 2016: Templatized Application Configuration on OpenShift and Kuber...
KubeCon EU 2016: Templatized Application Configuration on OpenShift and Kuber...KubeAcademy
 

Semelhante a Connecting to Amazon S3 Weekly Code Drop (20)

Introduction to Amazon Athena
Introduction to Amazon AthenaIntroduction to Amazon Athena
Introduction to Amazon Athena
 
Mongodb in-anger-boston-rb-2011
Mongodb in-anger-boston-rb-2011Mongodb in-anger-boston-rb-2011
Mongodb in-anger-boston-rb-2011
 
AWS Java SDK @ scale
AWS Java SDK @ scaleAWS Java SDK @ scale
AWS Java SDK @ scale
 
Scylla Summit 2016: Analytics Show Time - Spark and Presto Powered by Scylla
Scylla Summit 2016: Analytics Show Time - Spark and Presto Powered by ScyllaScylla Summit 2016: Analytics Show Time - Spark and Presto Powered by Scylla
Scylla Summit 2016: Analytics Show Time - Spark and Presto Powered by Scylla
 
Spark Summit EU talk by Ross Lawley
Spark Summit EU talk by Ross LawleySpark Summit EU talk by Ross Lawley
Spark Summit EU talk by Ross Lawley
 
How To Connect Spark To Your Own Datasource
How To Connect Spark To Your Own DatasourceHow To Connect Spark To Your Own Datasource
How To Connect Spark To Your Own Datasource
 
Node js crash course session 5
Node js crash course   session 5Node js crash course   session 5
Node js crash course session 5
 
Introduction to pygments
Introduction to pygmentsIntroduction to pygments
Introduction to pygments
 
06 response-headers
06 response-headers06 response-headers
06 response-headers
 
Xml writers
Xml writersXml writers
Xml writers
 
Cassandra Java APIs Old and New – A Comparison
Cassandra Java APIs Old and New – A ComparisonCassandra Java APIs Old and New – A Comparison
Cassandra Java APIs Old and New – A Comparison
 
AWS Hadoop and PIG and overview
AWS Hadoop and PIG and overviewAWS Hadoop and PIG and overview
AWS Hadoop and PIG and overview
 
Introduction to Apache Tajo: Data Warehouse for Big Data
Introduction to Apache Tajo: Data Warehouse for Big DataIntroduction to Apache Tajo: Data Warehouse for Big Data
Introduction to Apache Tajo: Data Warehouse for Big Data
 
ASP.Net Presentation Part2
ASP.Net Presentation Part2ASP.Net Presentation Part2
ASP.Net Presentation Part2
 
Pdf tech deep dive 42 paris
Pdf tech deep dive 42 parisPdf tech deep dive 42 paris
Pdf tech deep dive 42 paris
 
Elasticsearch And Ruby [RuPy2012]
Elasticsearch And Ruby [RuPy2012]Elasticsearch And Ruby [RuPy2012]
Elasticsearch And Ruby [RuPy2012]
 
(BDT205) Your First Big Data Application On AWS
(BDT205) Your First Big Data Application On AWS(BDT205) Your First Big Data Application On AWS
(BDT205) Your First Big Data Application On AWS
 
Sqlxml vs xquery
Sqlxml vs xquerySqlxml vs xquery
Sqlxml vs xquery
 
IQPC Canada XML 2001: How to Use XML Parsing to Enhance Electronic Communication
IQPC Canada XML 2001: How to Use XML Parsing to Enhance Electronic CommunicationIQPC Canada XML 2001: How to Use XML Parsing to Enhance Electronic Communication
IQPC Canada XML 2001: How to Use XML Parsing to Enhance Electronic Communication
 
KubeCon EU 2016: Templatized Application Configuration on OpenShift and Kuber...
KubeCon EU 2016: Templatized Application Configuration on OpenShift and Kuber...KubeCon EU 2016: Templatized Application Configuration on OpenShift and Kuber...
KubeCon EU 2016: Templatized Application Configuration on OpenShift and Kuber...
 

Último

Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGSujit Pal
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 

Último (20)

Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAG
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 

Connecting to Amazon S3 Weekly Code Drop

  • 1. Weekly Code Drop: Connecting to Amazon S3 Part 1 of 3 Formulating the S3 Request Jason Hayes Christensen jasonc411.com July 11 Weekly Code Drop
  • 2. Amazon S3 is a cloud-storage technology from Amazon Web Services, LLC. ● Cloud storage can help overcome the storage limitations of mobile architectures. ● There is a cost to using S3, so the applications that use S3 to augment storage should have a business model that accounts for these costs. ● Pricing Information: http://aws.amazon.com/s3/#pricing July 11 Weekly Code Drop
  • 3. Detailed S3 documentation can be accessed at: http://developer.amazonwebservices.com/connect/entry.jspaexternalID=123&categoryID=48 ● We are not using any of the existing S3 libs. ● This is a 4-part set of presentations that show how to develop for S3 from the ground up. ● The focus of this particular presentation is how to augment the headers of the HTTP REST request for authentication in virtual hosted mode. – Using NSURL and NSMutableURLRequest. July 11 Weekly Code Drop
  • 4. First, we will be using the ehmacauth functionality from the July 4 code drop. – Note that a memory leak was fixed and the download site is updated. ● We create the “StringToSign” in this example. ● The “StringToSign” is defined on page 13 of the S3 Developers Guide 20060301 as: StringToSign = HTTP-Verb + "n" + Content-MD5 + "n" + Content-Type + "n" + Date + "n" + CanonicalizedAmzHeaders + CanonicalizedResource; July 11 Weekly Code Drop
  • 5. Remember, we are using virtual hosted mode, this means that we address a bucket as: <bucketName>.s3.amazonaws.com ● The “resource” is the file name, it is specified as the path on the server when using virtual hosted mode: mybucket.s3.amazonaws.com/myresource.wav ● This model is nice because we do not have to determine what part of the file path is the bucket vs. the resource. July 11 Weekly Code Drop
  • 6. Let's define a new class that will modify the headers of the outbound URL Request. ● This class adds S3 headers to an existing NSMutableURLRequest. ● This class is named S3HTTPRequestHeaders. ● The one initializer for this class is: - (id)initForBucket:(NSString*) bucket andResource:(NSString*) resource; ● To avoid any specific coupling, the bucket and resource names are broken out. July 11 Weekly Code Drop
  • 7. This initializer simply sets up the member variables, including the start of the auth token: - (id) initForBucket:(NSString*) bucket andResource:(NSString*) resource { _bucket = bucket; _resource = resource; _authToken = [NSString stringWithFormat:@"AWS %@:", kPublicKey]; _amzDate = NO; return self; } July 11 Weekly Code Drop
  • 8. Dates are key to the request process. ● First of all, a request's date can differ by no more than 15 minutes from the time it is received by the Amazon servers. ● Second, if the date in the StringToSign is different than the date Amazon receives in the request header it will not authenticate. ● Watch for issues that affect the date header; for instance some proxies can modify Date header slightly. – In this case use X-Amz-Date header. July 11 Weekly Code Drop
  • 9. Date header formatting must meet the RFC 1123 standard( http://ietf.org/rfc/rfc1123.txt ) ● To do this we use NSDateFormatter. – This allows us to both read and stream string representations of the Date header. - (NSString*)currentRFC1123DateTime:(NSDate*) date { NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease]; [dateFormatter setFormatterBehavior: NSDateFormatterBehavior10_4]; [dateFormatter setDateFormat:@"EEE, dd MMM yyyy HH:mm:ss ZZ"]; [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; return [dateFormatter stringFromDate:date]; } July 11 Weekly Code Drop
  • 10. Modifying a header is simple, here we update the HTTP Date header by calling: – NSMutableURLRequest setValue: forHTTPHeaderField:. - (void) appendDateHeader:(NSMutableURLRequest*) request date:(NSDate*) date useAmzDate:(Boolean) amzDate; { [request setValue:[self currentRFC1123DateTime:date] forHTTPHeaderField:@"Date"]; if(amzDate){ [request setValue:[self currentRFC1123DateTime:date] forHTTPHeaderField:@"X-Amz-Date"]; _amzDate = amzDate;} } July 11 Weekly Code Drop
  • 11. Since we are using virtualized host mode, we have to modify the host header, this again is very simple using the NSHttpURLRequest setValue:forHTTPHeaderField:. - (void) appendHostHeader:(NSMutableURLRequest*) request { [request setValue:[NSString stringWithFormat:@"%@.%@", _bucket, kHost] forHTTPHeaderField:@"Host"]; } July 11 Weekly Code Drop
  • 12. Next we will add the canonicalizedResource. ● Directly from page 14 of the developers guide: 1 Start with the empty string (""). 2 If the request specif es a bucket using the HTTP Host header (virtual hosted- i style), append the bucket name preceded by a "/" (e.g., "/bucketname"). For path-style requests and requests that don't address a bucket, do nothing. For more information on virtual hosted-style requests, see Virtual Hosting of Buckets (p. 25). 3 Append the path part of the un-decoded HTTP Request-URI, up-to but not including the query string. 4 If the request addresses a sub-resource, like ?location, ?acl, or ? torrent, append the sub-resource including question mark. July 11 Weekly Code Drop
  • 13. Because we break out the resource and bucket separately in the initializer for S3HTTPRequestHeaders, this ends up being very simple. - (NSString*)canonicalizedResource:(NSURLRequest*) request { NSMutableString* canonResource = [[[NSMutableString alloc] initWithString:@"/"] autorelease]; if(_bucket != nil) [canonResource appendFormat:@"%@", _bucket]; if(_resource != nil) [canonResource appendFormat:@"%@", _resource]; return canonResource; } July 11 Weekly Code Drop
  • 14. The most obscure part of the “StringToSign” for new devs are the canonicalizedAmzHeaders. ● These headers all have the prefix X-Amz- ● They are used to communicate application specific information in the REST request. ● One caveat: multiple headers of the same name are not supported by NSHTTPUrlRequest. ● Therefore our demo code just concatenates the headers after sorting them. July 11 Weekly Code Drop
  • 15. Directly from pp 14-15 of the Developers Guide: 1 Convert each HTTP header name to lower-case. For example, 'X-Amz-Date' becomes 'x- amz-date'. 2 Sort the collection of headers lexicographically by header name. 3 Combine header f elds with the same name into one "header-name:comma- i separated-value-list" pair as prescribed by RFC 2616, section 4.2, without any white-space between values. For example, the two metadata headers 'x-amz-meta-username: fred' and 'x- amz-meta-username: barney' would be combined into the single header 'x-amz-meta- username: fred,barney'. 4 "Un-fold" long headers that span multiple lines (as allowed by RFC 2616, section 4.2) by replacing the folding white-space (including new-line) by a single space. July 11 Weekly Code Drop
  • 16. CanonicalizedAmzHeaders Process Cont. 5 Trim any white-space around the colon in the header. For example, the header 'x-amz- meta-username: fred,barney' would become 'x- amz-meta-username:fred,barney' 6 Finally, append a new-line (U+000A) to each canonicalized header in the resulting list. Construct the CanonicalizedResource element by concatenating all headers in this list into a single string ● Since our utility class NSHTTPUrlRequest does not support multiple entries of the same header, and removes whitespace, we have simplified the code for the demo. July 11 Weekly Code Drop
  • 17. First, we have to sort the headers – to do this we grab the array of keys and sort them using NSString's caseInsensitiveCompare. - (NSString*)canonicalizedAmzHeaders:(NSURLRequest*) request { NSMutableString* ret = [[[NSMutableString alloc] init] autorelease]; NSDictionary* dict = [request allHTTPHeaderFields]; NSArray* keys = [[dict allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:) ]; July 11 Weekly Code Drop
  • 18. Next we iterate over the array of keys looking for keys with the header X-Amz ● When we find one we append it and its value to the return string. for(id header in keys) { NSString* str = [(NSString*)header lowercaseString]; if([str hasPrefix:@"x-amz"]) [ret appendFormat:@"%@:%@n", str, (NSString*)[dict objectForKey:header]]; } return ret; } July 11 Weekly Code Drop
  • 19. Finally we have all the information we need for the StringToSign so we add the authorization header. ● We sign the string with our private key, then pass the public key, and the signature to S3 in the Authorization header. ● The string has the format: “AWS <PublicKey>:<Signature>” July 11 Weekly Code Drop
  • 20. OK, a final look at setting up the StringToSign ● Let's setup a mutable string and grab the standard headers that make up the string. NSMutableString* s2s = [[[NSMutableString alloc] initWithFormat:@"%@n", [request HTTPMethod]] autorelease]; NSString* contentMD5 = [request valueForHTTPHeaderField:@"content-md5"]; NSString* contentType = [request valueForHTTPHeaderField:@"content-type"]; NSString* date = [request valueForHTTPHeaderField:@"date"]; //We can't append null strings, so we do the following check on each header if(contentMD5 != nil) [s2s appendFormat:@"%@n", contentMD5]; else [s2s appendString:@"n"]; July 11 Weekly Code Drop
  • 21. Next we append the canonicalized headers, push out a debug string, and return the string. [s2s appendString:[self canonicalizedAmzHeaders:request]]; [s2s appendString:[self canonicalizedResource:request]]; NSLog(@"************ String to Sign follows *******************"); NSLog(s2s); NSLog(@"************ End String To Sign ***********************"); return s2s; } July 11 Weekly Code Drop
  • 22. Finally we sign the string, this should look familiar from last weeks code drop. - (void) appendAuthorizationHeader:(NSMutableURLRequest*) request { NSString* stringToSign = [self createStringToSign:request]; NSString* authToken = [NSString stringWithFormat:@"%@:%@", _authToken, [EncodedHMACToken createEncodedHMACToken:kPrivateKey message:stringToSign signatureType:kSHA1 forURI:NO]]; [request setValue:authToken forHTTPHeaderField:@"Authorization"]; } July 11 Weekly Code Drop
  • 23. At this point, we should be good to go. The NSMutableURLRequest has the appropriate headers to make the invocation. ● From this point, to make a request, you will have to setup your own S3 Account. ● See page 9 of the Getting Started Guide for S3 accessible at: http://developer.amazonwebservices.com/connect/entry.jspaexternalID=123&categoryID=48 July 11 Weekly Code Drop
  • 24. In summary – Unit test are included – To this point, we are able to use the outlined tests in the developers guide on pp. 14-19 – The first three lines of each test are just staged for right now, in the actual requests they will be more formalized. – As always, code is accessible at jasonc411.com's downloads pages. – July 18 WCD should go out mid-week. July 11 Weekly Code Drop
  • 25. Upcoming Code Drops: – Part 2 Processing a Response – Part 3 Creating the libS3 Functional interface – Part 4 Using S3 with the iAudioNotebook. Hope all is well, jason h christensen (on Twitter: jasonc411) founder jasonc411.com software architecture technical research technical thought leadership July 11 Weekly Code Drop
  • 26. Signatures Slide 1 EHMACAUTH files SHA1(Base64Encoder.h)= 848aa02c301987ab116e5228e8437816191c68f8 ● SHA1(Base64Encoder.m)= b494db4979f5e001a954d9559e73175b3adfd426 ● SHA1(EncodedHMACToken.h)= a9709162247ded70311e69d5233dc8994cb511f1 ● SHA1(EncodedHMACToken.m)= 3bd9b592455920476eff5bb931dc4ac7cbf1e18f ● SHA1(base64HMACTests-Info.plist)= 6b31f761a5a58d61c06282778fa005410bdbbe37 ● SHA1(base64HMACTests.h)= be22db6b5528ed65856568ce0e1658b3b12997dd ● SHA1(base64HMACTests.m)= fd4b7dce4519ff11cd0942d8bb9075b8d96229c4 ● SHA1(ehmacauth_Prefix.pch)= 7c43d1c65c49c85da9a73643fe6032f2bbf95c2a ● SHA1(ehmacauth.xcodeproj/project.pbxproj)= cd287838fcd106a55dddfa1477719acc0a798898 July 11 Weekly Code Drop
  • 27. Signatures Slide 2 S3HTTPRequestHeaders and Tests SHA1(S3HTTPRequestHeaders.h)= baaabcf47147758ef9b9bc51de9fef650a5c5767 ● SHA1(S3HTTPRequestHeaders.m)= ce5e49cac2d19e430cc9b49373aa6129c121c093 ● SHA1(S3Tests-Info.plist)= 6b31f761a5a58d61c06282778fa005410bdbbe37 ● SHA1(S3_Prefix.pch)= 7c43d1c65c49c85da9a73643fe6032f2bbf95c2a ● SHA1(libS3RequestTests.h)= f52cd50b70cca323549f1f0f148d94b3934a3849 ● SHA1(libS3RequestTests.m)= aa2e08ce3e7f1d700360bad587e612e17b6e890d ● SHA1(S3.xcodeproj/project.pbxproj)= ff7f3b41e08ddd5dd3405e74887112ce5c072616 July 11 Weekly Code Drop