diff --git a/.github/dependabot.yml b/.github/dependabot.yml index cd1f551a..acb957b0 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,11 +5,6 @@ updates: schedule: interval: "weekly" target-branch: "master" - ignore: - # Restrict updates to jetty in the 10.x space - - dependency-name: "org.eclipse.jetty:*" - versions: [ ">=11" ] - - package-ecosystem: "github-actions" directory: "/" schedule: diff --git a/Jenkinsfile b/Jenkinsfile index 5fc52de4..cc6dd186 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -5,6 +5,5 @@ */ buildPlugin(useContainerAgent: true, configurations: [ [platform: 'linux', jdk: 21], - [platform: 'windows', jdk: 17], - [platform: 'linux', jdk: 11] + [platform: 'windows', jdk: 17] ]) diff --git a/README.md b/README.md index cf91dc88..fe83999d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # What is Winstone? -Winstone is a command line interface around Jetty 10.0.x, which implements +Winstone is a command line interface around Jetty 12.0.x, which implements Servlet 4.0 (JakartaEE 8/`javax.servlet.*`), WebSocket/JSR-356, and HTTP/2 support. It is used as the default embedded servlet container in Jenkins (via the `executable` package in the `war` module) and can be used by any other web applications that wants to be self-contained. diff --git a/pom.xml b/pom.xml index 51030d77..d966db1d 100644 --- a/pom.xml +++ b/pom.xml @@ -35,14 +35,12 @@ - 6.22 + 7.0 -SNAPSHOT - 10.0.22 + 12.0.12 2.0.16 jenkinsci/winstone false - - 11 @@ -54,6 +52,13 @@ pom import + + org.eclipse.jetty.ee8 + jetty-ee8-bom + ${jetty.version} + pom + import + org.slf4j @@ -101,10 +106,6 @@ org.eclipse.jetty jetty-server - - org.eclipse.jetty - jetty-servlet - org.eclipse.jetty jetty-unixdomain-server @@ -114,21 +115,25 @@ jetty-util - org.eclipse.jetty - jetty-webapp + org.eclipse.jetty.ee8 + jetty-ee8-servlet - org.eclipse.jetty.http2 - http2-hpack + org.eclipse.jetty.ee8 + jetty-ee8-webapp + + + org.eclipse.jetty.ee8.websocket + jetty-ee8-websocket-jetty-server + org.eclipse.jetty.http2 - http2-server + jetty-http2-hpack - org.eclipse.jetty.websocket - websocket-jetty-server - + org.eclipse.jetty.http2 + jetty-http2-server org.slf4j diff --git a/src/main/java/winstone/HostConfiguration.java b/src/main/java/winstone/HostConfiguration.java index 6c1effbd..fca6314c 100644 --- a/src/main/java/winstone/HostConfiguration.java +++ b/src/main/java/winstone/HostConfiguration.java @@ -30,15 +30,12 @@ import java.util.jar.JarFile; import java.util.logging.Level; import javax.servlet.SessionTrackingMode; -import org.eclipse.jetty.http.MimeTypes; +import org.eclipse.jetty.ee8.webapp.WebAppContext; +import org.eclipse.jetty.ee8.websocket.server.config.JettyWebSocketServletContainerInitializer; import org.eclipse.jetty.security.LoginService; -import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.RequestLog; import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.handler.RequestLogHandler; import org.eclipse.jetty.server.handler.gzip.GzipHandler; -import org.eclipse.jetty.webapp.WebAppContext; -import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; import winstone.cmdline.CompressionScheme; import winstone.cmdline.Option; @@ -55,7 +52,6 @@ public class HostConfiguration { private Map args; private Map webapps; private ClassLoader commonLibCL; - private MimeTypes mimeTypes = new MimeTypes(); private final LoginService loginService; public HostConfiguration(Server server, String hostname, ClassLoader commonLibCL, @NonNull Map args) @@ -85,7 +81,11 @@ public HostConfiguration(Server server, String hostname, ClassLoader commonLibCL // trim off the trailing '/' that Jetty doesn't like prefix = prefix.substring(0, prefix.length() - 1); } - Handler handler = configureAccessLog(create(getWebRoot(webroot, warfile), prefix), "webapp"); + WebAppContext webAppContext = create(getWebRoot(webroot, warfile), prefix); + RequestLog requestLog = configureAccessLog("webapp"); + if (requestLog != null) { + server.setRequestLog(requestLog); + } { // load additional mime types loadBuiltinMimeTypes(); @@ -100,7 +100,7 @@ public HostConfiguration(Server server, String hostname, ClassLoader commonLibCL } String extension = mapping.substring(0, delimPos); String mimeType = mapping.substring(delimPos + 1); - this.mimeTypes.addMimeMapping(extension.toLowerCase(), mimeType); + server.getMimeTypes().addMimeMapping(extension.toLowerCase(), mimeType); } } } @@ -109,11 +109,11 @@ public HostConfiguration(Server server, String hostname, ClassLoader commonLibCL switch (compressionScheme) { case GZIP: GzipHandler gzipHandler = new GzipHandler(); - gzipHandler.setHandler(handler); + gzipHandler.setHandler(webAppContext); server.setHandler(gzipHandler); break; case NONE: - server.setHandler(handler); + server.setHandler(webAppContext); break; default: throw new IllegalArgumentException("Unexpected compression scheme: " + compressionScheme); @@ -132,7 +132,8 @@ private void loadBuiltinMimeTypes() { Properties props = new Properties(); props.load(in); for (Entry e : props.entrySet()) { - mimeTypes.addMimeMapping(e.getKey().toString(), e.getValue().toString()); + server.getMimeTypes() + .addMimeMapping(e.getKey().toString(), e.getValue().toString()); } } catch (IOException e) { throw new UncheckedIOException("Failed to load the built-in MIME types", e); @@ -143,24 +144,21 @@ private void loadBuiltinMimeTypes() { * @param webAppName * Unique name given to the access logger. */ - private Handler configureAccessLog(Handler handler, String webAppName) { + private RequestLog configureAccessLog(String webAppName) { try { Class loggerClass = Option.ACCESS_LOGGER_CLASSNAME.get(args, RequestLog.class, commonLibCL); if (loggerClass != null) { // Build the realm Constructor loggerConstr = loggerClass.getConstructor(String.class, Map.class); - RequestLogHandler rlh = new RequestLogHandler(); - rlh.setHandler(handler); - rlh.setRequestLog(loggerConstr.newInstance(webAppName, args)); - return rlh; + return loggerConstr.newInstance(webAppName, args); } else { Logger.log(Level.FINER, Launcher.RESOURCES, "WebAppConfig.LoggerDisabled"); } } catch (Throwable err) { Logger.log(Level.SEVERE, Launcher.RESOURCES, "WebAppConfig.LoggerError", "", err); } - return handler; + return null; } private WebAppContext create(File app, String prefix) { @@ -199,7 +197,6 @@ public void postConfigure() throws Exception { wac.getSecurityHandler().setLoginService(loginService); wac.setThrowUnavailableOnStartupException( true); // if boot fails, abort the process instead of letting empty Jetty run - wac.setMimeTypes(mimeTypes); wac.getSessionHandler().setSessionTrackingModes(Set.of(SessionTrackingMode.COOKIE)); wac.getSessionHandler().setSessionCookie(WinstoneSession.SESSION_COOKIE_NAME); this.webapps.put(wac.getContextPath(), wac); diff --git a/src/main/java/winstone/HttpsConnectorFactory.java b/src/main/java/winstone/HttpsConnectorFactory.java index 6eacd11e..4b29916e 100644 --- a/src/main/java/winstone/HttpsConnectorFactory.java +++ b/src/main/java/winstone/HttpsConnectorFactory.java @@ -11,7 +11,6 @@ import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.handler.HandlerList; import org.eclipse.jetty.server.handler.SecuredRedirectHandler; import winstone.cmdline.Option; @@ -40,14 +39,9 @@ public Connector start(Map args, Server server) throws IOExcepti if (currentHandler == null) { server.setHandler(new SecuredRedirectHandler()); } else { - if (currentHandler instanceof HandlerList) { - ((HandlerList) currentHandler).addHandler(new SecuredRedirectHandler()); - } else { - HandlerList handlers = new HandlerList(); - handlers.addHandler(new SecuredRedirectHandler()); - handlers.addHandler(currentHandler); - server.setHandler(handlers); - } + Handler.Wrapper securedRedirectHandler = new SecuredRedirectHandler(); + securedRedirectHandler.setHandler(currentHandler); + server.setHandler(securedRedirectHandler); } } configureSsl(args, server); diff --git a/src/main/java/winstone/accesslog/SimpleAccessLogger.java b/src/main/java/winstone/accesslog/SimpleAccessLogger.java index 004f57db..1b9601e8 100644 --- a/src/main/java/winstone/accesslog/SimpleAccessLogger.java +++ b/src/main/java/winstone/accesslog/SimpleAccessLogger.java @@ -16,12 +16,13 @@ import java.nio.file.Files; import java.nio.file.InvalidPathException; import java.nio.file.StandardOpenOption; +import java.security.Principal; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Map; import java.util.logging.Level; -import org.eclipse.jetty.server.Authentication; +import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.RequestLog; import org.eclipse.jetty.server.Response; @@ -95,44 +96,41 @@ public SimpleAccessLogger(String webAppName, Map startupArgs) th @Override public void log(Request request, Response response) { - String uriLine = request.getMethod() + " " + request.getRequestURI() + " " + request.getProtocol(); + String uriLine = request.getMethod() + " " + request.getHttpURI().getPath() + " " + + request.getConnectionMetaData().getProtocol(); int status = response.getStatus(); - long size = response.getContentCount(); + long size = Response.getContentBytesWritten(response); String date; synchronized (DF) { date = DF.format(new Date()); } // mimic - // https://github.com/eclipse/jetty.project/blob/jetty-9.4.0.v20161208/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractNCSARequestLog.java#L130 - Authentication authentication = request.getAuthentication(); - String remoteUser; - if (authentication instanceof Authentication.User) { - Authentication.User user = (Authentication.User) authentication; - remoteUser = user.getUserIdentity().getUserPrincipal().getName(); - } else { - remoteUser = null; - } + // https://github.com/jetty/jetty.project/blob/c5b2533fdecce21b54c6fbaf36f79bc3ba909775/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/CustomRequestLog.java#L1093-L1099 + Request.AuthenticationState authenticationState = Request.getAuthenticationState(request); + Principal principal = authenticationState == null ? null : authenticationState.getUserPrincipal(); + String remoteUser = principal == null ? "-" : principal.getName(); + HttpFields httpFields = request.getHeaders(); String logLine = WinstoneResourceBundle.globalReplace(this.pattern, new String[][] { - {"###x-forwarded-for###", nvl(request.getHeader("X-Forwarded-For"))}, - {"###x-forwarded-host###", nvl(request.getHeader("X-Forwarded-Host"))}, - {"###x-forwarded-proto###", nvl(request.getHeader("X-Forwarded-Proto"))}, - {"###x-forwarded-protocol###", nvl(request.getHeader("X-Forwarded-Protocol"))}, - {"###x-forwarded-server###", nvl(request.getHeader("X-Forwarded-Server"))}, - {"###x-forwarded-ssl###", nvl(request.getHeader("X-Forwarded-Ssl"))}, - {"###x-requested-with###", nvl(request.getHeader("X-Requested-With"))}, - {"###x-do-not-track###", nvl(request.getHeader("X-Do-Not-Track"))}, - {"###dnt###", nvl(request.getHeader("DNT"))}, - {"###via###", nvl(request.getHeader("Via"))}, - {"###ip###", request.getRemoteHost()}, + {"###x-forwarded-for###", nvl(httpFields.get("X-Forwarded-For"))}, + {"###x-forwarded-host###", nvl(httpFields.get("X-Forwarded-Host"))}, + {"###x-forwarded-proto###", nvl(httpFields.get("X-Forwarded-Proto"))}, + {"###x-forwarded-protocol###", nvl(httpFields.get("X-Forwarded-Protocol"))}, + {"###x-forwarded-server###", nvl(httpFields.get("X-Forwarded-Server"))}, + {"###x-forwarded-ssl###", nvl(httpFields.get("X-Forwarded-Ssl"))}, + {"###x-requested-with###", nvl(httpFields.get("X-Requested-With"))}, + {"###x-do-not-track###", nvl(httpFields.get("X-Do-Not-Track"))}, + {"###dnt###", nvl(httpFields.get("DNT"))}, + {"###via###", nvl(httpFields.get("Via"))}, + {"###ip###", Request.getRemoteAddr(request)}, {"###user###", nvl(remoteUser)}, {"###time###", "[" + date + "]"}, {"###uriLine###", uriLine}, {"###status###", "" + status}, {"###size###", "" + size}, - {"###referer###", nvl(request.getHeader("Referer"))}, - {"###userAgent###", nvl(request.getHeader("User-Agent"))} + {"###referer###", nvl(httpFields.get("Referer"))}, + {"###userAgent###", nvl(httpFields.get("User-Agent"))} }); this.outWriter.println(logLine); } diff --git a/src/main/resources/winstone/mime.properties b/src/main/resources/winstone/mime.properties index 76b659ab..a8086236 100644 --- a/src/main/resources/winstone/mime.properties +++ b/src/main/resources/winstone/mime.properties @@ -20,32 +20,21 @@ aep=application/vnd.audiograph afm=application/x-font-type1 afp=application/vnd.ibm.modcap ahead=application/vnd.ahead.space -ai=application/postscript -aif=audio/x-aiff -aifc=audio/x-aiff -aiff=audio/x-aiff aim=application/x-aim air=application/vnd.adobe.air-application-installer-package+zip ait=application/vnd.dvb.ait ami=application/vnd.amiga.ami anx=application/annodex -apk=application/vnd.android.package-archive application=application/x-ms-application apr=application/vnd.lotus-approach art=image/x-jg -asc=application/pgp-signature -asf=video/x-ms-asf asm=text/x-asm aso=application/vnd.accpac.simply.aso -asx=video/x-ms-asf atc=application/vnd.acucorp atom=application/atom+xml atomcat=application/atomcat+xml atomsvc=application/atomsvc+xml atx=application/vnd.antix.game-component -au=audio/basic -avif=image/avif -avi=video/x-msvideo avx=video/x-rad-screenplay aw=application/applixware axa=audio/annodex @@ -54,21 +43,17 @@ azf=application/vnd.airzip.filesecure.azf azs=application/vnd.airzip.filesecure.azs azw=application/vnd.amazon.ebook bat=application/x-msdownload -bcpio=application/x-bcpio bdf=application/x-font-bdf bdm=application/vnd.syncml.dm+wbxml bed=application/vnd.realvnc.bed bh2=application/vnd.fujitsu.oasysprs -bin=application/octet-stream bmi=application/vnd.bmi -bmp=image/bmp body=text/html book=application/vnd.framemaker box=application/vnd.previewsystems.box boz=application/x-bzip2 bpk=application/octet-stream btif=image/prs.btif -bz2=application/x-bzip2 bz=application/x-bzip c11amc=application/vnd.cluetrust.cartomobile-config c11amz=application/vnd.cluetrust.cartomobile-config-pkg @@ -77,7 +62,6 @@ c4f=application/vnd.clonk.c4group c4g=application/vnd.clonk.c4group c4p=application/vnd.clonk.c4group c4u=application/vnd.clonk.c4group -cab=application/vnd.ms-cab-compressed cap=application/vnd.tcpdump.pcap car=application/vnd.curl.car cat=application/vnd.ms-pki.seccat @@ -85,7 +69,6 @@ cct=application/x-director cc=text/x-c ccxml=application/ccxml+xml cdbcmsg=application/vnd.contact.cmsg -cdf=application/x-cdf cdkey=application/vnd.mediastation.cdkey cdmia=application/cdmi-capability cdmic=application/cdmi-container @@ -98,13 +81,11 @@ cdy=application/vnd.cinderella cer=application/pkix-cert cgm=image/cgm chat=application/x-chat -chm=application/vnd.ms-htmlhelp chrt=application/vnd.kde.kchart cif=chemical/x-cif cii=application/vnd.anser-web-certificate-issue-initiation cil=application/vnd.ms-artgalry cla=application/vnd.claymore -class=application/java clkk=application/vnd.crick.clicker.keyboard clkp=application/vnd.crick.clicker.palette clkt=application/vnd.crick.clicker.template @@ -119,19 +100,13 @@ cmx=image/x-cmx cod=application/vnd.rim.cod com=application/x-msdownload conf=text/plain -cpio=application/x-cpio cpp=text/x-c -cpt=application/mac-compactpro crd=application/x-mscardfile crl=application/pkix-crl -crt=application/x-x509-ca-cert cryptonote=application/vnd.rig.cryptonote -csh=application/x-csh csml=chemical/x-csml csp=application/vnd.commonspace -css=text/css cst=application/x-director -csv=text/csv c=text/x-c cu=application/cu-seeme curl=text/vnd.curl @@ -142,7 +117,6 @@ dae=model/vnd.collada+xml daf=application/vnd.mobius.daf dataless=application/vnd.fdsn.seed davmount=application/davmount+xml -dcr=application/x-director dcurl=text/vnd.curl.dcurl dd2=application/vnd.oma.dd2+xml ddd=application/vnd.fujixerox.ddd @@ -154,18 +128,14 @@ dfac=application/vnd.dreamfactory dib=image/bmp dic=text/x-c diff=text/plain -dir=application/x-director dis=application/vnd.mobius.dis dist=application/octet-stream distz=application/octet-stream djv=image/vnd.djvu djvu=image/vnd.djvu -dll=application/x-msdownload dmg=application/octet-stream dmp=application/vnd.tcpdump.pcap -dms=application/octet-stream dna=application/vnd.dna -doc=application/msword docm=application/vnd.ms-word.document.macroenabled.12 docx=application/vnd.openxmlformats-officedocument.wordprocessingml.document dot=application/msword @@ -177,18 +147,15 @@ dra=audio/vnd.dra dsc=text/prs.lines.tag dssc=application/dssc+der dtb=application/x-dtbook+xml -dtd=application/xml-dtd dts=audio/vnd.dts dtshd=audio/vnd.dts.hd dump=application/octet-stream dvb=video/vnd.dvb.file -dvi=application/x-dvi dv=video/x-dv dwf=model/vnd.dwf dwg=image/vnd.dwg dxf=image/vnd.dxf dxp=application/vnd.spotfire.dxp -dxr=application/x-director ear=application/octet-stream ecelp4800=audio/vnd.nuera.ecelp4800 ecelp7470=audio/vnd.nuera.ecelp7470 @@ -202,19 +169,14 @@ elc=application/octet-stream eml=message/rfc822 emma=application/emma+xml eol=audio/vnd.digital-winds -eot=application/vnd.ms-fontobject -eps=application/postscript epub=application/epub+zip es3=application/vnd.eszigno3+xml esf=application/vnd.epson.esf et3=application/vnd.eszigno3+xml -etx=text/x-setext -exe=application/x-msdownload exi=application/exi ext=application/vnd.novadigm.ext ez2=application/vnd.ezpix-album ez3=application/vnd.ezpix-package -ez=application/andrew-inset f4v=video/x-f4v f77=text/x-fortran f90=text/x-fortran @@ -262,7 +224,6 @@ gex=application/vnd.geometry-explorer ggb=application/vnd.geogebra.file ggt=application/vnd.geogebra.tool ghf=application/vnd.groove-help -gif=image/gif gim=application/vnd.groove-identity-message gmx=application/vnd.gmx gnumeric=application/x-gnumeric @@ -274,46 +235,33 @@ gre=application/vnd.geometry-explorer grv=application/vnd.groove-injector grxml=application/srgs+xml gsf=application/x-font-ghostscript -gtar=application/x-gtar gtm=application/vnd.groove-tool-message gtw=model/vnd.gtw gv=text/vnd.graphviz gxt=application/vnd.geonext -gz=application/gzip -gzip=application/gzip h261=video/h261 h263=video/h263 h264=video/h264 hal=application/vnd.hal+xml hbci=application/vnd.hbci -hdf=application/x-hdf hh=text/x-c hlp=application/winhlp hpgl=application/vnd.hp-hpgl hpid=application/vnd.hp-hpid hps=application/vnd.hp-hps -hqx=application/mac-binhex40 -htc=text/x-component h=text/x-c htke=application/vnd.kenameaapp -html=text/html -htm=text/html hvd=application/vnd.yamaha.hv-dic hvp=application/vnd.yamaha.hv-voice hvs=application/vnd.yamaha.hv-script i2g=application/vnd.intergeo icc=application/vnd.iccprofile -ice=x-conference/x-cooltalk icm=application/vnd.iccprofile -ico=image/x-icon ics=text/calendar -ief=image/ief ifb=text/calendar ifm=application/vnd.shana.informed.formdata -iges=model/iges igl=application/vnd.igloader igm=application/vnd.insors.igm -igs=model/iges igx=application/vnd.micrografx.igx iif=application/vnd.shana.informed.interchange imp=application/vnd.accpac.simply.imp @@ -331,25 +279,15 @@ iso=application/octet-stream itp=application/vnd.shana.informed.formtemplate ivp=application/vnd.immervision-ivp ivu=application/vnd.immervision-ivu -jad=text/vnd.sun.j2me.app-descriptor jam=application/vnd.jam -jar=application/java-archive -java=text/x-java-source jisp=application/vnd.jisp jlt=application/vnd.hp-jlyt -jnlp=application/x-java-jnlp-file joda=application/vnd.joost.joda-archive -jpeg=image/jpeg -jpe=image/jpeg -jpg=image/jpeg jpgm=video/jpm jpgv=video/jpeg jpm=video/jpm -js=text/javascript jsf=text/plain -json=application/json jspf=text/plain -kar=audio/midi karbon=application/vnd.kde.karbon kfo=application/vnd.kde.kformula kia=application/vnd.kidspiration @@ -369,11 +307,9 @@ ktz=application/vnd.kahootz kwd=application/vnd.kde.kword kwt=application/vnd.kde.kword lasxml=application/vnd.las.las+xml -latex=application/x-latex lbd=application/vnd.llamagraphics.life-balance.desktop lbe=application/vnd.llamagraphics.life-balance.exchange+xml les=application/vnd.hhe.lesson-player -lha=application/octet-stream link66=application/vnd.route66.link66+xml list3820=application/vnd.ibm.modcap listafp=application/vnd.ibm.modcap @@ -385,7 +321,6 @@ lrm=application/vnd.ms-lrm ltf=application/vnd.frogans.ltf lvp=audio/vnd.lucent.voice lwp=application/vnd.lotus-wordpro -lzh=application/octet-stream m13=application/x-msmediaview m14=application/x-msmediaview m1v=video/mpeg @@ -405,8 +340,6 @@ mac=image/x-macpaint mads=application/mads+xml mag=application/vnd.ecowin.chart maker=application/vnd.framemaker -man=text/troff -mathml=application/mathml+xml mb=application/mathematica mbk=application/vnd.mobius.mbk mbox=application/mbox @@ -415,9 +348,7 @@ mcd=application/vnd.mcd mcurl=text/vnd.curl.mcurl mdb=application/x-msaccess mdi=image/vnd.ms-modi -mesh=model/mesh meta4=application/metalink4+xml -me=text/troff mets=application/mets+xml mfm=application/vnd.mfmp mft=application/rpki-manifest @@ -425,13 +356,9 @@ mgp=application/vnd.osgeo.mapguide.package mgz=application/vnd.proteus.magazine mht=message/rfc822 mhtml=message/rfc822 -mid=audio/midi -midi=audio/midi -mif=application/vnd.mif mime=message/rfc822 mj2=video/mj2 mjp2=video/mj2 -mjs=text/javascript mlp=application/vnd.dolby.mlp mmd=application/vnd.chipnuts.karaoke-mmd mmf=application/vnd.smaf @@ -439,25 +366,16 @@ mmr=image/vnd.fujixerox.edmics-mmr mny=application/x-msmoney mobi=application/x-mobipocket-ebook mods=application/mods+xml -movie=video/x-sgi-movie -mov=video/quicktime mp1=audio/mpeg mp21=application/mp21 mp2a=audio/mpeg -mp2=audio/mpeg -mp3=audio/mpeg mp4a=audio/mp4 mp4s=application/mp4 -mp4=video/mp4 mp4v=video/mp4 mpa=audio/mpeg mpc=application/vnd.mophun.certificate mpega=audio/x-mpeg -mpeg=video/mpeg -mpe=video/mpeg mpg4=video/mp4 -mpga=audio/mpeg -mpg=video/mpeg mpkg=application/vnd.apple.installer+xml mpm=application/vnd.blueice.multipass mpn=application/vnd.mophun.application @@ -472,10 +390,7 @@ mscml=application/mediaservercontrol+xml mseed=application/vnd.fdsn.mseed mseq=application/vnd.mseq msf=application/vnd.epson.msf -msh=model/mesh -msi=application/x-msdownload msl=application/vnd.mobius.msl -ms=text/troff msty=application/vnd.muvee.style mts=model/vnd.mts mus=application/vnd.musician @@ -490,7 +405,6 @@ mxu=video/vnd.mpegurl n3=text/n3 nb=application/mathematica nbp=application/vnd.wolfram.player -nc=application/x-netcdf ncx=application/x-dtbncx+xml n-gage=application/vnd.nokia.n-gage.symbian.install ngdat=application/vnd.nokia.n-gage.data @@ -508,19 +422,7 @@ o=application/octet-stream oas=application/vnd.fujitsu.oasys obd=application/x-msbinder obj=application/octet-stream -oda=application/oda -odb=application/vnd.oasis.opendocument.database -odc=application/vnd.oasis.opendocument.chart -odf=application/vnd.oasis.opendocument.formula -odft=application/vnd.oasis.opendocument.formula-template -odg=application/vnd.oasis.opendocument.graphics -odi=application/vnd.oasis.opendocument.image -odm=application/vnd.oasis.opendocument.text-master -odp=application/vnd.oasis.opendocument.presentation -ods=application/vnd.oasis.opendocument.spreadsheet -odt=application/vnd.oasis.opendocument.text oga=audio/ogg -ogg=audio/ogg ogv=video/ogg ogx=application/ogg onepkg=application/onenote @@ -532,15 +434,6 @@ oprc=application/vnd.palm org=application/vnd.lotus-organizer osf=application/vnd.yamaha.openscoreformat osfpvg=application/vnd.yamaha.openscoreformat.osfpvg+xml -otc=application/vnd.oasis.opendocument.chart-template -otf=application/x-font-otf -otg=application/vnd.oasis.opendocument.graphics-template -oth=application/vnd.oasis.opendocument.text-web -oti=application/vnd.oasis.opendocument.image-template -otm=application/vnd.oasis.opendocument.text-master -otp=application/vnd.oasis.opendocument.presentation-template -ots=application/vnd.oasis.opendocument.spreadsheet-template -ott=application/vnd.oasis.opendocument.text-template oxps=application/oxps oxt=application/vnd.openofficeorg.extension p10=application/pkcs10 @@ -554,7 +447,6 @@ p8=application/pkcs8 pas=text/x-pascal paw=application/vnd.pawaafile pbd=application/vnd.powerbuilder6 -pbm=image/x-portable-bitmap pcap=application/vnd.tcpdump.pcap pcf=application/x-font-pcf pcl=application/vnd.hp-pcl @@ -562,15 +454,11 @@ pclxl=application/vnd.hp-pclxl pct=image/pict pcurl=application/vnd.curl.pcurl pcx=image/x-pcx -pdb=application/vnd.palm -pdf=application/pdf pfa=application/x-font-type1 pfb=application/x-font-type1 pfm=application/x-font-type1 pfr=application/font-tdpfr pfx=application/x-pkcs12 -pgm=image/x-portable-graymap -pgn=application/x-chess-pgn pgp=application/pgp-encrypted pic=image/pict pict=image/pict @@ -584,8 +472,6 @@ plist=text/xml pls=application/pls+xml pl=text/plain pml=application/vnd.ctc-posml -png=image/png -pnm=image/x-portable-anymap pnt=image/x-macpaint portpkg=application/vnd.macports.portpkg pot=application/vnd.ms-powerpoint @@ -594,18 +480,14 @@ potx=application/vnd.openxmlformats-officedocument.presentationml.template ppa=application/vnd.ms-powerpoint ppam=application/vnd.ms-powerpoint.addin.macroenabled.12 ppd=application/vnd.cups-ppd -ppm=image/x-portable-pixmap -pps=application/vnd.ms-powerpoint ppsm=application/vnd.ms-powerpoint.slideshow.macroenabled.12 ppsx=application/vnd.openxmlformats-officedocument.presentationml.slideshow -ppt=application/vnd.ms-powerpoint pptm=application/vnd.ms-powerpoint.presentation.macroenabled.12 pptx=application/vnd.openxmlformats-officedocument.presentationml.presentation pqa=application/vnd.palm prc=application/x-mobipocket-ebook pre=application/vnd.lotus-freelance prf=application/pics-rules -ps=application/postscript psb=application/vnd.3gpp.pic-bw-small psd=image/vnd.adobe.photoshop psf=application/x-font-linux-psf @@ -627,45 +509,33 @@ qfx=application/vnd.intu.qfx qps=application/vnd.publishare-delta-tree qtif=image/x-quicktime qti=image/x-quicktime -qt=video/quicktime qwd=application/vnd.quark.quarkxpress qwt=application/vnd.quark.quarkxpress qxb=application/vnd.quark.quarkxpress qxd=application/vnd.quark.quarkxpress qxl=application/vnd.quark.quarkxpress qxt=application/vnd.quark.quarkxpress -ra=audio/x-pn-realaudio -ram=audio/x-pn-realaudio -rar=application/x-rar-compressed -ras=image/x-cmu-raster rcprofile=application/vnd.ipunplugged.rcprofile -rdf=application/rdf+xml rdz=application/vnd.data-vision.rdz rep=application/vnd.businessobjects res=application/x-dtbresource+xml -rgb=image/x-rgb rif=application/reginfo+xml rip=audio/vnd.rip rl=application/resource-lists+xml rlc=image/vnd.fujixerox.edmics-rlc rld=application/resource-lists-diff+xml -rm=application/vnd.rn-realmedia rmi=audio/midi rmp=audio/x-pn-realaudio-plugin rms=application/vnd.jcp.javame.midlet-rms rnc=application/relax-ng-compact-syntax roa=application/rpki-roa -roff=text/troff rp9=application/vnd.cloanto.rp9 -rpm=application/x-rpm rpss=application/vnd.nokia.radio-presets rpst=application/vnd.nokia.radio-preset rq=application/sparql-query rs=application/rls-services+xml rsd=application/rsd+xml rss=application/rss+xml -rtf=application/rtf -rtx=text/richtext saf=application/vnd.yamaha.smaf-audio sbml=application/sbml+xml sc=application/vnd.ibm.secure-container @@ -686,29 +556,18 @@ seed=application/vnd.fdsn.seed sema=application/vnd.sema semd=application/vnd.semd semf=application/vnd.semf -ser=application/java-serialized-object setpay=application/set-payment-initiation setreg=application/set-registration-initiation sfd-hdstx=application/vnd.hydrostatix.sof-data sfs=application/vnd.spotfire.sfs sgl=application/vnd.stardivision.writer-global -sgml=text/sgml -sgm=text/sgml -sh=application/x-sh -shar=application/x-shar shf=application/shf+xml sic=application/vnd.wap.sic sig=application/pgp-signature -silo=model/mesh sis=application/vnd.symbian.install sisx=application/vnd.symbian.install -sit=application/x-stuffit si=text/vnd.wap.si sitx=application/x-stuffitx -skd=application/vnd.koan -skm=application/vnd.koan -skp=application/vnd.koan -skt=application/vnd.koan slc=application/vnd.wap.slc sldm=application/vnd.ms-powerpoint.slide.macroenabled.12 sldx=application/vnd.openxmlformats-officedocument.presentationml.slide @@ -716,20 +575,15 @@ slt=application/vnd.epson.salt sl=text/vnd.wap.sl sm=application/vnd.stepmania.stepchart smf=application/vnd.stardivision.math -smi=application/smil+xml -smil=application/smil+xml smzip=application/vnd.stepmania.package -snd=audio/basic snf=application/x-font-snf so=application/octet-stream spc=application/x-pkcs7-certificates spf=application/vnd.yamaha.smaf-phrase -spl=application/x-futuresplash spot=text/vnd.in3d.spot spp=application/scvp-vp-response spq=application/scvp-vp-request spx=audio/ogg -src=application/x-wais-source sru=application/sru+xml srx=application/sparql-results+xml sse=application/vnd.kodak-descriptor @@ -748,14 +602,9 @@ stw=application/vnd.sun.xml.writer.template sub=text/vnd.dvb.subtitle sus=application/vnd.sus-calendar susp=application/vnd.sus-calendar -sv4cpio=application/x-sv4cpio -sv4crc=application/x-sv4crc svc=application/vnd.dvb.service svd=application/vnd.svd -svg=image/svg+xml -svgz=image/svg+xml swa=application/x-director -swf=application/x-shockwave-flash swi=application/vnd.arastra.swi sxc=application/vnd.sun.xml.calc sxd=application/vnd.sun.xml.draw @@ -765,41 +614,28 @@ sxm=application/vnd.sun.xml.math sxw=application/vnd.sun.xml.writer taglet=application/vnd.mynfc tao=application/vnd.tao.intent-module-archive -tar=application/x-tar -tar.gz=application/gzip tcap=application/vnd.3gpp2.tcap -tcl=application/x-tcl teacher=application/vnd.smart.teacher tei=application/tei+xml teicorpus=application/tei+xml -tex=application/x-tex -texi=application/x-texinfo -texinfo=application/x-texinfo text=text/plain tfi=application/thraud+xml tfm=application/x-tex-tfm -tgz=application/x-gtar thmx=application/vnd.ms-officetheme -tiff=image/tiff -tif=image/tiff tmo=application/vnd.tmobile-livetv torrent=application/x-bittorrent tpl=application/vnd.groove-tool-template tpt=application/vnd.trid.tpt tra=application/vnd.trueapp trm=application/x-msterminal -tr=text/troff tsd=application/timestamped-data -tsv=text/tab-separated-values ttc=application/x-font-ttf -t=text/troff ttf=application/x-font-ttf ttl=text/turtle twd=application/vnd.simtech-mindmapper twds=application/vnd.simtech-mindmapper txd=application/vnd.genomatix.tuxedo txf=application/vnd.mobius.txf -txt=text/plain u32=application/x-authorware-bin udeb=application/x-debian-package ufd=application/vnd.ufdl @@ -811,7 +647,6 @@ uoml=application/vnd.uoml+xml uris=text/uri-list uri=text/uri-list urls=text/uri-list -ustar=application/x-ustar utz=application/vnd.uiq.theme uu=text/x-uuencode uva=audio/vnd.dece.audio @@ -843,7 +678,6 @@ uvvz=application/vnd.dece.zip uvx=application/vnd.dece.unspecified uvz=application/vnd.dece.zip vcard=text/vcard -vcd=application/x-cdlink vcf=text/x-vcard vcg=application/vnd.groove-vcard vcs=text/x-vcalendar @@ -852,28 +686,22 @@ vis=application/vnd.visionary viv=video/vnd.vivo vor=application/vnd.stardivision.writer vox=application/x-authorware-bin -vrml=model/vrml vsd=application/vnd.visio vsf=application/vnd.vsf vss=application/vnd.visio vst=application/vnd.visio vsw=application/vnd.visio vtu=model/vnd.vtu -vxml=application/voicexml+xml w3d=application/x-director wad=application/x-doom war=application/octet-stream -wasm=application/wasm -wav=audio/x-wav wax=audio/x-ms-wax -wbmp=image/vnd.wap.wbmp wbs=application/vnd.criticaltools.wbs+xml wbxml=application/vnd.wap.wbxml wcm=application/vnd.ms-works wdb=application/vnd.ms-works weba=audio/webm webm=video/webm -webp=image/webp wg=application/vnd.pmi.widget wgt=application/widget wiz=application/msword @@ -881,22 +709,15 @@ wks=application/vnd.ms-works wma=audio/x-ms-wma wmd=application/x-ms-wmd wmf=application/x-msmetafile -wmlc=application/vnd.wap.wmlc -wmlsc=application/vnd.wap.wmlscriptc -wmls=text/vnd.wap.wmlscript -wml=text/vnd.wap.wml wm=video/x-ms-wm wmv=video/x-ms-wmv wmx=video/x-ms-wmx wmz=application/x-ms-wmz -woff=font/woff -woff2=font/woff2 wpd=application/vnd.wordperfect wpl=application/vnd.ms-wpl wps=application/vnd.ms-works wqd=application/vnd.wqd wri=application/x-mswrite -wrl=model/vrml wsdl=application/wsdl+xml wspolicy=application/wspolicy+xml wtb=application/vnd.webturbo @@ -907,7 +728,6 @@ xap=application/x-silverlight-app xar=application/vnd.xara xbap=application/x-ms-xbap xbd=application/vnd.fujixerox.docuworks.binder -xbm=image/x-xbitmap xdf=application/xcap-diff+xml xdm=application/vnd.syncml.dm+xml xdp=application/vnd.adobe.xdp+xml @@ -917,8 +737,6 @@ xenc=application/xenc+xml xer=application/patch-ops-error+xml xfdf=application/vnd.adobe.xfdf xfdl=application/vnd.xfdl -xht=application/xhtml+xml -xhtml=application/xhtml+xml xhvml=application/xv+xml xif=image/vnd.xiff xla=application/vnd.ms-excel @@ -926,7 +744,6 @@ xlam=application/vnd.ms-excel.addin.macroenabled.12 xlb=application/vnd.ms-excel xlc=application/vnd.ms-excel xlm=application/vnd.ms-excel -xls=application/vnd.ms-excel xlsb=application/vnd.ms-excel.sheet.binary.macroenabled.12 xlsm=application/vnd.ms-excel.sheet.macroenabled.12 xlsx=application/vnd.openxmlformats-officedocument.spreadsheetml.sheet @@ -934,31 +751,22 @@ xlt=application/vnd.ms-excel xltm=application/vnd.ms-excel.template.macroenabled.12 xltx=application/vnd.openxmlformats-officedocument.spreadsheetml.template xlw=application/vnd.ms-excel -xml=application/xml xo=application/vnd.olpc-sugar xop=application/xop+xml xpdl=application/xml xpi=application/x-xpinstall -xpm=image/x-xpixmap xpr=application/vnd.is-xpr xps=application/vnd.ms-xpsdocument xpw=application/vnd.intercon.formnet xpx=application/vnd.intercon.formnet -xsl=application/xml -xslt=application/xslt+xml xsm=application/vnd.syncml+xml xspf=application/xspf+xml -xul=application/vnd.mozilla.xul+xml xvm=application/xv+xml xvml=application/xv+xml -xwd=image/x-xwindowdump -xyz=chemical/x-xyz yang=application/yang yin=application/yin+xml -z=application/x-compress Z=application/x-compress zaz=application/vnd.zzazz.deck+xml -zip=application/zip zir=application/vnd.zul zirz=application/vnd.zul zmm=application/vnd.handheld-entertainment+xml diff --git a/src/test/java/winstone/AbstractWinstoneTest.java b/src/test/java/winstone/AbstractWinstoneTest.java index 5b1b8e20..6bf15f8d 100644 --- a/src/test/java/winstone/AbstractWinstoneTest.java +++ b/src/test/java/winstone/AbstractWinstoneTest.java @@ -6,9 +6,9 @@ import java.net.ConnectException; import java.net.Socket; import java.nio.file.Path; +import org.eclipse.jetty.client.ContentResponse; import org.eclipse.jetty.client.HttpClient; -import org.eclipse.jetty.client.api.ContentResponse; -import org.eclipse.jetty.client.dynamic.HttpClientTransportDynamic; +import org.eclipse.jetty.client.transport.HttpClientTransportDynamic; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.io.ClientConnector; import org.junit.After; diff --git a/src/test/java/winstone/HostConfigurationTest.java b/src/test/java/winstone/HostConfigurationTest.java new file mode 100644 index 00000000..b3cb04df --- /dev/null +++ b/src/test/java/winstone/HostConfigurationTest.java @@ -0,0 +1,41 @@ +package winstone; + +import java.io.IOException; +import java.io.InputStream; +import java.util.NavigableMap; +import java.util.Properties; +import java.util.TreeMap; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ErrorCollector; + +public class HostConfigurationTest { + + @Rule + public ErrorCollector errors = new ErrorCollector(); + + @Test + public void mimeTypes() throws IOException { + NavigableMap jetty = loadMimeTypes("/org/eclipse/jetty/http/mime.properties"); + NavigableMap winstone = loadMimeTypes("/winstone/mime.properties"); + for (String key : winstone.keySet()) { + if (jetty.containsKey(key)) { + errors.addError(new AssertionError(String.format( + "Attempting to add %s=%s but Jetty already defines %s=%s", + key, winstone.get(key), key, jetty.get(key)))); + } + } + } + + private static NavigableMap loadMimeTypes(String name) throws IOException { + Properties props = new Properties(); + try (InputStream in = HostConfigurationTest.class.getResourceAsStream(name)) { + props.load(in); + } + NavigableMap result = new TreeMap<>(); + for (String key : props.stringPropertyNames()) { + result.put(key, props.getProperty(key)); + } + return result; + } +}