Java EE 7 SDK 

Samples Main Page

The HTTP Upgrade Servlet Sample Application

This sample application demonstrates how to use the HTTP Protocol Upgrade API from the Servlet specification.

Description

HTTP/1.1 allows the client to specify additional communication protocols that it supports and would like to use. The Servlet specification includes support for the HTTP protocol upgrade mechanism. The client (ClientTest) initiates the upgrade request. The server (ServerTest) receives the upgrade request and invokes the HttpServletRequest.upgrade() method, which instantiates the HttpUpgradeHandler implementation (ProtocolUpgradeHandler). The HttpUpgradeHandler.init() method is invoked after exiting the ProcessRequest() method of the servlet.

In this sample, the client sends the request to the server. The server accepts the request, sends back the response, and then invokes the HttpUpgradeHandler.init() method and continues the communication using a dummy protocol. The client shows the request and response headers during the handshake process.

Client

In ClientTest.java, the client initiates the HTTP upgrade request.

@WebServlet(name = "ClientTest", urlPatterns = {"/"})
public class ClientTest extends HttpServlet {
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
                                  throws ServletException, IOException {
	    ...
        String reqStr = "POST " + contextRoot + "/ServerTest HTTP/1.1" + CRLF;
        reqStr += "User-Agent: Java/1.7" + CRLF;
        reqStr += "Host: " + host + ":" + port + CRLF;
        reqStr += "Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" + CRLF;
        reqStr += "Upgrade: Dummy Protocol" + CRLF;
        reqStr += "Connection: Upgrade" + CRLF;
        reqStr += "Content-type: application/x-www-form-urlencoded" + CRLF;
        reqStr += "Transfer-Encoding: chunked" + CRLF;
        reqStr += CRLF;
        reqStr += Data + CRLF;

        // Create socket connection to ServerTest
        s = new Socket(host, port);
        input = s.getInputStream();
        output = s.getOutputStream();
		// Send request header with data
        output.write(reqStr.getBytes());
        output.flush();
   }
}

The header Upgrade: Dummy Protocol is an HTTP/1.1 header field set to Dummy Protocol in this sample. The server decides whether to accept the protocol upgrade request.

Server

ServerTest.java checks the Upgrade field in the request header. When it accepts the upgrade requests, the server instantiates ProtocolUpgradeHandler, which is the implementation of HttpUpgradeHandler. If the server does not support the Upgrade protocol specified by the client, it sends a response with 404 Status.

@WebServlet(name="ServerTest", urlPatterns={"/ServerTest"})
public class ServerTest extends HttpServlet {
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
                                  throws ServletException, IOException { 
        // Checking request header
        if ("Dummy Protocol".equals(request.getHeader("Upgrade"))) {
            System.out.println("Accept to upgrade");
            response.setStatus(101);
            response.setHeader("X-Powered-By", "Servlet/3.1 "
                + "(GlassFish Server Open Source Edition 4.0 Java/Oracle Corporation/1.7)");
            response.setHeader("Upgrade", "Dummy Protocol");
            response.setHeader("Connection", "Upgrade");
            response.flushBuffer();
            // Call the upgrade API, and invoke the upgrade handler
            ProtocolUpgradeHandler handler = request.upgrade(ProtocolUpgradeHandler.class);
        } else {
            response.setStatus(400);
            response.setHeader("X-Powered-By", "Servlet/3.1 "
                + "(GlassFish Server Open Source Edition 4.0 Java/Oracle Corporation/1.7)");
            response.setHeader("Connection", "Refused");
            response.sendError(400, "The Upgrade request sent by the client was incorrect or can not be accept by the server");
            System.out.println("Upgrade field is: " + request.getHeader("Upgrade"));
            System.out.println("Upgrade refused");
        }
    }
    ...
}

ProtocolUpgradeHandler is the implementation of HttpUpgradeHandler, which processes the upgrade request and switchs the comminication protocol. The server checks the value of the Upgrade header to determine if it supports that protocol. Once server accepts the request, it must use the Upgrade header field within a 101 (Switching Protocols) response to indicate which protocol(s) are being switched.

Implementation of HttpUpgradeHandler

ProtocolUpgradeHandler is the implementation of HttpUpgradeHandler.

public class ProtocolUpgradeHandler implements HttpUpgradeHandler {
    @Override
    public void init(WebConnection wc) {
        this.wc = wc;
        try {
            ServletOutputStream output = wc.getOutputStream();
            ServletInputStream input = wc.getInputStream();
            Calendar calendar = Calendar.getInstance();
            DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
			
            // Reading the data into byte array
            input.read(echoData);

            // Setting new protocol header
            String resStr = "Dummy Protocol/1.0 " + CRLF;
            resStr += "Server: Glassfish/ServerTest" + CRLF;
            resStr += "Content-Type: text/html" + CRLF;
            resStr += "Connection: Upgrade" + CRLF;
            resStr += "Date: " + dateFormat.format(calendar.getTime()) + CRLF;
            resStr += CRLF;
            
			// Appending data with new protocol
            resStr += new String(echoData) + CRLF;
            
            // Sending back to client
            ...
            output.write(resStr.getBytes());
            output.flush();
        } catch (IOException ex) {
            Logger.getLogger(ProtocolUpgradeHandler.class.getName()).log(Level.SEVERE, null, ex);
        }
	    ...
    }
	
    @Override
    public void destroy() {
        ...
    
        try {
            wc.close();
        } catch (Exception ex) {
            Logger.getLogger(ProtocolUpgradeHandler.class.getName()).log(Level.SEVERE, 
                             "Failed to close connection", ex);
        }
		...
    }
}

The init() method sets up the new protocol headers. The new protocol is used for subsequent comminications. This sample uses a dummy protocol. The destroy() method is invoked when the upgrade process is done.

This sample shows the handshake process of the protocol upgrade. After the handshake process, the subsequent communications use the new protocol. This mechanism only applies to upgrading application-layer protocols upon the existing transport-layer connection. This feature is normally most useful for Java EE Platform providers.

Key Features

This sample application demonstrates how to handle HTTP Protocol Upgrade requests in Java EE Servlets.

Building, Deploying, and Running the Application

Following are the instructions for building, deploying, and running this sample application.

  1. Set up your build environment and configure the application server with which the build system has to work by following the common build instructions.
  2. app_dir is the sample application base directory: samples_install_dir/servlet/http-upgrade-war.
  3. Change directory to app_dir.
  4. Build and deploy the sample application using the mvn target:
  5. Use the command below to run this sample which is using Cargo framework:

    app_dir> mvn clean verify cargo:run

    You can point Cargo to an already installed and running Glassfish server:

    app_dir> mvn clean verify cargo:run -Dglassfish.home=$<glassfish_dir> (e.g. ../glassfish4)

    You can also build, deploy the sample application without Cargo:

    app_dir> mvn install

    app_dir> asadmin deploy ./target/<app_name>.war

  6. Run the sample as follows:

  7. Use the glassfish command line to undeploy the application.

    app_dir> asadmin undeploy <app_name>

  8. Use the target clean to remove the temporary directories like /target.

    app_dir> mvn clean

Building, Deploying, and Running the Application in NetBeans IDE

Perform the following steps to build, deploy, and run the application using NetBeans IDE:

  1. Refer to the common build instructions for setting up NetBeans IDE and Java EE 7 SDK.
  2. In the NetBeans IDE, choose File → Open Project (Ctrl-Shift-O), navigate to the samples_install_dir/servlet/ directory, select http-upgrade-war, and click Open Project.
  3. In the Projects tab, right click http-upgrade-war and select Run to build, deploy, and run the project.

Troubleshooting

If you have problems when running the application, refer the troubleshooting document.

 

Copyright © 1997-2013 Oracle and/or its affiliates. All rights reserved.