Drakma和Dexador都仅在请求localhost时在USocket调用上均失败,从而请求Internet正常 [英] Drakma and Dexador both fails at USocket call while requesting localhost only, requesting the internet works fine

查看:71
本文介绍了Drakma和Dexador都仅在请求localhost时在USocket调用上均失败,从而请求Internet正常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前有无法解释的行为,请感谢任何线索。



背景



我有一个通过PHP内置开发网络服务器<$ c $在本地运行的wordpress实例。 c> php -S localhost:8000 -t / doc / root / wordpress 。该站点可以正常运行,我可以使用 curl http:// localhost:8000 / 成功获取它,也可以在Web浏览器中打开它。



但是简单的程序例如:

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

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

-都失败。



drakma 失败,回溯:

 条件USOCKET:CONNECTION-REFUSED-ERROR已发出信号。 
[类型USOCKET:CONNECTION-REFUSED-ERROR的条件]

重新启动:
0:[重试]重试SLIME REPL评估请求。
1:[* ABORT]返回SLIME的顶层。
2:[ABORT]中止线程(#< THREAD repl-thread RUNNING {1004CC9B93}>))

回溯:
0:((USOCKET :: HANDLE-条件#< 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:套接字错误连接 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)#<关闭(Flet SB-BSD-SOCKETS :: WITH-SOCKET-ADDR-THUNK:IN SB-BSD-袜子:..
5:((::方法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)[快速方法]
6:((FLET WITHOUT-INTERRUPTS-BODY-22:IN USOCKET:SOCKET-CONNECT))
7:(USOCKET:SOCKET-CONNECT loca lhost 8000:协议:流:元素类型的弹性流:八脚:超时20:截止时间无效:无延迟:如果支持:本地主机无效:本地端口无效)
8:(DRAKMA:HTTP-请求#< 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:在SWANK-REPL :: REPL-EVAL){100435A53B}>)
14:(SWANK :: CALL-WITH- RETRY-RESTART重试SLIME REPL评估请求。#<关闭(LAMBDA NIL:在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:在SWANK :: HANDLE-REQUESTS))
22:((LAMBDA NIL:在SWANK :: HANDLE-REQUESTS))
23:(SWANK / SBCL: :CALL-WITH-BREAK-HOOK#<功能SWANK:SWANK-DEBUGGER-HOOK> #<关闭(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)#<功能SWANK:SWANK-DEBUGGER-HOOK>#<关闭(LAMBDA NIL:IN SWANK :: HANDLE-REQUESTS){。
25:(SWANK :: CALL-WITH-BINDINGS((* STANDARD-INPUT *。#< SWANK / GRAY :: SLIME-INPUT-STREAM {1004BC9E93}>)))#<关闭(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 -螺纹功能蹦床))
29:((Fleet SB-螺纹:: WITH-MUTEX-THUNK:在SB-螺纹::初始螺纹-功能-蹦床))
30:( (FLET WITHOUT-INTERRUPTS-BODY-1:在SB-螺纹:: CALL-WITH-MUTEX中))
31:(SB-螺纹:: CALL-WITH-MUTEX#<关闭(FLET SB-螺纹:: WITH-MU TEX-THUNK:在SB-螺纹中:: INITIAL-THREAD-FUNCTION-TRAMPOLINE){3A67D6B}> #< SB-THREAD:MUTEX线程结果锁定所有者:#< SB-THREAD:THREAD ..
32:(SB-THREAD :: INITIAL-THREAD-FUNCTION-TRAMPOLINE#< SB-线程:线程 REPL-线程正在运行{1004CC9B93}> NIL#<关闭(LAMBDA NIL:在SWANK-REPL :: SPAWN-REPL-THREAD){1004CC9B3B}> NIL)
33:(外部函数:call_into_lisp)
34:(外部函数:new_thread_trampoline)
35:(外部函数:_pthread_body)
36:(外部函数:_pthread_body)
37 :(外部函数:thread_start)

有趣的是,如果我将URI更改为互联网上的其他用户:

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

-然后就可以了。





我的笔记

$ b $可能是在我的本地计算机和本地php-server上下文中的某个地方。 b

  • 在回溯中我看到t他的线路(USOCKET:SOCKET-CONNECT localhost 8000:协议:STREAM:ELEMENT-TYPE FLEXI-STREAMS:OCTET:TIMEOUT 20:DEADLINE NIL:NODELAY:IF-SUPPORTED:LOCAL-HOST NIL:LOCAL -PORT NIL):local-host :local-port 这两个键都是 nil 。可能就是问题所在,因为根据飞机规格,这些参数是负责在本地地址上调用 bind()(与调用非本地地址有什么不同吗?)。


  • drakma:http-request 的规范中也没有找到任何特殊参数来指定我正在请求本地服务器。根据示例, https://edicl.github.io/drakma/#ex -basic-auth ,请求任何URI都很简单,并且无需区分本地地址与非本地地址。




总结




  • 为什么请求 http:// localhost:8000 不适用于 drakma dexador 。有人可以确认本地Web服务器的行为相同吗?


  • bind() syscall是否以某种方式被调用本地和非本地地址是否不同?







P.S。我已经问过类似的问题,首先它看起来像问题是旧软件版本。现在,我找到了该问题的其他详细信息,并对其进行了重新表述,所以我在这里提出另一个问题。






更新1



也许,问题出在特定的PHP内置Web服务器进行开发,因为只有使用PHP Web服务器+ SBCL + Drakma才能重现此问题。但是PHP Web服务器可以很好地用于 curl ,Go客户端和Web浏览器。



PHP版本:


PHP 7.3.1(cli)(内置: 2019年1月10日13:16:34)(NTS)版权所有(c)
1997-2018 The PHP Group Zend Engine v3.3.1,版权所有(c)1998-2018
Zend Technologies
with Zend OPcache v7.3.1,版权所有(c)1999-2018,由Zend Technologies


-安装了 brew install php



复制步骤



服务器:

  php -S localhost:7070 

然后尝试与客户端:

  curl http:// localhost:7070 

-工作正常(预期并收到状态码404)。



Lisp:

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

-失败(状态码为404,但连接被拒绝返回)。

解决方案

谁来了详细信息,有一个讨论,其中Stas Boukarev帮助调试了该问题。 p>

运行 php -S localhost:7070 启动一个服务器,侦听我计算机上的 ipv6 地址,因此请求 ipv4 地址 127.0.0.1:7070 无效。



因此,服务器必须使用显式的 ipv4 地址 php -S 127.0.0.1:7070 启动,才能正常工作。


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).

解决方案

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.

这篇关于Drakma和Dexador都仅在请求localhost时在USocket调用上均失败,从而请求Internet正常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆