org.apache.hc.core5.http.NoHttpResponseException from automation framework / script

898 views
Skip to first unread message

Adam Lock

unread,
May 18, 2023, 5:57:15 PM5/18/23
to OWASP ZAP User Group
Hi all,

I'm writing an automation framework script that uses an authentication (Oracle Nashorn) script to get a token from a service that is set later on for other stages. It does so by constructing an HttpMessage with some POST data of JSON that is sent to a service that returns the token..

Unfortunately when I call using the code snippet below, I get an error org.apache.hc.core5.http.NoHttpResponseException

[pcp-as-login.js] Sending request "{"email":"myemail.com","password":"PasswordXX"}" to "https://private.service/api/session/token" for bearer token
[pcp-as-login.js] Body =  {"email":" myemail .com","password":" PasswordXX"}
[pcp-as-login.js] Sending request now...
[pcp-as-login.js] Error from sending request - org.apache.hc.core5.http.NoHttpResponseException: private.service:443 failed to respond

I have found that if I comment out the lines where I set the request body (denoted with xxx) that it actually talks with the service and the service yields an error, because the payload was invalid, but at least it responds. I can also call the service just fine through postman with the same payload. Therefore I think it is something to do with the act of setting the body on the message in the code which breaks and causes the NoHttpResponseException. I cannot see any way to capture the traffic so I don't know what is wrong other than it throws an exception.

I'm at my wits end with this. Does anyone know what I might be doing wrong?

Adam

      var payload = JSON.stringify({
        email: username,
        password: password,
      });

      var url =
        "https://private." +
        environment +
        "/api/accesssessionservice/session/token";
      logger(
        'Sending request "' + payload + '" to "' + url + '" for bearer token'
      );

      var requestUri = new URI(url, false);
      var requestHeader = new HttpRequestHeader(
        HttpRequestHeader.POST,
        requestUri,
        HttpHeader.HTTP11
      );
      requestHeader.addHeader(HttpHeader.CONTENT_TYPE, "application/json");
      requestHeader.addHeader("Accept", "application/json");

      var msg = helper.prepareMessage();
      msg.setRequestHeader(requestHeader);
      var bytes = payload.getBytes();
      msg.getRequestBody().setContent(bytes); //xxx
      msg.getRequestBody().setLength(bytes.length); //xxx
      logger("Body =  " + msg.getRequestBody().toString());


kingthorin+owaspzap

unread,
May 18, 2023, 6:14:25 PM5/18/23
to OWASP ZAP User Group
try msg.setRequestBody(payload);

Adam Lock

unread,
May 18, 2023, 6:23:41 PM5/18/23
to OWASP ZAP User Group
Same thing happens

Adam Lock

unread,
May 18, 2023, 6:32:41 PM5/18/23
to OWASP ZAP User Group
I think I have a workaround which is not to use the helper or HttpMessage, but instead just call the built-in HTTP code in Java - this code below works. There is something clearly going wrong when I use the Zap Http classes for the same.



function xxx(urlString, username, password) {
    var URL = Java.type('java.net.URL');
    var HttpURLConnection = Java.type('java.net.HttpURLConnection');
    var InputStreamReader = Java.type('java.io.InputStreamReader');
    var BufferedReader = Java.type('java.io.BufferedReader');
    var OutputStreamWriter = Java.type('java.io.OutputStreamWriter');
   
    // Define the URL and JSON payload
    var jsonPayload = {
      email: username,
      password: password
    };
   
    // Convert JSON payload to a string
    var payloadString = JSON.stringify(jsonPayload);
   
    // Create the URL object
    var url = new URL(urlString);
   
    logger("Sending request");

    // Open a connection to the URL
    var connection = url.openConnection();
    connection.setRequestMethod("POST");
    connection.setRequestProperty("Content-Type", "application/json");
    connection.setDoOutput(true);
   
    // Write the payload to the connection's output stream
    var outputStream = connection.getOutputStream();
    var writer = new OutputStreamWriter(outputStream);
    writer.write(payloadString);
    writer.flush();
   
    // Get the response from the connection
    var inputStream = connection.getInputStream();
    var reader = new BufferedReader(new InputStreamReader(inputStream));
    var response = "";
    var line;
    while ((line = reader.readLine()) !== null) {
      response += line;
    }

    logger("RESPONSE!!! " + response);
   
    // Close the streams and connection
    writer.close();
    reader.close();
    outputStream.close();
    inputStream.close();
    connection.disconnect();
}

Hector Luna

unread,
May 18, 2023, 6:33:34 PM5/18/23
to OWASP ZAP User Group
Make sure you are running the latest version of the weekly release (just in case), and just in case, maybe add the `keep-alive` header and see if that helps.

Adam Lock

unread,
May 18, 2023, 6:39:02 PM5/18/23
to OWASP ZAP User Group
Will do - I will check again in the morning if keep-alive is a problem

thc...@gmail.com

unread,
May 19, 2023, 12:21:16 AM5/19/23
to zaprox...@googlegroups.com
Hi.

You are not updating the content-length header, unless you are using
HTTP/2 or closing the connection, that's going to lead to problems.

After setting the body e.g.:
requestHeader.setContentLength(bytes.length)


I will update the auth examples script and JavaDocs to be mention that.

Best regards.
Reply all
Reply to author
Forward
0 new messages