From 6a0d9f97047d0f449263f15fac3282d093b080d0 Mon Sep 17 00:00:00 2001 From: Hugi Thordarson Date: Thu, 20 Jul 2023 10:12:33 +0000 Subject: [PATCH] Delete some obsolete docs on jetty 12 upgrade --- ng-adaptor-jetty/scratch/jetty-12.txt | 352 -------------------------- 1 file changed, 352 deletions(-) delete mode 100644 ng-adaptor-jetty/scratch/jetty-12.txt diff --git a/ng-adaptor-jetty/scratch/jetty-12.txt b/ng-adaptor-jetty/scratch/jetty-12.txt deleted file mode 100644 index 83a52883..00000000 --- a/ng-adaptor-jetty/scratch/jetty-12.txt +++ /dev/null @@ -1,352 +0,0 @@ - - org.eclipse.jetty - jetty-server - 12.0.0.beta3 - - - org.eclipse.jetty.ee10 - jetty-ee10-servlet - 12.0.0.beta3 - - -========== - -package ng.adaptor.jetty; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.UncheckedIOException; -import java.net.BindException; -import java.nio.file.Files; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Objects; -import java.util.UUID; - -import org.eclipse.jetty.ee10.servlet.ServletContextHandler; -import org.eclipse.jetty.ee10.servlet.ServletHandler; -import org.eclipse.jetty.ee10.servlet.ServletHolder; -import org.eclipse.jetty.server.Connector; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.server.handler.ContextHandlerCollection; -import org.eclipse.jetty.util.thread.QueuedThreadPool; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import jakarta.servlet.Servlet; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.Cookie; -import jakarta.servlet.http.HttpServlet; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.servlet.http.Part; -import ng.appserver.NGAdaptor; -import ng.appserver.NGApplication; -import ng.appserver.NGCookie; -import ng.appserver.NGRequest; -import ng.appserver.NGResponse; -import ng.appserver.privates.NGDevelopmentInstanceStopper; - -public class NGAdaptorJetty extends NGAdaptor { - - private static final Logger logger = LoggerFactory.getLogger( NGAdaptorJetty.class ); - - /** - * Port used if no port number is specified in properties - * - * FIXME: This should be a default for all adaptors // Hugi 2021-12-31 - */ - private static final int DEFAULT_PORT_NUMBER = 1200; - - private Server server; - - @Override - public void start( NGApplication application ) { - final int minThreads = 8; - final int maxThreads = 32; - final int idleTimeout = 2000; // Specified in milliseconds - - Integer port = application.properties().propWOPort(); // FIXME: Ugly way to get the port number - - if( port == null ) { - logger.warn( "port property is not set, defaulting to port {}", DEFAULT_PORT_NUMBER ); - port = DEFAULT_PORT_NUMBER; - } - - final QueuedThreadPool threadPool = new QueuedThreadPool( maxThreads, minThreads, idleTimeout ); - - server = new Server( threadPool ); - final ServerConnector connector = new ServerConnector( server ); - connector.setPort( port ); - server.setConnectors( new Connector[] { connector } ); - - final ContextHandlerCollection contexts = new ContextHandlerCollection(); - server.setHandler( contexts ); - - final ContextHandler context = new ServletContextHandler( "/" ); - - final ServletHandler servletHandler = new ServletHandler(); - context.setHandler( servletHandler ); - contexts.addHandler( context ); - - final Servlet servlet = new NGServlet( application ); - final ServletHolder servletHolder = new ServletHolder(); - servletHolder.setServlet( servlet ); - servletHandler.addServletWithMapping( servletHolder, "/" ); - - // final ServletHandler servletHandler = new ServletHandler(); - // server.setHandler( servletHandler ); - // - // ServletHolder holder = new ServletHolder(); - // holder.setServlet( new NGServlet( application ) ); - // servletHandler.addServletWithMapping( holder, "/" ); - - try { - server.start(); - } - catch( final Exception e ) { - if( application.properties().isDevelopmentMode() && e instanceof IOException && e.getCause() instanceof BindException ) { - logger.info( "Our port seems to be in use and we're in development mode. Let's try murdering the bastard that's blocking us" ); - NGDevelopmentInstanceStopper.stopPreviousDevelopmentInstance( port ); - start( application ); - } - else { - // FIXME: Handle this a bit more gracefully perhaps? // Hugi 2021-11-20 - e.printStackTrace(); - System.exit( -1 ); - } - } - } - - public void stop() throws Exception { - server.stop(); - } - - public static class NGServlet extends HttpServlet { - - private NGApplication _application; - - public NGServlet( NGApplication application ) { - Objects.requireNonNull( application ); - _application = application; - } - - @Override - protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { - doRequest( request, response ); - } - - @Override - protected void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { - doRequest( request, response ); - } - - private void doRequest( final HttpServletRequest servletRequest, final HttpServletResponse servletResponse ) throws ServletException, IOException { - - // This is where the application logic will perform it's actual work - final NGRequest woRequest = servletRequestToNGRequest( servletRequest ); - final NGResponse ngResponse = _application.dispatchRequest( woRequest ); - - servletResponse.setStatus( ngResponse.status() ); - - // FIXME: Thoughts on content-length: - // - Should we always be setting the content length to zero? - // - Should we complain if a content stream has been set, but contentInputStreamLength not? - // Hugi 2023-01-26 - final long contentLength; - - if( ngResponse.contentInputStream() != null ) { - // If an inputstream is present, use the stream's manually specified length value - contentLength = ngResponse.contentInputStreamLength(); - } - else { - // Otherwise we go for the length of the response's contained data/bytes. - contentLength = ngResponse.contentBytesLength(); - } - - servletResponse.setHeader( "content-length", String.valueOf( contentLength ) ); - - for( final NGCookie ngCookie : ngResponse.cookies() ) { - servletResponse.addCookie( ngCookieToServletCookie( ngCookie ) ); - } - - for( final Entry> entry : ngResponse.headers().entrySet() ) { - for( final String headerValue : entry.getValue() ) { - servletResponse.addHeader( entry.getKey(), headerValue ); - } - } - - try( final OutputStream out = servletResponse.getOutputStream()) { - if( ngResponse.contentInputStream() != null ) { - try( final InputStream inputStream = ngResponse.contentInputStream()) { - // FIXME: We should probably be doing some buffering // Hugi 2023-01-26 - inputStream.transferTo( out ); - } - } - else { - ngResponse.contentByteStream().writeTo( out ); - } - } - } - } - - private static Cookie ngCookieToServletCookie( final NGCookie ngCookie ) { - final Cookie servletCookie = new Cookie( ngCookie.name(), ngCookie.value() ); - - servletCookie.setVersion( 1 ); - - if( ngCookie.domain() != null ) { - servletCookie.setDomain( ngCookie.domain() ); - } - - if( ngCookie.path() != null ) { - servletCookie.setPath( ngCookie.path() ); - } - - servletCookie.setHttpOnly( ngCookie.isHttpOnly() ); - servletCookie.setSecure( ngCookie.isSecure() ); - - if( ngCookie.comment() != null ) { - servletCookie.setComment( ngCookie.comment() ); - } - - if( ngCookie.maxAge() != null ) { - servletCookie.setMaxAge( ngCookie.maxAge() ); - } - - // FIXME: The setAttribute() API was added in Servlet API 6.0, so this will have to wait for Jetty 12 (or for Jetty 11 to support an updated servlet spec) // Hugi 2023-02-06 - // if( ngCookie.sameSite() != null ) { - // servletCookie.setAttribute( "SameSite", ngCookie.sameSite() ); - // } - - return servletCookie; - } - - /** - * @return the given HttpServletRequest converted to an NGRequest - */ - private static NGRequest servletRequestToNGRequest( final HttpServletRequest sr ) { - - // FIXME: Starting work on multipart request handling. Very much experimental/work in progress // Hugi 2023-04-16 - if( sr.getContentType() != null && sr.getContentType().startsWith( "multipart/form-data" ) ) { - System.out.println( ">>>>>>>>>> Multipart request detected" ); - - try { - final String string = Files.createTempFile( UUID.randomUUID().toString(), ".fileupload" ).toString(); - System.out.println( "Multipart temp dir: " + string ); - // sr.setAttribute( Request.__MULTIPART_CONFIG_ELEMENT, new MultipartConfigElement( string ) ); - - for( Part part : sr.getParts() ) { - // MultiPart mp = (MultiPart)part; - System.out.println( "============= START PARTS =============" ); - System.out.println( part.getClass() ); - System.out.println( part.getContentType() ); - System.out.println( part.getName() ); - System.out.println( part.getSubmittedFileName() ); - System.out.println( part.getSize() ); - - System.out.println( "- Headers:" ); - for( String headerName : part.getHeaderNames() ) { - System.out.println( "-- %s : %s".formatted( headerName, part.getHeaders( headerName ) ) ); - - } - - System.out.println( "============= END PARTS =============" ); - } - } - catch( IOException | ServletException e ) { - throw new RuntimeException( e ); - } - } - - // We read the formValues map before reading the requests content stream, since consuming the content stream will remove POST parameters - final Map> formValuesFromServletRequest = formValues( sr.getParameterMap() ); - - final ByteArrayOutputStream bos = new ByteArrayOutputStream(); - - try( final InputStream is = sr.getInputStream()) { - is.transferTo( bos ); - } - catch( final IOException e ) { - throw new UncheckedIOException( "Failed to consume the HTTP request's inputstream", e ); - } - - final NGRequest request = new NGRequest( sr.getMethod(), sr.getRequestURI(), sr.getProtocol(), headerMap( sr ), bos.toByteArray() ); - - // FIXME: Form value parsing should really happen within the request object, not in the adaptor // Hugi 2021-12-31 - request._setFormValues( formValuesFromServletRequest ); - - // FIXME: Cookie parsing should happen within the request object, not in the adaptor // Hugi 2021-12-31 - request._setCookieValues( cookieValues( sr.getCookies() ) ); - - return request; - } - - /** - * @return The queryParameters as a formValue Map (our format) - */ - private static Map> formValues( Map queryParameters ) { - - Map> map = new HashMap<>(); - - for( Entry entry : queryParameters.entrySet() ) { - map.put( entry.getKey(), Arrays.asList( entry.getValue() ) ); - } - - return map; - } - - /** - * @return The listed cookies as a map - */ - private static Map> cookieValues( final Cookie[] cookies ) { - final Map> cookieValues = new HashMap<>(); - - if( cookies != null ) { - for( Cookie cookie : cookies ) { - List list = cookieValues.get( cookie.getName() ); - - if( list == null ) { - list = new ArrayList<>(); - cookieValues.put( cookie.getName(), list ); - } - - list.add( cookie.getValue() ); - } - } - - return cookieValues; - } - - /** - * @return The headers from the ServletRequest as a Map - */ - private static Map> headerMap( final HttpServletRequest servletRequest ) { - final Map> map = new HashMap<>(); - - final Enumeration headerNamesEnumeration = servletRequest.getHeaderNames(); - - while( headerNamesEnumeration.hasMoreElements() ) { - final String headerName = headerNamesEnumeration.nextElement(); - final List values = new ArrayList<>(); - map.put( headerName, values ); - - final Enumeration headerValuesEnumeration = servletRequest.getHeaders( headerName ); - - while( headerValuesEnumeration.hasMoreElements() ) { - values.add( headerValuesEnumeration.nextElement() ); - } - } - - return map; - } -} \ No newline at end of file