blob: 776f828b390a5d19c8e0a1cca7aea33d16138107 [file]
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Configuring SPDY Proxy</title><link rel="stylesheet" type="text/css" href="css/docbook.css"><meta name="generator" content="DocBook XSL-NS Stylesheets V1.76.1"><meta name="keywords" content="jetty, servlet, servlet-api, cometd, http, spdy, websocket, eclipse, maven, java, server, software"><link rel="home" href="index.html" title="Jetty : The Definitive Reference"><link rel="up" href="spdy.html" title="Chapter&nbsp;14.&nbsp;SPDY"><link rel="prev" href="spdy-configuring.html" title="Configuring SPDY"><link rel="next" href="spdy-configuring-push.html" title="Configuring SPDY push"><link xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times" rel="shortcut icon" href="images/favicon.ico"><script type="text/javascript" src="js/shCore.js"></script><script type="text/javascript" src="js/shBrushJava.js"></script><script type="text/javascript" src="js/shBrushXml.js"></script><script type="text/javascript" src="js/shBrushBash.js"></script><script type="text/javascript" src="js/shBrushJScript.js"></script><script type="text/javascript" src="js/shBrushSql.js"></script><script type="text/javascript" src="js/shBrushProperties.js"></script><script type="text/javascript" src="js/shBrushPlain.js"></script><link type="text/css" rel="stylesheet" href="css/shCore.css"><link type="text/css" rel="stylesheet" href="css/shThemeEclipse.css"><link type="text/css" rel="stylesheet" href="css/font-awesome.min.css"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><table xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times"><tr><td style="width: 25%"><a href="http://www.eclipse.org/jetty"><img src="images/jetty-header-logo.png" alt="Jetty Logo"></a><br><span style="font-size: small">
Version: 9.2.21.v20170120</span></td><td style="width: 50%"><script type="text/javascript"> (function() {
var cx = '016459005284625897022:obd4lsai2ds';
var gcse = document.createElement('script');
gcse.type = 'text/javascript';
gcse.async = true;
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
'//www.google.com/cse/cse.js?cx=' + cx;
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(gcse, s);
})();
</script><gcse:search></gcse:search></td></tr></table><div xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times" class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Configuring SPDY Proxy</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="spdy-configuring.html"><i class="icon-chevron-left"></i> Previous</a>&nbsp;</td><th width="60%" align="center">Chapter&nbsp;14.&nbsp;SPDY<br><a accesskey="p" href="index.html"><i class="icon-home"></i> Home</a></th><td width="20%" align="right">&nbsp;<a accesskey="n" href="spdy-configuring-push.html">Next <i class="icon-chevron-right"></i></a></td></tr></table><hr></div><div xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times" class="jetty-callout"><h5 class="callout"><a href="http://www.webtide.com/">Contact the core Jetty developers at
<span class="website">www.webtide.com</span></a></h5><p>
private support for your internal/customer projects ... custom extensions and distributions ... versioned snapshots for indefinite support ...
scalability guidance for your apps and Ajax/Comet projects ... development services from 1 day to full product delivery
</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="spdy-configuring-proxy"></a>Configuring SPDY Proxy</h2></div></div></div><div class="toc"><dl><dt><span class="section"><a href="spdy-configuring-proxy.html#spdy-example-config">Configuring SPDY by Example</a></span></dt><dt><span class="section"><a href="spdy-configuring-proxy.html#spdy-to-http-example-config">An Example Configuration for a SPDY to HTTP Proxy</a></span></dt></dl></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="spdy-example-config"></a>Configuring SPDY by Example</h3></div></div></div><p>
<code class="filename">spdy-jetty-http</code>
provides a fully functional SPDY proxy server out of the box. Jetty's SPDY proxy can receive
SPDY
(currently v2/v3) and HTTP requests, and proxy those requests to other SPDY servers. If necessary, an implementation of the Proxy Engine class translates
the incoming protocol to a protocol the target host understands. Currently we provide a SPDYProxyEngine
that can talk SPDY v2 and SPDY v3. We plan to support other protocols soon. As always, contributions are welcome.
</p><p>Configuring SPDY is straightforward, as the following example shows. The example server has
a plain SPDY connector listening on port 9090 and a SPDY proxy connector listening on port 8080. Incoming requests
to port 8080 are proxied and translated to the connector listening on port 9090. In real world scenarios you
more likely proxy to a different host.
</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: xml;toolbar: false">
<![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<New id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory">
<Set name="keyStorePath">src/main/resources/keystore.jks</Set>
<Set name="keyStorePassword">storepwd</Set>
<Set name="trustStore">src/main/resources/truststore.jks</Set>
<Set name="trustStorePassword">storepwd</Set>
<Set name="protocol">TLSv1</Set>
</New>
<!--
<Set class="org.eclipse.jetty.npn.NextProtoNego" name="debug" type="boolean">
true</Set>
-->
<!--
This is the upstream server connector. It speaks non-SSL SPDY/2(HTTP) on port 9090.
-->
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.spdy.http.HTTPSPDYServerConnector">
<Set name="Port">9090</Set>
<Set name="defaultAsyncConnectionFactory">
<Call name="getAsyncConnectionFactory">
<Arg>spdy/2</Arg>
</Call>
</Set>
</New>
</Arg>
</Call>
<!--
This ProxyEngine translates the incoming SPDY/x(HTTP) request to SPDY/2(HTTP)
-->
<New id="spdyProxyEngine" class="org.eclipse.jetty.spdy.proxy.SPDYProxyEngine">
<Arg>spdy/2</Arg>
<Arg>
<New class="org.eclipse.jetty.spdy.SPDYClient$Factory">
<Call name="start"/>
</New>
</Arg>
</New>
<!--
The ProxyEngineSelector receives SPDY/x(HTTP) requests from proxy connectors below
and is configured to process requests for host "localhost".
Such requests are converted from SPDY/x(HTTP) to SPDY/2(HTTP) by the configured ProxyEngine
and forwarded to 127.0.0.1:9090, where they are served by the upstream server above.
-->
<New id="proxyEngineSelector" class="org.eclipse.jetty.spdy.proxy.ProxyEngineSelector">
<Call name="putProxyEngine">
<Arg>
<Ref id="spdyProxyEngine"/>
</Arg>
</Call>
<Set name="proxyServerInfos">
<Map>
<Entry>
<Item>localhost</Item>
<Item>
<New class="org.eclipse.jetty.spdy.proxy.ProxyEngineSelector$ProxyServerInfo">
<Arg type="String">spdy/2</Arg>
<Arg>127.0.0.1</Arg>
<Arg type="int">9090</Arg>
</New>
</Item>
</Entry>
</Map>
</Set>
</New>
<!--
These are the reverse proxy connectors accepting requests from clients.
They accept non-SSL (on port 8080) and SSL (on port 8443) HTTP,
SPDY/2(HTTP) and SPDY/3(HTTP).
Non-SPDY HTTP requests are converted to SPDY internally and passed to the
ProxyEngine above.
-->
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.spdy.proxy.HTTPSPDYProxyConnector">
<Arg>
<Ref id="proxyEngineSelector"/>
</Arg>
<Set name="Port">8080</Set>
</New>
</Arg>
</Call>
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.spdy.proxy.HTTPSPDYProxyConnector">
<Arg>
<Ref id="proxyEngineSelector"/>
</Arg>
<Arg>
<Ref id="sslContextFactory"/>
</Arg>
<Set name="Port">8443</Set>
</New>
</Arg>
</Call>
</Configure>
]]>
</script></div><p>Let's take this apart:</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: xml;toolbar: false">
<![CDATA[
<!--
This ProxyEngine translates the incoming SPDY/x(HTTP) request to SPDY/2(HTTP)
-->
<New id="spdyProxyEngine" class="org.eclipse.jetty.spdy.proxy.SPDYProxyEngine">
<Arg>spdy/2</Arg>
<Arg>
<New class="org.eclipse.jetty.spdy.SPDYClient$Factory">
<Call name="start"/>
</New>
</Arg>
</New>
This is the ProxyEngine configuration. It is a SPDYProxyEngine that can translate to SPDY v2 as
configured above. If your target host is capable of speaking SPDY v3, you change the first constructor argument
to <code>spdy/3.</code> If you have different target hosts speaking different protocols, you configure multiple proxy
engines and feed them to the ProxyEngineSelector as follows.
<!--
The ProxyEngineSelector receives SPDY/x(HTTP) requests from proxy connectors below
and is configured to process requests for host "localhost".
Such requests are converted from SPDY/x(HTTP) to SPDY/2(HTTP) by the configured ProxyEngine
and forwarded to 127.0.0.1:9090, where they are served by the upstream server above.
-->
<New id="proxyEngineSelector" class="org.eclipse.jetty.spdy.proxy.ProxyEngineSelector">
<Call name="putProxyEngine">
<Arg>
<Ref id="spdyProxyEngine"/>
</Arg>
</Call>
<Set name="proxyServerInfos">
<Map>
<Entry>
<Item>localhost</Item>
<Item>
<New class="org.eclipse.jetty.spdy.proxy.ProxyEngineSelector$ProxyServerInfo">
<Arg type="String">spdy/2</Arg>
<Arg>127.0.0.1</Arg>
<Arg type="int">9090</Arg>
</New>
</Item>
</Entry>
</Map>
</Set>
</New>
]]>
</script></div><p>This is the ProxyEngineSelector. The ProxyEngineSelector keeps the configurations for the
known target hosts and also chooses the right ProxyEngine for the protocol the target host
speaks.
</p><p>Let's take even smaller parts of the snipplet above to explain them in detail:</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: xml;toolbar: false">
<![CDATA[
<Call name="putProxyEngine">
<Arg>
<Ref id="spdyProxyEngine"/>
</Arg>
</Call>
]]>
</script></div><p>This adds the SPDYProxyEngine configured above to the ProxyEngineSelector. The SPDYProxyEngine is
configured to translate to <code class="code">spdy/2.</code> By adding it to the Selector, it now knows how to translate to <code class="code">spdy/2.</code>
</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: xml;toolbar: false">
<![CDATA[
<Set name="proxyServerInfos">
<Map>
<Entry>
<Item>localhost</Item>
<Item>
<New class="org.eclipse.jetty.spdy.proxy.ProxyEngineSelector$ProxyServerInfo">
<Arg type="String">spdy/2</Arg>
<Arg>127.0.0.1</Arg>
<Arg type="int">9090</Arg>
</New>
</Item>
</Entry>
</Map>
</Set>
]]>
</script></div><p>You configure target hosts and the protocol you want to communicate with them by adding so-called
ProxyServerInfos. Key for the map is the hostname. You configure protocol, host,
and port for the ProxyServerInfo.
</p><p>Request flow with the proxy given above:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>
Incoming SPDY Request to https://localhost:8443/ reaches the HTTPSPDYProxyConnector listening on
port 8443.
</p></li><li class="listitem"><p>
HTTPSPDYProxyConnector forwards the request to the ProxyEngineSelector.
</p></li><li class="listitem"><p>
ProxyEngineSelector reads the Host header's host portion: "localhost".
</p></li><li class="listitem"><p>
ProxyEngineSelector looks up the host in its ProxyServerInfo mappings. It finds the matching entry,
"localhost". (If there is no matching entry it rst the stream).
</p></li><li class="listitem"><p>
ProxyEngineSelector looks up a ProxyEngine that matches the protocol configured in the
ProxyServerInfo it found in the last step and forwards the request to that ProxyEngine.
</p></li><li class="listitem"><p>
The ProxyEngine translates the request to the given target protocol and proxies it to the target
host.
</p></li><li class="listitem"><p>
All responses are forwarded to the client.
</p></li></ul></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="spdy-to-http-example-config"></a>An Example Configuration for a SPDY to HTTP Proxy</h3></div></div></div><p>
<code class="filename">spdy-jetty-http</code>
provides full proxy functionality as described above. Here's another example configuration for a SPDY to
HTTP proxy. This proxy accepts SPDY requests and proxies them to an HTTP server.
</p><p>
This is a very common use case, for example to terminate SPDY on a frontend server when you need to talk
plain HTTP to your backend, because either your network hardware needs to inspect HTTP content or your
backend is unable to talk SPDY. You have the performance advantages of SPDY over the slow
internet with high latencies, and you talk HTTP to your backend as needed.
</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: xml;toolbar: false">
<![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<!-- ============================================================= -->
<!-- Configure the Jetty Server instance with an ID "Server" -->
<!-- by adding a SPDY connector. -->
<!-- This configuration must be used in conjunction with jetty.xml -->
<!-- It should not be used with jetty-https.xml as this connector -->
<!-- can provide both HTTPS and SPDY connections -->
<!-- ============================================================= -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- =========================================================== -->
<!-- Set up the SSL Context factory used to establish all TLS -->
<!-- Connections and session. -->
<!-- -->
<!-- Consult the javadoc of o.e.j.util.ssl.SslContextFactory -->
<!-- o.e.j.server.HttpConnectionFactory for all configuration -->
<!-- that may be set here. -->
<!-- =========================================================== -->
<New id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory">
<Set name="KeyStorePath"><Property name="jetty.home" default="." />/etc/keystore</Set>
<Set name="KeyStorePassword">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
<Set name="KeyManagerPassword">OBF:1u2u1wml1z7s1z7a1wnl1u2g</Set>
<Set name="TrustStorePath"><Property name="jetty.home" default="." />/etc/keystore</Set>
<Set name="TrustStorePassword">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
</New>
<!-- =========================================================== -->
<!-- Enables NPN debugging on System.err -->
<!-- ===========================================================
<Set class="org.eclipse.jetty.npn.NextProtoNego" name="debug" type="boolean">true</Set>
-->
<!-- =========================================================== -->
<!-- Create a TLS specific HttpConfiguration based on the -->
<!-- common HttpConfiguration defined in jetty.xml -->
<!-- Add a SecureRequestCustomizer to extract certificate and -->
<!-- session information -->
<!-- =========================================================== -->
<New id="tlsHttpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
<Arg><Ref refid="httpConfig"/></Arg>
<Call name="addCustomizer">
<Arg><New class="org.eclipse.jetty.server.SecureRequestCustomizer"/></Arg>
</Call>
</New>
<!-- =========================================================== -->
<!-- This is the upstream server connector. -->
<!-- It speaks HTTP on port 9090. -->
<!-- =========================================================== -->
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.ServerConnector">
<Arg name="server"><Ref id="Server" /></Arg>
<Arg name="factories">
<Array type="org.eclipse.jetty.server.ConnectionFactory">
<Item>
<New class="org.eclipse.jetty.server.HttpConnectionFactory">
<Arg name="config"><Ref id="httpConfig" /></Arg>
</New>
</Item>
</Array>
</Arg>
<Set name="host"><Property name="jetty.host" /></Set>
<Set name="port"><Property name="jetty.port" default="9090" /></Set>
<Set name="idleTimeout">30000</Set>
</New>
</Arg>
</Call>
<!-- =========================================================== -->
<!-- This ProxyEngine translates the incoming SPDY/x(HTTP) -->
<!-- requests to HTTP -->
<!-- =========================================================== -->
<New id="httpProxyEngine" class="org.eclipse.jetty.spdy.server.proxy.HTTPProxyEngine">
<Arg>
<New class="org.eclipse.jetty.client.HttpClient">
<Call name="start"/>
</New>
</Arg>
</New>
<!-- =========================================================== -->
<!-- The ProxyEngineSelector receives SPDY/x(HTTP) requests -->
<!-- from proxy connectors below and is configured to process -->
<!-- requests for host "localhost". -->
<!-- Such requests are converted from SPDY/x(HTTP) to -->
<!-- HTTP by the configured ProxyEngine and forwarded -->
<!-- to 127.0.0.1:9090, where they are served by the upstream -->
<!-- server above. -->
<!-- =========================================================== -->
<New id="proxyEngineSelector" class="org.eclipse.jetty.spdy.server.proxy.ProxyEngineSelector">
<Call name="putProxyEngine">
<Arg>http/1.1</Arg>
<Arg>
<Ref refid="httpProxyEngine"/>
</Arg>
</Call>
<Set name="proxyServerInfos">
<Map>
<Entry>
<Item>localhost</Item>
<Item>
<New class="org.eclipse.jetty.spdy.server.proxy.ProxyEngineSelector$ProxyServerInfo">
<Arg type="String">http/1.1</Arg>
<Arg>127.0.0.1</Arg>
<Arg type="int">9090</Arg>
</New>
</Item>
</Entry>
</Map>
</Set>
</New>
<!-- =========================================================== -->
<!-- These are the reverse proxy connectors accepting requests -->
<!-- from clients. -->
<!-- They accept non-SSL (on port 8080) and SSL (on port 8443) -->
<!-- HTTP, SPDY/2(HTTP) and SPDY/3(HTTP). -->
<!-- Non-SPDY HTTP requests are converted to SPDY internally -->
<!-- and passed to the ProxyEngine above. -->
<!-- =========================================================== -->
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.spdy.server.proxy.HTTPSPDYProxyServerConnector">
<Arg>
<Ref refid="Server"/>
</Arg>
<Arg>
<Ref refid="proxyEngineSelector"/>
</Arg>
<Set name="Port">8080</Set>
</New>
</Arg>
</Call>
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.spdy.server.proxy.HTTPSPDYProxyServerConnector">
<Arg>
<Ref refid="Server"/>
</Arg>
<Arg>
<Ref refid="sslContextFactory"/>
</Arg>
<Arg>
<Ref refid="proxyEngineSelector"/>
</Arg>
<Set name="Port">8443</Set>
</New>
</Arg>
</Call>
</Configure>
]]>
</script></div></div></div><script type="text/javascript">
SyntaxHighlighter.all()
</script><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spdy-configuring.html"><i class="icon-chevron-left"></i> Previous</a>&nbsp;</td><td width="20%" align="center"><a accesskey="u" href="spdy.html"><i class="icon-chevron-up"></i> Top</a></td><td width="40%" align="right">&nbsp;<a accesskey="n" href="spdy-configuring-push.html">Next <i class="icon-chevron-right"></i></a></td></tr><tr><td width="40%" align="left" valign="top">Configuring SPDY&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="index.html"><i class="icon-home"></i> Home</a></td><td width="40%" align="right" valign="top">&nbsp;Configuring SPDY push</td></tr></table></div><p xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times"><div class="jetty-callout">
See an error or something missing?
<span class="callout"><a href="http://github.com/jetty-project/jetty-documentation">Contribute to this documentation at
<span class="website"><i class="icon-github"></i> Github!</span></a></span><span style="float: right"><i>(Generated: 2015-03-13T11:47:52-05:00)</i></span></div></p><script xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times" type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-1149868-7']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script></body></html>