diff --git a/README.md b/README.md index 52f3618..78974b1 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,11 @@ -![Build Status](https://travis-ci.org/niilo/clamav-rest.svg) [![Docker Pulls](https://img.shields.io/docker/pulls/niilo/clamav-rest.svg)]() - This is two in one docker image so it runs open source virus scanner ClamAV (https://www.clamav.net/), automatic virus definition updates as background process and REST api interface to interact with ClamAV process. -Travis CI build will build new release on weekly basis and push those to Docker hub [ClamAV-rest docker image](https://hub.docker.com/r/niilo/clamav-rest/). Virus definitions will be updated on every docker build. - ## Usage: Run clamav-rest docker image: ```bash -docker run -p 9000:9000 --rm -it niilo/clamav-rest +docker run -p 9000:9000 -v ./scan-target:/scan-target --rm -it clamav-go-rest ``` Test that service detects common test virus signature: @@ -39,6 +35,11 @@ Content-Length: 33 { Status: "OK", Description: "" } ``` +Test that service returns results for scan target directory: +```bash +$ curl http://localhost:9000/scanPath?path=/scan-target +``` + **Status codes:** - 200 - clean file = no KNOWN infections - 406 - INFECTED diff --git a/clamrest.go b/clamrest.go index 15332d5..49e8b52 100644 --- a/clamrest.go +++ b/clamrest.go @@ -1,6 +1,7 @@ package main import ( + "encoding/json" "fmt" "io" "io/ioutil" @@ -9,8 +10,6 @@ import ( "os" "strings" "time" - - "github.com/dutchcoders/go-clamd" ) var opts map[string]string @@ -20,7 +19,64 @@ func init() { } func home(w http.ResponseWriter, r *http.Request) { - io.WriteString(w, "...running...") + c := clamd.NewClamd(opts["CLAMD_PORT"]) + + response, err := c.Stats() + + if err != nil { + errJson, eErr := json.Marshal(err) + if eErr != nil { + fmt.Println(eErr) + return + } + fmt.Fprint(w, string(errJson)) + return + } + + resJson, eRes := json.Marshal(response) + if eRes != nil { + fmt.Println(eRes) + return + } + w.Header().Set("Content-Type", "application/json; charset=utf-8") + fmt.Fprint(w, string(resJson)) +} + +func scanPathHandler(w http.ResponseWriter, r *http.Request) { + paths, ok := r.URL.Query()["path"] + if !ok || len(paths[0]) < 1 { + log.Println("Url Param 'path' is missing") + return + } + + path := paths[0] + + c := clamd.NewClamd(opts["CLAMD_PORT"]) + response, err := c.AllMatchScanFile(path) + + if err != nil { + errJson, eErr := json.Marshal(err) + if eErr != nil { + fmt.Println(eErr) + return + } + fmt.Fprint(w, string(errJson)) + return + } + + var scanResults []*clamd.ScanResult + + for responseItem := range response { + scanResults = append(scanResults, responseItem) + } + + resJson, eRes := json.Marshal(scanResults) + if eRes != nil { + fmt.Println(eRes) + return + } + w.Header().Set("Content-Type", "application/json; charset=utf-8") + fmt.Fprint(w, string(resJson)) } //This is where the action happens. @@ -118,6 +174,7 @@ func main() { fmt.Printf("Connected to clamd on %v\n", opts["CLAMD_PORT"]) http.HandleFunc("/scan", scanHandler) + http.HandleFunc("/scanPath", scanPathHandler) http.HandleFunc("/", home) //Listen on port PORT