Giter VIP home page Giter VIP logo

node-unblocker's Introduction

unblocker

Unblocker was originally a web proxy for evading internet censorship, similar to CGIproxy / PHProxy / Glype but written in node.js. It's since morphed into a general-purpose library for proxying and rewriting remote webpages.

All data is processed and relayed to the client on the fly without unnecessary buffering, making unblocker one of the fastest web proxies available.

Node.js CI npm-version

The magic part

The script uses "pretty" urls which, besides looking pretty, allow links with relative paths to just work without modification. (E.g. <a href="path/to/file2.html"></a>)

In addition to this, links that are relative to the root (E.g. <a href="/path/to/file2.html"></a>) can be handled without modification by checking the referrer and 307 redirecting them to the proper location in the referring site. (Although the proxy does attempt to rewrite these links to avoid the redirect.)

Cookies are proxied by adjusting their path to include the proxy's URL, and a bit of extra work is done to ensure they remain intact when switching protocols or subdomains.

Limitations

Although the proxy works well for standard login forms and even most AJAX content, OAuth login forms and anything that uses postMessage (Google, Facebook, etc.) are not likely to work out of the box. This is not an insurmountable issue, but it's not one that I expect to have fixed in the near term.

More advanced websites, such as Roblox, Discord, YouTube*, Instagram, etc. do not currently work. At the moment, there is no timeframe for when these might be supported.

Patches are welcome, including both general-purpose improvements to go into the main library, and site-specific fixes to go in the examples folder.

Running the website on your computer

See https://github.com/nfriedly/nodeunblocker.com

Using unblocker as a library in your software

npm install --save unblocker

Unblocker exports an express-compatible API, so using in an express application is trivial:

var express = require('express')
var Unblocker = require('unblocker');
var app = express();
var unblocker = new Unblocker({prefix: '/proxy/'});

// this must be one of the first app.use() calls and must not be on a subdirectory to work properly
app.use(unblocker);

app.get('/', function(req, res) {
    //...
});

// the upgrade handler allows unblocker to proxy websockets
app.listen(process.env.PORT || 8080).on('upgrade', unblocker.onUpgrade);

See examples/simple/server.js for a complete example.

Usage without express is similarly easy, see examples/simple/server.js for an example.

Configuration

Unblocker supports the following configuration options, defaults are shown:

{
    prefix: '/proxy/',  // Path that the proxied URLs begin with. '/' is not recommended due to a few edge cases.
    host: null, // Host used in redirects (e.g `example.com` or `localhost:8080`). Default behavior is to determine this from the request headers.
    requestMiddleware: [], // Array of functions that perform extra processing on client requests before they are sent to the remote server. API is detailed below.
    responseMiddleware: [], // Array of functions that perform extra processing on remote responses before they are sent back to the client. API is detailed below.
    standardMiddleware: true, // Allows you to disable all built-in middleware if you need to perform advanced customization of requests or responses.
    clientScripts: true, // Injects JavaScript to force things like WebSockets and XMLHttpRequest to go through the proxy.
    processContentTypes: [ // All  built-in middleware that modifies the content of responses limits itself to these content-types.
        'text/html',
        'application/xml+xhtml',
        'application/xhtml+xml',
        'text/css'
    ],
    httpAgent: null, //override agent used to request http response from server. see https://nodejs.org/api/http.html#http_class_http_agent
    httpsAgent: null //override agent used to request https response from server. see https://nodejs.org/api/https.html#https_class_https_agent
}

Setting process.env.NODE_ENV='production' will enable more aggressive caching on the client scripts and potentially other optimizations in the future.

Custom Middleware

Unblocker "middleware" are small functions that allow you to inspect and modify requests and responses. The majority of Unblocker's internal logic is implimented as middleware, and it's possible to write custom middleware to augment or replace the built-in middleware.

Custom middleware should be a function that accepts a single data argument and runs synchronously.

To process request and response data, create a Transform Stream to perform the processing in chunks and pipe through this stream. (Example below.)

To respond directly to a request, add a function to config.requestMiddleware that handles the clientResponse (a standard http.ServerResponse when used directly, or a Express Response when used with Express. Once a response is sent, no further middleware will be executed for that request. (Example below.)

requestMiddleware

Data example:

{
    url: 'http://example.com/',
    clientRequest: {request},
    clientResponse: {response},
    headers: {
        //...
    },
    stream: {ReadableStream of data for PUT/POST requests, empty stream for other types}
}

requestMiddleware may inspect the headers, url, etc. It can modify headers, pipe PUT/POST data through a transform stream, or respond to the request directly. If you're using express, the request and response objects will have all of the usual express goodies. For example:

function validateRequest(data) {
    if (!data.url.match(/^https?:\/\/en.wikipedia.org\//)) {
        data.clientResponse.status(403).send('Wikipedia only.');
    }
}
var config = {
    requestMiddleware: [
        validateRequest
    ]
}

If any piece of middleware sends a response, no further middleware is run.

After all requestMiddleware has run, the request is forwarded to the remote server with the (potentially modified) url/headers/stream/etc.

responseMiddleware

responseMiddleware receives the same data object as the requestMiddleware, but the headers and stream fields are replaced with those of the remote server's response, and several new fields are added for the remote request and response:

Data example:

{
    url: 'http://example.com/',
    clientRequest: {request},
    clientResponse: {response},
    remoteRequest {request},
    remoteResponse: {response},
    contentType: 'text/html',
    headers: {
        //...
    },
    stream: {ReadableStream of response data}
}

For modifying content, create a new stream and then pipe data.stream to it and replace data.stream with it:

var Transform = require('stream').Transform;

function injectScript(data) {
    if (data.contentType == 'text/html') {

        // https://nodejs.org/api/stream.html#stream_transform
        var myStream = new Transform({
            decodeStrings: false,
            function(chunk, encoding, next) {
                chunk = chunk.toString.replace('</body>', '<script src="/my/script.js"></script></body>');
                this.push(chunk);
                next();
                }
        });

        data.stream = data.stream.pipe(myStream);
    }
}

var config = {
    responseMiddleware: [
        injectScript
    ]
}

See examples/nodeunblocker.com/app.js for another example of adding a bit of middleware. Also, see any of the built-in middleware in the lib/ folder.

Built-in Middleware

Most of the internal functionality of the proxy is also implemented as middleware:

  • host: Corrects the host header in outgoing responses
  • referer: Corrects the referer header in outgoing requests
  • cookies: Fixes the Path attribute of set-cookie headers to limit cookies to their "path" on the proxy (e.g. Path=/proxy/http://example.com/). Also injects redirects to copy cookies from between protocols and subdomains on a given domain.
  • hsts: Removes Strict-Transport-Security headers because they can leak to other sites and can break the proxy.
  • hpkp: Removes Public-Key-Pinning headers because they can leak to other sites and can break the proxy.
  • csp: Removes Content-Security-Policy headers because they can leak to other sites and can break the proxy.
  • redirects: Rewrites urls in 3xx redirects to ensure they go through the proxy
  • decompress: Decompresses Content-Encoding: gzip|deflate responses and also tweaks request headers to ask for either gzip-only or no compression at all. (It will attempt to decompress deflate content, but there are some issues, so it does not advertise support for deflate.)
  • charsets: Converts the charset of responses to UTF-8 for safe string processing in node.js. Determines charset from headers or meta tags and rewrites all headers and meta tags in outgoing response.
  • urlPrefixer: Rewrites URLS of links/images/css/etc. to ensure they go through the proxy
  • metaRobots: Injects a ROBOTS: NOINDEX, NOFOLLOW meta tag to prevent search engines from crawling the entire web through the proxy.
  • contentLength: Deletes the content-length header on responses if the body was modified.

Setting the standardMiddleware configuration option to false disables all built-in middleware, allowing you to selectively enable, configure, and re-order the built-in middleware.

This configuration would mimic the defaults:

var Unblocker = require('unblocker');

var config = {
    prefix: '/proxy/',
    host: null,
    requestMiddleware: [],
    responseMiddleware: [],
    standardMiddleware: false,  // disables all built-in middleware
    processContentTypes: [
        'text/html',
        'application/xml+xhtml',
        'application/xhtml+xml'
    ]
}

var host = Unblocker.host(config);
var referer = Unblocker.referer(config);
var cookies = Unblocker.cookies(config);
var hsts = Unblocker.hsts(config);
var hpkp = Unblocker.hpkp(config);
var csp = Unblocker.csp(config);
var redirects = Unblocker.redirects(config);
var decompress = Unblocker.decompress(config);
var charsets = Unblocker.charsets(config);
var urlPrefixer = Unblocker.urlPrefixer(config);
var metaRobots = Unblocker.metaRobots(config);
var contentLength = Unblocker.contentLength(config);

config.requestMiddleware = [
    host,
    referer,
    decompress.handleRequest,
    cookies.handleRequest
    // custom requestMiddleware here
];

config.responseMiddleware = [
    hsts,
    hpkp,
    csp,
    redirects,
    decompress.handleResponse,
    charsets,
    urlPrefixer,
    cookies.handleResponse,
    metaRobots,
    // custom responseMiddleware here
    contentLength
];

var unblocker = new Unblocker(config);
app.use(unblocker);

// ...

// the upgrade handler allows unblocker to proxy websockets
app.listen(process.env.PORT || 8080).on('upgrade', unblocker.onUpgrade);

Debugging

Unblocker is fully instrumented with debug. Enable debugging via environment variables:

DEBUG=unblocker:* node mycoolapp.js

There is also a middleware debugger that adds extra debugging middleware before and after each existing middleware function to report on changes. It's included with the default DEBUG activation and may also be selectively enabled:

DEBUG=unblocker:middleware node mycoolapp.js

... or disabled:

DEBUG=*,-unblocker:middleware node mycoolapp.js

Troubleshooting

If you're using Nginx as a reverse proxy, you probably need to disable merge_slashes to avoid endless redirects and/or other issues:

merge_slashes off;

Todo

  • Consider adding compress middleware to compress text-like responses
  • Un-prefix urls in GET / POST data
  • Inject js to proxy postMessage data and fix origins
  • More examples
  • Even more tests

AGPL-3.0 License

This project is released under the terms of the GNU Affero General Public License version 3.

All source code is copyright Nathan Friedly.

Commercial licensing and support are also available, contact Nathan Friedly ([email protected]) for details.

Contributors

node-unblocker's People

Contributors

codeseer avatar dependabot[bot] avatar emilhem avatar greenkeeperio-bot avatar hellais avatar nfriedly avatar piman51277 avatar tfmen avatar weibeu avatar

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  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

node-unblocker's Issues

Charset troubles

In file charsets.js i find one problem for my proxy. Into snippet:

        var charset = contentTypes.getCharset(data);

        // todo: consider just rewriting headers and meta tags to utf8 instead of reencoding things
        if (iconv.encodingExists(charset)) {
            // happy case, we know the encoding right away, so we can just return decode/recode streams
            data.charset = charset;
            data.stream = data.stream.pipe(iconv.decodeStream(charset));
            debug('decoding %s charset via iconv stream', charset);
        } else if (mayContainMeta(data.contentType)) {
            debug('decoding unknown charset via iconv html stream');
            data.charsetDecoder = new IconvHtmlStream();
            data.charsetDecoder.on('charset', function(charset) {
                // note: while the recode stream will accept content before this and just output utf-8, it shouldn't actually receive any data because the decode stream buffers until *after* this event
                data.charset = charset;
            });
            data.stream = data.stream.pipe(data.charsetDecoder);
        } else {
            debug('no charset info available, assuming utf8');
            // semi-happy case. we know the content needs parsed but have no way of knowing it's charset. Hopefully .toString() will be good enough. No recoding
            data.stream = data.stream.pipe(new PassThrough({
                encoding: 'utf8'
            }));
        }

When charset = undefined, executing snippet in else if block. But in this case, stream hang up on this place = > data.charsetDecoder.on('charset', ...).

For resolving this trouble I add new condition into if ... else ... processing:
if (charset && iconv.encodingExists(charset)) { ... }
else if(charset && mayContainMeta(data.contentType)){ ... }
else { ... }

If u have best idea for this trouble, please, add your resolve in next commit

Sorry for my english)

<meta http-equiv="refresh"... not parsed

I tested this site that used IPv6. If you don't have IPv6 it returns a page with the following (only):

<META HTTP-EQUIV="Refresh" CONTENT="0;URL=http://support.bredbandskollen.se/support/solutions/articles/1000212163-vad-r-ipv6-och-hur-fungerar-bredbandskollen-ver-ipv6">

Headers:

HTTP/1.1 200 OK
Date: Mon, 11 Jul 2016 14:24:35 GMT
Server: Apache/2.2.22 (Debian)
X-Powered-By: PHP/5.4.45-0+deb7u2
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 157
Content-Type: text/html

This is the page that does this: http://ipv6.bredbandskollen.se/

The issue is that the url parsing doesn't catch this one even though the content-type is text/html...

Internationalized domainnames results in breaking up the domainname

When going to domains with internationalized domainnames such as http://www.vårdverktyget.se/ it causes unblocker to redirect to http://www.v/årdverktyget.se/ instead making unblocker trying to connect to the domain www.v instead of www.xn--vrdverktyget-tcb.se.

I might look into this at a later time unless you get to it first.

Look into Punycode: https://en.wikipedia.org/wiki/Punycode

Possible module: https://www.npmjs.com/package/punycode

https:// requests are redirected to http://

The following HTTPS url loads without problems:

https://www.optimcore.com/proxy/http://example.com/

However if the final trailing slash is omitted the request is redirected to HTTP

https://www.optimcore.com/proxy/http://example.com -> http://www.optimcore.com/proxy/http://example.com/

Redirects like these cause Mixed Content errors on HTTPS pages such the below error when requesting:

https://www.optimcore.com/proxy/http://www.bbc.co.uk/

Mixed Content: The page at 'https://www.optimcore.com/proxy/http://www.bbc.co.uk/' was loaded over HTTPS, but requested an insecure script 'http://www.optimcore.com/proxy/https://fig.bbc.co.uk/frameworks/fig/1/fig.js'. This request has been blocked; the content must be served over HTTPS.

proxy gets in a loop when you click the sign in button on plus.google.com

Gatling not found

Your install instructions seem to be missing a step

npm start

npm ERR! [email protected] start: `gatling ./app.js`
(...)
npm ERR! Tell the Author that this fails on your system:
npm ERR!     gatling ./app.js

Installing gatling fixes the issue, but I thought I'd mention it.

An Other broken Page

http://node-unblocker.herokuapp.com/proxy/http://www.pocketgamer.biz/r/PG.Biz/PocketGamer.biz/feature.asp?c=56325

Hey,
I found another broken page. The images don't load. Maybe U should add a functionallity so that one can report the page directly to u via email. Or that u have a form in Which u enter your deatails and automatically get ya issues which u then can post to github.

Spruce

V1.0 trouble with npm start

Greetings,

Trying to install and run from git or zip download on Linux Mint 17.1 32bit , npm install appears to run ok:

lmint@lmint-VirtualBox ~/scratch/node-unblocker-master/examples/nodeunblocker.com $ sudo npm install
npm WARN engine [email protected]: wanted: {"node":"0.12.x","npm":"2.7.x"} (current: {"node":"0.12.5","npm":"2.11.2"})
[email protected] node_modules/express
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected] ([email protected])
├── [email protected] ([email protected])
├── [email protected] ([email protected])
├── [email protected] ([email protected], [email protected])
├── [email protected] ([email protected], [email protected], [email protected], [email protected], [email protected])
├── [email protected] ([email protected], [email protected])
└── [email protected] ([email protected], [email protected])

[email protected] node_modules/gatling
└── [email protected] ([email protected], [email protected])

[email protected] node_modules/unblocker
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected] ([email protected])
├── [email protected]
└── [email protected]

[email protected] node_modules/newrelic

However npm start does not fair so well:
lmint@lmint-VirtualBox ~/scratch/node-unblocker-master/examples/nodeunblocker.com $ sudo npm start

[email protected] start /home/lmint/scratch/node-unblocker-master/examples/nodeunblocker.com
./node_modules/gatling/gatling.js ./app.js

module.js:338
throw err;
^
Error: Cannot find module 'through'
at Function.Module._resolveFilename (module.js:336:15)
at Function.Module._load (module.js:278:25)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at Object. (/home/lmint/scratch/node-unblocker-master/examples/nodeunblocker.com/app.js:16:15)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)

npm ERR! Linux 3.13.0-37-generic
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "start"
npm ERR! node v0.12.5
npm ERR! npm v2.11.2
npm ERR! code ELIFECYCLE
npm ERR! [email protected] start: ./node_modules/gatling/gatling.js ./app.js
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] start script './node_modules/gatling/gatling.js ./app.js'.
npm ERR! This is most likely a problem with the nodeunblocker.com package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! ./node_modules/gatling/gatling.js ./app.js
npm ERR! You can get their info via:
npm ERR! npm owner ls nodeunblocker.com
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR! /home/lmint/scratch/node-unblocker-master/examples/nodeunblocker.com/npm-debug.log

Here is teh output of the log file:

lmint@lmint-VirtualBox ~/scratch/node-unblocker-master/examples/nodeunblocker.com $ cat /home/lmint/scratch/node-unblocker-master/examples/nodeunblocker.com/npm-debug.log
0 info it worked if it ends with ok
1 verbose cli [ '/usr/local/bin/node', '/usr/local/bin/npm', 'start' ]
2 info using [email protected]
3 info using [email protected]
4 verbose run-script [ 'prestart', 'start', 'poststart' ]
5 info prestart [email protected]
6 info start [email protected]
7 verbose unsafe-perm in lifecycle true
8 info [email protected] Failed to exec start script
9 verbose stack Error: [email protected] start: ./node_modules/gatling/gatling.js ./app.js
9 verbose stack Exit status 1
9 verbose stack at EventEmitter. (/usr/local/lib/node_modules/npm/lib/utils/lifecycle.js:213:16)
9 verbose stack at EventEmitter.emit (events.js:110:17)
9 verbose stack at ChildProcess. (/usr/local/lib/node_modules/npm/lib/utils/spawn.js:24:14)
9 verbose stack at ChildProcess.emit (events.js:110:17)
9 verbose stack at maybeClose (child_process.js:1015:16)
9 verbose stack at Process.ChildProcess._handle.onexit (child_process.js:1087:5)
10 verbose pkgid [email protected]
11 verbose cwd /home/lmint/scratch/node-unblocker-master/examples/nodeunblocker.com
12 error Linux 3.13.0-37-generic
13 error argv "/usr/local/bin/node" "/usr/local/bin/npm" "start"
14 error node v0.12.5
15 error npm v2.11.2
16 error code ELIFECYCLE
17 error [email protected] start: ./node_modules/gatling/gatling.js ./app.js
17 error Exit status 1
18 error Failed at the [email protected] start script './node_modules/gatling/gatling.js ./app.js'.
18 error This is most likely a problem with the nodeunblocker.com package,
18 error not with npm itself.
18 error Tell the author that this fails on your system:
18 error ./node_modules/gatling/gatling.js ./app.js
18 error You can get their info via:
18 error npm owner ls nodeunblocker.com
18 error There is likely additional logging output above.
19 verbose exit [ 1, true ]

Any ideas?
Thanks.

cookies

node-unblocker starting well but when i try login any website facebook - twitter etc. website alert your browser does not support cookies please open cookies bla bla bla.

i am trying cookies on your unblocker, its works well. source code and your unblocker files are different or i lost sometings ?

Website Not Working

Hey,
This Website doesn't work on the heroku version at least. haven't had the time to setup one myself.

http://node-unblocker.herokuapp.com/proxy/http://us.battle.net/sc2/en/forum/topic/11040734962 

Maybe You can look into that?

Not working behind nginx reverse proxy

Hi! great project.

I'm having an issue where the proxy works fine with the url, but fails when placed behind a reverse proxy.
I get 'Oops, there was a problem!'

my nginx config is very basic:

server {
    listen 80;
    server_name proxy.site.com;
    keepalive_timeout 15m;

    location / {
            proxy_pass http://192.168.1.157:8080/;

    }

    location /robots.txt {
    return 200 "User-agent: *\nDisallow: /";
    }

}

I get in the terminal log:

error TypeError: Cannot read property 'split' of null
    at registeredDomain (/root/node-unblocker/proxy/node_modules/unblocker/node_modules/tld/lib/tld.js:80:23)
    at Object.exports.registered (/root/node-unblocker/proxy/node_modules/unblocker/node_modules/tld/lib/tld.js:120:12)
    at rewriteCookiesAndLinks (/root/node-unblocker/proxy/node_modules/unblocker/lib/cookies.js:97:27)
    at /root/node-unblocker/proxy/node_modules/unblocker/lib/proxy.js:66:13
    at arraySome (/root/node-unblocker/proxy/node_modules/unblocker/node_modules/lodash/index.js:1493:13)
    at Function.some (/root/node-unblocker/proxy/node_modules/unblocker/node_modules/lodash/index.js:7051:14)
    at proxyResponse (/root/node-unblocker/proxy/node_modules/unblocker/lib/proxy.js:65:43)
    at ClientRequest.<anonymous> (/root/node-unblocker/proxy/node_modules/unblocker/lib/proxy.js:42:17)
    at ClientRequest.g (events.js:260:16)
    at emitOne (events.js:77:13)

Implement some sort of URL "garbling"

I will admit, I definitely agree that the fact that URLs do not need to be altered aside from changing the site root is wonderful! While I would absolutely love to be able to use node-unblocker like this, it is unfortunately detected by the web filtering in use at my workplace. When I use the "encode URLs" feature offered by Glype, I have no issues, but it will be blocked just the same if I don't use that feature.

If there is any way to make it so that the URLs are able to be more random, or a way to exclude the indicators that I am accessing another domain name (like the http:// and .com parts in the URL), that would be absolutely lovely!

Website with JS genereting links

Hey again,
this Website also breaks the proxy in the way, that links point to the wrong location:

http://node-unblocker.herokuapp.com/proxy/http://www.bytebybytesolutions.com/BBB/Blog/Blog.html

Every Blogpost is linking to a link like this

http://node-unblocker.herokuapp.com/proxy/http://www.bytebybytesolutions.com/BBB/Blog/http://bytebybytesolutions.com/BBB/Blog/Entries/2013/4/17_Tutorial_-_Reusable_Game_Center_Singleton.html

Thanks for the grat service.

Protocol strings defined in Yandex Metrica script tag incorrectly proxified

Below is the Yandex Metrica script tag from the webpage http://www.survio.com/l-cs-dotaznik-form/

<script type="text/javascript">
(function(d, w, c) {
    (w[c] = w[c] || []).push(function() {
        try {
            w.yaCounter24267952 = new Ya.Metrika({
                id: 24267952,
                clickmap: true,
                trackLinks: true,
                accurateTrackBounce: true
            });
        } catch (e) {}
    });
    var n = d.getElementsByTagName("script")[0],
        s = d.createElement("script"),
        f = function() {
            n.parentNode.insertBefore(s, n);
        };
    s.type = "text/javascript";
    s.async = true;
    s.src = (d.location.protocol == "https:" ? "https:" : "http:") + "//mc.yandex.ru/metrika/watch.js";
    if (w.opera == "[object Opera]") {
        d.addEventListener("DOMContentLoaded", f, false);
    } else {
        f();
    }
})(document, window, "yandex_metrika_callbacks");
</script>

When this page is loaded via the unblocker proxy this script is rewritten as follows:

<script type="text/javascript">
(function(d, w, c) {
    (w[c] = w[c] || []).push(function() {
        try {
            w.yaCounter24267952 = new Ya.Metrika({
                id: 24267952,
                clickmap: true,
                trackLinks: true,
                accurateTrackBounce: true
            });
        } catch (e) {}
    });
    var n = d.getElementsByTagName("script")[0],
        s = d.createElement("script"),
        f = function() {
            n.parentNode.insertBefore(s, n);
        };
    s.type = "text/javascript";
    s.async = true;
    s.src = (d.location.protocol == "/proxy/https:" ? "/proxy/https:" : "/proxy/http:") + "/proxy/http://mc.yandex.ru/metrika/watch.js";
    if (w.opera == "[object Opera]") {
        d.addEventListener("DOMContentLoaded", f, false);
    } else {
        f();
    }
})(document, window, "yandex_metrika_callbacks");
</script>

The script then creates the following url: /proxy/http://proxy/http://mc.yandex.ru/metrika/watch.js, which is not correct and causes a 500 error.

http://nodeunblocker.com/ is down

You may already know, the webapp doesn't work anymore

Heroku | No such app
There is no app configured at that hostname.
Perhaps the app owner has renamed it, or you mistyped the URL.

Cheers,

Cant start server on windows

0 info it worked if it ends with ok
1 verbose cli [ 'C:\Program Files (x86)\nodejs\node.exe',
1 verbose cli 'C:\Program Files (x86)\nodejs\node_modules\npm\bin\npm-cli.js',
1 verbose cli 'start' ]
2 info using [email protected]
3 info using [email protected]
4 verbose run-script [ 'prestart', 'start', 'poststart' ]
5 info prestart [email protected]
6 info start [email protected]
7 verbose unsafe-perm in lifecycle true
8 info [email protected] Failed to exec start script
9 verbose stack Error: [email protected] start: ./node_modules/gatling/gatling.js ./app.js
9 verbose stack Exit status 1
9 verbose stack at EventEmitter. (C:\Program Files (x86)\nodejs\node_modules\npm\lib\utils\lifecycle.js:217:16)
9 verbose stack at emitTwo (events.js:87:13)
9 verbose stack at EventEmitter.emit (events.js:172:7)
9 verbose stack at ChildProcess. (C:\Program Files (x86)\nodejs\node_modules\npm\lib\utils\spawn.js:24:14)
9 verbose stack at emitTwo (events.js:87:13)
9 verbose stack at ChildProcess.emit (events.js:172:7)
9 verbose stack at maybeClose (internal/child_process.js:827:16)
9 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)
10 verbose pkgid [email protected]
11 verbose cwd C:\Users\Administrator\Desktop\node-unblocker\examples\nodeunblocker.com
12 error Windows_NT 6.2.9200
13 error argv "C:\Program Files (x86)\nodejs\node.exe" "C:\Program Files (x86)\nodejs\node_modules\npm\bin\npm-cli.js" "start"
14 error node v4.4.5
15 error npm v2.15.5
16 error code ELIFECYCLE
17 error [email protected] start: ./node_modules/gatling/gatling.js ./app.js
17 error Exit status 1
18 error Failed at the [email protected] start script './node_modules/gatling/gatling.js ./app.js'.
18 error This is most likely a problem with the nodeunblocker.com package,
18 error not with npm itself.
18 error Tell the author that this fails on your system:
18 error ./node_modules/gatling/gatling.js ./app.js
18 error You can get information on how to open an issue for this project with:
18 error npm bugs nodeunblocker.com
18 error Or if that isn't available, you can get their info via:
18 error
18 error npm owner ls nodeunblocker.com
18 error There is likely additional logging output above.
19 verbose exit [ 1, true ]

Round-Robin Hosting?

I was wondering if you would change it to be more like Tor2Web, where contributers could run their own node then have it work in a round-robin to handle traffic from the actual domain.

Due to the Heroku domain-binding issue, you could give each node it's own subdomain (like node4.nodeunblocker.com) then have any requests to nodeunblocker.com redirect to a valid node.

Just a thought.

Is there a chance to use a http/https proxy in proxy.js?

I checked unblocker/lib/proxy.js, and this module used http and https library to send real request.
It's a little hard to integrate proxy feature.
Maybe you could think about using request library to send request?
So that the proxy feature can be easily integrated.

error decompressing gzip

I recently encountered an error:
`
events.js:160
throw er; // Unhandled 'error' event
^

Error: unexpected end of file
at Zlib.__dirname.Zlib.mode._handle.onerror (zlib.js:370:17)
`
Please help me in fixing this!!

After npm start node-unblocker throw errors.

Hello !

I fallowed steps from "installation on your system" and after npm start
I'm seeing fallowing error:

MBP-Mateusz:node-unblocker mateusz$ npm start

> [email protected] start /Users/mateusz/Desktop/node-unblocker
> ./node_modules/gatling/gatling.js --threads 2 ./app.js

module.js:338
    throw err;
          ^
Error: Cannot find module '../build/Debug/iconv.node'
    at Function.Module._resolveFilename (module.js:336:15)
    at Function.Module._load (module.js:278:25)
    at Module.require (module.js:365:17)
    at require (module.js:384:17)
    at Object.<anonymous> (/Users/mateusz/Desktop/node-unblocker/node_modules/iconv/lib/iconv.js:27:14)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Module.require (module.js:365:17)

npm ERR! Darwin 14.3.0
npm ERR! argv "node" "/usr/local/bin/npm" "start"
npm ERR! node v0.12.0
npm ERR! npm  v2.5.1
npm ERR! code ELIFECYCLE
npm ERR! [email protected] start: `./node_modules/gatling/gatling.js --threads 2 ./app.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] start script './node_modules/gatling/gatling.js --threads 2 ./app.js'.
npm ERR! This is most likely a problem with the node-unblocker package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     ./node_modules/gatling/gatling.js --threads 2 ./app.js
npm ERR! You can get their info via:
npm ERR!     npm owner ls node-unblocker
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/mateusz/Desktop/node-unblocker/npm-debug.log

any thoughts ?

Logins not working

First off, this is a great project -- I'm really impressed at how fast it is compared to similar projects (Glype, CGIProxy)

I was just wondering if you had a fix / had thought about how to process logins. I've tried numerous sites, and none work (Google, LinkedIn, etc.).

Thanks

Redirect to homepage for bad urls

Currently http://nodeunblocker.com/proxy/http throws this error:

TypeError: Cannot read property 'length' of undefined
at getCookies (/app/server.js:334:37)
at proxy (/app/server.js:162:19)
at Object.handle (/app/server.js:89:10)
at next (/app/node_modules/connect/lib/proto.js:176:15)
at /app/node_modules/connect/lib/middleware/session.js:276:9
at /app/node_modules/connect/lib/middleware/session.js:298:9
at /app/node_modules/connect-redis/lib/connect-redis.js:85:9
at try_callback (/app/node_modules/redis/index.js:466:9)
at RedisClient.return_reply (/app/node_modules/redis/index.js:503:13)
at RedisReplyParser. (/app/node_modules/redis/index.js:259:14)

That should be caught and responded to with a redirect to something like /proxy?error=Unable to process your request, please check the URL and try again.

TypeError: Cannot read property 'split' of null

The proxy is crashing on some sites. An example of a URL that causes the proxy to crash is: http://www.optimcore.com/

Here is the full error message:

Air:simple matthew$ npm start

> [email protected] start /Users/matthew/Sites/node-unblocker-master/examples/simple
> node server.js

/Users/matthew/Sites/node-unblocker-master/examples/simple/node_modules/tld/lib/tld.js:80
    var parts = domain.split('.'),
                      ^

TypeError: Cannot read property 'split' of null
    at registeredDomain (/Users/matthew/Sites/node-unblocker-master/examples/simple/node_modules/tld/lib/tld.js:80:23)
    at Object.exports.registered (/Users/matthew/Sites/node-unblocker-master/examples/simple/node_modules/tld/lib/tld.js:120:12)
    at rewriteCookiesAndLinks (/Users/matthew/Sites/node-unblocker-master/examples/simple/node_modules/unblocker/lib/cookies.js:97:27)
    at /Users/matthew/Sites/node-unblocker-master/examples/simple/node_modules/unblocker/lib/proxy.js:66:13
    at arraySome (/Users/matthew/Sites/node-unblocker-master/examples/simple/node_modules/lodash/index.js:1493:13)
    at Function.some (/Users/matthew/Sites/node-unblocker-master/examples/simple/node_modules/lodash/index.js:7051:14)
    at proxyResponse (/Users/matthew/Sites/node-unblocker-master/examples/simple/node_modules/unblocker/lib/proxy.js:65:43)
    at ClientRequest.<anonymous> (/Users/matthew/Sites/node-unblocker-master/examples/simple/node_modules/unblocker/lib/proxy.js:42:17)
    at ClientRequest.g (events.js:260:16)
    at emitOne (events.js:77:13)

npm ERR! Darwin 15.2.0
npm ERR! argv "/opt/local/bin/node" "/opt/local/bin/npm" "start"
npm ERR! node v4.2.3
npm ERR! npm  v3.5.2
npm ERR! code ELIFECYCLE
npm ERR! [email protected] start: `node server.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] start script 'node server.js'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the simple-unblocker-server package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     node server.js
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs simple-unblocker-server
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls simple-unblocker-server
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/matthew/Sites/node-unblocker-master/examples/simple/npm-debug.log

and here is the contents of the log file:

0 info it worked if it ends with ok
1 verbose cli [ '/opt/local/bin/node', '/opt/local/bin/npm', 'start' ]
2 info using [email protected]
3 info using [email protected]
4 verbose run-script [ 'prestart', 'start', 'poststart' ]
5 info lifecycle [email protected]~prestart: [email protected]
6 silly lifecycle [email protected]~prestart: no script for prestart, continuing
7 info lifecycle [email protected]~start: [email protected]
8 verbose lifecycle [email protected]~start: unsafe-perm in lifecycle true
9 verbose lifecycle [email protected]~start: PATH: /opt/local/lib/node_modules/npm/bin/node-gyp-bin:/Users/matthew/Sites/node-unblocker-master/examples/simple/node_modules/.bin:/opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
10 verbose lifecycle [email protected]~start: CWD: /Users/matthew/Sites/node-unblocker-master/examples/simple
11 silly lifecycle [email protected]~start: Args: [ '-c', 'node server.js' ]
12 silly lifecycle [email protected]~start: Returned: code: 1  signal: null
13 info lifecycle [email protected]~start: Failed to exec start script
14 verbose stack Error: [email protected] start: `node server.js`
14 verbose stack Exit status 1
14 verbose stack     at EventEmitter.<anonymous> (/opt/local/lib/node_modules/npm/lib/utils/lifecycle.js:232:16)
14 verbose stack     at emitTwo (events.js:87:13)
14 verbose stack     at EventEmitter.emit (events.js:172:7)
14 verbose stack     at ChildProcess.<anonymous> (/opt/local/lib/node_modules/npm/lib/utils/spawn.js:24:14)
14 verbose stack     at emitTwo (events.js:87:13)
14 verbose stack     at ChildProcess.emit (events.js:172:7)
14 verbose stack     at maybeClose (internal/child_process.js:818:16)
14 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)
15 verbose pkgid [email protected]
16 verbose cwd /Users/matthew/Sites/node-unblocker-master/examples/simple
17 error Darwin 15.2.0
18 error argv "/opt/local/bin/node" "/opt/local/bin/npm" "start"
19 error node v4.2.3
20 error npm  v3.5.2
21 error code ELIFECYCLE
22 error [email protected] start: `node server.js`
22 error Exit status 1
23 error Failed at the [email protected] start script 'node server.js'.
23 error Make sure you have the latest version of node.js and npm installed.
23 error If you do, this is most likely a problem with the simple-unblocker-server package,
23 error not with npm itself.
23 error Tell the author that this fails on your system:
23 error     node server.js
23 error You can get information on how to open an issue for this project with:
23 error     npm bugs simple-unblocker-server
23 error Or if that isn't available, you can get their info via:
23 error     npm owner ls simple-unblocker-server
23 error There is likely additional logging output above.
24 verbose exit [ 1, true ]

Block access to local IPs

Sorry to be back so soon again.

I've just noticed that it is possible to reach local IP addresses through the proxy. (like 192.168.1.154)

Is there a setting or some lines I can add to stop the proxy from reaching local IP addresses? I know I could create a whole vlan, but that would be overkill and interfere with the other nodejs services I have running on the same VM.

eror in running app

i edit the config
using my hostname without port
using my ip host

but when i run it ,that app break

[root@test node-unblocker]# node debug app.js
< debugger listening on port 5858
connecting... ok
break in app.js:13
11
12 // native imports
13 var http = require('http'),
14 https = require('https'),
15 url = require('url'),
debug>

Reverse Proxy

Hi,

I'm trying to put node-unblocker behind a reverse proxy for intranet access:

I need to have under a subdirectory, and have modified the code to point to /foo/bar as it's root and it is working perfectly on it's own. But when I put nginx infront of node-unblocker I get stuck in a redirect loop:

curling node-unblocker directly results in the expected output:

curl -i http://172.16.6.168:800/foo/bar/proxy/http://example.com/
**expected output**

while the proxy returns:

curl -i http://172.16.6.168/foo/bar/proxy/http://example.com
HTTP/1.1 307 Temporary Redirect
Date: Wed, 25 Mar 2015 13:28:05 GMT
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: unblocker.sid=s%3AOWn3F7Kx4eGCwtoTxgeui6ui.w0vbLLD3wwWYHCXUQly85wTf0PhwEj9S89ccLrhrQCo; Path=/
location: http://172.16.6.168/foo/bar/proxy/http://localhost/foo/bar/proxy

The relevant section of my nginx config is:

location /foo/bar/ {
        proxy_pass        http://X.X.X.X:XX/foo/bar/;
        proxy_http_version 1.1;
        proxy_pass_header Server;
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        }

Im sure i must be missing something pretty simple? If you had any pointers it would be greatly appreciated.

Cheers

Pete

Remove dependency on redis

I've been thinking about how to make umblocker easier to embed in larger apps, and the big issue is the dependency on redis to store cookies. If we just dropped it entirely, and started passing cookies along verbatim, most things would continue to work although they would of course leak between sites.

You could set the path to /proxy/http://example.com + cookie.path and it would keep server-generated cookies from leaking, but you'd loose them when switching from http to https and vice versa & when switching subdomains. I thought about just always setting two cookies - one for http and one for https, but that seems a bit redundant and still doesn't handle the subdomain issue.

My current thinking, though is to set the cookies to /proxy/http://example.com + cookie.path but then have an extra filter that detects any links that change protocol or subdomain, and rewrite them to stay on the current domain, but add a parameter to the end that would let the proxy know to copy cookies and then redirect to the correct url.

It would also be possible to create a "meta cookie" that stored things like cookie paths and httponly flags to honor those, but I don't think it would be necessary for a first pass.

This would add a bit of complexity, but I think it might be worth it.

I'm also thinking that I want to make things a bit more modularizable - so the existing cookie code could be kept as an option, as could this new stateless mode. And anyone that wanted to embed unblocker could choose to enable one (or neither).

Redirect to wrong address using google

Greetings,

I am testing latest git.Sometime using a search engine google.com your module redirect me to wrong url, (http://localhost/url?sa=t&rct=j&q=&esrc=s&source=web&cd=3&ved=0CDwQFjACahUKEwjsv-r014LHAhUBhSwKHbq7AYo&url=%2Fproxy%2Fhttp%3A%2F%2Fwww.apple.com%2Fru%2Fstevejobs%2F&ei=1wG6Vaz4HoGKsgG694bQCA&usg=AFQjCNELu0sMKoBA1ZZwj5D57TXfU17AyA&bvm=bv.99028883,d.bGg instead of allaboutstevejobs.com/) to reproduce the problem you need to go to the google, search Steave Jobs and click on link "all about Steve Jobs.com"

Sites using location-bar or similar breaks in unblocker

So there is this technology that more and more sites are starting to use that breaks the way that unblocker handles paths. (https://github.com/KidkArolis/location-bar)

The technology enables JavaScript to change the complete path (not including domains) for the client without reloading the browser.

I noticed this problem when trying to make DynaMeds page work in my project Proxive.

Other examples of this technology in use:
Discourse: http://try.discourse.org/
LinkedIn Pulse: https://www.linkedin.com/pulse/how-those-totally-useless-meetings-can-make-break-your-jack-welch
Ember.js uses this technology in its routers.

To fix this it would require a complete rewrite of unblocker so it instead uses the domain for the domain of the page visited like this:

http://google.com.example.com/path?query=query#hash instead of the current http://example.com/proxy/http://google.com/path?query=query#hash

The biggest issue I see is how to detect wheter the site is https or not. Maybe a solution would be prepending the domain with something like h-t-t-p-s so that the domain would look like h-t-t-p-s.google.com.example.com.

You can close this issue if you feel that this will not/cannot be part of this project. Maybe we can cooperate on a separate project/branch that enables the above? (I'm planning on working on this very soon since my job needs to stay on top of the issue so please respond as soon as possible if you're interested in cooperating.)

Major sites like Facebook, Twitter and Google not working

None of the google logins work, they just throw an error after attempting to login.
Twitter's password field cannot be typed into, it just remains blank when attempting to type a password.
Facebook keeps throwing redirect notifications

dual license

Hi @hellais, @emilhem, and @tfMen,

I received a request for an alternate-licensed version of node-unblocker for inclusion in a project that's not compatible with the GPL. (node-unblocker is currently GPL-licensed, which applies to your contributions as well.) Are you guys willing to dual-license your contributions as GPL and MIT?

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.