Convert OkHttp requests into curl logs.

Overview

Ok2Curl Build Status Android Arsenal Release

Convert OkHttp requests into curl logs.

Usage

Add library to project dependencies. Library is hosted on jcenter.

repositories {
    jcenter()
}

dependencies {
    implementation 'com.github.mrmike:ok2curl:0.7.0'
}

To start logging requests with Ok2Curl add interceptor to OkHttp client.

OkHttpClient okHttp = new OkHttpClient.Builder()
    .addInterceptor(new CurlInterceptor(new Loggable() {
            @Override
            public void log(String message) {
                Log.v("Ok2Curl", message);
            }
        }))
    .build();

Result

With Ok2Curl set up correctly every executed request will be transformed into curl log e.g.

adb logcat -s "Ok2Curl"
curl -X GET -H "Cache-Control:max-stale=2147483647, only-if-cached" https://api.github.com/repos/vmg/redcarpet/issues?state=closed

Network interceptors

By default Ok2Curl uses application interceptors from OkHttp which is adequate for most cases. But sometimes you may want to use network interceptor e.g. to log Cookies set via CookieHandler. In such a case add interceptor the same way as below:

OkHttpClient okHttp = new OkHttpClient.Builder()
    .addNetworkInterceptor(new CurlInterceptor())
    .build();

To get know more about Interceptor in OkHttp take a look here: https://github.com/square/okhttp/wiki/Interceptors

Header modifiers

Ok2Curl allows you to modify any header before creating curl command. All you have to do is create your own modifier that implements HeaderModifier and add this modifier to CurlInterceptor. See sample for reference.

final BasicAuthorizationHeaderModifier modifier = new BasicAuthorizationHeaderModifier(new Base64Decoder());
final List<HeaderModifier> modifiers = Collections.<HeaderModifier>singletonList(modifier);

final CurlInterceptor curlInterceptor = new CurlInterceptor(new AndroidLogger(), modifiers);

Options

Ok2Curl supports basic Curl options. In order to use options use the following code:

final Options options = Options.builder()
                .insecure()
                .connectTimeout(120)
                .retry(5)
                .build();

final CurlInterceptor interceptor = new CurlInterceptor(logger, options);

Since now every Curl command will start with curl --insecure --connect-timeout 120 --retry 5...

Supported options

  • --insecure
  • --max-time seconds
  • --connect-timeout seconds
  • --retry num
  • --compressed
  • --location

If would like to support any new options please feel free to open PR. Full list of curl options is available here.

License

Copyright 2018 Michał Moczulski

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • Configurable builder

    Configurable builder

    To enable creating custom CurlBuilders (for https://github.com/mrmike/Ok2Curl/issues)

    public static class MyCurlInterceptor extends CurlInterceptor {
        private static final int[] PARTS_ORDER = new int[]{
                ConfigurableCurlBuilder.PART_CURL,
                ConfigurableCurlBuilder.PART_OPTIONS,
                ConfigurableCurlBuilder.PART_METHOD,
                ConfigurableCurlBuilder.PART_URL,
                ConfigurableCurlBuilder.PART_BODY,
                ConfigurableCurlBuilder.PART_CONTENT_TYPE,
                ConfigurableCurlBuilder.PART_HEADERS
        };
    
        public MyCurlInterceptor(Loggable logger) {
            super(logger);
        }
    
        @Override
        protected CurlBuilder getCurlBuilder(Request copy) {
            return new ConfigurableCurlBuilder(copy, limit, headerModifiers, options, delimiter, PARTS_ORDER);
        }
    }
    

    Let me know what do you think. I think it can also be merged into CurlBuilder, since we have a default order so we can move all the code in ConfigurableCurlBuilder into CurlBuilder

    opened by flocsy 6
  • Put URL and body before headers

    Put URL and body before headers

    Hi and thanks for the lib,

    I'm using this lib in my project to have HTTP calls logged and be able to reproduce them and import them in Postman. It works great ! But it's quite hard to find the call we are looking for because every request log start with the same text :

    curl -X GET -H "Authorization:Bearer <a very looonnngg token>" -H "<some more headers>: <some more headers values>" "https://<the url we are looking for>"
    

    So we are still using a "standard" OkHttp logger to get the URL readable easily.

    Would it be possible to change the order of arguments in the curl command to :

    • the method
    • the url
    • the body
    • headers

    Ex : curl -X GET "https://example.com/endpoint" -d "a body" -H "header1: foo" -H "header2: bar"

    opened by yDelouis 6
  • Fix curl when the request url has some special characters

    Fix curl when the request url has some special characters

    Regarding to the curl documentation:

     When using [] or {} sequences when invoked from a command line prompt, you probably have to put the full URL within double quotes to avoid the shell from interfering with it. This
           also goes for other characters treated special, like for example '&', '?' and '*'.
    
    opened by mirland 4
  • Recognize Basic Authorization

    Recognize Basic Authorization

    In case request contains Authorization header of Basic type, e.g.,

    Authorizaton: Basic bWFjaWVrOnRham5laGFzbG8xMjM=
    

    would it be possible to have the following

    curl -u maciej:tajnehaslo123 ...
    

    ?

    opened by mgawinec 4
  • Invalid handling of multiple headers of same name

    Invalid handling of multiple headers of same name

    My request is having two headers of the same name:

    Cookie: JSESSIONID=....
    Cookie: SOMETOKEN=....; OTHERTOKEN=....
    

    This is correct with respect to HTTP protocol. However, CurlBuilder will take only the last header, because it is using a map with unique keys for header names:

        public CurlBuilder(Request request, long limit) {
           ...
    
            final Headers headers = request.headers();
            for (int i = 0; i < headers.size(); i++) {
                \\ MG: If there was already a header with same name it will be overwritten here
                this.headers.put(headers.name(i), headers.value(i));
            }
        }
    
    opened by mgawinec 4
  • Migrate from JCenter to MavenCentral

    Migrate from JCenter to MavenCentral

    JFrog announced yesterday that Bintray and JCenter repositories will be closed by May 1st. You use JCenter to distribute your artifacts. Are you planning to migrate to MavenCentral?

    opened by JcMinarro 3
  • Missing from Jcenter

    Missing from Jcenter

    I cannot find the repo in jcenter, I tried this url and it looks like it's missing. Is it available on it? I'm using jitpack and it's working fine.

    I saw that the remote was changed in this commit https://github.com/mrmike/Ok2Curl/commit/10a27fc214e304b695cf7010d0598ed34418de24

    opened by mirland 3
  • Library not available in Maven Central

    Library not available in Maven Central

    How can I use your library with maven?

    I tried to get it from Maven Central repo:

            <dependency>
                <groupId>com.github.mrmike</groupId>
                <artifactId>okcurl</artifactId>
                <version>0.2.5</version>
            </dependency>
    

    but there's no such groupId. Going to https://repo.maven.apache.org/maven2/com/github/mrmike/ returns 404.

    opened by mgawinec 3
  • v0.2.4 - broken build

    v0.2.4 - broken build

    after upgrading from v0.2.3 to v0.2.4

    ...
    :app:transformClassesWithDexForLiveDebug
    Dex: Error converting bytecode to dex:
    Cause: Dex cannot parse version 52 byte code.
    This is caused by library dependencies that have been compiled using Java 8 or above.
    If you are using the 'java' gradle plugin in a library submodule add
    targetCompatibility = '1.7'
    sourceCompatibility = '1.7'
    to that submodule's build.gradle file.
        UNEXPECTED TOP-LEVEL EXCEPTION:
        java.lang.RuntimeException: Exception parsing classes
            at com.android.dx.command.dexer.Main.processClass(Main.java:761)
            at com.android.dx.command.dexer.Main.processFileBytes(Main.java:727)
            at com.android.dx.command.dexer.Main.access$1200(Main.java:87)
            at com.android.dx.command.dexer.Main$FileBytesConsumer.processFileBytes(Main.java:1655)
            at com.android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpener.java:284)
            at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:166)
            at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:144)
            at com.android.dx.command.dexer.Main.processOne(Main.java:681)
            at com.android.dx.command.dexer.Main.processAllFiles(Main.java:578)
            at com.android.dx.command.dexer.Main.runMonoDex(Main.java:315)
            at com.android.dx.command.dexer.Main.run(Main.java:286)
            at com.android.builder.internal.compiler.DexWrapper.run(DexWrapper.java:52)
            at com.android.builder.core.AndroidBuilder$2.call(AndroidBuilder.java:1511)
            at com.android.builder.core.AndroidBuilder$2.call(AndroidBuilder.java:1507)
            at java.util.concurrent.FutureTask.run(FutureTask.java:262)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
            at java.lang.Thread.run(Thread.java:745)
        Caused by: com.android.dx.cf.iface.ParseException: bad class file magic (cafebabe) or version (0034.0000)
            at com.android.dx.cf.direct.DirectClassFile.parse0(DirectClassFile.java:472)
            at com.android.dx.cf.direct.DirectClassFile.parse(DirectClassFile.java:406)
            at com.android.dx.cf.direct.DirectClassFile.parseToInterfacesIfNecessary(DirectClassFile.java:388)
            at com.android.dx.cf.direct.DirectClassFile.getMagic(DirectClassFile.java:251)
            at com.android.dx.command.dexer.Main.parseClass(Main.java:773)
            at com.android.dx.command.dexer.Main.access$1600(Main.java:87)
            at com.android.dx.command.dexer.Main$ClassParserTask.call(Main.java:1694)
            at com.android.dx.command.dexer.Main.processClass(Main.java:758)
            ... 17 more
    
    1 error; aborting
    :app:transformClassesWithDexForLiveDebug FAILED
    

    I have only one module (android application)

        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_7
            targetCompatibility JavaVersion.VERSION_1_7
        }
    
    opened by jbaginski 3
  • Escape `

    Escape `"` in the the headers

    From backend I'm receiving a header like this: etag: "estoesunapruebadeetag" the " are part of the etag.

    OkHttp when I call this endpoint again it adds this header: If-None-Match: "estoesunapruebadeetag".

    But on curl I see this: -H "If-None-Match:"estoesunapruebadeetag"" when it should be -H "If-None-Match:\"estoesunapruebadeetag\"". The " should be escaped.

    opened by BraisGabin 2
  • Update dependencies and remove unnecessary code

    Update dependencies and remove unnecessary code

    A bunch of project updates and cleanups. Please check individual commits for details.

    Update for the latest stable version of Android Studio 3.2.0 Also fixes all Lint warnings and whitespace errors.

    Once approved, please use a normal GitHub merge (i.e. NO rebase/squash merge) to integrate the commit(s) from the branch of this pull request. The changes are broken up into meaningful, atomic commits, and my branch should already be up-to-date with the latest target branch. If it isn't, or if you'd like me to combine something, please let me know, and I will make the necessary updates as soon as possible. Thank you!

    opened by friederbluemle 2
  • Research support for OkHttp 5.x

    Research support for OkHttp 5.x

    • OkHttp version 5 is coming. Do some research what needs to be changed in order to make Ok2Curl compatible with OkHttp
    • https://github.com/square/okhttp/blob/master/CHANGELOG.md#version-500-alpha9
    enhancement help wanted 
    opened by mrmike 0
  • Replaced deprecated IntentService in sample

    Replaced deprecated IntentService in sample

    • Sample app uses IntentService and this class is deprecated
    • Replace with something new (WorkManager maybe or even something simpler Callback in OkHttp?)
    enhancement 
    opened by mrmike 0
Releases(0.8.0)
Owner
Michal Moczulski
Android Developer
Michal Moczulski
Trail is a simple logging system for Java and Android. Create logs using the same API and the library will detect automatically in which platform the code is running.

Trail Trail is a simple logging system for Java and Android. Create logs using the same API and the library will detect automatically in which platfor

Mauricio Togneri 13 Aug 29, 2022
🐫🐍🍢🅿 Multiplatform Kotlin library to convert strings between various case formats including Camel Case, Snake Case, Pascal Case and Kebab Case

KaseChange Multiplatform Kotlin library to convert strings between various case formats Supported Case Formats SCREAMING_SNAKE_CASE snake_case PascalC

PearX Team 67 Dec 30, 2022
A simple Android utils library to write any type of data into cache files and read them later.

CacheUtilsLibrary This is a simple Android utils library to write any type of data into cache files and then read them later, using Gson to serialize

Wesley Lin 134 Nov 25, 2022
writing into android application lib.so with offset & hex bytes

KMrite writing into android application lib.so with offset & hex bytes support root and non root devices Changelogs 3.1 : fix hex input only number up

BryanGIG 13 Nov 28, 2022
A low intrusive, configurable android library that converts layout XML files into Java code to improve performance

qxml English 一个低侵入,可配置的 Android 库,用于将 layout xml 文件转换为 Java 代码以提高性能。 与X2C的对比 X2C: 使用注解处理器生成View类,使用时需要在类中添加注解,并替换setContentView方法,侵入性较强; 对于布局属性的支持不够完美

null 74 Oct 6, 2022
Small command-line utility to safely merge multiple WhatsApp backups (msgstore.db) into one.

whatsapp-database-merger A small command-line utility that can be used to merge multiple WhatsApp databases (msgstore.db) into one. A few notes: input

Mattia Iavarone 31 Dec 27, 2022
Kotlin HTTP requests library. Similar to Python requests.

khttp khttp is a simple library for HTTP requests in Kotlin. It functions similarly to Python's requests module. import khttp.get fun main(args: Arra

Anna Clemens 466 Dec 20, 2022
Speech-Text Converter is a simple task that enable the user to convert the speech to text or convert text to speech (by Mic)

Speech-Text Converter About Speech-Text Converter is a simple task that enable the user to convert the speech to text or convert text to speech (by Mi

Kareem Saeed 1 Oct 21, 2021
Utility logger library for storing logs into database and push them to remote server for debugging

HyperLog Android Overview Log format Download Initialize Usage Get Logs in a File Push Logs Files to Remote Server Sample Testing Endpoint using Reque

HyperTrack 675 Nov 14, 2022
Page Curl for Android

Page Curl for Android Overview The android-page-curl is a 2D View which simulates a page curl effect. Without OpenGL, only the android canvas has been

Moritz Wundke 377 Jan 3, 2023
Page Curl for Android

Page Curl for Android Overview The android-page-curl is a 2D View which simulates a page curl effect. Without OpenGL, only the android canvas has been

Moritz Wundke 376 Nov 20, 2022
Page Curl library for Jetpack Compose

Page Curl Page Curl library for Jetpack Compose. Motivation This library allows to create an effect of turning pages, which can be used in book reader

Oleksandr Balan 153 Dec 25, 2022
A Java serialization/deserialization library to convert Java Objects into JSON and back

Gson Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to a

Google 21.7k Jan 5, 2023
Convert your YouTube channel into a native Android app using YouTube Data API v3.

Convert your YouTube channel into an app. Screenshots • Description • Features • Configuration • Documentation Screenshots Description Channelify is a

Aculix Technologies LLP 121 Dec 26, 2022
Silky - Android application to convert videos from applications such as YouTube, Facebook, Twitter into audio (.mp3)

Silky Español (actualmente la app se encuentra en desarrollo ) Descripcion Aplic

null 2 Aug 24, 2022
A CLI tool to convert multi-module Jetpack Compose compiler metrics into beautiful HTML reports

A CLI tool to convert multi-module Jetpack Compose compiler metrics into beautiful HTML reports 1. What are Jetpack Compose compiler metrics? The Comp

Jaya Surya Thotapalli 116 Jan 3, 2023
Create a simple and more understandable Android logs.

DebugLog Create a simple and more understandable Android logs. #Why? android.util.Log is the most usable library of the Android. But, when the app rel

mf 418 Nov 25, 2022
Trail is a simple logging system for Java and Android. Create logs using the same API and the library will detect automatically in which platform the code is running.

Trail Trail is a simple logging system for Java and Android. Create logs using the same API and the library will detect automatically in which platfor

Mauricio Togneri 13 Aug 29, 2022
Source++ is an open-source live coding platform. Add breakpoints, logs, metrics, and tracing to live production applications

Source++ is an open-source live coding platform. Add breakpoints, logs, metrics, and distributed tracing to live production software in real-time on-d

Source++ 40 Dec 14, 2022