ConnettoreExtBaseHTTP.java
/*
* GovWay - A customizable API Gateway
* https://govway.org
*
* Copyright (c) 2005-2025 Link.it srl (https://link.it).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openspcoop2.pdd.core.connettori;
import java.io.ByteArrayOutputStream;
import java.net.Proxy;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.openspcoop2.core.config.ResponseCachingConfigurazione;
import org.openspcoop2.core.config.constants.CostantiConfigurazione;
import org.openspcoop2.core.constants.CostantiConnettori;
import org.openspcoop2.core.constants.TipiConnettore;
import org.openspcoop2.core.constants.TransferLengthModes;
import org.openspcoop2.pdd.mdb.ConsegnaContenutiApplicativi;
import org.openspcoop2.utils.NameValue;
import org.openspcoop2.utils.UtilsException;
import org.openspcoop2.utils.transport.TransportUtils;
import org.openspcoop2.utils.transport.http.RFC2047Utilities;
/**
* Classe utilizzata per effettuare consegne di messaggi, attraverso
* l'invocazione di un server http.
* Gestisce aspetti della connessione quali redirect, trasfern mode, proxy e parametri https
*
* @author Poli Andrea (apoli@link.it)
* @author $Author$
* @version $Rev$, $Date$
*/
public abstract class ConnettoreExtBaseHTTP extends ConnettoreBaseHTTP {
/* ******** F I E L D S P R I V A T I ******** */
public ByteArrayOutputStream outByte = new ByteArrayOutputStream();
/** Proxy Configuration */
protected Proxy.Type proxyType = null;
protected String proxyHostname = null;
protected int proxyPort;
protected String proxyUsername;
protected String proxyPassword;
/** Redirect */
protected boolean followRedirects = false;
public boolean isFollowRedirects() {
return this.followRedirects;
}
protected String routeRedirect = null;
public String getRouteRedirect() {
return this.routeRedirect;
}
protected int numberRedirect = 0;
public int getNumberRedirect() {
return this.numberRedirect;
}
protected int maxNumberRedirects = 5;
public int getMaxNumberRedirects() {
return this.maxNumberRedirects;
}
protected String redirectLocation = null;
public void setRedirectLocation(String redirectLocation) {
this.redirectLocation = redirectLocation;
}
public String getRedirectLocation() {
return this.redirectLocation;
}
protected String originalAbsolutePrefixForRelativeRedirectLocation = null;
public void setOriginalAbsolutePrefixForRelativeRedirectLocation(
String originalAbsolutePrefixForRelativeRedirectLocation) {
this.originalAbsolutePrefixForRelativeRedirectLocation = originalAbsolutePrefixForRelativeRedirectLocation;
}
public String getOriginalAbsolutePrefixForRelativeRedirectLocation() {
return this.originalAbsolutePrefixForRelativeRedirectLocation;
}
/** TransferMode */
protected TransferLengthModes tlm = null;
protected int chunkLength = -1;
/* Costruttori */
public ConnettoreExtBaseHTTP(){
super();
}
public ConnettoreExtBaseHTTP(boolean https){
super(https);
}
/* ******** METODI ******** */
@Override
protected boolean initializePreSend(ResponseCachingConfigurazione responseCachingConfig, ConnettoreMsg request) {
return this.initialize(request, true, responseCachingConfig);
}
@Override
public boolean send(ConnettoreMsg request) {
// HTTPS
try{
this.setSSLContext();
}catch(Exception e){
this.eccezioneProcessamento = e;
this.logger.error("[HTTPS error]"+ this.readExceptionMessageFromException(e),e);
this.errore = "[HTTPS error]"+ this.readExceptionMessageFromException(e);
return false;
}
// Proxy
if(this.properties.get(CostantiConnettori.CONNETTORE_HTTP_PROXY_TYPE)!=null){
String tipo = this.properties.get(CostantiConnettori.CONNETTORE_HTTP_PROXY_TYPE).trim();
if(CostantiConnettori.CONNETTORE_HTTP_PROXY_TYPE_VALUE_HTTP.equals(tipo)){
this.proxyType = Proxy.Type.HTTP;
}
else if(CostantiConnettori.CONNETTORE_HTTP_PROXY_TYPE_VALUE_HTTPS.equals(tipo)){
this.proxyType = Proxy.Type.HTTP;
}
else{
this.errore = "Proprieta' '"+CostantiConnettori.CONNETTORE_HTTP_PROXY_TYPE
+"' non corretta. Impostato un tipo sconosciuto ["+tipo+"] (valori ammessi: "+CostantiConnettori.CONNETTORE_HTTP_PROXY_TYPE_VALUE_HTTP
+","+CostantiConnettori.CONNETTORE_HTTP_PROXY_TYPE_VALUE_HTTPS+")";
return false;
}
this.proxyHostname = this.properties.get(CostantiConnettori.CONNETTORE_HTTP_PROXY_HOSTNAME);
if(this.proxyHostname!=null){
this.proxyHostname = this.proxyHostname.trim();
}else{
this.errore = "Proprieta' '"+CostantiConnettori.CONNETTORE_HTTP_PROXY_HOSTNAME+
"' non impostata, obbligatoria in presenza della proprietà '"+CostantiConnettori.CONNETTORE_HTTP_PROXY_TYPE+"'";
return false;
}
String proxyPortTmp = this.properties.get(CostantiConnettori.CONNETTORE_HTTP_PROXY_PORT);
if(proxyPortTmp!=null){
proxyPortTmp = proxyPortTmp.trim();
}else{
this.errore = "Proprieta' '"+CostantiConnettori.CONNETTORE_HTTP_PROXY_PORT+
"' non impostata, obbligatoria in presenza della proprietà '"+CostantiConnettori.CONNETTORE_HTTP_PROXY_TYPE+"'";
return false;
}
try{
this.proxyPort = Integer.parseInt(proxyPortTmp);
}catch(Exception e){
this.errore = "Proprieta' '"+CostantiConnettori.CONNETTORE_HTTP_PROXY_PORT+"' non corretta: "+this.readExceptionMessageFromException(e);
return false;
}
this.proxyUsername = this.properties.get(CostantiConnettori.CONNETTORE_HTTP_PROXY_USERNAME);
if(this.proxyUsername!=null){
this.proxyUsername = this.proxyUsername.trim();
}
this.proxyPassword = this.properties.get(CostantiConnettori.CONNETTORE_HTTP_PROXY_PASSWORD);
if(this.proxyPassword!=null){
this.proxyPassword = this.proxyPassword.trim();
}else{
if(this.proxyUsername!=null){
this.errore = "Proprieta' '"+CostantiConnettori.CONNETTORE_HTTP_PROXY_PASSWORD
+"' non impostata, obbligatoria in presenza della proprietà '"+CostantiConnettori.CONNETTORE_HTTP_PROXY_USERNAME+"'";
return false;
}
}
}
// TransferMode
if(ConsegnaContenutiApplicativi.ID_MODULO.equals(this.idModulo)){
this.tlm = this.openspcoopProperties.getTransferLengthModes_consegnaContenutiApplicativi();
this.chunkLength = this.openspcoopProperties.getChunkLength_consegnaContenutiApplicativi();
}
else{
// InoltroBuste e InoltroRisposte
this.tlm = this.openspcoopProperties.getTransferLengthModes_inoltroBuste();
this.chunkLength = this.openspcoopProperties.getChunkLength_inoltroBuste();
}
String tlmTmp = this.properties.get(CostantiConnettori.CONNETTORE_HTTP_DATA_TRANSFER_MODE);
if(tlmTmp!=null){
tlmTmp = tlmTmp.trim();
try{
this.tlm = TransferLengthModes.getTransferLengthModes(tlmTmp);
}catch(Exception e){
this.errore = "Proprieta' '"+CostantiConnettori.CONNETTORE_HTTP_DATA_TRANSFER_MODE
+"' non impostata correttamente: "+e.getMessage();
return false;
}
}
if(TransferLengthModes.TRANSFER_ENCODING_CHUNKED.equals(this.tlm)){
tlmTmp = this.properties.get(CostantiConnettori.CONNETTORE_HTTP_DATA_TRANSFER_MODE_CHUNK_SIZE);
//this.log.info("PROPERTY! ("+redirectTmp+")");
if(tlmTmp!=null){
tlmTmp = tlmTmp.trim();
this.chunkLength = Integer.parseInt(tlmTmp);
}
}
// Redirect
if(ConsegnaContenutiApplicativi.ID_MODULO.equals(this.idModulo)){
if(this.isSoap) {
this.followRedirects = this.openspcoopProperties.isFollowRedirects_consegnaContenutiApplicativi_soap();
}else {
this.followRedirects = this.openspcoopProperties.isFollowRedirects_consegnaContenutiApplicativi_rest();
}
this.maxNumberRedirects = this.openspcoopProperties.getFollowRedirectsMaxHop_consegnaContenutiApplicativi();
}
else{
// InoltroBuste e InoltroRisposte
if(this.isSoap) {
this.followRedirects = this.openspcoopProperties.isFollowRedirects_inoltroBuste_soap();
}
else {
this.followRedirects = this.openspcoopProperties.isFollowRedirects_inoltroBuste_rest();
}
this.maxNumberRedirects = this.openspcoopProperties.getFollowRedirectsMaxHop_inoltroBuste();
}
String redirectTmp = this.properties.get(CostantiConnettori.CONNETTORE_HTTP_REDIRECT_FOLLOW);
if(redirectTmp!=null){
redirectTmp = redirectTmp.trim();
this.followRedirects = "true".equalsIgnoreCase(redirectTmp) || CostantiConfigurazione.ABILITATO.getValue().equalsIgnoreCase(redirectTmp);
}
//this.log.info("FOLLOW! ("+this.followRedirects+")");
if(this.followRedirects){
redirectTmp = this.properties.get(CostantiConnettori.CONNETTORE_HTTP_REDIRECT_MAX_HOP);
//this.log.info("PROPERTY! ("+redirectTmp+")");
if(redirectTmp!=null){
redirectTmp = redirectTmp.trim();
this.maxNumberRedirects = Integer.parseInt(redirectTmp);
}
redirectTmp = this.properties.get(CostantiConnettori.CONNETTORE_HTTP_REDIRECT_NUMBER);
//this.log.info("PROPERTY! ("+redirectTmp+")");
if(redirectTmp!=null){
redirectTmp = redirectTmp.trim();
this.numberRedirect = Integer.parseInt(redirectTmp);
}
redirectTmp = this.properties.get(CostantiConnettori.CONNETTORE_HTTP_REDIRECT_ROUTE);
//this.log.info("PROPERTY! ("+redirectTmp+")");
if(redirectTmp!=null){
redirectTmp = redirectTmp.trim();
this.routeRedirect = redirectTmp;
}
}
return sendHTTP(request);
}
/**
* Si occupa di effettuare la consegna HTTP_POST (sbustando il messaggio SOAP).
* Si aspetta di ricevere una risposta non sbustata.
*
* @return true in caso di consegna con successo, false altrimenti
*
*/
protected abstract boolean sendHTTP(ConnettoreMsg request);
/**
* Ritorna l'informazione su dove il connettore sta spedendo il messaggio
*
* @return location di inoltro del messaggio
*/
@Override
public String getLocation(){
if(this.location==null){
// può darsi che per un errore non sia ancora stata inizializzata la location
try{
this.buildLocation();
}catch(Throwable t){}
}
if(this.location!=null){
String l = new String(this.location);
if(this.routeRedirect!=null){
l = l+" [redirects route path: "+this.routeRedirect+"]";
}
if(this.proxyType!=null){
l = l+" [proxy: "+this.proxyHostname+":"+this.proxyPort+"]";
}
// if(this.forwardProxy!=null && this.forwardProxy.isEnabled()) {
// l = l+" [govway-proxy]";
// }
return l;
}
return null;
}
protected String getTipoImplConnettore() {
if(this.tipoConnettore!=null && StringUtils.isNotEmpty(this.tipoConnettore)) {
return this.tipoConnettore;
}
else {
return this.connettoreHttps ? TipiConnettore.HTTPS.toString() : TipiConnettore.HTTP.toString();
}
}
protected void buildLocation() throws ConnettoreException {
if(this.redirectLocation!=null) {
this.location = this.redirectLocation;
}
else {
this.location = TransportUtils.getObjectAsString(this.properties,CostantiConnettori.CONNETTORE_LOCATION);
}
NameValue nv = this.getTokenQueryParameter();
if(nv!=null) {
if(this.requestMsg!=null && this.requestMsg.getTransportRequestContext()!=null) {
this.requestMsg.getTransportRequestContext().removeParameter(nv.getName()); // Fix: senno sovrascriveva il vecchio token
}
if(this.propertiesUrlBased==null) {
this.propertiesUrlBased = new HashMap<>();
}
TransportUtils.setParameter(this.propertiesUrlBased, nv.getName(), nv.getValue());
}
if(this.redirectLocation==null) {
this.location = ConnettoreUtils.buildLocationWithURLBasedParameter(this.logger!=null ? this.logger.getLogger() : null, this.requestMsg,
this.getTipoImplConnettore(),
this.propertiesUrlBased, this.location,
this.getProtocolFactory(), this.idModulo);
}
this.updateLocationForwardProxy(this.location);
}
protected void setRequestHeader(boolean validazioneHeaderRFC2047, String key, List<String> values, ConnettoreLogger logger, Map<String, List<String>> propertiesTrasportoDebug) throws Exception {
if(validazioneHeaderRFC2047){
try{
RFC2047Utilities.validHeader(key, values);
setRequestHeader(key, values, propertiesTrasportoDebug);
}catch(UtilsException e){
logger.error(e.getMessage(),e);
}
}
else{
setRequestHeader(key,values, propertiesTrasportoDebug);
}
}
@Override
protected abstract void setRequestHeader(String key,List<String> values) throws ConnettoreException;
}