tinganho / connect-modrewrite Goto Github PK
View Code? Open in Web Editor NEWModrewrite middleware for connect/express
License: MIT License
Modrewrite middleware for connect/express
License: MIT License
I'm trying to setup a rule that will redirect the /api subdirectory to a development endpoint on port 9000. Unfortunately, it seems like connect-modrewrite strips out the port for some reasons and it keeps requesting from port 80.
Here's the rule:
^/api/(.*)$ http://localhost:9000/$1 [P]
npm show connect-modrewrite | grep repository -A 2
repository:
{ type: 'git',
url: 'git://github.com/%3Atinganho/connect-modrewrite.git' },
repository:
{ type: 'git',
url: 'https://github.com/tinganho/connect-modrewrite.git' },
According to that the repository URL in package.json
may also be modified.
https://www.npmjs.org/package/connect-modrewrite shows 0.6.4-pre, installing the package via npm install connect-modrewrite
installs this version as well. Unstable versions (e.g. those ending with -pre
) shouldn't be tagged as latest so that they're not automatically installed unless the developer explicitely opts in to that.
Hi,
I would be perfect to handle the dash syntax :
- (dash)
A dash indicates that no substitution should be performed (the existing path is passed through untouched). This is used when a flag (see below) needs to be applied without changing the path.
It would be possible to write something like this :
'^/data/(.*)$ - [L]',
instead of
'^/data/(.*)$ /data/$1 [L]'
As of right now the index page works, but none of the internal pages do. Here's Slim's stock .htaccess file:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
Using this directly will load the index page:
rewrite(['%{REQUEST_FILENAME} !-f ^ index.php [QSA,L]'])
Trying to access http://127.0.0.1:9000/news throws a Cannot GET error:
Cannot GET /news
This works slightly better - it will load index.php when you go to /news, but the route doesn't get triggered:
rewrite(['!\\.php|\\.html|\\.js|\\.css|\\.svg|\\.jp(e?)g|\\.png|\\.gif$ /index.php [QSA,L]'])
I think it needs to be a regex pattern like the second example?
I would like to use the following rules to use in conjunction with html5-push-state urls:
# If requested resource exists as a file or directory, skip next two rules
RewriteCond %{DOCUMENT_ROOT}/$1 -f [OR]
RewriteCond %{DOCUMENT_ROOT}/$1 -d
RewriteRule (.*) - [S=2]
#
# Requested resource does not exist, do rewrite if it exists in /archive
RewriteCond %{DOCUMENT_ROOT}/archive/$1 -f [OR]
RewriteCond %{DOCUMENT_ROOT}/archive/$1 -d
RewriteRule (.*) /archive/$1 [L]
#
# Else rewrite requests for non-existent resources to /index.php
RewriteRule (.*) /index.php?q=$1 [L]
How would I apply them using connect-modrewrite
?
I am not sure if it is an issue with connect-modrewrite
or grunt-contrib-connect
plugin...
TypeError: Object /home/[...]/public has no method 'charAt'
at exports.normalize (path.js:336:27)
at SendStream.root.SendStream.from (/home/[...]/node_modules/grunt-contrib-connect/node_modules/connect/node_modules/send/lib/send.js:116:16)
at Object.static (/home/[...]/node_modules/grunt-contrib-connect/node_modules/connect/lib/middleware/static.js:79:8)
at next (/home/[...]/node_modules/grunt-contrib-connect/node_modules/connect/lib/proto.js:190:15)
at Object.handle (/home/[...]/node_modules/connect-modrewrite/src/modrewrite.js:115:7)
at next (/home/[...]/node_modules/grunt-contrib-connect/node_modules/connect/lib/proto.js:190:15)
at Function.app.handle (/home/[...]/node_modules/grunt-contrib-connect/node_modules/connect/lib/proto.js:198:3)
at Server.app (/home/[...]/node_modules/grunt-contrib-connect/node_modules/connect/lib/connect.js:65:37)
at Server.EventEmitter.emit (events.js:98:17)
at HTTPParser.parser.onIncoming (http.js:2045:12)
at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:119:23)
at Socket.socket.ondata (http.js:1935:22)
at TCP.onread (net.js:524:27)
I'm writing a new version of my API and I want to redirect all calls except one to an older version:
app.use(modRewrite([
'/api/1.1/(.)/content(.) /api/1.1/$1/content$2 [L]',
'/api/1.1/(.*) /api/1.0/$1 [L]' //all 1.1 calls except content should be forwarded to 1.0
]))
I'm trying to match the URL I want to ignore and use the [L] flag so the next rule doesn't get processed.
However, when calling the content URL I get this:
GET /api/1.1/users/f76c77d6-3ae9-4350-9e47-08c44253abaf/content?location=CA 304 - - 4080 ms
GET /api/1.1/users/f76c77d6-3ae9-4350-9e47-08c44253abaf/content?location=CA 304 - - 1292 ms
GET /api/1.1/users/f76c77d6-3ae9-4350-9e47-08c44253abaf/content?location=CA 304 - - 3293 ms
GET /api/1.1/users/f76c77d6-3ae9-4350-9e47-08c44253abaf/content?location=CA 304 - - 236 ms
GET /api/1.1/users/f76c77d6-3ae9-4350-9e47-08c44253abaf/content?location=CA 304 - - 277 ms
GET /api/1.1/users/f76c77d6-3ae9-4350-9e47-08c44253abaf/content?location=CA 304 - - 304 ms
GET /api/1.1/users/f76c77d6-3ae9-4350-9e47-08c44253abaf/content?location=CA 304 - - 235 ms
GET /api/1.1/users/f76c77d6-3ae9-4350-9e47-08c44253abaf/content?location=CA 304 - - 275 ms
(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.
Trace
at Request.EventEmitter.addListener (events.js:160:15)
....
Fatal error: Exceeded maxRedirects. Probably stuck in a redirect loop http://localhost:4126/api/1.1/users/f76c77d6-3ae9-4350-9e47-08c44253abaf/content?location=CA
I tried using a negative lookahead regexp but couldn't make it work with this kind of URL.
I might be missing something, but where's the error handling?
I'm using this to have gulp-webserver connect to an API that's running in the background as a separate HTTP server. When it isn't running, I want it to display something like "yo, fire up the API, you fool" instead of a cryptic exception message.
So, I need to catch those exceptions when the proxy part of modrewrite wasn't able to connect.
I'm using connect-modrewrite
with ember.js push state url. I've setup it up with grunt no problems. But it doesn't work with query strings. I'm using oauth authentication from backend. So the callback from the server goes to localhost:9000/callback?auth_token=123
. Everytime the request is passed url gets refreshed to clear the query before ember starts. Is there a way to do that with connect-modrewrite?
i am building an app using angularjs using yeoman. so i had enabled the html5mod and had problem with livereload so i added modRewrite , the moment i added this the gif file i used(from css with relative path) not loading !
when i opened http://localhost:9000/images/ajax-loader.gif in the browser it showes a skinned down view of my index page !
Hi,
it would be great if this module could rewrite the "location" header of a http response. I think that the matching Apache httpd option would be "ProxyPassReverse".
Regards,
Martin
I wanted to do something along the lines of
modRewrite([
'^/.+$ /index.html', //Rewrite all routes to index.html
]),
How do I get this to work ?
"^/(?!api|assets|favicon) /index.html [L]"
it is not rewriting /about to /index.html
It is appending about
to index.html
:
Location: http://localhost:8000/index.htmlabout
Hi there
From my understanding of the module, the httpd mod_rewrite implementation only considers the path when matching the URLs to be rewritten. From http://httpd.apache.org/docs/current/mod/mod_rewrite.html :
In VirtualHost context, The Pattern will initially be matched against the part of the URL after the hostname and port, and before the query string (e.g. "/app1/index.html").
Presently connect-modrewrite matches on both the path and the query string when matching a request URL.
Naturally I'm aware that this is only a partial implementation of mod_rewrite's RewriteRule directive, but this seems like quite a significant derivation from the original implementation. It makes my use case of sharing or porting existing configuration very tricky!
In addition to only matching on the path, it's important for me to support mod_rewrite's behaviour for handling query strings when rewriting URLs. In brief:
My fork of the project contains this commit which pretty much covers the above (minus updates to the documentation)
08de509 : Breaking change: path now only considered when matching rules to bring more in line with mod_rewrite. Add support for QSA flag.
This is a breaking change to the API, so I'd assume it would require a major version increment.
As it is a breaking change, please advise on whether you'd like me to raise a pull request for this or you would prefer me to maintain the fork.
Thanks
I have been using version 0.5.11 with consistent and satisfying performance, for a couple of months now, along with grunt-connect server and livereload as part of the default AngularJS Yeoman generator.
However, the newest version (0.6.2-pre) doesn't work for the following rules, with the middleware
method (syntax below):
connect: {
options: {
port: 80,
// Change this to '0.0.0.0' to access the server from outside.
hostname: yeomanConfig.hostname
},
livereload: {
options: {
middleware: function (connect) {
return [
modRewrite([
'^/srv/(.*)$ http://app.ourdomain.com/srv/$1 [P]',
'!\\.\\w+$ /index.html'
]),
lrSnippet,
mountFolder(connect, '.tmp'),
mountFolder(connect, yeomanConfig.app),
function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', '*');
next();
}
];
}
}
},
...
I'm getting 404s on everything. Reverting to version 0.5.11 restored functionality. Your feedback is appreciated! And thanks for your wonderful script.
It appears redirection hosts are appended to the original host instead of using that host to redirect to.
Take this example:
port: 8887,
livereload: false,
middleware: function () {
return [
$modRewrite([
'/api/(.*) http://localhost:8888/$1 [R]'
])
];
}
This will result in the following location:
localhost:8887localhost:8888/api/booger
Lines 14 and 16 in modrewrite.js need a $ at the end of their regexes to support rules with character classes.
Upon further review, it needs a bit more help, otherwise it's too greedy:
This seems to be working: /[(\w+)]$/
Hey, I've been playing with this plugin for few hours and I could not get it to work the way I wanted so I'm seeking some help. I'm running a simple static website with browsersync and I would like to remove all .html extensions, but everything I try also broke all my css and images. Any idea how could I achieve this?
I have few static pages in my site root and few pages in a posts
subfolder.
Here's what I would like to achieve.
localhost:3000/page.html
-> localhost:3000/page
localhost:3000/contact.html
-> localhost:3000/contact
localhost:3000/posts/post1.html
-> localhost:3000/posts/post1
localhost:3000/posts/post2.html
-> localhost:3000/posts/post2
Let me know if you want me to post some example I tried.
Thanks a lot in advance!
lefoy
I have the following inverted rule:
var middleware = modRewrite(['!/a /b [L]']);
When this gets called with a non matching url with a query, the request.query is set to an empty object.
Example:
/c?q=foo&w=bar
Before the modrewrite middleware is called request.query contains the following as expected:
{q: 'foo', w: 'bar'}
After the middleware is executed for the non matching url, the request.query is {}
This is because of the following code on lines 113-117 of index.js:
// Add to query object
var queryValue = querySyntax.exec(req.url);
if(queryValue) {
req.params = req.query = querystring.parse(queryValue[1]);
}
Which gets executed for every request, wether it's matching or not. I'm not sure what this piece of code is supposed to do so I didn't make a pull request with the fix.
One of tests does not fire because of missing "done" callback argument:
it('should be able to recognize Last [L] flag', function(done){
Unfortunetely, it fails when I add missing parameter :(
I have the following configuration:
modRewrite([
'^/accounts/(.*)$ http://ANOTHER_URL/accounts/$1 [P]',
]),
And when I go to http://localhost:8500/accounts/static/css/styles.css
, the server gets http://ANOTHER_URL/accounts/static/css/styles.css/
, i.e. the trailing slash gets added which causes the URL to return 404 instead of a proper styles file.
I'm posting this issue to let you know that we will be publishing Grunt 0.4 on Monday, February 18th.
If your plugin is not already Grunt 0.4 compatible, would you please consider updating it? For an overview of what's changed, please see our migration guide.
If you'd like to develop against the final version of Grunt before Monday, please specify "grunt": "0.4.0rc8"
as a devDependency in your project. After Monday's release, you'll be able to use "grunt": "~0.4.0"
to actually publish your plugin. If you depend on any plugins from the grunt-contrib series, please see our list of release candidates for compatible versions. All of these will be updated to final status when Grunt 0.4 is published.
Also, in an effort to reduce duplication of effort and fragmentation in the developer community, could you review the grunt-contrib series of plugins to see if any of your functionality overlaps significantly with them? Grunt-contrib is community maintained with 40+ contributors—we'd love to discuss any additions you'd like to make.
Finally, we're working on a new task format that doesn't depend on Grunt: it's called node-task. Once this is complete, there will be one more conversion, and then we'll never ask you to upgrade your plugins to support our changes again. Until that happens, thanks for bearing with us!
If you have any questions about how to proceed, please respond here, or join us in #grunt on irc.freenode.net.
Thanks, we really appreciate your work!
I get this error when I start the server with "grunt serve". I don't have express installed.
I fixed it by replacing req.header('x-forwarded-proto')
with req.headers['x-forwarded-proto']
.
Stacktrace:
TypeError: Object #<IncomingMessage> has no method 'header'
at Object.handle (/Users/arbeit/nosleep/distributionstool-client/node_modules/connect-modrewrite/index.js:21:52)
at next (/Users/arbeit/nosleep/distributionstool-client/node_modules/grunt-contrib-connect/node_modules/connect/lib/proto.js:193:15)
at Object.livereload [as handle] (/Users/arbeit/nosleep/distributionstool-client/node_modules/grunt-contrib-connect/node_modules/connect-livereload/index.js:147:5)
at next (/Users/arbeit/nosleep/distributionstool-client/node_modules/grunt-contrib-connect/node_modules/connect/lib/proto.js:193:15)
at Function.app.handle (/Users/arbeit/nosleep/distributionstool-client/node_modules/grunt-contrib-connect/node_modules/connect/lib/proto.js:201:3)
at Server.app (/Users/arbeit/nosleep/distributionstool-client/node_modules/grunt-contrib-connect/node_modules/connect/lib/connect.js:65:37)
at Server.EventEmitter.emit (events.js:98:17)
at HTTPParser.parser.onIncoming (http.js:2108:12)
at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:121:23)
at Socket.socket.ondata (http.js:1966:22)
at TCP.onread (net.js:525:27)
$n replacement does not appear to be working
Input URL is: /somevar/img/sprite.png
Real File is: /img/sprite.png
"^/[^/]+(/img/sprite.png) /img/sprite.png [L]" - Works
"^/[^/]+(/img/sprite.png) $1 [L]" - 404s
"^/[^/]+/(img/sprite.png) /$1 [L]" - 404s
Ideas?
Hi! I have the next path in a Angular application:
.state('signup', { url: '/signup/invite/{code:[0-9a-fA-F]{64}}?email&name' });
The thing is to access this using HTML5 mode I added the next config (the same as everyone in the internet) to Grunt to serve the application with modrewrite:
var modRewrite = require('connect-modrewrite');
var serveStatic = require('serve-static');
connect: {
...
middleware: function (connect, options) {
var middlewares = [];
middlewares.push(modRewrite(['!(\\..+)$ / [L]']));
options.base.forEach(function(base) {
middlewares.push(connect().use(serveStatic(base)));
});
return middlewares;
}
...
}
But then, when I have a URL like: http://localhost:9000/signup/invite/72fa78cbe19327a61cc0ea992f0e341f8cb78266cd248df6cd6650341cf5d4b8?email=example@example.com&name=Its+me+Mario
the redirection fails. At first I though it was something in the configuration, but then I started playing with the query string params until I removed the @
and everything goes well.
So, the question is, how could I trace this error and understand better how modrewrite is handling this cases, to fixit or to avoid it.
I've got node 0.10.15, connect 2.8.5 and connect-modrewrite 0.5.4 installed and can't get the proxy example to work:
var connect = require('connect');
var modRewrite = require('connect-modrewrite');
var app = connect()
.use(modRewrite([
'^/test/proxy/(.*)$ http://nodejs.org/$1 [P]'
]))
.use(connect.logger('dev'))
.use(connect.static(__dirname))
.listen(3000)
I then run this server.js using
$ node server.js
Connect works for other files, just returns a 404 for the proxy example.
I can't figure out how to debug this (new to node) - the logger doesn't show the rewritten paths?
Other simple rewrites work ok, I think it's just not capturing that (.*) group?
Your npm package is still called: grunt-contrib-connect-modrewrite
. Can you please rename it too?
The in coming url is like
http://localhost:8080/test/bower_components/bootstrap/dist/css/bootstrap.css
I need to write a proxy such as all urls starting with /test/bower_components should be rewritten such as to remove /test from the url.
http://localhost:8080/bower_components/bootstrap/dist/css/bootstrap.css
Any help please
Looks like the proxying doesn't work with SSL targets, if the express server is not also running on SSL.
I have the below setup
app.use(modRewrite([
'^/imgproxy\\?url=(.*)$ https://i.embed.ly/1/image?key=XXX&url=$1 [P]'
]));
Error: Protocol:https: not supported.
at exports.request (http.js:1730:11)
at _proxy (/Users/zohebsait/wi/frontend/node_modules/connect-modrewrite/index.js:157:14)
at /Users/zohebsait/wi/frontend/node_modules/connect-modrewrite/index.js:63:9
at Array.some (native)
at Object.module.exports [as handle] (/Users/zohebsait/wi/frontend/node_modules/connect-modrewrite/index.js:24:11)
at next (/Users/zohebsait/wi/frontend/node_modules/express/node_modules/connect/lib/proto.js:190:15)
at pass (/Users/zohebsait/wi/frontend/node_modules/express/lib/router/index.js:110:24)
at Router._dispatch (/Users/zohebsait/wi/frontend/node_modules/express/lib/router/index.js:173:5)
at Object.router (/Users/zohebsait/wi/frontend/node_modules/express/lib/router/index.js:33:10)
at next (/Users/zohebsait/wi/frontend/node_modules/express/node_modules/connect/lib/proto.js:190:15)
The node.js server running the above proxy is running on http, however the target server is https.
Is this a known issue or am I missing something?
Right now there isn't a test for
'^/test-flag-2$ /connection-2',
'^/connection-2$ /index.html'
I'm using the following configuration:
gulp.task('browser-sync', function () {
browserSync({
port: 8000,
open: false,
minify: false,
host: "127.0.0.1",
server: {
baseDir: ["app", ".tmp"],
middleware: [
modRewrite([
'^[^\\.]*$ /index.html [L]'
])
]
}
});
});
It works fine, but when I open a URL with query parameters, for ex. http://localhost:8000/change-password?passwordResetToken=abc
, I get the 404 error.
For dev use on one of our Javascript applications, we use gulp-connect as local server with connect-modrewrite to proxy to backend APIs. The local connect server running on localhost uses http as individual devs do not have SSL setup on their machines. The backend services which they connect to use HTTPS.
e.g. our rewrite rules are as follows
http://localhost/my-backend-api/ -> https://my-backend-api.example.com/
^/my-backend-api/(.*)$ https://my-backend-api.example.com/$1 [P]
In 0.8.2 this worked, but as of 0.8.3 it no longer does. Is this an intentional change? See the error below.
Error: Protocol "http:" not supported. Expected "https:".
at new ClientRequest (_http_client.js:75:11)
at Object.exports.request (http.js:49:10)
at exports.request (https.js:136:15)
at _proxy (/Users/tonyfinn/aop/ui-modules/tactic-workflow/node_modules/aopui-common/node_modules/connect-modrewrite/index.js:200:14)
at /Users/tonyfinn/aop/ui-modules/tactic-workflow/node_modules/aopui-common/node_modules/connect-modrewrite/index.js:93:9
at Array.some (native)
at Object.handle (/Users/tonyfinn/aop/ui-modules/tactic-workflow/node_modules/aopui-common/node_modules/connect-modrewrite/index.js:41:11)
at next (/Users/tonyfinn/aop/ui-modules/tactic-workflow/node_modules/aopui-common/node_modules/gulp-connect/node_modules/connect/lib/proto.js:174:15)
at Function.app.handle (/Users/tonyfinn/aop/ui-modules/tactic-workflow/node_modules/aopui-common/node_modules/gulp-connect/node_modules/connect/lib/proto.js:182:3)
at Server.app (/Users/tonyfinn/aop/ui-modules/tactic-workflow/node_modules/aopui-common/node_modules/gulp-connect/node_modules/connect/lib/connect.js:67:37)
at Server.emit (events.js:129:20)
at HTTPParser.parserOnIncoming [as onIncoming] (_http_server.js:491:12)
at HTTPParser.parserOnHeadersComplete (_http_common.js:111:23)
at Socket.socketOnData (_http_server.js:343:22)
at Socket.emit (events.js:107:17)
at readableAddChunk (_stream_readable.js:163:16)
When I do this:
npm install connect-modrewrite
I'm getting this:
npm WARN package.json [email protected] No repository field.
npm WARN package.json [email protected] No readme data.
npm http GET https://registry.npmjs.org/connect-modrewrite
npm http 304 https://registry.npmjs.org/connect-modrewrite
npm WARN package.json [email protected] No repository field.
npm WARN package.json [email protected] No repository field.
npm WARN package.json [email protected] No repository field.
npm WARN package.json [email protected] No repository field.
npm WARN package.json [email protected] No repository field.
npm WARN package.json [email protected] No repository field.
npm WARN package.json [email protected] No repository field.
npm WARN package.json [email protected] No repository field.
npm WARN package.json [email protected] 'repositories' (plural) Not supported.
npm WARN package.json Please pick one as the 'repository' field
npm WARN package.json [email protected] No repository field.
npm WARN package.json [email protected] No repository field.
npm WARN package.json [email protected] No repository field.
npm WARN package.json [email protected] 'repositories' (plural) Not supported.
npm WARN package.json Please pick one as the 'repository' field
Gruntjs seemed to have a similar problem and fixed it by changing the dependencies to make them compatible with the latest SME sever. I don't know if that solution could also fix this issue.
Hello,
this is not issue but question.
Is there a way how to do something with request before it is proxied to other resource?
app.use(modRewrite([`^/api/(.*)$ some.other.api/$1 [P]`]))
When I do request /api/something
with cookie username and token I need to use this cookie to generate Authorization header.
update method should look like:
app.use(cookieParser())
function addAuthorizationHeaderFromCookie(req) {
var cookies = cookieDough(req)
var username = cookies.get('username')
var token = cookies.get('token')
req.headers.set('Authorization', Base64.encode(`${username}:${token}`))
return req
}
0.10.2 was published to npm, but I can't find it reflected in this repo. Hopefully I'm just missing it, and this was not a malicious publish. Please confirm the status, thanks.
I need to do some type of an inverted rule like I can do with traditional modrewrite with a !
Something like: ['!^/js|css|partials|libs/.*$ /index.html] which sadly does not work.
This would allow for optimal html5 pushState usage and application 404 delegation with clean urls by saying "Hijack ALL the things to redirect to /index.html unless it is css,js,partials,libs in which case ignore and route as usual"
Is this possible?
Would it be possible to populate the request_uri and the query_string like apache does? With this feature it would be possible to serve php that runs with apache modrewrite.
^/$ /.index.html
does not work for me: throws a "Cannot GET /".
^/$ /index.html
works fine.
Am I missing something here?
Thanks!
Is there a way that I can add RewriteCond or I can only add rewrite rules?
Thanks
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.