-
Notifications
You must be signed in to change notification settings - Fork 587
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
packages/stream-collector-browser not compatible with Edge/IE11/Older versions of android #1107
Comments
@AllanFly120 tagging you as you have recently contributed to packages/stream-collector-browser |
More information: updating runtimeconfig.browser.ts in client-cognito-identity with the following makes amplify work in both chrome and edge/ie:
Another note/issue: importing Obviously this is a hack, but by removing our dependency on fetch (which, IMO, is poorly defined in Typescript's lib.dom - lib.dom should not define that the Response constructor can take in a ReadableStream, as that is experimental), we have a library that works in all browsers. Suggested fixes:
|
@trivikr pinging you also since you reviewed #721, which seemed to introduce the issue Using ReadableStream should be fine as there are polyfills, but this line is problematic: |
Could be related as well aws-amplify/amplify-js#5405 |
@AllanFly120 @trivikr @Amplifiyer PR is here: Tested in Chrome, IE11, and Edge |
Thanks a lot for the detailed analysis and description, also the PR, I will review it soon. Is the Regarding the browser support I need to discuss with the team together with feedbacks from Amplify. Potentially, we can either remove non-compatible components(if there's more), or provide a guide to bundle the SDK for IE. |
Polyfills are still required for Web Streams and fetch, but that's pretty much BAU for front-end orgs. The big issue here is that you can't polyfill to overload a constructor AFAIK, hence why the Response() constructor was replaced with another implementation |
I did some more tests to find a production-ready usage, and found the following issues with the popular polyfills:
After cycling through various polyfills, @stardazed/streams-polyfill works excellently - and even monkey-patches the Response constructor so that the sdk works in-browser without my fix, but I'm curious if there's more we should do to make the sdk compatible with different environments.
@AllanFly120 and @trivikr - given the vision for the new sdk, where should we take it from here? @Amplifiyer - what is the correct guidance for the amplify community? Should amplify include a polyfill, suggest users pull in the stardazed polyfill, or ... ? |
Hey @russell-dot-js I think the main problem to solve here is the SDK's dependency on ReadableStream body from the fetch response. By default the SDK assumes This structure brings us the problem that if users need to polyfill the If you want to use the same solution in your code, you can: import {FooClient} from "@aws-sdk/client-foo";
import {FetchHttpHandler} from "@aws-sdk/fetch-http-handler";
import { streamCollector } from "@aws-sdk/stream-collector-native";
const client = new FooClient({
requestHandler: FetchHttpHandler({bufferBody: true}),
streamCollector // this always pairs with 'requestHandler'
}) With this change, you can polyfill the SDK with pretty much all the providers you mentioned above. But I know it requires code change, this definitele does not fix issue for most prod apps. I will dig more for solutions not requiring code changes. |
One solution on the top of my head is that inside the fetch handler, we return the body in different shapes basing on whether if (typeof ReadableStream === 'function' && response.body instanceof ReadableStream) {
// return the response body as a ReadableStream
} else {
// return response body as blob
return response.blob().then(body => ({
response: new HttpResponse({
headers: transformedHeaders,
statusCode: response.status,
body
})
}));
} In this case the SDK will return a |
@AllanFly120 very cool that requestHandler and streamCollector can already be overridden by calling the constructor yourself. I was only looking at ClientDefaultValues, not the constructor, and was going to suggest this change, but it looks like it already works the way I was hoping. That being said, the decision is whether or not the sdk should try to support every environment, or whether that responsibility falls on the consumer. I'm more than happy to put up a PR that implements fetch-http-handler and stream-collector-browser to work whether or not fetch (and the Response constructor) are implemented, but before going down that path, I want to make sure that the intention of this sdk is to support both cases, or if we should put that responsibility on the consumer. |
@AllanFly120 here you go, I was bored: |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs and link to relevant comments in this thread. |
Confirm by changing [ ] to [x] below to ensure that it's a bug:
Describe the bug
packages/stream-collector-browser exports the following function:
However, the constructor Response(ReadableStream), as defined in Typescripts lib.dom, is not implemented in IE, Edge, older versions of android, and (potentially - unknown) other older browsers. The code results in error "invalid arguments".
Compounding the issue is that since fetch itself is implemented in some of these browsers, polyfills such as whatwg-fetch will not be applied.
Is the issue in the browser/Node.js?
Browser
Details of the browser/Node.js version
Microsoft Edge 44.17763.1.0
IE11
SDK version number
1.0.0-beta.3
To Reproduce (observed behavior)
Easy: run any app using cognito identity with the
@aws-amplify
library in IE11, Edge, or Older android versions (the official Microsoft VM reproduces just fine: https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/)Once logged in, stream-collector-browser's attempt to turn the cached Cognito identity will fail, resulting in subsequent requests being signed with accessKeyId "undefined", despite successful authentication with Cognito.
Expected behavior
streamCollector() should not throw an error
Screenshots
If applicable, add screenshots to help explain your problem.
Additional context
Related issues:
aws-amplify/amplify-js#5332
aws-amplify/amplify-js#5534
I've spent a couple days debugging this issue, and working on potential fixes. Trying to ponyfill Response with whatwg-fetch or node-fetch's Response has not yet been successful - node-fetch works in Chrome but Edge is still broken, whatwg-fetch actually causes Chrome to start throwing the same error that Edge already throws (digging in, it looks like whatwg-fetch does not properly implement the Response(ReadableStream) constructor.
Suggestion: I am not wildly familiar with these new API's and didn't find an easy way to convert a ReadableStream to a Uint8Array.
Buffer.from(String(stream));
seems like the easy way to do it, but does not seem to work (I'm aware this is for node-only). My concern is that this new aws sdk, which hopefully we can all use in production soon, requires fetch to be properly implemented globally. Sadly, fetch is not part of the ECMA spec, and cannot safely be used in production today without being transpiled.The text was updated successfully, but these errors were encountered: