5

For debugging matters, I would like to get the request executed by Unirest-Java when presented with a set of options. How can I get this:

POST / HTTP/1.1
Host: www.some.host.tld
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
field1=FIELD1&field2=FIELD2

From this:

HttpRequest request = Unirest.post(SOMEHOST_URL)
            .field("field1" , FIELD1)
            .field("field2", FIELD2)
            .getHttpRequest();

That is, how can I get the full HTTP request from a HttpRequest? I don't really know of a proxy to use, as the only one with which I could get SSL support working was Charles, and for some reason it won't pickup the java traffic. Other tools would choke on the SSL mainly because the server I need to talk to is flawed, using self-signed certificates and invalid hostnames. So I would gladly try a proxy, but it has to work under these conditions. Better would be to extract this information from Unirest/HTTPClient itself. I already tried building the HttpClient with .setInterceptorFirst( but I couldn't get the request body from the interceptor, only some of its headers.

Délisson Junio
  • 1,296
  • 4
  • 21
  • 43

3 Answers3

5

I have never used Unirest, but it uses Apache HTTP client 4, so setting debug level logger on org.apache.http should give you all the data transferred including headers and content.

Please see how to do it depending on the log system you use at

Edit: https://hc.apache.org/httpcomponents-client-4.5.x/logging.html

Lyoneel
  • 419
  • 6
  • 16
volkovs
  • 1,153
  • 2
  • 11
  • 24
3

Unfortunately, Unirest doesn't have a good mechanism for getting the request as sent. But you can reconstruct the request by doing this:

// build a request
HttpRequestWithBody request = Unirest.post(url);
request.headers = myHeaders;
request.body = myBody;

// send the request
HttpResponse<String> response = request.asString(); 

// print the request 
System.out.println(request.getHttpMethod() + " " + request.getUrl() + " HTTP/1.1");

Map<String, List<String>> requestHeaders = request.getHeaders();

for(String key : requestHeaders.keySet()) {
    List<String> values = requestHeaders.get(key);
    for(String value : values) {
        System.out.println(key + " : " + value);
    }
}

InputStream in = loginRequest.getBody().getEntity().getContent();
String body = IOUtils.toString(in, "UTF-8");
in.close();

System.out.println(body);
fijiaaron
  • 5,015
  • 3
  • 35
  • 28
1

You can use TCPMon: https://code.google.com/p/tcpmon/

From the website:

The client will connect to the Local Port on the host where tcpmon is running. The address of the server should be specified in Server Name and Server Port. Information captured for each connection is displayed in a tabbed panel identified by the local port of the connection.

I have used this tool before, and it's light and easy to use. If you want a tutorial please check the following:

http://www.asjava.com/web-services/tcpmon-tutorial-web-service-debugging-tool/

UPDATE.

TCPMon cannot monitor https traffic. Alternatively you can use SSLDump.

The main site of ssldump: http://www.rtfm.com/ssldump/Ssldump.html An example of usage: http://blog.facilelogin.com/2010/11/ssl-debugging-part-ii-intercepting.html

Ernesto Campohermoso
  • 7,213
  • 1
  • 40
  • 51