Дракма и Дексадор оба терпят неудачу при вызове USocket при запросе только локального хоста, запрос интернета работает нормально - PullRequest
0 голосов
/ 11 февраля 2019

На данный момент для меня есть необъяснимое поведение, оцените любые подсказки.

Фон

У меня есть локально запущенный экземпляр WordPress через встроенный веб-сервер разработки PHP php -S localhost:8000 -t /doc/root/wordpress.Сайт работает, я могу получить его с помощью curl "http://localhost:8000/", я также могу открыть его в веб-браузере.

Но простые программы, такие как:

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

или

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

- обе не работают.

drakma завершается неудачно с обратным следом:

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

Интересно, если я изменю URI на любой другой в Интернете:

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

- тогда этоработает отлично.

Так что проблема, наверное, где-то в контексте моей локальной машины и локального php-сервера.Что может быть не так с этими простыми вызовами функций?

Мои заметки

  • в обратном следе я вижу эту строку (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).Клавиши :local-host и :local-port являются nil.Вероятно, это проблема, потому что согласно спецификациям usocket эти параметры отвечают за вызов bind() по локальному адресу (чем-то отличается от вызова нелокального адреса?).

  • Я также не нашел в спецификации для drakma:http-request каких-либо специальных параметров, чтобы указать, что я запрашиваю локальный сервер.В соответствии с примером, https://edicl.github.io/drakma/#ex-basic-auth, запрос любого URI прост и проходит без какого-либо различия между «локальным адресом» и нелокальным.

Подведение итогов

  • Почему запрос "http://localhost:8000" не работает с drakma или dexador. Кто-нибудьможет подтвердить то же поведение для локальных веб-серверов?

  • Системный вызов bind() чем-то отличается для локальных и нелокальных адресов?


PS Я уже задавал аналогичный вопрос , и сначала мне показалось, что проблема связана со старыми версиями программного обеспечения. Теперь я нашел дополнительные сведения о проблеме и перефразировал ее, поэтому я задаю здесь другой вопрос.


Обновление 1

Возможно, проблема связана с конкретным встроенным веб-сервером PHP для разработки, поскольку проблема воспроизводима только с помощью веб-сервера PHP + SBCL + Drakma.PHP-сервер отлично подходит для curl, клиента Go, веб-браузера.

Версия PHP:

PHP 7.3.1 (cli) (сборка: 10 января 2019 г. 13:16:34) (NTS) Copyright (c) 1997-2018 PHP Group Zend Engine v3.3.1, Copyright (c) 1998-2018 Zend Technologies с Zend OPcache v7.3.1, Copyright (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, но возвращается connection refused).

1 Ответ

0 голосов
/ 15 февраля 2019

Кому нужны подробности, есть обсуждение , где Стас Букарев помог отладить проблему.

Запуск php -S localhost:7070 запускает прослушивание сервера по адресу ipv6 намой компьютер, поэтому запрос ipv4 адреса 127.0.0.1:7070 в этом случае не работает.

Поэтому сервер должен быть запущен с явным ipv4 адресом php -S 127.0.0.1:7070вместо того, чтобы работать правильно.

...