queen-raae / gatsby-remark-oembed

A GatsbyJS Plugin that transforms oembed links into its corresponding embed code.
https://gatsby-remark-oembed.netlify.com/
MIT License
162 stars 25 forks source link

add socks5 proxy 👻 #87

Closed tizee closed 4 years ago

tizee commented 5 years ago

Why

Right now for some network issues, I couldn't use this plugin to fetch oembed code that providers return directly. This is a very common issue for many Chinese users and it caused by the GFW. To solve this, I have to hard code the configuration in fetchOembed.js so that the axios could use socks5 proxy to request the data successfully. Otherwise, I would get ETIMEDOUT errors.

original:

// node_modules/@raae/gatsby-remark-oembed/utils/fetchOembed.js
const axios = require("axios");

const fetchOembed = async endpoint => {
  const response = await axios.get(endpoint.url, {
    params: {
      format: "json",
      ...endpoint.params
    }
  });
  return response.data;
};

module.exports = fetchOembed;

My workaround:

// modified: node_modules/@raae/gatsby-remark-oembed/utils/fetchOembed.js
const axios = require("axios");
const SocksProxyAgent = require("socks-proxy-agent");

const fetchOembed = async endpoint => {
  const proxyHost = "127.0.0.1", proxyPort = "9999";
  const proxyOptions = `socks5://${proxyHost}:${proxyPort}`;
  const httpAgent = new SocksProxyAgent(proxyOptions);
  const httpsAgent = httpAgent;
  const response = await axios.get(endpoint.url, {
    params: {
      format: "json",
      ...endpoint.params
    },
    httpAgent: httpAgent,
    httpsAgent: httpsAgent
  });
  return response.data

However, these changes will be overwritten whenever yarn updates.

Solution

The right way to solve this is by forking the repository to customized gatsby-remark-oembed. I add a new option named useProxy to custom the proxy that axios uses.

So I could use it like using usePrefix.

 options:{
 useProxy: {
       host: '127.0.0.1',
        port: '1234',
        // useSocks5 defaults to true
         useSocks5: false // this will use  axios proxy config instead of socks5
       }
}

If useProxy is missing, the proxy is disabled as expected.

 options:{
 useProxy:  false, // -> disable explicitly
}

Files and test

I've modified amendedOptions.js and created a file named getProxyAgent.js to handle above processing. In order to maintain the stability of the plugin, I also created getProxyAgent.test.js and all tests were passed. In addition, some test cases were also added to other .test.js files.

code review is needed

I don't know whether some of my code is necessary to achieve this feature.

raae commented 4 years ago

If I remember correctly from another project it is possible to "highjack" Axios globally. If so that might be a better approach so we do not have to change it in several places.

nickytonline commented 4 years ago

Hi @tizee, Nick here, a new maintainer on the project. Thanks for the PR.

Would you mind opening an issue for this so that we can discuss the issue in there? From what I can tell, the issue is pretty much your PR description, but it's always nice to have issues to track these things.

I haven't used Axios myself, just good old fetch @raae, but I agree that changing it in several places to use the proxy will add a bit of a maintenance burden which we should try to avoid if possible.

tizee commented 4 years ago

Hi @tizee, Nick here, a new maintainer on the project. Thanks for the PR.

Would you mind opening an issue for this so that we can discuss the issue in there? From what I can tell, the issue is pretty much your PR description, but it's always nice to have issues to track these things.

I haven't used Axios myself, just good old fetch @raae, but I agree that changing it in several places to use the proxy will add a bit of a maintenance burden which we should try to avoid if possible.

Sorry for the late response, the issue was due to poor network connection and I have managed to address this by setting up a VPN. To keep it simple, I'd like to close this PR now.

raae commented 4 years ago

Okey, thanks for closing!