<commit_before>package main

import (
	"database/sql"
	"encoding/xml"
	"io"
	"net/http"
	"os"
	"sync"
	"time"

	"github.com/geo-stanciu/go-utils/utils"
	"github.com/sirupsen/logrus"

	_ "github.com/denisenkom/go-mssqldb"
	_ "github.com/go-sql-driver/mysql"
	_ "github.com/lib/pq"
	//_ "github.com/mattn/go-oci8"
)

var (
	appName    = "RssGather"
	appVersion = "0.0.0.2"
	log        = logrus.New()
	audit      = utils.AuditLog{}
	db         *sql.DB
	dbutl      *utils.DbUtils
	config     = configuration{}
	queue      chan rssSource
)

func init() {
	// Log as JSON instead of the default ASCII formatter.
	log.Formatter = new(logrus.JSONFormatter)
	log.Level = logrus.DebugLevel

	dbutl = new(utils.DbUtils)

	queue = make(chan rssSource, 32)
}

// ParseSourceStream - Parse Source Stream
type ParseSourceStream func(rss *rssSource, source io.Reader) error

func main() {
	var err error
	var wg sync.WaitGroup

	cfgFile := "./conf.json"
	err = config.ReadFromFile(cfgFile)
	if err != nil {
		log.Println(err)
		return
	}

	err = dbutl.Connect2Database(&db, config.DbType, config.DbURL)
	if err != nil {
		log.Println(err)
		return
	}
	defer db.Close()

	audit.SetLogger(appName+"/"+appVersion, log, dbutl)
	audit.SetWaitGroup(&wg)
	defer audit.Close()

	mw := io.MultiWriter(os.Stdout, audit)
	log.Out = mw

	// initialize the rss readers
	for i := 0; i < config.RSSParalelReaders; i++ {
		go dealWithRSS(&wg)
	}

	for _, rss := range config.Rss {
		queue <- rss
	}

	done := rssSource{Done: true}
	for i := 0; i < config.RSSParalelReaders; i++ {
		queue <- done
	}

	audit.Log(nil, "gather rss", "Import done.")
	wg.Wait()
}

func dealWithRSS(wg *sync.WaitGroup) {
	for {
		rss := <-queue

		if rss.Done {
			break
		}

		wg.Add(1)

		err := getStreamFromURL(&rss, parseXMLSource)

		audit.Log(err,
			"get rss",
			"save rss",
			"lang", rss.Lang,
			"source", rss.SourceName,
			"link", rss.Link)

		time.Sleep(10 * time.Millisecond)
		wg.Done()
	}
}

func getStreamFromURL(rss *rssSource, callback ParseSourceStream) error {
	client := &http.Client{}

	req, err := http.NewRequest("GET", rss.Link, nil)
	if err != nil {
		return err
	}

	req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:58.0) Gecko/20100101 Firefox/58.0")

	response, err := client.Do(req)
	if err != nil {
		return err
	}
	defer response.Body.Close()

	err = callback(rss, response.Body)
	if err != nil {
		return err
	}

	return nil
}

func parseXMLSource(rss *rssSource, source io.Reader) error {
	tx, err := db.Begin()
	if err != nil {
		return err
	}
	defer tx.Rollback()

	decoder := xml.NewDecoder(source)

	var feed RssFeed
	feed.Source = rss.SourceName
	feed.Link = rss.Link
	feed.Language = rss.Lang

	for {
		t, _ := decoder.Token()
		if t == nil {
			break
		}

		switch se := t.(type) {
		case xml.StartElement:
			switch se.Name.Local {
			case "title":
				decoder.DecodeElement(&feed.Title, &se)
			case "description":
				decoder.DecodeElement(&feed.Description, &se)
			case "link":
				decoder.DecodeElement(&feed.Link, &se)
			case "language":
				decoder.DecodeElement(&feed.Language, &se)
			case "pubDate":
				decoder.DecodeElement(&feed.Date, &se)
			case "lastBuildDate":
				decoder.DecodeElement(&feed.LastDate, &se)
			case "item":
				var item RssItem
				decoder.DecodeElement(&item, &se)
				feed.Rss = append(feed.Rss, &item)
			}
		}
	}

	err = feed.Save(tx)
	if err != nil {
		return err
	}

	tx.Commit()

	return nil
}
<commit_msg>Check if erros were encountered<commit_after>package main

import (
	"database/sql"
	"encoding/xml"
	"errors"
	"io"
	"net/http"
	"os"
	"sync"
	"time"

	"github.com/geo-stanciu/go-utils/utils"
	"github.com/sirupsen/logrus"

	_ "github.com/denisenkom/go-mssqldb"
	_ "github.com/go-sql-driver/mysql"
	_ "github.com/lib/pq"
	//_ "github.com/mattn/go-oci8"
)

var (
	appName    = "RssGather"
	appVersion = "0.0.1.0"
	log        = logrus.New()
	audit      = utils.AuditLog{}
	db         *sql.DB
	dbutl      *utils.DbUtils
	config     = configuration{}
	queue      chan rssSource
	mutex      sync.RWMutex
	errFound   = false
)

func init() {
	// Log as JSON instead of the default ASCII formatter.
	log.Formatter = new(logrus.JSONFormatter)
	log.Level = logrus.DebugLevel

	dbutl = new(utils.DbUtils)

	queue = make(chan rssSource, 32)
}

// ParseSourceStream - Parse Source Stream
type ParseSourceStream func(rss *rssSource, source io.Reader) error

func main() {
	var err error
	var wg sync.WaitGroup

	cfgFile := "./conf.json"
	err = config.ReadFromFile(cfgFile)
	if err != nil {
		log.Println(err)
		return
	}

	err = dbutl.Connect2Database(&db, config.DbType, config.DbURL)
	if err != nil {
		log.Println(err)
		return
	}
	defer db.Close()

	audit.SetLogger(appName+"/"+appVersion, log, dbutl)
	audit.SetWaitGroup(&wg)
	defer audit.Close()

	mw := io.MultiWriter(os.Stdout, audit)
	log.Out = mw

	// initialize the rss readers
	for i := 0; i < config.RSSParalelReaders; i++ {
		go dealWithRSS(&wg)
	}

	for _, rss := range config.Rss {
		queue <- rss
	}

	done := rssSource{Done: true}
	for i := 0; i < config.RSSParalelReaders; i++ {
		wg.Add(1)
		queue <- done
	}

	// wait for all rss to be done
	wg.Wait()

	mutex.Lock()

	if errFound {
		err = errors.New("errors found while gathering rss")
		audit.Log(err, "gather rss", "Import failed.")
	} else {
		audit.Log(nil, "gather rss", "Import done.")
	}

	mutex.Unlock()

	// wait for all logs to be written
	wg.Wait()
}

func dealWithRSS(wg *sync.WaitGroup) {
	for {
		rss := <-queue

		if rss.Done {
			wg.Done()
			break
		}

		wg.Add(1)

		err := getStreamFromURL(&rss, parseXMLSource)

		if err != nil {
			mutex.Lock()
			errFound = true
			mutex.Unlock()
		}

		audit.Log(err,
			"get rss",
			"save rss",
			"lang", rss.Lang,
			"source", rss.SourceName,
			"link", rss.Link)

		time.Sleep(10 * time.Millisecond)
		wg.Done()
	}
}

func getStreamFromURL(rss *rssSource, callback ParseSourceStream) error {
	client := &http.Client{}

	req, err := http.NewRequest("GET", rss.Link, nil)
	if err != nil {
		return err
	}

	req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:58.0) Gecko/20100101 Firefox/58.0")

	response, err := client.Do(req)
	if err != nil {
		return err
	}
	defer response.Body.Close()

	err = callback(rss, response.Body)
	if err != nil {
		return err
	}

	return nil
}

func parseXMLSource(rss *rssSource, source io.Reader) error {
	tx, err := db.Begin()
	if err != nil {
		return err
	}
	defer tx.Rollback()

	decoder := xml.NewDecoder(source)

	var feed RssFeed
	feed.Source = rss.SourceName
	feed.Link = rss.Link
	feed.Language = rss.Lang

	for {
		t, _ := decoder.Token()
		if t == nil {
			break
		}

		switch se := t.(type) {
		case xml.StartElement:
			switch se.Name.Local {
			case "title":
				decoder.DecodeElement(&feed.Title, &se)
			case "description":
				decoder.DecodeElement(&feed.Description, &se)
			case "link":
				decoder.DecodeElement(&feed.Link, &se)
			case "language":
				decoder.DecodeElement(&feed.Language, &se)
			case "pubDate":
				decoder.DecodeElement(&feed.Date, &se)
			case "lastBuildDate":
				decoder.DecodeElement(&feed.LastDate, &se)
			case "item":
				var item RssItem
				decoder.DecodeElement(&item, &se)
				feed.Rss = append(feed.Rss, &item)
			}
		}
	}

	err = feed.Save(tx)
	if err != nil {
		return err
	}

	tx.Commit()

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"de.fraxxor.gofrax/gomin/input/gofilereader"
	"de.fraxxor.gofrax/gomin/input/godirectoryreader"
	"de.fraxxor.gofrax/gomin/input/gofilecollector"
	"de.fraxxor.gofrax/gomin/processing/pfile"
)

func main() {
	fmt.Println("Hello World")
	var reader gofilereader.Gofilereader
	reader = new(gofilereader.GofilereaderFS)
	content, err := reader.ContentOf("D:/Programmierung/Go/rsrc/testfile.txt")
	if err != nil {
		fmt.Printf("Error on Read: %v", err)
	} else {
		fmt.Printf("Successfully read the following:\n%s\n", content)
	}
	dirReader := new(godirectoryreader.GodirectoryreaderFS)
	godir, err := dirReader.ReadDirectory("D:/Programmierung/Go/rsrc")
	if err != nil {
		fmt.Printf("Error on DirRead: %v", err)
	} else {
		fmt.Printf("Directory = \n%s\n", godir)
	}
	var dirReaderAbstr godirectoryreader.Godirectoryreader
	dirReaderAbstr = dirReader
	dirCollector := gofilecollector.MakeGofilecollector(&dirReaderAbstr, &reader)
	gofilesRecursive := dirCollector.CollectRecursive("D:/Programmierung/Go/src/de.fraxxor.gofrax/gomin")
	var processor pfile.PfileProcessor
	processor = new(pfile.ProcessGofileImpl)
	for _, gf := range gofilesRecursive {
		fmt.Printf("Gofile: %s\n", gf.AbsolutePath)
		processedFile, err := processor.ProcessGofile(&gf)
		if (err != nil) {
			panic(err)
		}
		fmt.Printf("Pfile: %s\n", (*processedFile).PackageAbsolutePath)
	}
}
<commit_msg>Added line to determine current exe position<commit_after>package main

import (
	"fmt"
	"os"
    "path/filepath"
	"de.fraxxor.gofrax/gomin/input/gofilereader"
	"de.fraxxor.gofrax/gomin/input/godirectoryreader"
	"de.fraxxor.gofrax/gomin/input/gofilecollector"
	"de.fraxxor.gofrax/gomin/processing/pfile"
)

func main() {
	dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err == nil {
		fmt.Printf("Filename is <%s>.\n", dir)
	}
	fmt.Println("Hello World")
	var reader gofilereader.Gofilereader
	reader = new(gofilereader.GofilereaderFS)
	content, err := reader.ContentOf("D:/Programmierung/Go/rsrc/testfile.txt")
	if err != nil {
		fmt.Printf("Error on Read: %v", err)
	} else {
		fmt.Printf("Successfully read the following:\n%s\n", content)
	}
	dirReader := new(godirectoryreader.GodirectoryreaderFS)
	godir, err := dirReader.ReadDirectory("D:/Programmierung/Go/rsrc")
	if err != nil {
		fmt.Printf("Error on DirRead: %v", err)
	} else {
		fmt.Printf("Directory = \n%s\n", godir)
	}
	var dirReaderAbstr godirectoryreader.Godirectoryreader
	dirReaderAbstr = dirReader
	dirCollector := gofilecollector.MakeGofilecollector(&dirReaderAbstr, &reader)
	gofilesRecursive := dirCollector.CollectRecursive("D:/Programmierung/Go/src/de.fraxxor.gofrax/gomin")
	var processor pfile.PfileProcessor
	processor = new(pfile.ProcessGofileImpl)
	for _, gf := range gofilesRecursive {
		fmt.Printf("Gofile: %s\n", gf.AbsolutePath)
		processedFile, err := processor.ProcessGofile(&gf)
		if (err != nil) {
			panic(err)
		}
		fmt.Printf("Pfile: %s\n", (*processedFile).PackageAbsolutePath)
	}
}
<|endoftext|>


<commit_before>package compressutil

import (
	"bytes"
	"compress/gzip"
	"encoding/json"
	"testing"
)

func TestCompressUtil_CompressSnappy(t *testing.T) {
	input := map[string]interface{}{
		"sample":       "data",
		"verification": "process",
	}

	// Encode input into JSON
	var buf bytes.Buffer
	enc := json.NewEncoder(&buf)
	if err := enc.Encode(input); err != nil {
		t.Fatal(err)
	}
	inputJSONBytes := buf.Bytes()

	// Set Snappy compression in the configuration
	compressionConfig := &CompressionConfig{
		Type: CompressionTypeSnappy,
	}

	// Compress the input
	compressedJSONBytes, err := Compress(inputJSONBytes, compressionConfig)
	if err != nil {
		t.Fatal(err)
	}

	decompressedJSONBytes, wasNotCompressed, err := Decompress(compressedJSONBytes)
	if err != nil {
		t.Fatal(err)
	}

	// Check if the input for decompress was not compressed in the first place
	if wasNotCompressed {
		t.Fatalf("bad: expected compressed bytes")
	}

	// Compare the value after decompression
	if string(inputJSONBytes) != string(decompressedJSONBytes) {
		t.Fatalf("bad: decompressed value;\nexpected: %q\nactual: %q", string(inputJSONBytes), string(decompressedJSONBytes))
	}
}

func TestCompressUtil_CompressDecompress(t *testing.T) {
	input := map[string]interface{}{
		"sample":       "data",
		"verification": "process",
	}

	// Encode input into JSON
	var buf bytes.Buffer
	enc := json.NewEncoder(&buf)
	if err := enc.Encode(input); err != nil {
		t.Fatal(err)
	}

	inputJSONBytes := buf.Bytes()
	// Test nil configuration
	if _, err := Compress(inputJSONBytes, nil); err == nil {
		t.Fatal("expected an error")
	}

	// Test invalid configuration
	if _, err := Compress(inputJSONBytes, &CompressionConfig{}); err == nil {
		t.Fatal("expected an error")
	}

	// Compress input using lzw format
	compressedJSONBytes, err := Compress(inputJSONBytes, &CompressionConfig{
		Type: CompressionTypeLZW,
	})
	if err != nil {
		t.Fatal("expected an error")
	}
	if len(compressedJSONBytes) == 0 {
		t.Fatal("failed to compress data in lzw format")
	}
	// Check the presence of the canary
	if compressedJSONBytes[0] != CompressionCanaryLZW {
		t.Fatalf("bad: compression canary: expected: %d actual: %d", CompressionCanaryLZW, compressedJSONBytes[0])
	}

	// Decompress the input and check the output
	decompressedJSONBytes, uncompressed, err := Decompress(compressedJSONBytes)
	if err != nil {
		t.Fatal(err)
	}
	if uncompressed {
		t.Fatal("failed to recognize compressed data")
	}
	if len(decompressedJSONBytes) == 0 {
		t.Fatal("failed to decompress lzw formatted data")
	}

	if string(inputJSONBytes) != string(decompressedJSONBytes) {
		t.Fatalf("bad: mismatch: inputJSONBytes: %s\n decompressedJSONBytes: %s", string(inputJSONBytes), string(decompressedJSONBytes))
	}

	// Compress input using Gzip format, assume DefaultCompression
	compressedJSONBytes, err = Compress(inputJSONBytes, &CompressionConfig{
		Type: CompressionTypeGzip,
	})
	if err != nil {
		t.Fatal("expected an error")
	}
	if len(compressedJSONBytes) == 0 {
		t.Fatal("failed to compress data in lzw format")
	}
	// Check the presence of the canary
	if compressedJSONBytes[0] != CompressionCanaryGzip {
		t.Fatalf("bad: compression canary: expected: %d actual: %d", CompressionCanaryGzip, compressedJSONBytes[0])
	}

	// Decompress the input and check the output
	decompressedJSONBytes, uncompressed, err = Decompress(compressedJSONBytes)
	if err != nil {
		t.Fatal(err)
	}
	if uncompressed {
		t.Fatal("failed to recognize compressed data")
	}
	if len(decompressedJSONBytes) == 0 {
		t.Fatal("failed to decompress lzw formatted data")
	}

	if string(inputJSONBytes) != string(decompressedJSONBytes) {
		t.Fatalf("bad: mismatch: inputJSONBytes: %s\n decompressedJSONBytes: %s", string(inputJSONBytes), string(decompressedJSONBytes))
	}

	// Compress input using Gzip format: DefaultCompression
	compressedJSONBytes, err = Compress(inputJSONBytes, &CompressionConfig{
		Type:                 CompressionTypeGzip,
		GzipCompressionLevel: gzip.DefaultCompression,
	})
	if err != nil {
		t.Fatal("expected an error")
	}
	if len(compressedJSONBytes) == 0 {
		t.Fatal("failed to compress data in lzw format")
	}
	// Check the presence of the canary
	if compressedJSONBytes[0] != CompressionCanaryGzip {
		t.Fatalf("bad: compression canary: expected: %d actual: %d", CompressionCanaryGzip, compressedJSONBytes[0])
	}

	// Decompress the input and check the output
	decompressedJSONBytes, uncompressed, err = Decompress(compressedJSONBytes)
	if err != nil {
		t.Fatal(err)
	}
	if uncompressed {
		t.Fatal("failed to recognize compressed data")
	}
	if len(decompressedJSONBytes) == 0 {
		t.Fatal("failed to decompress lzw formatted data")
	}

	if string(inputJSONBytes) != string(decompressedJSONBytes) {
		t.Fatalf("bad: mismatch: inputJSONBytes: %s\n decompressedJSONBytes: %s", string(inputJSONBytes), string(decompressedJSONBytes))
	}

	// Compress input using Gzip format, BestCompression
	compressedJSONBytes, err = Compress(inputJSONBytes, &CompressionConfig{
		Type:                 CompressionTypeGzip,
		GzipCompressionLevel: gzip.BestCompression,
	})
	if err != nil {
		t.Fatal("expected an error")
	}
	if len(compressedJSONBytes) == 0 {
		t.Fatal("failed to compress data in lzw format")
	}
	// Check the presence of the canary
	if compressedJSONBytes[0] != CompressionCanaryGzip {
		t.Fatalf("bad: compression canary: expected: %d actual: %d", CompressionCanaryGzip, compressedJSONBytes[0])
	}

	// Decompress the input and check the output
	decompressedJSONBytes, uncompressed, err = Decompress(compressedJSONBytes)
	if err != nil {
		t.Fatal(err)
	}
	if uncompressed {
		t.Fatal("failed to recognize compressed data")
	}
	if len(decompressedJSONBytes) == 0 {
		t.Fatal("failed to decompress lzw formatted data")
	}

	if string(inputJSONBytes) != string(decompressedJSONBytes) {
		t.Fatalf("bad: mismatch: inputJSONBytes: %s\n decompressedJSONBytes: %s", string(inputJSONBytes), string(decompressedJSONBytes))
	}

	// Compress input using Gzip format, BestSpeed
	compressedJSONBytes, err = Compress(inputJSONBytes, &CompressionConfig{
		Type:                 CompressionTypeGzip,
		GzipCompressionLevel: gzip.BestSpeed,
	})
	if err != nil {
		t.Fatal("expected an error")
	}
	if len(compressedJSONBytes) == 0 {
		t.Fatal("failed to compress data in lzw format")
	}
	// Check the presence of the canary
	if compressedJSONBytes[0] != CompressionCanaryGzip {
		t.Fatalf("bad: compression canary: expected: %d actual: %d",
			CompressionCanaryGzip, compressedJSONBytes[0])
	}

	// Decompress the input and check the output
	decompressedJSONBytes, uncompressed, err = Decompress(compressedJSONBytes)
	if err != nil {
		t.Fatal(err)
	}
	if uncompressed {
		t.Fatal("failed to recognize compressed data")
	}
	if len(decompressedJSONBytes) == 0 {
		t.Fatal("failed to decompress lzw formatted data")
	}

	if string(inputJSONBytes) != string(decompressedJSONBytes) {
		t.Fatalf("bad: mismatch: inputJSONBytes: %s\n decompressedJSONBytes: %s", string(inputJSONBytes), string(decompressedJSONBytes))
	}
}
<commit_msg>Tablify compression tests (#5405)<commit_after>package compressutil

import (
	"bytes"
	"compress/gzip"
	"testing"
)

func TestCompressUtil_CompressDecompress(t *testing.T) {
	t.Parallel()

	tests := []struct {
		compressionType   string
		compressionConfig CompressionConfig
		canary            byte
	}{
		{"GZIP default implicit",
			CompressionConfig{Type: CompressionTypeGzip},
			CompressionCanaryGzip,
		},
		{"GZIP default explicit",
			CompressionConfig{Type: CompressionTypeGzip, GzipCompressionLevel: gzip.DefaultCompression},
			CompressionCanaryGzip,
		},
		{"GZIP best speed",
			CompressionConfig{Type: CompressionTypeGzip, GzipCompressionLevel: gzip.BestSpeed},
			CompressionCanaryGzip,
		},
		{"GZIP best compression",
			CompressionConfig{Type: CompressionTypeGzip, GzipCompressionLevel: gzip.BestCompression},
			CompressionCanaryGzip,
		},
		{"Snappy",
			CompressionConfig{Type: CompressionTypeSnappy},
			CompressionCanarySnappy,
		},
		{"LZ4",
			CompressionConfig{Type: CompressionTypeLZ4},
			CompressionCanaryLZ4,
		},
		{"LZW",
			CompressionConfig{Type: CompressionTypeLZW},
			CompressionCanaryLZW,
		},
	}

	inputJSONBytes := []byte(`{"sample":"data","verification":"process"}`)

	for _, test := range tests {
		// Compress the input
		compressedJSONBytes, err := Compress(inputJSONBytes, &test.compressionConfig)
		if err != nil {
			t.Fatalf("compress error (%s): %s", test.compressionType, err)
		}
		if len(compressedJSONBytes) == 0 {
			t.Fatalf("failed to compress data in %s format", test.compressionType)
		}

		// Check the presence of the canary
		if compressedJSONBytes[0] != test.canary {
			t.Fatalf("bad (%s): compression canary: expected: %d actual: %d", test.compressionType, test.canary, compressedJSONBytes[0])
		}

		decompressedJSONBytes, wasNotCompressed, err := Decompress(compressedJSONBytes)
		if err != nil {
			t.Fatalf("decompress error (%s): %s", test.compressionType, err)
		}

		// Check if the input for decompress was not compressed in the first place
		if wasNotCompressed {
			t.Fatalf("bad (%s): expected compressed bytes", test.compressionType)
		}

		if len(decompressedJSONBytes) == 0 {
			t.Fatalf("bad (%s): expected decompressed bytes", test.compressionType)
		}

		// Compare the value after decompression
		if !bytes.Equal(inputJSONBytes, decompressedJSONBytes) {
			t.Fatalf("bad (%s): decompressed value;\nexpected: %q\nactual: %q", test.compressionType, string(inputJSONBytes), string(decompressedJSONBytes))
		}
	}
}

func TestCompressUtil_InvalidConfigurations(t *testing.T) {
	t.Parallel()

	inputJSONBytes := []byte(`{"sample":"data","verification":"process"}`)

	// Test nil configuration
	if _, err := Compress(inputJSONBytes, nil); err == nil {
		t.Fatal("expected an error")
	}

	// Test invalid configuration
	if _, err := Compress(inputJSONBytes, &CompressionConfig{}); err == nil {
		t.Fatal("expected an error")
	}
}
<|endoftext|>


<commit_before>package main

import (
	"./aws"
	"./db"
	"encoding/json"
	"fmt"
	// "io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strconv"
)

const (
	imagesRoot = "/var/www/like-av.xyz/images/"
)

type Payload struct {
	Id         string
	Name       string
	File       string
	Img        string
	Similarity string
}

func UploadHandler(w http.ResponseWriter, r *http.Request) {
	// allow cross domain AJAX requests
	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Set("Content-Type", "application/json")

	if r.Method != "POST" {
		http.Error(w, "Allowed POST method only", http.StatusMethodNotAllowed)
		return
	}

	err := r.ParseMultipartForm(32 << 20) // maxMemory
	if err != nil {
		log.Fatal(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	file, handler, err := r.FormFile("upload")
	if err != nil {
		log.Fatal(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	defer file.Close()

	b, err := ioutil.ReadAll(file)
	if err != nil {
		log.Fatal(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	js, err := searchFace(b, handler.Filename)
	if err != nil {
		log.Fatal(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Write(js)
}

func main() {
	http.HandleFunc("/upload", UploadHandler) // set router
	err := http.ListenAndServe(":9090", nil)  // set listen port
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}

func searchFace(b []byte, fileName string) ([]byte, error) {
	result, err := aws.SearchFacesByImage(b)
	if err != nil {
		return nil, err
	}

	emptyPayload := Payload{
		Id:   "",
		File: fileName,
	}

	if result == nil {
		js, err := json.Marshal(emptyPayload)
		if err != nil {
			return nil, err
		}

		return js, nil
	} else {
		id := result.Id
		similarity := strconv.FormatFloat(result.Similarity, 'f', 2, 64)
		fmt.Println(id)
		fmt.Println(similarity)

		os.Mkdir(imagesRoot+id, os.ModePerm)
		err := ioutil.WriteFile(imagesRoot+id+"/"+fileName, b, 0644)
		if err != nil {
			return nil, err
		}

		val := db.FindOneActress(id)
		fmt.Println(val)

		if len(val) == 0 {
			js, err := json.Marshal(emptyPayload)
			if err != nil {
				return nil, err
			}

			return js, nil
		}

		payload := Payload{
			Id:         id,
			Name:       val["name"],
			File:       fileName,
			Img:        val["img"],
			Similarity: similarity,
		}
		js, err := json.Marshal(payload)
		if err != nil {
			return nil, err
		}

		return js, nil
	}
}
<commit_msg>Add FeedbackHandler method<commit_after>package main

import (
	"./aws"
	"./db"
	"encoding/json"
	"fmt"
	// "io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strconv"
)

const (
	imagesRoot = "/var/www/like-av.xyz/images/"
)

type Payload struct {
	Id         string
	Name       string
	File       string
	Img        string
	Similarity string
}

func UploadHandler(w http.ResponseWriter, r *http.Request) {
	// allow cross domain AJAX requests
	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Set("Content-Type", "application/json")

	if r.Method != "POST" {
		http.Error(w, "Allowed POST method only", http.StatusMethodNotAllowed)
		return
	}

	err := r.ParseMultipartForm(32 << 20) // maxMemory
	if err != nil {
		log.Fatal(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	file, handler, err := r.FormFile("upload")
	if err != nil {
		log.Fatal(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	defer file.Close()

	b, err := ioutil.ReadAll(file)
	if err != nil {
		log.Fatal(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	js, err := searchFace(b, handler.Filename)
	if err != nil {
		log.Fatal(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Write(js)
}

func FeedbackHandler(w http.ResponseWriter, r *http.Request) {
	// allow cross domain AJAX requests
	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Set("Content-Type", "application/json")

	if r.Method != "POST" {
		http.Error(w, "Allowed POST method only", http.StatusMethodNotAllowed)
		return
	}

	decoder := json.NewDecoder(r.Body)
	val := map[string]string{}
	err := decoder.Decode(&val)
	if err != nil {
		log.Fatal(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	fmt.Println(val)
	db.UpsertOneFeedback(val["id"], val["ox"], val["image"])
}

func main() {
	http.HandleFunc("/upload", UploadHandler)     // set router
	http.HandleFunc("/feedback", FeedbackHandler) // set router
	err := http.ListenAndServe(":9090", nil)      // set listen port
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}

func searchFace(b []byte, fileName string) ([]byte, error) {
	result, err := aws.SearchFacesByImage(b)
	if err != nil {
		return nil, err
	}

	emptyPayload := Payload{
		Id:   "",
		File: fileName,
	}

	if result == nil {
		js, err := json.Marshal(emptyPayload)
		if err != nil {
			return nil, err
		}

		return js, nil
	} else {
		id := result.Id
		similarity := strconv.FormatFloat(result.Similarity, 'f', 2, 64)
		fmt.Println(id)
		fmt.Println(similarity)

		os.Mkdir(imagesRoot+id, os.ModePerm)
		err := ioutil.WriteFile(imagesRoot+id+"/"+fileName, b, 0644)
		if err != nil {
			return nil, err
		}

		val := db.FindOneActress(id)
		fmt.Println(val)

		if len(val) == 0 {
			js, err := json.Marshal(emptyPayload)
			if err != nil {
				return nil, err
			}

			return js, nil
		}

		payload := Payload{
			Id:         id,
			Name:       val["name"],
			File:       fileName,
			Img:        val["img"],
			Similarity: similarity,
		}
		js, err := json.Marshal(payload)
		if err != nil {
			return nil, err
		}

		return js, nil
	}
}
<|endoftext|>


<commit_before>// Copyright 2016 Circonus, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// User API support - Fetch, Update, and Search
// See: https://login.circonus.com/resources/api/calls/user
// Note: Create and Delete are not supported directly via the User API
// endpoint. See the Account endpoint for inviting and removing users
// from specific accounts.

package api

import (
	"encoding/json"
	"fmt"
	"net/url"
	"regexp"

	"github.com/circonus-labs/circonus-gometrics/api/config"
)

// UserContactInfo defines known contact details
type UserContactInfo struct {
	SMS  string `json:"sms,omitempty"`
	XMPP string `json:"xmpp,omitempty"`
}

// User defines a user. See https://login.circonus.com/resources/api/calls/user for more information.
type User struct {
	CID         string          `json:"_cid,omitempty"`
	ContactInfo UserContactInfo `json:"contact_info,omitempty"`
	Email       string          `json:"email"`
	Firstname   string          `json:"firstname"`
	Lastname    string          `json:"lastname"`
}

// FetchUser retrieves a specific user. Pass a valid cid or nil for '/user/current'.
func (a *API) FetchUser(cid CIDType) (*User, error) {
	var userCID string

	if cid == nil || *cid == "" {
		userCID = config.UserPrefix + "/current"
	} else {
		userCID = string(*cid)
	}

	matched, err := regexp.MatchString(config.UserCIDRegex, userCID)
	if err != nil {
		return nil, err
	}
	if !matched {
		return nil, fmt.Errorf("Invalid user CID [%s]", userCID)
	}

	result, err := a.Get(userCID)
	if err != nil {
		return nil, err
	}

	if a.Debug {
		a.Log.Printf("[DEBUG] fetch user, received JSON: %s", string(result))
	}

	user := new(User)
	if err := json.Unmarshal(result, user); err != nil {
		return nil, err
	}

	return user, nil
}

// FetchUsers retrieves all users available to API Token.
func (a *API) FetchUsers() (*[]User, error) {
	result, err := a.Get(config.UserPrefix)
	if err != nil {
		return nil, err
	}

	var users []User
	if err := json.Unmarshal(result, &users); err != nil {
		return nil, err
	}

	return &users, nil
}

// UpdateUser updates passed user.
func (a *API) UpdateUser(cfg *User) (*User, error) {
	if cfg == nil {
		return nil, fmt.Errorf("Invalid user config [nil]")
	}

	userCID := string(cfg.CID)

	matched, err := regexp.MatchString(config.UserCIDRegex, userCID)
	if err != nil {
		return nil, err
	}
	if !matched {
		return nil, fmt.Errorf("Invalid user CID [%s]", userCID)
	}

	jsonCfg, err := json.Marshal(cfg)
	if err != nil {
		return nil, err
	}

	if a.Debug {
		a.Log.Printf("[DEBUG] update user, sending JSON: %s", string(jsonCfg))
	}

	result, err := a.Put(userCID, jsonCfg)
	if err != nil {
		return nil, err
	}

	user := &User{}
	if err := json.Unmarshal(result, user); err != nil {
		return nil, err
	}

	return user, nil
}

// SearchUsers returns users matching a filter (search queries
// are not suppoted by the user endpoint). Pass nil as filter for all
// users available to the API Token.
func (a *API) SearchUsers(filterCriteria *SearchFilterType) (*[]User, error) {
	q := url.Values{}

	if filterCriteria != nil && len(*filterCriteria) > 0 {
		for filter, criteria := range *filterCriteria {
			for _, val := range criteria {
				q.Add(filter, val)
			}
		}
	}

	if q.Encode() == "" {
		return a.FetchUsers()
	}

	reqURL := url.URL{
		Path:     config.UserPrefix,
		RawQuery: q.Encode(),
	}

	result, err := a.Get(reqURL.String())
	if err != nil {
		return nil, fmt.Errorf("[ERROR] API call error %+v", err)
	}

	var users []User
	if err := json.Unmarshal(result, &users); err != nil {
		return nil, err
	}

	return &users, nil
}
<commit_msg>upd: documentation<commit_after>// Copyright 2016 Circonus, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// User API support - Fetch, Update, and Search
// See: https://login.circonus.com/resources/api/calls/user
// Note: Create and Delete are not supported directly via the User API
// endpoint. See the Account endpoint for inviting and removing users
// from specific accounts.

package api

import (
	"encoding/json"
	"fmt"
	"net/url"
	"regexp"

	"github.com/circonus-labs/circonus-gometrics/api/config"
)

// UserContactInfo defines known contact details
type UserContactInfo struct {
	SMS  string `json:"sms,omitempty"`
	XMPP string `json:"xmpp,omitempty"`
}

// User defines a user. See https://login.circonus.com/resources/api/calls/user for more information.
type User struct {
	CID         string          `json:"_cid,omitempty"`
	ContactInfo UserContactInfo `json:"contact_info,omitempty"`
	Email       string          `json:"email"`
	Firstname   string          `json:"firstname"`
	Lastname    string          `json:"lastname"`
}

// FetchUser retrieves user with passed cid. Pass nil for '/user/current'.
func (a *API) FetchUser(cid CIDType) (*User, error) {
	var userCID string

	if cid == nil || *cid == "" {
		userCID = config.UserPrefix + "/current"
	} else {
		userCID = string(*cid)
	}

	matched, err := regexp.MatchString(config.UserCIDRegex, userCID)
	if err != nil {
		return nil, err
	}
	if !matched {
		return nil, fmt.Errorf("Invalid user CID [%s]", userCID)
	}

	result, err := a.Get(userCID)
	if err != nil {
		return nil, err
	}

	if a.Debug {
		a.Log.Printf("[DEBUG] fetch user, received JSON: %s", string(result))
	}

	user := new(User)
	if err := json.Unmarshal(result, user); err != nil {
		return nil, err
	}

	return user, nil
}

// FetchUsers retrieves all users available to API Token.
func (a *API) FetchUsers() (*[]User, error) {
	result, err := a.Get(config.UserPrefix)
	if err != nil {
		return nil, err
	}

	var users []User
	if err := json.Unmarshal(result, &users); err != nil {
		return nil, err
	}

	return &users, nil
}

// UpdateUser updates passed user.
func (a *API) UpdateUser(cfg *User) (*User, error) {
	if cfg == nil {
		return nil, fmt.Errorf("Invalid user config [nil]")
	}

	userCID := string(cfg.CID)

	matched, err := regexp.MatchString(config.UserCIDRegex, userCID)
	if err != nil {
		return nil, err
	}
	if !matched {
		return nil, fmt.Errorf("Invalid user CID [%s]", userCID)
	}

	jsonCfg, err := json.Marshal(cfg)
	if err != nil {
		return nil, err
	}

	if a.Debug {
		a.Log.Printf("[DEBUG] update user, sending JSON: %s", string(jsonCfg))
	}

	result, err := a.Put(userCID, jsonCfg)
	if err != nil {
		return nil, err
	}

	user := &User{}
	if err := json.Unmarshal(result, user); err != nil {
		return nil, err
	}

	return user, nil
}

// SearchUsers returns users matching a filter (search queries
// are not suppoted by the user endpoint). Pass nil as filter for all
// users available to the API Token.
func (a *API) SearchUsers(filterCriteria *SearchFilterType) (*[]User, error) {
	q := url.Values{}

	if filterCriteria != nil && len(*filterCriteria) > 0 {
		for filter, criteria := range *filterCriteria {
			for _, val := range criteria {
				q.Add(filter, val)
			}
		}
	}

	if q.Encode() == "" {
		return a.FetchUsers()
	}

	reqURL := url.URL{
		Path:     config.UserPrefix,
		RawQuery: q.Encode(),
	}

	result, err := a.Get(reqURL.String())
	if err != nil {
		return nil, fmt.Errorf("[ERROR] API call error %+v", err)
	}

	var users []User
	if err := json.Unmarshal(result, &users); err != nil {
		return nil, err
	}

	return &users, nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/glaslos/tlsh"
)

var (
	// VERSION is set by the makefile
	VERSION = "v0.0.0"
	// BUILDDATE is set by the makefile
	BUILDDATE = ""
)

func main() {
	var file = flag.String("f", "", "path to the file to be hashed")
	var raw = flag.Bool("r", false, "set to get only the hash")
	var version = flag.Bool("version", false, "print version")
	flag.Parse()
	if *version {
		fmt.Printf("%s %s\n", VERSION, BUILDDATE)
		return
	}
	if *file == "" {
		fmt.Fprintf(os.Stderr, "Usage of %s [-f <file>]\n\n", os.Args[0])
		flag.PrintDefaults()
		fmt.Println()
		return
	}
	hash, err := tlsh.Hash(*file)
	if err != nil {
		fmt.Println(err)
		return
	}
	if *raw {
		fmt.Println(hash)
	} else {
		fmt.Printf("%s  %s\n", hash, *file)
	}
}
<commit_msg>Set parameter name for flag<commit_after>package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/glaslos/tlsh"
)

var (
	// VERSION is set by the makefile
	VERSION = "v0.0.0"
	// BUILDDATE is set by the makefile
	BUILDDATE = ""
)

func main() {
	var file = flag.String("f", "", "path to the `file` to be hashed")
	var raw = flag.Bool("r", false, "set to get only the hash")
	var version = flag.Bool("version", false, "print version")
	flag.Parse()
	if *version {
		fmt.Printf("%s %s\n", VERSION, BUILDDATE)
		return
	}
	if *file == "" {
		fmt.Fprintf(os.Stderr, "Usage of %s [-f <file>]\n\n", os.Args[0])
		flag.PrintDefaults()
		fmt.Println()
		return
	}
	hash, err := tlsh.Hash(*file)
	if err != nil {
		fmt.Println(err)
		return
	}
	if *raw {
		fmt.Println(hash)
	} else {
		fmt.Printf("%s  %s\n", hash, *file)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"
)

var wordCount map[string]int
var tagCount map[string]int

func main() {
	if len(os.Args) != 2 {
		fmt.Println("\n Usage: countFreq path/to/inputFile \n")
		return
	}

	// open the passed file
	file, err := os.Open(os.Args[1])
	if err != nil {
		panic(err.Error())
	}

	wordCount = make(map[string]int)
	tagCount = make(map[string]int)

	reader := bufio.NewReader(file)
	scanner := bufio.NewScanner(reader)
	scanner.Split(bufio.ScanLines)
	var tags []string

	for scanner.Scan() {
		members := strings.SplitAfter(scanner.Text(), " ")

		if tags == nil || len(members) < 2 {
			tags = []string{"*", "*", "*"}
		}

		if len(members) == 2 {
			wordCount[members[0]]++
			tags = append(tags[1:], members[1])
			tagCount[strings.Join(tags, " ")]++
		}
	}

	// print word counts
	for word, count := range wordCount {
		fmt.Println(word, count)
	}
	for tag, count := range tagCount {
		fmt.Println(tag, count)
	}
}
<commit_msg>add bigram counts<commit_after>package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"
)

var wordCount map[string]int
var biTagCount map[string]int
var triTagCount map[string]int

func main() {
	if len(os.Args) != 2 {
		fmt.Println("\n Usage: countFreq path/to/inputFile \n")
		return
	}

	// open the passed file
	file, err := os.Open(os.Args[1])
	if err != nil {
		panic(err.Error())
	}

	wordCount = make(map[string]int)
	biTagCount = make(map[string]int)
	triTagCount = make(map[string]int)

	reader := bufio.NewReader(file)
	scanner := bufio.NewScanner(reader)
	scanner.Split(bufio.ScanLines)
	var tags []string

	for scanner.Scan() {
		members := strings.SplitAfter(scanner.Text(), " ")

		if tags == nil || len(members) < 2 {
			tags = []string{"*", "*", "*"}
		}

		if len(members) == 2 {
			wordCount[members[0]]++
			tags = append(tags[1:], members[1])
			biTagCount[strings.Join(tags[1:], " ")]++
			triTagCount[strings.Join(tags, " ")]++
		}
	}

	// print word counts
	for word, count := range wordCount {
		fmt.Println(word, count)
	}

	fmt.Println("\nBi Tag Count:")
	for tag, count := range biTagCount {
		fmt.Println(tag, count)
	}

	fmt.Println("\nTri Tag Count:")
	for tag, count := range triTagCount {
		fmt.Println(tag, count)
	}
}
<|endoftext|>


<commit_before>package ultron

import (
	"fmt"
	"io"
	"io/ioutil"
	"net"
	"net/http"
	"time"

	"go.uber.org/zap"
)

type (
	// Attacker 定义一个事务、请求，需要确保该对象是Goroutine-safe
	Attacker interface {
		Name() string
		Fire() error
	}

	// HTTPPrepareFunc 构造http.Request函数，需要调用方定义，由HTTPAttacker来发送
	HTTPPrepareFunc func() (*http.Request, error)
	// HTTPResponseCheck http.Response校验函数，可由调用方自定义，如果返回error，则视为请求失败
	HTTPResponseCheck func(resp *http.Response, body []byte) error

	// HTTPAttacker http协议的Attacker实现
	HTTPAttacker struct {
		Client     *http.Client
		Prepare    HTTPPrepareFunc
		name       string
		CheckChain []HTTPResponseCheck
	}
)

var (
	// DefaultHTTPClient 默认http.Client
	// http://tleyden.github.io/blog/2016/11/21/tuning-the-go-http-client-library-for-load-testing/
	DefaultHTTPClient = &http.Client{
		Timeout: 90 * time.Second,
		Transport: &http.Transport{
			Proxy: http.ProxyFromEnvironment,
			DialContext: (&net.Dialer{
				Timeout:   30 * time.Second,
				KeepAlive: 30 * time.Second,
				DualStack: true,
			}).DialContext,
			MaxIdleConns:          2000,
			MaxIdleConnsPerHost:   1000,
			IdleConnTimeout:       30 * time.Second,
			TLSHandshakeTimeout:   10 * time.Second,
			ExpectContinueTimeout: 1 * time.Second,
		},
	}
)

// NewHTTPAttacker 创建一个新的HTTPAttacker对象
func NewHTTPAttacker(n string, p HTTPPrepareFunc, check ...HTTPResponseCheck) *HTTPAttacker {
	return &HTTPAttacker{
		Client:     DefaultHTTPClient,
		Prepare:    p,
		name:       n,
		CheckChain: check,
	}
}

// Name 返回HTTPAttacker的名称
func (ha *HTTPAttacker) Name() string {
	return ha.name
}

// Fire HTTPAttacker发起一次请求
func (ha *HTTPAttacker) Fire() error {
	if ha.Prepare == nil {
		panic("please implement Prepare() first")
	}

	req, err := ha.Prepare()
	if err != nil {
		Logger.Error("occur error on creating new http.Request object", zap.Error(err))
		return err
	}

	resp, err := ha.Client.Do(req)
	if err != nil {
		Logger.Error("occur error on sending http request", zap.Error(err))
		return err
	}

	if ha.CheckChain == nil || len(ha.CheckChain) == 0 {
		io.Copy(ioutil.Discard, resp.Body) // no checker defined, discard body
		resp.Body.Close()
		return nil
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		Logger.Error("occur error on receiving http response", zap.Error(err))
		return err
	}
	resp.Body.Close()

	for _, check := range ha.CheckChain {
		if check == nil {
			continue
		}
		if err = check(resp, body); err != nil {
			return err
		}
	}
	return nil
}

// CheckHTTPStatusCode 检查状态码是否>=400, 如果是则视为请求失败
func CheckHTTPStatusCode(resp *http.Response, body []byte) error {
	if resp.StatusCode >= http.StatusBadRequest {
		return fmt.Errorf("bad status code: %d", resp.StatusCode)
	}
	return nil
}
<commit_msg>update<commit_after>package ultron

import (
	"fmt"
	"io"
	"io/ioutil"
	"net"
	"net/http"
	"time"

	"go.uber.org/zap"
)

type (
	// Attacker 定义一个事务、请求，需要确保该对象是Goroutine-safe
	Attacker interface {
		Name() string
		Fire() error
	}

	// HTTPPrepareFunc 构造http.Request函数，需要调用方定义，由HTTPAttacker来发送
	HTTPPrepareFunc func() (*http.Request, error)
	// HTTPResponseCheck http.Response校验函数，可由调用方自定义，如果返回error，则视为请求失败
	HTTPResponseCheck func(resp *http.Response, body []byte) error

	// HTTPAttacker http协议的Attacker实现
	HTTPAttacker struct {
		Client     *http.Client
		Prepare    HTTPPrepareFunc
		name       string
		CheckChain []HTTPResponseCheck
	}
)

var (
	// DefaultHTTPClient 默认http.Client
	// http://tleyden.github.io/blog/2016/11/21/tuning-the-go-http-client-library-for-load-testing/
	DefaultHTTPClient = &http.Client{
		Timeout: 90 * time.Second,
		Transport: &http.Transport{
			Proxy: http.ProxyFromEnvironment,
			DialContext: (&net.Dialer{
				Timeout:   30 * time.Second,
				KeepAlive: 30 * time.Second,
				DualStack: true,
			}).DialContext,
			DisableKeepAlives:     false,
			MaxIdleConns:          2000,
			MaxIdleConnsPerHost:   1000,
			IdleConnTimeout:       30 * time.Second,
			TLSHandshakeTimeout:   10 * time.Second,
			ExpectContinueTimeout: 1 * time.Second,
		},
	}
)

// NewHTTPAttacker 创建一个新的HTTPAttacker对象
func NewHTTPAttacker(n string, p HTTPPrepareFunc, check ...HTTPResponseCheck) *HTTPAttacker {
	return &HTTPAttacker{
		Client:     DefaultHTTPClient,
		Prepare:    p,
		name:       n,
		CheckChain: check,
	}
}

// Name 返回HTTPAttacker的名称
func (ha *HTTPAttacker) Name() string {
	return ha.name
}

// Fire HTTPAttacker发起一次请求
func (ha *HTTPAttacker) Fire() error {
	if ha.Prepare == nil {
		panic("please implement Prepare() first")
	}

	req, err := ha.Prepare()
	if err != nil {
		Logger.Error("occur error on creating new http.Request object", zap.Error(err))
		return err
	}

	resp, err := ha.Client.Do(req)
	if err != nil {
		Logger.Error("occur error on sending http request", zap.Error(err))
		return err
	}

	if ha.CheckChain == nil || len(ha.CheckChain) == 0 {
		io.Copy(ioutil.Discard, resp.Body) // no checker defined, discard body
		resp.Body.Close()
		return nil
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		Logger.Error("occur error on receiving http response", zap.Error(err))
		return err
	}
	resp.Body.Close()

	for _, check := range ha.CheckChain {
		if check == nil {
			continue
		}
		if err = check(resp, body); err != nil {
			return err
		}
	}
	return nil
}

// CheckHTTPStatusCode 检查状态码是否>=400, 如果是则视为请求失败
func CheckHTTPStatusCode(resp *http.Response, body []byte) error {
	if resp.StatusCode >= http.StatusBadRequest {
		return fmt.Errorf("bad status code: %d", resp.StatusCode)
	}
	return nil
}
<|endoftext|>


<commit_before>// +build linux,cgo

package udev

/*
  #cgo LDFLAGS: -ludev
  #include <libudev.h>
  #include <linux/types.h>
  #include <stdlib.h>
	#include <linux/kdev_t.h>
*/
import "C"
import (
	"errors"

	"golang.org/x/sys/unix"
)

// Monitor is an opaque object handling an event source
type Monitor struct {
	ptr *C.struct_udev_monitor
	u   *Udev
}

const (
	maxEpollEvents = 32
	epollTimeout   = 1000
)

// Lock the udev context
func (m *Monitor) lock() {
	m.u.m.Lock()
}

// Unlock the udev context
func (m *Monitor) unlock() {
	m.u.m.Unlock()
}

// Unref the monitor
func monitorUnref(m *Monitor) {
	C.udev_monitor_unref(m.ptr)
}

// SetReceiveBufferSize sets the size of the kernel socket buffer.
// This call needs the appropriate privileges to succeed.
func (m *Monitor) SetReceiveBufferSize(size int) (err error) {
	m.lock()
	defer m.unlock()
	if C.udev_monitor_set_receive_buffer_size(m.ptr, (C.int)(size)) != 0 {
		err = errors.New("udev: udev_monitor_set_receive_buffer_size failed")
	}
	return
}

// FilterAddMatchSubsystemDevtype adds a filter matching the device against a subsystem and device type.
// This filter is efficiently executed inside the kernel, and libudev subscribers will usually not be woken up for devices which do not match.
// The filter must be installed before the monitor is switched to listening mode with the DeviceChan function.
func (m *Monitor) FilterAddMatchSubsystemDevtype(subsystem, devtype string) (err error) {
	m.lock()
	defer m.unlock()
	s, d := C.CString(subsystem), C.CString(devtype)
	defer freeCharPtr(s)
	defer freeCharPtr(d)
	if C.udev_monitor_filter_add_match_subsystem_devtype(m.ptr, s, d) != 0 {
		err = errors.New("udev: udev_monitor_filter_add_match_subsystem_devtype failed")
	}
	return
}

// FilterAddMatchTag adds a filter matching the device against a tag.
// This filter is efficiently executed inside the kernel, and libudev subscribers will usually not be woken up for devices which do not match.
// The filter must be installed before the monitor is switched to listening mode.
func (m *Monitor) FilterAddMatchTag(tag string) (err error) {
	m.lock()
	defer m.unlock()
	t := C.CString(tag)
	defer freeCharPtr(t)
	if C.udev_monitor_filter_add_match_tag(m.ptr, t) != 0 {
		err = errors.New("udev: udev_monitor_filter_add_match_tag failed")
	}
	return
}

// FilterUpdate updates the installed socket filter.
// This is only needed, if the filter was removed or changed.
func (m *Monitor) FilterUpdate() (err error) {
	m.lock()
	defer m.unlock()
	if C.udev_monitor_filter_update(m.ptr) != 0 {
		err = errors.New("udev: udev_monitor_filter_update failed")
	}
	return
}

// FilterRemove removes all filter from the Monitor.
func (m *Monitor) FilterRemove() (err error) {
	m.lock()
	defer m.unlock()
	if C.udev_monitor_filter_remove(m.ptr) != 0 {
		err = errors.New("udev: udev_monitor_filter_remove failed")
	}
	return
}

// receiveDevice is a helper function receiving a device while the Mutex is locked
func (m *Monitor) receiveDevice() (d *Device) {
	m.lock()
	defer m.unlock()
	return m.u.newDevice(C.udev_monitor_receive_device(m.ptr))
}

// DeviceChan binds the udev_monitor socket to the event source and spawns a
// goroutine. The goroutine efficiently waits on the monitor socket using epoll.
// Data is received from the udev monitor socket and a new Device is created
// with the data received. Pointers to the device are sent on the returned channel.
// The function takes a done signalling channel as a parameter, which when
// triggered will stop the goroutine and close the device channel.
// Only socket connections with uid=0 are accepted.
func (m *Monitor) DeviceChan(done <-chan struct{}) (<-chan *Device, error) {

	var event unix.EpollEvent
	var events [maxEpollEvents]unix.EpollEvent

	// Lock the context
	m.lock()
	defer m.unlock()

	// Enable receiving
	if C.udev_monitor_enable_receiving(m.ptr) != 0 {
		return nil, errors.New("udev: udev_monitor_enable_receiving failed")
	}

	// Set the fd to non-blocking
	fd := C.udev_monitor_get_fd(m.ptr)
	if e := unix.SetNonblock(int(fd), true); e != nil {
		return nil, errors.New("udev: unix.SetNonblock failed")
	}

	// Create an epoll fd
	epfd, e := unix.EpollCreate1(0)
	if e != nil {
		return nil, errors.New("udev: unix.EpollCreate1 failed")
	}

	// Add the fd to the epoll fd
	event.Events = unix.EPOLLIN | unix.EPOLLET
	event.Fd = int32(fd)
	if e = unix.EpollCtl(epfd, unix.EPOLL_CTL_ADD, int(fd), &event); e != nil {
		return nil, errors.New("udev: unix.EpollCtl failed")
	}

	// Create the channel
	ch := make(chan *Device)

	// Create goroutine to epoll the fd
	go func(done <-chan struct{}, fd int32) {
		// Close the epoll fd when goroutine exits
		defer unix.Close(epfd)
		// Close the channel when goroutine exits
		defer close(ch)
		// Loop forever
		for {
			// Poll the file descriptor
			nevents, e := unix.EpollWait(epfd, events[:], epollTimeout)
			if e != nil {
				return
			}
			// Process events
			for ev := 0; ev < nevents; ev++ {
				if events[ev].Fd == fd {
					if (events[ev].Events & unix.EPOLLIN) != 0 {
						for d := m.receiveDevice(); d != nil; d = m.receiveDevice() {
							ch <- d
						}
					}
				}
			}
			// Check for done signal
			select {
			case <-done:
				return
			default:
			}
		}
	}(done, int32(fd))

	return ch, nil
}
<commit_msg>Add Monitor.FilterAddMatchSubsystem<commit_after>// +build linux,cgo

package udev

/*
  #cgo LDFLAGS: -ludev
  #include <libudev.h>
  #include <linux/types.h>
  #include <stdlib.h>
	#include <linux/kdev_t.h>
*/
import "C"
import (
	"errors"

	"golang.org/x/sys/unix"
)

// Monitor is an opaque object handling an event source
type Monitor struct {
	ptr *C.struct_udev_monitor
	u   *Udev
}

const (
	maxEpollEvents = 32
	epollTimeout   = 1000
)

// Lock the udev context
func (m *Monitor) lock() {
	m.u.m.Lock()
}

// Unlock the udev context
func (m *Monitor) unlock() {
	m.u.m.Unlock()
}

// Unref the monitor
func monitorUnref(m *Monitor) {
	C.udev_monitor_unref(m.ptr)
}

// SetReceiveBufferSize sets the size of the kernel socket buffer.
// This call needs the appropriate privileges to succeed.
func (m *Monitor) SetReceiveBufferSize(size int) (err error) {
	m.lock()
	defer m.unlock()
	if C.udev_monitor_set_receive_buffer_size(m.ptr, (C.int)(size)) != 0 {
		err = errors.New("udev: udev_monitor_set_receive_buffer_size failed")
	}
	return
}

// FilterAddMatchSubsystem adds a filter matching the device against a subsystem.
// This filter is efficiently executed inside the kernel, and libudev subscribers will usually not be woken up for devices which do not match.
// The filter must be installed before the monitor is switched to listening mode with the DeviceChan function.
func (m *Monitor) FilterAddMatchSubsystem(subsystem string) (err error) {
	m.lock()
	defer m.unlock()
	s := C.CString(subsystem)
	defer freeCharPtr(s)
	if C.udev_monitor_filter_add_match_subsystem_devtype(m.ptr, s, nil) != 0 {
		err = errors.New("udev: udev_monitor_filter_add_match_subsystem_devtype failed")
	}
	return
}

// FilterAddMatchSubsystemDevtype adds a filter matching the device against a subsystem and device type.
// This filter is efficiently executed inside the kernel, and libudev subscribers will usually not be woken up for devices which do not match.
// The filter must be installed before the monitor is switched to listening mode with the DeviceChan function.
func (m *Monitor) FilterAddMatchSubsystemDevtype(subsystem, devtype string) (err error) {
	m.lock()
	defer m.unlock()
	s, d := C.CString(subsystem), C.CString(devtype)
	defer freeCharPtr(s)
	defer freeCharPtr(d)
	if C.udev_monitor_filter_add_match_subsystem_devtype(m.ptr, s, d) != 0 {
		err = errors.New("udev: udev_monitor_filter_add_match_subsystem_devtype failed")
	}
	return
}

// FilterAddMatchTag adds a filter matching the device against a tag.
// This filter is efficiently executed inside the kernel, and libudev subscribers will usually not be woken up for devices which do not match.
// The filter must be installed before the monitor is switched to listening mode.
func (m *Monitor) FilterAddMatchTag(tag string) (err error) {
	m.lock()
	defer m.unlock()
	t := C.CString(tag)
	defer freeCharPtr(t)
	if C.udev_monitor_filter_add_match_tag(m.ptr, t) != 0 {
		err = errors.New("udev: udev_monitor_filter_add_match_tag failed")
	}
	return
}

// FilterUpdate updates the installed socket filter.
// This is only needed, if the filter was removed or changed.
func (m *Monitor) FilterUpdate() (err error) {
	m.lock()
	defer m.unlock()
	if C.udev_monitor_filter_update(m.ptr) != 0 {
		err = errors.New("udev: udev_monitor_filter_update failed")
	}
	return
}

// FilterRemove removes all filter from the Monitor.
func (m *Monitor) FilterRemove() (err error) {
	m.lock()
	defer m.unlock()
	if C.udev_monitor_filter_remove(m.ptr) != 0 {
		err = errors.New("udev: udev_monitor_filter_remove failed")
	}
	return
}

// receiveDevice is a helper function receiving a device while the Mutex is locked
func (m *Monitor) receiveDevice() (d *Device) {
	m.lock()
	defer m.unlock()
	return m.u.newDevice(C.udev_monitor_receive_device(m.ptr))
}

// DeviceChan binds the udev_monitor socket to the event source and spawns a
// goroutine. The goroutine efficiently waits on the monitor socket using epoll.
// Data is received from the udev monitor socket and a new Device is created
// with the data received. Pointers to the device are sent on the returned channel.
// The function takes a done signalling channel as a parameter, which when
// triggered will stop the goroutine and close the device channel.
// Only socket connections with uid=0 are accepted.
func (m *Monitor) DeviceChan(done <-chan struct{}) (<-chan *Device, error) {

	var event unix.EpollEvent
	var events [maxEpollEvents]unix.EpollEvent

	// Lock the context
	m.lock()
	defer m.unlock()

	// Enable receiving
	if C.udev_monitor_enable_receiving(m.ptr) != 0 {
		return nil, errors.New("udev: udev_monitor_enable_receiving failed")
	}

	// Set the fd to non-blocking
	fd := C.udev_monitor_get_fd(m.ptr)
	if e := unix.SetNonblock(int(fd), true); e != nil {
		return nil, errors.New("udev: unix.SetNonblock failed")
	}

	// Create an epoll fd
	epfd, e := unix.EpollCreate1(0)
	if e != nil {
		return nil, errors.New("udev: unix.EpollCreate1 failed")
	}

	// Add the fd to the epoll fd
	event.Events = unix.EPOLLIN | unix.EPOLLET
	event.Fd = int32(fd)
	if e = unix.EpollCtl(epfd, unix.EPOLL_CTL_ADD, int(fd), &event); e != nil {
		return nil, errors.New("udev: unix.EpollCtl failed")
	}

	// Create the channel
	ch := make(chan *Device)

	// Create goroutine to epoll the fd
	go func(done <-chan struct{}, fd int32) {
		// Close the epoll fd when goroutine exits
		defer unix.Close(epfd)
		// Close the channel when goroutine exits
		defer close(ch)
		// Loop forever
		for {
			// Poll the file descriptor
			nevents, e := unix.EpollWait(epfd, events[:], epollTimeout)
			if e != nil {
				return
			}
			// Process events
			for ev := 0; ev < nevents; ev++ {
				if events[ev].Fd == fd {
					if (events[ev].Events & unix.EPOLLIN) != 0 {
						for d := m.receiveDevice(); d != nil; d = m.receiveDevice() {
							ch <- d
						}
					}
				}
			}
			// Check for done signal
			select {
			case <-done:
				return
			default:
			}
		}
	}(done, int32(fd))

	return ch, nil
}
<|endoftext|>


<commit_before>package main

import (
	"code.google.com/p/go.net/websocket"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"queue"
	"runtime"
	"strings"
	"time"
)

const debug = true
const maxSizeHealthStatusQueue = 600 // Magnificent Server Log Store Size, displays the last 600 seconds in the plot

type Msg struct {
	MessageId string
	Content   string
	TimeStamp int64
}

// Client connection consists of the websocket and the client ip
type Client struct {
	websocket *websocket.Conn
	clientIP  string
}

type ServiceMonitor struct {
	errChan           chan error // unbuffered channel
	errChanWebsock    chan error // unbuffered channel
	activeClients     map[string]Client
	healthStatusChan  chan bool
	alertChan         chan string
	newClientChan     chan Client
	alertQueue        *queue.Queue
	healthStatusQueue *queue.Queue
}

func NewServiceMonitor() *ServiceMonitor {
	m := ServiceMonitor{}
	m.activeClients = make(map[string]Client)
	m.errChan = make(chan error)
	m.healthStatusChan = make(chan bool, 10)
	m.alertChan = make(chan string, 10)
	m.newClientChan = make(chan Client, 10)
	m.alertQueue = queue.NewQueue()
	m.healthStatusQueue = queue.NewQueue()
	return &m
}

func BoolToString(value bool) string {
	if value {
		return "1"
	}
	return "0"
}

func (m *ServiceMonitor) sendClientMsg(msg *Msg, ip string) {
	var err error
	var Message = websocket.JSON

	if err = Message.Send(m.activeClients[ip].websocket, msg); err != nil {
		// we could not send the message to a peer
		log.Println("Could not send message to:", ip, err.Error())
		log.Println("Client disconnected:", ip)
		delete(m.activeClients, ip)
	}
}

func (m *ServiceMonitor) sendBroadcastMsg(msg *Msg) {
	var err error
	var Message = websocket.JSON

	for ip, _ := range m.activeClients {
		if err = Message.Send(m.activeClients[ip].websocket, msg); err != nil {
			// we could not send the message to a peer
			log.Println("Could not send message to:", ip, err.Error())
			log.Println("Client disconnected:", ip)
			delete(m.activeClients, ip)
		}
	}
}

func (m *ServiceMonitor) sendQueueData(ip string) {
	for i := 0; i < m.healthStatusQueue.Len(); i++ {
		e, found := m.healthStatusQueue.Get(i)

		if found {
			if msg, ok := e.(*Msg); ok {
				m.sendClientMsg(msg, ip)
			}
		}
	}

	for i := 0; i < m.alertQueue.Len(); i++ {
		e, found := m.alertQueue.Get(i)

		if found {
			if msg, ok := e.(*Msg); ok {
				m.sendClientMsg(msg, ip)
			}
		}
	}
}

// this routine handles all outgoing websocket messages
func (m *ServiceMonitor) pushDataToClients() {
	for {
		select {
		// a new Client is connecting
		case newClient := <-m.newClientChan:
			// send current Queue data to the new connecting client
			m.activeClients[newClient.clientIP] = newClient
			m.sendQueueData(newClient.clientIP)

		// broadcast a new health status message to all clients
		// newHealthStatus == 1 ... deamon failure
		// newHealthStatus == 0 ... deamon ok
		case newHealthStatus := <-m.healthStatusChan:
			msg := Msg{"Plot", BoolToString(newHealthStatus), time.Now().UnixNano() / int64(time.Millisecond)}
			m.sendBroadcastMsg(&msg)
			// add msg to HealthStatusQueue
			if m.healthStatusQueue.Len() < maxSizeHealthStatusQueue {
				m.healthStatusQueue.Push(&msg)
			} else {
				m.healthStatusQueue.Pop()
				m.healthStatusQueue.Push(&msg)
			}

		// broadcast an alert message to all clients
		case newAlert := <-m.alertChan:
			msg := Msg{"Alert", newAlert, time.Now().UnixNano() / int64(time.Millisecond)}
			m.sendBroadcastMsg(&msg)
			// add msg to alertQueue
			m.alertQueue.Push(&msg)
		}
	}
}

// reference: https://github.com/Niessy/websocket-golang-chat
// WebSocket server to handle clients
func (m *ServiceMonitor) WebSocketServer(ws *websocket.Conn) {
	var err error

	// cleanup on server side
	defer func() {
		if err = ws.Close(); err != nil {
			log.Println("Websocket could not be closed", err.Error())
		}
	}()

	client := ws.Request().RemoteAddr
	if debug {
		log.Println("New client connected:", client)
	}

	m.newClientChan <- Client{ws, client}

	// wait for errChan, so the websocket stays open otherwise it'll close
	err = <-m.errChanWebsock
}

// handler for the main page
func HomeHandler(response http.ResponseWriter, request *http.Request) {
	response.Header().Set("Content-type", "text/html")
	webpage, err := ioutil.ReadFile("home.html")

	if err != nil {
		http.Error(response, fmt.Sprintf("home.html file error %v", err), 500)
	}

	fmt.Fprint(response, string(webpage))
}

func (m *ServiceMonitor) parseResponse(resp string) {
  if !strings.Contains(resp, "Magnificent!") {
		m.healthStatusChan <- false
	} else {
		m.healthStatusChan <- true
		m.alertChan <- "Server has failed"
	}
}

func (m *ServiceMonitor) requestDeamonStatus(url string) {
	response, err := http.Get(url)
	if err != nil {
		if debug {
			log.Println("requestDeamonStatus failed:", err.Error())
			return
		}
	}

	defer response.Body.Close()
	contents, err := ioutil.ReadAll(response.Body)
	if err != nil {
		if debug {
			log.Println("requestDeamonStatus failed:", err.Error())
			return
		}
	}

	resp := string(contents)
	m.parseResponse(resp)
}

func (m *ServiceMonitor) monitorDeamon(url string, time_interval time.Duration) {
	for {
		go m.requestDeamonStatus(url)
		time.Sleep(time_interval * time.Second)
	}
}

func (m *ServiceMonitor) startHTTPServer() {
	http.Handle("/", http.HandlerFunc(HomeHandler))
	http.Handle("/sock", websocket.Handler(m.WebSocketServer))

	err := http.ListenAndServe(":8080", nil)
	m.errChanWebsock <- err
	m.errChan <- err
}

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	m := NewServiceMonitor()

	go m.startHTTPServer()
	go m.pushDataToClients()
	go m.monitorDeamon("http://localhost:12345/", 1)

	err := <-m.errChan
	if err != nil {
		log.Println(err)
		os.Exit(1)
	}
}
<commit_msg>removed go routine<commit_after>package main

import (
	"code.google.com/p/go.net/websocket"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"queue"
	"runtime"
	"strings"
	"time"
)

const debug = true
const maxSizeHealthStatusQueue = 600 // Magnificent Server Log Store Size, displays the last 600 seconds in the plot

type Msg struct {
	MessageId string
	Content   string
	TimeStamp int64
}

// Client connection consists of the websocket and the client ip
type Client struct {
	websocket *websocket.Conn
	clientIP  string
}

type ServiceMonitor struct {
	errChan           chan error // unbuffered channel
	errChanWebsock    chan error // unbuffered channel
	activeClients     map[string]Client
	healthStatusChan  chan bool
	alertChan         chan string
	newClientChan     chan Client
	alertQueue        *queue.Queue
	healthStatusQueue *queue.Queue
}

func NewServiceMonitor() *ServiceMonitor {
	m := ServiceMonitor{}
	m.activeClients = make(map[string]Client)
	m.errChan = make(chan error)
	m.healthStatusChan = make(chan bool, 10)
	m.alertChan = make(chan string, 10)
	m.newClientChan = make(chan Client, 10)
	m.alertQueue = queue.NewQueue()
	m.healthStatusQueue = queue.NewQueue()
	return &m
}

func BoolToString(value bool) string {
	if value {
		return "1"
	}
	return "0"
}

func (m *ServiceMonitor) sendClientMsg(msg *Msg, ip string) {
	var err error
	var Message = websocket.JSON

	if err = Message.Send(m.activeClients[ip].websocket, msg); err != nil {
		// we could not send the message to a peer
		log.Println("Could not send message to:", ip, err.Error())
		log.Println("Client disconnected:", ip)
		delete(m.activeClients, ip)
	}
}

func (m *ServiceMonitor) sendBroadcastMsg(msg *Msg) {
	var err error
	var Message = websocket.JSON

	for ip, _ := range m.activeClients {
		if err = Message.Send(m.activeClients[ip].websocket, msg); err != nil {
			// we could not send the message to a peer
			log.Println("Could not send message to:", ip, err.Error())
			log.Println("Client disconnected:", ip)
			delete(m.activeClients, ip)
		}
	}
}

func (m *ServiceMonitor) sendQueueData(ip string) {
	for i := 0; i < m.healthStatusQueue.Len(); i++ {
		e, found := m.healthStatusQueue.Get(i)

		if found {
			if msg, ok := e.(*Msg); ok {
				m.sendClientMsg(msg, ip)
			}
		}
	}

	for i := 0; i < m.alertQueue.Len(); i++ {
		e, found := m.alertQueue.Get(i)

		if found {
			if msg, ok := e.(*Msg); ok {
				m.sendClientMsg(msg, ip)
			}
		}
	}
}

// this routine handles all outgoing websocket messages
func (m *ServiceMonitor) pushDataToClients() {
	for {
		select {
		// a new Client is connecting
		case newClient := <-m.newClientChan:
			// send current Queue data to the new connecting client
			m.activeClients[newClient.clientIP] = newClient
			m.sendQueueData(newClient.clientIP)

		// broadcast a new health status message to all clients
		// newHealthStatus == 1 ... deamon failure
		// newHealthStatus == 0 ... deamon ok
		case newHealthStatus := <-m.healthStatusChan:
			msg := Msg{"Plot", BoolToString(newHealthStatus), time.Now().UnixNano() / int64(time.Millisecond)}
			m.sendBroadcastMsg(&msg)
			// add msg to HealthStatusQueue
			if m.healthStatusQueue.Len() < maxSizeHealthStatusQueue {
				m.healthStatusQueue.Push(&msg)
			} else {
				m.healthStatusQueue.Pop()
				m.healthStatusQueue.Push(&msg)
			}

		// broadcast an alert message to all clients
		case newAlert := <-m.alertChan:
			msg := Msg{"Alert", newAlert, time.Now().UnixNano() / int64(time.Millisecond)}
			m.sendBroadcastMsg(&msg)
			// add msg to alertQueue
			m.alertQueue.Push(&msg)
		}
	}
}

// reference: https://github.com/Niessy/websocket-golang-chat
// WebSocket server to handle clients
func (m *ServiceMonitor) WebSocketServer(ws *websocket.Conn) {
	var err error

	// cleanup on server side
	defer func() {
		if err = ws.Close(); err != nil {
			log.Println("Websocket could not be closed", err.Error())
		}
	}()

	client := ws.Request().RemoteAddr
	if debug {
		log.Println("New client connected:", client)
	}

	m.newClientChan <- Client{ws, client}

	// wait for errChan, so the websocket stays open otherwise it'll close
	err = <-m.errChanWebsock
}

// handler for the main page
func HomeHandler(response http.ResponseWriter, request *http.Request) {
	response.Header().Set("Content-type", "text/html")
	webpage, err := ioutil.ReadFile("home.html")

	if err != nil {
		http.Error(response, fmt.Sprintf("home.html file error %v", err), 500)
	}

	fmt.Fprint(response, string(webpage))
}

func (m *ServiceMonitor) parseResponse(resp string) {
  if !strings.Contains(resp, "Magnificent!") {
		m.healthStatusChan <- false
	} else {
		m.healthStatusChan <- true
		m.alertChan <- "Server has failed"
	}
}

func (m *ServiceMonitor) requestDeamonStatus(url string) {
	response, err := http.Get(url)
	if err != nil {
		if debug {
			log.Println("requestDeamonStatus failed:", err.Error())
			return
		}
	}

	defer response.Body.Close()
	contents, err := ioutil.ReadAll(response.Body)
	if err != nil {
		if debug {
			log.Println("requestDeamonStatus failed:", err.Error())
			return
		}
	}

	resp := string(contents)
	m.parseResponse(resp)
}

func (m *ServiceMonitor) monitorDeamon(url string, time_interval time.Duration) {
	for {
		m.requestDeamonStatus(url)
		time.Sleep(time_interval * time.Second)
	}
}

func (m *ServiceMonitor) startHTTPServer() {
	http.Handle("/", http.HandlerFunc(HomeHandler))
	http.Handle("/sock", websocket.Handler(m.WebSocketServer))

	err := http.ListenAndServe(":8080", nil)
	m.errChanWebsock <- err
	m.errChan <- err
}

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	m := NewServiceMonitor()

	go m.startHTTPServer()
	go m.pushDataToClients()
	go m.monitorDeamon("http://localhost:12345/", 1)

	err := <-m.errChan
	if err != nil {
		log.Println(err)
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>package gob

import (
	"github.com/veandco/go-sdl2/sdl"
)

const SDL_PIXEL_SIZE int32 = 5

// Interface for a screen which displays the game
type Monitor interface {
	// Initialise the monitor
	Init()
	// Render a frame of the game
	RenderScreen()
	// Destroy the monitor instance
	Destroy()
}

// Get an SDL2 monitor
func GetSDLMonitor(gameboy *Gameboy) SDLMonitor {
	monitor := SDLMonitor{Gameboy: gameboy}
	monitor.Init()
	return monitor
}

// And SDL2 monitor instance
type SDLMonitor struct {
	Monitor
	Gameboy *Gameboy
	window  *sdl.Window
	surface *sdl.Surface
}

// Initialise the display
func (mon *SDLMonitor) Init() {
	sdl.Init(sdl.INIT_EVERYTHING)
	window, err := sdl.CreateWindow(
		"test",
		sdl.WINDOWPOS_UNDEFINED,
		sdl.WINDOWPOS_UNDEFINED,
		int(SDL_PIXEL_SIZE * 160),
		int(SDL_PIXEL_SIZE * 144),
		sdl.WINDOW_SHOWN,
	)
	if err != nil {
		panic(err)
	}
	mon.window = window

	surface, err := window.GetSurface()
	if err != nil {
		panic(err)
	}
	mon.surface = surface
}

// Combine an array of an RGB array a single number
func (mon *SDLMonitor) toColour(cols [3]int) uint32 {
	return uint32(cols[2]) << 16 | uint32(cols[1]) << 8 | uint32(cols[0])
}

// Draw a frame of the game to the screen
func (mon *SDLMonitor) RenderScreen() {
	for x := 0; x < 160; x++ {
		for y := 0; y < 144; y++ {
			rect := sdl.Rect{
				X: int32(x) * SDL_PIXEL_SIZE,
				Y: int32(y) * SDL_PIXEL_SIZE,
				W: SDL_PIXEL_SIZE,
				H: SDL_PIXEL_SIZE,
			}
			mon.surface.FillRect(&rect, mon.toColour(mon.Gameboy.ScreenData[x][y]))
		}
	}
	mon.window.UpdateSurface()
}

// Destroy the monitor instance
func (mon *SDLMonitor) Destroy() {
	mon.window.Destroy()
	sdl.Quit()
}<commit_msg>Use DrawPoint for drawing screen.<commit_after>package gob

import (
	"github.com/veandco/go-sdl2/sdl"
)

const PIXEL_SCALE int = 3

// Interface for a screen which displays the game
type Monitor interface {
	// Initialise the monitor
	Init()
	// Render a frame of the game
	RenderScreen()
	// Destroy the monitor instance
	Destroy()
}

// Get an SDL2 monitor
func GetSDLMonitor(gameboy *Gameboy) SDLMonitor {
	monitor := SDLMonitor{Gameboy: gameboy}
	monitor.Init()
	return monitor
}

// And SDL2 monitor instance
type SDLMonitor struct {
	Monitor
	Gameboy  *Gameboy
	window   *sdl.Window
	surface  *sdl.Surface
	renderer *sdl.Renderer
}

// Initialise the display
func (mon *SDLMonitor) Init() {
	sdl.Init(sdl.INIT_EVERYTHING)
	window, renderer, err := sdl.CreateWindowAndRenderer(
		160 * PIXEL_SCALE, 144 * PIXEL_SCALE, 0,
	)
	if err != nil {
		panic(err)
	}
	renderer.SetScale(float32(PIXEL_SCALE), float32(PIXEL_SCALE))
	mon.window = window
	mon.renderer = renderer
}

// Combine an array of an RGB array a single number
func (mon *SDLMonitor) toColour(cols [3]int) uint32 {
	return uint32(cols[2]) << 16 | uint32(cols[1]) << 8 | uint32(cols[0])
}

// Draw a frame of the game to the screen
func (mon *SDLMonitor) RenderScreen() {
	for x := 0; x < 160; x++ {
		for y := 0; y < 144; y++ {
			col := mon.Gameboy.ScreenData[x][y]
			mon.renderer.SetDrawColor(uint8(col[0]), uint8(col[1]), uint8(col[2]), 0xFF)
			mon.renderer.DrawPoint(x, y)
		}
	}
	mon.renderer.Present()
}

// Destroy the monitor instance
func (mon *SDLMonitor) Destroy() {
	mon.window.Destroy()
	sdl.Quit()
}<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"os"
	"os/exec"
	"path"
	"strconv"
	"strings"
)

func main() {
	for _, binding := range GetAllBindings() {
		mountPoint, err := MakeMountPoint(binding)
		if err != nil {
			panic(err)
		}
		RunCommand(CreateCommand(binding))
		fmt.Printf("Mounted SSHFS filesystem for service instance %s into %s", binding.Name, mountPoint)
	}
}

type Credentials struct {
	Host string `json:"host"`
	Port int    `json:"port"`
	User string `json:"user"`
	Pass string `json:"password"`
}

type Binding struct {
	Credentials Credentials `json:"credentials"`
	Plan        string      `json:"plan"`
	Name        string      `json:"name"`
}

func GetAllBindings() []Binding {
	sshfsBindings := map[string][]Binding{}
	jsonString := os.Getenv("VCAP_SERVICES")

	err := json.Unmarshal([]byte(jsonString), &sshfsBindings)
	if err != nil {
		panic("Unable to decode JSON in env var VCAP_SERVICES")
	}

	return sshfsBindings["sshfs"]
}

func MakeMountPoint(binding Binding) (mountPath string, err error) {
	currentPath, err := os.Getwd()
	if err != nil {
		return "", err
	}
	mountPath = path.Join(currentPath, binding.Name)
	err = os.Mkdir(mountPath, 0777)
	return mountPath, err
}

func CreateCommand(binding Binding) *exec.Cmd {
	cmd := exec.Command(
		"sshfs",
		fmt.Sprintf("%s@%s:", binding.Credentials.User, binding.Credentials.Host),
		"-p", strconv.Itoa(binding.Credentials.Port),
		"-o", "password_stdin",
		"-o", "StrictHostKeyChecking=false",
		binding.Name,
	)

	cmd.Stdin = strings.NewReader(binding.Credentials.Pass + "\n")

	return cmd
}

func RunCommand(command *exec.Cmd) error {
	commandOutput, err := command.CombinedOutput()
	if err != nil {
		return fmt.Errorf("Failed while running %s : %s : %s", command, commandOutput, err)
	}

	return nil
}
<commit_msg>Update message formatting<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"os"
	"os/exec"
	"path"
	"strconv"
	"strings"
)

func main() {
	for _, binding := range GetAllBindings() {
		mountPoint, err := MakeMountPoint(binding)
		if err != nil {
			panic(err)
		}
		RunCommand(CreateCommand(binding))
		fmt.Printf("Mounted SSHFS filesystem for service instance %s into %s\n", binding.Name, mountPoint)
	}
}

type Credentials struct {
	Host string `json:"host"`
	Port int    `json:"port"`
	User string `json:"user"`
	Pass string `json:"password"`
}

type Binding struct {
	Credentials Credentials `json:"credentials"`
	Plan        string      `json:"plan"`
	Name        string      `json:"name"`
}

func GetAllBindings() []Binding {
	sshfsBindings := map[string][]Binding{}
	jsonString := os.Getenv("VCAP_SERVICES")

	err := json.Unmarshal([]byte(jsonString), &sshfsBindings)
	if err != nil {
		panic("Unable to decode JSON in env var VCAP_SERVICES")
	}

	return sshfsBindings["sshfs"]
}

func MakeMountPoint(binding Binding) (mountPath string, err error) {
	currentPath, err := os.Getwd()
	if err != nil {
		return "", err
	}
	mountPath = path.Join(currentPath, binding.Name)
	err = os.Mkdir(mountPath, 0777)
	return mountPath, err
}

func CreateCommand(binding Binding) *exec.Cmd {
	cmd := exec.Command(
		"sshfs",
		fmt.Sprintf("%s@%s:", binding.Credentials.User, binding.Credentials.Host),
		"-p", strconv.Itoa(binding.Credentials.Port),
		"-o", "password_stdin",
		"-o", "StrictHostKeyChecking=false",
		binding.Name,
	)

	cmd.Stdin = strings.NewReader(binding.Credentials.Pass + "\n")

	return cmd
}

func RunCommand(command *exec.Cmd) error {
	commandOutput, err := command.CombinedOutput()
	if err != nil {
		return fmt.Errorf("failed while running %s : %s : %s", command, commandOutput, err)
	}

	return nil
}
<|endoftext|>


<commit_before>package aws

import (
	"bytes"
	"container/list"
	"fmt"
	"io"
	"io/ioutil"
	"math"
	"net/http"
	"net/http/httputil"
	"net/url"
	"reflect"
	"regexp"
	"time"
)

const SDKName = "aws-sdk-go"
const SDKVersion = "0.5.0"

func UserAgentHandler(r *Request) {
	r.HTTPRequest.Header.Set("User-Agent", SDKName+"/"+SDKVersion)
}

func SendHandler(r *Request) {
	r.HTTPResponse, r.Error = r.Service.Config.HTTPClient.Do(r.HTTPRequest)
}

func ValidateResponseHandler(r *Request) {
	if r.HTTPResponse.StatusCode == 0 || r.HTTPResponse.StatusCode >= 400 {
		r.Error = APIError{
			StatusCode: r.HTTPResponse.StatusCode,
			Retryable:  r.Service.ShouldRetry(r),
			RetryDelay: r.Service.RetryRules(r),
			RetryCount: r.RetryCount,
		}
	}
}

func AfterRetryHandler(r *Request) {
	delay := 0 * time.Second
	willRetry := false

	if err := Error(r.Error); err != nil {
		delay = err.RetryDelay
		if err.Retryable && r.RetryCount < r.Service.MaxRetries() {
			r.RetryCount++
			willRetry = true
		}
	}

	if willRetry {
		r.Error = nil
		time.Sleep(delay)
	}
}

type Operation struct {
	*OperationBindings
	Name       string
	HTTPMethod string
	HTTPPath   string
}

type OperationBindings struct {
	InPayload   string
	OutPayload  string
	Required    []string
	QueryParams []string
	URIParams   []string
	InHeaders   []string
	OutHeaders  []string
}

type Service struct {
	Config            *Config
	Handlers          Handlers
	ManualSend        bool
	ServiceName       string
	APIVersion        string
	Endpoint          string
	JSONVersion       string
	TargetPrefix      string
	RetryRules        func(*Request) time.Duration
	ShouldRetry       func(*Request) bool
	DefaultMaxRetries uint
}

var schemeRE = regexp.MustCompile("^([^:]+)://")

func retryRules(r *Request) time.Duration {
	delay := time.Duration(math.Pow(2, float64(r.RetryCount))) * 30
	return delay * time.Millisecond
}

func shouldRetry(r *Request) bool {
	if err := Error(r.Error); err != nil {
		if err.StatusCode >= 500 {
			return true
		}

		switch err.Code {
		case "ExpiredTokenException":
		case "ProvisionedThroughputExceededException", "Throttling":
			return true
		}
	}
	return false
}

func (s *Service) Initialize() {
	if s.Config.HTTPClient == nil {
		s.Config.HTTPClient = http.DefaultClient
	}

	if s.RetryRules == nil {
		s.RetryRules = retryRules
	}

	if s.ShouldRetry == nil {
		s.ShouldRetry = shouldRetry
	}

	s.DefaultMaxRetries = 3
	s.Handlers.Build.PushBack(UserAgentHandler)
	s.Handlers.Sign.PushBack(BuildContentLength)
	s.Handlers.Send.PushBack(SendHandler)
	s.Handlers.AfterRetry.PushBack(AfterRetryHandler)
	s.Handlers.ValidateResponse.PushBack(ValidateResponseHandler)
	s.AddDebugHandlers()
	s.buildEndpoint()
}

type Request struct {
	*Service
	Handlers     Handlers
	Time         time.Time
	ExpireTime   time.Duration
	Operation    *Operation
	HTTPRequest  *http.Request
	HTTPResponse *http.Response
	Body         io.ReadSeeker
	Params       interface{}
	Error        error
	Data         interface{}
	RequestID    string
	RetryCount   uint

	built bool
}

func NewRequest(service *Service, operation *Operation, params interface{}, data interface{}) *Request {
	method := operation.HTTPMethod
	if method == "" {
		method = "POST"
	}
	httpReq, _ := http.NewRequest(method, "", nil)
	httpReq.URL, _ = url.Parse(service.Endpoint + operation.HTTPPath)

	r := &Request{
		Service:     service,
		Handlers:    service.Handlers.copy(),
		Time:        time.Now(),
		ExpireTime:  300,
		Operation:   operation,
		HTTPRequest: httpReq,
		Body:        nil,
		Params:      params,
		Error:       nil,
		Data:        data,
	}

	return r
}

func (s *Service) buildEndpoint() {
	if s.Config.Endpoint != "" {
		s.Endpoint = s.Config.Endpoint
	} else {
		s.Endpoint = s.endpointForRegion()
	}

	if !schemeRE.MatchString(s.Endpoint) {
		scheme := "https"
		if s.Config.DisableSSL {
			scheme = "http"
		}
		s.Endpoint = scheme + "://" + s.Endpoint
	}
}

func (s *Service) AddDebugHandlers() {
	if s.Config.LogLevel == 0 {
		return
	}

	s.Handlers.Sign.PushBack(func(r *Request) {
		dumpedBody, _ := httputil.DumpRequest(r.HTTPRequest, true)

		fmt.Printf("=> [%s] %s.%s(%+v)\n", r.Time,
			r.Service.ServiceName, r.Operation.Name, r.Params)
		fmt.Printf("---[ REQUEST PRE-SIGN ]------------------------------\n")
		fmt.Printf("%s\n", string(dumpedBody))
		fmt.Printf("-----------------------------------------------------\n")
	})
	s.Handlers.Send.PushFront(func(r *Request) {
		dumpedBody, _ := httputil.DumpRequest(r.HTTPRequest, true)

		fmt.Printf("---[ REQUEST POST-SIGN ]-----------------------------\n")
		fmt.Printf("%s\n", string(dumpedBody))
		fmt.Printf("-----------------------------------------------------\n")
	})
	s.Handlers.Send.PushBack(func(r *Request) {
		fmt.Printf("---[ RESPONSE ]--------------------------------------\n")
		if r.HTTPResponse != nil {
			if r.HTTPResponse.Body != nil {
				defer r.HTTPResponse.Body.Close()
			}
			dumpedBody, _ := httputil.DumpResponse(r.HTTPResponse, true)

			fmt.Printf("%s\n", string(dumpedBody))
		} else if r.Error != nil {
			fmt.Printf("%s\n", r.Error)
		}
		fmt.Printf("-----------------------------------------------------\n")
	})
}

func (r *Request) ParamsFilled() bool {
	return reflect.ValueOf(r.Params).Elem().IsValid()
}

func (r *Request) DataFilled() bool {
	return reflect.ValueOf(r.Data).Elem().IsValid()
}

func (r *Request) SetBufferBody(buf []byte) {
	r.SetReaderBody(bytes.NewReader(buf))
}

func (r *Request) SetReaderBody(reader io.ReadSeeker) {
	r.HTTPRequest.Body = ioutil.NopCloser(reader)
	r.Body = reader
}

func (s *Service) MaxRetries() uint {
	if s.Config.MaxRetries < 0 {
		return s.DefaultMaxRetries
	} else {
		return uint(s.Config.MaxRetries)
	}
}

func (r *Request) Presign(expireTime time.Duration) (string, error) {
	r.ExpireTime = expireTime
	r.Sign()
	if r.Error != nil {
		return "", r.Error
	} else {
		return r.HTTPRequest.URL.String(), nil
	}
}

func (r *Request) Build() error {
	if !r.built {
		r.Error = nil
		r.Handlers.Build.Run(r)
		r.built = true
	}

	return r.Error
}

func (r *Request) Sign() error {
	r.Build()
	if r.Error != nil {
		return r.Error
	}

	r.Handlers.Sign.Run(r)
	return r.Error
}

func (r *Request) Send() error {
	r.Sign()
	if r.Error != nil {
		return r.Error
	}

	for {
		r.Handlers.Send.Run(r)
		if r.Error != nil {
			return r.Error
		}

		r.Handlers.UnmarshalMeta.Run(r)
		r.Handlers.ValidateResponse.Run(r)
		if r.Error != nil {
			r.Handlers.Retry.Run(r)
			r.Handlers.AfterRetry.Run(r)
			if r.Error != nil {
				r.Handlers.UnmarshalError.Run(r)
				return r.Error
			}
			continue
		}

		r.Handlers.Unmarshal.Run(r)
		if r.Error != nil {
			return r.Error
		}

		return nil
	}
}

type Handlers struct {
	Build            HandlerList
	Sign             HandlerList
	Send             HandlerList
	ValidateResponse HandlerList
	Unmarshal        HandlerList
	UnmarshalMeta    HandlerList
	UnmarshalError   HandlerList
	Retry            HandlerList
	AfterRetry       HandlerList
}

func (h *Handlers) copy() Handlers {
	return Handlers{
		Build:            h.Build.copy(),
		Sign:             h.Sign.copy(),
		Send:             h.Send.copy(),
		ValidateResponse: h.ValidateResponse.copy(),
		Unmarshal:        h.Unmarshal.copy(),
		UnmarshalError:   h.UnmarshalError.copy(),
		UnmarshalMeta:    h.UnmarshalMeta.copy(),
		Retry:            h.Retry.copy(),
		AfterRetry:       h.AfterRetry.copy(),
	}
}

// Clear removes callback functions for all handlers
func (h *Handlers) Clear() {
	h.Build.Init()
	h.Send.Init()
	h.Sign.Init()
	h.Unmarshal.Init()
	h.UnmarshalMeta.Init()
	h.UnmarshalError.Init()
	h.ValidateResponse.Init()
	h.Retry.Init()
	h.AfterRetry.Init()
}

type HandlerList struct {
	list.List
}

func (l HandlerList) copy() HandlerList {
	var n HandlerList
	for e := l.Front(); e != nil; e = e.Next() {
		h := e.Value.(func(*Request))
		n.PushBack(h)
	}
	return n
}

func (l *HandlerList) Run(r *Request) {
	for e := l.Front(); e != nil; e = e.Next() {
		h := e.Value.(func(*Request))
		h(r)
	}
}
<commit_msg>Ensure that r.Params/r.Data are not pointing directly at nil.<commit_after>package aws

import (
	"bytes"
	"container/list"
	"fmt"
	"io"
	"io/ioutil"
	"math"
	"net/http"
	"net/http/httputil"
	"net/url"
	"reflect"
	"regexp"
	"time"
)

const SDKName = "aws-sdk-go"
const SDKVersion = "0.5.0"

func UserAgentHandler(r *Request) {
	r.HTTPRequest.Header.Set("User-Agent", SDKName+"/"+SDKVersion)
}

func SendHandler(r *Request) {
	r.HTTPResponse, r.Error = r.Service.Config.HTTPClient.Do(r.HTTPRequest)
}

func ValidateResponseHandler(r *Request) {
	if r.HTTPResponse.StatusCode == 0 || r.HTTPResponse.StatusCode >= 400 {
		r.Error = APIError{
			StatusCode: r.HTTPResponse.StatusCode,
			Retryable:  r.Service.ShouldRetry(r),
			RetryDelay: r.Service.RetryRules(r),
			RetryCount: r.RetryCount,
		}
	}
}

func AfterRetryHandler(r *Request) {
	delay := 0 * time.Second
	willRetry := false

	if err := Error(r.Error); err != nil {
		delay = err.RetryDelay
		if err.Retryable && r.RetryCount < r.Service.MaxRetries() {
			r.RetryCount++
			willRetry = true
		}
	}

	if willRetry {
		r.Error = nil
		time.Sleep(delay)
	}
}

type Operation struct {
	*OperationBindings
	Name       string
	HTTPMethod string
	HTTPPath   string
}

type OperationBindings struct {
	InPayload   string
	OutPayload  string
	Required    []string
	QueryParams []string
	URIParams   []string
	InHeaders   []string
	OutHeaders  []string
}

type Service struct {
	Config            *Config
	Handlers          Handlers
	ManualSend        bool
	ServiceName       string
	APIVersion        string
	Endpoint          string
	JSONVersion       string
	TargetPrefix      string
	RetryRules        func(*Request) time.Duration
	ShouldRetry       func(*Request) bool
	DefaultMaxRetries uint
}

var schemeRE = regexp.MustCompile("^([^:]+)://")

func retryRules(r *Request) time.Duration {
	delay := time.Duration(math.Pow(2, float64(r.RetryCount))) * 30
	return delay * time.Millisecond
}

func shouldRetry(r *Request) bool {
	if err := Error(r.Error); err != nil {
		if err.StatusCode >= 500 {
			return true
		}

		switch err.Code {
		case "ExpiredTokenException":
		case "ProvisionedThroughputExceededException", "Throttling":
			return true
		}
	}
	return false
}

func (s *Service) Initialize() {
	if s.Config.HTTPClient == nil {
		s.Config.HTTPClient = http.DefaultClient
	}

	if s.RetryRules == nil {
		s.RetryRules = retryRules
	}

	if s.ShouldRetry == nil {
		s.ShouldRetry = shouldRetry
	}

	s.DefaultMaxRetries = 3
	s.Handlers.Build.PushBack(UserAgentHandler)
	s.Handlers.Sign.PushBack(BuildContentLength)
	s.Handlers.Send.PushBack(SendHandler)
	s.Handlers.AfterRetry.PushBack(AfterRetryHandler)
	s.Handlers.ValidateResponse.PushBack(ValidateResponseHandler)
	s.AddDebugHandlers()
	s.buildEndpoint()
}

type Request struct {
	*Service
	Handlers     Handlers
	Time         time.Time
	ExpireTime   time.Duration
	Operation    *Operation
	HTTPRequest  *http.Request
	HTTPResponse *http.Response
	Body         io.ReadSeeker
	Params       interface{}
	Error        error
	Data         interface{}
	RequestID    string
	RetryCount   uint

	built bool
}

func NewRequest(service *Service, operation *Operation, params interface{}, data interface{}) *Request {
	method := operation.HTTPMethod
	if method == "" {
		method = "POST"
	}
	httpReq, _ := http.NewRequest(method, "", nil)
	httpReq.URL, _ = url.Parse(service.Endpoint + operation.HTTPPath)

	r := &Request{
		Service:     service,
		Handlers:    service.Handlers.copy(),
		Time:        time.Now(),
		ExpireTime:  300,
		Operation:   operation,
		HTTPRequest: httpReq,
		Body:        nil,
		Params:      params,
		Error:       nil,
		Data:        data,
	}

	return r
}

func (s *Service) buildEndpoint() {
	if s.Config.Endpoint != "" {
		s.Endpoint = s.Config.Endpoint
	} else {
		s.Endpoint = s.endpointForRegion()
	}

	if !schemeRE.MatchString(s.Endpoint) {
		scheme := "https"
		if s.Config.DisableSSL {
			scheme = "http"
		}
		s.Endpoint = scheme + "://" + s.Endpoint
	}
}

func (s *Service) AddDebugHandlers() {
	if s.Config.LogLevel == 0 {
		return
	}

	s.Handlers.Sign.PushBack(func(r *Request) {
		dumpedBody, _ := httputil.DumpRequest(r.HTTPRequest, true)

		fmt.Printf("=> [%s] %s.%s(%+v)\n", r.Time,
			r.Service.ServiceName, r.Operation.Name, r.Params)
		fmt.Printf("---[ REQUEST PRE-SIGN ]------------------------------\n")
		fmt.Printf("%s\n", string(dumpedBody))
		fmt.Printf("-----------------------------------------------------\n")
	})
	s.Handlers.Send.PushFront(func(r *Request) {
		dumpedBody, _ := httputil.DumpRequest(r.HTTPRequest, true)

		fmt.Printf("---[ REQUEST POST-SIGN ]-----------------------------\n")
		fmt.Printf("%s\n", string(dumpedBody))
		fmt.Printf("-----------------------------------------------------\n")
	})
	s.Handlers.Send.PushBack(func(r *Request) {
		fmt.Printf("---[ RESPONSE ]--------------------------------------\n")
		if r.HTTPResponse != nil {
			if r.HTTPResponse.Body != nil {
				defer r.HTTPResponse.Body.Close()
			}
			dumpedBody, _ := httputil.DumpResponse(r.HTTPResponse, true)

			fmt.Printf("%s\n", string(dumpedBody))
		} else if r.Error != nil {
			fmt.Printf("%s\n", r.Error)
		}
		fmt.Printf("-----------------------------------------------------\n")
	})
}

func (r *Request) ParamsFilled() bool {
	return r.Params != nil && reflect.ValueOf(r.Params).Elem().IsValid()
}

func (r *Request) DataFilled() bool {
	return r.Data != nil && reflect.ValueOf(r.Data).Elem().IsValid()
}

func (r *Request) SetBufferBody(buf []byte) {
	r.SetReaderBody(bytes.NewReader(buf))
}

func (r *Request) SetReaderBody(reader io.ReadSeeker) {
	r.HTTPRequest.Body = ioutil.NopCloser(reader)
	r.Body = reader
}

func (s *Service) MaxRetries() uint {
	if s.Config.MaxRetries < 0 {
		return s.DefaultMaxRetries
	} else {
		return uint(s.Config.MaxRetries)
	}
}

func (r *Request) Presign(expireTime time.Duration) (string, error) {
	r.ExpireTime = expireTime
	r.Sign()
	if r.Error != nil {
		return "", r.Error
	} else {
		return r.HTTPRequest.URL.String(), nil
	}
}

func (r *Request) Build() error {
	if !r.built {
		r.Error = nil
		r.Handlers.Build.Run(r)
		r.built = true
	}

	return r.Error
}

func (r *Request) Sign() error {
	r.Build()
	if r.Error != nil {
		return r.Error
	}

	r.Handlers.Sign.Run(r)
	return r.Error
}

func (r *Request) Send() error {
	r.Sign()
	if r.Error != nil {
		return r.Error
	}

	for {
		r.Handlers.Send.Run(r)
		if r.Error != nil {
			return r.Error
		}

		r.Handlers.UnmarshalMeta.Run(r)
		r.Handlers.ValidateResponse.Run(r)
		if r.Error != nil {
			r.Handlers.Retry.Run(r)
			r.Handlers.AfterRetry.Run(r)
			if r.Error != nil {
				r.Handlers.UnmarshalError.Run(r)
				return r.Error
			}
			continue
		}

		r.Handlers.Unmarshal.Run(r)
		if r.Error != nil {
			return r.Error
		}

		return nil
	}
}

type Handlers struct {
	Build            HandlerList
	Sign             HandlerList
	Send             HandlerList
	ValidateResponse HandlerList
	Unmarshal        HandlerList
	UnmarshalMeta    HandlerList
	UnmarshalError   HandlerList
	Retry            HandlerList
	AfterRetry       HandlerList
}

func (h *Handlers) copy() Handlers {
	return Handlers{
		Build:            h.Build.copy(),
		Sign:             h.Sign.copy(),
		Send:             h.Send.copy(),
		ValidateResponse: h.ValidateResponse.copy(),
		Unmarshal:        h.Unmarshal.copy(),
		UnmarshalError:   h.UnmarshalError.copy(),
		UnmarshalMeta:    h.UnmarshalMeta.copy(),
		Retry:            h.Retry.copy(),
		AfterRetry:       h.AfterRetry.copy(),
	}
}

// Clear removes callback functions for all handlers
func (h *Handlers) Clear() {
	h.Build.Init()
	h.Send.Init()
	h.Sign.Init()
	h.Unmarshal.Init()
	h.UnmarshalMeta.Init()
	h.UnmarshalError.Init()
	h.ValidateResponse.Init()
	h.Retry.Init()
	h.AfterRetry.Init()
}

type HandlerList struct {
	list.List
}

func (l HandlerList) copy() HandlerList {
	var n HandlerList
	for e := l.Front(); e != nil; e = e.Next() {
		h := e.Value.(func(*Request))
		n.PushBack(h)
	}
	return n
}

func (l *HandlerList) Run(r *Request) {
	for e := l.Front(); e != nil; e = e.Next() {
		h := e.Value.(func(*Request))
		h(r)
	}
}
<|endoftext|>


<commit_before>// Package netlink provides a simple library for netlink. Netlink is
// the interface a user-space program in linux uses to communicate with
// the kernel. It can be used to add and remove interfaces, set up ip
// addresses and routes, and confiugre ipsec. Netlink communication
// requires elevated privileges, so in most cases this code needs to
// be run as root. The low level primitives for netlink are contained
// in the nl subpackage. This package attempts to provide a high-level
// interface that is loosly modeled on the iproute2 cli.
package netlink

import (
	"net"

	"github.com/vishvananda/netlink/nl"
)

const (
	// Family type definitions
	FAMILY_ALL = nl.FAMILY_ALL
	FAMILY_V4  = nl.FAMILY_V4
	FAMILY_V6  = nl.FAMILY_V6
)

// ParseIPNet parses a string in ip/net format and returns a net.IPNet.
// This is valuable because addresses in netlink are often IPNets and
// ParseCIDR returns an IPNet with the IP part set to the base IP of the
// range.
func ParseIPNet(s string) (*net.IPNet, error) {
	ip, ipNet, err := net.ParseCIDR(s)
	if err != nil {
		return nil, err
	}
	return &net.IPNet{IP: ip, Mask: ipNet.Mask}, nil
}

// NewIPNet generates an IPNet from an ip address using a netmask of 32.
func NewIPNet(ip net.IP) *net.IPNet {
	return &net.IPNet{IP: ip, Mask: net.CIDRMask(32, 32)}
}
<commit_msg>Add support for IPv6 in NewIPNet<commit_after>// Package netlink provides a simple library for netlink. Netlink is
// the interface a user-space program in linux uses to communicate with
// the kernel. It can be used to add and remove interfaces, set up ip
// addresses and routes, and confiugre ipsec. Netlink communication
// requires elevated privileges, so in most cases this code needs to
// be run as root. The low level primitives for netlink are contained
// in the nl subpackage. This package attempts to provide a high-level
// interface that is loosly modeled on the iproute2 cli.
package netlink

import (
	"net"

	"github.com/vishvananda/netlink/nl"
)

const (
	// Family type definitions
	FAMILY_ALL = nl.FAMILY_ALL
	FAMILY_V4  = nl.FAMILY_V4
	FAMILY_V6  = nl.FAMILY_V6
)

// ParseIPNet parses a string in ip/net format and returns a net.IPNet.
// This is valuable because addresses in netlink are often IPNets and
// ParseCIDR returns an IPNet with the IP part set to the base IP of the
// range.
func ParseIPNet(s string) (*net.IPNet, error) {
	ip, ipNet, err := net.ParseCIDR(s)
	if err != nil {
		return nil, err
	}
	return &net.IPNet{IP: ip, Mask: ipNet.Mask}, nil
}

// NewIPNet generates an IPNet from an ip address using a netmask of 32 or 128.
func NewIPNet(ip net.IP) *net.IPNet {
	if ip.To4() != nil {
		return &net.IPNet{IP: ip, Mask: net.CIDRMask(32, 32)}
	}
	return &net.IPNet{IP: ip, Mask: net.CIDRMask(128, 128)}
}
<|endoftext|>