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

feat(ios): allow for for per-image-request-headers #691

Merged

Conversation

dreampiggy
Copy link
Contributor

@dreampiggy dreampiggy commented Jun 5, 2020

See detail issue description in #690. See SDWebImage issue: SDWebImage/SDWebImage#3031
Close #242

Fix the implementation on iOS for per-image-request-header-setup. Should not use SDWebImageDownloader which manage the global shared headers.

Should Use the context option of request modifier. Or when concurrent request comes, the headers may mass up.

This MR also bump webp coder because the old version contains OOM issue.

CC @DylanVann @andreialecu

…DownloaderRequestModifier convenient API usage
…uld not use `SDWebImageDownloader` which manage the global shared headers. Use the context option of request modifier.
@andreialecu
Copy link

andreialecu commented Jun 5, 2020

🎉

@dreampiggy
Copy link
Contributor Author

dreampiggy commented Jun 5, 2020

Extra changes:

  1. Fix the issue of data:image for WebP images. Using SDWebImage's API can keep the external format support, including WebP/APNG/AVIF/HEIF. As well as iOS system default format.
  2. Alaways bypass invalid SSL certificate error, same behavior like React-Native itself

@dreampiggy
Copy link
Contributor Author

The CI environment seems broken (Not related to this MR changes). I can ensure the build sucess on my local development environment.

image

image

@dreampiggy
Copy link
Contributor Author

@andreialecu If your RN iOS use CocoaPods. You can use the git commit dependnecy to test the behavior.

pod 'react-native-fast-image', :git => 'https://github.com/dreampiggy/react-native-fast-image.git', :branch => 'bugfix_ios_sd_header_per_image_request'

@andreialecu
Copy link

I generally like to use patch-package. I think it should work just the same.

I seem to be getting this error on pod install though. I can probably update the deployment target, but it may result in breaking changes for users?

[!] CocoaPods could not find compatible versions for pod "SDWebImage":
  In snapshot (Podfile.lock):
    SDWebImage (= 5.7.0, ~> 5.0)

  In Podfile:
    RNFastImage (from `../node_modules/react-native-fast-image`) was resolved to 8.1.5, which depends on
      SDWebImage (~> 5.8)

Specs satisfying the `SDWebImage (= 5.7.0, ~> 5.0), SDWebImage (~> 5.8)` dependency were found, but they required a higher minimum deployment target.

@andreialecu
Copy link

Okay, deleting Podfile.lock then running pod repo update then pod install got it going.

It's probably an artifact of using patch-package to update the package.

@andreialecu
Copy link

andreialecu commented Jun 5, 2020

I seem to be seeing this crash:

image

Not sure what is wrong, could be a problem on my end. It did not occur previously though

The error above goes away if I remove the specific FastImage that fails to load, so it must be related to it.

I'm trying to clean the ios build folder and will report back.

@andreialecu
Copy link

No luck:

  return (<FastImage
    style={{ height: 100, width: 100 }}
    source={{ uri: "https://dummyimage.com/600x400/000/fff"}}
  />);

Enters error handler here:

image

But more interestingly:

  return (<FastImage
    style={{ height: 100, width: 100 }}
    source={{ uri: "https://loremflickr.com/320/240"}}
  />);

This crashes with EXC_BAD_ACCESS shown in a previous message. I suspect it's because the URL is a redirect and doesn't store the image directly.

Both images display properly if I replace FastImage with the react-native Image

@andreialecu
Copy link

Commenting out this line makes the images load:

https://github.com/DylanVann/react-native-fast-image/pull/691/files#diff-c18dcaa41187abeeba66a03f2fd7b89aR193

But that would make custom headers not work.

I guess something is incomplete related to the context.

@dreampiggy
Copy link
Contributor Author

Please paste the demo code or project so I can have a debug check tomorrow. Seems some more strange behavior inside.

@andreialecu
Copy link

andreialecu commented Jun 6, 2020

@dreampiggy minimal repro at: https://github.com/andreialecu/rnfastimage-691

To get it going, run:

yarn
cd ios && pod install
yarn ios

Take a look at App.js, I left a comment there. Should show both the crash and the empty images.

(the changes in this PR are applied by patch-package automatically on yarn install, via the file in patches/*, so they are ready to use)

@dreampiggy
Copy link
Contributor Author

dreampiggy commented Jun 7, 2020

After using native debug code, I found the following issue:

  1. Your example URL https://dummyimage.com/600x400/000/fff, use the multipart/mixed contents for image, which is not considered in currernt SDWebImage implementation. (Ususally image server return image/jpeg or something, not a multipart contents, just raw blob data).

But React-Native provide the implemenation, see: https://github.com/facebook/react-native/blob/0.63-stable/React/Base/RCTMultipartDataTask.m#L101-L128

So, which means, until we support the same code, you can not request the stream-style image server provider.

  1. Your example URL https://dummyimage.com/600x400/000/fff which use a not-trusted SSL certificate. (You have wrong Let's Encrypt config?). Because of this, you will trigger the SSL authoriation error for SDWebImage. Use SDWebImageDownloaderAllowInvalidSSLCertificates can skip this validation.

But however, react-native-fast-image does not have anything customizable for this behavior. For temp workaround, I can hardcode this to always skip.

@dreampiggy
Copy link
Contributor Author

The multipart/mixed case I can create a Feature Request on SDWebImage side. This must need Client Code update to handle.

@dreampiggy
Copy link
Contributor Author

Send TODO feature reuqest: SDWebImage/SDWebImage#3033

@andreialecu
Copy link

andreialecu commented Jun 7, 2020

Strange. I don't see any SSL certificate error in Desktop Chrome or iOS Safari on neither of the images.

Could you clarify which one has the SSL issue?

@andreialecu
Copy link

I've updated the code as per your latest commit and the second image still crashes the app. (loremflickr)

I don't think there's any SSL issue, because the crash occurs when using a google maps photos url as well. The only thing in common is that both do a redirect.

@andreialecu
Copy link

andreialecu commented Jun 7, 2020

Additionally, could you clarify where you see multipart/mixed? The raw headers for https://dummyimage.com/600x400/000/fff are:

$ curl https://dummyimage.com/600x400/000/fff -i

HTTP/2 200 
server: nginx
date: Sun, 07 Jun 2020 09:53:34 GMT
content-type: image/png
content-length: 1783
cache-control: public, max-age=7776000
expires: Sat, 05 Sep 2020 09:08:05 +0000
last-modified: Sun, 07 Jun 2020 09:08:05 GMT
x-srcache-fetch-status: HIT
x-srcache-store-status: BYPASS
access-control-allow-origin: *
access-control-allow-methods: GET, POST, OPTIONS
access-control-allow-headers: DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range
access-control-expose-headers: Content-Length,Content-Range

This is the second one:

$ curl https://loremflickr.com/320/240 -i -L

HTTP/2 302 
date: Sun, 07 Jun 2020 10:16:55 GMT
content-type: text/html; charset=UTF-8
set-cookie: __cfduid=d73251b784a012e5458b99e9b1bd8b59d1591525014; expires=Tue, 07-Jul-20 10:16:54 GMT; path=/; domain=.loremflickr.com; HttpOnly; SameSite=Lax; Secure
expires: Thu, 19 Nov 1981 08:52:00 GMT
cache-control: no-store, no-cache, must-revalidate
pragma: no-cache
access-control-allow-origin: *
set-cookie: PHPSESSID=8845ac386084cd41085da14df128f2d8; path=/
location: /cache/resized/65535_49600375582_8b90c8f3ca_n_320_240_nofilter.jpg
vary: User-Agent,Accept-Encoding
cf-cache-status: DYNAMIC
cf-request-id: 032fe195100000290c6bb1f200000001
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
cf-ray: 59f99ece8c54290c-OTP

HTTP/2 200 
date: Sun, 07 Jun 2020 10:16:55 GMT
content-type: image/jpeg
content-length: 16788
set-cookie: __cfduid=d545204559e173f7cf0ac3aa276f227991591525015; expires=Tue, 07-Jul-20 10:16:55 GMT; path=/; domain=.loremflickr.com; HttpOnly; SameSite=Lax; Secure
last-modified: Thu, 04 Jun 2020 11:15:25 GMT
etag: "4194-5a74042e6aa73"
cache-control: public, max-age=604800
expires: Sat, 04 Jul 2020 12:28:58 GMT
vary: User-Agent
access-control-allow-origin: *
access-control-allow-headers: origin, x-requested-with, content-type
access-control-allow-methods: GET,POST,OPTIONS,DELETE,PUT
cf-cache-status: HIT
accept-ranges: bytes
cf-request-id: 032fe196920000290c6bb30200000001
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
cf-ray: 59f99ed0ed81290c-OTP

Seems like all the data would be there. I see content-type: image/png and image/jpeg. Also both images load with the master version of react-native-fast-image, but they're broken with this PR.

@andreialecu
Copy link

    [self sd_setImageWithURL:_source.url
            placeholderImage:nil
                     options:options
//                     context:context
                    progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {

Again, I just verified that commenting out context here makes both images load perfectly. But the headers are (obviously) going to be missing.

@dreampiggy dreampiggy mentioned this pull request Jun 8, 2020
@migueldaipre
Copy link

I did the tests as described by you, and it worked perfectly with local Base64 WebP images.
I could only notice how the @andreialecu said, without commenting on the context the external images do not work.

I got the same error: EXC_BAD_ACCESS (code = 1, address = 0x0)
CFNetwork internal error

I wanted to understand more to help. If you can guide me.

I had problems with Flipper, I changed in PodFile to 0.37.0.

image

@andreialecu
Copy link

Hey @dreampiggy, was just wondering if you saw the latest discussion here.

@dreampiggy
Copy link
Contributor Author

Busy working in daily job...

For the strange crash, I doubt there are something race condition for iOS native code to mutable copy && copy the NSURLRequest.

If I can reproduce the crash, maybe it's better to do not mutable copy and re-create a new NSURLRequest instead. I'll have a try and verify, if that can fix, I'll update the MR.

@andreialecu
Copy link

andreialecu commented Jun 10, 2020

Sure, I understand.

But there's not just the crash, neither of the images load with these changes unless context is removed. I think there's something else wrong with it.

Edit: the multipart/mixed and SSL error may be related to the great firewall perhaps? Don't see those issues myself.

@dreampiggy
Copy link
Contributor Author

Seems the fucky fact that mutableCopy is dangerous.

I write the exact same code in logic, to re-construct a new NSURLRequest, instead of mutable copy the original one and modify, the crash disappears. :)

image

…bugs on 5.8.0 (will fix in 5.8.1), revert the dependency bump
@dreampiggy
Copy link
Contributor Author

dreampiggy commented Jun 11, 2020

@andreialecu
Confirmed the bug because of SDWebImage's usage.

The NSURLRequest.HTTPMethod should not use nil, should use GET for default value.

I'll provide a hotfix on SDWebImage for this.

This PR already apply the patch, and can be mereged now. You can have a try again with the latest branch commit.

@andreialecu
Copy link

andreialecu commented Jun 11, 2020

@dreampiggy awesome, I just tested it and it loads all images that were previously not loading, and headers are not leaking any more. There's one minor concern about skipping invalid SSL certs, which I added a comment about. (edit: this has been reverted, PR should be good to go)

@gwenoleR
Copy link

Hi guys, any news about this fix ?

@dreampiggy
Copy link
Contributor Author

I want to merge this, but seems not get any reply from the maintainer yet.

@dreampiggy
Copy link
Contributor Author

dreampiggy commented Jul 17, 2020

@DylanVann I'm glad to see you back here for continue maintains.

This PR not only just used for logic fix, but also fix the security issue talked about by #690. This means you leaks the HTTP headers like Cookie to other domain.

@dreampiggy dreampiggy force-pushed the bugfix_ios_sd_header_per_image_request branch from da534b4 to 0826cac Compare July 17, 2020 04:28
.gitignore Show resolved Hide resolved
@DylanVann
Copy link
Owner

@dreampiggy Thanks so much for implementing this. This was an aspect of SDWebImage that always frustrated me, great that it's fixed.

@DylanVann DylanVann changed the title Fix the implementation on iOS for per-image-request-header-setup feat: on iOS allow for for per-image-request-headers Jul 17, 2020
@DylanVann DylanVann changed the title feat: on iOS allow for for per-image-request-headers feat(ios): allow for for per-image-request-headers Jul 17, 2020
@DylanVann DylanVann merged commit 4a7cd64 into DylanVann:master Jul 17, 2020
github-actions bot pushed a commit that referenced this pull request Jul 17, 2020
# [8.3.0](v8.2.2...v8.3.0) (2020-07-17)

### Features

* **ios:** allow for for per-image-request-headers ([#691](#691)) ([4a7cd64](4a7cd64))
@github-actions
Copy link

🎉 This PR is included in version 8.3.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@dreampiggy
Copy link
Contributor Author

dreampiggy commented Jul 17, 2020

@dreampiggy Thanks so much for implementing this. This was an aspect of SDWebImage that always frustrated me, great that it's fixed.

Note this MR also add the support for any external image format support for base64:// on iOS. So maybe it's better to update the release changelog as well.

Previouslly, only the HTTP url can load WebP/AVIF/SVG/PDF, etc.

The iOS user just need to register the coder plugin following SDWebImage's Coder Plugin, then all things done.

github-actions bot pushed a commit to perrystreetsoftware/react-native-fast-image that referenced this pull request Aug 3, 2021
# [6.0.0](v5.0.11...v6.0.0) (2021-08-03)

### Bug Fixes

* add react@17 as peer dependency ([DylanVann#790](https://github.com/perrystreetsoftware/react-native-fast-image/issues/790)) ([27bd586](27bd586))
* xcode 12 compatibility ([DylanVann#732](https://github.com/perrystreetsoftware/react-native-fast-image/issues/732)) ([23c3955](23c3955))
* **android:** make center ResizeMode work correctly ([d648ef8](d648ef8))
* **android:** remove explicit use of UI thread ([DylanVann#698](https://github.com/perrystreetsoftware/react-native-fast-image/issues/698)) ([5d2894e](5d2894e))
* accessibilityIgnoresInvertColors prop not recognised when using TypeScript ([DylanVann#666](https://github.com/perrystreetsoftware/react-native-fast-image/issues/666)) ([22f89e4](22f89e4)), closes [/github.com/DylanVann/react-native-fast-image/blob/master/src/index.tsx#L150-L160](https://github.com//github.com/DylanVann/react-native-fast-image/blob/master/src/index.tsx/issues/L150-L160)
* Add git tag to CocoaPods source property ([DylanVann#601](https://github.com/perrystreetsoftware/react-native-fast-image/issues/601)) ([2d706ad](2d706ad))
* Add tintColor type definition. ([4adf42f](4adf42f))
* Bump Glide version number to v4.11.0. ([DylanVann#649](https://github.com/perrystreetsoftware/react-native-fast-image/issues/649)) ([c4e4306](c4e4306)), closes [DylanVann#536](https://github.com/perrystreetsoftware/react-native-fast-image/issues/536)
* Fix dependency versions not specified in podfile. ([89f3379](89f3379)), closes [DylanVann#456](https://github.com/perrystreetsoftware/react-native-fast-image/issues/456)
* Fix fallback prop not working. ([DylanVann#420](https://github.com/perrystreetsoftware/react-native-fast-image/issues/420)) ([487d410](487d410))
* Fix IllegalArgumentException crash (Android). ([DylanVann#511](https://github.com/perrystreetsoftware/react-native-fast-image/issues/511)) ([b6c4677](b6c4677))
* Fix incorrect syntax. ([11f6047](11f6047))
* Fix local resource cache issue on Android. ([DylanVann#472](https://github.com/perrystreetsoftware/react-native-fast-image/issues/472)) ([5f65383](5f65383)), closes [DylanVann#402](https://github.com/perrystreetsoftware/react-native-fast-image/issues/402)
* Fix memory leak on iOS. ([DylanVann#433](https://github.com/perrystreetsoftware/react-native-fast-image/issues/433)) ([70be744](70be744))
* Fix peer dependency and remove prop-types. ([44a4c8b](44a4c8b))
* Fix setting props order issue for iOS. ([DylanVann#303](https://github.com/perrystreetsoftware/react-native-fast-image/issues/303)) ([5597ed0](5597ed0)), closes [DylanVann#304](https://github.com/perrystreetsoftware/react-native-fast-image/issues/304)
* Fix wildcard peer dependencies. ([7149420](7149420)), closes [DylanVann#440](https://github.com/perrystreetsoftware/react-native-fast-image/issues/440)
* Fixes cacheControl types. ([DylanVann#382](https://github.com/perrystreetsoftware/react-native-fast-image/issues/382)) ([e13db7d](e13db7d)), closes [DylanVann#325](https://github.com/perrystreetsoftware/react-native-fast-image/issues/325)
* Fixes podspec syntax. ([b627646](b627646))
* Fixes WebP rendering on iOS 12. ([DylanVann#412](https://github.com/perrystreetsoftware/react-native-fast-image/issues/412)) ([97630c8](97630c8)), closes [DylanVann#298](https://github.com/perrystreetsoftware/react-native-fast-image/issues/298) [DylanVann#385](https://github.com/perrystreetsoftware/react-native-fast-image/issues/385)
* Loading images by reverting "bug: Use device scale when loading images.". ([0326c3e](0326c3e)), closes [DylanVann#509](https://github.com/perrystreetsoftware/react-native-fast-image/issues/509)
* peer dependency warning ([DylanVann#653](https://github.com/perrystreetsoftware/react-native-fast-image/issues/653)) ([cd81b1b](cd81b1b))
* remove cache property if using fallback ([ba0f238](ba0f238))
* Replace 'Component' with 'ComponentType' ([DylanVann#647](https://github.com/perrystreetsoftware/react-native-fast-image/issues/647)) ([6abb273](6abb273))
* update SDWebImage and SDWebImageWebPCoder ([DylanVann#689](https://github.com/perrystreetsoftware/react-native-fast-image/issues/689)) ([9646456](9646456))
* Updates SDWebImageWebPCoder. ([DylanVann#628](https://github.com/perrystreetsoftware/react-native-fast-image/issues/628)) ([325d77f](325d77f))
* Upgrade vendored SDWebImage to v5.0.5. ([5016172](5016172)), closes [DylanVann#489](https://github.com/perrystreetsoftware/react-native-fast-image/issues/489)
* wrong cache type ([DylanVann#688](https://github.com/perrystreetsoftware/react-native-fast-image/issues/688)) [skip ci] ([94e2256](94e2256))

### Features

* **ios:** allow for for per-image-request-headers ([DylanVann#691](https://github.com/perrystreetsoftware/react-native-fast-image/issues/691)) ([4a7cd64](4a7cd64))
* Add cookie support for iOS. ([DylanVann#284](https://github.com/perrystreetsoftware/react-native-fast-image/issues/284)) ([ae47bff](ae47bff))
* Add tint color support. ([03c50f0](03c50f0)), closes [DylanVann#124](https://github.com/perrystreetsoftware/react-native-fast-image/issues/124)
* Add tvOS target. ([DylanVann#486](https://github.com/perrystreetsoftware/react-native-fast-image/issues/486)) ([6805972](6805972))
* converts to TypeScript ([DylanVann#642](https://github.com/perrystreetsoftware/react-native-fast-image/issues/642)) ([ac11706](ac11706))
* export ResizeMode and Priority types ([DylanVann#678](https://github.com/perrystreetsoftware/react-native-fast-image/issues/678)) ([e33664f](e33664f))
* Upgrade example apps. ([DylanVann#453](https://github.com/perrystreetsoftware/react-native-fast-image/issues/453)) ([25f8f0d](25f8f0d))
* Upgrade to React Native 0.60.0 / CocoaPods / Android X. ([DylanVann#513](https://github.com/perrystreetsoftware/react-native-fast-image/issues/513)) ([5489f9e](5489f9e))
* Upgrade to SDWebImage 5.0. ([DylanVann#454](https://github.com/perrystreetsoftware/react-native-fast-image/issues/454)) ([8a216e2](8a216e2)), closes [DylanVann#447](https://github.com/perrystreetsoftware/react-native-fast-image/issues/447)
* Use forwardRef to allow access to ref.measure and others. ([DylanVann#419](https://github.com/perrystreetsoftware/react-native-fast-image/issues/419)) ([2b4fba3](2b4fba3)), closes [DylanVann#69](https://github.com/perrystreetsoftware/react-native-fast-image/issues/69)

### Performance Improvements

* Use React.memo for FastImage. ([DylanVann#449](https://github.com/perrystreetsoftware/react-native-fast-image/issues/449)) ([5c2b4af](5c2b4af))

### Reverts

* Remove functionality for notifying other images on load. ([DylanVann#452](https://github.com/perrystreetsoftware/react-native-fast-image/issues/452)) ([292223d](292223d))

### BREAKING CHANGES

* This changes how network requests are handled on iOS. Make sure they still work for you.
* You should upgrade React Native. See https://facebook.github.io/react-native/blog/2019/07/03/version-60
* Upgrade SDWebImage, may affect some projects and CocoaPods users.

Fix the bug of `cacheOnly` behavior
alicayan008 pushed a commit to alicayan008/ReactNative-fast-image that referenced this pull request Jul 4, 2023
# [8.3.0](DylanVann/react-native-fast-image@v8.2.2...v8.3.0) (2020-07-17)

### Features

* **ios:** allow for for per-image-request-headers ([#691](DylanVann/react-native-fast-image#691)) ([4a7cd64](DylanVann/react-native-fast-image@4a7cd64))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Some images are not showing.
5 participants