Package com.nhncorp.mods.socket.io.impl.handlers

Source Code of com.nhncorp.mods.socket.io.impl.handlers.HandshakeHandler

package com.nhncorp.mods.socket.io.impl.handlers;

import com.nhncorp.mods.socket.io.impl.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.vertx.java.core.MultiMap;
import org.vertx.java.core.http.HttpServerRequest;

import java.util.Map;
import java.util.UUID;

/**
* Handles a handshake request.
*
* @see <a href="https://github.com/LearnBoost/socket.io/blob/master/lib/manager.js">manager.js</a>
* @see "Manager.prototype.handleHandshake"
* @author Keesun Baik
*/
public class HandshakeHandler {

  private static final Logger log = LoggerFactory.getLogger(HandshakeHandler.class);

  private Manager manager;

  public HandshakeHandler(Manager manager) {
    this.manager = manager;
  }

  /**
   * Handles a handshake request.
   *
   * @see "Manager.prototype.handleHandshake"
   * @param clientData
   */
  public void handle(final ClientData clientData) {
    final HttpServerRequest request = clientData.getRequest();
    final Settings settings = manager.getSettings();

    log.trace("In handshake handler");
    MultiMap reqHeaders = request.headers();
    final MultiMap resHeaders = request.response().headers();
    String reqOrigin = reqHeaders.get("Origin");
    resHeaders.add("CONTENT_TYPE", "text/plain; charset=UTF-8");

    if (!this.verifyOrigin(reqOrigin)) {
      manager.writeError(request, 403, "handshake bad origin");
      return;
    }

    final HandshakeData handshakeData = new HandshakeData(clientData);

    if (reqOrigin != null) {
      // https://developer.mozilla.org/En/HTTP_Access_Control
      resHeaders.add("Access-Control-Allow-Origin", reqOrigin);
      resHeaders.add("Access-Control-Allow-Credentials", "true");
    }

    authorize(request, handshakeData, new AuthorizationCallback() {
      public void handle(Exception e, boolean isAuthorized) {
        if(e != null) {
          manager.writeError(request, e);
          return;
        }

        if(isAuthorized) {
          String id = UUID.randomUUID().toString();
          String result = id + ":"
              + (settings.isHeartbeats() ? settings.getHeartbeatTimeout() : "") + ":"
              + settings.getCloseTimeout() + ":"
              + settings.getTransports();

          request.response().setStatusCode(200);
          String jsonp = clientData.getParams().get("jsonp");
          if(jsonp != null) {
            result = "io.j[" + jsonp + "](\"" + result + "\");";
            resHeaders.add("Content-Type", "application/javascript");
          }
          request.response().end(result);

          manager.getHandshaken().put(id, handshakeData);
          // self.store.publish('handshake', id, newData || handshakeData);
          log.info("handshake authorized " + id);
        } else {
          manager.writeError(request, 403, "handshake unauthorized");
          log.info("handshake unauthorized");
        }
      }
    });
  }

  /**
   * Performs authentication.
   *
   * @see "Manager.prototype.authorize"
   * @param request
   * @param handshakeData
   * @param authorizeCallback
   */
  private void authorize(HttpServerRequest request, HandshakeData handshakeData, final AuthorizationCallback authorizeCallback) {
    AuthorizationHandler globalAuthHandler = manager.getGlobalAuthorizationHandler();
    if(manager.getSettings().isAuthorization()) {
      if(globalAuthHandler == null) {
        manager.writeError(request, 500, "global authorization callback is required");
        return;
      }
      globalAuthHandler.handle(handshakeData, new AuthorizationCallback() {
        @Override
        public void handle(Exception e, boolean isAuthorized) {
          log.debug("client " + (isAuthorized ? "authorized" : "unauthorized"));
          authorizeCallback.handle(e, isAuthorized);
        }
      });
    } else {
      log.debug("client authorized");
      authorizeCallback.handle(null, true);
    }
  }

  /**
   * Verifies the origin of a request.
   *
   * @see "Manager.prototype.verifyOrigin"
   * @param origin
   * @return
   */
  private boolean verifyOrigin(String origin) {
    String origins = manager.getSettings().getOrigins();
    if(origin == null) {
      origin = "*";
    }

    if(origins.indexOf("*:*") != -1) {
      return true;
    }

    String hostname = origin.split("://")[1];
    String port = null;
    int semicolonIndex = origin.indexOf(":");
    if(semicolonIndex != -1) {
      String[] parts = hostname.split(":");
      hostname = parts[0];
      port = parts[1];
    }

    if(origins.indexOf(hostname + ":" + port) != -1) return true;
    if(origins.indexOf(hostname + ":*") != -1) return true;
    if(origins.indexOf("*:" + port) != -1) return true;

    return false;
  }
}
TOP

Related Classes of com.nhncorp.mods.socket.io.impl.handlers.HandshakeHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.