Connecting React Production build with Express Gateway - node.js

Our React Development build runs flawless with Express Gateway setup on localhost. After build React for production and when we run serve -s build login page comes as it is the entry point of the app. It gets 200 ok response when we put sign-in credential. But when we looked into it we can see the request to server was not successful cause token it saves to browser application is undefined and we checked the response, It is "You need to enable javascript...". JS is enabled no doubt. I have checked By using
axios.post('http://localhost:8080/api/v1/auth/sign-in', userData)
It works fine but when setup proxy:
axios.post('/auth/sign-in', userData)
react doesn’t run
Here is the part of yml for express gateway setup:
http:
port: 8080
apiEndpoints:
auth-service:
host: "*"
paths: ["/api/v1/auth/*", "/api/v1/auth"]
mail-service:
host: "*"
paths: ["/api/v1/mail/*", "/api/v1/mail"]
serviceEndpoints:
auth-service-endpoint:
url: http://localhost:3003/
mail-service-endpoint:
url: http://localhost:3005/
policies:
- proxy
pipelines:
auth-service-pipeline:
apiEndpoints:
- auth-service
policies:
- proxy:
action:
serviceEndpoint: auth-service-endpoint
changeOrigin: true
stripPath: true
mail-service-pipeline:
apiEndpoints:
- mail-service
policies:
- proxy:
action:
serviceEndpoint: mail-service-endpoint
changeOrigin: true
stripPath: true
I put the setupProxy.js on src directory of React:
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(createProxyMiddleware('/api/v1',
{ target: 'http://localhost:8080',
secure: false,
changeOrigin: true,
// pathRewrite: {
// "^/api": "/api/v1",
// }
}
));
}
Currently everything is on same machine. We are not using docker.
The application runs on Dev environment but shows 200 ok response in production build
Any help will be appreciated.
[Edit]
krypton:admin-dashboard-server hasan$ curl -v http://localhost:3001/find_all_services/1/10
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 3001 (#0)
> GET /find_all_services/1/10 HTTP/1.1
> Host: localhost:3001
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Access-Control-Allow-Origin: *
< X-DNS-Prefetch-Control: off
< X-Frame-Options: SAMEORIGIN
< Strict-Transport-Security: max-age=15552000; includeSubDomains
< X-Download-Options: noopen
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Content-Type: application/json; charset=utf-8
< Content-Length: 1833
< ETag: W/"729-LM91B3vCUrbvesBrp32ykiXXkQo"
< Date: Tue, 12 Jan 2021 14:57:24 GMT
< Connection: keep-alive
<
* Connection #0 to host localhost left intact
[{"id":1,"name":"Laser Hair Remove"},
{"id":2,"name":"Facial Treatments"}
]
krypton:admin-dashboard-server hasan$ curl -v
http://localhost:8080/api/v1/services/find_all_services/1/10
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET /api/v1/services/find_all_services/1/10 HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< access-control-allow-origin: *
< x-dns-prefetch-control: off
< x-frame-options: SAMEORIGIN
< strict-transport-security: max-age=15552000; includeSubDomains
< x-download-options: noopen
< x-content-type-options: nosniff
< x-xss-protection: 1; mode=block
< content-type: application/json; charset=utf-8
< content-length: 1833
< etag: W/"729-LM91B3vCUrbvesBrp32ykiXXkQo"
< date: Tue, 12 Jan 2021 15:03:45 GMT
< connection: keep-alive
<
* Connection #0 to host localhost left intact
[{"id":1,"name":"Laser Hair Remove"},
{"id":2,"name":"Facial Treatments"}
]
krypton:admin-dashboard-server hasan$ curl -v -H "Content-Type: application/json" -X POST -d
'{"email":"mh.mithun#gmail.com","password":"safe123"}'
http://localhost:8080/api/v1/auth/sign-in
Note: Unnecessary use of -X or --request, POST is already inferred.
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> POST /api/v1/auth/sign-in HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 52
>
* upload completely sent off: 52 out of 52 bytes
< HTTP/1.1 200 OK
< access-control-allow-origin: *
< x-dns-prefetch-control: off
< x-frame-options: SAMEORIGIN
< strict-transport-security: max-age=15552000; includeSubDomains
< x-download-options: noopen
< x-content-type-options: nosniff
< x-xss-protection: 1; mode=block
< content-type: application/json; charset=utf-8
< content-length: 270
< etag: W/"10e-S+kd8b4Yfl7un04FVGe3MFLFEaY"
< date: Tue, 12 Jan 2021 15:40:12 GMT
< connection: keep-alive
<
* Connection #0 to host localhost left intact
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhbGdvcml0aG0iOiJIUzI1N"
krypton:admin-dashboard-server hasan$ curl -v -H "Content-Type: application/json" -X POST -d '{"email":"mh.mithun#gmail.com","password":"safe123"}' http://localhost:3003/sign-in
Note: Unnecessary use of -X or --request, POST is already inferred.
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 3003 (#0)
> POST /sign-in HTTP/1.1
> Host: localhost:3003
> User-Agent: curl/7.54.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 52
>
* upload completely sent off: 52 out of 52 bytes
< HTTP/1.1 200 OK
< Access-Control-Allow-Origin: *
< X-DNS-Prefetch-Control: off
< X-Frame-Options: SAMEORIGIN
< Strict-Transport-Security: max-age=15552000; includeSubDomains
< X-Download-Options: noopen
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Content-Type: application/json; charset=utf-8
< Content-Length: 270
< ETag: W/"10e-LW/1l5fXf5BaiF3KJMvG60xRthE"
< Date: Tue, 12 Jan 2021 15:45:33 GMT
< Connection: keep-alive
<
* Connection #0 to host localhost left intact
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhbGdvcml0aG0i"

Related

SSL certificate error on linux local virtual host

* Trying 172.28.1.11:443... * TCP_NODELAY set * Connected to local.accounts.tandfeditingservices.com (172.28.1.11) port 443 (#0) * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: /etc/ssl/certs/ca-certificates.crt CApath: /etc/ssl/certs * SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384 * ALPN, server accepted to use http/1.1 * Server certificate: * subject: O=mkcert development certificate; OU=sanketm#SANKETM (SANKET MORE) * start date: Jun 1 00:00:00 2019 GMT * expire date: Sep 28 10:43:11 2032 GMT * issuer: O=mkcert development CA; OU=sanketm#SANKETM (SANKET MORE); CN=mkcert sanketm#SANKETM (SANKET MORE) * SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway. > POST /oauth/token HTTP/1.1 Host: local.accounts.tandfeditingservices.com User-Agent: GuzzleHttp/7 Content-Type: application/x-www-form-urlencoded Content-Length: 135 * upload completely sent off: 135 out of 135 bytes * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < Server: nginx/1.18.0 (Ubuntu) < Content-Type: application/json; charset=UTF-8 < Transfer-Encoding: chunked < Connection: keep-alive < X-Powered-By: PHP/8.0.7 < pragma: no-cache < Cache-Control: no-store, private < Date: Wed, 28 Sep 2022 10:44:54 GMT < X-RateLimit-Limit: 500 < X-RateLimit-Remaining: 499 < Strict-Transport-Security: max-age=15768000; includeSubDomains < * Connection #0 to host local.accounts.tandfeditingservices.com left intact
I am getting above message during any virtual domain network call on localhost. I dig around it so come to know it is regarding SSL certicate. But when I checked the certificate with openssl s_client -connect local.api.com:443 -CAfile /etc/ssl/certs/ca-certificates.crt. It showing the correct result as Verify return code: 0 (ok)
Any help or guidance will be helpful.

Unable to redirect to other url in apache

I have two Redhat Linux servers, say 'original' and 'demo'. Both have apache running on them. On original server, I have a link 'http://original.com/abc' on a page which I want redirect it to http://demo.com.
What I have done is-
Open httpd.conf on original server and added following lines and restarted apache service:
ProxyPass /abc http://demo.com/
ProxyPassReverse /abc http://demo.com/
But when I am trying to access http://original.com/abc, it is redirecting me to the original server i.e. on http://original.com (not on http://demo.com)
I have tried to find the solutions on various sites but unable to find out what the problem is.
Edit:
Output of curl -v http://original.com/abc:
curl -v http://original.com/abc
* About to connect() to original.com port 80 (#0)
* Trying 10.100.100.100...
* Connected to original.com (10.100.100.100) port 80 (#0)
> GET /demo HTTP/1.1
> User-Agent: curl/7.29.0
> Host: original.com
> Accept: */*
>
< HTTP/1.1 302 Found
< Date: Tue, 24 Apr 2018 06:30:23 GMT
< Server: Apache-Coyote/1.1
< X-Frame-Options: SAMEORIGIN
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-XSS-Protection: 1; mode=block
< X-Frame-Options: SAMEORIGIN
< X-Content-Type-Options: nosniff
< Location: login.action
< Content-Type: text/html; charset=UTF-8
< Content-Length: 0
< Set-Cookie: JSESSIONID=0BAA246C7F2505D2F5A0335CB0542CAA; Path=/; HttpOnly
<
* Connection #0 to host original.com left intact
Output of curl -v http://demo.com/ :
#curl -v http://demo.com
* About to connect() to 10.100.100.101 port 80 (#0)
* Trying 10.100.100.101...
* Connected to 10.100.100.101 (10.100.100.101) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: demo.com
> Accept: */*
>
< HTTP/1.1 302 Found
< Server: Apache-Coyote/1.1
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-XSS-Protection: 1; mode=block
< X-Frame-Options: SAMEORIGIN
< X-Content-Type-Options: nosniff
< Set-Cookie: JSESSIONID=FED19458459131F456D638EC57278C2A; Path=/; HttpOnly
< Location: login.action
< Content-Type: text/html
< Content-Length: 0
< Date: Tue, 24 Apr 2018 06:31:47 GMT
<
* Connection #0 to host demo.com left intact
The textual order of ProxyPass statements is relevant. The first matched entry stops further matching.
ProxyPass / http://some.tomcat:8080/
ProxyPassReverse / http://some.tomcat:8080/
...
ProxyPass /abc http://demo.com/
ProxyPassReverse /abc http://demo.com/
Here, demo.com would be fed nothing. The some.tomcat would be fed both / and /abc

CouchDB can't get cookie auth session for nonadmin user

For admin user:
$ curl -X POST localhost:5984/_session -d "username=admin&password=admin"
{"ok":true,"name":"admin","roles":["_admin"]}
$ curl -vX GET localhost:5984/_session --cookie AuthSession=YWRtaW...
{"ok":true,"userCtx":{"name":"admin","roles":["_admin"]},"info":{"authentication_db":"_users","authentication_handlers":["cookie","default"],"authenticated":"cookie"}}
but for regular user:
$ curl -vX POST localhost:5984/_session -d "username=user&password=123"
{"ok":true,"name":"user","roles":["users"]}
$ curl -vX GET localhost:5984/_session --cookie AuthSession=ZGlqbzo...
{"ok":true,"userCtx":{"name":null,"roles":[]},"info":{"authentication_db":"_users","authentication_handlers":["cookie","default"]}}
The same thing happens when im doing XmlHttpRequest via iron-ajax element, or simply from chrome. What am I doing wrong?
CouchDB version: 2.1.1
Config:
[chttpd]
bind_address = 0.0.0.0
port = 5984
authentication_handlers = {couch_httpd_auth, cookie_authentication_handler}, {couch_httpd_auth, default_authentication_handler}
[httpd]
enable_cors = true
[couch_httpd_auth]
allow_persistent_cookies = true
timeout = 60000
[cors]
credentials = true
origins = *
headers = accept, authorization, content-type, origin, referer
methods = GET, PUT, POST, HEAD, DELETE
I didn't quite get your problem, but here is what I do with curl to authenticate with cookie as a nonadmin user:
First I run curl with -v option to see the header fields:
$ curl -k -v -X POST https://192.168.1.106:6984/_session -d 'username=jan&password=****'
Note: Unnecessary use of -X or --request, POST is already inferred.
* Trying 192.168.1.106...
* Connected to 192.168.1.106 (192.168.1.106) port 6984 (#0)
* found 148 certificates in /etc/ssl/certs/ca-certificates.crt
* found 604 certificates in /etc/ssl/certs
* ALPN, offering http/1.1
* SSL connection using TLS1.2 / ECDHE_RSA_AES_128_GCM_SHA256
* server certificate verification SKIPPED
* server certificate status verification SKIPPED
* error fetching CN from cert:The requested data were not available.
* common name: (does not match '192.168.1.106')
* server certificate expiration date OK
* server certificate activation date OK
* certificate public key: RSA
* certificate version: #3
* subject: O=Tech Studio
* start date: Sat, 31 Mar 2018 04:37:51 GMT
* expire date: Tue, 30 Mar 2021 04:37:51 GMT
* issuer: O=Tech Studio
* compression: NULL
* ALPN, server did not agree to a protocol
> POST /_session HTTP/1.1
> Host: 192.168.1.106:6984
> User-Agent: curl/7.47.0
> Accept: */*
> Content-Length: 25
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 25 out of 25 bytes
< HTTP/1.1 200 OK
< Set-Cookie: AuthSession=amFuOjVBRTk3MENGOuKAb68qYzf5jJ7bIOq72Jlfw-Qb; Version=1; Secure; Path=/; HttpOnly
< Server: CouchDB/2.1.1 (Erlang OTP/18)
< Date: Wed, 02 May 2018 08:03:27 GMT
< Content-Type: application/json
< Content-Length: 44
< Cache-Control: must-revalidate
<
{"ok":true,"name":"jan","roles":["sample"]}
* Connection #0 to host 192.168.1.106 left intact
I see in the above header fields the cookie:
Set-Cookie: AuthSession=amFuOjVBRTk3MENGOuKAb68qYzf5jJ7bIOq72Jlfw-Qb; Version=1; Secure; Path=/; HttpOnly
I use the above cookie to authenticate as a nonadmin user and get the user info for the same nonadmin user like this:
$ curl -k -X GET https://192.168.1.106:6984/_users/org.couchdb.user:jan -H 'Cookie: AuthSession=amFuOjVBRTk3MENGOuKAb68qYzf5jJ7bIOq72Jlfw-Qb'
{"_id":"org.couchdb.user:jan","_rev":"3-f11b227a6e1236fa502af668fdbf326d","name":"jan","roles":["sample"],"type":"user","password_scheme":"pbkdf2","iterations":10,"derived_key":"a973123ebd9dbc2a543d477a506268b018e7aab4","salt":"0ef2111a894062b08ffd723fd34b6b75"}
Problem gone when i removed from my local.ini
authentication_handlers = {couch_httpd_auth, cookie_authentication_handler}, {couch_httpd_auth, default_authentication_handler}
Because i used incorrect handler: couch_httpd_auth in the config for chttpd, when that handler is only written to work with the original couch_httpd module

Express return 200 in browser but 404 with curl -I

I have an express server which serve some static files.
When I make a request from my browser all is fine. But when I use cURL it becomes a little bit weird:
curl https://www.goukitok.com : HTTP 200 with page content
curl -I https://www.goukitok.com : HTTP 404 (see verbose logs below).
I need curl -I to work because my client need to promote this page via Google AdWords and Google performs a check before allowing him to create the ad.
My server is hosted on Heroku.
I cannot figure what is making that? Do you have some idea?
Thanks in advance!
curl -v https://goukitok.com
* Rebuilt URL to: https://www.goukitok.com/
* Trying 79.125.104.202...
* Connected to www.goukitok.com (79.125.104.202) port 443 (#0)
* found 148 certificates in /etc/ssl/certs/ca-certificates.crt
* found 597 certificates in /etc/ssl/certs
* ALPN, offering http/1.1
* SSL connection using TLS1.2 / ECDHE_RSA_AES_128_GCM_SHA256
* server certificate verification OK
* server certificate status verification SKIPPED
* common name: www.goukitok.com (matched)
* server certificate expiration date OK
* server certificate activation date OK
* certificate public key: RSA
* certificate version: #3
* subject: CN=www.goukitok.com
* start date: Sat, 16 Dec 2017 23:42:00 GMT
* expire date: Fri, 16 Mar 2018 23:42:00 GMT
* issuer: C=US,O=Let's Encrypt,CN=Let's Encrypt Authority X3
* compression: NULL
* ALPN, server accepted to use http/1.1
> GET / HTTP/1.1
> Host: www.goukitok.com
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: Cowboy
< Connection: keep-alive
< X-Powered-By: Express
< Access-Control-Allow-Origin: *
< Accept-Ranges: bytes
< Cache-Control: public, max-age=0
< Last-Modified: Fri, 02 Feb 2018 10:00:37 GMT
< Etag: W/"33cc-16155f5f188"
< Content-Type: text/html; charset=UTF-8
< Content-Length: 13260
< Set-Cookie: sessionId=s%3Akeguyz6fxoKCQDHIGY2Nd9mBgzM1pdiw.WhMMw37PNfXdv%2FYdx93oOdyTYMuv9SfcrYY0yuBrZ2E; Path=/; Expires=Tue, 13 Feb 2018 13:52:09 GMT; HttpOnly
< Link: <https://code.jquery.com/jquery-1.10.2.js>; rel=preload; as=script
< Link: <https://fonts.googleapis.com/css?family=Cuprum:400,700%7CNunito>; rel=preload; as=style
< Link: </static/libs/bootstrap/css/bootstrap.min.css>; rel=preload; as=style
< Link: </static/libs/animate/animate.css>; rel=preload; as=style
< Link: </static/libs/slick-slider/slick.css>; rel=preload; as=style
< Link: </static/libs/slick-slider/slick-theme.css>; rel=preload; as=style
< Link: </static/libs/fancybox/css/jquery.fancybox.css>; rel=preload; as=style
< Link: </static/libs/fancybox/css/jquery.fancybox-buttons.css>; rel=preload; as=style
< Link: </static/libs/fancybox/css/jquery.fancybox-thumbs.css>; rel=preload; as=style
< Link: </static/css/layout.css>; rel=preload; as=style
< Link: </static/css/components.css>; rel=preload; as=style
< Link: </static/css/responsive.css>; rel=preload; as=style
< Link: </static/libs/jquery/jquery-2.2.4.min.js>; rel=preload; as=script
< Link: <https://www.facebook.com/tr?id=1796165227077270&ev=PageView&noscript=1>; rel=preload; as=image
< Link: <https://maps.googleapis.com/maps/api/js?key=AIzaSyDqCiEbDSYSs-Wn-MHsq5jaygV4aew3_Tc&libraries=places>; rel=preload; as=script
< Link: </app/static/css/app.e595d7bef36fb3598585be947d8eb42a.css>; rel=preload; as=style
< Link: </app/static/js/manifest.1b6260866eb9b8932450.js>; rel=preload; as=script
< Link: </app/static/js/vendor.9159aedaca9691925a48.js>; rel=preload; as=script
< Link: </app/static/js/app.238040a9cfecf8b392ea.js>; rel=preload; as=script
< Link: </static/libs/bootstrap/js/bootstrap.min.js>; rel=preload; as=script
< Link: </static/libs/wow-js/wow.min.js>; rel=preload; as=script
< Link: </static/libs/slick-slider/slick.min.js>; rel=preload; as=script
< Link: </static/libs/isotope/isotope.pkgd.min.js>; rel=preload; as=script
< Link: </static/libs/fancybox/js/jquery.fancybox.min.js>; rel=preload; as=script
< Link: </static/libs/fancybox/js/jquery.fancybox-buttons.min.js>; rel=preload; as=script
< Link: </static/libs/fancybox/js/jquery.fancybox-thumbs.min.js>; rel=preload; as=script
< Link: </static/js/main.js>; rel=preload; as=script
< Link: </static/libs/parallax/jquery.parallax-scroll.min.js>; rel=preload; as=script
< Vary: Accept-Encoding
< Date: Tue, 06 Feb 2018 13:52:09 GMT
< Via: 1.1 vegur
<
..... My page content
* Connection #0 to host www.goukitok.com left intact
curl -Iv https://goukitok.com
* Rebuilt URL to: https://www.goukitok.com/
* Trying 79.125.111.38...
* Connected to www.goukitok.com (79.125.111.38) port 443 (#0)
* found 148 certificates in /etc/ssl/certs/ca-certificates.crt
* found 597 certificates in /etc/ssl/certs
* ALPN, offering http/1.1
* SSL connection using TLS1.2 / ECDHE_RSA_AES_128_GCM_SHA256
* server certificate verification OK
* server certificate status verification SKIPPED
* common name: www.goukitok.com (matched)
* server certificate expiration date OK
* server certificate activation date OK
* certificate public key: RSA
* certificate version: #3
* subject: CN=www.goukitok.com
* start date: Sat, 16 Dec 2017 23:42:00 GMT
* expire date: Fri, 16 Mar 2018 23:42:00 GMT
* issuer: C=US,O=Let's Encrypt,CN=Let's Encrypt Authority X3
* compression: NULL
* ALPN, server accepted to use http/1.1
> HEAD / HTTP/1.1
> Host: www.goukitok.com
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 404 Not Found
HTTP/1.1 404 Not Found
< Server: Cowboy
Server: Cowboy
< Connection: keep-alive
Connection: keep-alive
< X-Powered-By: Express
X-Powered-By: Express
< Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: *
< Content-Type: text/html; charset=utf-8
Content-Type: text/html; charset=utf-8
< Content-Length: 2644
Content-Length: 2644
< Etag: W/"a54-jADpSsEjSg0qJ+/8y3dImxntFHg"
Etag: W/"a54-jADpSsEjSg0qJ+/8y3dImxntFHg"
< Set-Cookie: sessionId=s%3ADWjJv6A4KYHEJcSdoxMABFcVXc6L-093.2lROCz0XKPu5dI1wmSOKgB3Ch%2FbPJQVaaS58zHXhLi8; Path=/; Expires=Tue, 13 Feb 2018 13:54:59 GMT; HttpOnly
Set-Cookie: sessionId=s%3ADWjJv6A4KYHEJcSdoxMABFcVXc6L-093.2lROCz0XKPu5dI1wmSOKgB3Ch%2FbPJQVaaS58zHXhLi8; Path=/; Expires=Tue, 13 Feb 2018 13:54:59 GMT; HttpOnly
< Vary: Accept-Encoding
Vary: Accept-Encoding
< Date: Tue, 06 Feb 2018 13:54:59 GMT
Date: Tue, 06 Feb 2018 13:54:59 GMT
< Via: 1.1 vegur
Via: 1.1 vegur
<
* Connection #0 to host www.goukitok.com left intact
I've figured out by enforcing the static path at the very beginning of my routing file. It was a problem of middleware order
As #PeterVC pointed out here my server didn't handle the HEAD requests (sent by cURL when using the I flag).
I just moved app.use('/', express.static(path.join(__dirname, '../../dist'))) to the top a my express router file.

Use express sendFile for HEAD requests

sendFile is for sending files and it also figures out some interesting headers from the file (like content length). For a HEAD request I would ideally want the exact same headers but just skip the body.
There doesn't seem to be an option for this in the API. Maybe I can override something in the response object to stop it from sending anything?
Here's what I got:
res.sendFile(file, { headers: hdrs, lastModified: false, etag: false })
Has anyone solved this?
As Robert Klep has already written, the sendFile already has the required behavior of sending the headers and not sending the body if the request method is HEAD.
In addition to that, Express already handles HEAD requests for routes that have GET handlers defined. So you don't even need to define any HEAD handler explicitly.
Example:
let app = require('express')();
let file = __filename;
let hdrs = {'X-Custom-Header': '123'};
app.get('/file', (req, res) => {
res.sendFile(file, { headers: hdrs, lastModified: false, etag: false });
});
app.listen(3322, () => console.log('Listening on 3322'));
This sends its own source code on GET /file as can be demonstrated with:
$ curl -v -X GET localhost:3322/file
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3322 (#0)
> GET /file HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:3322
> Accept: */*
>
< HTTP/1.1 200 OK
< X-Powered-By: Express
< X-Custom-Header: 123
< Accept-Ranges: bytes
< Cache-Control: public, max-age=0
< Content-Type: application/javascript
< Content-Length: 267
< Date: Tue, 11 Apr 2017 10:45:36 GMT
< Connection: keep-alive
<
[...]
The [...] is the body that was not included here.
Without adding any new handler this will also work:
$ curl -v -X HEAD localhost:3322/file
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3322 (#0)
> HEAD /file HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:3322
> Accept: */*
>
< HTTP/1.1 200 OK
< X-Powered-By: Express
< X-Custom-Header: 123
< Accept-Ranges: bytes
< Cache-Control: public, max-age=0
< Content-Type: application/javascript
< Content-Length: 267
< Date: Tue, 11 Apr 2017 10:46:29 GMT
< Connection: keep-alive
<
This is the same but with no body.
Express uses send to implement sendFile, which already does exactly what you want.

Resources