in transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestBodyHandler.java [97:175]
public void handle(RoutingContext context) {
final HttpServerRequest request = context.request();
final HttpServerResponse response = context.response();
if (request.headers().contains(HttpHeaders.UPGRADE, HttpHeaders.WEBSOCKET, true)) {
context.next();
return;
}
Boolean bypass = context.get(BYPASS_BODY_HANDLER);
if (Boolean.TRUE.equals(bypass)) {
context.next();
return;
}
// we need to keep state since we can be called again on reroute
if (!((RoutingContextInternal) context).seenHandler(RoutingContextInternal.BODY_HANDLER)) {
((RoutingContextInternal) context).visitHandler(RoutingContextInternal.BODY_HANDLER);
// Check if a request has a request body.
// A request with a body __must__ either have `transfer-encoding`
// or `content-length` headers set.
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.3
final long parsedContentLength = parseContentLengthHeader(request);
// http2 never transmits a `transfer-encoding` as frames are chunks.
final boolean hasTransferEncoding =
request.version() == HttpVersion.HTTP_2 || request.headers().contains(HttpHeaders.TRANSFER_ENCODING);
if (!hasTransferEncoding && parsedContentLength == -1) {
// there is no "body", so we can skip this handler
context.next();
return;
}
// before parsing the body we can already discard a bad request just by inspecting the content-length against
// the body limit, this will reduce load, on the server by totally skipping parsing the request body
if (bodyLimit != -1 && parsedContentLength != -1) {
if (parsedContentLength > bodyLimit) {
context.fail(413);
return;
}
}
// handle expectations
// https://httpwg.org/specs/rfc7231.html#header.expect
final String expect = request.getHeader(HttpHeaders.EXPECT);
if (expect != null) {
// requirements validation
if (expect.equalsIgnoreCase("100-continue")) {
// A server that receives a 100-continue expectation in an HTTP/1.0 request MUST ignore that expectation.
if (request.version() != HttpVersion.HTTP_1_0) {
// signal the client to continue
response.writeContinue();
}
} else {
// the server cannot meet the expectation, we only know about 100-continue
context.fail(417);
return;
}
}
final BHandler handler = new BHandler(context, isPreallocateBodyBuffer ? parsedContentLength : -1);
boolean ended = request.isEnded();
if (!ended) {
request
// resume the request (if paused)
.handler(handler)
.endHandler(handler::end)
.resume();
}
} else {
// on reroute we need to re-merge the form params if that was desired
if (mergeFormAttributes && request.isExpectMultipart()) {
request.params().addAll(request.formAttributes());
}
context.next();
}
}