GithubHelp home page GithubHelp logo

node-proxy-middleware's Introduction

Build Status

Usage:

var connect = require('connect');
var url = require('url');
var proxy = require('proxy-middleware');

var app = connect();
app.use('/api', proxy(url.parse('https://example.com/endpoint')));
// now requests to '/api/x/y/z' are proxied to 'https://example.com/endpoint/x/y/z'

//same as example above but also uses a short hand string only parameter
app.use('/api-string-only', proxy('https://example.com/endpoint'));

Documentation:

proxyMiddleware(options)

options allows any options that are permitted on the http or https request options.

Other options:

  • route: you can pass the route for connect middleware within the options, as well.
  • via: by default no via header is added. If you pass true for this option the local hostname will be used for the via header. You can also pass a string for this option in which case that will be used for the via header.
  • cookieRewrite: this option can be used to support cookies via the proxy by rewriting the cookie domain to that of the proxy server. By default cookie domains are not rewritten. The cookieRewrite option works as the via option - if you pass true the local hostname will be used, and if you pass a string that will be used as the rewritten cookie domain.
  • preserveHost: When enabled, this option will pass the Host: line from the incoming request to the proxied host. Default: false.

Usage with route:

var proxyOptions = url.parse('https://example.com/endpoint');
proxyOptions.route = '/api';

var middleWares = [proxy(proxyOptions) /*, ...*/];

// Grunt connect uses this method
connect(middleWares);

node-proxy-middleware's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

node-proxy-middleware's Issues

Redirect doesn't work

I tried it a long time but I didn*t get it. Here is a piece of my code:

var connect = require('gulp-connect'),
      runSequence = require('run-sequence'),
      url = require('url'),
      proxy = require('proxy-middleware');

gulp.task('connect', function () {
    var proxyOptions = url.parse('http://localhost:8080/api');
    proxyOptions.route = '/api';

    connect.server({
        root: distDir,
        host: 'localhost',
        port: 3000,
        livereload: true,
        middleware: function() {
            return [proxy(proxyOptions)];
        }
    });
});

as you can see my express REST Service is running on localhost:8080 and the service is working. I tried an ajax call to localhost:3000/api/whatever but the proxy will not work. I can't see the error.

Server manually closed but still getting errors from the proxy

I manually closed the express server with server.close(), yet the proxy throws an error. I guess the proxy is not listening to the server's shutdown process?

Error: connect ECONNREFUSED
    at errnoException (net.js:905:11)
    at afterConnect (net.js:896:19)
---------------------------------------------
    at Readable.on (_stream_readable.js:708:33)
    at http.js:1758:12
    at process._tickDomainCallback (node.js:486:13)
---------------------------------------------
    at ClientRequest.onSocket (http.js:1735:11)
    at Agent.addRequest (http.js:1274:9)
    at new ClientRequest (http.js:1421:16)
    at exports.request (http.js:1848:10)
    at /home/xxx/node_modules/proxy-middleware/index.js:50:17
 ...

POST request non proxyed

Hi,
it seems that POST requests are not proxyed correctly as I see no requests arriving on destination server. The same request works fine from chrome/postman to the destination proxy. Also get requests works fine

BTW I've added this to handle the form data:
var body=req.body;
if (body) {
opts.form=body
}
before

var myReq = request(opts, function (myRes) {

my opts variable contains the following:
{ protocol: 'http:',
slashes: true,
auth: null,
host: '127.0.0.1:4000',
port: '4000',
hostname: '127.0.0.1',
hash: null,
search: null,
query: null,
pathname: '/admin',
path: '/admin/test',
href: 'http://127.0.0.1:4000/admin',
method: 'POST',
headers:
{ connection: 'keep-alive',
'content-length': '263',
'cache-control': 'no-cache',
origin: 'chrome-extension://fdmmgilgnpjigdojojpjoooidkmcomcm',
'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.78 Safari/537.36',
'content-type': 'application/x-www-form-urlencoded',
accept: '/',
'accept-encoding': 'gzip, deflate',
'accept-language': 'it-IT,it;q=0.8,en-US;q=0.6,en;q=0.4',
cookie: ...' },
form:
{ key1: 'value1' } }

do you have any idea about that ?

thanks

giuliano

routes with a trailing '/'

When a route is specified on the options, an extra / is added on the end. So the route specified is not actually matched with the request url if the request url doesn't contain a trailing / also.

var route = slashJoin(options.route, '');
The line turns a specified route like /api/endpointone
into /api/endpointone/

So when the boolean check immediately below is ran on the requested url that we want to proxy its comparing:
"/api/endpointone" === "/api/endpointone/" which is obviously not true.

A realistic and valid use case is to be able to pass in a route with no trailing slash and expect that to match with requested urls with no trailing slash.

Log redirects

It's good in dev mode see how the proxy works, to make debugging much more easy. For now it's black box.

Secure Cookies

Open to a pull request removing the Secure directive from cookies when proxying to http from https?

no method 'use' on connect

connect.use('/api', proxy(url.parse("https://google.com")));
^
TypeError: Object function createServer() {
function app(req, res){ app.handle(req, res); }
utils.merge(app, proto);
utils.merge(app, EventEmitter.prototype);
app.route = '/';
app.stack = [];
for (var i = 0; i < arguments.length; ++i) {
app.use(arguments[i]);
}
return app;
} has no method 'use'
at Object. (/home/projects/node/proxy.js:6:9)
at Module._compile (module.js:449:26)
at Object.Module._extensions..js (module.js:467:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.runMain (module.js:492:10)
at process.startup.processNextTick.process._tickCallback (node.js:244:9)

var connect = require('connect')
, url = require('url')
, proxy = require('proxy-middleware')

var app = connect();
connect.use('/api', proxy(url.parse("https://google.com")));

Not handling the server redirect

Seems like when server sends 302 request, then it's not been handle properly. E.g. as follows,
Client requests URL app/public/page/logon
then server respond with a 302 app/public/page/signup
however location I can see in Chrome developer is //public/page/signup

Can't shrinkwrap 0.8.0

Hey,

For some reason 0.8.0 appears to fail when shrinkwrapped, but 0.7.0 does not. Here's my error log:

0 info it worked if it ends with ok
1 verbose cli [ 'node', '/usr/local/bin/npm', 'shrinkwrap' ]
2 info using [email protected]
3 info using [email protected]
4 error Error: Problems were encountered
4 error Please correct and try again.
4 error invalid: [email protected] /Users/driftyadmin/git/ionic-cli/node_modules/proxy-middleware
4 error     at shrinkwrap_ (/usr/local/lib/node_modules/npm/lib/shrinkwrap.js:30:15)
4 error     at /usr/local/lib/node_modules/npm/lib/shrinkwrap.js:24:5
4 error     at /usr/local/lib/node_modules/npm/lib/ls.js:45:30
4 error     at /usr/local/lib/node_modules/npm/node_modules/read-installed/read-installed.js:130:5
4 error     at /usr/local/lib/node_modules/npm/node_modules/read-installed/read-installed.js:244:14
4 error     at cb (/usr/local/lib/node_modules/npm/node_modules/slide/lib/async-map.js:47:24)
4 error     at /usr/local/lib/node_modules/npm/node_modules/read-installed/read-installed.js:244:14
4 error     at cb (/usr/local/lib/node_modules/npm/node_modules/slide/lib/async-map.js:47:24)
4 error     at /usr/local/lib/node_modules/npm/node_modules/read-installed/read-installed.js:244:14
4 error     at cb (/usr/local/lib/node_modules/npm/node_modules/slide/lib/async-map.js:47:24)
5 error If you need help, you may report this *entire* log,
5 error including the npm and node versions, at:
5 error     <http://github.com/npm/npm/issues>
6 error System Darwin 14.0.0
7 error command "node" "/usr/local/bin/npm" "shrinkwrap"
8 error cwd /Users/driftyadmin/git/ionic-cli
9 error node -v v0.10.33
10 error npm -v 1.4.28
11 verbose exit [ 1, true ]

Proxy sometimes hangs when request is disrupted

We have a single-page-app with several proxies as we migrate off of rails, and we've found that sometimes, when a request hasn't completed (whether it's a proxied request or not, i think) and we make a new request (either by refreshing the page or, say, clicking another part of the page and triggering a new request), the proxy hangs, and we have to restart our server. On a refresh, we see all locally served files, but requests to a proxied server hang without a response. We're running proxy-middleware within browsersync, all within gulp.

If you have any insights about why this might happen, I'm happy to take a look and give a crack at it, but I figured I should post an issue about it to get some feedback first.

Thanks!

Malformed Cookie causes Invalid character in header content ["set-cookie"] error

Problem: I noticed the following error when sending a malformed cookie

TypeError [ERR_INVALID_CHAR]: Invalid character in header content ["set-cookie"]
at storeHeader (_http_outgoing.js:411:5)
at processHeader (_http_outgoing.js:401:9)
at ServerResponse._storeHeader (_http_outgoing.js:312:9)
at ServerResponse.writeHead (_http_server.js:271:8)
at ClientRequest. (/Users/nyeung/Projects/corvette-frontend/node_modules/proxy-middleware/index.js:61:12)
at Object.onceWrapper (events.js:273:13)
at ClientRequest.emit (events.js:182:13)
at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:556:21)
at HTTPParser.parserOnHeadersComplete (_http_common.js:109:17)
at TLSSocket.socketOnData (_http_client.js:442:20).

Proposed Solution: We can either fix by discarding the malformed cookie within `myRes.headers. The browsers are handling malformed cookies as follow:

Chrome:
drops cookies containing \u0001 through \u0019
except \u0000 which is stripped

Firefox:

drops cookies containing \u0000 through \u0019
except \u0000 which terminates the header
except \u0009 (tab) which is retained

Safari:
truncates cookie at character containing \u0000 through \u0019
truncates cookie at character containing \u007f through \u00ff
except \u0009 (tab) which is retained

In index.js I propose we follow Chrome's implementation and add a method cleanHeaderOfMalformedCookies call on line 66 to drop cookies containing those characters. The method would do the following:

  • drop cookies in [\u0000..\u0019]]

X-Forwarded-Host is not passed onto the proxy

I'm using the latest version of this package node-proxy-middleware, proxing all requests with /api to a backend process. listening on another port. It requires the X-Forwarded-Host header.

Somehow this module is not passing on this header. It's missing on the other side.

Does this module copy all the headers?

via header received-by: os.hostname() vs incoming request host

I've noticed that os.hostname() is used to populate the via header's "received-by" section rather than the incoming request url host domain, port. I might be misinterpreting the spec here but I thought the intent of via was to specify the host dns name used to reach the proxy server rather than proxy host machine name.

Consider the following scenario:

I have two dns names pointing to my node webserver which uses node-proxy-middleware

  • customer1.webserver.com -> my-webserver-ip
  • customer2.webserver.com -> my-webserver-ip

if my-webserver-ip uses proxy-middleware to proxy "/api" to "http://my-appserver/api", then my-appserver should be able to use the via header to figure out if the request came via customer1.webserver.com or customer2.webserver.com.

I understand that the preserveHost flag can be used but becoming blind to the proxy shouldn't be necessary.

I can create a PR for this if desired.

URL pattern matching

It would be nice to be able to use patterns for URLs so that this proxy is a little more flexible. Instead of string comparison, minimatch can be used.

middleware doesn't call next() on res.end

I noticed while trying to use this library in a Grunt instance that, when installed on top of other middlewares, the middlewares further down the stack are not executed. Adding a call to next() after the end event seemed to fix the problem. Opened a pull request to fix this issue: #59

websockets support?

Hello,

I really have fun with proxy-middleware. :-)
I want to use websockets (like sockjs) with proxy-middleware. How can I use websockets with proxy-middleware?

Thanks.

Add via header in responses

It doesn't look like the via header is set in responses, which http requires proxies to do. I'll try to make time to fix this tonight and send you a pull request.

Causes weird behaviour when a url without the http:// is not specified

I'm using this with ember-cli and just discovered the following:

This is a low-priority aesthetic thing, but a warning would be nice when an invalid URL type was specified for the proxy. Here is an example of what we get in the console

TypeError: Cannot read property 'length' of null
at slashJoin (/[PATH]/node_modules/ember-cli/node_modules/proxy-middleware/index.js:83:9)

Thanks!

Can You Update The Public Readme?

Your project has the same name as this one - git://github.com/gonsfx/connect-proxy.git. Really confusing as one can end up downloading this version, when using NPM.

/endpoint gets proxied to /endpoint/

I have an endpoint /endpoint which I want to proxy to, however all my requests get redirected to /endpoint/ which doesn't exist.

It is set up like so:
app.use('/endpoint', proxy('http://somehost.com/endpoint'));

The error seems to be somewhere in slashJoin in index.js.

Change repository name to reflect npm package

Firstly, thanks for the awesome middleware.

Secondly, would you consider renaming this repository to "proxy-middleware"? It is a very common practice to have the npmjs and github repo named the same.

I have lost some minutes debugging why this middleware wasn't working, when the problem was I was actually installing http://npmjs.com/package/connect-proxy. I believe this must be a common mistake.

I understand this is a great name, but unless you can get the package owner to move, this difference only creates confusion.

Thanks!

Proper way to setup Gruntfile?

I tried to setup grunt + connect to proxy request to /api into local apache for PHP back-end (i.e http://localhost:9000/api would be proxied to http://localhost:80). But when i requested http://localhost:9000/api it says Cannot GET /api

Below are excerpt from my Gruntfile (generated by yeoman and edited for my project). If required, i can post my full Gruntfile

First i define proxy and proxyOption at top of the file

var url = require('url');
var proxy = require('proxy-middleware');
var proxyOption = url.parse('http://localhost');
proxyOption.route = '/api';

var mountFolder = function (connect, dir) {
    return connect.static(require('path').resolve(dir));
};

Then add the middleware on initConfig

grunt.initConfig({
    connect: {
        options: {
            port: 9000,
            hostname: 'localhost'
        },
        livereload: {
            options: {
                middleware: function(connect) {
                    return [
                        mountFolder(connect, '.tmp'),
                        mountFolder(connect, 'app'),
                        proxy(proxyOption)
                    ]
                }
            }
        }
    }
})

Proxy hangs in new version of Express/Connect

I haven't been able to track down the root cause, but after upgrading to the v3.4.4 of Express, the proxy call appears to be hanging for a period of time that is directly correlated to the socket timeout on the server.

It works on v3.4.0 of Express.

URLs with a '-' do not work for cookieRewrites

We are trying to use your cookieRewrite functionality in order to pass cookies back through our proxy from our staging server to localhost. Our staging URL looks like name-stage.otherName.com, which does not match the regex /(Domain)=[a-z\.-_]*?(;|$)/gi in https://github.com/andrewrk/node-proxy-middleware/blob/master/index.js#L110. This blocks the cookieRewrite from actually happening.

Is there a reason you have excluded URLs with a - in them? If not, please update the regex to match URLs such as myurl-stage.com. I can put out a PR if you want :) we used /(Domain)=[a-z\.-_-]*?(;|$)/gi locally.

proxyOptions.route = '*.go'

Can a glob option be implemented please to proxy for example all *.go files to a backend server?

var proxyOptions = url.parse('https://localhost:8080/');
proxyOptions.route = '*.go';

It will enable to implement a more flexible router for this issue

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.