Hacker Timesnew | past | comments | ask | show | jobs | submitlogin

It's an artefact of the way in which news.arc (actually srv.arc) uses functions for links. Here's the key code:

  (= dead-msg* "\nUnknown or expired link.")

  (defop-raw x (str req)
    (w/stdout str
      (aif (fns* (sym (arg req "fnid")))
           (it req)
           (pr dead-msg*))))
If the fnid (function ID) isn't in the fns* list then you get the dead message.

  (def flink (f)
    (string fnurl* "?fnid=" (fnid (fn (req) (prn) (f req)))))
In many places in the code closures are used to handle requests (see the flink code there). If the fns* list is cleared (say news.arc is restarted or harvest-fnids kills them) then you'll get the message.

The use of closures in this manner means that the code needed to handle say a form submission is really compact and set up when the form itself is generated.



I would be interested to know how much state is in those closures. If it is less than 200 or so bytes, it would not be impractical to encode it (b64) in the url for the next page (rather than a reference to the state).


You don't want to execute code from URLs. (Yes, you can use cryptography to "sign" URLs you create. Don't try that at home unless you know the difference between MACs and hashes, and how to avoid timing attacks.)


Whoa, whoa. Putting the state from the closure in the url is not the same as putting the closure in the url.


But you are still likely to want to sign the state so you can tell if it has been corrupted (or deliberately doctored) and reject it if so.


Sign or sanity check, whichever you prefer. Personally in a simple interface like this site I'd rather sanity check the few simple parameters.


It's not a druthers kind of thing. If you need to trust that it hasn't been tampered with you must sign it.

And if you don't care you might as well not add authentication because without signing it's just a fancy CRC - ie, totally replicable by an attacker. As cookies and links are sent over TCP there should be vanishingly few errors in transmission - you're far more likely to introduce false positives with buggy code, and ...

You need to sanity check your inputs anyways. Just do it. This is also how you avoid bugs normally.


I'm not sure what your argument is.

Yes if you want to trust it you have to sign it and make sure you implement all the crypto correctly. But I don't see a need for that here.

Also TCP's checksum sucks.


You said "sign or sanity check it", as if you can do whichever you want. But in the area suggested they have vast differences and security implications.

How many corrupted web pages do you see because of CRC failure in TCP?


I wouldn't call it a closure unless it has something like a "next-instruction" field, which is probably enough to get control - and certainly enough to do nasty things (think 'debug-mode, 'restart-server, 'shutdown.)


The PLT-Scheme (aka Racket) folks do this. Its kind of awesome, and I used it for a side project. It works pretty well except some browsers have a max url length, so you can only safely shove so much data to the client side, and then your stuck with old fashion IDs again. Still lots of fun to play with :)

In a scary way


Racket has support for serialization of closures and continuations, which it's web server makes extensive use of. It seems like it'd be possible to expose the relevant functions to make that happen, though I have no idea how large the closures actually are once serialized.


I believe the Racket web server works similarly to the Arc server. At least it did last I checked (back when it was still PLT Scheme).


> how much state is in those closures [...] to encode it (b64) in the url

I would be interested to know if this is even possible to determine from a macro which variables are bound in the closure.


My (unofficial) documentation of the Arc web server may help understand this: http://files.arcfn.com/doc/srv.html

In particular, harvest-fnids has as maximum number of allowed fnids. If there are too many, it purges any fnids that are older than their expiration time, and the oldest 10%.

Thus, the more fnids created (i.e. the more users), the sooner fnids will get harvested and you'll get the expired error.


A website written in Lisp? That is awesome.


It was created by pg. What other language (type) would he have used?




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: