Virus scanning rest api
This commit is contained in:
parent
e061bcc1fb
commit
3e087ebb07
7 changed files with 100 additions and 14 deletions
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
target
|
||||||
|
src
|
||||||
|
*.swp
|
||||||
|
clamrest
|
||||||
|
pyenv
|
11
Dockerfile
Normal file
11
Dockerfile
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
FROM golang:1.3
|
||||||
|
|
||||||
|
ADD . /go/src/github.com/osterzel/clamrest
|
||||||
|
|
||||||
|
WORKDIR /go/src/github.com/osterzel/clamrest
|
||||||
|
RUN go get
|
||||||
|
RUN go install github.com/osterzel/clamrest
|
||||||
|
|
||||||
|
ENTRYPOINT /go/bin/clamrest
|
||||||
|
|
||||||
|
EXPOSE 8080
|
33
Makefile
Normal file
33
Makefile
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
SERVICE=clamrest
|
||||||
|
VERSION := dev
|
||||||
|
|
||||||
|
run-container: .clamav build-container
|
||||||
|
-@docker rm -f $(SERVICE)
|
||||||
|
@docker run -d -p 9000:9000 -e PORT=9000 --name $(SERVICE) --link clamd:clamd $(SERVICE):$(VERSION)
|
||||||
|
|
||||||
|
build-container:
|
||||||
|
docker build -t $(SERVICE):$(VERSION) .
|
||||||
|
|
||||||
|
run-slug: .clamav build-slug
|
||||||
|
-@docker rm -f $(SERVICE)
|
||||||
|
@docker run -d -v target/app:/app -p 9000:9000 -e PORT=9000 --name $(SERVICE) --link clamd:clamd flynn/slugrunner start web
|
||||||
|
@echo "Clamrest listening on port 9000"
|
||||||
|
|
||||||
|
build-slug:
|
||||||
|
-@rm -rf target
|
||||||
|
-@mkdir target
|
||||||
|
@tar cf - . | docker run --rm -i -a stdin -a stdout -a stderr flynn/slugbuilder -> target/slug.tgz
|
||||||
|
|
||||||
|
test:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.clamav:
|
||||||
|
@echo "Starting clamav docker image"
|
||||||
|
-@docker rm -f clamd
|
||||||
|
@docker run -d -p 3310:3310 --name clamd dinkel/clamavd
|
||||||
|
@echo "Waiting for clamd to respond"
|
||||||
|
@sleep 10
|
||||||
|
|
||||||
|
.restapi:
|
||||||
|
docker
|
27
clamrest.go
27
clamrest.go
|
@ -19,11 +19,11 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//This is where the action happens.
|
//This is where the action happens.
|
||||||
func uploadHandler(w http.ResponseWriter, r *http.Request) {
|
func scanHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
switch r.Method {
|
switch r.Method {
|
||||||
//POST takes the uploaded file(s) and saves it to disk.
|
//POST takes the uploaded file(s) and saves it to disk.
|
||||||
case "POST":
|
case "POST":
|
||||||
c := clamd.NewClamd(opts["CLAMD_CONNECTION"])
|
c := clamd.NewClamd(opts["CLAMD_PORT"])
|
||||||
//get the multipart reader for the request.
|
//get the multipart reader for the request.
|
||||||
reader, err := r.MultipartReader()
|
reader, err := r.MultipartReader()
|
||||||
|
|
||||||
|
@ -71,16 +71,16 @@ func main() {
|
||||||
opts[pair[0]] = pair[1]
|
opts[pair[0]] = pair[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts["CLAMD_CONNECTION"] == "" {
|
if opts["CLAMD_PORT"] == "" {
|
||||||
opts["CLAMD_CONNECTION"] = "tcp://localhost:3031"
|
opts["CLAMD_PORT"] = "tcp://localhost:3031"
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("Starting clamav rest bridge\n")
|
fmt.Printf("Starting clamav rest bridge\n")
|
||||||
fmt.Printf("Connecting to clamd on %v\n", opts["CLAMD_CONNECTION"])
|
fmt.Printf("Connecting to clamd on %v\n", opts["CLAMD_PORT"])
|
||||||
clamd_test := clamd.NewClamd(opts["CLAMD_CONNECTION"])
|
clamd_test := clamd.NewClamd(opts["CLAMD_PORT"])
|
||||||
clamd_test.Ping()
|
clamd_test.Ping()
|
||||||
version, err := clamd_test.Version()
|
version, err := clamd_test.Version()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Error getting clamd version: %v\n", err)
|
fmt.Printf("Error getting clamd version: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
@ -88,13 +88,12 @@ func main() {
|
||||||
for version_string := range version {
|
for version_string := range version {
|
||||||
fmt.Printf("Clamd version: %v\n", version_string)
|
fmt.Printf("Clamd version: %v\n", version_string)
|
||||||
}
|
}
|
||||||
fmt.Printf("Connected to clamd on %v\n", opts["CLAMD_CONNECTION"])
|
fmt.Printf("Connected to clamd on %v\n", opts["CLAMD_PORT"])
|
||||||
|
|
||||||
http.HandleFunc("/scan", uploadHandler)
|
http.HandleFunc("/scan", scanHandler)
|
||||||
|
|
||||||
//static file handler.
|
//Listen on port PORT
|
||||||
http.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir("assets"))))
|
if opts["PORT"] == "" { opts["PORT"] = "9000" }
|
||||||
|
fmt.Printf("Listening on port " + opts["PORT"])
|
||||||
//Listen on port 8080
|
http.ListenAndServe(":" + opts["PORT"], nil)
|
||||||
http.ListenAndServe(":3030", nil)
|
|
||||||
}
|
}
|
||||||
|
|
18
tests/features/steps/scanning.py
Normal file
18
tests/features/steps/scanning.py
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
from behave import *
|
||||||
|
from hamcrest import *
|
||||||
|
import requests
|
||||||
|
|
||||||
|
@given('I have a file with contents "{contents}"')
|
||||||
|
def step_imp(context, contents):
|
||||||
|
context.file_contents = contents
|
||||||
|
|
||||||
|
@when('I scan the file for a virus')
|
||||||
|
def step_impl(context):
|
||||||
|
files = { 'file': context.file_contents }
|
||||||
|
url = "http://localhost:9000"
|
||||||
|
r = requests.post(url + "/scan", files=files)
|
||||||
|
context.result = r
|
||||||
|
|
||||||
|
@then('I get a http status of "{status}"')
|
||||||
|
def step_impl(context, status):
|
||||||
|
assert_that(int(status), equal_to(context.result.status_code))
|
11
tests/features/virus-scan.feature
Normal file
11
tests/features/virus-scan.feature
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
Feature: testing virus scanning through rest API
|
||||||
|
|
||||||
|
Scenario Outline: scan files for viruses
|
||||||
|
Given I have a file with contents <content>
|
||||||
|
When I scan the file for a virus
|
||||||
|
Then I get a http status of <status>
|
||||||
|
|
||||||
|
Examples: virus_files
|
||||||
|
| content | status |
|
||||||
|
| "hello_world" | "200" |
|
||||||
|
| "X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*" | "500" |
|
9
tests/requirements.txt
Normal file
9
tests/requirements.txt
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
PyHamcrest==1.8.5
|
||||||
|
argparse==1.2.1
|
||||||
|
behave==1.2.5
|
||||||
|
enum34==1.0.4
|
||||||
|
parse==1.6.6
|
||||||
|
parse-type==0.3.4
|
||||||
|
requests==2.7.0
|
||||||
|
six==1.9.0
|
||||||
|
wsgiref==0.1.2
|
Loading…
Add table
Reference in a new issue