react-native icon indicating copy to clipboard operation
react-native copied to clipboard

fetch doesn't work with Brotli on Android

Open andresribeiro opened this issue 2 years ago • 9 comments

Description

When making an HTTP request with br on Accept-Encoding, the request throws an error on Android, but works perfectly well on iOS

React Native Version

0.72.5

Output of npx react-native info

System:
  OS: Linux 5.15 Linux Mint 21.2 (Victoria)
  CPU: (4) x64 AMD A8-9600 RADEON R7, 10 COMPUTE CORES 4C+6G
  Memory: 11.27 GB / 15.07 GB
  Shell:
    version: 5.8.1
    path: /usr/bin/zsh
Binaries:
  Node:
    version: 20.8.0
    path: ~/.nvm/versions/node/v20.8.0/bin/node
  Yarn:
    version: 3.6.3
    path: /usr/bin/yarn
  npm:
    version: 10.1.0
    path: ~/.nvm/versions/node/v20.8.0/bin/npm
  Watchman: Not Found
SDKs:
  Android SDK: Not Found
IDEs:
  Android Studio: AI-223.8836.35.2231.10671973
Languages:
  Java:
    version: 11.0.20.1
    path: /usr/bin/javac
  Ruby: Not Found
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.2.0
    wanted: 18.2.0
  react-native:
    installed: 0.72.5
    wanted: ^0.72.5
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: Not found
  newArchEnabled: Not found
iOS:
  hermesEnabled: Not found
  newArchEnabled: Not found

Steps to reproduce

Try to run the following code, both on iOS and Android:

import { useEffect } from 'react';
import { Alert, Text, View, StyleSheet } from 'react-native';

export default function App() {
  useEffect(() => {
    async function doApiRequest() {
      try {
        const result = await fetch('http://worldtimeapi.org/api/timezone/America/Sao_Paulo', {
          method: 'GET',
          headers: {
            'Accept-Encoding': 'br'
          }
        })

        const json = await result.json()
        Alert.alert(JSON.stringify(json))
      } catch (error) {
        Alert.alert('error', JSON.stringify(error))
      }
    }

    doApiRequest()
  }, [])

  return (
    <View style={styles.container}>
      <Text style={styles.paragraph}>
        Hey!
      </Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    backgroundColor: '#ecf0f1',
    padding: 8,
  },
  paragraph: {
    margin: 24,
    fontSize: 18,
    fontWeight: 'bold',
    textAlign: 'center',
  },
});

Snack, screenshot, or link to a repository

https://snack.expo.dev/@andresribeiro/effe49

andresribeiro avatar Sep 30 '23 22:09 andresribeiro

the request throws an error on Android, but works perfectly well on iOS

What's the error?

cortinico avatar Oct 02 '23 21:10 cortinico

@cortinico on the example i provided, it catchs "{}" on the try catch

andresribeiro avatar Oct 02 '23 23:10 andresribeiro

I think we would need to add this: https://github.com/square/okhttp/blob/master/okhttp-brotli/README.md

NickGerleman avatar Oct 03 '23 14:10 NickGerleman

We would need to get internal version of OKHttp updated further to do this I think (we recently moved that from 3.6.0 to 3.14.9, but that is still behind what OSS RN is on).

NickGerleman avatar Oct 03 '23 14:10 NickGerleman

I think we would need to add this: square/okhttp@master/okhttp-brotli/README.md

I think the user should be able to override the default OkHTTP client, and provide its own implementation with the Brotli interceptor. We don't need this to live inside core afterall. Also the OSS version of OkHTTP we use is 4.9.x so the interceptor should just work

cortinico avatar Oct 03 '23 14:10 cortinico

I think we would need to add this: square/okhttp@master/okhttp-brotli/README.md

I think the user should be able to override the default OkHTTP client, and provide its own implementation with the Brotli interceptor. We don't need this to live inside core afterall. Also the OSS version of OkHTTP we use is 4.9.x so the interceptor should just work

I fully understand that React Native tries to keep it's core as minimal as possible, but I really think that this should be implemented inside core

1 - Brotli it's an official content encoding 2 - It's supported and used by all major browsers 3 - It's used by a lot of companies, including Cloudflare 4 - Even Expo started using Brotli for the expo-updates

andresribeiro avatar Oct 03 '23 15:10 andresribeiro

I fully understand that React Native tries to keep it's core as minimal as possible, but I really think that this should be implemented inside core

This is an implementation detail, and it's up to us to decide where the integration point should live. As a last resort, we could just provide a thin layer that adds Brotli and other commonly used interceptors in a separate NPM package that gets added by default.

Still you can use this today by feeding your own OkHTTP instance, so there is no blocker in using it.

cortinico avatar Oct 03 '23 15:10 cortinico

I tend to agree it would be best for RN to provide this out of the box. 99% of users won't know to add this, and it means network may be more expensive for RN users on Android in the meantime.

As a matter of practicality, I don't think RN will add this in the near-term, just because of the internal OKHttp dependency. But as @cortinico has mentioned, RN does allow customizing the default OKHttp client, so you could add this for your app.

NickGerleman avatar Oct 03 '23 15:10 NickGerleman

This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.

github-actions[bot] avatar Apr 03 '24 05:04 github-actions[bot]

This issue was closed because it has been stalled for 7 days with no activity.

github-actions[bot] avatar Apr 10 '24 05:04 github-actions[bot]