diff --git a/libmproxy/console/common.py b/libmproxy/console/common.py index 12fdfe27e..f28db013f 100644 --- a/libmproxy/console/common.py +++ b/libmproxy/console/common.py @@ -276,27 +276,30 @@ def copy_flow_format_data(part, scope, flow): raise ValueError("Unknown part: {}".format(part)) return data, False +def copy_as_curl_command(flow): -def copy_flow(part, scope, flow, master, state): - """ - part: _c_ontent, _h_eaders+content, _u_rl - scope: _a_ll, re_q_uest, re_s_ponse - """ - data, err = copy_flow_format_data(part, scope, flow) + if flow.request.content is None or flow.request.content == CONTENT_MISSING: + return None, "Request content is missing" - if err: - signals.status_message.send(message=err) - return + headerString = "" + for k,v in flow.request.headers: + headerString += " -H \"" + k + ":" + v + "\" " - if not data: - if scope == "q": - signals.status_message.send(message="No request content to copy.") - elif scope == "s": - signals.status_message.send(message="No response content to copy.") - else: - signals.status_message.send(message="No contents to copy.") - return + data = "curl" + if flow.request.method != "GET": + data += " -X " + flow.request.method + + full_url = flow.request.scheme + "://" + flow.request.host + flow.request.path + data += headerString + " \"" + full_url + "\"" + + if flow.request.content != None and flow.request.content != "": + data += " --data-binary " + "'" + flow.request.content + "'" + + copy_to_clipboard_or_prompt(data) + + +def copy_to_clipboard_or_prompt(data): # pyperclip calls encode('utf-8') on data to be copied without checking. # if data are already encoded that way UnicodeDecodeError is thrown. toclip = "" @@ -320,6 +323,28 @@ def copy_flow(part, scope, flow, master, state): callback = save ) +def copy_flow(part, scope, flow, master, state): + """ + part: _c_ontent, _h_eaders+content, _u_rl + scope: _a_ll, re_q_uest, re_s_ponse + """ + data, err = copy_flow_format_data(part, scope, flow) + + if err: + signals.status_message.send(message=err) + return + + if not data: + if scope == "q": + signals.status_message.send(message="No request content to copy.") + elif scope == "s": + signals.status_message.send(message="No response content to copy.") + else: + signals.status_message.send(message="No contents to copy.") + return + + copy_to_clipboard_or_prompt(data) + def ask_copy_part(scope, flow, master, state): choices = [ diff --git a/libmproxy/console/flowlist.py b/libmproxy/console/flowlist.py index 2b77f4a37..6edf5212e 100644 --- a/libmproxy/console/flowlist.py +++ b/libmproxy/console/flowlist.py @@ -13,6 +13,7 @@ def _mkhelp(): ("A", "accept all intercepted flows"), ("a", "accept this intercepted flow"), ("b", "save request/response body"), + ("Z", "copy request as curl command"), ("C", "clear flow list or eventlog"), ("d", "delete flow"), ("D", "duplicate flow"), @@ -254,6 +255,8 @@ class ConnectionItem(urwid.WidgetWrap): ) elif key == "P": common.ask_copy_part("a", self.flow, self.master, self.state) + elif key == "Z": + common.copy_as_curl_command(self.flow) elif key == "b": common.ask_save_body(None, self.master, self.state, self.flow) else: diff --git a/libmproxy/console/flowview.py b/libmproxy/console/flowview.py index 0038558b9..518817d47 100644 --- a/libmproxy/console/flowview.py +++ b/libmproxy/console/flowview.py @@ -25,6 +25,7 @@ def _mkhelp(): ("A", "accept all intercepted flows"), ("a", "accept this intercepted flow"), ("b", "save request/response body"), + ("Z", "copy as curl command"), ("d", "delete flow"), ("D", "duplicate flow"), ("e", "edit request/response"), @@ -574,6 +575,8 @@ class FlowView(tabs.Tabs): callback = self.master.save_one_flow, args = (self.flow,) ) + elif key == "Z": + common.copy_as_curl_command(self.flow) elif key == "|": signals.status_prompt_path.send( prompt = "Send flow to script",