@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())); }
@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()); }