common-lispsbclhunchentoot

Get Hunchentoot to output no headers at all


I want to return a TSV file from a web call in Hunchentoot (SBCL), but want the user to just save the raw result blatted to the page, rather than use a separate file and download link (which is hard because of local firewall complexities).

I can't figure out how to output the page without any headers at all, i.e., to make it just plain raw text. (I know that the browser would make a mess w/o headers in the DOM, but don't care; the goal is just to have the user save the page, not read it.)

I've tried various combinations of

(setf (hunchentoot:content-type*) "text/plain")

and

(cl-who:with-html-output-to-string                                                                                            
          (*standard-output* nil :prologue nil)

and setting the content-type* inside, outside, and around the with... but I always get header junk.


Solution

  • Writing a string directly

    I tried defining a handler as follows:

    (define-easy-handler (text :uri "/text") ()
      (setf (content-type*) "text/csv")
      "a,b,c")
    

    When I visit the page locally, the browser automatically downloads a text file without even displaying (this is probably a setting we can change in Chrome, I don't know).

    When I enable the browser developer mode, here are the response headers I receive as part of the HTTP protocol:

    HTTP/1.1 200 OK
    Server: ...
    Date: ...
    Content-Type: text/csv; charset=utf-8
    Content-Length: 5
    Connection: keep-alive
    

    But the file itself is just the string a,b,c.

    If I change the content-type to "text/plain", then the browser successfully displays the text, and nothing else (the HTTP headers are the same).

    Remarks

    You don't need to use the cl-who macros if you do not intend to build an HTML document, in fact its better not to. In any case, you can supply your own REPLY-CLASS when initializing the acceptor (see https://edicl.github.io/hunchentoot/#replies) and have a very low-level control about what you emit as a reply, headers included. But I don't think this is necessary in your case. I don't clearly understand where your problem comes from, but sending back a plain text is something the framework is supposed to be able to do out of the box. Please add more details if you can.