A new patch is attached. On Thu, 30 Dec 2004 09:57:49 -0600, Justin Johnson <justinjohnson@gmail.com> wrote:
Option 1 is also most like the way things work today for sending anything that isn't an error. The only reason CopyableFailure exists is because you HAVE to send a failure. Whether it is jelly/unjellyable or not, the other end must be informed of errors. But as soon as a developer decides to make their errors copyable, they have in effect agreed that they are responsible for testing the unjellying on the other end.
On Thu, 30 Dec 2004 09:48:17 -0600, Justin Johnson <justinjohnson@gmail.com> wrote:
I agree. I did some testing to verify what you were saying. So this is basically reiterating everything you just said, but just for clarification for myself... in the current non-patched code the following happens:
When the server encounters an error while calling a method that was invoked from a remote client, it will... 1) Wrap all subclasses of pb.Error in a pb.CopyableFailure, thus replacing actual pb.Error instances with a string representation of them. 2) Return a new (non-wrapping) pb.CopyableFailure for all other errors, thus including stack trace, etc.
When the server needs to send anything else back to the client, if it is a subclass of flavors.Jellyable it sends it back. Otherwise it raises InsecureJelly on the server side.
On the client side it will unjelly the thing sent across if it can (i.e. if setUnjellyableForClass was called). Otherwise it raises an InsecureJelly on the client side.
So it seems like these are our options:
1) If an error is Jellyable, send it and assume the client will either unjelly it or deal with unjellying errors.
2) If an error is Jellyable, send it. If the client fails to unjelly it, communicate back to the server who then sends a CopyableFailure wrapping the original error.
3) If an error is Jellyable, send both it and a CopyableFailure wrapping the original error. The client can then first try to unjelly the error and fall back to the CopyableFailure that was passed along.
I vote for option 1. Options 2 and 3 seem somewhat hacky to me.
-Justin
On 29 Dec 2004 21:31:17 -0500, David Bolen <db3l@fitlinxx.com> wrote:
Justin Johnson <justinjohnson@gmail.com> writes:
In my testing it seemed that I would get an InsecureJelly error on the sending side if I tried to send back an object that I hadn't called pb.setUnjellyableForClass on the sending side for. In other words, calling setUnjellyableForClass on the sending side was a way of saying that it was okay to send over the wire, and also a way of registering what class to use when unjellying it if it were received.
Is this not correct?
I believe the only purpose of setUnjellyableForClass is to establish what to do for unjellying. While it does also impact the global security options (which do get checked during jellying) the way it stores type information in there is only matched during unjellying, at least in my experience (it adds permission for the type but not the instance).
I believe the only (typical) requirement to support jellying an object is that it be a class that is a jelly.Jellyable subclass (such as any of the remoteable flavors like Copyable, Referenceable, etc...). Nothing else should be needed on the server side.
I just tried a quick tweak to your s/e/c.py modules so that s.py returned an instance of a dummy class defined in e.py instead of an error, and it seems to work fine even if the server side (s) hasn't issued the setUnjellyableForClass call. Without that call, the client will raise the error after receiving the object. And even if the server does issue that call, if the dummy class isn't inheriting from Copyable, the insecure error is generated on the transmitting side.
It is, however, possible to insert additional types/classes/modules into the global security options independent of class inheritance from Jellyable. This is how all the basic Python types are handled, but it can be extended to support your own classes (although I had a problem with extension classes/types, since I originally tried to use this to support mxDateTime objects without modifying jelly).
So for example, if I have my test class "MyObject" in e.py, and instead of setUnjellyableForClass, I use something like "jelly.globalSecurity.allowInstancesOf(MyObject)", then the object will still be successfully sent and received (providing the instance data can also be jellied).
So after writing this, the fact that the security options could get used to permit an instance (that isn't of a subclass of Jellyable) to be encoded might mean that just verifying Jellyable (ala my last response to Christopher) is insufficient, at least technically.
Perhaps the only true way to determine if something is jellyable is to try to jelly it (heck, that's probably more Pythonic anyway), and just handle an exception as a fallback to the string representation.
-- David
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python