44package scenarios
55
66import (
7+ "bytes"
78 "fmt"
89 "io"
910 "log"
11+ "mime/multipart"
1012 "net/http"
1113 "os"
1214 "strings"
@@ -23,6 +25,7 @@ import (
2325// unit testing.
2426type IHttpRequester interface {
2527 Get (url string ) (resp * http.Response , err error )
28+ Post (url , contentType string , body io.Reader ) (resp * http.Response , err error )
2629 Put (url string , contentLength int64 , body io.Reader ) (resp * http.Response , err error )
2730 Delete (url string ) (resp * http.Response , err error )
2831}
@@ -33,6 +36,15 @@ type HttpRequester struct{}
3336func (httpReq HttpRequester ) Get (url string ) (resp * http.Response , err error ) {
3437 return http .Get (url )
3538}
39+ func (httpReq HttpRequester ) Post (url , contentType string , body io.Reader ) (resp * http.Response , err error ) {
40+ postRequest , err := http .NewRequest ("POST" , url , body )
41+ if err != nil {
42+ return nil , err
43+ }
44+ postRequest .Header .Set ("Content-Type" , contentType )
45+ return http .DefaultClient .Do (postRequest )
46+ }
47+
3648func (httpReq HttpRequester ) Put (url string , contentLength int64 , body io.Reader ) (resp * http.Response , err error ) {
3749 putRequest , err := http .NewRequest ("PUT" , url , body )
3850 if err != nil {
@@ -51,6 +63,43 @@ func (httpReq HttpRequester) Delete(url string) (resp *http.Response, err error)
5163
5264// snippet-end:[gov2.s3.IHttpRequester.helper]
5365
66+ // snippet-start:[gov2.s3.MultipartUpload.helper]
67+ func sendMultipartRequest (url string , fields map [string ]string , file * os.File , filePath string , httpRequester IHttpRequester ) (* http.Response , error ) {
68+ // Create a buffer to hold the multipart data
69+ var requestBody bytes.Buffer
70+ writer := multipart .NewWriter (& requestBody )
71+
72+ // Add form fields
73+ for key , val := range fields {
74+ err := writer .WriteField (key , val )
75+ if err != nil {
76+ return nil , err
77+ }
78+ }
79+
80+ // Always has to be named like this, and always has to be the last one
81+ fileField := "file"
82+ part , err := writer .CreateFormFile (fileField , filePath )
83+ if err != nil {
84+ return nil , err
85+ }
86+ _ , err = io .Copy (part , file )
87+ if err != nil {
88+ return nil , err
89+ }
90+
91+ // Close the writer to finalize the multipart message
92+ err = writer .Close ()
93+ if err != nil {
94+ return nil , err
95+ }
96+
97+ // make the request
98+ return httpRequester .Post (url , writer .FormDataContentType (), & requestBody )
99+ }
100+
101+ // snippet-end:[gov2.s3.MultipartUpload.helper]
102+
54103// snippet-start:[gov2.s3.Scenario_Presigning]
55104
56105// RunPresigningScenario is an interactive example that shows you how to get presigned
@@ -76,7 +125,7 @@ func (httpReq HttpRequester) Delete(url string) (resp *http.Response, err error)
76125func RunPresigningScenario (sdkConfig aws.Config , questioner demotools.IQuestioner , httpRequester IHttpRequester ) {
77126 defer func () {
78127 if r := recover (); r != nil {
79- fmt .Printf ("Something went wrong with the demo. " )
128+ fmt .Printf ("Something went wrong with the demo" )
80129 }
81130 }()
82131
@@ -159,6 +208,24 @@ func RunPresigningScenario(sdkConfig aws.Config, questioner demotools.IQuestione
159208 log .Println (string (downloadBody [:100 ]))
160209 log .Println (strings .Repeat ("-" , 88 ))
161210
211+ log .Println ("Now we'll create a new request to put the same object using a presigned post request" )
212+ presignPostRequest , err := presigner .PresignPostObject (bucketName , uploadKey , 60 )
213+ if err != nil {
214+ panic (err )
215+ }
216+ log .Printf ("Got a presigned post request to url %v with values %v\n " , presignPostRequest .URL , presignPostRequest .Values )
217+ log .Println ("Using net/http multipart to send the request..." )
218+ uploadFile , err = os .Open (uploadFilename )
219+ if err != nil {
220+ panic (err )
221+ }
222+ defer uploadFile .Close ()
223+ multiPartResponse , err := sendMultipartRequest (presignPostRequest .URL , presignPostRequest .Values , uploadFile , uploadKey , httpRequester )
224+ if err != nil {
225+ panic (err )
226+ }
227+ log .Printf ("Presign post object %v with presigned URL returned %v." , uploadKey , multiPartResponse .StatusCode )
228+
162229 log .Println ("Let's presign a request to delete the object." )
163230 questioner .Ask ("Press Enter when you're ready." )
164231 presignedDelRequest , err := presigner .DeleteObject (bucketName , uploadKey )
0 commit comments