/**
   * Handles a operation request via HTTP.
   *
   * @param http The HttpExchange object that allows access to the request and response.
   * @throws IOException if an error occurs while attempting to process the request.
   */
  private void processRequest(final HttpExchange http) throws IOException {
    final URI request = http.getRequestURI();
    final String requestMethod = http.getRequestMethod();

    boolean isGet = GET.equals(requestMethod);
    if (!isGet && !POST.equals(requestMethod)) {
      http.sendResponseHeaders(METHOD_NOT_ALLOWED, -1);

      return;
    }

    ModelNode dmr;
    ModelNode response;
    int status = OK;

    Headers requestHeaders = http.getRequestHeaders();
    boolean encode =
        APPLICATION_DMR_ENCODED.equals(requestHeaders.getFirst(ACCEPT))
            || APPLICATION_DMR_ENCODED.equals(requestHeaders.getFirst(CONTENT_TYPE));

    try {
      dmr = isGet ? convertGetRequest(request) : convertPostRequest(http.getRequestBody(), encode);
    } catch (IllegalArgumentException iae) {
      ROOT_LOGGER.debugf("Unable to construct ModelNode '%s'", iae.getMessage());
      http.sendResponseHeaders(INTERNAL_SERVER_ERROR, -1);

      return;
    }

    try {
      response = modelController.execute(new OperationBuilder(dmr).build());
    } catch (Throwable t) {
      ROOT_LOGGER.modelRequestError(t);
      http.sendResponseHeaders(INTERNAL_SERVER_ERROR, -1);

      return;
    }

    if (response.hasDefined(OUTCOME) && FAILED.equals(response.get(OUTCOME).asString())) {
      status = INTERNAL_SERVER_ERROR;
    }

    boolean pretty = dmr.hasDefined("json.pretty") && dmr.get("json.pretty").asBoolean();
    writeResponse(http, isGet, pretty, response, status, encode);
  }
  public void handle(HttpExchange http) throws IOException {
    /**
     * Request Verification - before the request is handled a set of checks are performed for CSRF
     * and XSS
     */

    /*
     * Completely disallow OPTIONS - if the browser suspects this is a cross site request just reject it.
     */
    final String requestMethod = http.getRequestMethod();
    if (OPTIONS.equals(requestMethod)) {
      drain(http);
      http.sendResponseHeaders(METHOD_NOT_ALLOWED, -1);

      return;
    }

    /*
     *  Origin check, if it is set the Origin header should match the Host otherwise reject the request.
     *
     *  This check is for cross site scripted GET and POST requests.
     */
    final Headers headers = http.getRequestHeaders();
    final URI request = http.getRequestURI();
    if (headers.containsKey(ORIGIN)) {
      String origin = headers.getFirst(ORIGIN);
      String host = headers.getFirst(HOST);
      String protocol = http.getHttpContext().getServer() instanceof HttpServer ? HTTP : HTTPS;
      String allowedOrigin = protocol + "://" + host;

      // This will reject multi-origin Origin headers due to the exact match.
      if (origin.equals(allowedOrigin) == false) {
        drain(http);
        http.sendResponseHeaders(FORBIDDEN, -1);

        return;
      }
    }

    /*
     *  Cross Site Request Forgery makes use of a specially constructed form to pass in what appears to be
     *  a valid operation request - except for upload requests any inbound requests where the Content-Type
     *  is not application/json or application/dmr-encoded will be rejected.
     */

    final boolean uploadRequest = UPLOAD_REQUEST.equals(request.getPath());
    if (POST.equals(requestMethod)) {
      if (uploadRequest) {
        // This type of request doesn't need the content type check.
        processUploadRequest(http);

        return;
      }

      String contentType = extractContentType(headers.getFirst(CONTENT_TYPE));
      if (!(APPLICATION_JSON.equals(contentType) || APPLICATION_DMR_ENCODED.equals(contentType))) {
        drain(http);
        http.sendResponseHeaders(FORBIDDEN, -1);

        return;
      }
    }

    processRequest(http);
  }