Swagger API service problem when using HTTPS URL - XData SwaggerUI - XDataServerModule

Hello,

unit XData.SwaggerUI.Service.Internal
variable url in code below, is set to http:// although the URL used is http secure https://

code:
window.onload = function() {
var url = "http://../openapi/swagger.json"
var swaggerOptions = {
url: url,
displayOperationId: true,
docExpansion: "list",

Is returning the following browser ERROR Message when trying to call (https://........./swaggerui)

Failed to load API definition.

Fetch errorFailed to fetch http://../openapi/swagger.json
Fetch errorPossible mixed-content issue? The page was loaded over https:// but a http:// URL was specified. Check that you are not attempting to load mixed content.

Costas Economopoulos
Lysp Ltd

Is your XData server behind a reverse proxy? Because otherwise it should use the same scheme (http/https) as defined in your BaseUrl. If your BaseUrl is http, how is your server being reached via https?

Thank you for the fast response.

The server is running on an Azure VM with Ubuntu 20.04 and Apache 2.4 installed.

The TXDataServerModule is created with https:// and all references are https://.

The https://../openapi/swagger.json is loading and exploring properly in https://petstore.swagger.io .

Are you able to debug your server? In XData.SwaggerUI.Service.Internal you can see this code:

  SwaggerUrl := TXDataOperationContext.Current.Handler.AbsoluteUrl('openapi/swagger.json') + Query;
  JS := SwaggerUICode;
  JS := StringReplace(JS, '%URL%', SwaggerUrl, []);

You can see that the SwaggerUrl is provided via a construction using AbsoluteUrl method.
And AbsoluteUrl is this:

function TXDataRequestHandler.AbsoluteUrl(const RelativeUrl: string): string;
var
  Scheme: string;
  Authority: string;
  Path: string;
begin
  Scheme := Request.Uri.Scheme;
  Authority := Request.Uri.Authority; // Module.BaseUri.Authority,
  Path := Module.BaseUri.OriginalPath;

  Result := TXDataUtils.CombineUrlFast(
    Format('%s://%s%s', [Scheme, Authority, Path]),
    RelativeUrl
  );

  XModule.DoGetAbsoluteUrl(Scheme, Authority, Path, RelativeUrl, Result);
end;

Unless you have the OnGetAbsoluteUrl event set, you can see that it gets the scheme directly from the request (not from BaseUrl). Thus if your server is somehow being accessed via HTTP (not HTTPS) then it would built the URL to swagger.json file using HTTP. It's hard to tell what's going on from our side, it should be working fine, it would be good if you could do deeper investigation base on the information I just provided.

Hello,

Thank you for the resposnse.
As I see it (refering to my first post window.onload script), the scheme as defined by the REQUEST is not parsed properly for the secure HTTP part and the built URL part always contains HTTP (not HTTPS) .

Thank you again for your time.

As I explained, that is not correct. It will parse the request url and extract properly if it used HTTP or HTTPS.

Hello,

I realize this and I do not intend to go any further. My second post describes my situation and the steps I took to verify that there is no problem when using https . If I was to stop using the secure uri, I would have no chance working with https://petstore.swagger.io explorer, since it does not accept the non secure uri.

Thank you for your time, I will use the direct link to swagger.io in order to continue with my project.

Hello,

I enclose an image of the response I get using the Delphi 10.4.2 Rest Debugger tool. Marked in yellow is the issue as I have stated in my first post (the HTTPS request is not parsed properly as shown in the response body).

Thank you.

Which XData version are you using?
Which Sparkle dispatcher are you using?

XData 5.3
Sparkle 3.18

Which Sparkle dispatcher are you using? Indy? HttpSys? Apache?
Are you able to debug the key points of the code I mentioned earlier?

Apache.
Yes
The HTTPS referrer URL is never parsed when /openapi/swagger.json replaces the /swagerui

Since you are using Apache, that's expected behavior. Sparkle can't tell from an Apache module if you are using http or https. In this cause you should use the OnGetAbsoluteUrl and manually provide the correct scheme there (http or https).

The secure URL is already defined in TXDataServerModule's constructor Create(const ABaseUrl: string; AConnection: IDBConnection) how do you suggest (example) I use TXDataServerModule's OnGetAbsoluteUrl property to overcome this limitation?

Here is an example:

procedure TForm7.XDataServer1ModuleCreate(Sender: TObject; Module: TXDataServerModule);
begin
  Module.OnGetAbsoluteUrl :=
    procedure(const Schema, Authority, Path, RelativeUrl: string; var Url: string)
    begin
      Url := StringReplace(Url, 'http://', 'https://', []);
    end;
end;

Thank you!

1 Like

This topic was automatically closed 60 minutes after the last reply. New replies are no longer allowed.