Nick Gerakines
Sep 8 · 3 min read

We recently released a new feature that allows draws dynamic SVG badges that can be displayed on sites and pages outside of www.sslhound.com. What we found was that although SVG is great, it isn’t the most portable image type and we had some problems making it widely available.

When embedding an SVG image from www.sslhound.com onto medium.com, a special header needs to be set to allow the count to be sourced correctly. That header is X-Frame-Options:

X-Frame-Options: allow-from https://www.sslhound.com/

Depending on the server hosting the content that you want to display the SVG onto, the default recommended value is “deny” or “sameorigin”. Doing that, however, means that SVGs from SSL Hound won’t work.

Research and Design

The solution is to render a dynamic PNG or JPEG image. The best way to be consistent was to use the original SVG feature and data to do so.

There are a handful of projects and libraries that provide SVG rendering capabilities. There are also a few websites and services that have this same challenge.

Shields.io is a popular badge generator that lets developers embed status badges for various sites and services. At first, I considered using their API to render the badge content and do the conversion, but I didn’t believe that it would be a good idea to put that additional load onto their service.

There are some upload-and-go websites that do image conversion, but they too don’t allow for easy programmatic use or have a price point that was too high.

The library that I’m most familiar with and is my go to for image manipulation is Image Magick. Through searching, I had found a link to github.com/shakiba/svgexport as a better alternative to using image magick, but that project uses a headless browser behind the scenes, specifically PhantomJS, which is no longer maintained.

Switching gears, I went back to the shields.io project and organization to see how they were doing it. That brought me to github.com/badges/svg-to-image-proxy, their home-grown solution. Unfortunately, it too is based on headless browsers and wasn’t what I was looking for.

The SSL Hound web application, services, agents, and tooling are all written in Golang. I ran across a few SVG libraries with Golang wrappers, but after some experimentation, found that they really weren’t going to meet my needs or just simply didn’t work.

The Microservice

In the end, I settled on writing a small HTTP microservice in C++ that leverages cpprestsdk for the HTTP framework, and librsvg2 with cairo for image conversion.

You can find the project and all of the source code at github.com/sslhound/svger.

The API is very simple and exposes two methods, GET and POST. The GET method allows you to make read-through HTTP requests and use the service as a proxy. For example, when making the request GET /foo.svg to SVGer with the backend set to http://cool-svgs.s3.amazonaws.com, it would receive the request and make an HTTP GET request to http://cool-svgs.s3.amazonaws.com/foo.svg and render the resulting SVG into a PNG.

The POST request allows clients to submit an SVG body and get a PNG in response.

The service does only thing and it does it pretty quickly. It’s single threaded and is meant to be scaled through multiple containers, not complex thread/queue/worker configuration.

Deploying with Kubernetes

This service can be deployed with Kubernetes using the following configuration.

---
apiVersion: v1
kind: Service
metadata:
labels:
run: svger
name: svger
spec:
ports:
- port: 5004
protocol: TCP
targetPort: 5003
selector:
app: svger
sessionAffinity: None
type: ClusterIP
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: svger
spec:
replicas: 1
template:
metadata:
labels:
app: svger
spec:
containers:
- name: svger
image: docker.pkg.github.com/sslhound/svger/svger:v1.3.0
imagePullPolicy: Always
ports:
- containerPort: 5003
env:
- name: ENVIRONMENT
value: "production"

The service doesn’t have any dependencies on other services. To see all of the available environment variables that can be set, run svger with the --help option.

Closing

And there you have it. We’re really happy to be contributing to the open source community over at www.sslhound.com. This project is open source under the MIT license. If you use it, let us know.

sslhound

SSL Hound

Thanks to Martha Carter

Nick Gerakines

Written by

sslhound

sslhound

SSL Hound

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade