Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sandbox class wraps/overrides RepyV1 calls #3

Open
aaaaalbert opened this issue Mar 17, 2017 · 0 comments
Open

Sandbox class wraps/overrides RepyV1 calls #3

aaaaalbert opened this issue Mar 17, 2017 · 0 comments

Comments

@aaaaalbert
Copy link
Contributor

See

try-repyV2/tr_sandbox.r2py

Lines 16 to 223 in 95bf161

class Sandbox:
"""
<Purpose>
A Sandbox is an isolated space that each user receives when requesting
the Try Repy webinterface. Each Sandbox has its own context to evaluate
Repy code using VitualNamespaces and some logging facilities.
Additionally the Sandbox wraps used Repy functions, mainly in order to isolate
it from other Sandboxes.
<Example Use>
Creation
Sandbox(user_id, context_dictionary, global_runtime)
Evaluation
Sandbox.evaluate(code, callargs)
Retrieve Current Log Buffer
Sandbox.getLog()
...
"""
def __init__(self, user_id, context, global_runtime):
"""
<Purpose>
Sandbox Constructor
It wraps the Sandboxes Context Functions and instantiates
variables and locks for logging and thread accounting.
<Arguments>
user_id (string)
context (dict)
A copy of a clean context, in which global functions dedicated
to the webcontroller are not included.
global_runtime (float)
Used to wrap the Sandboxes runtime.
"""
self.user = user_id
self.context = context
# Prepare the sandbox context
self.context_wrap()
self.start_time = getruntime() - global_runtime
self.log = {}
self.log_lock = createlock()
self.tmp_logtime = ""
self.tmp_output_buffer = ""
self.lock_output_buffer = createlock()
# Used for thread accounting
self.thread_count = 0
self.thread_lock = createlock()
self.thread_accounting_lock = createlock()
def my_log(self, *args):
"""
<Purpose>
Override The Repy log function to safe the evaluation output
to a log dictionary and a current log buffer.
<Arguments>
*args
The output which would be normally written to stdout.
"""
self.log_lock.acquire(True)
for arg in args:
if arg != self:
self.log[self.tmp_logtime]["output"] += str(arg) + " "
self.write_output_buffer( (str(arg) + " ") )
self.log[self.tmp_logtime]["output"] += "\n"
self.write_output_buffer("\n")
self.log_lock.release()
def context_wrap(self):
"""
<Purpose>
This makes sure that a Sandbox context is completely isolated
from other contexti.
Per default a Context copy is a shallow copy. Here we make sure
that deeper layers of the Context do not contain any References
shared between the contexti.
Additionally we wrap most of the repy functions to perform according
to our custom needs.
"""
#Initialize clean mycontext dict and callargs list
self.context["mycontext"] = {}
self.context["callargs"] = []
##
# General wrappers
def wrapped_log(*args):
self.my_log(*args)
self.context["log"] = wrapped_log
def wrapped_getruntime():
return (getruntime() - self.start_time)
self.context["getruntime"] = wrapped_getruntime
# This prevents user from kill the entire Application.
def wrapped_exitall():
pass
self.context["exitall"] = wrapped_exitall
##
# File wrappers
def wrapped_listdir():
return tr_listdir(self.user)
self.context["listdir"] = wrapped_listdir
def wrapped_open(*args):
return tr_open(self.user, *args)
self.context["open"] = wrapped_open
def wrapped_removefile(*args):
return tr_removefile(self.user, *args)
self.context["removefile"] = wrapped_removefile
##
# Timer wrappers
def wrapped_settimer(time, callbackfunction, args):
self.thread_register()
def wrapped_callbackfunction(*args):
try:
callbackfunction(*args[0])
except Exception, e:
# What do I do with this exception?
# A caught exception should bring the programm down.
# But for the moment it is only printed to the Shell
# were the webcontroller is called.
error_message = "ThreadException: " + str(e) + \
"\nCaution: Other threads could still be running!"
self.my_log(error_message)
self.thread_deregister()
return settimer(time, wrapped_callbackfunction, [args])
self.context['settimer'] = wrapped_settimer
def wrapped_canceltimer(timerhandle):
ret = canceltimer(timerhandle)
if ret:
self.thread_deregister()
return ret
self.context['canceltimer'] = wrapped_canceltimer
##
# Network wrappers
def wrapped_stopcomm(commhandle):
ret = stopcomm(commhandle)
if ret:
self.thread_deregister()
return ret
self.context['stopcomm'] = wrapped_stopcomm
def wrapped_recvmess(localip, localport, function):
self.thread_register() # This registers the listening thread
def wrapped_callback_udp(remIP, remport, message, commhandle):
self.thread_register()
try:
function(remIP, remport, message, commhandle)
except Exception, e:
# What do I do with this exception?
# A caught exception should bring the programm down.
# But for the moment it is only printed to the Shell
# were the webcontroller is called.
error_message = "ThreadException: " + str(e) + \
"\nCaution: Other threads could still be running!"
self.my_log(error_message)
self.thread_deregister()
return recvmess(localip, localport, wrapped_callback_udp)
self.context['recvmess'] = wrapped_recvmess
def wrapped_waitforconn(ip, port, callbackfunction):
self.thread_register()
def wrapped_callback_tcp(remip, remport, so, thishandle, listenhandle):
self.thread_register()
try:
callbackfunction(remip, remport, so, thishandle, listenhandle)
except Exception, e:
# What do I do with this exception?
# A caught exception should bring the programm down.
# But for the moment it is only printed to the Shell
# were the webcontroller is called.
error_message = "ThreadException: " + str(e) + \
"\nCaution: Other threads could still be running!"
self.my_log(error_message)
log("Exception: " + str(e))
self.thread_deregister()
return waitforconn(ip, port, wrapped_callback_tcp)
self.context['waitforconn'] = wrapped_waitforconn

This includes stopcomm, settimer, recvmess.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant