Last active
November 16, 2017 08:31
-
-
Save ilyaglow/7372ff280ecc57356a43e00164c18707 to your computer and use it in GitHub Desktop.
Maltrail's trails.csv as an API service
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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