Friday, March 3, 2017 #

Capture HTTPS traffic from iOS devices using Charles

This article will show you how to set up Charles and iOS devices so that you can capture HTTPS traffic from iOS devices using Charles. Step 0: Download and install Charles from https://www.charlesproxy.com/


Step 1: Find the IP address of your mac:


Ifconfig | grep “inet “     




Step 2: Find the port number Charles uses listens on. It should be 8888 if you haven’t change the default value. You can find the number from Settings-->Proxy Settings





Step 3: You need set up the proxy on the iOS device.

On the iOS device, Settings → Wi-Fi, click on the little i icon next to the Wi-Fi.




Change HTTP PROXY to Manual, type in the IP Address and Port number of your mac.



Step 4: Go back to Charles, set filters, so that Charles only record the connections your are interested. You don't have to do this step, in case you don't want Charles are flooded with records you are not interested as it will record everything.



Just include the urls you want to record.



Now, if you trigger HTTPS connections from your iOS app, you will find they are recorded by Charles, but the messages are encrypted. You can’t find any useful information from i.


Step 5: Enable SSL Proxying. Right click the URL, and check “Enable SSL Proxying”





You still won’t be able to get any useful information at this stage, as you iOS does not trust the certificate Charles provides.



Step 6: Install Charles’ certificate


Open Safari from your iOS device and browse to:  http://www.charlesproxy.com/getssl

Your iOS device will ask you to install the certificate. Just do it.



That is it. Now you should be able to all the details of the connections.







Posted On Friday, March 3, 2017 12:02 PM | Comments (19)

Execute AsyncTask like jquery’s $.ajax in Kotlin on Android

Last time I showed how to execute an AsyncTask in Jquery style. Now I will show how to do it in Kotlin.


Kotlin has much better support for functional programming, functions/lambdas are first class member of the language. A parameter of a method can be just typed function rather than having to be interface. So I don’t have to create interface for Func<T> and Action<T>.


This is how MyAsyncTask<T> looks like in Kotlin, note the type of task and completionHandler are ()->T or (T)->Unit?.

class MyAsyncTask<T>(private val task: () -> T) : AsyncTask<Void, Void, T>() {


  private var completionHandler: ((T) -> Unit)? = null

  private var errorHandler: ((Exception) -> Unit)? = null

  private var exception: Exception? = null


  fun setCompletionHandler(action: (T) -> Unit) {

      this.completionHandler = action

  }


  fun setErrorHandler(action: (Exception) -> Unit) {

      this.errorHandler = action

  }


  override fun doInBackground(vararg voids: Void): T? {

      try {

          return task.invoke()

      } catch (ex: Exception) {

          exception = ex

      }


      return null

  }


  override fun onPostExecute(result: T) {


      if (exception != null && errorHandler != null) {

          errorHandler!!.invoke(exception!!)

      } else if (completionHandler != null) {

          completionHandler!!.invoke(result)

      }

  }

}



And here is Async<T>:


class Async<T> private constructor() {


  private var task: MyAsyncTask<T>? = null


  fun whenComplete(action: (T) -> Unit): Async<T> {

      task!!.setCompletionHandler(action)

      return this

  }


  fun onError(action: (Exception) -> Unit): Async<T> {

      task!!.setErrorHandler(action)

      return this

  }


  fun execute() {

      try {

          task!!.execute()

      } catch (ex: Exception) {

          ex.printStackTrace()

      }

  }


  companion object {

      fun <T> run(task: () -> T): Async<T> {

          val runner = Async<T>()

          runner.task = MyAsyncTask(task)

          return runner

      }

  }

}


Here is an example of how it is used.


override fun onCreate(savedInstanceState: Bundle?) {

  super.onCreate(savedInstanceState)

  setContentView(R.layout.activity_main)


  Async.run {

      val api = MyAPI()

      api.signInUser("user_name", "password")

  }.whenComplete {

      //it.displayName

  }.onError {

      //it.message

  }.execute()

}


Posted On Friday, March 3, 2017 10:16 AM | Comments (7)

Copyright © Changhong Fu

Design by Bartosz Brzezinski

Design by Phil Haack Based On A Design By Bartosz Brzezinski