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

AuthTokenURLInterceptor overriding Content-Type header to application/json always #3184

Closed
sandeepklr opened this issue Aug 28, 2023 · 2 comments
Labels
api Issues related to the API category bug Something isn't working

Comments

@sandeepklr
Copy link

Describe the bug

Relevant amplifyconfiguration.json api configuration blob:

    "api": {
        "plugins": {
            "awsAPIPlugin": {
                "AbcApi": {
                    "endpointType": "REST",
                    "endpoint": "https://yyyyyyyyyy.execute-api.us-west-2.amazonaws.com/dev",
                    "region": "us-west-2",
                    "authorizationType": "OPENID_CONNECT"
                }
            }
        }
    }

I'm trying to use the Amplify API plugin to make multipart/form-data requests to API Gateway. From documentation listed here[1], I'd have expected to be able to do the following:

let headers = ["content-type": "multipart/form-data; boundary=....."]
let request = RESTRequest(path: ...., headers: headers, body: ...)

Ideally this would allow me to pass in the custom content-type while constructing a RESTRequest object[2], and then eventually override the default application/json content-type used while constructing a URLRequest object[3].

However, when the interceptors are run the AuthTokenURLInterceptor kicks and always overwrites the content-type header to set it to application/json [4, 5].

Is there a reason the AuthTokenURLInterceptor needs to set content-type?

As a workaround, I could just create another URLInterceptor and set the Content-Type there but given that the rest of the Amplify library is set up to accept custom headers it seems redundant to do that.

[1] https://docs.amplify.aws/lib/restapi/authz/q/platform/ios/#none
[2]

let inputHeaders = headers ?? [:]
self.headers = inputHeaders.merging(
["Cache-Control": "no-store"],
uniquingKeysWith: { current, _ in current}
)

[3]
var requestHeaders = ["content-type": "application/json"]
if let headers = headers {
for (key, value) in headers {
requestHeaders[key] = value
}
}

[4]
mutableRequest.setValue(URLRequestConstants.ContentType.applicationJson,
forHTTPHeaderField: URLRequestConstants.Header.contentType)

[5] Debug details:

URLRequest in AWSRESTOperation before AuthTokenURLInterceptor runs:

Printing description of urlRequest:
▿ ...
  ▿ httpMethod : Optional<String>
    - some : "POST"
  ▿ allHTTPHeaderFields : Optional<Dictionary<String, String>>
    ▿ some : 2 elements
      ▿ 0 : 2 elements
        - key : "Cache-Control"
        - value : "no-store"
      ▿ 1 : 2 elements
        - key : "Content-Type"
        - value : "multipart/form-data; boundary=CC1F1DBE-9CC3-448E-AE78-A1782C9D2BED"
  ▿ httpBody : Optional<Data>
    ▿ some : 2051407 bytes
      - count : 2051407
      ▿ pointer : 0x00007f7bfc821000
        - pointerValue : 140170494087168
  - httpBodyStream : nil
  - httpShouldHandleCookies : true
  - httpShouldUsePipelining : false

URLRequest in AWSRESTOperation after AuthTokenURLInterceptor runs:

Printing description of finalRequest:
▿ ....
  ▿ httpMethod : Optional<String>
    - some : "POST"
  ▿ allHTTPHeaderFields : Optional<Dictionary<String, String>>
    ▿ some : 5 elements
      ▿ 0 : 2 elements
        - key : "User-Agent"
        - value : "amplify-iOS/1.16.1 iOS/16.4 en_US"
      ▿ 1 : 2 elements
        - key : "Cache-Control"
        - value : "no-store"
      ▿ 2 : 2 elements
        - key : "Authorization"
        - value : "...."
      ▿ 3 : 2 elements
        - key : "Content-Type"
        - value : "application/json"
      ▿ 4 : 2 elements
        - key : "X-Amz-Date"
        - value : "20230828T103145Z"
  ▿ httpBody : Optional<Data>
    ▿ some : 2051407 bytes
      - count : 2051407
      ▿ pointer : 0x00007f7bfc821000
        - pointerValue : 140170494087168
  - httpBodyStream : nil
  - httpShouldHandleCookies : true
  - httpShouldUsePipelining : false  

Steps To Reproduce

See above.

Expected behavior

Overriding Content-Type should work in RESTRequest should work.

Amplify Framework Version

2.15.2

Amplify Categories

API

Dependency manager

Swift PM

Swift version

5.8.1

CLI version

12.2.5

Xcode version

14.3.1

Relevant log output

No response

Is this a regression?

No

Regression additional context

No response

Platforms

iOS

OS Version

All

Device

All

Specific to simulators

No response

Additional context

No response

@sandeepklr sandeepklr changed the title AuthTokenURLInterceptor overriding Content-Type header AuthTokenURLInterceptor overriding Content-Type header to application/json always Aug 28, 2023
@ruisebas ruisebas added api Issues related to the API category question General question labels Aug 28, 2023
@atierian
Copy link
Member

Thanks for opening this issue @sandeepklr. We really appreciate the thoroughness of it!

This is being worked on in PR #3190. We'll update you here once it's released.

@atierian atierian added bug Something isn't working and removed question General question labels Sep 18, 2023
@atierian
Copy link
Member

The fix for this was released in Amplify Swift 2.17.2
Thanks again for reporting this and your feedback in the PR review process!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api Issues related to the API category bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants