Skip to content

Practice creating grpc services and clients with buf.build, Rust, and tonic

License

Notifications You must be signed in to change notification settings

CleanCut/examine

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

"Examine" Client & Service

Practice creating grpc services and clients with buf.build, Rust, and tonic.

The Task

You are implementing an API which must analyze an HTTP user agent and make a decision as to whether to block or allow it. If the user agent header is from a Safari browser, it should return a decision to block the request. If it is from a Firefox browser, it should allow the request.

Create a gRPC client and server in Rust or Go which implements a single endpoint that receives the user agent string, analyzes it, and returns the result. Create a terminal CLI which uses the client to call the API. Include appropriate tests and documentation.

Built-in Tests

To run the built-in unit, integration, and doc tests, do:

cargo test

Protobuf Definitions

The (handwritten) protobuf file is in proto/examine/v1/examine.proto. buf.build was used to generate the code.

Rust Library Documentation

Most of the documentation for this project is right here in this readme, but there is also some Rust API documentation available. View it by running the command locally:

cargo doc --no-deps --open

Server

The code for the server binary is in src/bin/server.rs, while the logic for the service it runs is in the library file src/service.rs.

Running the server...

cargo run -r --bin server

OR...

cargo build -r
target/release/server

Testing the server...

To test the server in isolation using grpcurl, first run the server, and then run commands like the one below. (Replace USER-AGENT-STRING with the actual User-Agent value.)

grpcurl -plaintext -import-path ./proto -proto proto/examine/v1/examine.proto -d '{"user_agent": "USER-AGENT-STRING"}' 127.0.0.1:8080 examine.v1.ExamineService/Examine

Safari User-Agent Example

grpcurl -plaintext -import-path ./proto -proto proto/examine/v1/examine.proto -d '{"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 13_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Safari/605.1.15"}' 127.0.0.1:8080 examine.v1.ExamineService/Examine

...which outputs:

{
  "action": "ACTION_BLOCK"
}

Firefox User-Agent Example

grpcurl -plaintext -import-path ./proto -proto proto/examine/v1/examine.proto -d '{"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 13.5; rv:109.0) Gecko/20100101 Firefox/116.0"}' 127.0.0.1:8080 examine.v1.ExamineService/Examine

...which outputs

{
  "action": "ACTION_ALLOW"
}

Client

The client reads in User-Agent string(s) and then outputs either Allow or Block for each input value, one per line.

Running the client

While you can run the client through cargo, it's a bit...verbose. (ARGUMENT is the User-Agent string(s), separated by newlines)

cargo run -r --bin client -- ARGUMENT

It's probably easier to run the client by calling the binary directly:

cargo build -r
target/release/client ARGUMENT

Client Usage

Note: First run the server using the instructions above!

For the client help output, pass in -h:

target/release/client -h

Which should output something like:

`client` checks user agent string(s)and emits whether to Allow or Block for each one

Usage: client <USER_AGENT>

Arguments:
  <USER_AGENT>  User-Agent string of the browser. Use `-` to indicate reading from stdin instead

Options:
  -h, --help     Print help
  -V, --version  Print version

Stdin

If you would rather pass your User-Agent string(s) via stdin, use - as the argument:

# One argument via pipe
echo "some user agent" | target/release/client -

# Multiple arguments via pipe
echo "user agent string 1\nuser agent string 2" | target/release/client -

# Any number of arguments via file
target/release/client - < somefile.txt

Safari User-Agent Example (via positional argument)

target/release/client "Mozilla/5.0 (Macintosh; Intel Mac OS X 13_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Safari/605.1.15"

...which outputs:

Block

Firefox User-Agent Example (via stdin)

echo "Mozilla/5.0 (Macintosh; Intel Mac OS X 13.5; rv:109.0) Gecko/20100101 Firefox/116.0" | target/release/client -

...which outputs:

Allow

Multiple User-Agents via a file

This file is present in the repository if you would like to use it.

target/release/client - < tests/user_agents.txt
Block
Allow

About

Practice creating grpc services and clients with buf.build, Rust, and tonic

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages