A fork of pappy proxy
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

110 lines
3.6 KiB

import sys
import base64
import json
from twisted.protocols.basic import LineReceiver
from twisted.internet import defer
from util import PappyException
"""
comm.py
Handles creating a listening server bound to localhost that other processes can
use to interact with the proxy.
"""
debug = True
class CommServer(LineReceiver):
MAX_LENGTH=sys.maxint
def __init__(self):
self.delimiter = '\n'
self.action_handlers = {
'ping': self.action_ping,
'get_request': self.action_get_request,
'get_response': self.action_get_response,
'submit': self.action_submit_request,
}
def lineReceived(self, line):
line = line.strip()
if line == '':
return
try:
command_data = json.loads(line)
command = command_data['action']
valid = False
if command in self.action_handlers:
valid = True
result = {'success': True}
func_defer = self.action_handlers[command](command_data)
func_defer.addCallback(self.action_result_handler, result)
func_defer.addErrback(self.action_error_handler, result)
if not valid:
raise PappyException('%s is an invalid command' % command_data['action'])
except PappyException as e:
return_data = {'success': False, 'message': str(e)}
self.sendLine(json.dumps(return_data))
def action_result_handler(self, data, result):
result.update(data)
self.sendLine(json.dumps(result))
def action_error_handler(self, error, result):
if debug:
print error.getTraceback()
return_data = {'success': False, 'message': str(error.getErrorMessage())}
result.update(result)
error.trap(Exception)
self.sendLine(json.dumps(return_data))
return True
def action_ping(self, data):
return defer.succeed({'ping': 'pong'})
@defer.inlineCallbacks
def action_get_request(self, data):
from .http import Request
try:
reqid = data['reqid']
req = yield Request.load_request(reqid)
except KeyError:
raise PappyException("Request with given ID does not exist")
dat = json.loads(req.to_json())
defer.returnValue(dat)
@defer.inlineCallbacks
def action_get_response(self, data):
from .http import Request, Response
try:
reqid = data['reqid']
req = yield Request.load_request(reqid)
except KeyError:
raise PappyException("Request with given ID does not exist, cannot fetch associated response.")
if req.response:
rsp = yield Response.load_response(req.response.rspid)
dat = json.loads(rsp.to_json())
else:
dat = {}
defer.returnValue(dat)
@defer.inlineCallbacks
def action_submit_request(self, data):
from .http import Request
message = base64.b64decode(data['full_message'])
try:
req = yield Request.submit_new(data['host'].encode('utf-8'), data['port'], data['is_ssl'], message)
except Exception:
raise PappyException('Error submitting request. Please make sure request is a valid HTTP message.')
if 'tags' in data:
req.tags = set(data['tags'])
yield req.async_deep_save()
retdata = {}
retdata['request'] = json.loads(req.to_json())
if req.response:
retdata['response'] = json.loads(req.response.to_json())
defer.returnValue(retdata)