• This repository has been archived on 04/Jun/2018
  • Stars
    star
    383
  • Rank 111,995 (Top 3 %)
  • Language
    Go
  • License
    MIT License
  • Created almost 9 years ago
  • Updated over 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Web server that wraps around programs and shell scripts and exposes them as API

nigit Build Status MIT licensed

⚠️ This repository is no longer maintained by Lukas Martinelli.

nigit cat logo

Expose a program with a simple call to nigit <script> to the web. The small web server wraps around the program and exposes it as HTTP API. This comes in handy whenever you want to expose a legacy program without writing a web application and doing complicated subprocessing yourself.

Disclaimer

Please use goexpose. It is much more capable and mature than nigit. In the rush of building stuff I didn't realize that nigit is essentially a new take on the terrible CGI scripts we just escaped from. Be very careful where you use this, it is not intended for production usage in any means due to the security risks. I personally do use it for small home automation tasks.

Get Started

In this example we create a service to download the PDF version of websites using the wkhtmltopdf tool.

  1. Create the bash script html2pdf.sh and make it executable with chmod +x html2pdf.sh.
#!/bin/bash
wkhtmltopdf "$URL" page.pdf > /dev/null 2>&1
cat page.pdf
  1. Start up the server with nigit html2pdf.sh.
  2. Download the PDF with curl -o google.pdf http://localhost:8000/html2pdf?url=http://google.com

And that's all you needed to do in order to expose wkhtml2pdf as useful webservice.

Install

You can download a single binary for Linux, OSX or Windows.

OSX

wget -O nigit https://github.com/lukasmartinelli/nigit/releases/download/v0.3/nigit_darwin_amd64
chmod +x nigit

./nigit --help

Linux

wget -O nigit https://github.com/lukasmartinelli/nigit/releases/download/v0.3/nigit_linux_amd64
chmod +x nigit

./nigit --help

Install from Source

go get github.com/lukasmartinelli/nigit

If you are using Windows or 32-bit architectures you need to download the appropriate binary yourself.

Examples

How you can use nigit to build small and concise services:

  • PDF build service using pdflatex
  • Convert DOCX files to Markdown with pandoc
  • Image cropping with imagemagick
  • Convert WAV to MP4 with avconf
  • Transpile code with BabelJS
  • Lint Shell scripts with shellcheck

Usage

Pass Arguments

Form arguments or query strings are passed as environment variables into the program.

#!/bin/bash
echo "$MY_ARGUMENT"

You can specify them as form values or alternatively post a JSON file which is more convenient in JavaScript.

# pass as form values
curl -X POST -F my_argument=test http://localhost:8000/
# pass as query string
curl http://localhost:8000/?my_argument=test
# pass as JSON
curl -X POST -H "Content-Type: application/json" \
  -d '{"envs": ["MY_ARGUMENT=test"]}' \
  http://localhost:8000/hlint

Upload File

Uploaded content is provided as stdin to the file. You can either specify it as file upload or form value. In both cases the field must be named stdin.

# set value of stdin in form
curl -X POST -F stdin="Ping" http://localhost:8000/
# for short input you can even use query strings
curl http://localhost:8000/?stdin=Ping
# post a file to the web api
curl -X POST -F [email protected] http://localhost:8000/

You can also specify a stdin field in JSON to pass something to the script.

curl -X POST -H "Content-Type: application/json" \
  -d '{"stdin": "Ping", "envs": ["MY_ARGUMENT=test"]}' \
  http://localhost:8000/hlint

If you are using a Bash script as wrapper you can read in the stdin with cat.

#!/bin/bash
greetings=$(cat)
echo "$greetings"

Serve Multiple Files

nigit can also serve multiple scripts under different paths if you append more programs as arguments.

nigit echo.sh curl.sh lint.sh

This will serve each script under a different HTTP route.

Handle /echo -> echo.sh
Handle /curl -> curl.sh
Handle /lint -> lint.sh

Mime Type

nigit serves the response either as text/plain if no Accept header is specified or exactly with the mime type specified by the Accept header.

If you wrap around a program that outputs valid JSON you need to set the Accept header and you are good.

curl -H "Accept: application/json" http://localhost:8000/

Authorization

nigit has authorization middleware which allows you to call an executable to approve requests. The Authorization http header gets passed as the AUTH env variable. Thanks to @pdxjohnny for the implementation.

./nigit --auth ./auth.sh ./echo.sh

Example auth.sh

#!/bin/bash
echo $AUTH
exit $AUTH

If it exits non-zero then the client with receive a http.Unauthorized and the stdout of auth.sh will be printed to nigit stdout.

curl -H "Authorization: 1" http://localhost:8000/echo?say=hi

Output: {"Error":"Unauthorized"}

curl -H "Authorization: 0" http://localhost:8000/echo?say=hi

Output: hi

Use together with Docker

nigit fits perfectly into the Docker ecosystem. You can install nigit into a Docker container and wrap around a program that requires complex dependencies.

Create a Dockerfile with nigit and your dependencies for the shell script. In this example we provide shellcheck as a service.

FROM debian:jessie

RUN apt-get update \
 && apt-get install -y --no-install-recommends shellcheck \
 && rm -rf /var/lib/apt/lists/* \

# install nigit
RUN wget --quiet -O /usr/bin/nigit https://github.com/lukasmartinelli/nigit/releases/download/v0.2/nigit_linux_amd64 \
 && chmod +x /usr/bin/nigit

# copy shell scripts
COPY . /usr/src/app/
WORKDIR /usr/src/app

EXPOSE 8000
CMD ["nigit", "--timeout", "5", "shellcheck.sh"]

Now create a bash script to wrap around shellcheck. We specify the json output formatter so that a web client could consume the API.

#!/bin/bash

function clone_repo() {
    local working_dir=$(mktemp -dt "lint.XXX")
    local git_output=$(git clone --quiet "$GIT_REPOSITORY" "$working_dir")
    echo "$working_dir"
}

function find_files() {
    local path="$1"
    local extension="$2"
    find "$path" -type f -name "*$extension"
}

function lint() {
    local repo_path=$(clone_repo)
    shellcheck --format=json $(find_files "$repo_path" "sh") || suppress_lint_error
    trap "rm -rf $repo_path" EXIT
}

lint

And now you can send links to Git repositories to your service to check them for Bash errors.

curl -H "Accept: application/json" \
http://localhost:8000/shellcheck?git_repository=https://github.com/lukasmartinelli/nigit.git

Security

You should never expose this script directly to the internet. Shell scripts that take input from external are always vulnerable to different attack vectors.

A better approach is to run nigit in a Docker container and access it from your other micro services and never exposing it to the public. This is still handy because you can isolate that old program and act as if it is an API to your other micro services.

Develop

You need a Go workspace to get started.

Install Dependencies

Several dependencies are required.

go get "github.com/codegangsta/cli"
go get "github.com/op/go-logging"

Build

Create a executable using the standard Go build tool.

go build

Cross Compile Release

We use gox to create distributable binaries for Windows, OSX and Linux.

docker run --rm -v "$(pwd)":/usr/src/nigit -w /usr/src/nigit tcnksm/gox:1.4.2-light

More Repositories

1

pgfutter

Import CSV and JSON into PostgreSQL the easy way
Go
1,311
star
2

py14

Python to C++ 14 transpiler
C++
573
star
3

pipecat

Connect UNIX pipes and message queues
Go
435
star
4

pgclimb

Export data from PostgreSQL into different data formats
Go
386
star
5

redis-pipe

Treat Redis Lists like Unix Pipes
Go
283
star
6

postgis-editor

An accessible PostGIS query editor and visualizer.
JavaScript
192
star
7

mapbox-gl-inspect

Inspection plugin for Mapbox GL JS
JavaScript
142
star
8

naturalearthtiles

Natural Earth vector tiles (MVT) and raster tiles free and ready to use.
PLpgSQL
89
star
9

hwk

A Haskell based awk and sed alternative
Haskell
67
star
10

osm-noise-pollution

Approximate global noise pollution with OSM data and very simple noise model
Shell
66
star
11

php-dos-attack

Exploit json_decode vulnerability of PHP
PHP
35
star
12

osm-activity

Show global OpenStreetMap activity on a map
JavaScript
30
star
13

swissdem

Digital Elevation Model for Switzerland from SRTM (1 arc second / 25m) as download
Shell
17
star
14

osm-lakelines

Calculate nice centered linestrings for labelling OpenStreetMap lakes
Shell
15
star
15

px-to-csv

Convert PC-Axis files to CSV
JavaScript
14
star
16

mbtoolbox

MBTiles tools for optimizing and verifying MBTiles files
Python
13
star
17

push-it

Plays an encouraging sound when you do a git push
Shell
13
star
18

ghrr

Create realtime apps on top of GitHub
JavaScript
12
star
19

sharpen

Solve algorithmic Python challenges to sharpen the tools.
Python
11
star
20

detectivegit

Detective git takes a look at your repo and shows the hotspots and possible bugs.
JavaScript
9
star
21

osm-qa-filter

Extract GeoJSON features from OSM QA tiles
JavaScript
9
star
22

osm-simple-features

Defines an opinionated mapping from OSM to simple GeoJSON features with multiple layers and defined schemas.
JavaScript
7
star
23

swissnames

Curated extracts from the free swissNAMES3D data set from swisstopo.
Shell
5
star
24

delptr

Informs the world about people who still use naked pointers in C++
JavaScript
5
star
25

location-history-to-geojson

Turn your Google Location History into a GeoJSON feature collection
JavaScript
3
star
26

lukasmartinelli.github.io

Personal blog and portfolio.
HTML
2
star
27

battle-of-britain-map

A Mapbox GL map showcasing the air battle of Britain
CSS
2
star
28

biketour

Tracking my bike tour from Switzerland to Greece
HTML
1
star