Web Core/XData iOS errors

Hi,

I have a Web Core app which connects to an XData server running on a Windows 2019 server. On a PC it runs absolutely fine in any browser but when using iOS on a mobile it shows my login page but fails on the first call to

http://localhost:2001/tms/xdata

with a "Network Error".

It's like a CORS error but why would iOS/Safari be different?

All strings have been percent encoded. .I haven't yet worked out how to display the console.log in Safari.

Can anyone throw any light on why this is happening?

Thanks,

Ken

Shouldn't that address be updated to point to the address of your XData server? I don't imagine it is running locally on your iOS device.

When developing XData projects, that's the address we can use when connecting with a TMS WEB Core app running on the same system as the XData server, but if we run the TMS WEB Core project anywhere other than that system, mobile or otherwise, it needs to have the address of the XData server set explicitly.

Thanks Andrew. I wasn't sure about that but couldn't find anything in the documentation. Can you explain why it works on a pc when the xdata server is not running locally?

Sorry, my bad. It doesn't run.

Ah. Now I'm getting CORS errors even in Firefox. I thought I had that sorted. Do the URL reservations also have to be changed?

URL reservations have to be made on the server that is running XData, reserving the port that XData is using. That system also has to have the port open in any firewall you might be using, like Windows Firewall which I think is running by default.

As far as CORS is concerned, if you're running into it while connecting to XData, that's a bit curious, but there is a CORS middleware that can be installed in XData that should hopefully prevent any issues. Right-click the XDataServer component in Unit1 (if using the default XData project) and then select the middleware option. Add cors from the list, and then when it is selected, set the "origin" property in the Object Inspector to an asterisk. Should take care of things initially, and you can adjust it later if you want to use something more specific.

Before testing with an actual TMS WEB Core app (or a mobile app) it would be best to test that you can access the XData server just using a browser. It's not much to look at, but it will confirm that it is working. Just copy the URL into a browser and you should get a response like value:{} or something like that. If you get an error, then best to get that sorted before moving on to the actual app connections.

Note that the browser connection can work and you can still have a CORS issue accessing it using a TMS WEB Core app. But if the browser doesn't work you're almost definitely not going to be able to connect with the TMS WEB Core app and it likely has nothing to do with CORS.

Thanks. I can access and use swagger on the server from my PC using http but not https. have configered the address in the web app to be https. Is that my problem?

Certainly can be. Note that URL reservations are protocol-specific, so you might want to pick one and just use that for all connections to that server.

For example, on the development system, XData might be configured to use port 2001 and HTTP. On a test or production server, XData might instead be configured to use port 6001 and HTTPS.

This can be a nuisance to keep track of, particularly when you might want a TMS WEB Core app to connect at different times to either one, when running that app either on the development system or elsewhere. One way around this is to add some kind of configuration file, or a parameter of some kind, both to XData and your app. Initially, though, it is just a matter of ensuring that they are set properly for the particular combination that you're trying to test.

In the case of XData, the parameter would be set when it starts - telling it what port to run on. On the development system it might be set to use the default baseURL value:

ServerContainer.XDataServer.BaseURL := 'http://+:2001/tms/xdata'

When the XData project is deployed on another system with the HTTPS URL reserved for port 6001, you'd start XData with a different baseURL value:

ServerContainer.XDataServer.BaseURL := 'https://+:6001/tms/xdata'

For the client app (or your browser testing) you'd then use one or the other to connect to the server you're interested in. Either one of these:

https://devserver.com:2001/tms/xdata
https://prodserver.com:6001/tms/xdata

You can check out the last part of this blog post for how to set up a configuration.json file for the client app:

This other post covers a lot of the work involved in setting up XData from the beginning, including the CORS bit. It also uses a configuration.json file, but this was added after the blog post was written. You can see how it was handled by looking at the code on GitHub, for which there is a link at the bottom of the post.

Thanks. When I now run the xdata server I get

image

I actually tried to add it myself in HTTPConfig but it also said that it already existed but it certainly is not listed.

Port numbers can't be reserved for both HTTP and HTTPS at the same time. Look for 2001 in the HTTP Config Tool and see which has been reserved. HTTP/2001 was probably already reserved, so if you're going to use HTTP, use 2001. If you want to use HTTPS, pick a different port number and reserve/use that.

I seem to be goinf round in circles. Having changed it to port 2002 I now can't connect to swagger at all!

Just be sure to change everything at the same time.

  1. Reserve a URL in the HTTP Config Tool, eg:
    http://+:2002/tms/xdata
    https://+:2003/tms/xdata
  2. Set this as the baseURL value in XData, and restart the XData server it was already running.
  3. Make sure Windows Firewall is off or has otherwise been configured to allow access via Port 2002 or Port 2003 or whatever port numbers you're using
  4. Test with browser
  5. Test with app.

image

Firewall and antivirus disabled.

I cannot connect to swagger even on the server itself.

Let's start with HTTP.

Things to check:

  1. The HTTP Config Tool is running on the same system that the XData app is running.
  2. That the BaseURL for the XData app is set to, say, http://+:2003/tms/xdata
  3. From browser on the same system, try http://localhost:2003/tms/xdata
  4. From browser on another system, try http://<ipaddress>:2003/tms/xdata

You should be able to connect and get the {value:[] } response from XData. If swagger has been setup, it should work as well.

For HTTPS, things can be considerably more complicated, even though the setup is largely the same. Before we get to that, confirm that you have an IP name pointing at the same IP Address of the XData server. So you should be able to use http://<ipname>:2001/tms/xdata and get the same result.

Sometimes HTTPS can be a problem if the server is in your own local network. This is because of how HTTPS authenticates SSL credentials. Having the XData server hosted somewhere else makes this much less of a problem, in which case the steps are largely the same.

Things to check:

  1. The HTTP Config Tool is running on the same system that the XData app is running.
  2. That the BaseURL for the XData app is set to, say, https://+:2002/tms/xdata
  3. From browser on the same system, try https://<ipname>:2002/tms/xdata
  4. From browser on another system, try https://<ipaddress>:2002/tms/xdata

You can also try https://localhost:2002/tms/xdata on the same system, but you will likely get all kinds of warnings about how localhost isn't properly configured in the SSL certificate. Depending on the browser, you may be blocked entirely or allowed only after clicking through a few prompts.

If your server is inside your own network, you may be further blocked due to the SSL certificate not being able to be authenticated. For example, it is common to use NAT in a local router to move external traffic to a particular system inside your network. When you use HTTPS, it goes out and tries to confirm that the URL is correct and mapped to a valid IP - the external IP of your router, typically. And most routers don't allow you to go out of your network and back in through NAT to a local system, so this is a problem. Big enough that we don't really want to deal with i. So we use HTTP locally in development and HTTPS when it is deployed externally.

  1. True.
  2. True.
  3. Get error unable to connect.

This is the HTTP attempt?

Can you confirm (2) by seeing that it is the same as what XData reports in its interface? And that XData is not only started as an app, but that it is running the service? Depending on where BaseURL is set, the server may already be running on a default port. If you changed it in the Obejct Inspector, this is less likely to be an issue.

You should be able to connect using a browser on the same system that XData is running on using localhost.

I'm going to reboot the server and then come back to you.

Reboot made no difference. I hate Windows Server 2019. Not sure what you mean by "Can you confirm (2) by seeing that it is the same as what XData reports in its interface?"

This is the xdata server's StartServer procedure:

procedure StartServer;
var
  Module : TXDataServerModule;
begin
  if Assigned(SparkleServer) then
     Exit;

  DefaultTimeZoneMode := TTimeZoneMode.AsLocal;

  SparkleServer := THttpSysServer.Create;
{$IFDEF DEBUG}
  Module := TXDataServerModule.Create(
    'http://+:2001/tms/xdata',
    TNexusDBNexusDBConnection.CreatePool(20)
  );
{$ELSE}
  Module := TXDataServerModule.Create(
    'https://+:2002/tms/xdata',
    TNexusDBNexusDBConnection.CreatePool(20)
  );
{$ENDIF}
  // Uncomment line below to enable CORS in the server
  Module.AddMiddleware(TCorsMiddleware.Create);
  // Uncomment line below to allow compressed responses from server
  //Module.AddMiddleware(TCompressMiddleware.Create);

  Module.SwaggerUIOptions.ShowFilter:=True;
  Module.SwaggerUIOptions.TryItOutEnabled:=True;

  SparkleServer.AddModule(Module);

  SparkleServer.Start;
end;

I should add that there must be some communication with the xdata server as if I try localhost:2001 in the browser I get a 404 not found error whereas if I try 2003 I get unable to connect.

I was referring to the start message shown in the default XData application... It shows that (1) the XData server is running (not just the application, but the server inside the application) as well as the URL that it is serving up.

If there's an error of some kind, maybe the server inside the application isn't running. Or, given your example, if the conditionals regarding debug mode aren't set to what you're expecting, maybe a different URL has been configured for the server.