Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member

In a recent project our team was building a data visualization tool using a world map. The front-end was created using SAPUI5 and the backed runs on HANA using XSJS Services to deliver the data to the front-end.


To display a map on which we can visualize our data, the application needs to fetch map tiles from a separate server on the same network as our HANA machine. However, the HANA XS Server can only be accessed using HTTPS, while the map server only supportes HTTP. Using both in conjunction on one web application leads to a Mixed-Content error in the web browser blocks its execution. In order to circumvent this Mixed-Content error, we require some kind of proxy to map the tile server's HTTP resource to HTTPS. Since I did not have access to the server infrastructure, I was limited to using HANA native technolgy to solve this issue.


For this, I implemented a simple proxy using XS HTTP destinations. This approach is flexible and very easy to implement. I hope it will help some of you in case you have similar troubles or if you simply want to reroute a remote resource to your HANA server.


 


The proxy consists of 3 HANA development artifacts:




  1. A server.xshttpdest file to define the details of the server we would like to access

  2. A .xsaccess file for URL rewriting

  3. A proxy.xsjs script for the program logic


 



1. The HTTP Destination


To access the HTTP resource we would like to route through our proxy, we first create an HTTP destination in our HANA repository (more information on HTTP Destination Files can be found here [1]). For my purposes the following definition was sufficient for the server.xshttpdest file:
description = "Map Tile Server";
host = "<URL of the server>";
port = 80;
useProxy = false;
useSSL = false;
authType = none;
timeout = -1;

2. The .xsaccess file


The application access file is used to define the web-access to a repository [2]. In our case, we also use it to rewrite the URL so that it matches the URL structure used by the server we would like to access. In my case, the map server offers a service URL called "renderMap". Since I was using a javascript library to access the map tiles and this service URL was hardcoded within said librabry, I mapped "renderMap" to my proxy.xsjs. This means that I did not have to change the library and that my solution was generic with regards to the map server we were using.
{
     "exposed" : true,
     "authentication" : {
        "method": "Basic"
     },
     "rewrite_rules": [{
         "source": "renderMap",
         "target": "proxy.xsjs"
     }],
     "cache-control": "no-cache no-store"
}



3. Program logic


Lastly we need to implement some program logic to map the request to the proxy request to the HTTP Destination, to fetch the response and to return the response. For this, we create a proxy.xsjs file with the following content:
function proxy() {
    var destPackage = "path.to.your.destination";
    var destName = "server";
   
    // setup the HTTP connection
    var dest = $.net.http.readDestination(destPackage, destName);
    var client = new $.net.http.Client();
    // send a POST request to the resource on the server we want to reroute
    var req = new $.web.WebRequest($.net.http.POST, "/path/to/resource");
 
    // set the content of the original request as request body
    req.setBody($.request.body.asString());
 
    // send the request and fetch the response
    client.request(req, dest);
    var response = client.getResponse();
    $.response.status = $.net.http.OK;
    // return the response
    $.response.contentType = "application/json";
    $.response.setBody(response.body.asString());
}
try {
     proxy();
} catch (e) {
    // return the error as JSON for debugging


     var errorResponse = {"error": e.toString()};
     $.response.status = $.net.http.INTERNAL_SERVER_ERROR;
     $.response.contentType = "application/json";
     $.response.setBody(JSON.stringify(errorResponse));

}

The actual code is quite simple and easy to adjust to your requirements for the request and response structure. You can find more information on the available functions for the HTTP request using XSJS in the XS JavaScript API Reference [3].

I hope this short tutorial was helpful for you.

[1] Maintaining HTTP Destinations - SAP HANA Developer Guide for SAP HANA Web-Based Development Workbenc...

[2] The Application-Access File - SAP HANA Developer Guide for SAP HANA Web-Based Development Workbench ...

[3] SAP HANA XS JavaScript API Reference