How to listen to Server-sent Events on SAPUI5 - https

I'm trying to make my SAPUI5 app deployed on Sap Cloud Platform listen to server-sent events sent from a simple test server.
I found this tutorial: https://auth0.com/blog/developing-real-time-web-applications-with-server-sent-events/
The tutorial explains how to create a React app that displays a table with some information and how to use server-sent events to make the server update the information on the client without the client having to make periodic requests to the server.
I tested it and got it working, and now I'm trying to substitute the React client app for my SAPUI5 app.
I added a HANA destination in my sap account and added the destination in my neo-app file.
This is basically the controller for the app:
onInit: function () {
this.eventSource = new EventSource('/flightinfo/events');
this.eventSource.addEventListener('flightStateUpdate', this.updateFlightState, false);
}
updateFlightState: function(event) {
console.log("Hello");
}
And this is how the destination is declared in the neo-app.json file:
{
"path": "/flightinfo",
"target": {
"type": "destination",
"name": "flightinfo"
},
"description": "flightinfo"
}
I expected my app to print to the console every time the server sent an update, since I'm just testing the connection and not using the data received. However, the app doesn't fire the event that would trigger the console output.
My server log shows the request is received and the response is 200 OK, but the webapp shows the response as timed out:
HTTP Status 504 - Socket connection timed out for host [my server]. Reason: Read timed out (local port [port number] to address [ip address] ([...].od.sap.biz), remote port [port number] to address [ip address] ([...].od.sap.biz))
I redacted IPs and Ports from the error message.
Trying to open the request url from the network tab at chrome responds with:
HTTP Status 503 - No application is available to handle this request
However, navigating manually to the address of my server (the address I introduced in the Destinations tab on SCP) does show me the data that my server is sending, updates and all.
What am I getting wrong? Is there some security policy preventing my server from sending server-sent events through a SCP Destination?
Any help would be greatly appreciated, since I can't seem to find any information about using server-sent events on SAPUI5 anywhere.
Thank you!

Related

Expo client run in phone communication with local backend

I'm trying out the communication between my backend / frontend. The application is developed in react native and my backend is based on spring boot. When I run my application in my phone through the Expo Go app I can't send http requests to my backend (it works with postman at: localhost:8080/user).
When I try to do the same requests in my application I have defined the following function:
export function signup(signupRequest) {
return fetch({
url: "192.168.10.152:8080" + "/user",
method: "POST",
body: JSON.stringify(signupRequest)
});
}
And then I get the following error:
[Unhandled promise rejection: TypeError: Network request failed]
at node_modules/whatwg-fetch/dist/fetch.umd.js:535:17 in setTimeout$argument_0
If it helps I run my backend on ubuntu 20.04 and I got my local ip with the command
ip a
Update, I have no updated my application.properties in my spring-boot project like this:
server.address=192.168.10.152
server.port=8080
I still get the same error when I try to make a post-request from my react native application however.
I tried to push my backend to the domain with https protocol and everything was ok. There's an application, ngrok that allows you to send requests to a server but using other link with https protocol.
For example, if you have your backend server on localhost:5000, then you need to open ngrok command line and integrate your server with ngrok http 5000 command. As the result you'll get a link that will look like this:
https://f971-31-128-76-233.eu.ngrok.io

Ocelot API gateway fails to establish SSL connection to downstream

I have an Ocelot API gateway in front of all our microservices providing some form of an API. We also have some external services hosted in Azure, one which I figured I wanted to route through our API gateway. However, as the title says, when attempting to connect using https as the downstream scheme I get the following error message:
Error Code: ConnectionToDownstreamServiceError Message: Error connecting to downstream service, exception: System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
---> System.IO.IOException: Cannot determine the frame size or a corrupted frame was received.
at System.Net.Security.SslStream.ReceiveBlobAsync[TIOAdapter](TIOAdapter adapter)
at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](TIOAdapter adapter, Boolean receiveFirst, Byte[] reAuthenticationData, Boolean isApm)
at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Boolean async, Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
Googling the inner exception leads to some posts suggesting that since .net 5.0 preview 6 the default tls version is determined by the operating system default which by now should probably be TLSv1.3. I believe Azure functions does not support TLSv1.3 yet and it appears that the downstream request from Ocelot does not fall back on TLSv1.2 when this is the case.
Attempting to run the request a number of other ways yields only success which leads me to believe that this is an issue specific to Ocelot. Running requests directly to the Azure resource via
Postman: succeeds. TLSv1.2 is used.
curl: succeeds. TLS1.2 is used here too.
GetAsync using HttpClient in C# (.net 5.0): succeeds.
Running curl with -v I can see that it attempts a handshake with TLSv1.3 first but then falls back to TLS1.2.
Can anyone confirm that the tls version is indeed the problem? And in that case is there any way to allow TLSv1.2 in an asp.net 5 ocelot API Gateway project?
Additional information:
Setting "DangerousAcceptAnyServerCertificateValidator": true does not resolve the issue
The gateway has no issues when using http as downstream scheme
I have a similar environement where most of my Ocelot downstream requests are currently pointing to localhost microservices (in development). However i have rigged up an Azure Function (Http Trigger) that i deployed to Azure and therefore need Ocelot to route a downstream request to the external facing url.
What I can confirm is that my Ocelot environment is running on .NET Core 5.0 and am able to succesfully call the Azure Function and return the data to my front end Web App (upstream route)
I havent had to do anything different with Ocelot for it to work. Below is the snippet from the ocelot.json file
"Routes": [
// ---------------------------------------------------
// ---------- Azure Functions HTTP Triggers ----------
// ---------------------------------------------------
// ----------- Logs -----------
{
"DownstreamPathTemplate": "/api/logproperties",
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "azurefunction-httpget-logproperties.azurewebsites.net",
"Port": 443
}
],
"UpstreamPathTemplate": "/logs/logproperties",
"UpstreamHttpMethod": [ "Get" ],
"RouteIsCaseSensitive": false,
"AuthenticationOptions": {
"AuthenticationProviderKey": "Bearer",
"AllowedScopes": []
}
}
]
The actual url path for my function is shown below (obviously with the api key removed)
https://azurefunction-httpget-logproperties.azurewebsites.net/api/logproperties?code=<MyApiKeyHere>&containerName=ohiAppSource&logPropertyName=OhiAppSource
I was having issues intitially but after removing 'https://' from the string set for the "Host" in the Json config then it went through OK.
My Ocelot environement authenticates upstream requests (Client App --> Ocelot) using Microsoft Identity Web library so calling a function with a simple API key is not a security concern for me. But regardless of how you're securing the inbound side of ocelot, I dont think that would affect the issue you encountered. My solution is not promising a fix to your particular issue but it always helps to see a working configuration.

Setup a basic WebSocket mock in AWS ApiGateway

I am trying to setup an extremely simple WebSocket mock within AWS ApiGateway. However, every attempt I've tried gives me an error:
13:36:52 (X33uOGUfIAMFq7w=) Extended Request Id: X33uOGUfIAMFq7w=
13:36:52 (X33uOGUfIAMFq7w=) Verifying Usage Plan for request: X33uOGUfIAMFq7w=. API Key: API Stage: redacted/prod
13:36:52 (X33uOGUfIAMFq7w=) API Key authorized because route '$connect' does not require API Key. Request will not contribute to throttle or quota limits
13:36:52 (X33uOGUfIAMFq7w=) Usage Plan check succeeded for API Key and API Stage redacted/prod
13:36:52 (X33uOGUfIAMFq7w=) Starting execution for request: X33uOGUfIAMFq7w=
13:36:52 (X33uOGUfIAMFq7w=) WebSocket Request Route: [$connect]
13:36:52 (X33uOGUfIAMFq7w=) Client [UserAgent: null, SourceIp: redacted] attempts to connect to WebSocket API [redacted].
13:36:52 (X33uOGUfIAMFq7w=) Execution failed due to configuration error: statusCode should be an integer which defined in request template
13:36:52 (X33uOGUfIAMFq7w=) Client [UserAgent: null, SourceIp: redacted] failed to connect to API [redacted].
As far as I can tell, I've followed the most basic configuration possible. I do not need any responses or templates, just simple a WebSocket connection that allows me to connect to it and do nothing, or perhaps respond to ping requests with a pong eventaully.
All authorizations and API keys are disabled. No request templates or integration responses are setup since I do not need them. Again, the goal is to just be able to have a dumb WebSocket that can be connected to.
However, whenever I try to connect to it, I get a 500 error with the error logs from above about a status code.
WebSocket connection to 'wss://redacted.execute-api.us-east-1.amazonaws.com/prod' failed: Error during WebSocket handshake: Unexpected response code: 500
Using the following sources (below), I was able to get a quick and loose example AWS API Gateway connection working use MOCK endpoints with web sockets. I'm sure this can be flushed out more to provide an even better understanding of different request/response body messages and codes..
First, go to API Gateway, click Create API
For Choose the protocol, select WebSocket
Give the API a name, and use the example $request.body.message for the route selection expression
Click the Create API button
Select the new API from the side pane, and click Routes
Select the $connect route
Under Route overview, select the Mock radio button for endpoint
For the Request Template, enter an expression (using 200 for example).
For Template Key, enter a key (using 200 for example)
For the popup window on passthrough behavior, select No, Use Current Settings for now
Click on the Template Key 200, and enter a template: {"statusCode" : 200} and then click the Save button.
Select Route Overview to go back to the $connect overview page and then select the Add Integration Response button
Create a response key of $default, which will reference the $default key under Routes
For the $disconnect route, please repeat steps 7 - 13 for this specific route.
Once done setting up the $disconnect route, please select the $default route under the Routes pane.
Create an Integration Request the same way that was done for $connect and $disconnect (steps 7 - 11)
For Integration Response under $default, we will be setting the route response up slightly different than $connect and $disconnect as those 2 routes' responses actually reference the $default response within their own respective Integration Responses.
Create a response key of $default
Enter a Template Selection Expression (using 200 for this example)
Then create a Template Key (using 200 for this example)
Click on the Template Key 200, and enter a template: {"statusCode" : 200, "connectionId" : "$context.connectionId"} and then click the Save button.
{"connectionId" : "$context.connectionId"} was added to the response payload to show how variables can be used within the response to represent an actual value of the connection.
Finally, under the Actions dropdown, select Deploy API, and enter a deployment stage name. This should generate a WebSocket URL that can now be connected to e.g. (wss://#######.execute-api.us-east-1.amazonaws.com/Test)
Using wscat via cli, I am now able to connect to my WebSocket URL (see source below for installing wscat): wscat -c wss://#######.execute-api.us-east-1.amazonaws.com/Test
Sources:
https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-how-to-call-websocket-api-wscat.html
https://forums.aws.amazon.com/thread.jspa?threadID=299642&tstart=0
I've automated the steps described by Woodrow using CloudFormation so now anyone can reproduce it more easily.
The template can be found here: https://gist.github.com/maatthc/9d2dfe0448733f0ee1624d658fbac80f .
To create a new stack using it you should:
Download the template to your machine.
Head to Cloudformation in the AWS Console (https://ap-southeast-2.console.aws.amazon.com/cloudformation/) - Change your AWS Region.
Click in "Create Stack"
Choose "Upload a template file" and use the template you've downloaded.
Click Next, give the stack a name and click Next again.
Click Next and "Create Stack".
I hope it helps.
Cheers

Fiddler not showing websocket protocol using ws prefix

I use fiddler to review many of the http and https communications from our application. We have a websocket implementation connected to a phoenix/elixir server using the ws prefix. So our url looks like ws://{ip}:4000/socket/websocket. None of the communications from our application to this end point are visible in Fiddler.
I can see all http and https traffic we're doing, but not the websocket calls. The websocket connections are working and the app is sending and receiving messages correctly, but I'd like to be able to see the messages to monitor this part of the application.
Any idea how to make the ws prefix visible in Fiddler?
Script Language C#
public static void OnWebSocketMessage(WebSocketMessage oMsg) {
// Log Message to the LOG tab
FiddlerObject.log(oMsg.ToString());
}
JScript.Net
static function OnWebSocketMessage(oMsg: WebSocketMessage) {
// Log Message to the LOG tab
FiddlerApplication.Log.LogString(oMsg.ToString());
}
add above code to FiddlerScript, you will see log on the fiddler log tab.
(Source)

Google location auto complete is not working on aws server

I am using google location autocomplete at aws server its not working and the same code i am using on another server its working fine you can check here AWS==> http://52.91.226.167/testgeo.php other server==>http://142.4.10.93/~vooap/alcohol/test.php geocomplete needs any server side setting ?
You should use a valid API key as mentionned in the message received when the autocomplete message is sent:
You can see this message under Network panel in developer console. Each time you hit a key in the input, an ajax request is sent and you receive this message.

Resources