chapter four

4 Advanced FFI

 

This chapter covers

  • Creating an NGINX extension module with Rust
  • Generating Rust bindings for an existing C codebase
  • Using a C memory allocator from Rust
  • Sharing functions between Rust crates

The previous chapter was centered around a simple example of calling a Rust function from C code. There was a single C-stack-allocated string value which was used from our Rust code, but the Rust code did not send any heap-allocated values to the C code, nor did it call any C functions. The API surface of our C calculator program was very small, and thus it was quite straightforward to add Rust to it. This chapter is an extension on the previous chapter’s calculator example. Instead of adding our calculator function to a simple CLI application, we’re going to write an NGINX extension module which responds to HTTP requests with calculation results. This chapter is not intended as a general guide on writing NGINX extensions, NGINX is simply a stand-in for a sufficiently complex C codebase to which we want to add some Rust code.

Goal: create a module for NGINX that will solve Reverse Polish Notation (RPN) math expressions using the calculate library that we created in Chapter 3. It should read the expressions from the request POST body, so assuming that the NGINX server is running on port 8080, it should be usable like this:

$ curl -X POST -d '3 4 +' http://localhost:8080/calculate
7
$ curl -X POST -d '3 4 * 2 -' http://localhost:8080/calculate
10

4 Advanced FFI

4.1 Download the NGINX source code

4.2 Create the NGINX module

4.3.1 Build Scripts

4.3.2 Bindgen

4.4 Read the NGINX request

4.4.1 Lifetime Annotations

4.4.2 Lifetime annotations in our NGINX plugin

4.5 Use our calculator library

4.6 Writing the HTTP response

4.7 Summary