[Ur] redirect breaks channels
Sergey Mironov
grrwlf at gmail.com
Tue Dec 24 19:24:21 EST 2013
OK, I've looked under the hood and now I see that my application is
invalid because we can't call recv() on channels obtained from
anywhere but the channel call. I agree, that otherwise we would
provoke a security weakness. But also it means that channel API
signatures (in basis.urs) do not describe the server-side
implementation correctly. I would suggest writing something like
con channel :: Type -> Type
con channelw :: Type -> Type (* the write end of a channel *)
val channel : t ::: Type -> transaction (channel t)
val channelw : t ::: Type -> channel t -> channelw t
val send : t ::: Type -> channelw t -> t -> transaction unit
val recv : t ::: Type -> channel t -> transaction t
and define sqlifiers for 'channelw' but not for 'channel' to forbid
calling recv on anything but the valid channel. Maybe it is possible
to do with minimal changes in C code.
Unfortunately, rewriting my program didn't help me to deal with errors
[1] . I see them in correctly written programs as well. Is it the
concurrency problem you mentioned in the manual? Could you please
explain in a bit more details why do we need to start a transaction
within a transaction here?
[1] Begin error: cannot start a transaction within a
transaction<br/>Expunge blocked by error: Error running SQL BEGIN
Regards,
Sergey
2013/12/25 Sergey Mironov <grrwlf at gmail.com>:
> Hi.
> I've faced a channel issue. Looks like I can't put a value into a
> channel from the transaction which didn't create that channel using
> `channel' function. Consider the following program:
>
> table t : { Id : int , Chan : channel int }
>
> fun put (i:int) =
> r <- oneRow1(SELECT * FROM t WHERE t.Id = 0);
> Basis.send r.Chan i
>
> fun monitor {} : transaction page =
> r <- oneRow1(SELECT * FROM t WHERE t.Id = 0);
> ch <- return r.Chan;
> let
> fun ping () =
> i <- recv ch;
> alert (show i);
> ping ()
> in
> return
> <xml>
> <body onload={ping ()}>
> <button value="Send a value" onclick={fn x => rpc (put 33)}/>
> </body>
> </xml>
> end
>
> fun main () : transaction page =
> ch <- channel;
> dml(INSERT INTO t (Id,Chan) VALUES (0,{[ch]}));
> redirect (url (monitor ()))
>
>
> The monitor here doesn't receive any messages from the channel,
> despite the fact that there is only one channel in the database. But
> if I move
> ch <- channel; dml(INSERT INTO t (Id,Chan) VALUES (0,{[ch]}));
> lines from main to the monitor's body, everything works. Please
> suggest a fix/workaround!
>
> Merry christmas to all
>
> Sergey
>
> PS
>
> Application reports
> Begin error: cannot start a transaction within a transaction<br
> />Expunge blocked by error: Error running SQL BEGIN
> Note, I'm using sqlite engine. I've tried it using vanilla urweb too:)
> The source is in attach.
More information about the Ur
mailing list