Drakma and Dexador both fails at USocket call while requesting localhost only, requesting the internet works fine

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-10 21:17:00

问题


There is an unexplained behavior for me for the moment, appreciate any clues.

Background

I have a locally running instance of wordpress via PHP built-in development webserver php -S localhost:8000 -t /doc/root/wordpress. The site works, I can fetch it with curl "http://localhost:8000/" successfully, I can open it in a web browser also.

But simple programs like:

(drakma:http-request "http://localhost:8000/")

or

(dexador:get "http://localhost:8000/")

-- both fail.

drakma fails with the backtrace:

Condition USOCKET:CONNECTION-REFUSED-ERROR was signalled.
   [Condition of type USOCKET:CONNECTION-REFUSED-ERROR]

Restarts:
 0: [RETRY] Retry SLIME REPL evaluation request.
 1: [*ABORT] Return to SLIME's top level.
 2: [ABORT] abort thread (#<THREAD "repl-thread" RUNNING {1004CC9B93}>)

Backtrace:
  0: (USOCKET::HANDLE-CONDITION #<SB-BSD-SOCKETS:CONNECTION-REFUSED-ERROR {100435B3A3}> #<USOCKET:STREAM-USOCKET {100435AE33}>)
  1: (SB-KERNEL::%SIGNAL #<SB-BSD-SOCKETS:CONNECTION-REFUSED-ERROR {100435B3A3}>)
  2: (ERROR SB-BSD-SOCKETS:CONNECTION-REFUSED-ERROR :ERRNO 61 :SYSCALL "connect")
  3: (SB-BSD-SOCKETS:SOCKET-ERROR "connect" 61)
  4: (SB-BSD-SOCKETS::CALL-WITH-SOCKET-ADDR #<SB-BSD-SOCKETS:INET-SOCKET 127.0.0.1:49431, fd: 16 {100435AD23}> (#(127 0 0 1) 8000) #<CLOSURE (FLET SB-BSD-SOCKETS::WITH-SOCKET-ADDR-THUNK :IN SB-BSD-SOCKETS:..
  5: ((:METHOD SB-BSD-SOCKETS:SOCKET-CONNECT (SB-BSD-SOCKETS:SOCKET)) #<SB-BSD-SOCKETS:INET-SOCKET 127.0.0.1:49431, fd: 16 {100435AD23}> #(127 0 0 1) 8000) [fast-method]
  6: ((FLET "WITHOUT-INTERRUPTS-BODY-22" :IN USOCKET:SOCKET-CONNECT))
  7: (USOCKET:SOCKET-CONNECT "localhost" 8000 :PROTOCOL :STREAM :ELEMENT-TYPE FLEXI-STREAMS:OCTET :TIMEOUT 20 :DEADLINE NIL :NODELAY :IF-SUPPORTED :LOCAL-HOST NIL :LOCAL-PORT NIL)
  8: (DRAKMA:HTTP-REQUEST #<PURI:URI http://localhost:8000/>)
  9: (SB-INT:SIMPLE-EVAL-IN-LEXENV (DRAKMA:HTTP-REQUEST "http://localhost:8000/") #<NULL-LEXENV>)
 10: (EVAL (DRAKMA:HTTP-REQUEST "http://localhost:8000/"))
 11: (SWANK::EVAL-REGION "(drakma:http-request \"http://localhost:8000/\") ..)
 12: ((LAMBDA NIL :IN SWANK-REPL::REPL-EVAL))
 13: (SWANK-REPL::TRACK-PACKAGE #<CLOSURE (LAMBDA NIL :IN SWANK-REPL::REPL-EVAL) {100435A53B}>)
 14: (SWANK::CALL-WITH-RETRY-RESTART "Retry SLIME REPL evaluation request." #<CLOSURE (LAMBDA NIL :IN SWANK-REPL::REPL-EVAL) {100435A4DB}>)
 15: (SWANK::CALL-WITH-BUFFER-SYNTAX NIL #<CLOSURE (LAMBDA NIL :IN SWANK-REPL::REPL-EVAL) {100435A4BB}>)
 16: (SWANK-REPL::REPL-EVAL "(drakma:http-request \"http://localhost:8000/\") ..)
 17: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SWANK-REPL:LISTENER-EVAL "(drakma:http-request \"http://localhost:8000/\") ..)
 18: (EVAL (SWANK-REPL:LISTENER-EVAL "(drakma:http-request \"http://localhost:8000/\") ..)
 19: (SWANK:EVAL-FOR-EMACS (SWANK-REPL:LISTENER-EVAL "(drakma:http-request \"http://localhost:8000/\") ..)
 20: (SWANK::PROCESS-REQUESTS NIL)
 21: ((LAMBDA NIL :IN SWANK::HANDLE-REQUESTS))
 22: ((LAMBDA NIL :IN SWANK::HANDLE-REQUESTS))
 23: (SWANK/SBCL::CALL-WITH-BREAK-HOOK #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<CLOSURE (LAMBDA NIL :IN SWANK::HANDLE-REQUESTS) {1004CD008B}>)
 24: ((FLET SWANK/BACKEND:CALL-WITH-DEBUGGER-HOOK :IN "/Users/ihar/.roswell/lisp/slime/2019.02.02/swank/sbcl.lisp") #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<CLOSURE (LAMBDA NIL :IN SWANK::HANDLE-REQUESTS) {..
 25: (SWANK::CALL-WITH-BINDINGS ((*STANDARD-INPUT* . #<SWANK/GRAY::SLIME-INPUT-STREAM {1004BC9E93}>)) #<CLOSURE (LAMBDA NIL :IN SWANK::HANDLE-REQUESTS) {1004CD00AB}>)
 26: (SWANK::HANDLE-REQUESTS #<SWANK::MULTITHREADED-CONNECTION {10079AA873}> NIL)
 27: ((FLET SB-UNIX::BODY :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
 28: ((FLET "WITHOUT-INTERRUPTS-BODY-4" :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
 29: ((FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
 30: ((FLET "WITHOUT-INTERRUPTS-BODY-1" :IN SB-THREAD::CALL-WITH-MUTEX))
 31: (SB-THREAD::CALL-WITH-MUTEX #<CLOSURE (FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE) {3A67D6B}> #<SB-THREAD:MUTEX "thread result lock" owner: #<SB-THREAD:THREAD "..
 32: (SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE #<SB-THREAD:THREAD "repl-thread" RUNNING {1004CC9B93}> NIL #<CLOSURE (LAMBDA NIL :IN SWANK-REPL::SPAWN-REPL-THREAD) {1004CC9B3B}> NIL)
 33: ("foreign function: call_into_lisp")
 34: ("foreign function: new_thread_trampoline")
 35: ("foreign function: _pthread_body")
 36: ("foreign function: _pthread_body")
 37: ("foreign function: thread_start")

Interesting, if I change the URI to any other on the internet:

(drakma:http-request "https://stackoverflow.com")

-- then it works fine.

So the problem, probably, somewhere in the context of my local machine and local php-server. What could be wrong with these simple function calls?

My notes

  • in the backtrace I see this line (USOCKET:SOCKET-CONNECT "localhost" 8000 :PROTOCOL :STREAM :ELEMENT-TYPE FLEXI-STREAMS:OCTET :TIMEOUT 20 :DEADLINE NIL :NODELAY :IF-SUPPORTED :LOCAL-HOST NIL :LOCAL-PORT NIL). The keys :local-host and :local-port are both nil. Probably that's the issue, because according to the usocket specs those params are responsible for calling bind() on local address (is it somehow different than calling non-local address?).

  • I also haven't found in the specs for drakma:http-request any special parameters to specify that I'm requesting a local server. According to the example, https://edicl.github.io/drakma/#ex-basic-auth, requesting any URI is simple and goes without any differentiation of 'local address' vs non-local.

Summing up

  • Why requesting "http://localhost:8000" doesn't work with drakma or dexador. Does anybody can confirm the same behavior for local web servers?

  • Is the bind() syscall somehow different for local and non-local addresses?


P.S. I already asked the similar question and first it seemed like the problem was with old software versions. Now I found additional details of the problem and rephrased it, so I'm making another question here.


Update 1

Maybe, the problem is connected to the particular PHP built-it webserver for development, because the issue is reproducible only with the PHP webserver + SBCL + Drakma. But PHP webserver serves fine for curl, a Go client, a web browser.

PHP version:

PHP 7.3.1 (cli) (built: Jan 10 2019 13:16:34) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.3.1, Copyright (c) 1998-2018 Zend Technologies with Zend OPcache v7.3.1, Copyright (c) 1999-2018, by Zend Technologies

-- installed with brew install php.

Steps to reproduce

The server:

php -S localhost:7070

Then try with clients:

curl "http://localhost:7070"

-- works fine (status code 404 is expected and received).

Lisp:

(drakma:http-request "http://localhost:7070")

-- fails (status code 404 is expected but connection refused is returned).


回答1:


Who wants details, there is a discussion where Stas Boukarev helped to debug the problem.

Running php -S localhost:7070 starts a server listening on ipv6 address on my computer, so requesting the ipv4 address 127.0.0.1:7070 doesn't work in that case.

So the server must be started with explicit ipv4 address php -S 127.0.0.1:7070 instead to work correctly.



来源:https://stackoverflow.com/questions/54638335/drakma-and-dexador-both-fails-at-usocket-call-while-requesting-localhost-only-r

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!