Permalink
Browse files

Initial release. Technical Preview

  • Loading branch information...
Phoenixmatrix committed Feb 2, 2015
0 parents commit 5799c54e73610a27f92a454805068687c376ab6b
Showing with 6,760 additions and 0 deletions.
  1. +5 −0 .gitignore
  2. +22 −0 LICENSE
  3. +105 −0 README.md
  4. +34 −0 app.js
  5. BIN doc/example.png
  6. +45 −0 gulpfile.js
  7. BIN icon.png
  8. +108 −0 index.html
  9. +15 −0 js/app.js
  10. +6 −0 js/controllers/index.js
  11. +57 −0 js/controllers/proxy.js
  12. +6 −0 js/directives/index.js
  13. +143 −0 js/directives/requestList.js
  14. +3 −0 js/filters/index.js
  15. +1 −0 js/lib/angular.js
  16. +128 −0 js/lib/certificate.js
  17. +1 −0 js/lib/config.js
  18. +13 −0 js/lib/helpers.js
  19. +284 −0 js/lib/proxy.js
  20. +8 −0 js/services/index.js
  21. +15 −0 js/services/requestFilter.js
  22. +70 −0 js/services/requests.js
  23. +4 −0 openssl.cnf
  24. +61 −0 package.json
  25. +6 −0 phoenixmatrix.json
  26. +183 −0 stylesheets/style.less
  27. +242 −0 vendor/angular/angular.min.js
  28. +8 −0 vendor/angular/angular.min.js.map
  29. +551 −0 vendor/bootstrap-ui/ui-bootstrap-custom-tpls-0.12.0.js
  30. +5 −0 vendor/bootstrap/css/bootstrap-theme.min.css
  31. +5 −0 vendor/bootstrap/css/bootstrap.min.css
  32. BIN vendor/bootstrap/fonts/glyphicons-halflings-regular.eot
  33. +229 −0 vendor/bootstrap/fonts/glyphicons-halflings-regular.svg
  34. BIN vendor/bootstrap/fonts/glyphicons-halflings-regular.ttf
  35. BIN vendor/bootstrap/fonts/glyphicons-halflings-regular.woff
  36. +6 −0 vendor/bootstrap/js/bootstrap.min.js
  37. +39 −0 vendor/bootstrap/less/mixins.less
  38. +14 −0 vendor/bootstrap/less/mixins/alerts.less
  39. +8 −0 vendor/bootstrap/less/mixins/background-variant.less
  40. +18 −0 vendor/bootstrap/less/mixins/border-radius.less
  41. +50 −0 vendor/bootstrap/less/mixins/buttons.less
  42. +7 −0 vendor/bootstrap/less/mixins/center-block.less
  43. +22 −0 vendor/bootstrap/less/mixins/clearfix.less
  44. +81 −0 vendor/bootstrap/less/mixins/forms.less
  45. +59 −0 vendor/bootstrap/less/mixins/gradients.less
  46. +91 −0 vendor/bootstrap/less/mixins/grid-framework.less
  47. +122 −0 vendor/bootstrap/less/mixins/grid.less
  48. +21 −0 vendor/bootstrap/less/mixins/hide-text.less
  49. +34 −0 vendor/bootstrap/less/mixins/image.less
  50. +12 −0 vendor/bootstrap/less/mixins/labels.less
  51. +29 −0 vendor/bootstrap/less/mixins/list-group.less
  52. +10 −0 vendor/bootstrap/less/mixins/nav-divider.less
  53. +9 −0 vendor/bootstrap/less/mixins/nav-vertical-align.less
  54. +8 −0 vendor/bootstrap/less/mixins/opacity.less
  55. +23 −0 vendor/bootstrap/less/mixins/pagination.less
  56. +24 −0 vendor/bootstrap/less/mixins/panels.less
  57. +10 −0 vendor/bootstrap/less/mixins/progress-bar.less
  58. +8 −0 vendor/bootstrap/less/mixins/reset-filter.less
  59. +6 −0 vendor/bootstrap/less/mixins/resize.less
  60. +15 −0 vendor/bootstrap/less/mixins/responsive-visibility.less
  61. +10 −0 vendor/bootstrap/less/mixins/size.less
  62. +9 −0 vendor/bootstrap/less/mixins/tab-focus.less
  63. +28 −0 vendor/bootstrap/less/mixins/table-row.less
  64. +8 −0 vendor/bootstrap/less/mixins/text-emphasis.less
  65. +8 −0 vendor/bootstrap/less/mixins/text-overflow.less
  66. +224 −0 vendor/bootstrap/less/mixins/vendor-prefixes.less
  67. +846 −0 vendor/bootstrap/less/variables.less
  68. +1,801 −0 vendor/font-awesome/css/font-awesome.css
  69. BIN vendor/font-awesome/fonts/FontAwesome.otf
  70. BIN vendor/font-awesome/fonts/fontawesome-webfont.eot
  71. +565 −0 vendor/font-awesome/fonts/fontawesome-webfont.svg
  72. BIN vendor/font-awesome/fonts/fontawesome-webfont.ttf
  73. BIN vendor/font-awesome/fonts/fontawesome-webfont.woff
  74. BIN vendor/font-awesome/fonts/fontawesome-webfont.woff2
  75. +5 −0 vendor/jquery/jquery.min.js
  76. +1 −0 vendor/jquery/jquery.min.map
  77. +90 −0 vendor/splitter/splitter.js
  78. +76 −0 vendor/splitter/style.css
@@ -0,0 +1,5 @@
node_modules
.idea
certificate
npm-debug.log
dist
22 LICENSE
@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2015 Francois Ward
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
105 README.md
@@ -0,0 +1,105 @@
PhoenixMatrix web development proxy
===================================
_v0.1 technical preview_
Web debugging proxy in the spirit of Fiddler and Charles Proxy, written in JavaScript with [nw.js](http//nwjs.io/)
and node.
Tested on MacOSX Yosemite, Windows 8.1 and Ubuntu 14, with caveats*
## Warning: Technical Preview
This is a technical preview at best!!
The UI is far from finished, the code is a mess, there's a lot of bugs. Expect crashes, slowness, and generally an
unfinished product feel. It 'works' when stars are aligned, and that's as much as you should expect.
Again, the code is a mess. Please don't look at it and email me that its bad. For now my priority was to get things working.
### Features
![PhoenixMatrix web development proxy](/doc/example.png?raw=true "See what happens behind the scene")
* Works on all major browsers
* Works on all operating systems that nw.js supports
* Supports both http and https
* Allows real time https decryption with no scary warning (not even from Chrome!)
* Handles gzipped responses (doesn't yet decode base65 encoded bodies though. That's coming)
* Dynamically creates its own certificates for https decryption. No need to fiddle with OpenSSL! (though you do need to have it installed)
* Free and open source the MIT license. Feel free to hack it up.
* Built on open web technology. JavaScript, CSS, node.js.
* Uses the latest EcmaScript 6 features.
### Setup
* Clone this repo
* Open a command prompt and navigate to the location where you cloned it.
* Run `npm install` (on Windows, you will get some kexec errors preceded with the message "optional dep failed, continuing".
This is ok, things will work anyway.
* Run `gulp`
* You should now see the inspector. Setup the proxy in your browser of choice (or in your application), and you're good to go!
* From now on you can use `npm start` to run PhoenixMatrix without rebuilding everything.
### Configuring your browser to use the proxy
Different browsers and operating systems use different methods of configuring proxies. For IE, Safari and Chrome in Windows and MacOSX, configure
the proxy from the system settings/control panel. For FireFox, configure the proxy in the options -> advanced under network. The default port is 3002 but
can be configured
Exclude SSl/HTTPS from using the proxy if you don't need it and/or don't want to go through the steps to configure a certificate for man-in-the-middle decryption.
For https support, after running PhoenixMatrix, look in the certificate folder where you cloned the repo. Import `ca.crt` in your browser (Firefox)
or as a system certificate for most other browsers/operating systems. If prompted, the certificate only need to be used for websites. On Windows, the certificate needs to
be configured in the Trusted Certificate Authorities (you can just double click the certificate to launch the wizard).
PhoenixMatrix uses a certificate authority to generate individual server certificates, so only the one certificate needs to be installed.
### Configuration
The available options can be found in phoenixmatrix.json, in JSON format (duh!).
* `includeConnect`: if you want to see http CONNECT requests, which will happen whenever you try to make an https request while using the proxy.
* `proxyPort`: used to configure which port the proxy listens to. Make sure to use a free port. Default to 3002.
* `httpsProxyPort`: used to configure on which port the https proxy listens to. This is only used internally and will not work
if you point your browser to it directly.
* `certificateExpiration`: how many days should the generated certificates be valid for
### Caveats
* On MacOSX, when using the trackpad, scrolling isn't as smooth as it should be.
* On newer versions of Ubuntu, or any distribution lacking libudev.so.0 (ie: with libudev.so.1 installed), see
[this link](https://github.com/nwjs/nw.js/wiki/The-solution-of-lacking-libudev.so.0) on how to get things running.
* On windows, make sure you have OpenSSL installed, and it is in the path. Using [Git Bash](http://git-scm.com/downloads)
will do the trick too.
* As of the technical preview, it is not possible to directly disable https support. If you don't want to setup the certificate, ensure your browser is not
configured to use the proxy for HTTPS if you do not want it to stop you from browsing https sites during development.
* The proxy currently only checks individual server certificate expiration dates to regenerate them. If you get an error that the CA certificate isn't valid
even though you imported it, just delete the content of the certificate folder, restart PhoenixMatrix and import ca.crt again
* Expect the code to change a LOT from now on. This was hacked up quickly to get things working. If you make a fork, don't expect to easily be able to merge from
upstream for very long.
* Doesn't support old HTTP versions, servers or uncommon network setups.
Inspiration taken from the following projects. Thanks! :
* [node-http-proxy](https://github.com/nodejitsu/node-http-proxy)
* [pem](https://github.com/andris9/pem)
### License
The MIT License (MIT)
Copyright (c) [year] [fullname]
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
34 app.js
@@ -0,0 +1,34 @@
// This will eventually become a command line version of the proxy. For now though, it's very broken.
var proxyFactory = require('./js/lib/proxy');
var onRequest = function(data) {
console.log('request: ' + data.method + ' ' + data.url);
};
var onResponse = function(data) {
console.log('response: ' + data.method + ' ' + data.url);
};
var httpProxy;
proxyFactory.createHttpProxy({port: 3002}).then(function(proxy) {
httpProxy = proxy;
proxy.on('proxyRequest', onRequest);
proxy.on('proxyResponse', onResponse);
proxy.on('proxyConnect', function(data) {
console.log('connect request: ' + data.state + ' ' + data.url + ':' + data.port);
});
return proxyFactory.createHttpsProxy({port: 8443});
})
.then(function(httpsProxy) {
httpsProxy.on('proxyRequest', onRequest);
httpsProxy.on('proxyResponse', onResponse);
httpProxy.enableHttpsProxy(httpsProxy);
});
Binary file not shown.
@@ -0,0 +1,45 @@
"use strict";
var gulp = require('gulp'),
watch = require('gulp-watch'),
to5 = require('gulp-6to5'),
runSequence = require('run-sequence'),
sourcemaps = require('gulp-sourcemaps'),
clean = require('gulp-clean'),
less = require('gulp-less'),
path = require('path');
var exec = require('child_process').exec;
gulp.task('clean', function() {
return gulp.src('./dist', {read: false})
.pipe(clean());
});
gulp.task('build:styles', function() {
return gulp.src('./stylesheets/style.less')
.pipe(less())
.pipe(gulp.dest('./dist/css'));
});
gulp.task('rebuild', function(cb) {
return runSequence('clean', 'build', cb);
});
gulp.task('build:js', function() {
return gulp.src(['./js/**/*.js'])
.pipe(sourcemaps.init())
.pipe(to5())
.pipe(sourcemaps.write())
.pipe(gulp.dest('dist'));
});
gulp.task('build', ['build:js', 'build:styles']);
gulp.task('run', function() {
exec(path.normalize('node_modules/.bin/nodewebkit'));
});
gulp.task('default', function(cb) {
return runSequence('build', 'run', cb);
});
BIN icon.png
Binary file not shown.
@@ -0,0 +1,108 @@
<!DOCTYPE html>
<html>
<head>
<title>PhoenixMatrix Proxy</title>
<link rel="stylesheet" type="text/css" href="./vendor/bootstrap/css/bootstrap.min.css"/>
<link rel="stylesheet" type="text/css" href="./vendor/font-awesome/css/font-awesome.css"/>
<link rel="stylesheet" type="text/css" href="./vendor/splitter/style.css"/>
<link rel="stylesheet" type="text/css" href="./dist/css/style.css"/>
<script type="text/javascript" src='vendor/jquery/jquery.min.js'></script>
<script type="text/javascript" src='vendor/bootstrap/js/bootstrap.min.js'></script>
<script type="text/javascript" src='vendor/angular/angular.min.js'></script>
<script type="text/javascript" src='vendor/bootstrap-ui/ui-bootstrap-custom-tpls-0.12.0.js'></script>
<script type="text/javascript" src='vendor/splitter/splitter.js'></script>
<script type="text/javascript">
require('./dist/app');
</script>
</head>
<body ng-app="phoenixmatrix">
<div class="view-wrapper">
<div class="main-section" ng-controller="ProxyCtrl as index">
<div class="header-section navbar navbar-inverse navbar-fixed-top">
<span class="navbar-brand">PhoenixMatrix web debugging proxy v0.1 Preview</span>
<form class="navbar-form navbar-right">
<input type="text" class="form-control" placeholder="Search..." ng-model="requestFilter"
ng-model-options="{ debounce: 500 }">
</form>
</div>
<bg-splitter orientation="horizontal">
<bg-pane min-size="370">
<div class="left-section">
<ul class="button-toolbar">
<li class="fa fa-ban" ng-click="index.clear()" tooltip-placement="right" tooltip="Clear requests"></li>
<li class="fa fa-pause" ng-click="index.togglePause()" ng-class="{ selected: index.paused }" tooltip-placement="right" tooltip="Pause capture"></li>
<li class="fa fa-server" ng-click="index.toggleConnect()" ng-class="{ selected: index.config.includeConnect }" tooltip-placement="right" tooltip="Display CONNECT requests"></li>
</ul>
<div class="requests" request-list requests="proxy.requests" filter="requestFilter"
request-selected="index.selectRequest"></div>
</div>
</bg-pane>
<bg-pane min-size="200">
<div class="content-section">
<div class="request-detail" ng-if="selectedRequest">
<div class="panel panel-default">
<div class="panel-heading">
<h4>Request</h4>
</div>
<div class="panel-body">
<h5 ng-bind="selectedRequest.url"></h5>
<div class="panel panel-primary headers-list" ng-if="selectedRequest.headers.length > 0">
<div class="panel-heading" ng-click="collapseRequestHeaders = !collapseRequestHeaders">
Headers
</div>
<table class="table table-hover" ng-if="!collapseRequestHeaders">
<tbody>
<tr ng-repeat="(key, value) in selectedRequest.headers">
<td ng-bind="key"></td>
<td ng-bind="value"></td>
</tr>
</tbody>
</table>
</div>
<div class="panel panel-primary request-body" ng-if="selectedRequest.body.length">
<div class="panel-heading" ng-click="showRequestBody = !showRequestBody">Body</div>
<div class="panel-body" ng-if="showRequestBody" ng-bind="selectedRequest.body"></div>
</div>
</div>
</div>
</div>
<div class="response-detail" ng-if="selectedRequest && selectedRequest.responseHeaders">
<div class="panel panel-default">
<div class="panel-heading">
<h4>Response</h4>
</div>
<div class="panel-body">
<div class="panel panel-primary headers-list">
<div class="panel-heading"
ng-click="collapseResponseHeaders = !collapseResponseHeaders">Headers
</div>
<table class="table table-hover" ng-if="!collapseResponseHeaders">
<tbody>
<tr ng-repeat="(key, value) in selectedRequest.responseHeaders">
<td ng-bind="key"></td>
<td ng-bind="value"></td>
</tr>
</tbody>
</table>
</div>
<div class="panel panel-primary response-body" ng-if="selectedRequest.responseBody">
<div class="panel-heading" ng-click="collapseResponseBody = !collapseResponseBody">
Body
</div>
<div class="panel-body" ng-if="collapseResponseBody">
<textarea ng-bind="selectedRequest.responseBody"></textarea>
</div>
</div>
</div>
</div>
</div>
</div>
</bg-pane>
</div>
<div class="footer-section"></div>
</div>
</div>
</body>
</html>
@@ -0,0 +1,15 @@
"use strict";
import '6to5/polyfill';
global.document = global.window.document;
global.navigator = global.window.navigator;
import angular from './lib/angular';
angular.module('phoenixmatrix', ['bgDirectives', 'ui.bootstrap']);
import './services';
import './filters';
import './directives';
import './controllers';
@@ -0,0 +1,6 @@
import angular from '../lib/angular';
import proxy from './proxy';
let app = angular.module('phoenixmatrix');
app.controller('ProxyCtrl', proxy);
Oops, something went wrong.

0 comments on commit 5799c54

Please sign in to comment.