@Override
        public void handle(ServerHttpRequest request, ServerHttpResponse response)
            throws IOException {

          if (!HttpMethod.GET.equals(request.getMethod())) {
            sendMethodNotAllowed(response, Arrays.asList(HttpMethod.GET));
            return;
          }

          String content = String.format(IFRAME_CONTENT, getSockJsClientLibraryUrl());
          byte[] contentBytes = content.getBytes(Charset.forName("UTF-8"));
          StringBuilder builder = new StringBuilder("\"0");
          DigestUtils.appendMd5DigestAsHex(contentBytes, builder);
          builder.append('"');
          String etagValue = builder.toString();

          List<String> ifNoneMatch = request.getHeaders().getIfNoneMatch();
          if (!CollectionUtils.isEmpty(ifNoneMatch) && ifNoneMatch.get(0).equals(etagValue)) {
            response.setStatusCode(HttpStatus.NOT_MODIFIED);
            return;
          }

          response
              .getHeaders()
              .setContentType(new MediaType("text", "html", Charset.forName("UTF-8")));
          response.getHeaders().setContentLength(contentBytes.length);

          addCacheHeaders(response);
          response.getHeaders().setETag(etagValue);
          response.getBody().write(contentBytes);
        }
  protected void addCorsHeaders(
      ServerHttpRequest request, ServerHttpResponse response, HttpMethod... httpMethods) {

    String origin = request.getHeaders().getFirst("origin");
    origin = ((origin == null) || origin.equals("null")) ? "*" : origin;

    response.getHeaders().add("Access-Control-Allow-Origin", origin);
    response.getHeaders().add("Access-Control-Allow-Credentials", "true");

    List<String> accessControllerHeaders =
        request.getHeaders().get("Access-Control-Request-Headers");
    if (accessControllerHeaders != null) {
      for (String header : accessControllerHeaders) {
        response.getHeaders().add("Access-Control-Allow-Headers", header);
      }
    }

    if (!ObjectUtils.isEmpty(httpMethods)) {
      response
          .getHeaders()
          .add(
              "Access-Control-Allow-Methods",
              StringUtils.arrayToDelimitedString(httpMethods, ", "));
      response.getHeaders().add("Access-Control-Max-Age", String.valueOf(ONE_YEAR));
    }
  }
        @Override
        public void handle(ServerHttpRequest request, ServerHttpResponse response)
            throws IOException {

          if (HttpMethod.GET.equals(request.getMethod())) {

            response
                .getHeaders()
                .setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));

            addCorsHeaders(request, response);
            addNoCacheHeaders(response);

            String content =
                String.format(
                    INFO_CONTENT,
                    random.nextInt(),
                    isJsessionIdCookieRequired(),
                    isWebSocketEnabled());
            response.getBody().write(content.getBytes());
          } else if (HttpMethod.OPTIONS.equals(request.getMethod())) {

            response.setStatusCode(HttpStatus.NO_CONTENT);

            addCorsHeaders(request, response, HttpMethod.OPTIONS, HttpMethod.GET);
            addCacheHeaders(response);
          } else {
            sendMethodNotAllowed(response, Arrays.asList(HttpMethod.OPTIONS, HttpMethod.GET));
          }
        }
  @Override
  public final boolean doHandshake(
      ServerHttpRequest request,
      ServerHttpResponse response,
      WebSocketHandler wsHandler,
      Map<String, Object> attributes)
      throws HandshakeFailureException {

    if (logger.isDebugEnabled()) {
      logger.debug(
          "Initiating handshake for " + request.getURI() + ", headers=" + request.getHeaders());
    }

    try {
      if (!HttpMethod.GET.equals(request.getMethod())) {
        response.setStatusCode(HttpStatus.METHOD_NOT_ALLOWED);
        response.getHeaders().setAllow(Collections.singleton(HttpMethod.GET));
        logger.debug("Only HTTP GET is allowed, current method is " + request.getMethod());
        return false;
      }
      if (!"WebSocket".equalsIgnoreCase(request.getHeaders().getUpgrade())) {
        handleInvalidUpgradeHeader(request, response);
        return false;
      }
      if (!request.getHeaders().getConnection().contains("Upgrade")
          && !request.getHeaders().getConnection().contains("upgrade")) {
        handleInvalidConnectHeader(request, response);
        return false;
      }
      if (!isWebSocketVersionSupported(request)) {
        handleWebSocketVersionNotSupported(request, response);
        return false;
      }
      if (!isValidOrigin(request)) {
        response.setStatusCode(HttpStatus.FORBIDDEN);
        return false;
      }
      String wsKey = request.getHeaders().getSecWebSocketKey();
      if (wsKey == null) {
        logger.debug("Missing \"Sec-WebSocket-Key\" header");
        response.setStatusCode(HttpStatus.BAD_REQUEST);
        return false;
      }
    } catch (IOException ex) {
      throw new HandshakeFailureException(
          "Response update failed during upgrade to WebSocket, uri=" + request.getURI(), ex);
    }

    String subProtocol = selectProtocol(request.getHeaders().getSecWebSocketProtocol());

    if (logger.isDebugEnabled()) {
      logger.debug("Upgrading request, sub-protocol=" + subProtocol);
    }

    this.requestUpgradeStrategy.upgrade(request, response, subProtocol, wsHandler, attributes);

    return true;
  }
 protected void handleWebSocketVersionNotSupported(
     ServerHttpRequest request, ServerHttpResponse response) {
   logger.debug(
       "WebSocket version not supported " + request.getHeaders().get("Sec-WebSocket-Version"));
   response.setStatusCode(HttpStatus.UPGRADE_REQUIRED);
   response
       .getHeaders()
       .setSecWebSocketVersion(StringUtils.arrayToCommaDelimitedString(getSupportedVerions()));
 }
Exemplo n.º 6
0
  @Override
  protected void extendResponse(ServerHttpResponse outputMessage) {
    super.extendResponse(outputMessage);

    HttpHeaders headers = outputMessage.getHeaders();
    if (headers.getContentType() == null) {
      headers.setContentType(new MediaType("text", "event-stream"));
    }
  }
  @Override
  public void handleReturnValue(
      Object returnValue,
      MethodParameter returnType,
      ModelAndViewContainer mavContainer,
      NativeWebRequest webRequest)
      throws Exception {

    if (returnValue == null) {
      mavContainer.setRequestHandled(true);
      return;
    }

    HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
    ServerHttpResponse outputMessage = new ServletServerHttpResponse(response);

    if (ResponseEntity.class.isAssignableFrom(returnValue.getClass())) {
      ResponseEntity<?> responseEntity = (ResponseEntity<?>) returnValue;
      outputMessage.setStatusCode(responseEntity.getStatusCode());
      outputMessage.getHeaders().putAll(responseEntity.getHeaders());
      returnValue = responseEntity.getBody();
      if (returnValue == null) {
        mavContainer.setRequestHandled(true);
        return;
      }
    }

    ServletRequest request = webRequest.getNativeRequest(ServletRequest.class);
    ShallowEtagHeaderFilter.disableContentCaching(request);

    Assert.isInstanceOf(ResponseBodyEmitter.class, returnValue);
    ResponseBodyEmitter emitter = (ResponseBodyEmitter) returnValue;
    emitter.extendResponse(outputMessage);

    // Commit the response and wrap to ignore further header changes
    outputMessage.getBody();
    outputMessage = new StreamingServletServerHttpResponse(outputMessage);

    DeferredResult<?> deferredResult = new DeferredResult<Object>(emitter.getTimeout());
    WebAsyncUtils.getAsyncManager(webRequest)
        .startDeferredResultProcessing(deferredResult, mavContainer);

    HttpMessageConvertingHandler handler =
        new HttpMessageConvertingHandler(outputMessage, deferredResult);
    emitter.initialize(handler);
  }
  @Override
  public final void handleRequest(
      ServerHttpRequest request,
      ServerHttpResponse response,
      WebSocketHandler wsHandler,
      SockJsSession wsSession)
      throws SockJsException {

    AbstractHttpSockJsSession sockJsSession = (AbstractHttpSockJsSession) wsSession;

    String protocol = null; // https://github.com/sockjs/sockjs-client/issues/130
    sockJsSession.setAcceptedProtocol(protocol);

    // Set content type before writing
    response.getHeaders().setContentType(getContentType());

    handleRequestInternal(request, response, sockJsSession);
  }
  @Override
  protected void beforeBodyWriteInternal(
      MappingJacksonValue bodyContainer,
      MediaType contentType,
      MethodParameter returnType,
      ServerHttpRequest request,
      ServerHttpResponse response) {

    HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest();

    for (String name : this.jsonpQueryParamNames) {
      String value = servletRequest.getParameter(name);
      if (value != null) {
        MediaType contentTypeToUse = getContentType(contentType, request, response);
        response.getHeaders().setContentType(contentTypeToUse);
        bodyContainer.setJsonpFunction(value);
        return;
      }
    }
  }
 protected void sendMethodNotAllowed(ServerHttpResponse response, List<HttpMethod> httpMethods)
     throws IOException {
   logger.debug("Sending Method Not Allowed (405)");
   response.setStatusCode(HttpStatus.METHOD_NOT_ALLOWED);
   response.getHeaders().setAllow(new HashSet<HttpMethod>(httpMethods));
 }
 protected void addNoCacheHeaders(ServerHttpResponse response) {
   response.getHeaders().setCacheControl("no-store, no-cache, must-revalidate, max-age=0");
 }
 protected void addCacheHeaders(ServerHttpResponse response) {
   response.getHeaders().setCacheControl("public, max-age=" + ONE_YEAR);
   response.getHeaders().setExpires(new Date().getTime() + ONE_YEAR * 1000);
 }
  /**
   * TODO
   *
   * @param request
   * @param response
   * @param sockJsPath
   * @throws Exception
   */
  @Override
  public final void handleRequest(
      ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler)
      throws IOException, TransportErrorException {

    String sockJsPath = getSockJsPath(request);
    if (sockJsPath == null) {
      logger.warn(
          "Could not determine SockJS path for URL \""
              + request.getURI().getPath()
              + ". Consider setting validSockJsPrefixes.");
      response.setStatusCode(HttpStatus.NOT_FOUND);
      return;
    }

    logger.debug(request.getMethod() + " with SockJS path [" + sockJsPath + "]");

    try {
      request.getHeaders();
    } catch (IllegalArgumentException ex) {
      // Ignore invalid Content-Type (TODO)
    }

    try {
      if (sockJsPath.equals("") || sockJsPath.equals("/")) {
        response
            .getHeaders()
            .setContentType(new MediaType("text", "plain", Charset.forName("UTF-8")));
        response.getBody().write("Welcome to SockJS!\n".getBytes("UTF-8"));
        return;
      } else if (sockJsPath.equals("/info")) {
        this.infoHandler.handle(request, response);
        return;
      } else if (sockJsPath.matches("/iframe[0-9-.a-z_]*.html")) {
        this.iframeHandler.handle(request, response);
        return;
      } else if (sockJsPath.equals("/websocket")) {
        handleRawWebSocketRequest(request, response, handler);
        return;
      }

      String[] pathSegments = StringUtils.tokenizeToStringArray(sockJsPath.substring(1), "/");
      if (pathSegments.length != 3) {
        logger.warn("Expected \"/{server}/{session}/{transport}\" but got \"" + sockJsPath + "\"");
        response.setStatusCode(HttpStatus.NOT_FOUND);
        return;
      }

      String serverId = pathSegments[0];
      String sessionId = pathSegments[1];
      String transport = pathSegments[2];

      if (!validateRequest(serverId, sessionId, transport)) {
        response.setStatusCode(HttpStatus.NOT_FOUND);
        return;
      }

      handleTransportRequest(
          request, response, sessionId, TransportType.fromValue(transport), handler);
    } finally {
      response.flush();
    }
  }
 public StreamingServletServerHttpResponse(ServerHttpResponse delegate) {
   this.delegate = delegate;
   this.mutableHeaders.putAll(delegate.getHeaders());
 }