Skip to content

Logs HTTP requests sent by REST-assured as CURL commands.

Notifications You must be signed in to change notification settings

ilusi0npl/curl-logger

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CURL Logger

Build Status Maven Central

Logs HTTP requests sent by REST-assured as CURL commands.

The following request from REST-assured test

given()
  .config(config)
  .redirects().follow(false)
.when()
  .get("http://google.com")
.then()
  .statusCode(302); 

will be logged as:

curl 'http://google.com/' -H 'Accept: */*' -H 'Content-Length: 0'  -H 'Connection: Keep-Alive' 
  -H 'User-Agent: Apache-HttpClient/4.5.2 (Java/1.8.0_112)' -H 'Content-Type: multipart/mixed' 
  --compressed -k -v

This way testers and developers can quickly reproduce an issue and isolate its root cause.

Usage

Latest release:

<dependency>
  <groupId>com.github.dzieciou.testing</groupId>
  <artifactId>curl-logger</artifactId>
  <version>1.0.4</version>
</dependency>

Using with REST-assured client

When sending HTTP Request with REST-assured, you must create RestAssuredConfig instance first as follows:

RestAssuredConfig config = CurlLoggingRestAssuredConfigFactory.createConfig();  

and then use it:

given()
  .config(config)
  ...

If you already have a RestAssuredConfig instance, you may reconfigure it as follows:

RestAssuredConfig config = ...;
config = CurlLoggingRestAssuredConfigFactory.updateConfig(config);  

The library provides a number of options for the way curl is generated and logged. They can be defined with Options class. For instance:

Options options = Options.builder()...build();
RestAssuredConfig config = CurlLoggingRestAssuredConfigFactory.createConfig(options);  

There is a separate section listing all options.

Configuring logger

CURL commands are logged to a "curl" logger. The library requires only the logger to be slf4j-compliant, e.g., using logback. Sample logback configuration that logs all CURL commands to standard system output would be:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
        </encoder>
    </appender>
    <logger name="curl" level="DEBUG">
        <appender-ref ref="STDOUT"/>
    </logger>
</configuration>

Options

Printing stacktrace

The library provides a way to log stacktrace where the curl was generated:

Options.builder().logStacktrace().build();

This might be particularly useful when your test is sending multiple requests and you cannot find which request generated printed curl command.

Printing curl in multiple lines

The library enables printing a curl command in multiple lines:

Options.builder().printMultiliner().build();

On Unix systems it will look like this:

curl 'http://google.pl/' \ 
  -H 'Content-Type: application/x-www-form-urlencoded' \ 
  -d 'param1=param1_value&param2=param2_value' \ 
  --compressed \ 
  -k \ 
  -v

and on Windows:

curl 'http://google.pl/' ^ 
  -H 'Content-Type: application/x-www-form-urlencoded' ^ 
  -d 'param1=param1_value&param2=param2_value' ^ 
  --compressed ^ 
  -k ^ 
  -v

By default CurlLoggingRestAssuredConfigFactory#createConfig creates configuration that prints a curl command in a single line.

Generating curl for Windows vs Unix

The library provides a way to force target platform, e.g.,:

Options.builder().targetPlatform(Platform.UNIX).build();

The curl command generated by the library is platform-specific because of new line characters and the ways it escapes strings. By default, the library assumes the target platform on which curl will be executed is the same as the platform where it was generated. However, when you work on two different platforms, sometimes a curl command generated on Unix might not be portable to Windows, and vice-versa.

Printing curl parameters in long form

The library enables printing longer form of curl parameters, e.g. "--header" instead of "-H":

Options.builder().useLongForm().build();

Here's an example of a curl command generated with parameters in default short form:

curl 'http://google.pl/' -H 'Content-Type: application/x-www-form-urlencoded' -H 'Host: google.pl' 
  -H 'User-Agent: 'User-Agent: Apache-HttpClient/4.5.2 (Java/1.8.0_112)' 
  -H 'Connection: Keep-Alive' -d 'param1=param1_value&param2=param2_value' --compressed -k -v

After enabling long form option it would look as follows:

curl 'http://google.pl/' -header 'Content-Type: application/x-www-form-urlencoded' 
  --header 'Host: google.pl'  --header 'User-Agent: 'User-Agent: Apache-HttpClient/4.5.2 
     (Java/1.8.0_112)' --header 'Connection: Keep-Alive' 
  --data 'param1=param1_value&param2=param2_value' --compressed --insecure --verbose

By default CurlLoggingRestAssuredConfigFactory#createConfig create configuration that prints a curl command parameters in short form.

Updating curl command before print

The library provides a way to modify curl command before printing:

Options.builder().updateCurl(curl -> ...).build();

#updateCurl method takes instance of Consumer<CurlCommand> class. CurlCommand is a mutable representation of curl and offers a number of methods to modify it: #addHeader, #removeHeader, etc.

This is useful to:

  • modify generated curl to test different variations of the same case
  • remove certain headers or parameters to make curl command more consise and thus easier to read

For instance, if you would like skip common headers like "Host", "User-Agent" and "Connection" from the following curl command:

curl 'http://google.pl/' -H 'Content-Type: application/x-www-form-urlencoded' -H 'Host: google.pl'  
  -H 'User-Agent: 'User-Agent: Apache-HttpClient/4.5.2 (Java/1.8.0_112)' 
  -H 'Connection: Keep-Alive'  -d 'param1=param1_value&param2=param2_value' --compressed -k -v

you should define Options as follows:

Options.builder()
  .updateCurl(curl -> curl
    .removeHeader("Host")
    .removeHeader("User-Agent")
    .removeHeader("Connection"))
  .build();

As a result it will generate the following curl:

curl 'http://google.pl/' -H 'Content-Type: application/x-www-form-urlencoded' 
  -d 'param1=param1_value&param2=param2_value' --compressed -k -v

Other features

Logging attached files

When you attach a file to your requests, e.g., sending content of "README.md" file:

given()
  .config(new CurlLoggingRestAssuredConfigFactory.create)
  .baseUri("http://someHost.com")
  .multiPart("myfile", new File("README.md"), "application/json")
.when()
  .post("/uploadFile");

the library will automatically include reference to it instead of pasting its content:

curl 'http://somehost.com/uploadFile' -F 'myfile=@README.md;type=application/json' -X POST ...

Prerequisities

  • JDK 8
  • Dependencies with which I tested the solution
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.3</version>
</dependency>
<dependency>
    <groupId>io.restassured</groupId>
    <artifactId>rest-assured</artifactId>
    <version>3.2.0</version>
</dependency>

Releases

1.0.4:

  • Bug fix: HTTPS protocol was not always recognized correctly (dzieciou#17). Many thanks to pafitchett-ks for troubleshooting.
  • Support slf4j 1.8.0-beta2.
  • Support rest-assured 3.2.0.

1.0.3:

  • Bug fix: Invalid basic authentication headers are failing curl generation (dzieciou#15)

1.0.2:

  • Bug fix: CurlLogger was failing when multiple Cookie headers are present in HTTP Request. Now it only prints warning (dzieciou#13)

1.0.1:

  • Bug fix: CurlLoggingRestAssuredConfigBuilder was not updating RestAssuredConfig properly (dzieciou#4):

1.0.0:

  • First major release with stable public API
  • Provided a way to force target platform of generated curl command
  • Backward-incompatible change: CurlLoggingRestAssuredConfigBuilder replaced with CurlLoggingRestAssuredConfigFactory that uses Options class to configure curl generation process.

0.7:

  • Added possibility to print shorter versions of curl parameters, e.g., -v instead of --verbose
  • Added possibility to modify a curl command before printing it, inspired by the suggestion from Alexey Dushen (blacky0x0): dzieciou#2.

0.6:

  • Fixed bug: For each cookie a separate "-b cookie=content" parameter was generated (dzieciou#4)
  • Upgraded to REST-assured 3.0.2
  • Simplified curl-logger configuration with CurlLoggingRestAssuredConfigBuilder, based on suggestion from Tao Zhang (dzieciou#4)

0.5:

  • Upgraded to REST-assured 3.0.1 that contains important fix impacting curl-logger: Cookie attributes are no longer sent in request in accordance with RFC6265.
  • Fixed bug: cookie values can have = sign inside so we need to get around them somehow
  • Cookie strings are now escaped
  • CurlLoggingInterceptor's constructor is now protected to make extending it possible
  • CurlLoggingInterceptor can now be configured to print a curl command in multiple lines

0.4:

  • Upgraded to REST-assured 3.0

0.3:

  • Each cookie is now defined with "-b" option instead of -"H"
  • Removed heavy dependencies like Guava
  • Libraries like REST-assured and Apache must be now provided by the user (didn't want to constrain users to a specific version)
  • Can log stacktrace where curl generation was requested

0.2:

  • Support for multipart/mixed and multipart/form content types
  • Now all generated curl commands are "--insecure --verbose"

0.1:

  • Support for logging basic operations

Bugs and features request

Report or request in JIRA.

Similar tools

  • Chrome Web browser team has "Copy as CURL" in the network panel, similarly Firebug add-on for Firefox.
  • OkHttp client provides similar request interceptor to log HTTP requests as curl command.
  • Postman add-on for Chrome provides a way to convert prepared requests as curl commands.

About

Logs HTTP requests sent by REST-assured as CURL commands.

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Java 99.3%
  • Shell 0.7%