In my implementation of this solution, it is a slight danger of code injection, but only in the sense that *existing methods can be called with bunk data*. Methods that are not implemented by the protocol (and thus destination) are ignored when received over the network. However, this connection between 2 Cocoa apps can further be secured by using SSL with AsyncSocket (it just uses CFSocket and friends, so it should be fairly straightforward, at least as far as SSL goes).
-Steven On Wed, Jan 20, 2010 at 3:15 PM, nicolas berloquin <cepak...@gmail.com>wrote: > This is a genuine question/remark that pops up. No check is done on what > selector or object is returned or is it ? > If this is done on a public service (web server or other), couldn't code > injection be too easilly done that way ? (easy hacking, wilfull crash etc) ? > > > Le 20 janv. 2010 à 19:47, Steven Degutis <steven.degu...@gmail.com> a > écrit : > > Oops, correction: the downside is that all arguments and return values >> need >> to conform to NSCoder protocol. So, it's even more strict than I described >> earlier. But it's still cool :) >> >> -Steven >> >> On Wed, Jan 20, 2010 at 12:40 PM, Steven Degutis >> <steven.degu...@gmail.com>wrote: >> >> Recently I had the same issue you were having, sort of. And I came up >>> with >>> a solution I really liked. >>> >>> When I was playing with Distributed Objects, I fell in love with the >>> abstract simplicity. However, it blocks and that's bad. It's even worse >>> when >>> the server stops responding, because you could potentially have a 60 >>> second >>> timeout before the single method will return. It's a potential disaster. >>> >>> So, I wrote an elegant compromise. Code is still written inline, no >>> callbacks or delegate messages needed. But, it requires Blocks (and thus >>> 10.6) to work. >>> >>> Essentially, I wrote some code on top of AsyncSocket (which is a >>> brilliant >>> framework by the way) that allows me to wrap up ObjC messages as NSData, >>> send it across the server, and unpack it on the other side. The other >>> side >>> then responds to the ObjC message as if it was called right inside the >>> application. (All this is thanks to NSInvocation's ability to introspect >>> an >>> ObjC message, by the way). >>> >>> The problem came when I had to return values. As long as the return value >>> was void, this worked like a charm. But once I wanted to return an array >>> of >>> strings or a number, I had to define a method in the sender's protocol to >>> receive such information. This is akin to your "thousands of delegate >>> messages" you would have to implement, as you stated. >>> >>> So, using Blocks and NSInvocation and AsyncSocket, I ended up writing >>> code >>> that allows me to write code like this: >>> >>> >>> // protocol.h >>> >>> @protocol ServerProtocol >>> >>> - (NSNumber*) calculatePiAndKillTime:(NSNumber*)shouldKillTime; >>> >>> @end >>> >>> >>> // client.m >>> >>> - (void) someMethod { >>> id <ServerProtocol> server; >>> NSNumber *sure = [NSNumber numberWithBool:YES]; >>> [[server calculatePiAndKillTime: sure] >>> returnedValue:^(id value) { >>> // this will be called later on at some point >>> NSLog(@"pi = %@", value); >>> }] >>> } >>> >>> >>> // server.m >>> >>> - (NSNumber*) calculatePiAndKillTime:(NSNumber*)shouldKillTime { >>> if ([shouldKillTime boolValue]) >>> // synchronously watch some film >>> [self goWatchTheNewStarTrekFilmFrom2009]; >>> >>> return [NSNumber numberWithFloat: 3.14]; >>> } >>> >>> >>> >>> All methods sent to a destination's proxy are sent asynchronously. And, >>> as >>> you can see, the return value of the method -calculatePiAndKillTime: is >>> not >>> actually an NSNumber, but rather a proxy that waits for a response from >>> the >>> destination. When the destination responds to the source with a return >>> value, the method -returnedValue: is called with the value. >>> >>> But that's only half of the coolness. >>> >>> The other half is that methods can simply return the value they want >>> right >>> inside the method, no hacks necessary or anything by the programmer. In >>> this >>> case, we just use this line of code: return [NSNumber numberWithFloat: >>> 3.14]; and then the NSNumber object is packaged up and sent back to the >>> source through the proxy, all automagically. >>> >>> The main downfall of this is that every argument and return value must be >>> an ObjC type, no scalars or structs or anything else will work with this >>> system. (Mike Ash explains pretty well on this blog why trying to support >>> those things can lead to some unfixable trickiness, which I just wanted >>> to >>> avoid altogether.) >>> >>> If you can't support 10.6, then, this won't work. But hopefully you can >>> soon ;) >>> >>> Good luck. >>> >>> -Steven >>> >>> >>> >>> On Wed, Jan 20, 2010 at 11:39 AM, Carter R. Harrison < >>> carterharri...@mac.com> wrote: >>> >>> I need some folks experienced with cocoa and socket programming to weigh >>>> in for me on some design problems I've been having. I'm designing an >>>> application that acts as a client in a client-server model. The client >>>> communicates with the server over the network by issuing a request and >>>> then >>>> receiving a response. Requests can only be issued one at a time, >>>> meaning >>>> that a request cannot be sent until a response from any outstanding >>>> request >>>> is first received. My application works in such a way that the it could >>>> request a handle to an object on the server and then use that handle in >>>> subsequent requests to retrieve additional information about the object. >>>> I >>>> see two ways of modeling the application - I've tried both and I'm not >>>> particularly happy with either. >>>> >>>> The first is to send a request, and then have the socket block until a >>>> response is received. This benefit to this model is that it is so much >>>> easier to write the higher level application code. The issue with this >>>> model is that over a slow network connection it can take a considerable >>>> amount of time for the response to come back from the server and while >>>> that >>>> is happening my CPU usage is through the roof b/c the thread is >>>> blocking. >>>> >>>> The second way is to send a request and then let the NSInputStream call >>>> a >>>> delegate method when the response data is available. The response data >>>> is >>>> then pushed up through my protocol stack and finally up to the higher >>>> level >>>> application code. The benefit to this method is that CPU usage is >>>> minimal >>>> due to the fact that I'm no longer blocking, but the downside is that >>>> the >>>> higher level application code is so much more difficult to write because >>>> I >>>> have to write about a thousand methods to act as a callback for each >>>> request >>>> in a series of requests. >>>> >>>> I've provided an example of how I see each working below. My first >>>> question is, is there other ways to design an application around this >>>> client-server model that I'm not thinking about? My 2nd question is, if >>>> there aren't other ways, how can I adapt either method that I have >>>> outlined >>>> to make it work a little bit better? >>>> >>>> As an example let's say the server knows about the following objects: >>>> >>>> 1. VendingMachine >>>> - An object that represents a vending machine. >>>> - A vending machine contains Soft Drink objects. >>>> 2. SoftDrink >>>> - Has the following properties: drink name, price, number of >>>> calories. >>>> >>>> If I use the blocking model, I could write my code like this. The code >>>> is >>>> simple to write but I'm forced to wait for the server to respond with >>>> information on pretty much every line of code. If the vending machine >>>> had >>>> enough soft drinks it could take a long time to iterate over each one >>>> and >>>> have the server respond with the drink's name of each drink. >>>> >>>> -(void)printDrinkNames >>>> { >>>> VendingMachine *machine = [server fetchVendingMachine]; >>>> NSArray *softDrinks = [machine getSoftDrinks]; >>>> for (int i = 0 ; i < softDrinks.count ; i++) >>>> { >>>> NSString *drinkName = [[softDrinks objectAtIndex:i] name]; >>>> NSLog(@"Found a drink named %@", drinkName); >>>> } >>>> } >>>> >>>> Likewise if I do the non-blocking approach I would have to have a method >>>> that gets called for each step in the process (see below). This model >>>> drives me crazy b/c the higher level application code is long, has tons >>>> of >>>> methods, and is just difficult to read and maintain. The example I have >>>> provided is simple enough to get the point across, but in reality some >>>> of >>>> the processes I'm trying to drive are much more complex and require >>>> numerous >>>> callback methods to pull off. >>>> >>>> -(void)printDrinkNames >>>> { >>>> [server fetchVendingMachineWithCallBackObject:self >>>> selector:@selector(didFetchVendingMachine:) >>>> } >>>> >>>> -(void)didFetchVendingMachine:(VendingMachine *)machine >>>> { >>>> [machine fetchSoftDrinksWithCallBackObject:self selector:@selector >>>> (didFetchSoftDrinks:)]; >>>> } >>>> >>>> -(void)didFetchSoftDrinks:(NSArray *)drinks >>>> { >>>> for (int i = 0 ; i < drinks.count ; i++) >>>> { >>>> SoftDrink *drink = [drinks objectAtIndex:i]; >>>> [drink fetchNameWithCallBackObject:self selector:@selector >>>> (didFetchDrinkName:)] >>>> } >>>> } >>>> >>>> -(void)didFetchDrinkName:(NSString *)name >>>> { >>>> NSLog(@"Drink name is %@", name); >>>> } >>>> >>>> _______________________________________________ >>>> >>>> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) >>>> >>>> Please do not post admin requests or moderator comments to the list. >>>> Contact the moderators at cocoa-dev-admins(at)lists.apple.com >>>> >>>> Help/Unsubscribe/Update your Subscription: >>>> >>>> >>>> http://lists.apple.com/mailman/options/cocoa-dev/steven.degutis%40gmail.com >>>> >>>> This email sent to steven.degu...@gmail.com >>>> >>>> >>> >>> >>> -- >>> Steven Degutis >>> http://www.thoughtfultree.com/ >>> http://www.degutis.org/ >>> >>> >> >> >> -- >> Steven Degutis >> http://www.thoughtfultree.com/ >> http://www.degutis.org/ >> _______________________________________________ >> >> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) >> >> Please do not post admin requests or moderator comments to the list. >> Contact the moderators at cocoa-dev-admins(at)lists.apple.com >> >> Help/Unsubscribe/Update your Subscription: >> http://lists.apple.com/mailman/options/cocoa-dev/cepakare%40gmail.com >> >> This email sent to cepak...@gmail.com >> > -- Steven Degutis http://www.thoughtfultree.com/ http://www.degutis.org/ _______________________________________________ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com