Shiou-Ju / number-a-b-guess-game

Given a number and the opponent should reply with `how many As and how many Bs`
0 stars 0 forks source link

瀏覽器可以請求但是 curl 不行 #3

Open Shiou-Ju opened 1 week ago

Shiou-Ju commented 1 week ago

GPT 整理

描述:

在使用 Actionhero 框架開發的應用中,當通過瀏覽器訪問 http://localhost:8080/sum?a=100&b=23 時,請求能夠正常響應並返回預期的 JSON 結果。然而,使用 curl 發送相同的請求卻返回 404 Not Found 錯誤,無法獲取到預期的數據。


重現步驟:

  1. 啟動伺服器:

    yarn dev
  2. 瀏覽器請求:

    • URL: http://localhost:8080/sum?a=100&b=23
    • 預期響應:
      {
      "sum": 123,
      "serverInformation": { /* 相關信息 */ },
      "requesterInformation": { /* 相關信息 */ }
      }
  3. 使用 curl 發送 GET 請求:

    curl -i "http://localhost:8080/api/sum?a=100&b=23" \
     -H "Accept: application/json" \
     -H "Content-Type: application/json"
    • 實際響應:
      HTTP/1.1 404 Not Found
      accept-ranges: bytes
      Date: Sun, 27 Oct 2024 09:09:56 GMT
      Connection: keep-alive
      Keep-Alive: timeout=5
      Content-Length: 0
  4. 使用 curl 發送 POST 請求:

    curl -X POST "http://localhost:8080/api/sum" \
     -H "Accept: application/json" \
     -H "Content-Type: application/json" \
     -d '{"a":100,"b":23}'
    • 實際響應:
      (無輸出)

預期行為:

curl 發送的請求應該與瀏覽器中的請求類似,返回相同的 200 OK 狀態和預期的 JSON 數據。

實際行為:

curl 請求返回 404 Not Found 錯誤,無法獲取到預期的數據。


環境:

Shiou-Ju commented 1 week ago

發現是 IPv4 vs. v6 的問題

➜  Repos curl -4 'http://localhost:8080/sum?a=100&b=23'

➜  Repos curl -6 'http://[::1]:8080/sum?a=100&b=23'

{
  "sum": 123,
  "serverInformation": {
    "serverName": "my_actionhero_project",
    "apiVersion": "0.1.0",
    "requestDuration": 9,
    "currentTime": 1730161396544
  },
  "requesterInformation": {
    "id": "6e4f4a03ac6a24baf9202f5a817d0c5068951544-a80eb4e2-fc4a-4b7f-85aa-d16bb4d828ad",
    "fingerprint": "6e4f4a03ac6a24baf9202f5a817d0c5068951544",
    "messageId": "a80eb4e2-fc4a-4b7f-85aa-d16bb4d828ad",
    "remoteIP": "::1",
    "receivedParams": {
      "a": "100",
      "b": "23",
      "action": "sum"
    }
  }
}%
➜  Repos
Shiou-Ju commented 1 week ago

目前 v4, v6 都有在聽

➜  Repos netstat -an | grep 8080
tcp46      0      0  *.8080                 *.*                    LISTEN
tcp4       0      0  *.8080                 *.*                    LISTEN
➜  Repos lsof -i :8080
COMMAND   PID   USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
node    21239 bamboo   19u  IPv4 0xf6ebc2a079917c87      0t0  TCP *:http-alt (LISTEN)
node    59054 bamboo   24u  IPv6 0xf6ebc29bae411177      0t0  TCP *:http-alt (LISTEN)
➜  Repos
Shiou-Ju commented 1 week ago

tcpdump for v4

sudo tcpdump -i lo0 port 8080 
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo0, link-type NULL (BSD loopback), capture size 262144 bytes
08:40:00.415418 IP localhost.56109 > localhost.http-alt: Flags [S], seq 4184030234, win 65535, options [mss 16344,nop,wscale 6,nop,nop,TS val 2454897083 ecr 0,sackOK,eol], length 0
08:40:00.415591 IP localhost.http-alt > localhost.56109: Flags [S.], seq 2974487535, ack 4184030235, win 65535, options [mss 16344,nop,wscale 6,nop,nop,TS val 3495734361 ecr 2454897083,sackOK,eol], length 0
08:40:00.415615 IP localhost.56109 > localhost.http-alt: Flags [.], ack 1, win 6379, options [nop,nop,TS val 2454897083 ecr 3495734361], length 0
08:40:00.415630 IP localhost.http-alt > localhost.56109: Flags [.], ack 1, win 6379, options [nop,nop,TS val 3495734361 ecr 2454897083], length 0
08:40:00.415649 IP localhost.56109 > localhost.http-alt: Flags [P.], seq 1:93, ack 1, win 6379, options [nop,nop,TS val 2454897083 ecr 3495734361], length 92: HTTP: GET /sum?a=100&b=23 HTTP/1.1
08:40:00.415674 IP localhost.http-alt > localhost.56109: Flags [.], ack 93, win 6378, options [nop,nop,TS val 3495734361 ecr 2454897083], length 0
08:40:00.428735 IP localhost.http-alt > localhost.56109: Flags [P.], seq 1:152, ack 93, win 6378, options [nop,nop,TS val 3495734374 ecr 2454897083], length 151: HTTP: HTTP/1.1 404 Not Found
08:40:00.428766 IP localhost.56109 > localhost.http-alt: Flags [.], ack 152, win 6377, options [nop,nop,TS val 2454897096 ecr 3495734374], length 0
08:40:00.428926 IP localhost.56109 > localhost.http-alt: Flags [F.], seq 93, ack 152, win 6377, options [nop,nop,TS val 2454897096 ecr 3495734374], length 0
08:40:00.428949 IP localhost.http-alt > localhost.56109: Flags [.], ack 94, win 6378, options [nop,nop,TS val 3495734374 ecr 2454897096], length 0
08:40:00.429018 IP localhost.http-alt > localhost.56109: Flags [F.], seq 152, ack 94, win 6378, options [nop,nop,TS val 3495734374 ecr 2454897096], length 0
08:40:00.429049 IP localhost.56109 > localhost.http-alt: Flags [.], ack 153, win 6377, options [nop,nop,TS val 2454897096 ecr 3495734374], length 0
^C
12 packets captured
2860 packets received by filter
0 packets dropped by kernel
Shiou-Ju commented 1 week ago

tcpdump for v6

 sudo tcpdump -i lo0 port 8080 
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo0, link-type NULL (BSD loopback), capture size 262144 bytes
08:37:27.686724 IP6 localhost.54809 > localhost.http-alt: Flags [S], seq 715042300, win 65535, options [mss 16324,nop,wscale 6,nop,nop,TS val 3167191331 ecr 0,sackOK,eol], length 0
08:37:27.686875 IP6 localhost.http-alt > localhost.54809: Flags [S.], seq 3849887279, ack 715042301, win 65535, options [mss 16324,nop,wscale 6,nop,nop,TS val 3312198690 ecr 3167191331,sackOK,eol], length 0
08:37:27.686888 IP6 localhost.54809 > localhost.http-alt: Flags [.], ack 1, win 6371, options [nop,nop,TS val 3167191331 ecr 3312198690], length 0
08:37:27.686901 IP6 localhost.http-alt > localhost.54809: Flags [.], ack 1, win 6371, options [nop,nop,TS val 3312198690 ecr 3167191331], length 0
08:37:27.691014 IP6 localhost.54809 > localhost.http-alt: Flags [P.], seq 1:878, ack 1, win 6371, options [nop,nop,TS val 3167191335 ecr 3312198690], length 877: HTTP: GET /sum?a=100&b=23 HTTP/1.1
08:37:27.691115 IP6 localhost.http-alt > localhost.54809: Flags [.], ack 878, win 6358, options [nop,nop,TS val 3312198694 ecr 3167191335], length 0
08:37:27.700446 IP6 localhost.54810 > localhost.http-alt: Flags [S], seq 2454154044, win 65535, options [mss 16324,nop,wscale 6,nop,nop,TS val 1694074242 ecr 0,sackOK,eol], length 0
08:37:27.700593 IP6 localhost.http-alt > localhost.54810: Flags [S.], seq 2013867277, ack 2454154045, win 65535, options [mss 16324,nop,wscale 6,nop,nop,TS val 1554486417 ecr 1694074242,sackOK,eol], length 0
08:37:27.700611 IP6 localhost.54810 > localhost.http-alt: Flags [.], ack 1, win 6371, options [nop,nop,TS val 1694074242 ecr 1554486417], length 0
08:37:27.700620 IP6 localhost.http-alt > localhost.54810: Flags [.], ack 1, win 6371, options [nop,nop,TS val 1554486417 ecr 1694074242], length 0
08:37:27.706376 IP6 localhost.http-alt > localhost.54809: Flags [P.], seq 1:946, ack 878, win 6358, options [nop,nop,TS val 3312198709 ecr 3167191335], length 945: HTTP: HTTP/1.1 200 OK
08:37:27.706417 IP6 localhost.54809 > localhost.http-alt: Flags [.], ack 946, win 6357, options [nop,nop,TS val 3167191350 ecr 3312198709], length 0
08:37:28.553746 IP6 localhost.54810 > localhost.http-alt: Flags [F.], seq 1, ack 1, win 6371, options [nop,nop,TS val 1694075096 ecr 1554486417], length 0
08:37:28.553763 IP6 localhost.54809 > localhost.http-alt: Flags [F.], seq 878, ack 946, win 6357, options [nop,nop,TS val 3167192198 ecr 3312198709], length 0
08:37:28.553803 IP6 localhost.http-alt > localhost.54810: Flags [.], ack 2, win 6371, options [nop,nop,TS val 1554487271 ecr 1694075096], length 0
08:37:28.553816 IP6 localhost.http-alt > localhost.54809: Flags [.], ack 879, win 6358, options [nop,nop,TS val 3312199557 ecr 3167192198], length 0
08:37:28.554176 IP6 localhost.http-alt > localhost.54810: Flags [F.], seq 1, ack 2, win 6371, options [nop,nop,TS val 1554487271 ecr 1694075096], length 0
08:37:28.554214 IP6 localhost.54810 > localhost.http-alt: Flags [.], ack 2, win 6371, options [nop,nop,TS val 1694075096 ecr 1554487271], length 0
08:37:28.554322 IP6 localhost.http-alt > localhost.54809: Flags [F.], seq 946, ack 879, win 6358, options [nop,nop,TS val 3312199557 ecr 3167192198], length 0
08:37:28.554343 IP6 localhost.54809 > localhost.http-alt: Flags [.], ack 947, win 6357, options [nop,nop,TS val 3167192198 ecr 3312199557], length 0
^C
20 packets captured
415 packets received by filter
0 packets dropped by kernel
Shiou-Ju commented 1 week ago

發現我的 8080 已經有東西

我將 bindIP: "::", 設成 bindIP: "0.0.0.0",

[ERROR] 08:54:15 Error: cannot start web server @ 0.0.0.0:8080 => Error: listen EADDRINUSE: address already in use 0.0.0.0:8080
2024-10-29T00:54:15.122Z - notice: stopping process...
2024-10-29T00:54:15.224Z - notice: Stopping server: web
2024-10-29T00:54:15.224Z - notice: Stopping server: websocket
2024-10-29T00:54:15.434Z - notice: *** my_actionhero_project Stopped ***
進程即將退出,退出碼:1

並且看了

netstat -anv | grep 8080
tcp4       0      0  *.8080                 *.*                    LISTEN      131072 131072  21239      0 0x0100 0x00000106

原來 8080 已經有在聽了。

所以是這邊:

[INFO] 08:55:20 ts-node-dev ver. 2.0.0 (using ts-node ver. 10.9.2, typescript ver. 5.6.3)
正在啟動 Actionhero 進程...
sum action constructor initialized
2024-10-29T00:55:20.820Z - info: creating routes automatically for all actions responding to GET HTTP verb
2024-10-29T00:55:20.821Z - info: creating routes automatically for all actions responding to POST HTTP verb
2024-10-29T00:55:20.853Z - notice: pid: 45812
2024-10-29T00:55:20.853Z - notice: environment: development
2024-10-29T00:55:20.853Z - info: *** Starting my_actionhero_project ***
2024-10-29T00:55:20.859Z - info: actionhero member 192.168.8.140 has joined the cluster
2024-10-29T00:55:20.859Z - notice: Starting server: `web` @ http://:::8080
2024-10-29T00:55:20.862Z - notice: Starting server: `websocket`
2024-10-29T00:55:20.878Z - notice: server ID: 192.168.8.140
2024-10-29T00:55:20.878Z - notice: *** my_actionhero_project Started ***
Actionhero 進程已成功啟動

他應該要出現類似 0.0.0.0 但是沒有出現

[ERROR] 08:54:15 Error: cannot start web server @ 0.0.0.0:8080 => Error: listen EADDRINUSE: address already in use 0.0.0.0:8080
Shiou-Ju commented 1 week ago

發現 action hero bug

如果 v4 的 port 已經被 listen,他的訊息仍然會一樣

Shiou-Ju commented 1 week ago

已發現問題,但需要思考對使用者來說是 warning or error

log 給使用者 還是直接 當成 error 比較好?

// Which IP to listen on (use '0.0.0.0' for the default ip stack; '::' for all on ipv4 and ipv6)
      // Set to `null` when listening to socket
      bindIP: "::",
      // bindIP: "0.0.0.0",

如果我這邊選擇使用 v4&&v6 一起,那麼 eg. 8080 已經被使用了,那麼我的行為應該是 warn 或是 throw error 讓程序退出呢?

看規格書、協定。

Shiou-Ju commented 1 week ago

關於 error or warning GPT 的建議:應該當成錯誤

根據您的描述,當您將 bindIP 設置為 "::"(同時監聽 IPv4 和 IPv6),但端口 8080 已經被 IPv4 使用時,伺服器在啟動時遇到了衝突。您想了解在這種情況下,伺服器應該是給出警告並繼續運行(僅監聽 IPv6),還是應該拋出錯誤並退出程序。

從規範和協議的角度來看,以下是對此問題的分析:

1. 網絡協議和標準行為

2. 用戶體驗和可用性

3. 最佳實踐

4. 行為一致性

結論和建議

基於以上考量,建議在伺服器無法綁定到指定的 IP 地址和端口時,拋出錯誤並退出程序。這樣可以:

附加建議

參考資料

希望以上分析能夠幫助您做出決策。

Shiou-Ju commented 1 week ago

原先如果只有 ipv4 的錯誤,退出的方式

[INFO] 13:19:12 ts-node-dev ver. 2.0.0 (using ts-node ver. 10.9.2, typescript ver. 5.6.3)
正在啟動 Actionhero 進程...
sum action constructor initialized
2024-10-29T05:19:13.151Z - info: creating routes automatically for all actions responding to GET HTTP verb
2024-10-29T05:19:13.152Z - info: creating routes automatically for all actions responding to POST HTTP verb
2024-10-29T05:19:13.188Z - notice: pid: 74494
2024-10-29T05:19:13.188Z - notice: environment: development
2024-10-29T05:19:13.188Z - info: *** Starting my_actionhero_project ***
2024-10-29T05:19:13.191Z - info: actionhero member 192.168.8.140 has joined the cluster
2024-10-29T05:19:13.192Z - notice: Starting server: `web` @ http://0.0.0.0:8080
2024-10-29T05:19:13.195Z - warning: [server: web] port 8080 is being used by ipv4
2024-10-29T05:19:13.196Z - emerg: Uncaught Exception stack=Error: cannot start web server @ 0.0.0.0:8080 => Error: listen EADDRINUSE: address already in use 0.0.0.0:8080
    at Server.<anonymous> (/Users/bamboo/Repos/number-a-b-guess-game/node_modules/actionhero/dist/servers/web.js:149:23)
    at Server.emit (node:events:519:28)
    at emitErrorNT (node:net:1940:8)
    at processTicksAndRejections (node:internal/process/task_queues:82:21)
[ERROR] 13:19:13 Error: cannot start web server @ 0.0.0.0:8080 => Error: listen EADDRINUSE: address already in use 0.0.0.0:8080
2024-10-29T05:19:13.196Z - notice: stopping process...
2024-10-29T05:19:13.298Z - notice: Stopping server: web
2024-10-29T05:19:13.298Z - notice: Stopping server: websocket
2024-10-29T05:19:13.523Z - notice: *** my_actionhero_project Stopped ***
進程即將退出,退出碼:1
error Command failed with signal "SIGINT".

目前嘗試的錯誤拋出方式

[INFO] 13:49:06 ts-node-dev ver. 2.0.0 (using ts-node ver. 10.9.2, typescript ver. 5.6.3)
正在啟動 Actionhero 進程...
sum action constructor initialized
2024-10-29T05:49:07.335Z - info: creating routes automatically for all actions responding to GET HTTP verb
2024-10-29T05:49:07.335Z - info: creating routes automatically for all actions responding to POST HTTP verb
2024-10-29T05:49:07.365Z - notice: pid: 80189
2024-10-29T05:49:07.366Z - notice: environment: development
2024-10-29T05:49:07.366Z - info: *** Starting my_actionhero_project ***
2024-10-29T05:49:07.369Z - info: actionhero member 192.168.8.140 has joined the cluster
2024-10-29T05:49:07.369Z - notice: Starting server: `web` @ http://:::8080
2024-10-29T05:49:07.374Z - error: Error from Initializer name=servers file=/Users/bamboo/Repos/number-a-b-guess-game/node_modules/actionhero/dist/initializers/servers.js type=start stack=Error: IPv4 port 8080 is already in use
    at WebServer.start (/Users/bamboo/Repos/number-a-b-guess-game/node_modules/actionhero/dist/servers/web.js:112:23)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at Servers.start (/Users/bamboo/Repos/number-a-b-guess-game/node_modules/actionhero/dist/initializers/servers.js:81:17)
    at startFunction (/Users/bamboo/Repos/number-a-b-guess-game/node_modules/actionhero/dist/classes/process.js:115:29)
    at Process.start (/Users/bamboo/Repos/number-a-b-guess-game/node_modules/actionhero/dist/classes/process.js:195:17)
    at main (/Users/bamboo/Repos/number-a-b-guess-game/src/server.ts:27:5)
2024-10-29T05:49:07.374Z - notice: stopping process...
2024-10-29T05:49:07.476Z - notice: Stopping server: web
2024-10-29T05:49:07.476Z - notice: Stopping server: websocket
2024-10-29T05:49:07.689Z - notice: *** my_actionhero_project Stopped ***
啟動 Actionhero 進程時發生錯誤: Error: IPv4 port 8080 is already in use
    at WebServer.start (/Users/bamboo/Repos/number-a-b-guess-game/node_modules/actionhero/dist/servers/web.js:112:23)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at Servers.start (/Users/bamboo/Repos/number-a-b-guess-game/node_modules/actionhero/dist/initializers/servers.js:81:17)
    at startFunction (/Users/bamboo/Repos/number-a-b-guess-game/node_modules/actionhero/dist/classes/process.js:115:29)
    at Process.start (/Users/bamboo/Repos/number-a-b-guess-game/node_modules/actionhero/dist/classes/process.js:195:17)
    at main (/Users/bamboo/Repos/number-a-b-guess-game/src/server.ts:27:5) {
  data: {
    name: 'servers',
    file: '/Users/bamboo/Repos/number-a-b-guess-game/node_modules/actionhero/dist/initializers/servers.js',
    type: 'start',
    stack: 'Error: IPv4 port 8080 is already in use\n' +
      '    at WebServer.start (/Users/bamboo/Repos/number-a-b-guess-game/node_modules/actionhero/dist/servers/web.js:112:23)\n' +
      '    at processTicksAndRejections (node:internal/process/task_queues:95:5)\n' +
      '    at Servers.start (/Users/bamboo/Repos/number-a-b-guess-game/node_modules/actionhero/dist/initializers/servers.js:81:17)\n' +
      '    at startFunction (/Users/bamboo/Repos/number-a-b-guess-game/node_modules/actionhero/dist/classes/process.js:115:29)\n' +
      '    at Process.start (/Users/bamboo/Repos/number-a-b-guess-game/node_modules/actionhero/dist/classes/process.js:195:17)\n' +
      '    at main (/Users/bamboo/Repos/number-a-b-guess-game/src/server.ts:27:5)'
  },
  code: 'FATAL_ACTIONHERO_ERROR'
}
✨  Done in 1.26s.