How to install OpenSSL & stunnel on MacOS

When travelling behind the Great Firewall of China,  I wanted a copy of OpenSSL and stunnel on my machine. Googling “install stunnel macos” gives a bunch of answers that involve the word “brew”.

OpenSSL and stunnel are open-source C programs, which means we can compile them from source. Doing so is not difficult, but it is a bit fiddly, and I think that fiddliness can dissuade people and cause them to unnecessarily reach for a bloated package manager.

All the information in this blog post is “as of February 2019”, and applies to stunnel 5.50, OpenSSL 1.1.1, and macOS 10.14.

stunnel depends on OpenSSL, so we will compile and install OpenSSL first.

Compiling & Installing OpenSSL on MacOS

stunnel is going to look for ssl.h, and to make it available we need to compile with the shared flag.  We probably don’t want to spray OpenSSL all over the system, so we will use --prefix to specify an install location other than the default /usr/bin.

$ ./Configure darwin64-x86_64-cc shared --prefix=/Users/hugh/somedir --openssldir=/Users/hugh/somedir no-ssl3

Now you can make and make install. Many lines of output later, you will

Compiling & Installing stunnel on MacOS

OpenSSL at the ready, we can now move on to stunnel.   We will tell stunnel about our newly minted copy of OpenSSL using the ./configure command:

$ ./configure --with-ssl=/Users/hugh/somedir --prefix=/Users/hugh/somedir

If the shared flag was not specified when compiling OpenSSL, then this is where you will hit the much-googled:

checking for TLS directory... not found
configure: error: 
Could not find your TLS library installation dir
Use --with-ssl option to fix this problem

We did used shared, so we are good to go! Hit that make button, followed by make install, and you are the proud owner of a copy of stunnel compiled with OpenSSL!

Result types in Swift. Are they useless?

Fresh-faced, amateur, and impressionable: Swift is not my main jam. When setting out to write Amatino Swift, I was hungry for best-practice and good patterns. Amatino Swift involves lots of asynchronous HTTP requests to the Amatino API.

Asynchronous programming requires bifurcation at the point of response receipt. That is, an asynchronous operation may yield a success state or a failure state. Result types are a pattern widely espoused as a pattern for handling such bifurcation.

I’d like to open a debate over whether result types should be used in Swift. After some thought, it appears to me that they are useless. I propose that we would be better off encouraging newbies to utilise existing Swift features, rather than learning about and building result type patterns.

For the purposes of this discussion, let’s assume that our code includes two functions, each of which handle a bifurcated state:

func handleSuccess(data: Data) {
  // Do stuff with data
}

func handleFailure(error: Error) {
  // Do stuff with error
}

Inside these functions, we might implement code which is independent of our bifurcation pattern. For example, we could `case-switch` on Error type in order to present a meaningful message to a user.

Now to the bifurcation itself. A naive and simple pattern might be:

// This is bad code. Do not copy it!
func asynchronousCallback(error: Error?, data: Data?) -> Void {
  if (error != nil) {
    handleFailure(error!)
  return
}
  handleSuccess(data!)
  return
}

There are myriad problems with this approach. We have no type safety over `data`. We do not control for cases where programmer error yields a state where both `data` and `error` are `nil`. It’s ugly. More.

Result types propose to improve upon this pattern by defining a type such as:

enum Result<Value> {
  case success(Value)
  case failure(Error)
}

Which may be used like so:

func asynchronousCallback(result: Result<Data>) {
  switch result {
  case .success(let data):
    handleSuccess(data)
  case .failure(let error):
    handleError(error)
  }
  return
}

This pattern introduces type safety to both `error` and `data`. I suggest that it does so at too great a cost when compared to using inbuilt Swift features. Every asynchronous bifurcation now requires a `switch-case` statement, and the use of a result type.

Compare the result type pattern with one that uses the Swift `guard` statement:

func asynchronousCallback(error: Error?, data: Data?) {
  guard let data = data else { handleError(error ?? TrainWreck()) }; return
  handleSuccess(data)
  return
}

In this case, we have type safety over `error` and `data`. We have handled a case in which a programmer failed to provide an `Error` using the nil-coalescing operator `??`. We have done it all in two lines of less than 80 char. A suitable error type might be defined elsewhere as:

struct TrainWreck: Error { let description = "No error provided" }

Bifurcation via a `guard` statement appears to me to have several advantages over result types:

  • Brevity. Functions handling asynchronous callbacks need only implement a single line pattern before proceeding with a type safe result.
  • Lower cognitive load. A developer utilising a library written with the `guard` pattern does not need to learn how the library’s result type behaves.
  • Clarity. A `guard` statement appears to me to be more readable than a `case-switch`. This is subjective, of course.

What do you think? I am not a Swift expert. Am I missing something obvious? Why would you choose to use a result type over a `guard` statement?

Cover image – A bee harvests pollen from lavender on Thornleigh Farm

Originally posted at The Practical Dev