jeffbski / wait-on

wait-on is a cross-platform command line utility and Node.js API which will wait for files, ports, sockets, and http(s) resources to become available
MIT License
1.87k stars 77 forks source link

wait-on claims endpoint is returning 404, when it's actually returning 200. #78

Open jwalton opened 4 years ago

jwalton commented 4 years ago

I have a webpack-dev-server running in HTTPS mode:

cross-env ./node_modules/.bin/webpack-dev-server --config webpack.ci.config.js --progress --inline --port 8080 --host 0.0.0.0 --public localhost:8080 --content-base src/

wait-on will correctly tell me the URL is up with no path:

npm-run wait-on https://127.0.0.1:8080/

passes no problem, but it fails for /login:

$npm-run wait-on -v https-get://127.0.0.1:8080/login
waiting for 1 resources: https-get://127.0.0.1:8080/login
making HTTP(S) get request to  url:https://127.0.0.1:8080/login ...
  HTTP(S) error for https://127.0.0.1:8080/login Error: Request failed with status code 404
making HTTP(S) get request to  url:https://127.0.0.1:8080/login ...
  HTTP(S) error for https://127.0.0.1:8080/login Error: Request failed with status code 404

But curl gets a 200 OK:

$ curl -v -k https://127.0.0.1:8080/login > /dev/null
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:

-- 8< -- cut  out lots of boring SSL stuff here -- >8 --

> GET /login HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Accept-Ranges: bytes
< Cache-Control: public, max-age=0
< Last-Modified: Sat, 22 Aug 2020 03:58:59 GMT
< ETag: W/"4654-1741451ce07"
< Content-Type: text/html; charset=UTF-8
< Content-Length: 18004
< Date: Sat, 22 Aug 2020 04:00:41 GMT
< Connection: keep-alive
<
{ [11512 bytes data]
100 18004  100 18004    0     0   502k      0 --:--:-- --:--:-- --:--:--  502k
* Connection #0 to host 127.0.0.1 left intact
* Closing connection 0

And cross-fetch finds it fine, too:

$ NODE_TLS_REJECT_UNAUTHORIZED=0 node
Welcome to Node.js v12.18.3.
Type ".help" for more information.
> const fetch = require('cross-fetch')
undefined
> fetch('https://127.0.0.1:8080/login').then(res => console.log(res.status))
Promise { <pending> }
> (node:91717) Warning: Setting the NODE_TLS_REJECT_UNAUTHORIZED environment variable to '0' makes TLS connections and HTTPS requests insecure by disabling certificate verification.
200
jwalton commented 4 years ago

Interestingly, curl --head -k https://127.0.0.1:8080/login returns a 404. I wonder if axios is secretly doing a HEAD before it does the GET?

tiagob commented 4 years ago

Same issue on a health check handler

jeffbski commented 4 years ago

wait-on by default does a HEAD request since that is idempotent. GET's are also supposed to be idempotent but sometimes the user implementation performs side effects.

In an ideal world you should always be able to make HEAD requests to a server if it is implemented properly so I am surprised when server implementations do not implement the HEAD method, it makes no sense to me.

Anyway if you need to do a GET request instead, change the URL to http-get://127.0.0.1:8080/login or for TLS https-get://127.0.0.1:8080/login

Your command would look like

npx wait-on https-get://127.0.0.1:8080/login
jwalton commented 4 years ago

As noted in my bug report above, this is exactly what I'm doing:

npm-run wait-on -v https-get://127.0.0.1:8080/login
jeffbski commented 4 years ago

sorry @jwalton I misread your comments above. Maybe axios is doing a HEAD request pre-flight or something. Previously we used request until it was no longer supported, so there are some differences between it and axios and maybe this is one of them. I will see if there is an option we can pass to skip that.

tiagob commented 4 years ago

Missed that. Unfortunately, I don't own the service I'm making the health check to so I can't update it to accept HEAD requests. Prefacing with http-get: fixed my issue. Thank you!

dallonf commented 3 years ago

I'm also having this problem with a Vite dev server. I see the same results ("Request failed with status code 404") regardless of whether I use http or http-get:

wait-on --verbose http-get://localhost:3030/

In other tools, requesting the same URL gives a 200 OK, although HEAD does return a 404.

ocavue commented 3 years ago

For now, a workaround would be using validateStatus in wait-on's configuration and make 404 a valid status code.

validateStatus: (status) => {
    return (200 <= status && status < 300) || status === 404
}
adam-lynch commented 3 years ago

I was getting a 404 when using Vite, not Webpack, but the solution I found might work for you too;

  1. Use GET not HEAD, i.e. use https-get:.
  2. Send an accept: text/html header.

You need a config file to send a header; waitOnConfig.json:

{
  "headers": {
    "accept": "text/html"
  }
}
wait-on -c waitOnConfig.json https-get://localhost:3001
jeffbski commented 3 years ago

I'll see if I can find anything this weekend.

On Thu, Jun 24, 2021 at 12:16 PM Adam Lynch @.***> wrote:

I was getting a 404 when using Vite, not Webpack, but the solution I found might work for you too;

  1. Use GET not HEAD, i.e. use https-get:.
  2. Send an accept: text/html header.

You need a config file to send a header; waitOnConfig.json:

{ "headers": { "accept": "text/html" } }

wait-on -c waitOnConfig.json https-get://localhost:3001

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/jeffbski/wait-on/issues/78#issuecomment-867813529, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAABMOOV67JZVEEGJX4OQI3TUNR6HANCNFSM4QH35UGQ .

-- Jeff Barczewski Founder of CodeWinds http://codewinds.com/ Live and Online developer training

xkim1994 commented 2 years ago

I'm also having this problem with a Vite dev server. I see the same results ("Request failed with status code 404") regardless of whether I use http or http-get:

wait-on --verbose http-get://localhost:3030/

In other tools, requesting the same URL gives a 200 OK, although HEAD does return a 404.

wait-on tcp:3030

kud commented 1 year ago

Thanks for the tips @xkim1994 , it works well! (using Vite here).

segevfiner commented 1 year ago

Why would Vite return a 404 for Accept: */* -.-", probably a bug https://github.com/vitejs/vite/issues/9520