Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uploading to devicefarm using the pre-signed URL gives signature mismatch #337

Closed
jedi4ever opened this issue Aug 6, 2015 · 4 comments
Closed

Comments

@jedi4ever
Copy link

I'm trying to upload to the presigned URL returned by the devicefarm CreateUpload call.
I get an URL and I can PUT to it but it keeps complaining:

The request signature we calculated does not match the signature you provided. Check your key and signing method

  • The file is read correctly
  • I'm able to list and do createupload with my credentials which have for testing no restrictions.
  • I've tried with and without headers, content-type with various spelling

Thank you for fixing/proving a sample to upload an ipa/apk to devicefarm.

 svc := devicefarm.New(&aws.Config{Region: aws.String("us-west-2")})

 name := "a.ipa"
myarn := "arn:aws:devicefarm:us-west-2:110440800955:project......"

uploadReq := &devicefarm.CreateUploadInput{
   Name:        aws.String(name),
   ProjectARN:  aws.String(myarn),
   Type:        aws.String("IOS_APP"),
   ContentType: aws.String("application/octet-stream"),
 }

resp, err := svc.CreateUpload(uploadReq)

  req, err := http.NewRequest("PUT", *resp.Upload.URL, data)
  req.Header.Set("Content-Type", "application/octet-stream")

  if err != nil {
    log.Fatal(err)
  }

  client := &http.Client{}
  res, err := client.Do(req)

  if err != nil {
    log.Fatal(err)
  }
  defer res.Body.Close()

@cristim
Copy link

cristim commented Aug 6, 2015

Hi,

I had similar issues when uploading to S3, needed for CloudFormation custom
resources written in golang.

The problem is caused by net/http, which un-escapes the special characters
from the response URL(in my case colons and pipe characters), which is
breaking the signature mechanism.

My workaround was to undo the un-escaping in the URL, using Opaque URLs:

req, err := http.NewRequest("PUT", event.ResponseURL, strings.NewReader(string(responseBody)))

req.URL.Opaque = strings.Replace(URL.Path, ":", "%3A", -1)
req.URL.Opaque = strings.Replace(req.URL.Opaque, "|", "%7C", -1)

req.Header.Set("content-length", strconv.Itoa(len(responseBody)))

client := &http.Client{}

resp, err := client.Do(req)

if err != nil {
    fmt.Println("Failed to set CloudFormation state", err.Error())
}

defer resp.Body.Close()

I hope this helps you, but if any of you guys can think of a better way,
I'm all ears :-)

-Cristi

@cristim
Copy link

cristim commented Aug 6, 2015

Apparently answering by email is not so well supported by Github, and looks like I can't properly format the answer's code anymore.

@jedi4ever
Copy link
Author

Thanks cristim! You put me on the right track with the opaque trick.
I've had to add the raw_query too

  fileToUpload := "a.ipa"
  file, err := os.Open(fileToUpload)

  if err != nil {
    fmt.Println(err)
    os.Exit(1)
  }

  defer file.Close()

  fileInfo, _ := file.Stat()
  var fileSize int64 = fileInfo.Size()

  buffer := make([]byte, fileSize)

  // read file content to buffer
  file.Read(buffer)

  fileBytes := bytes.NewReader(buffer) // convert to io.ReadSeeker type

 req, err := http.NewRequest("PUT", upload_url, fileBytes)

// Splitting the url by string function because golang URL parsing tries to be too clever
 strippedUrl := strings.Split(strings.Replace(upload_url, "https://prod-us-west-2-uploads.s3-us-west-2.amazonaws.com/", "/", -1), "?")
// The actual path
 req.URL.Opaque = strippedUrl[0]
// the part with AWS_KEY , Expire, ...
 req.URL.RawQuery = strippedUrl[1]

 req.Header.Set("Content-Type", "application/octet-stream")
 req.Header.Add("Content-Length", strconv.FormatInt(fileSize, 10))

client := &http.Client{}

    resp, err := client.Do(req)

    if err != nil {
        fmt.Println("Failed to set Upload To Devicefarm", err.Error())
    }

    defer resp.Body.Close()

@jedi4ever
Copy link
Author

For more info on using the devicefarm API - I've made a devicefarm-cli.

The upload part can be found at
https://github.com/jedi4ever/devicefarm-cli/blob/master/devicefarm-cli.go#L443

skotambkar added a commit to skotambkar/aws-sdk-go that referenced this issue May 20, 2021
aws#337)

Updated shape marshal model to handle the empty map vs nil map behavior.
Adding a test case to assert behavior when a user sends an empty map vs nil map.

Fix aws#332
skotambkar pushed a commit to skotambkar/aws-sdk-go that referenced this issue May 20, 2021
Services
===
* Synced the V2 SDK with latest AWS service API definitions.
* Fixes [aws#341](aws/aws-sdk-go-v2#341)
* Fixes [aws#342](aws/aws-sdk-go-v2#342)

SDK Breaking Changes
===
* `aws`: Add default HTTP client instead of http.DefaultClient/Transport ([aws#315](aws/aws-sdk-go-v2#315))
  * Adds a new BuildableHTTPClient type to the SDK's aws package. The type uses the builder pattern with immutable changes. Modifications to the buildable client create copies of the client.  Adds a HTTPClient interface to the aws package that the SDK will use as an abstraction over the specific HTTP client implementation. The SDK will default to the BuildableHTTPClient, but a *http.Client can be also provided for custom configuration.  When the SDK's aws.Config.HTTPClient value is a BuildableHTTPClient the SDK will be able to use API client specific request timeout options.
  * Fixes [aws#279](aws/aws-sdk-go-v2#279)
  * Fixes [aws#269](aws/aws-sdk-go-v2#269)

SDK Enhancements
===
* `service/s3/s3manager`: Update S3 Upload Multipart location ([aws#324](aws/aws-sdk-go-v2#324))
  * Updates the Location returned value of S3 Upload's Multipart UploadOutput type to be consistent with single part upload URL. This update also brings the multipart upload Location inline with the S3 object URLs created by the SDK.
  * Fixes [aws#323](aws/aws-sdk-go-v2#323)
  * V2 Port [aws#2453](aws#2453)

SDK Bugs
===
* `private/model`: Handles empty map vs unset map behavior in send request ([aws#337](aws/aws-sdk-go-v2#337))
  * Updated shape marshal model to handle the empty map vs nil map behavior. Adding a test case to assert behavior when a user sends an empty map vs nil map.
  * Fix [aws#332](aws/aws-sdk-go-v2#332)
* `service/rds`: Fix presign URL for same region ([aws#331](aws/aws-sdk-go-v2#331))
  * Fixes RDS no-autopresign URL for same region issue for aws-sdk-go-v2. Solves the issue by making sure that the presigned URLs are not created, when the source and destination regions are the same. Added and updated the tests accordingly.
  * Fix [aws#271](aws/aws-sdk-go-v2#271)
* `private/protocola/json/jsonutil`: Fix Unmarshal map[string]bool ([aws#320](aws/aws-sdk-go-v2#320))
  * Fixes the JSON unmarshaling of maps of bools. The unmarshal case was missing the condition for bool value, in addition the bool pointer.
  * Fix [aws#319](aws/aws-sdk-go-v2#319)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants