guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Web development


From: Ricardo Wurmus
Subject: Re: Web development
Date: Fri, 04 Sep 2020 22:25:43 +0200
User-agent: mu4e 1.4.13; emacs 27.1

Zelphir Kaltstahl <zelphirkaltstahl@posteo.de> writes:

>>> (2) What do you use to serve static files (securely)? If you use Guile's
>>> web server, how exactly do you do it? Do you have the code somewhere?
>> I configure an assets directory and define a procedure that sanitizes
>> the requested file name to serve it from that directory.  I don’t do
>> much with files so I don’t usually do anything other than
>>
>>     (call-with-input-file file-name get-bytevector-all)
>>
>> for the body of the response.  But if I had to send large files I’d use
>> “sendfile” directly.
>
> Don't you need to also check what kind of file type it is and select the
> appropriate MIME type for answering the request?

Yes, you need to send along the correct MIME type.  In my projects I
know the MIME type of all files I’ll send ahead of time, so I can get
away with looking up the file extension in an alist of extensions to
MIME types.

Something like that:

--8<---------------cut here---------------start------------->8---
(define (render-static-file root path)
  ;; PATH is a list of path components
  (let ((file-name (string-join (cons* root path) "/")))
    (if (and (not (any (cut string-contains <> "..") path))
             (file-exists? file-name)
             (not (directory? file-name)))
        (list `((content-type . ,(assoc-ref file-mime-types
                                            (file-extension file-name))))
              (call-with-input-file file-name get-bytevector-all))
        (not-found (build-uri 'http
                              #:host (assoc-ref %config 'host)
                              #:port (assoc-ref %config 'port)
                              #:path (string-join path "/" 'prefix))))))
--8<---------------cut here---------------end--------------->8---

There’s probably a better way and a fail-safe way to do this, but this
has worked fine for me.

> And how do you use sendfile directly? (Code example for this would also
> be great to see.)

I’ve got no example for that in my projects, but “guix publish” provides
an implementation of “http-write” that uses sendfile.  See
guix/scripts/publish.scm in the Guix source tree.

> Is it still necessary to sanitize the requested file names, when an HTTP
> server handles requests for assets before the Guile application is hit?

I’d still do that because I’d want the application to never do the wrong
thing, even when the deployment details change.

-- 
Ricardo



reply via email to

[Prev in Thread] Current Thread [Next in Thread]