BackendStack21/fast-gateway

https support for target URL

Closed this issue · 15 comments

Following is my gateway configuration :

const gateway = require(‘fast-gateway’)
server = gateway(
{
routes: [
{
prefix: ‘/fakeservice’,
target: ‘https://reqres.in/’,    //--->target URL with **HTTPS**
docs: {
name: ‘Fake service’,
endpoint: ‘/api/users/2’,
},
},
{
prefix: ‘/empservice’,
target: ‘http://dummy.restapiexample.com/’,   //--->target url with **HTTP**
docs: {
name: ‘Employee Service’,
endpoint: ‘/api/v1/employees’,
}
},
]
}
);
server.start(3123);

While I am running locally using following URLs to route, I have success and failure :

  1. http://localhost:3123/fakeservice/api/users/2
    —> FAILED : Returning NOT found error, even though target https://reqres.in/api/users/2 returns valid JSON

  2. http://localhost:3123/empservice/api/v1/employees
    —> SUCCEEDED : Returning success response with JSON payload as expected.

Question: does fast-gateway support target with HTTPS? If so, then why it’s not working? Am I missing any configuration? Do I need to add any extra parameter to route target having HTTPS protocol?

Please help. I am planning to use this in commercial production delivery project.

Hi @skskcco2o17 thanks for reaching out.

Can you please try out without the / character at the end of the target setting.
In case you are using self-signed SSL certs please consider that you need to extend the fast-proxy configuration as described:

...
{
  prefix: '/fakeservice',
  target: 'https://reqres.in'
  fastProxy: {
    rejectUnauthorized: false
  }
...

Looking forward to hear more from you.

Best Regards, Rolando

Hi Rolando,

Thanks for your quick response!

My fake service is GET https://reqres.in/api/users/2 , it does not require any self-signed SSL certificate, even you can run in any browser , it will return JSON response.

Now, as per your suggestion , I have changed the configuration as below and tried ,but no luck, same issue:

        ```
       {
    		    prefix: '/fakeservice',
    		    target: 'https://reqres.in',   
    		    docs: {
	    	        name: 'Fake service',
	    	        endpoint: '/api/users/2',
	    	      },
	    	      fastProxy: {
	    	    	    rejectUnauthorized: false
	    	    	  }
	    	   
    	  }, 
        server.start (31232)

As you see, my gateway server is running locally on port # 31232.
and so I am hitting below URL to test my fake service:
http://localhost:31232/fakeservice/api/users/2

And I am getting HTTP ERROR 400 :-(

Please help

Best Regards
Supal

Hi @skskcco2o17, I have checked your configuration.
Unfortunately I have reproduced your issue, but I can't find a reason for the why.
Are there any SSL specific configurations required? In that case, you can also overwrite the http request configuration, please see: https://www.npmjs.com/package/fast-proxy#extended-configurations
I am also not sure if there are other request requirements for those endpoints in https://reqres.in. For example, required CDN headers, etc...

As an example, here I describe an HTTPS proxy that points to https://httpbin.org, there is really nothing special on routing to SSL protected endpoints.

const gateway = require('fast-gateway')
gateway({
  routes: [{
    prefix: '/httpbin',
    target: 'https://httpbin.org'
  }]
}).start(8080)

then:

curl http://localhost:8080/httpbin/get

I really wish you a good resolution on this.

Regards,
Rolando

Hello Rolando...Thanks !

This is really strange! non of the following https URLs (which are actually publicly available for testing) are working except yours one i.e. https://httpbin.org: :

Even it's not working on a simple microservice exposed publicly as https, which I developed and deployed in OpenShift on IBM Cloud. There is no way I can debug the problem e.g., using console log or similar.

I must say that I really found fast-gateway the best simple and super fast API Gateway to implement for any microservice solution, compare to market leading products like nginx and express-gateway.

Since you are the author of fast-gateway , no one can figure out the problem and fix the issue but yourself. :-) .

Please help me knowing, when can I have this issue resolved.
I have a delivery timeline mid of this month.

Best regards
Supal

Sure , Rolando !! much appreciable !... eagerly waiting for the resolution :-)

Hi @skskcco2o17, I have found the issue.

The thing is, Cloudflare responds with 400 when the x-forwarded-host is localhost or localhost:8080, etc...
This is the reason why it does not fails with other https servers.

I am about to push a patch on the fast-proxy library that will make optional the addition of this header, or just make it configurable.
(some context: fastify/fast-proxy#26)
I will let you know as soon as the fix is available in a new version.

Thanks again for reporting,
Stay tuned!

Hi Ronaldo...

Thank you so much... I am expecting to have the new version of fast-proxy soon , so that I can incorporate and do final testing before deployment, by mid of this month.

regards
Supal

Hi @skskcco2o17, v2.3.3 was released with the latest version of fast-proxy.
Now you are able to modify the request headers, in this case, required for Cloudflare.

Here a working example:

const gateway = require('fast-proxy')

gateway({
  routes: [{
    prefix: '/httpbin',
    target: 'https://httpbin.org'
  }, {
    prefix: '/jsonplaceholder',
    target: 'https://jsonplaceholder.typicode.com',
    hooks: {
      rewriteRequestHeaders (req, headers) {
        delete headers['x-forwarded-host']

        return headers
      }
    }
  }]
}).start(8080)

Looking forward to your feedback, feel free to close this issue on success.

Regards,
Rolando

Hi Ronaldo,
Thanks for releasing new version with fix. I just saw your note.

I will upgrade fast-gateway with this new version v2.3.3 and start working to change my code accordingly and test thoroughly (will all my https microservices). I will give you feedback ASAP and will definitely close the issues on success.

Please stay tuned!
regards
Supal

Hi Rolando,
I just did thorough testing; it seems all https are working as expected.

But while testing my https REST API ( which does not require any self-signed SSL certificate) , I am NOT getting the JSON output as I was expecting:

My https REST API is :

https://stock-services-hemvyas1-in.kemeteleccorp-158084310-f72ef11f3ab089a8c677044eb28292cd-0001.eu-de.containers.appdomain.cloud/rest/stock/getHolding/114

While testing this API in browser I am getting expected JSON as below :

{"holdingId":114,"accountId":"ab","purchaseDate":1607731200000,"symbol":"HCL","companyName":"HCL Techonolgy","quantity":900,"price":4000.0}

My Gateway configuration is as below :

		``` server = gateway(
		{   
    	  routes: [
				{
  	    		    prefix: '/stockservice',
  	    		    target: 'https://stock-services-hemvyas1-in.kemeteleccorp-158084310-f72ef11f3ab089a8c677044eb28292cd-0001.eu-de.containers.appdomain.cloud',
  	    		    hooks: {
  	    		      rewriteRequestHeaders (req, headers) {
  	    		        delete headers['x-forwarded-host']

  	    		        return headers
  	    		      }
  	    		    },
  	    		    docs: {
  		    	        name: 'Daytrader Stock Microservice',
  		    	        endpoint: '/rest/stock/getHolding/114',
  		    	      },
  	    	  		
    			  },
			]
			
		}
	)
	server.start(8080); ```

Based on the above configuration, I was testing using following URL, but not getting the JSON output, which I am supposed to get as mentioned above :

http://localhost:8080/stockservice/rest/stock/getHolding/114

Extremely sorry for bothering you too much. I know that you are helping me in all aspects. But I need this problem to be resolved urgently.

Seeking your support again. My humble request to test my service only and fix.

Regards
Supal

Fix is waiting for review: fastify/fast-proxy#28
In the meantime you can also do:

hooks: {
  rewriteRequestHeaders (req, headers) {
    delete headers['x-forwarded-host']
    delete headers.host

    return headers
  }
},

Thanks for reporting.

WOWOOO !! Finally all https (with no self-signed cert) URL targets are working !!
Thanks Rolando for your splendid support. Really appreciable.

Let me know, whether I need to wait for your confirmation on new version's availability or I should close this issue now.

I may also need your help to know how we can handle https target having SSL self-signed cert required, but later.

Thanks again and best regards
Supal

Hi @skskcco2o17, is great to hear that it worked for you.
v2.3.4 of fast-gateway is out with the fix. So you don't need delete headers.host anymore.

For using self-signed certs you can use:

const gateway = require('./../index')

gateway({
  routes: [{
    fastProxy: {
      rejectUnauthorized: false
    },
    prefix: '/httpbin',
    target: 'https://httpbin.org'
  }]
}).start(8080)

I am closing this issue, in case you have other issues, feel free to contact me again.

Best Regards,
Rolando