Convert HttpRequestBase to Curl for Quick Performance Testing

This article explains how to transform a Java HttpRequestBase object into an equivalent curl command, enabling rapid request replay across servers and detailed timing analysis, and demonstrates the process with step‑by‑step code examples and a functional test using the FunTester framework.

FunTester
FunTester
FunTester
Convert HttpRequestBase to Curl for Quick Performance Testing

This article provides a utility that converts an HttpRequestBase instance back into a curl command. The conversion enables rapid replay of the same request on different servers and exposes detailed HTTP timing metrics.

Step 1 – Initialise FunRequest from HttpRequestBase

static FunRequest initFromRequest(HttpRequestBase base) {
    FunRequest request = null;
    String method = base.getMethod();
    RequestType requestType = RequestType.getRequestType(method);
    String uri = base.getURI().toString();
    List<Header> headers = Arrays.asList(base.getAllHeaders());
    if (requestType == RequestType.GET) {
        request = isGet().setUri(uri).addHeaders(headers);
    } else if (requestType == RequestType.POST) {
        HttpPost post = (HttpPost) base;
        HttpEntity entity = post.getEntity();
        String contentType = entity.getContentType().getValue();
        String content = null;
        try {
            content = EntityUtils.toString(entity);
        } catch (IOException e) {
            logger.error("Failed to parse response", e);
            fail();
        }
        if (contentType.equalsIgnoreCase(HttpClientConstant.ContentType_TEXT.getValue()) ||
            contentType.equalsIgnoreCase(HttpClientConstant.ContentType_JSON.getValue())) {
            request = isPost().setUri(uri).addHeaders(headers).addJson(JSONObject.parseObject(content));
        } else if (contentType.equalsIgnoreCase(HttpClientConstant.ContentType_FORM.getValue())) {
            request = isPost().setUri(uri).addHeaders(headers).addParams(getJson(content.split("&")));
        }
    } else {
        RequestException.fail("Unsupported request type!");
    }
    return request;
}

The method extracts the HTTP method, URI, and all headers from the original HttpRequestBase. For GET requests it creates a FunRequest with the URI and headers. For POST requests it reads the request body, determines the content type, and populates either a JSON payload ( addJson) or form parameters ( addParams). Unsupported methods raise an exception.

Step 2 – Build the curl command

String toCurl() {
    StringBuffer curl = new StringBuffer(
        "curl -w HTTPcode%{http_code}:代理返回code%{http_connect}:数据类型%{content_type}:DNS解析时间%{time_namelookup}:%{time_redirect}:连接建立完成时间%{time_pretransfer}:连接时间%{time_connect}:开始传输时间%{time_starttransfer}:总时间%{time_total}:下载速度%{speed_download}:speed_upload%{speed_upload} ");
    if (requestType == RequestType.GET) curl << " -G";
    headers.forEach(h -> curl << " -H '" + h.getName() + ":" + h.getValue().replace(SPACE_1, EMPTY) + "'");
    switch (requestType) {
        case GET:
            args.forEach((k, v) -> curl << " -d '" + k + "=" + v + "'");
            break;
        case POST:
            if (!params.isEmpty()) {
                curl << " -H Content-Type:application/x-www-form-urlencoded";
                params.forEach((k, v) -> curl << " -F '" + k + "=" + v + "'");
            }
            if (!json.isEmpty()) {
                curl << " -H \"Content-Type:application/json\"";
                json.forEach((k, v) -> curl << " -d '" + k + "=" + v + "'");
            }
            break;
        default:
            break;
    }
    curl << " " + uri;
    return curl.toString();
}

The command starts with curl -w and a custom format string that prints a series of timing metrics after the request finishes, such as HTTP status code, DNS lookup time, connection time, time to first byte, total time, download speed, and upload speed. The method then appends: -G for GET requests.

All request headers using -H.

Query parameters for GET ( -d).

Form fields for POST ( -F) with the appropriate Content-Type.

JSON payload for POST ( -d) with Content-Type: application/json.

The target URI.

Test Service Code (using Moco API)

public static void main(String[] args) {
    def server = getServer(getLogMonitor("1.log"));
    server.get(urlOnly("/test")).response(obRes(Result.success(getJson("324324=32432"))));
    server.post(and(urlOnly("/post"), eqForm("a", "a"))).response(textRes("234"));
    server.response(MocoResponse.textRes("hello word"));
    def run = run(server);
    waitForKey("fan");
    run.stop();
}

The mock server defines two endpoints: GET /test returns a JSON payload. POST /post expects a form field a=a and returns the plain text 234.

Test Result

The generated curl command printed to the console is:

curl -w HTTPcode%{http_code}:代理返回code%{http_connect}:数据类型%{content_type}:DNS解析时间%{time_namelookup}:%{time_redirect}:连接建立完成时间%{time_pretransfer}:连接时间%{time_connect}:开始传输时间%{time_starttransfer}:总时间%{time_total}:下载速度%{speed_download}:speed_upload%{speed_upload} -H 'Content-Type:application/x-www-form-urlencoded;charset=UTF-8' -H 'X-Requested-With:XMLHttpRequest' -H 'User-Agent:Mozilla/5.0(Macintosh;IntelMacOSX10_14_4)AppleWebKit/537.36(KHTML,likeGecko)Chrome/74.0.3729.108Safari/537.36' -H 'Connection:keep-alive' -H Content-Type:application/x-www-form-urlencoded -F 'a=a' http://localhost:12345/post

The mock service responds with 234, confirming that the conversion from HttpRequestBase to curl works correctly and that the timing placeholders are ready to be populated by curl after execution.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendJavaPerformance TestingHTTPcURLFunTester
FunTester
Written by

FunTester

10k followers, 1k articles | completely useless

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.