unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
From: "Thompson, David" <dthompson2@worcester.edu>
To: Martyn Smith <martyn.developer@googlemail.com>,
	Nala Ginrut <nalaginrut@gmail.com>
Cc: Guile User <guile-user@gnu.org>
Subject: Fixing "stringly typed" data structures in Artanis (Was: Learning Guile web. Stuck on returning an image.)
Date: Thu, 10 Dec 2015 17:02:52 -0500	[thread overview]
Message-ID: <CAJ=RwfaYZ=PC4HRtbiZmTLYVcU+jYPiiF7FHLBx9Wa8Fhs+30g@mail.gmail.com> (raw)

[ Changing the subject for this little rant below ]

On Thu, Dec 10, 2015 at 2:44 PM, Martyn Smith
<martyn.developer@googlemail.com> wrote:

[snip]

> (get "/image"
>      (lambda (rc)
>        (let* ((port (open-file "s.jpg" "r"))
>                (bytes (get-bytevector-all port)))
>      (close-port port)
>      (response-emit bytes #:headers '((content-type image/jpg))))))
>
> (run #:port 1234)
>
>
> For my personal website, I pass in an id (ie "/image/{id}") which returns a
> record from the database, containing the location of the file in question...
> plus other things (tags, uploader, etc)  -- once working I stick it inside
> an image tag - job done!

I guess this is as good a time as any to voice a concern that I have
with Artanis before too many people depend on it and its not feasible
to change it.  In Scheme, we have the luxury of being able to easily
create embedded domain specific languages or otherwise take advantage
of s-expressions to avoid the tiring work of writing parsers and
interpreters for new languages.  However, Artanis features a URI
routing language written in strings, like "/user/:id".  This
particular string means: Match a URI beginning with "/user/", followed
by any string and associate it with the name "id".  Generally
speaking, this is a pattern matcher.  Unfortunately, unlike Guile's
built-in pattern matcher, these patterns must be string encoded and
cannot do more sophisticated matching techniques such as making sure
"id" is a string representation of an integer.  Doing this type of
string-based URI matching is the status quo in many web frameworks
written in Ruby, Python, etc., but in Scheme we have the opportunity
to do *much* better.  For an example that uses more proper Guile
Scheme idioms, take a look the source for the 'guix publish' tool in
GNU Guix. [0]  By viewing a URI as a list strings, we can represent
"/user/1" as the list ("image" "1").  From there, it's easy to use a
pattern matcher to match this route:

    (match uri (("user" id) (display-user-info id)))

From there we can get more advanced and assert various things about
"id" in the match expression, as 'guix publish' does with its routes.

There are also security issues to think about when you use "stringly
typed" data.  It doesn't apply to this particular case, but working
with strings that are actually not strings (like HTML or SQL) opens
the door for injection attacks. [1] Fortunately, we can avoid such
issues entirely by choosing more appropriate data types.

I hope this has made some sense.  I think Artanis is a great project,
and I hope issues like this can be fixed so web developers looking at
Guile can truly see how much better it is in Lisp land.

- Dave

[0] http://git.savannah.gnu.org/cgit/guix.git/tree/guix/scripts/publish.scm#n309
[1] http://www.more-magic.net/posts/structurally-fixing-injection-bugs.html



             reply	other threads:[~2015-12-10 22:02 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-10 22:02 Thompson, David [this message]
2015-12-11  3:38 ` Fixing "stringly typed" data structures in Artanis Mike Gerwitz
2015-12-11  7:33 ` Fixing "stringly typed" data structures in Artanis (Was: Learning Guile web. Stuck on returning an image.) Nala Ginrut
2015-12-11 15:25   ` Christopher Allan Webber
2015-12-11 19:16     ` tomas
2015-12-11  7:53 ` tomas
2015-12-11 21:17 ` Fixing "stringly typed" data structures in Artanis Ludovic Courtès
2015-12-13 19:41 ` Amirouche Boubekki
2015-12-13 19:58   ` Thompson, David

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAJ=RwfaYZ=PC4HRtbiZmTLYVcU+jYPiiF7FHLBx9Wa8Fhs+30g@mail.gmail.com' \
    --to=dthompson2@worcester.edu \
    --cc=guile-user@gnu.org \
    --cc=martyn.developer@googlemail.com \
    --cc=nalaginrut@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).