All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.unicore.services.rest.RestServlet Maven / Gradle / Ivy

There is a newer version: 5.2.0-2
Show newest version
package eu.unicore.services.rest;

import java.io.IOException;
import java.nio.channels.SocketChannel;

import org.apache.cxf.transport.servlet.CXFNonSpringServlet;
import org.apache.logging.log4j.Logger;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.HttpTransport;
import org.eclipse.jetty.server.Request;

import eu.unicore.util.Log;
import eu.unicore.util.jetty.forwarding.Forwarder;
import eu.unicore.util.jetty.forwarding.ForwardingConnection;
import eu.unicore.util.jetty.forwarding.UpgradeHttpServletRequest;
import eu.unicore.util.jetty.forwarding.UpgradeHttpServletResponse;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

public class RestServlet extends CXFNonSpringServlet {
	
	private static final long serialVersionUID=1l;

	private static final Logger logger = Log.getLogger(Log.SERVICES, RestServlet.class);

	public static ThreadLocal backends = new ThreadLocal<>();

	@Override
	protected void invoke(HttpServletRequest request, HttpServletResponse response) throws ServletException {
		super.invoke(request, response);
		if(response.getStatus()==101) {
			logger.info("Handling 101 Switching Protocols");
			SocketChannel backend = backends.get();
			if(backend==null)throw new ServletException("No back-end for forwarding found.");
			backends.remove();
			try{
				upgradeConnection(request, response, backend);
			}catch(Exception ex) {
				throw new ServletException(ex);
			}
		}
	}

	protected void upgradeConnection(HttpServletRequest request, HttpServletResponse response, SocketChannel backend) throws Exception {
		Request baseRequest = Request.getBaseRequest(request);
		ForwardingConnection toClient = createForwardingConnection(baseRequest, backend);
		if (toClient == null)
			throw new IOException("not upgraded: no connection");
		logger.debug("forwarding-connection {}", toClient);
		HttpChannel httpChannel = baseRequest.getHttpChannel();
		httpChannel.getConnector().getEventListeners().forEach(toClient::addEventListener);
		baseRequest.setHandled(true);
		baseRequest.setAttribute(HttpTransport.UPGRADE_CONNECTION_ATTRIBUTE, toClient);

		// Save state from request/response and remove reference to the base request/response.
		new UpgradeHttpServletRequest(request).upgrade();
		new UpgradeHttpServletResponse(response).upgrade();
		Forwarder.get().attach(toClient);
		
		logger.info("Forwarding from backend {}, client={}", backend, toClient.getEndPoint().getRemoteSocketAddress());
	}
	
	protected ForwardingConnection createForwardingConnection(Request baseRequest, SocketChannel backend) {
		HttpChannel httpChannel = baseRequest.getHttpChannel();
		Connector connector = httpChannel.getConnector();
		return new ForwardingConnection(httpChannel.getEndPoint(),
				connector.getExecutor(),
				backend);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy