[Cosmo-dev] JSON-RPC considered harmful

Mikeal Rogers mikeal at osafoundation.org
Tue Dec 5 22:19:32 PST 2006


I'm trying to work through all of this.

Are we actually going to implement another RPC interface, other than  
our current public JSON-RPC interface, that returns JSON?

Why is this better or easier than expanding our current public JSON- 
RPC interface.

I have a few alternative suggestions but first I wanted to know; do  
we ever use GET for JSON-RPC or strictly POST? And do we have any  
plans to support GET per the JSON-RPC 1.1 spec?

-Mikeal


On Dec 5, 2006, at 6:07 PM, Travis Vachon wrote:

> Hi folks
>
> I've started design work for bug 7370. For background, please check  
> out:
> http://wiki.osafoundation.org/bin/view/Journal/ 
> BrianMoseleyCosmoCasualCollaborator (ticket vs. login)
> https://bugzilla.osafoundation.org/show_bug.cgi?id=7370
> http://wiki.osafoundation.org/bin/view/Journal/ZeroSixTaskBreakdown  
> ( anonymous access)
>
> The problem is to allow clients (in this case, the PIM ui) read or  
> write access to collections based on a ticket id.
>
> Currently, ticketed access to collections relies on information  
> presented in the url. For example, if I request /cosmo/collection/ 
> {collectionId}?ticket={ticketId}, the TicketAuthenticationProvider  
> pulls the collectionId and ticketId out of the url and makes a  
> decision to allow access based on this information.
>
> Problem is, the PIM ui uses JSON-RPC, which always makes a request  
> to /cosmo/JSON-RPC. This means the collection and ticket  
> information would need to be embedded either in a headers or in the  
> JSON content body of the request.
>
> There are a couple problems with doing either of these:
>
> headers - we already have the collectionId in the content body. If  
> we duplicate this information, we run into problems where a  
> malicious user could specify different collectionIds in the header  
> and JSON content body. We could work around this, making sure the  
> two match, but this would require parsing JSON in the  
> TicketAuthenticationProvider. We could also just ignore the  
> collectionId in the content body, but this would require some ugly  
> retooling of the JSON service. The necessity of having these  also  
> begs the question of why we are even using JSON.
>
> JSON content body - this would definitely require parsing the JSON  
> in the TicketAuthenticationProvider. If we're ok doing this, this  
> might be the most expedient way to get this feature working. That  
> said, Bobby and I agree that this isn't a great solution. First,  
> we're parsing JSON twice over the course of the request (once in  
> the TicketAuthenticationProvider and once in the RPCService). Next,  
> the JSON-RPC method signatures wouldn't necessarily guarantee a  
> position for the ticket id, so figuring out exactly where in the  
> content body the ticket lives would be dicey at best.
>
> Given this, Bobby and I are of the opinion that it would be more  
> worth our time to start moving away from JSON-RPC. Leaving the  
> current system in place, we would add on the new functionality we  
> need by implementing an HTTP based protocol which would return JSON  
> identical to the JSON currently returned by the ScoobyService object.
>
> To start (to fix 7370), we would implement the following requests,  
> each of which corresponds to a current JSON-RPC method;
>
> getEvent(calendarName, id) -> (GET /item/{itemUid}?ticket={ticketId}
> getEvents(calendarPath, beginDate, endDate) -> (GET /collection/ 
> {collectionUid}?bDate={beginDate}&eDate={endDate}&ticket={ticketId}
> saveEvent(calendarPath, event) -> PUT /item/{collectionUid}/ 
> {itemUid} w/ JSON item representation as content
> removeEvent(calendarPath, event) -> DELETE /item/{itemUid}
> getRecurrenceRules(calendarPath, eventIds) -> GET /item/{itemUid}/ 
> recurrence?iid={e1}&iid={e2}&...&iid={eN}
> saveRecurrenceRule(calendarPath, eventId, recurrenceRule) -> PUT / 
> item/{itemUid}/recurrence w/ JSON recurrenceRule representation as  
> content
> expandEvents(calendarPath, eventIds, utcStartTime, utcEndTime) ->
> 	GET /collection/{collectionUid}?iid={e1}&iid={e2}&...&iid={eN} 
> &stime={startTime}&etime={endTime}
> saveNewEventBreakRecurrence(String calendarPath, event,  
> originalEventId, originalEventEndDate) ->
> 	PUT /breakevent/{originalEventUid}?date=originalEventEndDate w/  
> JSON event as content
>
> You'll notice this scheme also takes into account the work I'm  
> going to be doing for bug 7405 (RPC calls by ID not path). I'm  
> probably going to fix 7405 before moving ahead with 7370, since it  
> will makes things considerably less confusing and prevent  
> duplication of effort.
>
> Finally, you'll notice some of these requests use methods other  
> than GET or POST. This is a problem for safari. Google has solved  
> this problem in their GData protocol with a new header X-HTTP- 
> Method-Override (http://code.google.com/apis/gdata/ 
> protocol.html#Updating-an-entry). I worked on this idea  a couple  
> months ago after talking with BCM, and have a ServletFilter  
> implemented that will provide this functionality, it just needs to  
> be checked in.
>
> These would used by any Calendars on the client side that require  
> ticket based access. Bobby has a few ideas about the specifics  
> about how this should be designed in the short term on the client  
> side, but I'd like to leave that for a future e-mail.
>
> We've been talking this through quite a bit today, and would  
> definitely like feedback. Thoughts?
>
> Thanks,
>
> Travis
> _______________________________________________
> cosmo-dev mailing list
> cosmo-dev at lists.osafoundation.org
> http://lists.osafoundation.org/mailman/listinfo/cosmo-dev



More information about the cosmo-dev mailing list