Fixes #612 - adds HTTP proxy support for `@import` inlining.
authorJule Marcoueille <marcou_j@btc.net>
Fri, 7 Aug 2015 17:34:32 +0000 (19:34 +0200)
committerJakub Pawlowicz <contact@jakubpawlowicz.com>
Sun, 16 Aug 2015 08:57:05 +0000 (09:57 +0100)
By passing a full href to request proxy we can instruct it to
pass the request to the upstream server.

To use a proxy (via API), pass the proxy hostname and port to the
inliner options, e.g.

```javascript
new CleanCSS({
  inliner: {
    request: {
      hostname: 'proxy host',
      port: 'proxy port'
    }
  }
}).minify(...);
```

Specs by @jakubpawlowicz.

History.md
lib/imports/inliner.js
package.json
test/protocol-imports-test.js

index 7488a09..4a20e7f 100644 (file)
@@ -4,6 +4,7 @@
 * Adds unit compatibility switches to disable length optimizations.
 * Unifies wrappers for simple & advanced optimizations.
 * Fixed issue [#599](https://github.com/jakubpawlowicz/clean-css/issues/599) - support for inlined source maps.
+* Fixed issue [#612](https://github.com/jakubpawlowicz/clean-css/issues/612) - adds HTTP proxy support.
 * Fixed issue [#625](https://github.com/jakubpawlowicz/clean-css/issues/625) - adds length unit optimizations.
 * Fixed issue [#644](https://github.com/jakubpawlowicz/clean-css/issues/644) - adds time unit optimizations.
 
index c395589..5d4da38 100644 (file)
@@ -248,6 +248,9 @@ function inlineRemoteResource(importedFile, mediaQuery, context) {
   }
 
   var requestOptions = override(url.parse(importedUrl), context.inliner.request);
+  if (context.inliner.request.hostname !== undefined)
+    requestOptions.path = requestOptions.href;
+
   get(requestOptions, function (res) {
     if (res.statusCode < 200 || res.statusCode > 399) {
       return handleError('error ' + res.statusCode);
index 97b05e7..a243265 100644 (file)
@@ -40,6 +40,7 @@
   },
   "devDependencies": {
     "browserify": "11.x",
+    "http-proxy": "1.x",
     "jshint": "2.8.x",
     "nock": "2.x",
     "server-destroy": "1.x",
index 9af60bb..d6ee816 100644 (file)
@@ -3,8 +3,10 @@
 var vows = require('vows');
 var assert = require('assert');
 var http = require('http');
+var httpProxy = require('http-proxy');
 var enableDestroy = require('server-destroy');
 var nock = require('nock');
+var url = require('url');
 var CleanCSS = require('../index');
 
 var port = 24682;
@@ -492,5 +494,45 @@ vows.describe('protocol imports').addBatch({
       this.server.destroy();
       nock.disableNetConnect();
     }
+  },
+  'of a proxied resource': {
+    topic: function () {
+      this.proxied = false;
+
+      var self = this;
+      var proxy = httpProxy.createProxyServer();
+      this.proxyServer = http.createServer(function (req, res) {
+        self.proxied = true;
+        proxy.web(req, res, { target: 'http://' + url.parse(req.url).host });
+      });
+      this.proxyServer.listen(8080);
+      enableDestroy(this.proxyServer);
+
+      this.reqMocks = nock('http://assets.127.0.0.1')
+        .get('/styles.css')
+        .reply(200, 'a{color:red}');
+
+      var options = {
+        inliner: {
+          request: {
+            hostname: '127.0.0.1',
+            port: 8080
+          }
+        }
+      };
+
+      new CleanCSS(options).minify('@import url(http://assets.127.0.0.1/styles.css);', this.callback);
+    },
+    'proxies the connection': function () {
+      assert.isTrue(this.proxied);
+    },
+    'gets right output': function (errors, minified) {
+      assert.equal(minified.styles, 'a{color:red}');
+    },
+    teardown: function () {
+      assert.isTrue(this.reqMocks.isDone());
+      nock.cleanAll();
+      this.proxyServer.destroy();
+    }
   }
 }).export(module);