// --------------------------------------------------------------- Handlers /// <summary> /// Handles a CORS request of type /// <see cref="CORSRequestType"/> /// .SIMPLE. /// </summary> /// <param name="request"> /// The /// <see cref="Javax.Servlet.Http.IHttpServletRequest"/> /// object. /// </param> /// <param name="response"> /// The /// <see cref="Javax.Servlet.Http.IHttpServletResponse"/> /// object. /// </param> /// <param name="filterChain"> /// The /// <see cref="Javax.Servlet.IFilterChain"/> /// object. /// </param> /// <exception cref="System.IO.IOException"/> /// <exception cref="Javax.Servlet.ServletException"/> /// <seealso><a href="http://www.w3.org/TR/cors/#resource-requests">Simple /// * Cross-Origin Request, Actual Request, and Redirects</a></seealso> public void HandleSimpleCORS(IHttpServletRequest request, IHttpServletResponse response, IFilterChain filterChain) { CORSFilter.CORSRequestType requestType = CheckRequestType(request); if (!(requestType == CORSFilter.CORSRequestType.Simple || requestType == CORSFilter.CORSRequestType.Actual)) { string message = "Expects a HttpServletRequest object of type " + CORSFilter.CORSRequestType.Simple + " or " + CORSFilter.CORSRequestType.Actual; throw new ArgumentException(message); } string origin = request.GetHeader(Edu.Stanford.Nlp.Naturalli.Demo.CORSFilter.RequestHeaderOrigin); string method = request.GetMethod(); // Section 6.1.2 if (!IsOriginAllowed(origin)) { HandleInvalidCORS(request, response, filterChain); return; } if (!allowedHttpMethods.Contains(method)) { HandleInvalidCORS(request, response, filterChain); return; } // Section 6.1.3 // Add a single Access-Control-Allow-Origin header. if (anyOriginAllowed && !supportsCredentials) { // If resource doesn't support credentials and if any origin is // allowed // to make CORS request, return header with '*'. response.AddHeader(Edu.Stanford.Nlp.Naturalli.Demo.CORSFilter.ResponseHeaderAccessControlAllowOrigin, "*"); } else { // If the resource supports credentials add a single // Access-Control-Allow-Origin header, with the value of the Origin // header as value. response.AddHeader(Edu.Stanford.Nlp.Naturalli.Demo.CORSFilter.ResponseHeaderAccessControlAllowOrigin, origin); } // Section 6.1.3 // If the resource supports credentials, add a single // Access-Control-Allow-Credentials header with the case-sensitive // string "true" as value. if (supportsCredentials) { response.AddHeader(Edu.Stanford.Nlp.Naturalli.Demo.CORSFilter.ResponseHeaderAccessControlAllowCredentials, "true"); } // Section 6.1.4 // If the list of exposed headers is not empty add one or more // Access-Control-Expose-Headers headers, with as values the header // field names given in the list of exposed headers. if ((exposedHeaders != null) && (exposedHeaders.Count > 0)) { string exposedHeadersString = Join(exposedHeaders, ","); response.AddHeader(Edu.Stanford.Nlp.Naturalli.Demo.CORSFilter.ResponseHeaderAccessControlExposeHeaders, exposedHeadersString); } // Forward the request down the filter chain. filterChain.DoFilter(request, response); }
/// <summary>Handles a CORS request that violates specification.</summary> /// <param name="request"> /// The /// <see cref="Javax.Servlet.Http.IHttpServletRequest"/> /// object. /// </param> /// <param name="response"> /// The /// <see cref="Javax.Servlet.Http.IHttpServletResponse"/> /// object. /// </param> /// <param name="filterChain"> /// The /// <see cref="Javax.Servlet.IFilterChain"/> /// object. /// </param> /// <exception cref="System.IO.IOException"/> /// <exception cref="Javax.Servlet.ServletException"/> public void HandleInvalidCORS(IHttpServletRequest request, IHttpServletResponse response, IFilterChain filterChain) { string origin = request.GetHeader(Edu.Stanford.Nlp.Naturalli.Demo.CORSFilter.RequestHeaderOrigin); string method = request.GetMethod(); string accessControlRequestHeaders = request.GetHeader(RequestHeaderAccessControlRequestHeaders); string message = "Invalid CORS request; Origin=" + origin + ";Method=" + method; if (accessControlRequestHeaders != null) { message = message + ";Access-Control-Request-Headers=" + accessControlRequestHeaders; } response.SetContentType("text/plain"); response.SetStatus(HttpServletResponseConstants.ScForbidden); response.ResetBuffer(); Log(message); }
/// <summary>Determines the request type.</summary> /// <param name="request"/> /// <returns/> public CORSFilter.CORSRequestType CheckRequestType(IHttpServletRequest request) { CORSFilter.CORSRequestType requestType = CORSFilter.CORSRequestType.InvalidCors; if (request == null) { throw new ArgumentException("HttpServletRequest object is null"); } string originHeader = request.GetHeader(RequestHeaderOrigin); // Section 6.1.1 and Section 6.2.1 if (originHeader != null) { if (originHeader.IsEmpty()) { requestType = CORSFilter.CORSRequestType.InvalidCors; } else { if (!IsValidOrigin(originHeader)) { requestType = CORSFilter.CORSRequestType.InvalidCors; } else { string method = request.GetMethod(); if (method != null && HttpMethods.Contains(method)) { if ("OPTIONS".Equals(method)) { string accessControlRequestMethodHeader = request.GetHeader(RequestHeaderAccessControlRequestMethod); if (accessControlRequestMethodHeader != null && !accessControlRequestMethodHeader.IsEmpty()) { requestType = CORSFilter.CORSRequestType.PreFlight; } else { if (accessControlRequestMethodHeader != null && accessControlRequestMethodHeader.IsEmpty()) { requestType = CORSFilter.CORSRequestType.InvalidCors; } else { requestType = CORSFilter.CORSRequestType.Actual; } } } else { if ("GET".Equals(method) || "HEAD".Equals(method)) { requestType = CORSFilter.CORSRequestType.Simple; } else { if ("POST".Equals(method)) { string contentType = request.GetContentType(); if (contentType != null) { contentType = contentType.ToLower().Trim(); if (SimpleHttpRequestContentTypeValues.Contains(contentType)) { requestType = CORSFilter.CORSRequestType.Simple; } else { requestType = CORSFilter.CORSRequestType.Actual; } } } else { if (ComplexHttpMethods.Contains(method)) { requestType = CORSFilter.CORSRequestType.Actual; } } } } } } } } else { requestType = CORSFilter.CORSRequestType.NotCors; } return(requestType); }