public GetResponse(WebResponse response) : base(response) { SortedList metadata = extractMetadata( response ); byte [] data = Utils.slurpInputStream( response.GetResponseStream() ); this.obj = new S3Object( data, metadata ); }
public string put( string bucket, string key, S3Object obj, SortedList headers ) { SortedList metadata = null; if ( obj != null ) { metadata = obj.Metadata; } return generateURL("PUT", bucket, key, mergeMeta(headers, metadata)); }
/// <summary> /// Make a new WebRequest /// </summary> /// <param name="method">The HTTP method to use (GET, PUT, DELETE)</param> /// <param name="bucket">The bucket name for this request</param> /// <param name="key">The key this request is for</param> /// <param name="headers">A map of string to string representing the HTTP headers to pass (can be null)</param> /// <param name="obj">S3Object that is to be written (can be null).</param> /// <param name="timeout">Timeout in ms. Set to zero for no timeout.</param> private WebResponse makeRequest(string method, string bucket, string key, SortedList query, SortedList headers, S3Object obj, int timeout) { if (!String.IsNullOrEmpty(key)) key = Utils.urlEncode(key); String url = buildUrl(bucket, key, query); int redirectCount = 0; for (; ; ) { // prep request HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); req.KeepAlive = false; //?????????????????????????????????? //Since we fixed the ".Close()" problem, I don't think this is needed... //if (timeout > 0) //{ // req.ReadWriteTimeout = timeout; // req.Timeout = timeout; //} //?????????????????????????????????? //default timeout is 100 sec... this is not good for putting ~100MB files! if (timeout > 0) req.Timeout = timeout; req.Method = method; // we handle redirects manually req.AllowAutoRedirect = false; // we already buffer everything req.AllowWriteStreamBuffering = false; // if we are sending >1kb data, ask for 100-Continue if (obj != null && obj.Bytes.Length > 1024) req.ServicePoint.Expect100Continue = true; addHeaders(req, headers); if (obj != null) addMetadataHeaders(req, obj.Metadata); addAuthHeader(req, bucket, key, query); if (obj != null) { // Work around an HttpWebRequest bug where it will // send the request body even if the server does *not* // send 100 continue req.KeepAlive = false; // Write actual data byte[] data = obj.Bytes; req.ContentLength = data.Length; Stream requestStream = req.GetRequestStream(); MemoryStream dataStream = new MemoryStream(data); BufferedTransfer(dataStream, requestStream); //requestStream.Write(data, 0, data.Length); requestStream.Close(); } // execute request HttpWebResponse response; try { response = (HttpWebResponse)req.GetResponse(); if (!isRedirect(response)) return response; // retry against redirected url url = response.Headers["Location"]; response.Close(); if (url == null || url.Length == 0) throw new WebException("Redirect without Location header, may need to change calling format.", WebExceptionStatus.ProtocolError); } catch (WebException ex) { if (ex.Response == null) throw; string msg = Utils.slurpInputStreamAsString(ex.Response.GetResponseStream()); throw new WebException(msg, ex, ex.Status, ex.Response); } redirectCount++; if (redirectCount > 10) throw new WebException("Too many redirects."); } }
static int Main(string[] args) { try { if ( awsAccessKeyId.StartsWith( "<INSERT" ) ) { System.Console.WriteLine( "Please examine S3Driver.cs and update it with your credentials" ); return 1; } AWSAuthConnection conn = new AWSAuthConnection( awsAccessKeyId, awsSecretAccessKey ); QueryStringAuthGenerator generator = new QueryStringAuthGenerator( awsAccessKeyId, awsSecretAccessKey ); // Check if the bucket exists. The high availability engineering of // Amazon S3 is focused on get, put, list, and delete operations. // Because bucket operations work against a centralized, global // resource space, it is not appropriate to make bucket create or // delete calls on the high availability code path of your application. // It is better to create or delete buckets in a separate initialization // or setup routine that you run less often. if (conn.checkBucketExists(bucketName)) { System.Console.WriteLine("----- bucket already exists! -----"); } else { System.Console.WriteLine( "----- creating bucket -----" ); // to create an EU located bucket change the Location param like this: // using ( Response response = conn.createBucket( bucketName, Location.EU, null ) ) using (Response response = conn.createBucket(bucketName, Location.EU, null)) { System.Console.WriteLine(response.getResponseMessage() ); } } System.Console.WriteLine("----- bucket location -----"); using (LocationResponse locationResponse = conn.getBucketLocation(bucketName)) { if (locationResponse.Location == null) System.Console.WriteLine("Location: <error>"); else if (locationResponse.Location.Length == 0) System.Console.WriteLine("Location: <default>"); else System.Console.WriteLine("Location: '{0}'", locationResponse.Location); } System.Console.WriteLine("----- listing bucket -----"); using ( ListBucketResponse listBucketResponse = conn.listBucket( bucketName, null, null, 0, null ) ) { dumpBucketListing( listBucketResponse ); } System.Console.WriteLine( "----- putting object -----" ); S3Object obj = new S3Object( "This is a test", null ); SortedList headers = new SortedList(); headers.Add( "Content-Type", "text/plain" ); using ( Response response = conn.put( bucketName, keyName, obj, headers ) ) { System.Console.WriteLine( response.getResponseMessage() ); } System.Console.WriteLine( "----- listing bucket -----" ); using ( ListBucketResponse listBucketResponse = conn.listBucket( bucketName, null, null, 0, null ) ) { dumpBucketListing( listBucketResponse ); } System.Console.WriteLine( "----- query string auth example -----" ); generator.ExpiresIn = 60 * 1000; System.Console.WriteLine( "Try this url in your web browser (it will only work for 60 seconds)\n" ); string url = generator.get( bucketName, keyName, null ); System.Console.WriteLine( url ); System.Console.Write( "\npress enter >" ); System.Console.ReadLine(); System.Console.WriteLine( "\nNow try just the url without the query string arguments. It should fail.\n" ); System.Console.WriteLine( generator.makeBaseURL(bucketName, keyName) ); System.Console.Write( "\npress enter >" ); System.Console.ReadLine(); System.Console.WriteLine( "----- putting object with metadata and public read acl -----" ); SortedList metadata = new SortedList(); metadata.Add( "blah", "foo" ); obj = new S3Object( "this is a publicly readable test", metadata ); headers = new SortedList(); headers.Add( "x-amz-acl", "public-read" ); headers.Add( "Content-Type", "text/plain" ); using ( Response response = conn.put( bucketName, keyName + "-public", obj, headers ) ) { System.Console.WriteLine( response.getResponseMessage() ); } System.Console.WriteLine( "----- anonymous read test -----" ); System.Console.WriteLine( "\nYou should be able to try this in your browser\n" ); string publicURL = generator.get(bucketName, keyName + "-public", null); System.Console.WriteLine(publicURL); System.Console.Write( "\npress enter >" ); System.Console.ReadLine(); System.Console.WriteLine("----- path style url example -----"); System.Console.WriteLine("\nNon-location-constrained buckets can also be specified as part of the url path. (This was the original url style supported by S3.)"); System.Console.WriteLine("\nTry this url out in your browser (it will only be valid for 60 seconds)\n"); generator.CallingFormat = CallingFormat.PATH; // could also have been done like this: // generator = new QueryStringAuthGenerator(awsAccessKeyId, awsSecretAccessKey, true, Utils.DEFAULT_HOST, CallingFormat.getPathCallingFormat()); generator.ExpiresIn = 60 * 1000; System.Console.WriteLine(generator.get(bucketName, keyName, null)); System.Console.Write("\npress enter> "); System.Console.ReadLine(); System.Console.WriteLine( "----- getting object's acl -----" ); using ( GetResponse response = conn.getACL( bucketName, keyName, null ) ) { System.Console.WriteLine( response.Object.Data ); } System.Console.WriteLine( "----- deleting objects -----" ); using ( Response response = conn.delete( bucketName, keyName, null ) ) { System.Console.WriteLine( response.getResponseMessage() ); } using ( Response response = conn.delete( bucketName, keyName + "-public", null ) ) { System.Console.WriteLine( response.getResponseMessage() ); } System.Console.WriteLine( "----- listing bucket -----" ); using ( ListBucketResponse listBucketResponse = conn.listBucket( bucketName, null, null, 0, null ) ) { dumpBucketListing( listBucketResponse ); } System.Console.WriteLine( "----- listing all my buckets -----" ); using ( ListAllMyBucketsResponse listBucketResponse = conn.listAllMyBuckets( null ) ) { dumpAllMyBucketListing( listBucketResponse ); } System.Console.WriteLine( "----- deleting bucket -----" ); using ( Response response = conn.deleteBucket( bucketName, null ) ) { System.Console.WriteLine( response.getResponseMessage() ); } return 0; } catch ( WebException e ) { System.Console.WriteLine( e.Status ); System.Console.WriteLine( e.Message ); System.Console.WriteLine( e.StackTrace ); System.Console.ReadLine(); return 1; } catch ( Exception e ) { System.Console.WriteLine( e.Message ); System.Console.WriteLine( e.StackTrace ); System.Console.ReadLine(); return 1; } }
/// <summary> /// Writes an object to S3. /// </summary> /// <param name="bucket">The name of the bucket to which the object will be added.</param> /// <param name="key">The name of the key to use</param> /// <param name="obj">An S3Object containing the data to write.</param> /// <param name="headers">A map of string to string representing the HTTP headers to pass (can be null)</param> public Response put( string bucket, string key, S3Object obj, SortedList headers ) { return new Response(makeRequest("PUT", bucket, key, null, headers, obj, 3600000)); // 60 min timeout }