mirror of
https://github.com/zhigang1992/mitmproxy.git
synced 2026-04-27 19:15:33 +08:00
Merge remote-tracking branch 'upstream/master' into print-bracket-fix
Conflicts: examples/har_extractor.py examples/nonblocking.py examples/read_dumpfile libmproxy/web/app.py
This commit is contained in:
@@ -79,6 +79,7 @@ class WebState(flow.State):
|
||||
data=[]
|
||||
)
|
||||
|
||||
|
||||
class Options(object):
|
||||
attributes = [
|
||||
"app",
|
||||
@@ -128,11 +129,13 @@ class WebMaster(flow.FlowMaster):
|
||||
if options.rfile:
|
||||
try:
|
||||
self.load_flows_file(options.rfile)
|
||||
except flow.FlowReadError, v:
|
||||
except flow.FlowReadError as v:
|
||||
self.add_event(
|
||||
"Could not read flow file: %s"%v,
|
||||
"Could not read flow file: %s" % v,
|
||||
"error"
|
||||
)
|
||||
if self.options.app:
|
||||
self.start_app(self.options.app_host, self.options.app_port)
|
||||
|
||||
def tick(self):
|
||||
flow.FlowMaster.tick(self, self.masterq, timeout=0)
|
||||
@@ -154,7 +157,8 @@ class WebMaster(flow.FlowMaster):
|
||||
self.shutdown()
|
||||
|
||||
def _process_flow(self, f):
|
||||
if self.state.intercept and self.state.intercept(f) and not f.request.is_replay:
|
||||
if self.state.intercept and self.state.intercept(
|
||||
f) and not f.request.is_replay:
|
||||
f.intercept(self)
|
||||
else:
|
||||
f.reply()
|
||||
@@ -173,4 +177,4 @@ class WebMaster(flow.FlowMaster):
|
||||
|
||||
def add_event(self, e, level="info"):
|
||||
super(WebMaster, self).add_event(e, level)
|
||||
self.state.add_event(e, level)
|
||||
self.state.add_event(e, level)
|
||||
|
||||
@@ -25,6 +25,13 @@ class RequestHandler(tornado.web.RequestHandler):
|
||||
"style-src 'self' 'unsafe-inline'"
|
||||
)
|
||||
|
||||
@property
|
||||
def json(self):
|
||||
if not self.request.headers.get(
|
||||
"Content-Type").startswith("application/json"):
|
||||
return None
|
||||
return json.loads(self.request.body)
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
return self.application.master.state
|
||||
@@ -61,8 +68,10 @@ class FiltHelp(RequestHandler):
|
||||
commands=filt.help
|
||||
))
|
||||
|
||||
|
||||
class WebSocketEventBroadcaster(tornado.websocket.WebSocketHandler):
|
||||
connections = None # raise an error if inherited class doesn't specify its own instance.
|
||||
# raise an error if inherited class doesn't specify its own instance.
|
||||
connections = None
|
||||
|
||||
def open(self):
|
||||
self.connections.add(self)
|
||||
@@ -111,6 +120,42 @@ class FlowHandler(RequestHandler):
|
||||
self.flow.kill(self.master)
|
||||
self.state.delete_flow(self.flow)
|
||||
|
||||
def put(self, flow_id):
|
||||
flow = self.flow
|
||||
flow.backup()
|
||||
for a, b in self.json.iteritems():
|
||||
|
||||
if a == "request":
|
||||
request = flow.request
|
||||
for k, v in b.iteritems():
|
||||
if k in ["method", "scheme", "host", "path"]:
|
||||
setattr(request, k, str(v))
|
||||
elif k == "port":
|
||||
request.port = int(v)
|
||||
elif k == "httpversion":
|
||||
request.httpversion = tuple(int(x) for x in v)
|
||||
elif k == "headers":
|
||||
request.headers.load_state(v)
|
||||
else:
|
||||
print "Warning: Unknown update {}.{}: {}".format(a, k, v)
|
||||
|
||||
elif a == "response":
|
||||
response = flow.response
|
||||
for k, v in b.iteritems():
|
||||
if k == "msg":
|
||||
response.msg = str(v)
|
||||
elif k == "code":
|
||||
response.code = int(v)
|
||||
elif k == "httpversion":
|
||||
response.httpversion = tuple(int(x) for x in v)
|
||||
elif k == "headers":
|
||||
response.headers.load_state(v)
|
||||
else:
|
||||
print "Warning: Unknown update {}.{}: {}".format(a, k, v)
|
||||
else:
|
||||
print "Warning: Unknown update {}: {}".format(a, b)
|
||||
self.state.update_flow(flow)
|
||||
|
||||
|
||||
class DuplicateFlow(RequestHandler):
|
||||
def post(self, flow_id):
|
||||
@@ -124,6 +169,10 @@ class RevertFlow(RequestHandler):
|
||||
|
||||
class ReplayFlow(RequestHandler):
|
||||
def post(self, flow_id):
|
||||
self.flow.backup()
|
||||
self.flow.response = None
|
||||
self.state.update_flow(self.flow)
|
||||
|
||||
r = self.master.replay_request(self.flow)
|
||||
if r:
|
||||
raise APIError(400, r)
|
||||
@@ -176,18 +225,12 @@ class Settings(RequestHandler):
|
||||
)
|
||||
))
|
||||
|
||||
def put(self, *update, **kwargs):
|
||||
def put(self):
|
||||
update = {}
|
||||
for k, v in self.request.arguments.iteritems():
|
||||
if len(v) != 1:
|
||||
print("Warning: Unknown length for setting {}: {}".format(k, v))
|
||||
continue
|
||||
|
||||
if k == "_xsrf":
|
||||
continue
|
||||
elif k == "intercept":
|
||||
self.state.set_intercept(v[0])
|
||||
update[k] = v[0]
|
||||
for k, v in self.json.iteritems():
|
||||
if k == "intercept":
|
||||
self.state.set_intercept(v)
|
||||
update[k] = v
|
||||
else:
|
||||
print("Warning: Unknown setting {}: {}".format(k, v))
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ body,
|
||||
#container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
outline: none;
|
||||
}
|
||||
#container > header,
|
||||
#container > footer,
|
||||
@@ -60,7 +61,6 @@ body,
|
||||
flex: 1 1 auto;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
outline: 0;
|
||||
}
|
||||
.main-view.vertical {
|
||||
flex-direction: column;
|
||||
@@ -145,7 +145,7 @@ header .menu {
|
||||
padding-left: 2.5px;
|
||||
padding-right: 2.5px;
|
||||
}
|
||||
@media (min-width: 992px) {
|
||||
@media (min-width: 768px) {
|
||||
.filter-input {
|
||||
float: left;
|
||||
width: 25%;
|
||||
@@ -155,6 +155,7 @@ header .menu {
|
||||
top: 27px;
|
||||
display: block;
|
||||
max-width: none;
|
||||
opacity: 0.9;
|
||||
}
|
||||
.filter-input .popover .popover-content {
|
||||
max-height: 500px;
|
||||
@@ -271,7 +272,12 @@ header .menu {
|
||||
}
|
||||
.flow-detail {
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
overflow-x: auto;
|
||||
overflow-y: scroll;
|
||||
/*.request .response-line,
|
||||
.response .request-line {
|
||||
opacity: 0.7;
|
||||
}*/
|
||||
}
|
||||
.flow-detail nav {
|
||||
background-color: #F2F2F2;
|
||||
@@ -290,6 +296,25 @@ header .menu {
|
||||
max-height: 100px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.flow-detail .request-line {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.flow-detail hr {
|
||||
margin: 0 0 5px;
|
||||
}
|
||||
.inline-input {
|
||||
margin: 0 -5px;
|
||||
padding: 0 5px;
|
||||
}
|
||||
.inline-input[contenteditable] {
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
.inline-input[contenteditable].has-warning {
|
||||
color: #ffb8b8;
|
||||
}
|
||||
.view-options {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.flow-detail table {
|
||||
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
|
||||
width: 100%;
|
||||
@@ -306,6 +331,9 @@ header .menu {
|
||||
width: 50%;
|
||||
padding-right: 1em;
|
||||
}
|
||||
.header-table td {
|
||||
line-height: 1.3em;
|
||||
}
|
||||
.header-table .header-name {
|
||||
width: 33%;
|
||||
padding-right: 1em;
|
||||
@@ -316,6 +344,38 @@ header .menu {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.flowview-image {
|
||||
text-align: center;
|
||||
}
|
||||
.flowview-image img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
.prompt-dialog {
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
position: fixed;
|
||||
z-index: 100;
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.prompt-content {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 25px;
|
||||
padding: 2px 5px;
|
||||
background-color: white;
|
||||
box-shadow: 0 -1px 3px lightgray;
|
||||
}
|
||||
.prompt-content .option {
|
||||
cursor: pointer;
|
||||
}
|
||||
.prompt-content .option:not(:last-child)::after {
|
||||
content: ", ";
|
||||
}
|
||||
.eventlog {
|
||||
height: 200px;
|
||||
flex: 0 0 auto;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -945,12 +945,24 @@ th {
|
||||
.glyphicon-bitcoin:before {
|
||||
content: "\e227";
|
||||
}
|
||||
.glyphicon-btc:before {
|
||||
content: "\e227";
|
||||
}
|
||||
.glyphicon-xbt:before {
|
||||
content: "\e227";
|
||||
}
|
||||
.glyphicon-yen:before {
|
||||
content: "\00a5";
|
||||
}
|
||||
.glyphicon-jpy:before {
|
||||
content: "\00a5";
|
||||
}
|
||||
.glyphicon-ruble:before {
|
||||
content: "\20bd";
|
||||
}
|
||||
.glyphicon-rub:before {
|
||||
content: "\20bd";
|
||||
}
|
||||
.glyphicon-scale:before {
|
||||
content: "\e230";
|
||||
}
|
||||
@@ -1147,6 +1159,9 @@ hr {
|
||||
overflow: visible;
|
||||
clip: auto;
|
||||
}
|
||||
[role="button"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
@@ -2548,10 +2563,13 @@ output {
|
||||
.form-control[disabled],
|
||||
.form-control[readonly],
|
||||
fieldset[disabled] .form-control {
|
||||
cursor: not-allowed;
|
||||
background-color: #eeeeee;
|
||||
opacity: 1;
|
||||
}
|
||||
.form-control[disabled],
|
||||
fieldset[disabled] .form-control {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
textarea.form-control {
|
||||
height: auto;
|
||||
}
|
||||
@@ -2618,6 +2636,7 @@ input[type="search"] {
|
||||
}
|
||||
.radio-inline,
|
||||
.checkbox-inline {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
padding-left: 20px;
|
||||
margin-bottom: 0;
|
||||
@@ -2654,6 +2673,7 @@ fieldset[disabled] .checkbox label {
|
||||
padding-top: 7px;
|
||||
padding-bottom: 7px;
|
||||
margin-bottom: 0;
|
||||
min-height: 34px;
|
||||
}
|
||||
.form-control-static.input-lg,
|
||||
.form-control-static.input-sm {
|
||||
@@ -2695,6 +2715,7 @@ select[multiple].form-group-sm .form-control {
|
||||
padding: 5px 10px;
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
min-height: 32px;
|
||||
}
|
||||
.input-lg {
|
||||
height: 46px;
|
||||
@@ -2731,6 +2752,7 @@ select[multiple].form-group-lg .form-control {
|
||||
padding: 10px 16px;
|
||||
font-size: 18px;
|
||||
line-height: 1.3333333;
|
||||
min-height: 38px;
|
||||
}
|
||||
.has-feedback {
|
||||
position: relative;
|
||||
@@ -3348,11 +3370,9 @@ input[type="button"].btn-block {
|
||||
}
|
||||
.collapse {
|
||||
display: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
.collapse.in {
|
||||
display: block;
|
||||
visibility: visible;
|
||||
}
|
||||
tr.collapse.in {
|
||||
display: table-row;
|
||||
@@ -3377,7 +3397,7 @@ tbody.collapse.in {
|
||||
height: 0;
|
||||
margin-left: 2px;
|
||||
vertical-align: middle;
|
||||
border-top: 4px solid;
|
||||
border-top: 4px dashed;
|
||||
border-right: 4px solid transparent;
|
||||
border-left: 4px solid transparent;
|
||||
}
|
||||
@@ -4016,11 +4036,9 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
|
||||
}
|
||||
.tab-content > .tab-pane {
|
||||
display: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
.tab-content > .active {
|
||||
display: block;
|
||||
visibility: visible;
|
||||
}
|
||||
.nav-tabs .dropdown-menu {
|
||||
margin-top: -1px;
|
||||
@@ -4062,7 +4080,6 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
|
||||
}
|
||||
.navbar-collapse.collapse {
|
||||
display: block !important;
|
||||
visibility: visible !important;
|
||||
height: auto !important;
|
||||
padding-bottom: 0;
|
||||
overflow: visible !important;
|
||||
@@ -4791,7 +4808,8 @@ a.label:focus {
|
||||
position: relative;
|
||||
top: -1px;
|
||||
}
|
||||
.btn-xs .badge {
|
||||
.btn-xs .badge,
|
||||
.btn-group-xs > .btn .badge {
|
||||
top: 0;
|
||||
padding: 1px 5px;
|
||||
}
|
||||
@@ -5614,10 +5632,10 @@ a.list-group-item-danger.active:focus {
|
||||
width: 100%;
|
||||
border: 0;
|
||||
}
|
||||
.embed-responsive.embed-responsive-16by9 {
|
||||
.embed-responsive-16by9 {
|
||||
padding-bottom: 56.25%;
|
||||
}
|
||||
.embed-responsive.embed-responsive-4by3 {
|
||||
.embed-responsive-4by3 {
|
||||
padding-bottom: 75%;
|
||||
}
|
||||
.well {
|
||||
@@ -5678,7 +5696,7 @@ button.close {
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1040;
|
||||
z-index: 1050;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
outline: 0;
|
||||
}
|
||||
@@ -5719,10 +5737,12 @@ button.close {
|
||||
outline: 0;
|
||||
}
|
||||
.modal-backdrop {
|
||||
position: absolute;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1040;
|
||||
background-color: #000000;
|
||||
}
|
||||
.modal-backdrop.fade {
|
||||
@@ -5793,7 +5813,6 @@ button.close {
|
||||
position: absolute;
|
||||
z-index: 1070;
|
||||
display: block;
|
||||
visibility: visible;
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
@@ -6316,7 +6335,6 @@ button.close {
|
||||
}
|
||||
.hidden {
|
||||
display: none !important;
|
||||
visibility: hidden !important;
|
||||
}
|
||||
.affix {
|
||||
position: fixed;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user