Permalink
Browse files

added warning for unsafe headers

Fixes #34
Fixes #41
  • Loading branch information...
1 parent faf1e25 commit 00c8a2a77502f85015ce98afa8603e52290a7eb2 @ahmadnassri ahmadnassri committed Sep 29, 2011
Showing with 113 additions and 57 deletions.
  1. +4 −9 application/index.html
  2. +7 −0 application/js/AutoComplete.js
  3. +102 −48 application/js/app.js
@@ -93,7 +93,7 @@
<div class="clearfix">
<label for="version">Version</label>
<div class="input">
- <input class="span1" type="number" name="version" value="1.0" min="1" step="1" autocomplete="on" placeholder="1.0" list="version" required/>
+ <input class="span1" type="number" name="version" value="1.0" min="1" step="1" autocomplete="on" placeholder="1.0" required/>
<span class="help-block"></span>
</div>
</div>
@@ -547,8 +547,8 @@
<div class="input">
<ul class="unstyled headers">
<li>
- <input class="span3" type="text" name="key" tabindex="3" autocomplete="on" placeholder="header" disabled/>
- <input class="span4" type="text" name="value" tabindex="3" autocomplete="on" placeholder="value" disabled/>
+ <input class="span3" type="text" name="key" tabindex="3" autocomplete="on" value="" placeholder="header" disabled/>
+ <input class="span4" type="text" name="value" tabindex="3" autocomplete="on" value="" placeholder="value" disabled/>
<input class="span1 btn danger" type="button" value="&mdash;"/>
<input class="span1 btn success" type="button" value="+"/>
</li>
@@ -981,7 +981,7 @@
</div>
<div class="span">
- <label><input type="radio" name="highlight" value="xml"/> <span>CSS</span></label>
+ <label><input type="radio" name="highlight" value="css"/> <span>CSS</span></label>
</div>
</div>
</div>
@@ -1448,11 +1448,6 @@
<option value="PATCH">PATCH</option>
</datalist>
- <datalist id="version">
- <option value="1.0">1.0</option>
- <option value="2.0">2.0</option>
- </datalist>
-
<script src="js/beautify.js"></script>
<script type="text/javascript" src="js/OAuthSimple.js"></script>
@@ -56,6 +56,13 @@ var AutoComplete = new Class({
'focus': function(event) {
var list = this.getNext('[for={0}]'.substitute([this.get('name')])).show().scrollTo(0, 0);
+ // reposition the list
+ list.position({
+ 'relativeTo': this,
+ 'position': 'bottomLeft',
+ 'edge': 'upperLeft'
+ });
+
list.dataset.current = -1;
list.getElements('div').hide().removeClass('enabled').removeClass('active');
View
@@ -363,7 +363,16 @@ window.addEvent('domready', function() {
document.getElement('form[name="options"] input[name="lines"]').fireEvent('change');
+ // init google prettify
prettyPrint();
+
+ // find links
+ // TODO parse query string params into fields
+ var body = responseBody.get('html');
+ var exp = new RegExp('\\b((https?|ftp|file)://[-A-Z0-9+&@#/%?=~_|!:,.;]*[-A-Z0-9+&@#/%=~_|])', 'gim');
+ body = body.replace(exp, '<a target="_blank" href="$1">$1</a>');
+ responseBody.set('html', body);
+ responseBody.scrollTo(0, 0);
}
},
@@ -373,6 +382,14 @@ window.addEvent('domready', function() {
}
});
+ document.id('responseBody').addEvent('click:relay(a[href])', function(event) {
+ event.preventDefault();
+
+ document.getElement('input[name="uri"]').set('value', this.get('href'));
+ document.getElement('input[name="method"]').set('value', 'GET');
+ document.getElement('form[name="request"]').fireEvent('submit', new DOMEvent);
+ });
+
document.getElement('form[name="request"] input[name="uri"]').addEvent('change', function(event) {
if (this.get('value').length > 0 && this.get('value').substr(0, 4) != 'http') {
this.set('value', 'http://' + this.get('value'));
@@ -506,48 +523,102 @@ window.addEvent('domready', function() {
'submit': function(event) {
event.preventDefault();
+ var error = false;
+
// get all form data
- var data = this.toQueryString().parseQueryString();
+ var request = this.toQueryString().parseQueryString();
- var headers = Object.clone(data);
+ // extract the headers
+ request.headers = Object.clone(request);
// delete none headers
- delete headers.uri;
- delete headers.method;
- delete headers.timeout;
- delete headers.raw;
- delete headers.encoding;
- delete headers.key;
- delete headers.value;
- delete headers.file_key;
+ delete request.headers.uri;
+ delete request.headers.method;
+ delete request.headers.timeout;
+ delete request.headers.raw;
+ delete request.headers.encoding;
+ delete request.headers.key;
+ delete request.headers.value;
+ delete request.headers.file_key;
+
+ // unsecure headers:
+ var unsafe = [
+ 'accept-charset',
+ 'accept-encoding',
+ 'content-length',
+ 'cookie',
+ 'date',
+ 'connection',
+ 'expect',
+ 'referer',
+ 'user-agent',
+ 'via',
+ 'proxy-authorization',
+ 'te',
+ 'upgrade'
+ ];
+
+ // get custom fields
+ var custom = {
+ 'headers': {
+ 'keys': this.getElements('ul.headers input[name="key"]').get('value'),
+ 'values': this.getElements('ul.headers input[name="value"]').get('value')
+ },
- var missing = false;
+ 'data': {
+ 'keys': this.getElements('ul.params input[name="key"]').get('value'),
+ 'values': this.getElements('ul.params input[name="value"]').get('value')
+ }
+ }
+
+ // init variables
+ request.data = {};
+ request.headers = {};
+
+ // set custom params data
+ custom.data.keys.each(function(key, index) {
+ if (key.length > 0) {
+ request.data[key] = custom.data.values[index];
+ }
+ });
+
+ // validate headers
+ custom.headers.keys.each(function(key, index) {
+ if (unsafe.contains(key.toLowerCase())) {
+ Error('Unsafe Header', 'Refused to set unsafe header "' + key +'"', this.getElement('ul.headers input[name="key"]:nth-of-type(' + (index + 1) + ')'));
+ error = true;
+ } else if (key.length > 0) {
+ request.headers[key] = custom.headers.values[index];
+ }
+ }.bind(this));
+ // check for required fields
this.getElements('*[required]').each(function(element) {
- if (element.get('value') == '') {
+ if (element.get('value').length == 0) {
Error('Missing Data', 'Please Fill out all the required fields', element);
- missing = true;
+ error = true;
}
});
- if (missing) {
+ if (error) {
+ // stop on error
return false;
} else {
- if (data.encoding) {
// special condition for encoding
- data['Content-Type'] = data['Content-Type'] + '; charset=' + data.encoding;
+ if (request.encoding) {
+ request['Content-Type'] = request['Content-Type'] + '; charset=' + request.encoding;
}
var options = {
- 'url': data.uri,
- 'method': data.method,
- 'encoding': data.encoding,
- 'timeout': data.timeout * 1000,
- 'raw': data.raw,
- 'data': {},
+ 'url': request.uri,
+ 'method': request.method,
+ 'encoding': request.encoding,
+ 'timeout': request.timeout * 1000,
+ 'raw': request.raw,
+ 'data': request.data,
'files': this.getElement('input[name="files"]').files,
- 'file_key': data.file_key,
- 'headers': headers,
+ 'file_key': request.file_key,
+ 'headers': request.headers,
'onRequest': function() {
// replace buttons with animation
@@ -661,6 +732,13 @@ window.addEvent('domready', function() {
var style = 'auto';
switch (contentType) {
+ case 'text/css':
+ style = 'css';
+
+ //responseText = beautify.css(responseText);
+ //document.id('responseBody').set('text', responseText);
+ break;
+
case 'application/ecmascript':
case 'application/javascript':
case 'application/json':
@@ -758,30 +836,6 @@ window.addEvent('domready', function() {
}
};
- // set custom headers
- var headers = {
- 'keys': this.getElements('ul.headers input[name="key"]'),
- 'values': this.getElements('ul.headers input[name="value"]')
- };
-
- headers.keys.each(function(key, index) {
- if (key.get('value') != '') {
- options.headers[key.get('value')] = headers.values[index].get('value');
- }
- });
-
- // set custom params
- var params = {
- 'keys': this.getElements('ul.params input[name="key"]'),
- 'values': this.getElements('ul.params input[name="value"]')
- };
-
- params.keys.each(function(key, index) {
- if (key.get('value') != '') {
- options.data[key.get('value')] = params.values[index].get('value');
- }
- });
-
// don't force the content-type header
if (options.files.length > 0) {
delete options.headers['Content-Type'];

0 comments on commit 00c8a2a

Please sign in to comment.