import ballerina/http;
import ballerina/log;http:Client clientEndpoint = new("http://localhost:9090",
                                 { http1Settings : { chunking: http:CHUNKING_NEVER }});service chunkingSample on new http:Listener(9092) {    @http:ResourceConfig {
        path: "/"
    }
    resource function invokeEndpoint(http:Caller caller, http:Request req) {
        http:Request newReq = new;
        newReq.setPayload({ "name": "Ballerina" });
        var clientResponse = clientEndpoint->post("/echo/", newReq);
        if (clientResponse is http:Response) {
            var result = caller->respond(clientResponse);
            if (result is error) {
               log:printError("Error sending response", err = result);
            }
        } else {
            http:Response errorResponse = new;
            json msg = { "error": "An error occurred while invoking the service." };
            errorResponse.setPayload(msg);
            var response = caller->respond(errorResponse);
            if (response is error) {
               log:printError("Error sending response", err = response);
            }
        }
    }
}
service echo on new http:Listener(9090) {
    @http:ResourceConfig {
        path: "/"
    }
    resource function echoResource(http:Caller caller, http:Request req) {
        string value;        http:Response res = new;
        boolean validationErrorFound = false;
        if (req.hasHeader("content-length")) {
            value = req.getHeader("content-length");
            value = "Length-" + value;
        } else if (req.hasHeader("Transfer-Encoding")) {
            value = req.getHeader("Transfer-Encoding");
            if (value != "chunked" && value != "compress" && value != "deflate"
                && value != "gzip" && value != "identity") {
                res.statusCode = 400;
                res.setPayload("Transfer-Encoding contains invalid data");
                validationErrorFound = true;
            }
        } else {
            value =
                "Neither Transfer-Encoding nor content-length header found";
        }        if (!validationErrorFound) {
            res.setPayload({ "Outbound request content": <@untainted> value });
        }
        var result = caller->respond(res);
        if (result is error) {
           log:printError("Error sending response from echo service",
                        err = result);
        }
    }
}function isValid(boolean|error value) returns boolean {
    if (value is boolean) {
        return value;
    }
    return false;
}

Disable Chunking

This sample demonstrates how to configure the chunking behavior of an HTTP client endpoint. By default, the HTTP client sends messages with the content-length header. If the message size is larger than the buffer size (8K), messages are chunked. Chunking can be disabled using the connector options.

import ballerina/http;
import ballerina/log;

The HTTP client’s chunking behaviour can be configured as CHUNKING_AUTO, CHUNKING_ALWAYS, or CHUNKING_NEVER. In this example, it is set to CHUNKING_NEVER, which means that chunking never happens irrespective of how it is specified in the request. When chunking is set to CHUNKING_AUTO, chunking is done as specified in the request.

http:Client clientEndpoint = new("http://localhost:9090",
                                 { http1Settings : { chunking: http:CHUNKING_NEVER }});
service chunkingSample on new http:Listener(9092) {
    @http:ResourceConfig {
        path: "/"
    }
    resource function invokeEndpoint(http:Caller caller, http:Request req) {
        http:Request newReq = new;
        newReq.setPayload({ "name": "Ballerina" });
        var clientResponse = clientEndpoint->post("/echo/", newReq);
        if (clientResponse is http:Response) {
            var result = caller->respond(clientResponse);
            if (result is error) {
               log:printError("Error sending response", err = result);
            }
        } else {
            http:Response errorResponse = new;
            json msg = { "error": "An error occurred while invoking the service." };
            errorResponse.setPayload(msg);
            var response = caller->respond(errorResponse);
            if (response is error) {
               log:printError("Error sending response", err = response);
            }
        }
    }
}

Create a new outbound request and set the payload.

service echo on new http:Listener(9090) {
    @http:ResourceConfig {
        path: "/"
    }
    resource function echoResource(http:Caller caller, http:Request req) {
        string value;

A sample backend, which responds according to the chunking behaviour.

        http:Response res = new;
        boolean validationErrorFound = false;
        if (req.hasHeader("content-length")) {
            value = req.getHeader("content-length");
            value = "Length-" + value;
        } else if (req.hasHeader("Transfer-Encoding")) {
            value = req.getHeader("Transfer-Encoding");

Set the response according to the request headers.

            if (value != "chunked" && value != "compress" && value != "deflate"
                && value != "gzip" && value != "identity") {
                res.statusCode = 400;
                res.setPayload("Transfer-Encoding contains invalid data");
                validationErrorFound = true;
            }
        } else {
            value =
                "Neither Transfer-Encoding nor content-length header found";
        }

Perform data validation for transfer-encoding.

        if (!validationErrorFound) {
            res.setPayload({ "Outbound request content": <@untainted> value });
        }
        var result = caller->respond(res);
        if (result is error) {
           log:printError("Error sending response from echo service",
                        err = result);
        }
    }
}

Since there is no validation error, mark the value as trusted data and set it to the response.

function isValid(boolean|error value) returns boolean {
    if (value is boolean) {
        return value;
    }
    return false;
}
# To start the services, navigate to the directory that contains the
# `.bal` file and execute the `ballerina run` command.
$ ballerina run http_disable_chunking.bal
# Service deployment
[ballerina/http] started HTTP/WS listener 0.0.0.0:9090
[ballerina/http] started HTTP/WS listener 0.0.0.0:9092
To use the client, execute the below cURL command. 
$ curl http://localhost:9092/chunkingSample
{"Outbound request content":"Length-20"}
To enable chunking, change the chunking option of the `clientEndpoint` in the `.bal` file to `http:CHUNKING_ALWAYS`.
{"Outbound request content":"chunked"}