Java Code Examples for io.undertow.server.HttpServerExchange#getRequestHeaders()

The following examples show how to use io.undertow.server.HttpServerExchange#getRequestHeaders() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: RequestHeaderAttribute.java    From quarkus-http with Apache License 2.0 6 votes vote down vote up
@Override
public String readAttribute(final HttpServerExchange exchange) {
    List<String> header = exchange.getRequestHeaders(requestHeader);
    if (header.isEmpty()) {
        return null;
    } else if (header.size() == 1) {
        return header.get(0);
    }
    StringBuilder sb = new StringBuilder();
    sb.append("[");
    for (int i = 0; i < header.size(); ++i) {
        if (i != 0) {
            sb.append(", ");
        }
        sb.append(header.get(i));
    }
    sb.append("]");
    return sb.toString();
}
 
Example 2
Source File: CorsHttpHandler.java    From wildfly-core with GNU Lesser General Public License v2.1 6 votes vote down vote up
private void setCorsResponseHeaders(HttpServerExchange exchange) throws Exception {
    HeaderMap headers = exchange.getRequestHeaders();
    if (headers.contains(Headers.ORIGIN)) {
        if(matchOrigin(exchange, allowedOrigins) != null) {
            exchange.getResponseHeaders().addAll(ACCESS_CONTROL_ALLOW_ORIGIN, headers.get(Headers.ORIGIN));
            exchange.getResponseHeaders().add(Headers.VARY, Headers.ORIGIN_STRING);
        }
    }
    HeaderValues requestedMethods = headers.get(ACCESS_CONTROL_REQUEST_METHOD);
    if (requestedMethods != null && !requestedMethods.isEmpty()) {
        exchange.getResponseHeaders().addAll(ACCESS_CONTROL_ALLOW_METHODS, requestedMethods);
    } else {
        exchange.getResponseHeaders().addAll(ACCESS_CONTROL_ALLOW_METHODS, Arrays.asList(new String[]{Methods.GET_STRING, Methods.POST_STRING}));
    }
    HeaderValues requestedHeaders = headers.get(ACCESS_CONTROL_REQUEST_HEADERS);
    if (requestedHeaders != null && !requestedHeaders.isEmpty()) {
        exchange.getResponseHeaders().addAll(ACCESS_CONTROL_ALLOW_HEADERS, requestedHeaders);
    } else {
        exchange.getResponseHeaders().add(ACCESS_CONTROL_ALLOW_HEADERS, Headers.CONTENT_TYPE_STRING);
        exchange.getResponseHeaders().add(ACCESS_CONTROL_ALLOW_HEADERS, Headers.WWW_AUTHENTICATE_STRING);
        exchange.getResponseHeaders().add(ACCESS_CONTROL_ALLOW_HEADERS, Headers.AUTHORIZATION_STRING);
    }
    exchange.getResponseHeaders().add(ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
    exchange.getResponseHeaders().add(ACCESS_CONTROL_MAX_AGE, ONE_HOUR_IN_SECONDS);
}
 
Example 3
Source File: RequestTimeLogger.java    From hawkular-metrics with Apache License 2.0 6 votes vote down vote up
@Override
public void exchangeEvent(HttpServerExchange exchange, NextListener nextListener) {
    try {
        long end = System.currentTimeMillis();
        long duration = end - start;
        if (duration > this.timeThreshold) {
            String method = exchange.getRequestMethod().toString();
            String query = exchange.getQueryString();
            String request_url = exchange.getRequestURI() + (query.isEmpty() ? "" : ("?" + query));
            HeaderMap headers = exchange.getRequestHeaders();
            if (headers.contains(tenantHeader)) {
                String tenantId = headers.get(tenantHeader, 0);
                log.warnf("Request %s %s took: %d ms, exceeds %d ms threshold, tenant-id: %s",
                        method, request_url, duration, timeThreshold, tenantId);
            } else {
                log.warnf("Request %s %s took: %d ms, exceeds %d ms threshold, no tenant",
                        method, request_url, duration, timeThreshold);
            }

        }
    } finally {
        if (nextListener != null) {
            nextListener.proceed();
        }
    }
}
 
Example 4
Source File: CorsHandler.java    From pivotal-bank-demo with Apache License 2.0 6 votes vote down vote up
/** Statically allows headers used by the api */
void handlePreflight(HttpServerExchange exchange) {
  HeaderMap requestHeaders = exchange.getRequestHeaders();
  String origin = requestHeaders.getFirst(ORIGIN);
  String method = requestHeaders.getFirst(ACCESS_CONTROL_REQUEST_METHOD);
  String requestedHeaders = requestHeaders.getFirst(ACCESS_CONTROL_REQUEST_HEADERS);
  HeaderMap responseHeaders = exchange.getResponseHeaders();

  responseHeaders.put(VARY,
    "origin,access-control-request-method,access-control-request-headers");
  if (
    ("POST".equals(method) || "GET".equals(method))
      && requestedHeadersAllowed(requestedHeaders)
      && setOrigin(origin, responseHeaders)
    ) {
    responseHeaders.put(ACCESS_CONTROL_ALLOW_METHODS, method);
    if (requestedHeaders != null) {
      responseHeaders.put(ACCESS_CONTROL_ALLOW_HEADERS, requestedHeaders);
    }
  }
}
 
Example 5
Source File: DatawaveAuthenticationMechanism.java    From datawave with Apache License 2.0 5 votes vote down vote up
private void addTimingRequestHeaders(HttpServerExchange exchange) {
    long requestStartTime = exchange.getRequestStartTime();
    long loginTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - requestStartTime);
    HeaderMap headers = exchange.getRequestHeaders();
    headers.add(HEADER_START_TIME, requestStartTime);
    headers.add(HEADER_LOGIN_TIME, loginTime);
}
 
Example 6
Source File: HttpTraceHandler.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
@Override
public void handleRequest(final HttpServerExchange exchange) throws Exception {
    if(exchange.getRequestMethod().equals(Methods.TRACE)) {
        exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "message/http");
        StringBuilder body = new StringBuilder("TRACE ");
        body.append(exchange.getRequestURI());
        if(!exchange.getQueryString().isEmpty()) {
            body.append('?');
            body.append(exchange.getQueryString());
        }
        body.append(' ');
        body.append(exchange.getProtocol().toString());
        body.append("\r\n");
        for(HeaderValues header : exchange.getRequestHeaders()) {
            for(String value : header) {
                body.append(header.getHeaderName());
                body.append(": ");
                body.append(value);
                body.append("\r\n");
            }
        }
        body.append("\r\n");
        exchange.getResponseSender().send(body.toString());
    } else {
        handler.handleRequest(exchange);
    }
}
 
Example 7
Source File: SSLHeaderHandler.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
    HeaderMap requestHeaders = exchange.getRequestHeaders();
    final String sessionId = requestHeaders.getFirst(SSL_SESSION_ID);
    final String cipher = requestHeaders.getFirst(SSL_CIPHER);
    String clientCert = requestHeaders.getFirst(SSL_CLIENT_CERT);
    //the proxy client replaces \n with ' '
    if (clientCert != null && clientCert.length() > 28) {
        StringBuilder sb = new StringBuilder(clientCert.length() + 1);
        sb.append(Certificates.BEGIN_CERT);
        sb.append('\n');
        sb.append(clientCert.replace(' ', '\n').substring(28, clientCert.length() - 26));//core certificate data
        sb.append('\n');
        sb.append(Certificates.END_CERT);
        clientCert = sb.toString();
    }
    if (clientCert != null || sessionId != null || cipher != null) {
        try {
            SSLSessionInfo info = new BasicSSLSessionInfo(sessionId, cipher, clientCert);
            exchange.setRequestScheme(HTTPS);
            exchange.getConnection().setSslSessionInfo(info);
            exchange.addExchangeCompleteListener(CLEAR_SSL_LISTENER);
        } catch (java.security.cert.CertificateException | CertificateException e) {
            UndertowLogger.REQUEST_LOGGER.debugf(e, "Could not create certificate from header %s", clientCert);
        }
    }
    next.handleRequest(exchange);
}
 
Example 8
Source File: HttpContinue.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Returns true if this exchange requires the server to send a 100 (Continue) response.
 *
 * @param exchange The exchange
 * @return <code>true</code> if the server needs to send a continue response
 */
public static boolean requiresContinueResponse(final HttpServerExchange exchange) {
    if (!COMPATIBLE_PROTOCOLS.contains(exchange.getProtocol()) || exchange.isResponseStarted() || !exchange.getConnection().isContinueResponseSupported() || exchange.getAttachment(ALREADY_SENT) != null) {
        return false;
    }

    HeaderMap requestHeaders = exchange.getRequestHeaders();
    return requiresContinueResponse(requestHeaders);
}
 
Example 9
Source File: RestHandler.java    From light with Apache License 2.0 5 votes vote down vote up
private String getIpAddress(HttpServerExchange exchange) {
    String ipAddress = null;
    HeaderMap headerMap = exchange.getRequestHeaders();
    ipAddress = headerMap.getFirst(Headers.X_FORWARDED_FOR_STRING);
    if(ipAddress == null) {
        //logger.debug("could not get ip address from x forward for, try sourceAddress in exchange");
        ipAddress = exchange.getSourceAddress().getAddress().getHostAddress();
    }
    //logger.debug("ip = {}", ipAddress);
    return ipAddress;
}
 
Example 10
Source File: SavedRequest.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
public static void trySaveRequest(final HttpServerExchange exchange, final byte[] buffer, int length) {
    int maxSize = exchange.getConnection().getUndertowOptions().get(UndertowOptions.MAX_BUFFERED_REQUEST_SIZE, UndertowOptions.DEFAULT_MAX_BUFFERED_REQUEST_SIZE);
    if (maxSize > 0) {
        if (length > maxSize) {
            UndertowLogger.REQUEST_LOGGER.debugf("Request to %s was to large to save", exchange.getRequestURI());
            return;//failed to save the request, we just return
        }
        //TODO: we should really be used pooled buffers
        //TODO: we should probably limit the number of saved requests at any given time
        HeaderMap headers = new HeaderMap();
        for (HeaderValues entry : exchange.getRequestHeaders()) {
            if (entry.getHeaderName().equals(Headers.CONTENT_LENGTH) ||
                    entry.getHeaderName().equals(Headers.TRANSFER_ENCODING) ||
                    entry.getHeaderName().equals(Headers.CONNECTION)) {
                continue;
            }
            headers.putAll(entry.getHeaderName(), entry);
        }
        SavedRequest request = new SavedRequest(buffer, length, exchange.getRequestMethod(), exchange.getRelativePath(), exchange.getRequestHeaders());
        final ServletRequestContext sc = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
        HttpSessionImpl session = sc.getCurrentServletContext().getSession(exchange, true);
        Session underlyingSession;
        if (System.getSecurityManager() == null) {
            underlyingSession = session.getSession();
        } else {
            underlyingSession = AccessController.doPrivileged(new HttpSessionImpl.UnwrapSessionAction(session));
        }
        underlyingSession.setAttribute(SESSION_KEY, request);
    }
}
 
Example 11
Source File: RequestUtils.java    From mangooio with Apache License 2.0 5 votes vote down vote up
/**
 * Checks if the requests content-type contains application/json
 *
 * @param exchange The Undertow HttpServerExchange
 * @return True if the request content-type contains application/json, false otherwise
 */
public static boolean isJsonRequest(HttpServerExchange exchange) {
    Objects.requireNonNull(exchange, Required.HTTP_SERVER_EXCHANGE.toString());

    final HeaderMap headerMap = exchange.getRequestHeaders();
    return headerMap != null && headerMap.get(Header.CONTENT_TYPE.toHttpString()) != null &&
            headerMap.get(Header.CONTENT_TYPE.toHttpString()).element().toLowerCase(Locale.ENGLISH).contains(MediaType.JSON_UTF_8.withoutParameters().toString());
}
 
Example 12
Source File: DomainApiCheckHandler.java    From wildfly-core with GNU Lesser General Public License v2.1 5 votes vote down vote up
private boolean commonChecks(HttpServerExchange exchange) throws Exception {
    // AS7-2284 If we are starting or stopping the web console won't be available, tell caller the service is unavailable and to try again
    // later. If "stopping" it's either a reload, in which case trying again will eventually succeed,
    // or it's a true process stop eventually the server will have stopped.
    if (!consoleAvailability.isAvailable()) {
        exchange.getResponseHeaders().add(Headers.RETRY_AFTER, "2"); //  2 secs is just a guesstimate
        Common.SERVICE_UNAVAIABLE.handleRequest(exchange);
        return false;
    }

    /*
     * Completely disallow OPTIONS - if the browser suspects this is a cross site request just reject it.
     */
    final HttpString requestMethod = exchange.getRequestMethod();
    if (!Methods.POST.equals(requestMethod) && !Methods.GET.equals(requestMethod)) {
        if (Methods.OPTIONS.equals(requestMethod)) {
            ROOT_LOGGER.debug("Request rejected due to 'OPTIONS' method which is not supported.");
        } else {
            ROOT_LOGGER.debug("Request rejected as method not one of (GET,POST).");
        }
        Common.METHOD_NOT_ALLOWED_HANDLER.handleRequest(exchange);
        return false;
    }

    /*
     *  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 HeaderMap headers = exchange.getRequestHeaders();
    if (headers.contains(Headers.ORIGIN)) {
       return matchOrigin(exchange, allowedOrigins) != null;
    }
    return true;
}
 
Example 13
Source File: RequestParser.java    From core-ng-project with Apache License 2.0 5 votes vote down vote up
public void parse(RequestImpl request, HttpServerExchange exchange, ActionLog actionLog) throws Throwable {
    HeaderMap headers = exchange.getRequestHeaders();

    request.scheme = scheme(exchange.getRequestScheme(), headers.getFirst(Headers.X_FORWARDED_PROTO));
    request.hostName = hostName(exchange.getHostName(), headers.getFirst(Headers.X_FORWARDED_HOST));
    int requestPort = requestPort(headers.getFirst(Headers.HOST), request.scheme, exchange);
    request.port = port(requestPort, headers.getFirst(Headers.X_FORWARDED_PORT));

    String method = exchange.getRequestMethod().toString();
    actionLog.context("method", method);

    request.requestURL = requestURL(request, exchange);
    actionLog.context("request_url", request.requestURL);

    logHeaders(headers);
    parseClientIP(request, exchange, actionLog, headers.getFirst(Headers.X_FORWARDED_FOR)); // parse client ip after logging header, as ip in x-forwarded-for may be invalid
    parseCookies(request, exchange);

    request.method = httpMethod(method);    // parse method after logging header/etc, to gather more info in case we see unsupported method passed from internet

    logSiteHeaders(headers, actionLog);

    parseQueryParams(request, exchange.getQueryParameters());

    if (withBodyMethods.contains(request.method)) {
        String contentType = headers.getFirst(Headers.CONTENT_TYPE);
        request.contentType = contentType == null ? null : ContentType.parse(contentType);
        parseBody(request, exchange);
    }
}
 
Example 14
Source File: OriginHandler.java    From quarkus-http with Apache License 2.0 5 votes vote down vote up
@Override
public void handleRequest(final HttpServerExchange exchange) throws Exception {
    final List<String> origin = exchange.getRequestHeaders(HttpHeaderNames.ORIGIN);
    if (origin == null) {
        if (requireOriginHeader) {
            //TODO: Is 403 (Forbidden) the best response code
            if (UndertowLogger.REQUEST_LOGGER.isDebugEnabled()) {
                UndertowLogger.REQUEST_LOGGER.debugf("Refusing request for %s due to lack of Origin: header", exchange.getRequestPath());
            }
            originFailedHandler.handleRequest(exchange);
            return;
        }
    } else {
        boolean found = false;
        final boolean requireAllOrigins = this.requireAllOrigins;
        for (final String header : origin) {
            if (allowedOrigins.contains(header)) {
                found = true;
                if (!requireAllOrigins) {
                    break;
                }
            } else if (requireAllOrigins) {
                if (UndertowLogger.REQUEST_LOGGER.isDebugEnabled()) {
                    UndertowLogger.REQUEST_LOGGER.debugf("Refusing request for %s due to Origin %s not being in the allowed origins list", exchange.getRequestPath(), header);
                }
                originFailedHandler.handleRequest(exchange);
                return;
            }
        }
        if (!found) {
            if (UndertowLogger.REQUEST_LOGGER.isDebugEnabled()) {
                UndertowLogger.REQUEST_LOGGER.debugf("Refusing request for %s as none of the specified origins %s were in the allowed origins list", exchange.getRequestPath(), origin);
            }
            originFailedHandler.handleRequest(exchange);
            return;
        }
    }
    next.handleRequest(exchange);
}
 
Example 15
Source File: HTTPErrorHandler.java    From core-ng-project with Apache License 2.0 5 votes vote down vote up
private Response defaultErrorResponse(Throwable e, HttpServerExchange exchange, ActionLog actionLog) {
    HTTPStatus status = httpStatus(e);

    HeaderMap headers = exchange.getRequestHeaders();
    String accept = headers.getFirst(Headers.ACCEPT);

    if (accept != null && accept.contains(ContentType.APPLICATION_JSON.mediaType)) {
        String userAgent = headers.getFirst(Headers.USER_AGENT);
        return Response.bean(errorResponse(e, userAgent, actionLog.id)).status(status);
    } else {
        return Response.text(errorHTML(e, actionLog.id)).status(status).contentType(ContentType.TEXT_HTML);
    }
}
 
Example 16
Source File: SanitizerHandler.java    From light-4j with Apache License 2.0 5 votes vote down vote up
@Override
public void handleRequest(final HttpServerExchange exchange) throws Exception {
    String method = exchange.getRequestMethod().toString();
    if (config.isSanitizeHeader()) {
        HeaderMap headerMap = exchange.getRequestHeaders();
        if (headerMap != null) {
            for (HeaderValues values : headerMap) {
                if (values != null) {
                    ListIterator<String> itValues = values.listIterator();
                    while (itValues.hasNext()) {
                        itValues.set(encoding.applyEncoding(itValues.next()));
                    }
                }
            }
        }
    }

    if (config.isSanitizeBody() && ("POST".equalsIgnoreCase(method) || "PUT".equalsIgnoreCase(method) || "PATCH".equalsIgnoreCase(method))) {
        // assume that body parser is installed before this middleware and body is parsed as a map.
        // we are talking about JSON api now.
        Object body = exchange.getAttachment(BodyHandler.REQUEST_BODY);
        if (body != null) {
            if(body instanceof List) {
                encoding.encodeList((List<Map<String, Object>>)body);
            } else {
                // assume it is a map here.
                encoding.encodeNode((Map<String, Object>)body);
            }
        }
    }
    Handler.next(exchange, next);
}
 
Example 17
Source File: JaegerHandler.java    From light-4j with Apache License 2.0 4 votes vote down vote up
/**
 * Extract the context, start and stop the span here.
 *
 * @param exchange HttpServerExchange
 * @throws Exception Exception
 */
@Override
public void handleRequest(final HttpServerExchange exchange) throws Exception {
    // get the path and method to construct the endpoint for the operation of tracing.
    Map<String, Object> auditInfo = exchange.getAttachment(AttachmentConstants.AUDIT_INFO);
    String endpoint = null;
    if(auditInfo != null) {
        endpoint = (String)auditInfo.get(Constants.ENDPOINT_STRING);
    } else {
        endpoint = exchange.getRequestPath() + "@" + exchange.getRequestMethod();
    }

    HeaderMap headerMap = exchange.getRequestHeaders();
    final HashMap<String, String> headers = new HashMap<>();
    for(HttpString key : headerMap.getHeaderNames()) {
        headers.put(key.toString(), headerMap.getFirst(key));
    }
    TextMap carrier = new TextMapAdapter(headers);

    // start the server span.
    Tracer.SpanBuilder spanBuilder;
    try {
        SpanContext parentSpanCtx = tracer.extract(Format.Builtin.HTTP_HEADERS, carrier);
        if (parentSpanCtx == null) {
            spanBuilder = tracer.buildSpan(endpoint);
        } else {
            spanBuilder = tracer.buildSpan(endpoint).asChildOf(parentSpanCtx);
        }
    } catch (IllegalArgumentException e) {
        spanBuilder = tracer.buildSpan(endpoint);
    }
    Span rootSpan = spanBuilder
            .withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_SERVER)
            .withTag(Tags.PEER_HOSTNAME.getKey(), NetUtils.getLocalAddressByDatagram())
            .withTag(Tags.PEER_PORT.getKey(), Server.config.getHttpsPort())
            .start();
    tracer.activateSpan(rootSpan);
    // This can be retrieved in the business handler to add tags and logs for tracing.
    exchange.putAttachment(ROOT_SPAN, rootSpan);
    // The client module can use this to inject tracer.
    exchange.putAttachment(EXCHANGE_TRACER, tracer);

    // add an exchange complete listener to close the Root Span for the request.
    exchange.addExchangeCompleteListener((exchange1, nextListener) -> {
        Span span = exchange1.getAttachment(ROOT_SPAN);
        if(span != null) {
            span.finish();
        }
        nextListener.proceed();
    });

    Handler.next(exchange, next);
}
 
Example 18
Source File: UndertowServerHttpRequest.java    From spring-analysis-note with MIT License 4 votes vote down vote up
private static HttpHeaders initHeaders(HttpServerExchange exchange) {
	return new HttpHeaders(new UndertowHeadersAdapter(exchange.getRequestHeaders()));
}
 
Example 19
Source File: CorsHandler.java    From pivotal-bank-demo with Apache License 2.0 4 votes vote down vote up
private static boolean isPreflightRequest(HttpServerExchange exchange) {
  HeaderMap headers = exchange.getRequestHeaders();
  return exchange.getRequestMethod().equals(OPTIONS) &&
    headers.contains(ORIGIN) && headers.contains(ACCESS_CONTROL_REQUEST_METHOD);
}
 
Example 20
Source File: GSSAPIAuthenticationMechanism.java    From quarkus-http with Apache License 2.0 4 votes vote down vote up
@Override
public AuthenticationMechanismOutcome authenticate(final HttpServerExchange exchange,
                                                   final SecurityContext securityContext) {
    NegotiationContext negContext = exchange.getAttachment(NegotiationContext.ATTACHMENT_KEY);
    if (negContext != null) {

        UndertowLogger.SECURITY_LOGGER.debugf("Existing negotiation context found for %s", exchange);
        exchange.putAttachment(NegotiationContext.ATTACHMENT_KEY, negContext);
        if (negContext.isEstablished()) {
            IdentityManager identityManager = getIdentityManager(securityContext);
            final Account account = identityManager.verify(new GSSContextCredential(negContext.getGssContext()));
            if (account != null) {
                securityContext.authenticationComplete(account, name, false);
                UndertowLogger.SECURITY_LOGGER.debugf("Authenticated as user %s with existing GSSAPI negotiation context for %s", account.getPrincipal().getName(), exchange);
                return AuthenticationMechanismOutcome.AUTHENTICATED;
            } else {
                UndertowLogger.SECURITY_LOGGER.debugf("Failed to authenticate with existing GSSAPI negotiation context for %s", exchange);
                return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
            }
        }
    }

    List<String> authHeaders = exchange.getRequestHeaders(AUTHORIZATION);
    if (authHeaders != null) {
        for (String current : authHeaders) {
            if (current.startsWith(NEGOTIATE_PREFIX)) {
                String base64Challenge = current.substring(NEGOTIATE_PREFIX.length());
                try {
                    ByteBuf challenge = FlexBase64.decode(base64Challenge);
                    return runGSSAPI(exchange, challenge, securityContext);
                } catch (IOException e) {
                }

                // By this point we had a header we should have been able to verify but for some reason
                // it was not correctly structured.
                return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
            }
        }
    }

    // No suitable header was found so authentication was not even attempted.
    return AuthenticationMechanismOutcome.NOT_ATTEMPTED;
}