eudoxia0 / lucerne

A web framework for Common Lisp, built on Clack
http://borretti.me/lucerne/
142 stars 19 forks source link

Lucerne is broken since new quicklisp version of http-body #29

Open file13 opened 5 years ago

file13 commented 5 years ago

It looks like the new version of http-body (http-body-20190813-git) has broken Lucerne. It appears that the commits since August 10th are the culprit.

With the latest version of quicklisp, running this now produces an error:

(ql:quickload :lucerne)
(annot:enable-annot-syntax)
(in-package :lucerne)

(defapp app)

@route app "/"
(defview index ()
  (respond "<h1>Welcome to Lucerne</h1>"))

@route app "/greet/:name"
(defview greet (name)
  (respond (format nil "Hello, ~A!" name)))

(start app)

When trying to visit a url, it's getting an error in http-body::parse:

The value of STRING is NIL, which is not of type STRING.
   [Condition of type SIMPLE-TYPE-ERROR]

Restarts:
 0: [STORE-VALUE] Supply a new value for STRING.
 1: [ABORT] abort thread (#<THREAD "hunchentoot-worker-127.0.0.1:45298" RUNNING {10015252E3}>)

Backtrace:
  0: (SB-KERNEL:CHECK-TYPE-ERROR STRING NIL STRING NIL)
  1: (HTTP-BODY.UTIL:STARTS-WITH "application/json" #<unavailable argument>)
      Locals:
        PREFIX = "application/json"
  2: (HTTP-BODY:PARSE NIL NIL #<CIRCULAR-STREAMS:CIRCULAR-INPUT-STREAM {100186F053}>)
      Locals:
        CONTENT-LENGTH = NIL
        CONTENT-TYPE = NIL
        FN = HTTP-BODY.JSON:JSON-PARSE
        STREAM = #<CIRCULAR-STREAMS:CIRCULAR-INPUT-STREAM {100186F053}>
  3: (CLACK.REQUEST:MAKE-REQUEST (:REQUEST-METHOD :GET :SCRIPT-NAME "" :PATH-INFO "/" ...))
      Locals:
        ENV = (:REQUEST-METHOD :GET :SCRIPT-NAME "" :PATH-INFO "/" ...)
        REQ = #<CLACK.REQUEST:<REQUEST> {100186ED63}>
  4: ((:METHOD LACK.COMPONENT:CALL (LUCERNE.APP:BASE-APP T)) #<LUCERNE.APP:BASE-APP {10049CE4F3}> (:REQUEST-METHOD :GET :SCRIPT-NAME "" :PATH-INFO "/" ...)) [fast-method]
  5: ((:METHOD HUNCHENTOOT:ACCEPTOR-DISPATCH-REQUEST (CLACK.HANDLER.HUNCHENTOOT::CLACK-ACCEPTOR T)) #<CLACK.HANDLER.HUNCHENTOOT::CLACK-ACCEPTOR (host 0.0.0.0, port 8000)> #<HUNCHENTOOT:REQUEST {100186DC33}..
  6: ((:METHOD HUNCHENTOOT:HANDLE-REQUEST (HUNCHENTOOT:ACCEPTOR HUNCHENTOOT:REQUEST)) #<CLACK.HANDLER.HUNCHENTOOT::CLACK-ACCEPTOR (host 0.0.0.0, port 8000)> #<HUNCHENTOOT:REQUEST {100186DC33}>) [fast-metho..
  7: ((:METHOD HUNCHENTOOT:PROCESS-REQUEST (T)) #<HUNCHENTOOT:REQUEST {100186DC33}>) [fast-method]
  8: (HUNCHENTOOT::DO-WITH-ACCEPTOR-REQUEST-COUNT-INCREMENTED #<CLACK.HANDLER.HUNCHENTOOT::CLACK-ACCEPTOR (host 0.0.0.0, port 8000)> #<CLOSURE (LAMBDA NIL :IN HUNCHENTOOT:PROCESS-CONNECTION) {100186D1CB}>)
  9: ((:METHOD HUNCHENTOOT:PROCESS-CONNECTION (HUNCHENTOOT:ACCEPTOR T)) #<CLACK.HANDLER.HUNCHENTOOT::CLACK-ACCEPTOR (host 0.0.0.0, port 8000)> #<USOCKET:STREAM-USOCKET {1001524613}>) [fast-method]
 10: ((:METHOD HUNCHENTOOT:PROCESS-CONNECTION :AROUND (HUNCHENTOOT:ACCEPTOR T)) #<CLACK.HANDLER.HUNCHENTOOT::CLACK-ACCEPTOR (host 0.0.0.0, port 8000)> #<USOCKET:STREAM-USOCKET {1001524613}>) [fast-method]
 11: ((:METHOD HUNCHENTOOT:PROCESS-CONNECTION :AROUND (CLACK.HANDLER.HUNCHENTOOT::CLACK-ACCEPTOR T)) #<CLACK.HANDLER.HUNCHENTOOT::CLACK-ACCEPTOR (host 0.0.0.0, port 8000)> #<USOCKET:STREAM-USOCKET {1001524..
 12: ((FLET HUNCHENTOOT::PROCESS-CONNECTION% :IN HUNCHENTOOT::HANDLE-INCOMING-CONNECTION%) #<CLACK.HANDLER.HUNCHENTOOT::CLACK-ACCEPTOR (host 0.0.0.0, port 8000)> #<USOCKET:STREAM-USOCKET {1001524613}>)
 13: ((LAMBDA NIL :IN BORDEAUX-THREADS::BINDING-DEFAULT-SPECIALS))
 14: ((FLET SB-UNIX::BODY :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
 15: ((FLET "WITHOUT-INTERRUPTS-BODY-4" :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
 16: ((FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
 17: ((FLET "WITHOUT-INTERRUPTS-BODY-1" :IN SB-THREAD::CALL-WITH-MUTEX))
 18: (SB-THREAD::CALL-WITH-MUTEX #<CLOSURE (FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE) {7F8C805CED7B}> #<SB-THREAD:MUTEX "thread result lock" owner: #<SB-THREAD:THR..
 19: (SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE #<SB-THREAD:THREAD "hunchentoot-worker-127.0.0.1:45298" RUNNING {10015252E3}> NIL #<CLOSURE (LAMBDA NIL :IN BORDEAUX-THREADS::BINDING-DEFAULT-SPECIALS) {..
 --more--

If I revert back to the http-body-20181210-git version Lucerne works fine.

I don't have a solution/workaround suggestion at the moment and am not sure how to proceed. But I did want to bring it to your attention. I'll try to play with it more if I have some time.

Thank you!

zacbrown commented 4 years ago

Weighing - I'm running into this as well.

file13 commented 4 years ago

I haven't had time to dig into the code to try to help out, but I did want to mention a workaround to use Lucerne out of the box with quicklisp. This is intended for newer lisp hackers who may not know about this.

Workaround

To do so, you can switch to an older version of quicklisp before clack related APIs broke where Lucerne works out of the box by running this just once:

(ql-dist:install-dist "http://beta.quicklisp.org/dist/quicklisp/2019-05-21/distinfo.txt" :replace t :prompt nil)

Now you can run the following normally:

(eval-when (:compile-toplevel :load-toplevel :execute)
  (ql:quickload :lucerne))

(in-package :lucerne)
(annot:enable-annot-syntax)

(defapp app)

@route app "/"
(defview index ()
  (respond "<h1>Welcome to Lucerne</h1>"))

@route app "/greet/:name"
(defview greet (name)
  (respond (format nil "Hello, ~A!" name)))

(start app)

If you ever need to switch versions, but don't know what's available, you can do so as follows.

(ql-dist:available-versions (ql-dist:dist "quicklisp"))

Frankly, for production websites, you probably do want to this anyways to stick to a known working quicklisp distro until you're ready to test with the latest (ql:update-all-dists).

Hope this helps in the meantime.

ghard commented 4 years ago

It looks like this one broke compatibility with Clack v1-compat so it's soundly in the upstream. The best long-term solution would probably be for Lucerne to be migrated to use the new-ish incarnation of clack/lack as it might be optimistic to try and motivate @fukamachi -san to keep maintaining/testing the legacy v1-compat codebase. That said, I've made a PR on clack that in my tests seems to fix it at https://github.com/fukamachi/clack/pull/161

ghard commented 4 years ago

That was quick. So this bug might be fixed in the upstream now. @eudoxia0 what do you think?

file13 commented 2 years ago

So given that this has been a couple years and this is still open, I have to ask the awkward question if this project is dead at this point? I completely understand that life happens and that sometimes open source projects simply burn out, so there's no judgement in my question. I'm simply asking for the practical reasons if I should be working on migrating off of Lucerne for my production sites? I'd obviously rather not, but if there's no plans to continue the project, it's probably time for me to move on. Would you please let me know either way if there's any plans to continue this project or not?