RestUtilities.java

  1. /*
  2.  * GovWay - A customizable API Gateway
  3.  * https://govway.org
  4.  *
  5.  * Copyright (c) 2005-2025 Link.it srl (https://link.it).
  6.  *
  7.  * This program is free software: you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License version 3, as published by
  9.  * the Free Software Foundation.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  *
  19.  */

  20. package org.openspcoop2.message.rest;

  21. import java.net.MalformedURLException;
  22. import java.net.URL;
  23. import java.util.HashMap;
  24. import java.util.List;
  25. import java.util.Map;

  26. import org.openspcoop2.message.constants.Costanti;
  27. import org.openspcoop2.utils.transport.TransportRequestContext;
  28. import org.openspcoop2.utils.transport.TransportUtils;
  29. import org.openspcoop2.utils.transport.http.HttpServletTransportRequestContext;
  30. import org.slf4j.Logger;

  31. /**
  32.  * RestUtilities
  33.  *
  34.  * @author Poli Andrea (apoli@link.it)
  35.  * @author $Author$
  36.  * @version $Rev$, $Date$
  37.  */
  38. public class RestUtilities {

  39.     public static String getUrlWithoutInterface(TransportRequestContext requestContext, String normalizedInterfaceName) {
  40.         String resourcePath = requestContext.getFunctionParameters();
  41.         if(resourcePath!=null){
  42.             if(resourcePath.startsWith("/")){
  43.                 resourcePath = resourcePath.substring(1);
  44.             }
  45.             if(requestContext.getInterfaceName()!=null) {
  46.                 if(resourcePath.startsWith(requestContext.getInterfaceName())){
  47.                     resourcePath = resourcePath.substring(requestContext.getInterfaceName().length());
  48.                 }      
  49.                 else if(normalizedInterfaceName!=null && resourcePath.startsWith(normalizedInterfaceName)){
  50.                     resourcePath = resourcePath.substring(normalizedInterfaceName.length());
  51.                 }
  52.             }
  53.         }
  54.         return resourcePath;
  55.     }
  56.    
  57.     public static String buildUrl(Logger log, String url,Map<String, List<String>>  p,TransportRequestContext requestContext, String normalizedInterfaceName){
  58.        
  59.         String baseUrl = url;
  60.         String parameterOriginalUrl = null;
  61.         if(url.contains("?")){
  62.             baseUrl = url.split("\\?")[0];
  63.             if(baseUrl!=null){
  64.                 baseUrl = baseUrl.trim();
  65.             }
  66.             parameterOriginalUrl = url.split("\\?")[1];
  67.             if(parameterOriginalUrl!=null){
  68.                 parameterOriginalUrl = parameterOriginalUrl.trim();
  69.             }
  70.         }
  71.        
  72.         StringBuilder newUrl = new StringBuilder();
  73.         newUrl.append(baseUrl);
  74.        
  75.         if(requestContext!=null){
  76.             String resourcePath = getUrlWithoutInterface(requestContext,normalizedInterfaceName);
  77.             if(resourcePath!=null){
  78.                 boolean extraPathApplicativoStartWithSlash = false;
  79.                 if(resourcePath.startsWith("/")){
  80.                     extraPathApplicativoStartWithSlash = true;
  81.                     // Lo elimino in modo da evitare doppi '//' se anche il baseUrl finisce con '/'
  82.                     resourcePath = resourcePath.substring(1);
  83.                 }
  84.                 if(resourcePath!=null && !"".equals(resourcePath)){
  85.                     // // extra path contiene ulteriori dati da aggiungere alla url
  86.                     if(baseUrl.endsWith("/")==false){
  87.                         newUrl.append("/");
  88.                     }
  89.                     newUrl.append(resourcePath);
  90.                 }
  91.                 else {
  92.                     if(extraPathApplicativoStartWithSlash) {
  93.                         if(baseUrl.endsWith("/")==false){
  94.                             // extra path terminava semplicemente con '/'. Questo slash va ripristinato poiche' e' importante per l'index
  95.                             newUrl.append("/");
  96.                         }
  97.                     }
  98.                 }
  99.             }
  100.         }
  101.                
  102.         if(parameterOriginalUrl!=null){
  103.             String [] split = parameterOriginalUrl.split("&");
  104.             if(split!=null){
  105.                 if(p==null){
  106.                     p = new HashMap<> ();
  107.                 }
  108.                
  109.                 // elimino tutte le proprieta' che sono poi indicate nella base url
  110.                 for (int i = 0; i < split.length; i++) {
  111.                     if(split[i].contains("=")){
  112.                         int indexOf = split[i].indexOf("=");
  113.                        
  114.                         String nome = null;
  115.                         if(indexOf>0) {
  116.                             nome = split[i].substring(0, indexOf);
  117.                         }
  118.                         if(nome!=null){
  119.                             nome = nome.trim();
  120.                         }
  121.                        
  122.                         if(nome!=null){
  123.                             TransportUtils.removeRawObject(p, nome);
  124.                         }
  125.                     }
  126.                 }
  127.                
  128.                 // adesso le aggiungo
  129.                 for (int i = 0; i < split.length; i++) {
  130.                     if(split[i].contains("=")){
  131.                         int indexOf = split[i].indexOf("=");
  132.                        
  133.                         String nome = null;
  134.                         if(indexOf>0) {
  135.                             nome = split[i].substring(0, indexOf);
  136.                         }
  137.                         if(nome!=null){
  138.                             nome = nome.trim();
  139.                         }
  140.                        
  141.                         String valore = null;
  142.                         if((indexOf+1)<=((split[i].length()-1))) {
  143.                             valore = split[i].substring((indexOf+1));
  144.                         }
  145.                         if(valore!=null){
  146.                             valore = valore.trim();
  147.                         }
  148.                         else {
  149.                             valore = "";
  150.                         }
  151.                        
  152.                         if(nome!=null && valore!=null){
  153.                             TransportUtils.addParameter(p, nome, valore);
  154.                         }
  155.                        
  156.                     }
  157.                 }
  158.             }
  159.         }
  160.        
  161.         return TransportUtils.buildUrlWithParameters(p, newUrl.toString(), log);
  162.        
  163.     }
  164.    
  165.     public static String buildPassReverseUrl(TransportRequestContext transportRequestContext, String baseUrl, String redirectLocationUrlParam, String prefixGatewayUrl,
  166.             String interfaceName) throws MalformedURLException {
  167.                
  168.         String r = baseUrl;
  169.         if(r.contains("?")) {
  170.             r = baseUrl.split("\\?")[0];
  171.         }
  172.          
  173.         URL uri = new URL(r);
  174.         String rRelative= uri.getPath();
  175.        
  176.         String redirectLocationUrl = null;
  177.         String redirectLocationUrlParameters = null;
  178.         if(redirectLocationUrlParam.contains("?")) {
  179.             String [] tmp = redirectLocationUrlParam.split("\\?");
  180.             redirectLocationUrl = tmp[0];
  181.             if(tmp.length>1) {
  182.                 StringBuilder sbc = new StringBuilder();
  183.                 for (int i = 1; i < tmp.length; i++) {
  184.                     if(sbc.length()>0) {
  185.                         sbc.append("?");
  186.                     }
  187.                     sbc.append(tmp[i]);
  188.                 }
  189.                 redirectLocationUrlParameters = sbc.toString();
  190.             }
  191.         }
  192.         else {
  193.             redirectLocationUrl = redirectLocationUrlParam;
  194.         }
  195.         if(redirectLocationUrl.endsWith("/")) {
  196.             if(!r.endsWith("/")) {
  197.                 r = r + "/";
  198.             }
  199.             if(!rRelative.endsWith("/")) {
  200.                 rRelative = rRelative + "/";
  201.             }
  202.         }
  203.         else {
  204.             if(r.endsWith("/")) {
  205.                 r = r.length()<=1 ? "" : r.substring(0,r.length()-1);
  206.             }
  207.             if(rRelative.endsWith("/")) {
  208.                 rRelative = rRelative.length()<=1 ? "" : rRelative.substring(0,rRelative.length()-1);
  209.             }
  210.         }
  211.        
  212.         if(redirectLocationUrl.startsWith(r) || redirectLocationUrl.startsWith(rRelative)) {
  213.            
  214. //          if(redirectLocationUrl.startsWith(r)) {
  215. //              System.out.println("AbsoluteURL redirect["+redirectLocationUrl+"]");
  216. //          }
  217. //          else {
  218. //              System.out.println("RelativeURL redirect["+redirectLocationUrl+"]");
  219. //          }
  220.            
  221.             String contextPath = null;
  222.             if(prefixGatewayUrl==null) {
  223.                 // Context path rappresenta il prefisso della richiesta contenente il contesto dell'applicazione (es. /openspcoop2),
  224.                 // il protocollo e il servizio. Ad esempio /govway/spcoop/out
  225.                 contextPath = transportRequestContext.getWebContext();
  226.                 if(contextPath.endsWith("/")==false) {
  227.                     contextPath = contextPath + "/";
  228.                 }
  229.                 String protocollo = transportRequestContext.getProtocolWebContext();
  230.                 if(Costanti.CONTEXT_EMPTY.equals(protocollo)==false) {
  231.                     contextPath = contextPath + protocollo + "/";
  232.                 }
  233.                 contextPath = contextPath + transportRequestContext.getFunction();
  234.             }
  235.            
  236.             // Il suffisso contiene la parte della url ritornata dalla redirect senza la parte iniziale rappresentata dalla base url del servizio
  237.             String suffix = "";
  238.             if(redirectLocationUrl.startsWith(r)) {
  239.                 if(redirectLocationUrl.equals(r)==false) {
  240.                     suffix=redirectLocationUrl.substring(r.length());
  241.                 }
  242.             }
  243.             else {
  244.                 if(redirectLocationUrl.equals(rRelative)==false) {
  245.                     suffix=redirectLocationUrl.substring(rRelative.length());
  246.                 }
  247.             }
  248.            
  249.             // Viene costruita una nuova url contenente la richiesta iniziale e il nuovo suffisso,
  250.             // in modo che la url ritornata tramite la redirect possa contenere una nuova url che viene veicolata nuovamente sulla PdD
  251.             StringBuilder bf = new StringBuilder();
  252.             if(redirectLocationUrl.startsWith(r)) {
  253.                 // absolute
  254.                 if(prefixGatewayUrl!=null) {
  255.                     prefixGatewayUrl = prefixGatewayUrl.trim();
  256.                     bf.append(prefixGatewayUrl);
  257.                     if(prefixGatewayUrl.endsWith("/")==false) {
  258.                         bf.append("/");
  259.                     }
  260.                 }
  261.                 else {
  262.                     bf.append(contextPath);
  263.                     if(contextPath.endsWith("/")==false) {
  264.                         bf.append("/");
  265.                     }
  266.                 }
  267.             }
  268.             else {
  269.                 // relative
  270.                 if(prefixGatewayUrl!=null) {
  271.                     URL urlPrefixGatewayUrl = new URL(prefixGatewayUrl);
  272.                     String urlPrefixGatewayUrlAsString = urlPrefixGatewayUrl.getPath();
  273.                     bf.append(urlPrefixGatewayUrlAsString);
  274.                     if(urlPrefixGatewayUrlAsString.endsWith("/")==false) {
  275.                         bf.append("/");
  276.                     }
  277.                 }
  278.                 else {
  279.                     bf.append(contextPath);
  280.                     if(contextPath.endsWith("/")==false) {
  281.                         bf.append("/");
  282.                     }
  283.                 }
  284.             }
  285.             String interfaceNameTmp = null;
  286.             if(interfaceName!=null) {
  287.                 interfaceNameTmp = interfaceName;
  288.             }
  289.             else {
  290.                 interfaceNameTmp = transportRequestContext.getInterfaceName();
  291.             }
  292.             if(interfaceNameTmp!=null) {
  293.                 if(interfaceNameTmp.startsWith("/")) {
  294.                     if(interfaceNameTmp.length()>1) {
  295.                         bf.append(interfaceNameTmp.substring(1));
  296.                     }
  297.                 }
  298.                 else {
  299.                     bf.append(interfaceNameTmp);
  300.                 }
  301.             }
  302.            
  303.            
  304.             if(suffix.equals("")) {
  305.                 if(redirectLocationUrl.endsWith("/")) {
  306.                     if(!bf.toString().endsWith("/")) {
  307.                         bf.append("/");
  308.                     }
  309.                 }
  310.             }
  311.             else {
  312.                 if(suffix.startsWith("/")==false) {
  313.                     bf.append("/");
  314.                 }
  315.                 bf.append(suffix);
  316.             }
  317.            
  318. //          if(redirectLocationUrl.startsWith(r)) {
  319. //              System.out.println("AbsoluteURL new["+bf.toString()+"]");
  320. //          }
  321. //          else {
  322. //              System.out.println("RelativeURL new["+bf.toString()+"]");
  323. //          }      
  324.            
  325.             String url = bf.toString();
  326.             if(redirectLocationUrlParameters!=null && !"".equals(redirectLocationUrlParameters)) {
  327.                 if(url.contains("?")) {
  328.                     url = url + "&";
  329.                 }
  330.                 else {
  331.                     url = url + "?";
  332.                 }
  333.                 url = url + redirectLocationUrlParameters;
  334.             }
  335.            
  336.             return url;
  337.            
  338.         }
  339.         else {
  340.            
  341. //          System.out.println("ProxyPass nop redirect["+redirectLocationUrl+"] relative["+rRelative+"] absolute["+r+"]");
  342.            
  343.             return redirectLocationUrlParam;
  344.         }
  345.     }

  346.     public static String buildCookiePassReversePath(TransportRequestContext transportRequestContext, String baseUrl, String cookiePathParam, String prefixGatewayUrl,
  347.             String interfaceName) throws MalformedURLException {
  348.        
  349.         String r = baseUrl;
  350.         if(r.contains("?")) {
  351.             r = baseUrl.split("\\?")[0];
  352.         }
  353.          
  354.         URL uri = new URL(r);
  355.         String rRelative= uri.getPath();
  356.        
  357.         String cookiePath = null;
  358.         String cookieParameters = null;
  359.         if(cookiePathParam.contains("?")) {
  360.             String [] tmp = cookiePathParam.split("\\?");
  361.             cookiePath = tmp[0];
  362.             if(tmp.length>1) {
  363.                 StringBuilder sbc = new StringBuilder();
  364.                 for (int i = 1; i < tmp.length; i++) {
  365.                     if(sbc.length()>0) {
  366.                         sbc.append("?");
  367.                     }
  368.                     sbc.append(tmp[i]);
  369.                 }
  370.                 cookieParameters = sbc.toString();
  371.             }
  372.         }
  373.         else {
  374.             cookiePath = cookiePathParam;
  375.         }
  376.         if(cookiePath.endsWith("/")) {
  377.             if(!rRelative.endsWith("/")) {
  378.                 rRelative = rRelative + "/";
  379.             }
  380.         }
  381.         else {
  382.             if(rRelative.endsWith("/")) {
  383.                 rRelative = rRelative.length()<=1 ? "" : rRelative.substring(0,rRelative.length()-1);
  384.             }
  385.         }
  386.        
  387.         if(cookiePath.startsWith(rRelative)) {
  388.            
  389.             //System.out.println("Cookie - RelativeURL redirect["+cookiePath+"]");
  390.            
  391.             String contextPath = null;
  392.             if(prefixGatewayUrl==null) {
  393.                 // Context path rappresenta il prefisso della richiesta contenente il contesto dell'applicazione (es. /openspcoop2),
  394.                 // il protocollo e il servizio. Ad esempio /govway/spcoop/out
  395.                 contextPath = transportRequestContext.getWebContext();
  396.                 if(contextPath.endsWith("/")==false) {
  397.                     contextPath = contextPath + "/";
  398.                 }
  399.                 String protocollo = transportRequestContext.getProtocolWebContext();
  400.                 if(Costanti.CONTEXT_EMPTY.equals(protocollo)==false) {
  401.                     contextPath = contextPath + protocollo + "/";
  402.                 }
  403.                 contextPath = contextPath + transportRequestContext.getFunction();
  404.             }
  405.            
  406.             // Il suffisso contiene la parte della url ritornata dalla redirect senza la parte iniziale rappresentata dalla base url del servizio
  407.             String suffix = "";
  408.             if(cookiePath.equals(rRelative)==false) {
  409.                 suffix=cookiePath.substring(rRelative.length());
  410.             }
  411.            
  412.             // Viene costruita una nuova url contenente la richiesta iniziale e il nuovo suffisso,
  413.             // in modo che la url ritornata tramite la redirect possa contenere una nuova url che viene veicolata nuovamente sulla PdD
  414.             StringBuilder bf = new StringBuilder();
  415.             // relative
  416.             if(prefixGatewayUrl!=null) {
  417.                 URL urlPrefixGatewayUrl = new URL(prefixGatewayUrl);
  418.                 String urlPrefixGatewayUrlAsString = urlPrefixGatewayUrl.getPath();
  419.                 bf.append(urlPrefixGatewayUrlAsString);
  420.                 if(urlPrefixGatewayUrlAsString.endsWith("/")==false) {
  421.                     bf.append("/");
  422.                 }
  423.             }
  424.             else {
  425.                 bf.append(contextPath);
  426.                 if(contextPath.endsWith("/")==false) {
  427.                     bf.append("/");
  428.                 }
  429.             }

  430.             String interfaceNameTmp = null;
  431.             if(interfaceName!=null) {
  432.                 interfaceNameTmp = interfaceName;
  433.             }
  434.             else {
  435.                 interfaceNameTmp = transportRequestContext.getInterfaceName();
  436.             }
  437.             if(interfaceNameTmp!=null) {
  438.                 if(interfaceNameTmp.startsWith("/")) {
  439.                     if(interfaceNameTmp.length()>1) {
  440.                         bf.append(interfaceNameTmp.substring(1));
  441.                     }
  442.                 }
  443.                 else {
  444.                     bf.append(interfaceNameTmp);
  445.                 }
  446.             }
  447.            
  448.             if(suffix.equals("")) {
  449.                 if(cookiePath.endsWith("/")) {
  450.                     if(!bf.toString().endsWith("/")) {
  451.                         bf.append("/");
  452.                     }
  453.                 }
  454.             }
  455.             else {
  456.                 if(suffix.startsWith("/")==false) {
  457.                     bf.append("/");
  458.                 }
  459.                 bf.append(suffix);
  460.             }
  461.            
  462.             //System.out.println("Cookie relativeURL new["+bf.toString()+"]");
  463.                
  464.             String url = bf.toString();
  465.             if(cookieParameters!=null && !"".equals(cookieParameters)) {
  466.                 if(url.contains("?")) {
  467.                     url = url + "&";
  468.                 }
  469.                 else {
  470.                     url = url + "?";
  471.                 }
  472.                 url = url + cookieParameters;
  473.             }
  474.            
  475.             return url;
  476.            
  477.         }
  478.         else {
  479.            
  480. //          System.out.println("ProxyPass nop cookiePath["+cookiePath+"] relative["+rRelative+"] absolute["+r+"]");
  481.            
  482.             return cookiePath;
  483.         }
  484.     }
  485.    
  486.     public static String buildCookiePassReverseDomain(TransportRequestContext transportRequestContext, String baseUrl, String cookieDomain, String prefixGatewayUrl) throws MalformedURLException {
  487.                
  488.         String r = baseUrl;
  489.         if(r.contains("?")) {
  490.             r = baseUrl.split("\\?")[0];
  491.         }
  492.          
  493.         URL uri = new URL(r);
  494.         String rDomain= uri.getHost();
  495.        
  496.         if(cookieDomain!=null && cookieDomain.equalsIgnoreCase(rDomain)) {
  497.            
  498.             //System.out.println("CookieDomain cookieDomain["+cookieDomain+"]");
  499.            
  500.             String newDomain = null;
  501.             if(prefixGatewayUrl==null) {
  502.                 if(transportRequestContext!=null && transportRequestContext instanceof HttpServletTransportRequestContext) {
  503.                     HttpServletTransportRequestContext http = (HttpServletTransportRequestContext) transportRequestContext;
  504.                     if(http.getHttpServletRequest()!=null) {
  505.                         String requestUrl = http.getHttpServletRequest().getRequestURL().toString();
  506.                         URL uriRequestUrl = new URL(requestUrl);
  507.                         newDomain = uriRequestUrl.getHost();
  508.                     }
  509.                 }
  510.             }
  511.             else {
  512.                 URL uriRequestUrl = new URL(prefixGatewayUrl);
  513.                 newDomain = uriRequestUrl.getHost();
  514.             }

  515.             if(newDomain!=null) {
  516.                
  517.                 //System.out.println("ProxyPass cookieDomain["+cookieDomain+"] newCookieDomain["+newDomain+"]");
  518.                
  519.                 return newDomain;
  520.             }
  521.             else {
  522.                
  523. //              System.out.println("ProxyPass nop cookieDomain["+cookieDomain+"]");
  524.            
  525.                 return cookieDomain;
  526.             }
  527.            
  528.         }
  529.         else {
  530.            
  531. //          System.out.println("ProxyPass nop cookieDomain["+cookieDomain+"]");
  532.            
  533.             return cookieDomain;
  534.         }
  535.     }
  536. }