ExternalResourceUtils.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.utils.transport.http;

  21. import java.io.File;
  22. import java.util.ArrayList;
  23. import java.util.HashMap;
  24. import java.util.List;
  25. import java.util.Map;

  26. import javax.naming.directory.Attribute;
  27. import javax.naming.directory.Attributes;

  28. import org.apache.commons.lang.StringUtils;
  29. import org.openspcoop2.utils.Utilities;
  30. import org.openspcoop2.utils.UtilsException;
  31. import org.openspcoop2.utils.io.Base64Utilities;
  32. import org.openspcoop2.utils.resources.FileSystemUtilities;
  33. import org.openspcoop2.utils.transport.TransportUtils;
  34. import org.openspcoop2.utils.transport.ldap.LdapClientFactory;
  35. import org.openspcoop2.utils.transport.ldap.LdapClientInterface;
  36. import org.openspcoop2.utils.transport.ldap.LdapEngineType;
  37. import org.openspcoop2.utils.transport.ldap.LdapQuery;
  38. import org.openspcoop2.utils.transport.ldap.LdapUtility;

  39. /**
  40.  * ExternalResourceUtils
  41.  *
  42.  * @author Andrea Poli (apoli@link.it)
  43.  * @author $Author$
  44.  * @version $Rev$, $Date$
  45.  */
  46. public class ExternalResourceUtils {
  47.    
  48.     private ExternalResourceUtils() {}

  49.     public static byte[] readResource(String resource, ExternalResourceConfig externalConfig) throws UtilsException {
  50.         return readResourceReturnHttpResponse(resource, externalConfig).getContent();
  51.     }
  52.     public static HttpResponse readResourceReturnHttpResponse(String resource, ExternalResourceConfig externalConfig) throws UtilsException {
  53.        
  54.         HttpResponse res = null;
  55.         try {
  56.             if(!TransportUtils.isRemoteResource(resource.trim())) {
  57.                 try {
  58.                     File f = new File(resource);
  59.                     if(f.exists()) {
  60.                         byte[] content = FileSystemUtilities.readBytesFromFile(f);
  61.                         HttpResponse response = new HttpResponse();
  62.                         response.setResultHTTPOperation(200);
  63.                         response.setContent(content);
  64.                         return response;
  65.                     }
  66.                 }catch(Exception t) {
  67.                     // ignore
  68.                 }
  69.                 throw new UtilsException("Unsupported protocol");
  70.             }
  71.            
  72.             if(TransportUtils.isLdapResource(resource)) {
  73.                 return readLdapResource(resource, externalConfig);
  74.             }
  75.            
  76.             HttpRequest req = new HttpRequest();
  77.             req.setMethod(HttpRequestMethod.GET);
  78.            
  79.             if(externalConfig.getHeaders()!=null && !externalConfig.getHeaders().isEmpty()) {
  80.                 for (Map.Entry<String,String> entry : externalConfig.getHeaders().entrySet()) {
  81.                     if(entry.getKey()!=null && entry.getValue()!=null) {
  82.                         req.addHeader(entry.getKey(),entry.getValue());
  83.                     }
  84.                 }
  85.             }
  86.            
  87.             resource = resource.trim();
  88.            
  89.             if(externalConfig.getQueryParameters()!=null && !externalConfig.getQueryParameters().isEmpty()) {
  90.                 resource = TransportUtils.buildUrlWithParameters(TransportUtils.convertToMapListValues(externalConfig.getQueryParameters()), resource);
  91.             }
  92.            
  93.             if(externalConfig.getForwardProxyUrl()!=null && StringUtils.isNotEmpty(externalConfig.getForwardProxyUrl())) {
  94.                 String forwardProxyUrl = externalConfig.getForwardProxyUrl();
  95.                 String remoteLocation = externalConfig.isForwardProxyBase64() ? Base64Utilities.encodeAsString(resource.getBytes()) : resource;
  96.                 if(externalConfig.getForwardProxyHeader()!=null && StringUtils.isNotEmpty(externalConfig.getForwardProxyHeader())) {
  97.                     req.addHeader(externalConfig.getForwardProxyHeader(), remoteLocation);
  98.                 }
  99.                 else if(externalConfig.getForwardProxyQueryParameter()!=null && StringUtils.isNotEmpty(externalConfig.getForwardProxyQueryParameter())) {
  100.                     Map<String, List<String>> queryParameters = new HashMap<>();
  101.                     TransportUtils.addParameter(queryParameters,externalConfig.getForwardProxyQueryParameter(), remoteLocation);
  102.                     forwardProxyUrl = TransportUtils.buildUrlWithParameters(queryParameters, forwardProxyUrl, false, null);
  103.                 }
  104.                 else {
  105.                     throw new UtilsException("Forward Proxy configuration error: header and query parameter not found");
  106.                 }
  107.                 req.setUrl(forwardProxyUrl);
  108.             }
  109.             else {
  110.                 req.setUrl(resource);
  111.             }
  112.            
  113.             if(req.getUrl().startsWith("https")) {
  114.                 req.setHostnameVerifier(externalConfig.isHostnameVerifier());
  115.                 req.setTrustAllCerts(externalConfig.isTrustAllCerts());
  116.                 if(externalConfig.getTrustStore()!=null) {
  117.                     req.setTrustStore(externalConfig.getTrustStore());
  118.                 }
  119.                 if(externalConfig.getKeyStore()!=null) {
  120.                     req.setKeyStore(externalConfig.getKeyStore());
  121.                     req.setKeyAlias(externalConfig.getKeyAlias());
  122.                     req.setKeyPassword(externalConfig.getKeyPassword());
  123.                 }
  124.             }
  125.             req.setConnectTimeout(externalConfig.getConnectTimeout());
  126.             req.setReadTimeout(externalConfig.getReadTimeout());
  127.            
  128.             req.setUsername(externalConfig.getBasicUsername());
  129.             req.setPassword(externalConfig.getBasicPassword());
  130.            
  131.             res = HttpUtilities.httpInvoke(req);

  132.         }catch(Exception t) {
  133.             throw new UtilsException("Retrieve external resource '"+resource+"' failed: "+t.getMessage(),t);
  134.         }

  135.         validateResponse(res, resource, externalConfig);
  136.        
  137.         return res;
  138.     }
  139.    
  140.     private static HttpResponse readLdapResource(String resource, ExternalResourceConfig externalConfig) throws UtilsException {
  141.        
  142.         try {
  143.        
  144.             LdapClientInterface clientLdap = LdapClientFactory.getClient(LdapEngineType.SPRING_FRAMEWORK);
  145.             clientLdap.uri(LdapUtility.getBaseUrlFromURI(resource));
  146.             if(externalConfig.getBasicUsername()!=null && externalConfig.getBasicPassword()!=null) {
  147.                 clientLdap.username(externalConfig.getBasicUsername());
  148.                 clientLdap.password(externalConfig.getBasicPassword());
  149.             }
  150.             LdapQuery parsedQuery = LdapUtility.getQueryFromURI(resource);
  151.             if(parsedQuery==null) {
  152.                 throw new UtilsException("parse failed");
  153.             }
  154.             String parsedAttribute = null;
  155.             if(parsedQuery.getAttributes()!=null && !parsedQuery.getAttributes().isEmpty()) {
  156.                 parsedAttribute = parsedQuery.getAttributes().get(0);
  157.             }
  158.             if(parsedAttribute==null) {
  159.                 throw new UtilsException("parse attribute failed");
  160.             }
  161.             List<Attributes> list = clientLdap.search(parsedQuery);
  162.             if(list == null || list.isEmpty()) {
  163.                 throw new UtilsException("results not found");
  164.             }
  165.             if(list.size()>1) {
  166.                 throw new UtilsException("more than one result found ("+list.size()+")");
  167.             }
  168.             Attributes attrs = list.get(0);
  169.             if(attrs==null || attrs.size()<=0) {
  170.                 throw new UtilsException("attributes empty");
  171.             }
  172.             Attribute a = attrs.get(parsedAttribute);
  173.             if(a==null) {
  174.                 throw new UtilsException("attribute '"+parsedAttribute+"' not found");
  175.             }
  176.             Object o = a.get();
  177.             if(o==null) {
  178.                 throw new UtilsException("attribute '"+parsedAttribute+"' null");
  179.             }
  180.             byte [] content = null;
  181.             if(o instanceof byte[]) {
  182.                 content = (byte[]) o;
  183.             }
  184.             else if(o instanceof String) {
  185.                 content = ((String) o).getBytes();
  186.             }
  187.             else {
  188.                 throw new UtilsException("attribute '"+parsedAttribute+"' with unknown type: "+o.getClass().getName());
  189.             }
  190.            
  191.             HttpResponse response = new HttpResponse();
  192.             response.setResultHTTPOperation(200);
  193.             response.setContent(content);
  194.             return response;
  195.        
  196.         }catch(Exception t) {
  197.             throw new UtilsException("Retrieve external resource '"+resource+"' failed: "+t.getMessage(),t);
  198.         }
  199.            
  200.     }
  201.    
  202.     private static void validateResponse(HttpResponse res, String resource, ExternalResourceConfig externalConfig) throws UtilsException {
  203.         try {
  204.             List<Integer> returnCodeValid = externalConfig.getReturnCode();
  205.             if(returnCodeValid==null) {
  206.                 returnCodeValid = new ArrayList<>();
  207.             }
  208.             if(returnCodeValid.isEmpty()) {
  209.                 returnCodeValid.add(200);
  210.             }
  211.             boolean isValid = false;
  212.             for (Integer rt : returnCodeValid) {
  213.                 if(rt!=null && rt.intValue() == res.getResultHTTPOperation()) {
  214.                     isValid = true;
  215.                     break;
  216.                 }
  217.             }
  218.    
  219.             byte[] response = res.getContent();
  220.    
  221.             if(isValid) {
  222.                 if(response==null || response.length<=0) {
  223.                     throw new UtilsException("Empty response (http code: "+res.getResultHTTPOperation()+")");
  224.                 }
  225.             }
  226.             else {
  227.                 String error = null;
  228.                 if(response.length<=(2048)) {
  229.                     error = Utilities.convertToPrintableText(response, 2048);
  230.                     if(error!=null && error.contains("Visualizzazione non riuscita")) {
  231.                         error = null;
  232.                     }
  233.                 }
  234.                 if(error==null) {
  235.                     error="";
  236.                 }
  237.                 else {
  238.                     error = ": "+error;
  239.                 }
  240.                
  241.                 throw new UtilsException("(http code: "+res.getResultHTTPOperation()+")"+error);
  242.             }
  243.    
  244.         }catch(Exception t) {
  245.             throw new UtilsException("Retrieve external resource '"+resource+"' failed: "+t.getMessage(),t);
  246.         }
  247.     }

  248. }