Skip to content

Instantly share code, notes, and snippets.

@ilyaglow
Last active November 16, 2017 08:31
Show Gist options
  • Save ilyaglow/7372ff280ecc57356a43e00164c18707 to your computer and use it in GitHub Desktop.
Save ilyaglow/7372ff280ecc57356a43e00164c18707 to your computer and use it in GitHub Desktop.
Maltrail's trails.csv as an API service
package main
import (
"encoding/csv"
"encoding/json"
"flag"
"fmt"
"io"
"log"
"net/http"
"os"
"time"
"github.com/gorilla/mux"
)
type Verdict struct {
Reason string `json:"reason"`
Source string `json:"source"`
}
type Entry struct {
Value string `json:"entry"`
Verdict
}
type DB struct {
Entries *[]Entry `json:"entries,omitempty"`
}
type Output struct {
Count int `json:"hits"`
Date time.Time `json:"timestamp"`
Entries []Entry `json:"entries"`
}
func main() {
var badEntries []Entry
host := flag.String("h", "127.0.0.1", "Host address to bind")
port := flag.Int("p", 9000, "Port to bind")
trails := flag.String("t", "trails.csv", "MalTrails CSV file")
flag.Parse()
db := &DB{&badEntries}
go db.fillDBFromTrails(*trails)
m := mux.NewRouter()
m.HandleFunc("/search/{item}", db.handleSearch).Methods("GET")
log.Println("Starting server...")
srv := &http.Server{
Handler: m,
Addr: fmt.Sprintf("%s:%d", *host, *port),
WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
}
log.Fatal(srv.ListenAndServe())
}
func (db *DB) fillDBFromTrails(name string) {
log.Println("Start filling database")
f, err := os.Open(name)
if err != nil {
log.Println("error opening file ", err)
os.Exit(1)
}
defer f.Close()
r := csv.NewReader(f)
for {
record, err := r.Read()
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
*db.Entries = append(*db.Entries, Entry{record[0], Verdict{record[1], record[2]}})
}
log.Println("Ended filling a database")
}
func (db *DB) handleSearch(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
f := searchEntry(vars["item"], db.Entries)
o := &Output{
Count: len(f),
Date: time.Now().UTC(),
Entries: f,
}
oj, err := json.Marshal(o)
if err != nil {
log.Println(err)
}
if o.Count == 0 {
w.WriteHeader(404)
}
w.Write(oj)
}
func searchEntry(s string, db *[]Entry) []Entry {
var found []Entry
for _, f := range *db {
if f.Value == s {
found = append(found, f)
}
}
return found
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment