简体   繁体   中英

How to fix ETIMEDOUT of webpack devServer proxy (ignoring corporate proxy?)

In my local development environment i use webpack devServer.proxy to proxy an API request to https://.atlassian.net/rest/api/2 to suppress CORS issues.

But the requests times out with

[HPM] Error occurred while trying to proxy request /project from localhost:9008 to https://<myProject>.atlassian.net/rest/api/2 (ETIMEDOUT) (https://nodejs.org/api/errors.html#errors_common_system_errors)

I guess the problem is, that i am in a corporate network behind a proxy and to get access to the internet i need to use the proxy. Proxy settings are included in /etc/profile (MacOS).

When i do a similar request with curl in the same shell like

curl --request GET --url 'https://<myProject>.atlassian.net/rest/api/2/project' --header 'Authorization: Basic <someBase64EncodedString>' --header 'Accept: application/json'

i get a valid answer (list of all projects i have access to). With webpack-dev-server running the same request times out (see above).

This is my webpack devServer.proxy configuration:

'/api/*': {
            target: 'https://<myProject>.atlassian.net/rest/api/2',
            headers: {
                Authorization: 'Basic <someBase64EncodedString>',
                Accept: "application/json"
            },
            secure: false,
            changeOrigin: true,
            pathRewrite: {
                '^/api': ''
            },
            logLevel: 'debug'
        }

Any ideas why webpack is ignoring https_proxy from /etc/profile ?

Any ideas?

As i didn't find anything about how to proxy devServer.proxy, I found a workaround:

We need to use another local proxy to send the request through the corporate proxy. This could be done by a nodejs script which runs a httpServer (localhost:9009) and gets the request, which i wanted to send to https://myProject.atlassian.net/rest/api/2 . This httpServer will then send my request to the corporate proxy. Webpack.devServer.proxy config will now look like this:

'/api/*': {
        target: 'http://localhost:9009',
        headers: {
            Authorization: 'Basic <someBase64EncodedString>',
            Accept: "application/json"
        },
        secure: false,
        changeOrigin: true,
        pathRewrite: {
            '^/api': ''
        },
        logLevel: 'debug'
    }

httpServer "postproxy.js" script can look like this:

var http = require('http');

var request = require('./node_modules/request');
var fs = require('fs');
var proxy = "<corporate proxy url>";
var api = "https://<myProject>.atlassian.net/rest/api/2/";
var hopper = "https://<myProject>.atlassian.net/rest/greenhopper/1.0";

http.createServer(function (reqorg, resorg) {

if (reqorg.method == 'POST'){
    var bodyorg = '';
    reqorg.on('data', function (data) {
        bodyorg += data;
    });
    reqorg.on('end', function () {

        var head = {
            "content-type" : "application/json",
            "Authorization": reqorg.headers.authorization
        };

        if(reqorg.url.includes("attachment")){
            // Adjusting Head for Attachment Transfer
            head["X-Atlassian-Token"] = "no-check";
            head["content-type"] = "multipart/form-data";

            var content = JSON.parse(bodyorg);
            var buffer = Buffer.from(content.file,'base64');

            var options = {
                headers: head,
                uri: api+reqorg.url,
                formData: {
                    file: {
                        value: buffer,
                        options: {
                            filename: content.filename
                        }
                    }
                },
                method: 'POST'
            }

            request(options, function(err, response, body){
                resorg.writeHead(200, {'Content-Type': 'application/json'});
                resorg.end(body);
            });

        } else {

            request.post({
                headers: head,
                url: api+reqorg.url,
                proxy: proxy,
                body: bodyorg
            }, function(error, response, body){
                resorg.writeHead(200, {'Content-Type': 'application/json'});
                resorg.end(body);
            });

        }
    });
} else if (reqorg.method == 'GET') {
    request.get({
        headers: {
            'content-type' : 'application/json',
            'Authorization': reqorg.headers.authorization
        },
        url: api + reqorg.url
    }, function (error, response, body) {
        resorg.writeHead(200, {'Content-Type': 'application/json'});
        resorg.end(body);
    })
} else if (reqorg.method == 'DELETE') {
    request.delete({
        headers: {
            'content-type' : 'application/json',
            'Authorization': reqorg.headers.authorization
        },
        url: api + reqorg.url
    }, function (error, response, body) {
        resorg.writeHead(200, {'Content-Type': 'application/json'});
        resorg.end(body);
    });
} else if (reqorg.method == 'PUT') {
    var bodyorg = '';
    reqorg.on('data', function (data) {
        bodyorg += data;
    });
    reqorg.on('end', function () {
        request.put({
            headers: {
                'content-type' : 'application/json',
                'Authorization': reqorg.headers.authorization
            },
            url: hopper+reqorg.url,
            proxy: proxy,
            body: bodyorg
        }, function(error, response, body){
            resorg.writeHead(200, {'Content-Type': 'application/json'});
            resorg.end(body);
        });
    });
}

}).listen(9009);

Do not forget to start it in package.json:

"scripts": {
    "start": "webpack-dev-server --mode development | npm run proxy",
    "proxy": "node postproxy.js"
},

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM