Skip to content

Commit

Permalink
- added preferences for types of requests to use
Browse files Browse the repository at this point in the history
  • Loading branch information
koto committed Oct 18, 2011
1 parent c79027c commit 76aaf1f
Showing 1 changed file with 163 additions and 48 deletions.
211 changes: 163 additions & 48 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
padding: 0.5em;
}

#help-text,#loader-text,#history-text {
#help-text,#loader-text,#pref-text {
display: none;
}
</style>
Expand All @@ -46,13 +46,48 @@
<strong>Go!</strong>
</button>
<button id=help>?</button>
<button id=history>History</button>
<button id=pref>Preferences</button>
<br />
</div>
<script>
var flash_agree = null;
var flash_agree = null;
var interval; // page loading time

var Preferences = (function() {
var name = 'cors-browser.pref';
var defaults = {
'type' : [ 'cors', 'flash' ]
}
var current = {};

function save(preferences) {
localStorage.setItem(name, JSON.stringify(preferences));
}
;

function load() {
current = $.extend(
JSON.parse(localStorage.getItem(name)) || {}, defaults);
}
;

var inter = {
get : function(name) {
return current[name];
},
getAll : function() {
return current;
},
set : function(name, value) {
current[name] = value;
save(current);
}
}

load();
return inter;
})();

var History = (function() {
var name = 'cors-browser.history';

Expand All @@ -78,26 +113,29 @@
})();

function clicker() {
var url = $(this).attr('href') || $(this).attr('action') || starter.href;
console.log('url',url, 'base', starter.href);
var url = $(this).attr('href') || $(this).attr('action')
|| starter.href;
console.log('url', url, 'base', starter.href);
if (!url.match(/^https?:/)) {
if (url.indexOf('/') === 0) { // domain-absolute url
var base_domain = starter.href.match(/(https?:\/\/[^\/]+)/)[1];
url = base_domain + url;
} else { // relative url
url = starter.href.replace(/\?.*/,'').replace(/\/[^\/]*$/, '') + '/'
+ url;
url = starter.href.replace(/\?.*/, '').replace(/\/[^\/]*$/,
'')
+ '/' + url;
}
} else {
var domain_re = /:\/\/(.*?)(\/|$)/;
var url_domain = url.match(domain_re)[1];
if (starter.href && url_domain !== starter.href.match(domain_re)[1]) {
if (starter.href
&& url_domain !== starter.href.match(domain_re)[1]) {
alert('URL is from other domain: ' + url_domain
+ ', cannot load.');
return false;
}
}
console.log('final',url);
console.log('final', url);
disableTimer();
var method = $(this).attr('method') || "GET", fields = null;

Expand All @@ -111,20 +149,50 @@
History.add(url);
$("#site").val(url);
write($('#loader-text')[0].innerHTML.replace('$url', url));
sendRequest(new XMLHttpRequest(), url, method, fields);
return false;

var types = Preferences.get('type').slice();
console.log("Allowed methods: " + types);
sendRequest(types, url, method, fields);
return false;
}

function sendRequest(xhr, url, method, fields) {
xhr.open(method, url, true);
xhr._url = url;
xhr._method = method;
if (fields) {
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
}
xhr._fields = fields;
xhr.onreadystatechange = display;
xhr.send(fields);

function RequestProcessorFactory(type) {
console.log('Trying ' + type);
switch (type) {
case 'cors':
return new XMLHttpRequest();
case 'flash':
if (location.protocol == 'file:')
throw "Flash will only load from a http[s], not from file://";
if (typeof CrossXHR === 'undefined')
throw "Flash is not loaded!";

return new CrossXHR();
}
throw 'Unsupported request processor type: ' + type;
}

function sendRequest(types, url, method, fields) {
try {
var xhr = RequestProcessorFactory(types.shift()); // get first available type
xhr.open(method, url, true);
xhr._url = url;
xhr._method = method;
xhr._types_left = types;
if (fields) {
xhr.setRequestHeader('Content-Type',
'application/x-www-form-urlencoded');
}
xhr._fields = fields;
xhr.onreadystatechange = processResponse;
xhr.send(fields);
} catch (e) {
alert(e);
}
}

function fallback(xhr) {
sendRequest(xhr._types_left, xhr._url, xhr._method, xhr._fields);
}

function write(text) {
Expand All @@ -146,13 +214,8 @@
interval = null;
}
}

function fallbackToFlash(xhr) {
var xhr2 = new CrossXHR();
sendRequest(xhr2, xhr._url, xhr._method, xhr._fields);
}

function display(event) {
function processResponse(event) {
var xhr = this;

try {
Expand All @@ -166,17 +229,14 @@
post(f.contentDocument)
}, 1000);
} else {
alert("Cannot load ("
+ xhr.statusText
+ ").\nBrowser supports websites that allow CORS requests (Access-Control-Allow-Origin: *)");
if (typeof CrossXHR !== "undefined" && !(xhr instanceof CrossXHR)) {
if (flash_agree === null ) { // no user decision made yet
flash_agree = confirm("I can fallback to method using Adobe Flash file (crossxhr.swf).\nDo you want to enable Flash fallback for this and future requests?");
}

if (flash_agree) { // user is ok with flash fallback
fallbackToFlash(xhr);
}
if (xhr._types_left.length == 0) {
alert("Could not load "
+ xhr._url
+ (xhr.statusText ? " (" + xhr.statusText
+ ")" : "") + "\nUsed methods: "
+ JSON.stringify(Preferences.get('type')));
} else {
return fallback(xhr);
}
}
}
Expand Down Expand Up @@ -231,10 +291,10 @@
write($("#help-text")[0].innerHTML);
});

$("#history").click(
$("#pref").click(
function() {
var h = History.get();
write($("#history-text")[0].innerHTML);
write($("#pref-text")[0].innerHTML);

setTimeout(function() {
var doc = $('#hello')[0].contentDocument;
Expand All @@ -248,11 +308,36 @@
.text(h[i].url)).end()
.show();
}
post(doc); // to activate links

$("#clear-history", doc.body).click(function() {
History.clear();
$('#history').click();
$('#pref').click();
});
post(doc); // to activate links

$("#pref-form", doc.body).unbind('submit').submit(
function() {
// update preferences from field values
var values = $(this).serializeArray();
for ( var i = 0; i < values.length; i++) {
Preferences.set(values[i].name, JSON
.parse(values[i].value));
}
;
$("#pref").click();
return false;
});

// fill form values from preferences
var pref = Preferences.getAll();
for ( var i in pref) {
if (pref.hasOwnProperty(i)) {
$("#pref-form", doc.body).find(
':input[name="' + i + '"]').val(
JSON.stringify(pref[i]));
}
}

}, 100);
});

Expand All @@ -270,6 +355,9 @@ <h2>Description</h2>
<strong>CORS proxy browser</strong> is a proof of concept of how
client-side web proxying can be done using <a target="_blank"
href="http://www.w3.org/TR/cors/">Cross Origin Resource Sharing</a>.



<p>
It allows you to fetch content of websites using
<code>Access-Control-Allow-Origin: *</code>
Expand Down Expand Up @@ -309,7 +397,8 @@ <h2>FAQ</h2>
communication originates from victim's browser, his IP address,
bandwidth etc. There is no server-side code, just a simple HTML
page. <strong>You can even download the file and use it
locally from <code>file://</code> protocol</strong> (Flash fallback won't work from file://).
locally from <code>file://</code> protocol</strong> (Flash fallback won't
work from file://).
</dd>
<dt>
What about Flash
Expand All @@ -321,7 +410,11 @@ <h2>FAQ</h2>
tiny Flash file for sites using <a target="_blank"
href="https://www.owasp.org/index.php/Reviewing_Flash_Applications">permissive</a>
<code>crossdomain.xml</code>
. But now, with CORS, it's possible without any addons, HTML5-style. I've added an optional Flash-based fallback though, because more websites now use permissive <code>crossdomain.xml</code> than CORS headers.
. But now, with CORS, it's possible without any addons, HTML5-style.
I've added an optional Flash-based fallback though, because more
websites now use permissive
<code>crossdomain.xml</code>
than CORS headers.
</dd>
<dt>How does it work?</dt>
<dd>
Expand All @@ -330,7 +423,8 @@ <h2>FAQ</h2>
<li>I ask browser to use <code>XMLHttpRequest</code> to fetch
that remote URL
<li>If we're lucky and website uses <code>Access-Control-Allow-Origin:
*</code>, I get that content. If there's an error and you agree, I try with Flash-based fallback.
*</code>, I get that content. If there's an error and you agree, I try
with Flash-based fallback.
<li>I modify the content adding marquee, base href and a
making an easy attempt to remove ads
<li>I create an iframe and display the content
Expand Down Expand Up @@ -372,7 +466,28 @@ <h2>FAQ</h2>
src="data:image/png;base64,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" />
</p>
</div>
<div id="history-text">
<div id="pref-text">
<h1>Preferences</h1>
<form id="pref-form">
<p>Which technology to use for cross domain communication?</p>
<ul>
<li><strong>CORS</strong> requires permissive
Access-Control-Allow-Origin headers on target domain, can be used
form file:// protocol and will not attach &amp; set cookies.</li>
<li><strong>Flash</strong> requires permissive crossdomain.xml
file, requires a server but will attach &amp; set cookies.</li>

</ul>
<select name="type">
<option value='["cors","flash"]'>Cross Origin Resource
Sharing, then Flash</option>
<option value='["flash","cors"]'>Flash, then Cross Origin
Resource Sharing</option>
<option value='["cors"]'>only Cross Origin Resource Sharing</option>
<option value='["flash"]'>only Flash</option>
</select>
<button type="submit">Save</button>
</form>
<h1>History</h1>
<table>
<thead>
Expand All @@ -388,6 +503,6 @@ <h1>History</h1>
</tr>
</tbody>
</table>
<button id="clear-history">Clear</button>
<button id="clear-history">Clear history</button>
</div>
</body>

0 comments on commit 76aaf1f

Please sign in to comment.