type=page
status=published
title=Protocol Upgrade Processing
next=servlets014a.html
prev=servlets013.html
~~~~~~
= Protocol Upgrade Processing


[[BEIJHCDJ]]

[[protocol-upgrade-processing]]
Protocol Upgrade Processing
---------------------------

In HTTP/1.1, clients can request to switch to a different protocol on
the current connection by using the `Upgrade` header field. If the
server accepts the request to switch to the protocol indicated by the
client, it generates an HTTP response with status 101 (switching
protocols). After this exchange, the client and the server communicate
using the new protocol.

For example, a client can make an HTTP request to switch to the XYZP
protocol as follows:

[source,oac_no_warn]
----
GET /xyzpresource HTTP/1.1
Host: localhost:8080
Accept: text/html
Upgrade: XYZP
Connection: Upgrade
OtherHeaderA: Value
----

The client can specify parameters for the new protocol using HTTP
headers. The server can accept the request and generate a response as
follows:

[source,oac_no_warn]
----
HTTP/1.1 101 Switching Protocols
Upgrade: XYZP
Connection: Upgrade
OtherHeaderB: Value

(XYZP data)
----

Java EE supports the HTTP protocol upgrade functionality in servlets, as
described in link:#BEIBDHAG[Table 18-7].

[[sthref110]][[BEIBDHAG]]

*Table 18-7 Protocol Upgrade Support*

[width="80%",cols="20%,60%"]
|=======================================================================
|*Class or Interface* |*Method*
|`HttpServletRequest` a|
`HttpUpgradeHandler upgrade(Class handler)`

The upgrade method starts the protocol upgrade processing. This method
instantiates a class that implements the `HttpUpgradeHandler` interface
and delegates the connection to it.

You call the `upgrade` method inside a service method when accepting a
request from a client to switch protocols.

|`HttpUpgradeHandler` a|
`void init(WebConnection wc)`

The `init` method is called when the servlet accepts the request to
switch protocols. You implement this method and obtain input and output
streams from the `WebConnection` object to implement the new protocol.

|`HttpUpgradeHandler` a|
`void destroy()`

The `destroy` method is called when the client disconnects. You
implement this method and free any resources associated with processing
the new protocol.

|`WebConnection` a|
`ServletInputStream getInputStream()`

The `getInputStream` method provides access to the input stream of the
connection. You can use link:servlets013.html#BEIHICDH[Nonblocking I/O]
with the returned stream to implement the new protocol.

|`WebConnection` a|
`ServletOutputStream getOutputStream()`

The `getOutputStream` method provides access to the output stream of the
connection. You can use link:servlets013.html#BEIHICDH[Nonblocking I/O]
with the returned stream to implement the new protocol.

|=======================================================================


The following code demonstrates how to accept an HTTP protocol upgrade
request from a client:

[source,oac_no_warn]
----
@WebServlet(urlPatterns={"/xyzpresource"})
public class XYZPUpgradeServlet extends HttpServlet {
   @Override
   public void doGet(HttpServletRequest request,
                     HttpServletResponse response) {
      if ("XYZP".equals(request.getHeader("Upgrade"))) {
         /* Accept upgrade request */
         response.setStatus(101);
         response.setHeader("Upgrade", "XYZP");
         response.setHeader("Connection", "Upgrade");
         response.setHeader("OtherHeaderB", "Value");
         /* Delegate the connection to the upgrade handler */
         XYZPUpgradeHandler = request.upgrade(XYZPUpgradeHandler.class);
         /* (the service method returns immedately) */
      } else {
         /* ... write error response ... */
      }
   }
}
----

The `XYZPUpgradeHandler` class handles the connection:

[source,oac_no_warn]
----
public class XYZPUpgradeHandler implements HttpUpgradeHandler {
   @Override
   public void init(WebConnection wc) {
      ServletInputStream input = wc.getInputStream();
      ServletOutputStream output = wc.getOutputStream();
      /* ... implement XYZP using these streams (protocol-specific) ... */
   }
   @Override
   public void destroy() { ... }
}
----

The class that implements `HttpUpgradeHandler` uses the streams from the
current connection to communicate with the client using the new
protocol. See the Servlet 4.0 specification at
`http://jcp.org/en/jsr/detail?id=369` for details on HTTP protocol
upgrade support.
