private void handleRequest(HttpServerRequest request) {
        enableCors(request);

        if (request.version() != HttpVersion.HTTP_1_1) {
            respond(request, HttpStatus.HTTP_VERSION_NOT_SUPPORTED);
            return;
        }

        HttpMethod requestMethod = request.method();
        if (requestMethod == HttpMethod.OPTIONS) {
            // Allow OPTIONS request caching by browser
            request.response().putHeader(HttpHeaders.ACCESS_CONTROL_MAX_AGE, "86400");
            respond(request, HttpStatus.OK);
            return;
        }

        if (!ALLOWED_HTTP_METHODS.contains(requestMethod)) {
            respond(request, HttpStatus.METHOD_NOT_ALLOWED);
            return;
        }

        String contentType = request.getHeader(HttpHeaders.CONTENT_TYPE);
        int contentLength = ProxyUtil.contentLength(request, 1024);
        if (contentType != null && contentType.startsWith("multipart/form-data")) {
            if (contentLength > storage.getMaxUploadedFileSize()) {
                respond(request, HttpStatus.REQUEST_ENTITY_TOO_LARGE, "Request body is too large");
                return;
            }
        } else {
            // not only the case, Content-Length can be missing when Transfer-Encoding: chunked
            if (contentLength > resourceService.getMaxSize()) {
                respond(request, HttpStatus.REQUEST_ENTITY_TOO_LARGE, "Request body is too large");
                return;
            }
        }

        String path = URLDecoder.decode(request.path(), StandardCharsets.UTF_8);
        if (request.method() == HttpMethod.GET && path.equals(HEALTH_CHECK_PATH)) {
            respond(request, HttpStatus.OK);
            return;
        }

        if (request.method() == HttpMethod.GET && path.equals(VERSION_PATH)) {
            respond(request, HttpStatus.OK, version);
            return;
        }

        Config config = configStore.get();
        SpanContext spanContext = Span.current().getSpanContext();
        String traceId = spanContext.getTraceId();
        String spanId = spanContext.getSpanId();

        request.pause();
        Future<AuthorizationResult> authorizationResultFuture = authorizeRequest(request);
        authorizationResultFuture.compose(result -> processAuthorizationResult(result.extractedClaims, config, request, result.apiKeyData, traceId, spanId))
                .onFailure(error -> handleError(error, request))
                .onComplete(ignore -> request.resume());
    }
Called when proxy received the request headers from a client.
server/src/main/java/com/epam/aidial/core/server/Proxy.java