<commit_before>/*
Package pipe provides filters that can be chained together in a manner
similar to Unix pipelines.

Each filter is a function that takes as input a sequence of
strings (read from a channel) and produces as output a sequence of
strings (written to a channel).

Filters can be chained together (e.g., via the Run function), the
output of one filter is fed as input to the next filter.  The empty
input is passed to the first filter. The following sequence will
print two lines to standard output:

	err := pipe.Run(
		pipe.Echo("hello", "world"),
		pipe.Reverse(),
		pipe.WriteLines(os.Stdout),
	)

An application can implement its own filters easily. For example,
repeat(n) returns a filter that repeats every input n times.

	func repeat(n int) Filter {
		return func(arg pipe.Arg) {
			for s := range arg.In {
				for i := 0; i < n; i++ {
					arg.Out <- s
				}
			}
		}
	}

	pipe.Run(
		pipe.Echo("hello"),
		repeat(10),
	)

Note that repeat is not a Filter since it needs to accept the
parameter n. Instead, it returns a Filter.  This convention is
followed throughout this library: all filtering functionality is
provided by functions that return a Filter.

*/
package pipe

import (
	"fmt"
	"regexp"
	"sync"
)

// filterErrors records errors accumulated during the execution of a filter.
type filterErrors struct {
	mu     sync.Mutex
	errors []error
}

// Arg contains the data passed to a Filter. Arg.In is a channel that
// produces the input to the filter, and Arg.Out is a channel that
// receives the output from the filter.
type Arg struct {
	In     <-chan string
	Out    chan<- string
	errors *filterErrors
}

// ReportError records an error encountered during an execution of a filter.
// This error will be reported by whatever facility (e.g., ForEach or Run)
// was being used to execute the filters.
//
// A filter should report any errors by calling ReportError.  Even if
// the filter has reported an error, it should read all data from
// arg.In, if only to disarded immediately.
func (a *Arg) ReportError(err error) {
	a.errors.mu.Lock()
	defer a.errors.mu.Unlock()
	a.errors.errors = append(a.errors.errors, err)
}

// Filter is the type of a function that reads a sequence of strings
// from a channel and produces a sequence on another channel.
type Filter func(Arg)

// Sequence returns a filter that is the concatenation of all filter arguments.
// The output of a filter is fed as input to the next filter.
func Sequence(filters ...Filter) Filter {
	return func(arg Arg) {
		in := arg.In
		for _, f := range filters {
			c := make(chan string, 10000)
			go runAndClose(f, Arg{in, c, arg.errors})
			in = c
		}
		passThrough(Arg{in, arg.Out, arg.errors})
	}
}

// Run executes the sequence of filters and discards all output.
// It returns either nil, an error if any filter reported an error.
func Run(filters ...Filter) error {
	return ForEach(Sequence(filters...), func(s string) {})
}

// ForEach calls fn(s) for every item s in the output of filter and
// returns either nil, or any error reported by the execution of the filter.
func ForEach(filter Filter, fn func(s string)) error {
	in := make(chan string, 0)
	close(in)
	out := make(chan string, 10000)
	e := &filterErrors{}
	go runAndClose(filter, Arg{in, out, e})
	for s := range out {
		fn(s)
	}

	e.mu.Lock()
	defer e.mu.Unlock()
	switch len(e.errors) {
	case 0:
		return nil
	case 1:
		return e.errors[0]
	default:
		return fmt.Errorf("Filter errors: %s", e.errors)
	}
}

func runAndClose(f Filter, arg Arg) {
	f(arg)
	close(arg.Out)
}

// passThrough copies all items read from in to out.
func passThrough(arg Arg) {
	for s := range arg.In {
		arg.Out <- s
	}
}

// Echo emits items.
// Any input items are copied verbatim to the output before items are emitted.
func Echo(items ...string) Filter {
	return func(arg Arg) {
		passThrough(arg)
		for _, s := range items {
			arg.Out <- s
		}
	}
}

// Numbers copies its input and then emits the integers x..y
func Numbers(x, y int) Filter {
	return func(arg Arg) {
		passThrough(arg)
		for i := x; i <= y; i++ {
			arg.Out <- fmt.Sprintf("%d", i)
		}
	}
}

// Map calls fn(x) for every item x and yields the outputs of the fn calls.
func Map(fn func(string) string) Filter {
	return func(arg Arg) {
		for s := range arg.In {
			arg.Out <- fn(s)
		}
	}
}

// If emits every input x for which fn(x) is true.
func If(fn func(string) bool) Filter {
	return func(arg Arg) {
		for s := range arg.In {
			if fn(s) {
				arg.Out <- s
			}
		}
	}
}

func errorFilter(err error) Filter {
	return func(arg Arg) {
		arg.ReportError(err)
		for _ = range arg.In {
			// Drop the input
		}
	}
}

// Grep emits every input x that matches the regular expression r.
func Grep(r string) Filter {
	re, err := regexp.Compile(r)
	if err != nil {
		return errorFilter(err)
	}
	return If(re.MatchString)
}

// GrepNot emits every input x that does not match the regular expression r.
func GrepNot(r string) Filter {
	re, err := regexp.Compile(r)
	if err != nil {
		return errorFilter(err)
	}
	return If(func(s string) bool { return !re.MatchString(s) })
}

// Uniq squashes adjacent identical items in arg.In into a single output.
func Uniq() Filter {
	return func(arg Arg) {
		first := true
		last := ""
		for s := range arg.In {
			if first || last != s {
				arg.Out <- s
			}
			last = s
			first = false
		}
	}
}

// UniqWithCount squashes adjacent identical items in arg.In into a single
// output prefixed with the count of identical items.
func UniqWithCount() Filter {
	return func(arg Arg) {
		current := ""
		count := 0
		for s := range arg.In {
			if s != current {
				if count > 0 {
					arg.Out <- fmt.Sprintf("%d %s", count, current)
				}
				count = 0
				current = s
			}
			count++
		}
		if count > 0 {
			arg.Out <- fmt.Sprintf("%d %s", count, current)
		}
	}
}

// Substitute replaces all occurrences of the regular expression r in
// an input item with replacement.  The replacement string can contain
// $1, $2, etc. which represent submatches of r.
func Substitute(r, replacement string) Filter {
	re, err := regexp.Compile(r)
	if err != nil {
		return errorFilter(err)
	}
	return func(arg Arg) {
		for s := range arg.In {
			arg.Out <- re.ReplaceAllString(s, replacement)
		}
	}
}

// Reverse yields items in the reverse of the order it received them.
func Reverse() Filter {
	return func(arg Arg) {
		var data []string
		for s := range arg.In {
			data = append(data, s)
		}
		for i := len(data) - 1; i >= 0; i-- {
			arg.Out <- data[i]
		}
	}
}

// First yields the first n items that it receives.
func First(n int) Filter {
	return func(arg Arg) {
		emitted := 0
		for s := range arg.In {
			if emitted < n {
				arg.Out <- s
				emitted++
			}
		}
	}
}

// DropFirst yields all items except for the first n items that it receives.
func DropFirst(n int) Filter {
	return func(arg Arg) {
		emitted := 0
		for s := range arg.In {
			if emitted >= n {
				arg.Out <- s
			}
			emitted++
		}
	}
}

// Last yields the last n items that it receives.
func Last(n int) Filter {
	return func(arg Arg) {
		var buf []string
		for s := range arg.In {
			buf = append(buf, s)
			if len(buf) > n {
				buf = buf[1:]
			}
		}
		for _, s := range buf {
			arg.Out <- s
		}
	}
}

// DropLast yields all items except for the last n items that it receives.
func DropLast(n int) Filter {
	return func(arg Arg) {
		var buf []string
		for s := range arg.In {
			buf = append(buf, s)
			if len(buf) > n {
				arg.Out <- buf[0]
				buf = buf[1:]
			}
		}
	}
}

// NumberLines prefixes its item with its index in the input sequence
// (starting at 1).
func NumberLines() Filter {
	return func(arg Arg) {
		line := 1
		for s := range arg.In {
			arg.Out <- fmt.Sprintf("%5d %s", line, s)
			line++
		}
	}
}

// Slice emits s[startOffset:endOffset] for each input item s.  Note
// that Slice follows Go conventions, and unlike the "cut" utility,
// offsets are numbered starting at zero, and the end offset is not
// included in the output.
func Slice(startOffset, endOffset int) Filter {
	return func(arg Arg) {
		for s := range arg.In {
			if len(s) > endOffset {
				s = s[:endOffset]
			}
			if len(s) < startOffset {
				s = ""
			} else {
				s = s[startOffset:]
			}
			arg.Out <- s
		}
	}
}

// Select splits each item into columns and yields the concatenation
// of the columns numbers passed as arguments to Select.  Columns are
// numbered starting at 1. A column number of 0 is interpreted as the
// full string.
func Select(columns ...int) Filter {
	return func(arg Arg) {
		for s := range arg.In {
			result := ""
			for _, col := range columns {
				if _, c := column(s, col); c != "" {
					if result != "" {
						result = result + " "
					}
					result = result + c
				}
			}
			arg.Out <- result
		}
	}
}
<commit_msg>fix typo<commit_after>/*
Package pipe provides filters that can be chained together in a manner
similar to Unix pipelines.

Each filter is a function that takes as input a sequence of
strings (read from a channel) and produces as output a sequence of
strings (written to a channel).

Filters can be chained together (e.g., via the Run function), the
output of one filter is fed as input to the next filter.  The empty
input is passed to the first filter. The following sequence will
print two lines to standard output:

	err := pipe.Run(
		pipe.Echo("hello", "world"),
		pipe.Reverse(),
		pipe.WriteLines(os.Stdout),
	)

An application can implement its own filters easily. For example,
repeat(n) returns a filter that repeats every input n times.

	func repeat(n int) Filter {
		return func(arg pipe.Arg) {
			for s := range arg.In {
				for i := 0; i < n; i++ {
					arg.Out <- s
				}
			}
		}
	}

	pipe.Run(
		pipe.Echo("hello"),
		repeat(10),
	)

Note that repeat is not a Filter since it needs to accept the
parameter n. Instead, it returns a Filter.  This convention is
followed throughout this library: all filtering functionality is
provided by functions that return a Filter.

*/
package pipe

import (
	"fmt"
	"regexp"
	"sync"
)

// filterErrors records errors accumulated during the execution of a filter.
type filterErrors struct {
	mu     sync.Mutex
	errors []error
}

// Arg contains the data passed to a Filter. Arg.In is a channel that
// produces the input to the filter, and Arg.Out is a channel that
// receives the output from the filter.
type Arg struct {
	In     <-chan string
	Out    chan<- string
	errors *filterErrors
}

// ReportError records an error encountered during an execution of a filter.
// This error will be reported by whatever facility (e.g., ForEach or Run)
// was being used to execute the filters.
//
// A filter should report any errors by calling ReportError.  Even if
// the filter has reported an error, it should read all data from
// arg.In, if only to disard it immediately.
func (a *Arg) ReportError(err error) {
	a.errors.mu.Lock()
	defer a.errors.mu.Unlock()
	a.errors.errors = append(a.errors.errors, err)
}

// Filter is the type of a function that reads a sequence of strings
// from a channel and produces a sequence on another channel.
type Filter func(Arg)

// Sequence returns a filter that is the concatenation of all filter arguments.
// The output of a filter is fed as input to the next filter.
func Sequence(filters ...Filter) Filter {
	return func(arg Arg) {
		in := arg.In
		for _, f := range filters {
			c := make(chan string, 10000)
			go runAndClose(f, Arg{in, c, arg.errors})
			in = c
		}
		passThrough(Arg{in, arg.Out, arg.errors})
	}
}

// Run executes the sequence of filters and discards all output.
// It returns either nil, an error if any filter reported an error.
func Run(filters ...Filter) error {
	return ForEach(Sequence(filters...), func(s string) {})
}

// ForEach calls fn(s) for every item s in the output of filter and
// returns either nil, or any error reported by the execution of the filter.
func ForEach(filter Filter, fn func(s string)) error {
	in := make(chan string, 0)
	close(in)
	out := make(chan string, 10000)
	e := &filterErrors{}
	go runAndClose(filter, Arg{in, out, e})
	for s := range out {
		fn(s)
	}

	e.mu.Lock()
	defer e.mu.Unlock()
	switch len(e.errors) {
	case 0:
		return nil
	case 1:
		return e.errors[0]
	default:
		return fmt.Errorf("Filter errors: %s", e.errors)
	}
}

func runAndClose(f Filter, arg Arg) {
	f(arg)
	close(arg.Out)
}

// passThrough copies all items read from in to out.
func passThrough(arg Arg) {
	for s := range arg.In {
		arg.Out <- s
	}
}

// Echo emits items.
// Any input items are copied verbatim to the output before items are emitted.
func Echo(items ...string) Filter {
	return func(arg Arg) {
		passThrough(arg)
		for _, s := range items {
			arg.Out <- s
		}
	}
}

// Numbers copies its input and then emits the integers x..y
func Numbers(x, y int) Filter {
	return func(arg Arg) {
		passThrough(arg)
		for i := x; i <= y; i++ {
			arg.Out <- fmt.Sprintf("%d", i)
		}
	}
}

// Map calls fn(x) for every item x and yields the outputs of the fn calls.
func Map(fn func(string) string) Filter {
	return func(arg Arg) {
		for s := range arg.In {
			arg.Out <- fn(s)
		}
	}
}

// If emits every input x for which fn(x) is true.
func If(fn func(string) bool) Filter {
	return func(arg Arg) {
		for s := range arg.In {
			if fn(s) {
				arg.Out <- s
			}
		}
	}
}

func errorFilter(err error) Filter {
	return func(arg Arg) {
		arg.ReportError(err)
		for _ = range arg.In {
			// Drop the input
		}
	}
}

// Grep emits every input x that matches the regular expression r.
func Grep(r string) Filter {
	re, err := regexp.Compile(r)
	if err != nil {
		return errorFilter(err)
	}
	return If(re.MatchString)
}

// GrepNot emits every input x that does not match the regular expression r.
func GrepNot(r string) Filter {
	re, err := regexp.Compile(r)
	if err != nil {
		return errorFilter(err)
	}
	return If(func(s string) bool { return !re.MatchString(s) })
}

// Uniq squashes adjacent identical items in arg.In into a single output.
func Uniq() Filter {
	return func(arg Arg) {
		first := true
		last := ""
		for s := range arg.In {
			if first || last != s {
				arg.Out <- s
			}
			last = s
			first = false
		}
	}
}

// UniqWithCount squashes adjacent identical items in arg.In into a single
// output prefixed with the count of identical items.
func UniqWithCount() Filter {
	return func(arg Arg) {
		current := ""
		count := 0
		for s := range arg.In {
			if s != current {
				if count > 0 {
					arg.Out <- fmt.Sprintf("%d %s", count, current)
				}
				count = 0
				current = s
			}
			count++
		}
		if count > 0 {
			arg.Out <- fmt.Sprintf("%d %s", count, current)
		}
	}
}

// Substitute replaces all occurrences of the regular expression r in
// an input item with replacement.  The replacement string can contain
// $1, $2, etc. which represent submatches of r.
func Substitute(r, replacement string) Filter {
	re, err := regexp.Compile(r)
	if err != nil {
		return errorFilter(err)
	}
	return func(arg Arg) {
		for s := range arg.In {
			arg.Out <- re.ReplaceAllString(s, replacement)
		}
	}
}

// Reverse yields items in the reverse of the order it received them.
func Reverse() Filter {
	return func(arg Arg) {
		var data []string
		for s := range arg.In {
			data = append(data, s)
		}
		for i := len(data) - 1; i >= 0; i-- {
			arg.Out <- data[i]
		}
	}
}

// First yields the first n items that it receives.
func First(n int) Filter {
	return func(arg Arg) {
		emitted := 0
		for s := range arg.In {
			if emitted < n {
				arg.Out <- s
				emitted++
			}
		}
	}
}

// DropFirst yields all items except for the first n items that it receives.
func DropFirst(n int) Filter {
	return func(arg Arg) {
		emitted := 0
		for s := range arg.In {
			if emitted >= n {
				arg.Out <- s
			}
			emitted++
		}
	}
}

// Last yields the last n items that it receives.
func Last(n int) Filter {
	return func(arg Arg) {
		var buf []string
		for s := range arg.In {
			buf = append(buf, s)
			if len(buf) > n {
				buf = buf[1:]
			}
		}
		for _, s := range buf {
			arg.Out <- s
		}
	}
}

// DropLast yields all items except for the last n items that it receives.
func DropLast(n int) Filter {
	return func(arg Arg) {
		var buf []string
		for s := range arg.In {
			buf = append(buf, s)
			if len(buf) > n {
				arg.Out <- buf[0]
				buf = buf[1:]
			}
		}
	}
}

// NumberLines prefixes its item with its index in the input sequence
// (starting at 1).
func NumberLines() Filter {
	return func(arg Arg) {
		line := 1
		for s := range arg.In {
			arg.Out <- fmt.Sprintf("%5d %s", line, s)
			line++
		}
	}
}

// Slice emits s[startOffset:endOffset] for each input item s.  Note
// that Slice follows Go conventions, and unlike the "cut" utility,
// offsets are numbered starting at zero, and the end offset is not
// included in the output.
func Slice(startOffset, endOffset int) Filter {
	return func(arg Arg) {
		for s := range arg.In {
			if len(s) > endOffset {
				s = s[:endOffset]
			}
			if len(s) < startOffset {
				s = ""
			} else {
				s = s[startOffset:]
			}
			arg.Out <- s
		}
	}
}

// Select splits each item into columns and yields the concatenation
// of the columns numbers passed as arguments to Select.  Columns are
// numbered starting at 1. A column number of 0 is interpreted as the
// full string.
func Select(columns ...int) Filter {
	return func(arg Arg) {
		for s := range arg.In {
			result := ""
			for _, col := range columns {
				if _, c := column(s, col); c != "" {
					if result != "" {
						result = result + " "
					}
					result = result + c
				}
			}
			arg.Out <- result
		}
	}
}
<|endoftext|>


<commit_before>package app

import (
	"github.com/toonsevrin/simplechain/types"
	"net/http"
	"github.com/gorilla/mux"

	"encoding/json"
	"io/ioutil"
	"fmt"
	"strings"
	"os"
)

type Server struct {
	App App
}
func (server *Server) Init(){

	router := mux.NewRouter().StrictSlash(true)

	router.Methods("GET").Path("/blocks").HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		if isLocalhostOrPeer(*server, *request){
			json.NewEncoder(writer).Encode(server.App.Blockchain)
		}else {
			json.NewEncoder(writer).Encode(Success{false, &string("Unauthorized")})
		}
	})
	router.Methods("POST").Path("/mineBlock").HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		if isLocalhostOrPeer(*server, *request) {
			body, err := ioutil.ReadAll(request.Body)
			if err != nil {
				json.NewEncoder(writer).Encode(Success{false, &string("An error occurred reading request body")})
				fmt.Println(err.Error())
				return
			}
			data := string(body)
			block := server.App.createAndAddNextBlock(data)
			json.NewEncoder(writer).Encode(Success{Success:true})
			server.App.broadcast(block)
		}else {
			json.NewEncoder(writer).Encode(Success{false, &"Unauthorized"})
		}
	})
	router.Methods("POST").Path("/addBlock").HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		if isLocalhostOrPeer(*server, *request){
			block := types.Block{}
			body, err := ioutil.ReadAll(request.Body)
			if err != nil {
				json.NewEncoder(writer).Encode(Success{false,&"An error occurred reading request body"})
				fmt.Println(err.Error())
				return
			}
			if err := json.Unmarshal(body, &block); err != nil {
				json.NewEncoder(writer).Encode(Success{false,&"An error occurred parsing request body"})
				fmt.Println(err.Error())
				return
			}
			if server.App.HasBlock(block){
				json.NewEncoder(writer).Encode(Success{false,&"Block already exists"})
				fmt.Println("Received block that already exists in db.")
				return
			}
			if !block.IsValid() {
				json.NewEncoder(writer).Encode(Success{false,&"Received invalid block"})
				fmt.Println("Received invalid block")
				return
			}
			if uint32(len(server.App.Blockchain)) == block.Index {//next block
				if block.PreviousHash == server.App.getLatestBlock().Hash {//next block references your chain
					server.App.AddBlock(block)
					json.NewEncoder(writer).Encode(Success{Success: true})
					server.App.broadcast(block)
				}else {
					json.NewEncoder(writer).Encode(Success{Success: false, Error: &"Invalid hash"})
				}
			}else if uint32(len(server.App.Blockchain)) < block.Index {//block is in the future
				RemoteChain := []types.Block{}
				response, err := http.NewRequest("GET", server.App.Peers[request.RemoteAddr].getUrl() + "/blocks", nil)
				if err != nil {
					json.NewEncoder(writer).Encode(Success{Success: false, Error: &string(err.Error())})
					fmt.Println(err.Error())
					return
				}
				body, err := ioutil.ReadAll(response.Body)
				if err != nil {
					json.NewEncoder(writer).Encode(Success{Success: false, Error: &string(err.Error())})
					fmt.Println(err.Error())
					return
				}
				if err := json.Unmarshal(body, &RemoteChain); err != nil {
					json.NewEncoder(writer).Encode(Success{Success: false, Error: &string(err.Error())})
					fmt.Println(err.Error())
					return
				}
				if(server.App.pickLongestChain(RemoteChain)){
					json.NewEncoder(writer).Encode(Success{Success: true})
					server.App.broadcast(block)
				}else {
					json.NewEncoder(writer).Encode(Success{Success: false, Error: &"Peer has a longer chain"})
				}
			}
		}else {
			json.NewEncoder(writer).Encode(Success{Success: false, Error: &"Unauthorized"})
		}
	})
	router.Methods("POST").Path("/addPeer").HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		if isLocalhost(*request){
			body, err := ioutil.ReadAll(request.Body)
			if err != nil {
				json.NewEncoder(writer).Encode(Success{Success: false, Error: &string(err.Error())})
				fmt.Println(err.Error())
				return
			}
			peer := Peer{}
			if err := json.Unmarshal(body, &peer); err != nil {
				json.NewEncoder(writer).Encode(Success{Success: false, Error: &string(err.Error())})
				fmt.Println(err.Error())
				return
			}
			server.App.Peers[peer.getUrl()] = &peer
			server.App.PeerAddresses[peer.Ip] = true
			json.NewEncoder(writer).Encode(Success{Success: true})
		}else{
			writer.Write([]byte("Only localhost can add peers"))
		}
	})
	http.ListenAndServe(":" + getPort(), router)
}
func getPort() string{
	port := os.Getenv("PORT")
	if(port == ""){
		return "8080"
	}else {
		return port
	}
}
func isLocalhostOrPeer(server Server, request http.Request) bool{
	_, isPeer := server.App.PeerAddresses[request.RemoteAddr]
	return isPeer || isLocalhost(request)
}
func isLocalhost(req http.Request) bool{
	fmt.Println(req.RemoteAddr)
	return strings.Contains(req.RemoteAddr, "127.0.0.1") || strings.Contains(req.RemoteAddr, "[::1]")//::1 is ipv6
}

type Success struct {
	Success bool `json:"success"`
	Error *string `json:"error"`
}<commit_msg>testing pointer string v2<commit_after>package app

import (
	"github.com/toonsevrin/simplechain/types"
	"net/http"
	"github.com/gorilla/mux"

	"encoding/json"
	"io/ioutil"
	"fmt"
	"strings"
	"os"
)

type Server struct {
	App App
}
func (server *Server) Init(){

	router := mux.NewRouter().StrictSlash(true)

	router.Methods("GET").Path("/blocks").HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		if isLocalhostOrPeer(*server, *request){
			json.NewEncoder(writer).Encode(server.App.Blockchain)
		}else {
			json.NewEncoder(writer).Encode(Success{false, str("Unauthorized")})
		}
	})
	router.Methods("POST").Path("/mineBlock").HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		if isLocalhostOrPeer(*server, *request) {
			body, err := ioutil.ReadAll(request.Body)
			if err != nil {
				json.NewEncoder(writer).Encode(Success{false, str("An error occurred reading request body")})
				fmt.Println(err.Error())
				return
			}
			data := string(body)
			block := server.App.createAndAddNextBlock(data)
			json.NewEncoder(writer).Encode(Success{Success:true})
			server.App.broadcast(block)
		}else {
			json.NewEncoder(writer).Encode(Success{false, &"Unauthorized"})
		}
	})
	router.Methods("POST").Path("/addBlock").HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		if isLocalhostOrPeer(*server, *request){
			block := types.Block{}
			body, err := ioutil.ReadAll(request.Body)
			if err != nil {
				json.NewEncoder(writer).Encode(Success{false,&"An error occurred reading request body"})
				fmt.Println(err.Error())
				return
			}
			if err := json.Unmarshal(body, &block); err != nil {
				json.NewEncoder(writer).Encode(Success{false,&"An error occurred parsing request body"})
				fmt.Println(err.Error())
				return
			}
			if server.App.HasBlock(block){
				json.NewEncoder(writer).Encode(Success{false,&"Block already exists"})
				fmt.Println("Received block that already exists in db.")
				return
			}
			if !block.IsValid() {
				json.NewEncoder(writer).Encode(Success{false,&"Received invalid block"})
				fmt.Println("Received invalid block")
				return
			}
			if uint32(len(server.App.Blockchain)) == block.Index {//next block
				if block.PreviousHash == server.App.getLatestBlock().Hash {//next block references your chain
					server.App.AddBlock(block)
					json.NewEncoder(writer).Encode(Success{Success: true})
					server.App.broadcast(block)
				}else {
					json.NewEncoder(writer).Encode(Success{Success: false, Error: &"Invalid hash"})
				}
			}else if uint32(len(server.App.Blockchain)) < block.Index {//block is in the future
				RemoteChain := []types.Block{}
				response, err := http.NewRequest("GET", server.App.Peers[request.RemoteAddr].getUrl() + "/blocks", nil)
				if err != nil {
					json.NewEncoder(writer).Encode(Success{Success: false, Error: &string(err.Error())})
					fmt.Println(err.Error())
					return
				}
				body, err := ioutil.ReadAll(response.Body)
				if err != nil {
					json.NewEncoder(writer).Encode(Success{Success: false, Error: &string(err.Error())})
					fmt.Println(err.Error())
					return
				}
				if err := json.Unmarshal(body, &RemoteChain); err != nil {
					json.NewEncoder(writer).Encode(Success{Success: false, Error: &string(err.Error())})
					fmt.Println(err.Error())
					return
				}
				if(server.App.pickLongestChain(RemoteChain)){
					json.NewEncoder(writer).Encode(Success{Success: true})
					server.App.broadcast(block)
				}else {
					json.NewEncoder(writer).Encode(Success{Success: false, Error: &"Peer has a longer chain"})
				}
			}
		}else {
			json.NewEncoder(writer).Encode(Success{Success: false, Error: &"Unauthorized"})
		}
	})
	router.Methods("POST").Path("/addPeer").HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		if isLocalhost(*request){
			body, err := ioutil.ReadAll(request.Body)
			if err != nil {
				json.NewEncoder(writer).Encode(Success{Success: false, Error: &string(err.Error())})
				fmt.Println(err.Error())
				return
			}
			peer := Peer{}
			if err := json.Unmarshal(body, &peer); err != nil {
				json.NewEncoder(writer).Encode(Success{Success: false, Error: &string(err.Error())})
				fmt.Println(err.Error())
				return
			}
			server.App.Peers[peer.getUrl()] = &peer
			server.App.PeerAddresses[peer.Ip] = true
			json.NewEncoder(writer).Encode(Success{Success: true})
		}else{
			writer.Write([]byte("Only localhost can add peers"))
		}
	})
	http.ListenAndServe(":" + getPort(), router)
}
func getPort() string{
	port := os.Getenv("PORT")
	if(port == ""){
		return "8080"
	}else {
		return port
	}
}
func isLocalhostOrPeer(server Server, request http.Request) bool{
	_, isPeer := server.App.PeerAddresses[request.RemoteAddr]
	return isPeer || isLocalhost(request)
}
func isLocalhost(req http.Request) bool{
	fmt.Println(req.RemoteAddr)
	return strings.Contains(req.RemoteAddr, "127.0.0.1") || strings.Contains(req.RemoteAddr, "[::1]")//::1 is ipv6
}

type Success struct {
	Success bool `json:"success"`
	Error *string `json:"error"`
}

func str(str string) *string{
	return &str
}<|endoftext|>


<commit_before>package containeranalysis

import (
	"context"
	"errors"

	containeranalysisapi "cloud.google.com/go/containeranalysis/apiv1"
	grafeasv1 "cloud.google.com/go/grafeas/apiv1"

	"github.com/docker/distribution/reference"
	"google.golang.org/api/iterator"
	grafeas "google.golang.org/genproto/googleapis/grafeas/v1"

	"github.com/Shopify/voucher"
	"github.com/Shopify/voucher/attestation"
	"github.com/Shopify/voucher/repository"
	"github.com/Shopify/voucher/signer"
)

var errCannotAttest = errors.New("cannot create attestations, keyring is empty")

// Client implements voucher.MetadataClient, connecting to containeranalysis Grafeas.
type Client struct {
	containeranalysis *grafeasv1.Client        // The client reference.
	keyring           signer.AttestationSigner // The keyring used for signing metadata.
	binauthProject    string                   // The project that Binauth Notes and Occurrences are written to.
	imageProject      string                   // The project that image information is stored.
}

// CanAttest returns true if the client can create and sign attestations.
func (g *Client) CanAttest() bool {
	return nil != g.keyring
}

// NewPayloadBody returns a payload body appropriate for this MetadataClient.
func (g *Client) NewPayloadBody(reference reference.Canonical) (string, error) {
	payload, err := attestation.NewPayload(reference).ToString()
	if err != nil {
		return "", err
	}

	return payload, err
}

// AddAttestationToImage adds a new attestation with the passed Attestation
// to the image described by ImageData.
func (g *Client) AddAttestationToImage(ctx context.Context, reference reference.Canonical, attestation voucher.Attestation) (voucher.SignedAttestation, error) {
	if !g.CanAttest() {
		return voucher.SignedAttestation{}, errCannotAttest
	}

	signedAttestation, err := voucher.SignAttestation(g.keyring, attestation)
	if nil != err {
		return voucher.SignedAttestation{}, err
	}

	_, err = g.containeranalysis.CreateOccurrence(
		ctx,
		newOccurrenceAttestation(
			reference,
			signedAttestation,
			g.binauthProject,
		),
	)

	if isAttestionExistsErr(err) {
		err = nil

		signedAttestation.Signature = ""
	}

	return signedAttestation, err
}

// GetAttestations returns all of the attestations associated with an image.
func (g *Client) GetAttestations(ctx context.Context, reference reference.Canonical) ([]voucher.SignedAttestation, error) {
	filterStr := kindFilterStr(reference, grafeas.NoteKind_ATTESTATION)

	var attestations []voucher.SignedAttestation

	project := projectPath(g.binauthProject)
	req := &grafeas.ListOccurrencesRequest{Parent: project, Filter: filterStr}
	occIterator := g.containeranalysis.ListOccurrences(ctx, req)

	for {
		occ, err := occIterator.Next()
		if nil != err {
			if iterator.Done == err {
				return attestations, nil
			}
			return nil, err
		}

		note, err := g.containeranalysis.GetOccurrenceNote(
			ctx,
			&grafeas.GetOccurrenceNoteRequest{
				Name: occ.GetName(),
			},
		)
		if nil != err {
			return nil, err
		}

		name := getCheckNameFromNoteName(g.binauthProject, note.GetName())

		attestations = append(
			attestations,
			OccurrenceToAttestation(name, occ),
		)
	}
}

// GetVulnerabilities returns the detected vulnerabilities for the Image described by voucher.ImageData.
func (g *Client) GetVulnerabilities(ctx context.Context, reference reference.Canonical) (vulnerabilities []voucher.Vulnerability, err error) {
	filterStr := kindFilterStr(reference, grafeas.NoteKind_VULNERABILITY)

	err = pollForDiscoveries(ctx, g, reference)
	if nil != err {
		return []voucher.Vulnerability{}, err
	}

	project := projectPath(g.imageProject)
	req := &grafeas.ListOccurrencesRequest{Parent: project, Filter: filterStr}
	occIterator := g.containeranalysis.ListOccurrences(ctx, req)

	for {
		var occ *grafeas.Occurrence

		occ, err = occIterator.Next()
		if nil != err {
			if iterator.Done == err {
				err = nil
			}

			break
		}

		vuln := OccurrenceToVulnerability(occ)
		vulnerabilities = append(vulnerabilities, vuln)
	}

	return
}

// Close closes the containeranalysis Grafeas client.
func (g *Client) Close() {
	g.containeranalysis.Close()
}

// GetBuildDetail gets the BuildDetail for the passed image.
func (g *Client) GetBuildDetail(ctx context.Context, reference reference.Canonical) (repository.BuildDetail, error) {
	var err error

	filterStr := kindFilterStr(reference, grafeas.NoteKind_BUILD)

	project := projectPath(g.imageProject)
	req := &grafeas.ListOccurrencesRequest{Parent: project, Filter: filterStr}
	occIterator := g.containeranalysis.ListOccurrences(ctx, req)

	occ, err := occIterator.Next()
	if err != nil {
		if err == iterator.Done {
			err = &voucher.NoMetadataError{
				Type: voucher.VulnerabilityType,
				Err:  errNoOccurrences,
			}
		}
		return repository.BuildDetail{}, err
	}

	if _, err := occIterator.Next(); err != iterator.Done {
		return repository.BuildDetail{}, errors.New("Found multiple Grafeas occurrences for " + reference.String())
	}

	return OccurrenceToBuildDetail(occ), nil
}

// NewClient creates a new containeranalysis Grafeas Client.
func NewClient(ctx context.Context, imageProject, binauthProject string, keyring signer.AttestationSigner) (*Client, error) {
	var err error

	caClient, err := containeranalysisapi.NewClient(ctx)
	if err != nil {
		return nil, err
	}

	client := &Client{
		containeranalysis: caClient.GetGrafeasClient(),
		keyring:           keyring,
		binauthProject:    binauthProject,
		imageProject:      imageProject,
	}

	return client, nil
}
<commit_msg>close keyring if it's open (#95)<commit_after>package containeranalysis

import (
	"context"
	"errors"

	containeranalysisapi "cloud.google.com/go/containeranalysis/apiv1"
	grafeasv1 "cloud.google.com/go/grafeas/apiv1"

	"github.com/docker/distribution/reference"
	"google.golang.org/api/iterator"
	grafeas "google.golang.org/genproto/googleapis/grafeas/v1"

	"github.com/Shopify/voucher"
	"github.com/Shopify/voucher/attestation"
	"github.com/Shopify/voucher/repository"
	"github.com/Shopify/voucher/signer"
)

var errCannotAttest = errors.New("cannot create attestations, keyring is empty")

// Client implements voucher.MetadataClient, connecting to containeranalysis Grafeas.
type Client struct {
	containeranalysis *grafeasv1.Client        // The client reference.
	keyring           signer.AttestationSigner // The keyring used for signing metadata.
	binauthProject    string                   // The project that Binauth Notes and Occurrences are written to.
	imageProject      string                   // The project that image information is stored.
}

// CanAttest returns true if the client can create and sign attestations.
func (g *Client) CanAttest() bool {
	return nil != g.keyring
}

// NewPayloadBody returns a payload body appropriate for this MetadataClient.
func (g *Client) NewPayloadBody(reference reference.Canonical) (string, error) {
	payload, err := attestation.NewPayload(reference).ToString()
	if err != nil {
		return "", err
	}

	return payload, err
}

// AddAttestationToImage adds a new attestation with the passed Attestation
// to the image described by ImageData.
func (g *Client) AddAttestationToImage(ctx context.Context, reference reference.Canonical, attestation voucher.Attestation) (voucher.SignedAttestation, error) {
	if !g.CanAttest() {
		return voucher.SignedAttestation{}, errCannotAttest
	}

	signedAttestation, err := voucher.SignAttestation(g.keyring, attestation)
	if nil != err {
		return voucher.SignedAttestation{}, err
	}

	_, err = g.containeranalysis.CreateOccurrence(
		ctx,
		newOccurrenceAttestation(
			reference,
			signedAttestation,
			g.binauthProject,
		),
	)

	if isAttestionExistsErr(err) {
		err = nil

		signedAttestation.Signature = ""
	}

	return signedAttestation, err
}

// GetAttestations returns all of the attestations associated with an image.
func (g *Client) GetAttestations(ctx context.Context, reference reference.Canonical) ([]voucher.SignedAttestation, error) {
	filterStr := kindFilterStr(reference, grafeas.NoteKind_ATTESTATION)

	var attestations []voucher.SignedAttestation

	project := projectPath(g.binauthProject)
	req := &grafeas.ListOccurrencesRequest{Parent: project, Filter: filterStr}
	occIterator := g.containeranalysis.ListOccurrences(ctx, req)

	for {
		occ, err := occIterator.Next()
		if nil != err {
			if iterator.Done == err {
				return attestations, nil
			}
			return nil, err
		}

		note, err := g.containeranalysis.GetOccurrenceNote(
			ctx,
			&grafeas.GetOccurrenceNoteRequest{
				Name: occ.GetName(),
			},
		)
		if nil != err {
			return nil, err
		}

		name := getCheckNameFromNoteName(g.binauthProject, note.GetName())

		attestations = append(
			attestations,
			OccurrenceToAttestation(name, occ),
		)
	}
}

// GetVulnerabilities returns the detected vulnerabilities for the Image described by voucher.ImageData.
func (g *Client) GetVulnerabilities(ctx context.Context, reference reference.Canonical) (vulnerabilities []voucher.Vulnerability, err error) {
	filterStr := kindFilterStr(reference, grafeas.NoteKind_VULNERABILITY)

	err = pollForDiscoveries(ctx, g, reference)
	if nil != err {
		return []voucher.Vulnerability{}, err
	}

	project := projectPath(g.imageProject)
	req := &grafeas.ListOccurrencesRequest{Parent: project, Filter: filterStr}
	occIterator := g.containeranalysis.ListOccurrences(ctx, req)

	for {
		var occ *grafeas.Occurrence

		occ, err = occIterator.Next()
		if nil != err {
			if iterator.Done == err {
				err = nil
			}

			break
		}

		vuln := OccurrenceToVulnerability(occ)
		vulnerabilities = append(vulnerabilities, vuln)
	}

	return
}

// Close closes the containeranalysis Grafeas client.
func (g *Client) Close() {
	if nil != g.keyring {
		_ = g.keyring.Close()
	}
	g.containeranalysis.Close()
}

// GetBuildDetail gets the BuildDetail for the passed image.
func (g *Client) GetBuildDetail(ctx context.Context, reference reference.Canonical) (repository.BuildDetail, error) {
	var err error

	filterStr := kindFilterStr(reference, grafeas.NoteKind_BUILD)

	project := projectPath(g.imageProject)
	req := &grafeas.ListOccurrencesRequest{Parent: project, Filter: filterStr}
	occIterator := g.containeranalysis.ListOccurrences(ctx, req)

	occ, err := occIterator.Next()
	if err != nil {
		if err == iterator.Done {
			err = &voucher.NoMetadataError{
				Type: voucher.VulnerabilityType,
				Err:  errNoOccurrences,
			}
		}
		return repository.BuildDetail{}, err
	}

	if _, err := occIterator.Next(); err != iterator.Done {
		return repository.BuildDetail{}, errors.New("Found multiple Grafeas occurrences for " + reference.String())
	}

	return OccurrenceToBuildDetail(occ), nil
}

// NewClient creates a new containeranalysis Grafeas Client.
func NewClient(ctx context.Context, imageProject, binauthProject string, keyring signer.AttestationSigner) (*Client, error) {
	var err error

	caClient, err := containeranalysisapi.NewClient(ctx)
	if err != nil {
		return nil, err
	}

	client := &Client{
		containeranalysis: caClient.GetGrafeasClient(),
		keyring:           keyring,
		binauthProject:    binauthProject,
		imageProject:      imageProject,
	}

	return client, nil
}
<|endoftext|>


<commit_before>package pool

import (
	"errors"
	"net"
	"sync"
	"time"
)

type NextConn func() (net.Conn, error)

type limitConn struct {
	net.Conn
	*sync.Cond
	limit *uint64
}

func (c *limitConn) Close() error {
	go func() {
		c.Cond.L.Lock()
		defer c.Cond.L.Unlock()
		(*c.limit)++
		c.Cond.Signal()
	}()
	return c.Conn.Close()
}

func PoolLimiter(next NextConn, limit uint64) NextConn {
	var mu sync.Mutex
	cond := sync.NewCond(&mu)

	return func() (net.Conn, error) {
		mu.Lock()
		defer mu.Unlock()
		for limit == 0 {
			cond.Wait()
		}
		c, err := next()
		if err == nil {
			limit--
			c = &limitConn{
				Conn:  c,
				Cond:  cond,
				limit: &limit,
			}
		}
		return c, err
	}
}

type Pool struct {
	next NextConn
	reqs *requests
	dead chan struct{}
}

func NewPool(next NextConn) *Pool {
	p := &Pool{
		next: next,
		reqs: newRequests(),
		dead: make(chan struct{}),
	}
	go p.manage()
	return p
}

var ErrPoolClosed = errors.New("pool closed")

func (p *Pool) Get() (net.Conn, error) {
	if c, ok := <-p.reqs.submit(); ok {
		return c, nil
	}
	return nil, ErrPoolClosed
}

func (p *Pool) manage() {
	for {
		req, ok := p.reqs.next()
		if !ok {
			return
		}

		var c net.Conn
		err := errors.New("temp error")

		for err != nil {
			c, err = p.next()
			if err != nil {
				select {
				case <-time.After(5 * time.Second):
				case <-p.dead:
					close(req)
					return
				}
			}
		}

		req <- c
	}
}

func (p *Pool) Close() error {
	p.reqs.close()
	close(p.dead)
	return nil
}

type requests struct {
	mu   sync.Mutex
	cond *sync.Cond
	dead bool
	reqs []chan net.Conn
}

func newRequests() *requests {
	r := &requests{reqs: make([]chan net.Conn, 0)}
	r.cond = sync.NewCond(&r.mu)
	return r
}

func (r *requests) submit() <-chan net.Conn {
	r.mu.Lock()
	defer r.mu.Unlock()
	req := make(chan net.Conn)
	if r.dead {
		close(req)
	} else {
		r.reqs = append(r.reqs, req)
		r.cond.Signal()
	}
	return req
}

func (r *requests) next() (req chan<- net.Conn, ok bool) {
	r.mu.Lock()
	defer r.mu.Unlock()
	for len(r.reqs) == 0 && !r.dead {
		r.cond.Wait()
	}
	if r.dead {
		return nil, false
	} else {
		req, r.reqs = r.reqs[0], r.reqs[1:]
		return req, true
	}
}

func (r *requests) close() {
	r.mu.Lock()
	defer r.mu.Unlock()
	r.dead = true
	for _, req := range r.reqs {
		close(req)
	}
	r.reqs = nil
	r.cond.Broadcast()
}
<commit_msg>added godoc<commit_after>package pool

import (
	"errors"
	"net"
	"sync"
	"time"
)

type NextConn func() (net.Conn, error)

type limitConn struct {
	net.Conn
	*sync.Cond
	limit *uint64
}

func (c *limitConn) Close() error {
	go func() {
		c.Cond.L.Lock()
		defer c.Cond.L.Unlock()
		(*c.limit)++
		c.Cond.Signal()
	}()
	return c.Conn.Close()
}

// PoolLimiter limits the number of concurrent connections returned by next to limit
func PoolLimiter(next NextConn, limit uint64) NextConn {
	var mu sync.Mutex
	cond := sync.NewCond(&mu)

	return func() (net.Conn, error) {
		mu.Lock()
		defer mu.Unlock()
		for limit == 0 {
			cond.Wait()
		}
		c, err := next()
		if err == nil {
			limit--
			c = &limitConn{
				Conn:  c,
				Cond:  cond,
				limit: &limit,
			}
		}
		return c, err
	}
}

// Pool manages connections
type Pool struct {
	next NextConn
	reqs *requests
	dead chan struct{}
}

// NewPool creates a new Pool object for managing connections
func NewPool(next NextConn) *Pool {
	p := &Pool{
		next: next,
		reqs: newRequests(),
		dead: make(chan struct{}),
	}
	go p.manage()
	return p
}

var ErrPoolClosed = errors.New("pool closed")

// Get will return a net.Conn, it can be called concurrently
// and calls to Get() will be returned in the order they were called.
func (p *Pool) Get() (net.Conn, error) {
	if c, ok := <-p.reqs.submit(); ok {
		return c, nil
	}
	return nil, ErrPoolClosed
}

func (p *Pool) manage() {
	for {
		req, ok := p.reqs.next()
		if !ok {
			return
		}

		var c net.Conn
		err := errors.New("temp error")

		for err != nil {
			c, err = p.next()
			if err != nil {
				select {
				case <-time.After(5 * time.Second):
				case <-p.dead:
					close(req)
					return
				}
			}
		}

		req <- c
	}
}

// Close closes the pool and cancels calls to Get()
func (p *Pool) Close() error {
	p.reqs.close()
	close(p.dead)
	return nil
}

type requests struct {
	mu   sync.Mutex
	cond *sync.Cond
	dead bool
	reqs []chan net.Conn
}

func newRequests() *requests {
	r := &requests{reqs: make([]chan net.Conn, 0)}
	r.cond = sync.NewCond(&r.mu)
	return r
}

func (r *requests) submit() <-chan net.Conn {
	r.mu.Lock()
	defer r.mu.Unlock()
	req := make(chan net.Conn)
	if r.dead {
		close(req)
	} else {
		r.reqs = append(r.reqs, req)
		r.cond.Signal()
	}
	return req
}

func (r *requests) next() (req chan<- net.Conn, ok bool) {
	r.mu.Lock()
	defer r.mu.Unlock()
	for len(r.reqs) == 0 && !r.dead {
		r.cond.Wait()
	}
	if r.dead {
		return nil, false
	} else {
		req, r.reqs = r.reqs[0], r.reqs[1:]
		return req, true
	}
}

func (r *requests) close() {
	r.mu.Lock()
	defer r.mu.Unlock()
	r.dead = true
	for _, req := range r.reqs {
		close(req)
	}
	r.reqs = nil
	r.cond.Broadcast()
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"
	"os/signal"
	"runtime/pprof"
	"strings"
	"syscall"

	"github.com/cenkalti/log"
	"github.com/cenkalti/rain/client"
	"github.com/cenkalti/rain/internal/logger"
	"github.com/cenkalti/rain/resume/torrentresume"
	"github.com/cenkalti/rain/storage/filestorage"
	"github.com/cenkalti/rain/torrent"
	"github.com/mitchellh/go-homedir"
)

var (
	configPath = flag.String("config", "", "config path")
	dest       = flag.String("dest", ".", "where to download")
	port       = flag.Int("port", 0, "listen port")
	debug      = flag.Bool("debug", false, "enable debug log")
	version    = flag.Bool("version", false, "version")
	seed       = flag.Bool("seed", false, "continue seeding after dowload finishes")
	cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`")
)

func main() {
	flag.Parse()
	if *cpuprofile != "" {
		f, err := os.Create(*cpuprofile)
		if err != nil {
			log.Fatal("could not create CPU profile: ", err)
		}
		if err := pprof.StartCPUProfile(f); err != nil {
			log.Fatal("could not start CPU profile: ", err)
		}
		defer pprof.StopCPUProfile()
	}
	if *version {
		fmt.Println(torrent.Version)
		return
	}
	args := flag.Args()
	if len(args) == 0 {
		_, _ = fmt.Fprintln(os.Stderr, "Give a torrent file as first argument!")
		os.Exit(1)
	}
	if *debug {
		logger.SetLogLevel(log.DEBUG)
	}
	cfg := client.NewConfig()
	if *configPath != "" {
		cp, err := homedir.Expand(*configPath)
		if err != nil {
			log.Fatal(err)
		}
		err = cfg.LoadFile(cp)
		if err != nil {
			log.Fatal(err)
		}
	}
	sto, err := filestorage.New(*dest)
	if err != nil {
		log.Fatal(err)
	}
	res, err := torrentresume.New("rain.resume")
	if err != nil {
		log.Fatal(err)
	}
	var t *torrent.Torrent
	if strings.HasPrefix(args[0], "magnet:") {
		t, err = torrent.DownloadMagnet(args[0], *port, sto, res)
	} else {
		f, err2 := os.Open(args[0])
		if err2 != nil {
			log.Fatal(err2)
		}
		t, err = torrent.DownloadTorrent(f, *port, sto, res)
		_ = f.Close()
	}
	if err != nil {
		log.Fatal(err)
	}

	sigC := make(chan os.Signal, 1)
	signal.Notify(sigC, syscall.SIGINT, syscall.SIGTERM)
LOOP:
	for {
		select {
		case <-sigC:
			break LOOP
		case <-t.NotifyComplete():
			if !*seed {
				break LOOP
			}
		case err = <-t.NotifyError():
			log.Error(err)
			os.Exit(1)
		}
	}
	err = t.Close()
	if err != nil {
		log.Fatal(err)
	}
}
<commit_msg>fix cli<commit_after>package main

import (
	"flag"
	"fmt"
	"os"
	"os/signal"
	"runtime/pprof"
	"strings"
	"syscall"

	"github.com/cenkalti/log"
	"github.com/cenkalti/rain/client"
	"github.com/cenkalti/rain/internal/logger"
	rainversion "github.com/cenkalti/rain/internal/version"
	"github.com/cenkalti/rain/resume/torrentresume"
	"github.com/cenkalti/rain/storage/filestorage"
	"github.com/cenkalti/rain/torrent"
	"github.com/mitchellh/go-homedir"
)

var (
	configPath = flag.String("config", "", "config path")
	dest       = flag.String("dest", ".", "where to download")
	port       = flag.Int("port", 0, "listen port")
	debug      = flag.Bool("debug", false, "enable debug log")
	version    = flag.Bool("version", false, "version")
	seed       = flag.Bool("seed", false, "continue seeding after dowload finishes")
	cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`")
)

func main() {
	flag.Parse()
	if *cpuprofile != "" {
		f, err := os.Create(*cpuprofile)
		if err != nil {
			log.Fatal("could not create CPU profile: ", err)
		}
		if err := pprof.StartCPUProfile(f); err != nil {
			log.Fatal("could not start CPU profile: ", err)
		}
		defer pprof.StopCPUProfile()
	}
	if *version {
		fmt.Println(rainversion.Version)
		return
	}
	args := flag.Args()
	if len(args) == 0 {
		_, _ = fmt.Fprintln(os.Stderr, "Give a torrent file as first argument!")
		os.Exit(1)
	}
	if *debug {
		logger.SetLogLevel(log.DEBUG)
	}
	cfg := client.NewConfig()
	if *configPath != "" {
		cp, err := homedir.Expand(*configPath)
		if err != nil {
			log.Fatal(err)
		}
		err = cfg.LoadFile(cp)
		if err != nil {
			log.Fatal(err)
		}
	}
	sto, err := filestorage.New(*dest)
	if err != nil {
		log.Fatal(err)
	}
	res, err := torrentresume.New("rain.resume")
	if err != nil {
		log.Fatal(err)
	}
	var t *torrent.Torrent
	if strings.HasPrefix(args[0], "magnet:") {
		t, err = torrent.DownloadMagnet(args[0], *port, sto, res)
	} else {
		f, err2 := os.Open(args[0])
		if err2 != nil {
			log.Fatal(err2)
		}
		t, err = torrent.DownloadTorrent(f, *port, sto, res)
		_ = f.Close()
	}
	if err != nil {
		log.Fatal(err)
	}

	sigC := make(chan os.Signal, 1)
	signal.Notify(sigC, syscall.SIGINT, syscall.SIGTERM)
LOOP:
	for {
		select {
		case <-sigC:
			break LOOP
		case <-t.NotifyComplete():
			if !*seed {
				break LOOP
			}
		case err = <-t.NotifyError():
			log.Error(err)
			os.Exit(1)
		}
	}
	t.Close()
}
<|endoftext|>


<commit_before>package tchannel

import (
	"math/rand"
	"sync"
)

// lockedSource allows a random number generator to be used by multiple goroutines concurrently.
// The code is very similar to math/rand.lockedSource, which is unfortunately not exposed.
type lockedSource struct {
	mut sync.Mutex
	src rand.Source
}

// NewRand returns a rand.Rand that is threadsafe.
func NewRand(seed int64) *rand.Rand {
	return rand.New(&lockedSource{src: rand.NewSource(seed)})
}

func (r *lockedSource) Int63() (n int64) {
	r.mut.Lock()
	n = r.src.Int63()
	r.mut.Unlock()
	return
}

func (r *lockedSource) Seed(seed int64) {
	r.mut.Lock()
	r.src.Seed(seed)
	r.mut.Unlock()
}
<commit_msg>Add copyright<commit_after>package tchannel

// Copyright (c) 2015 Uber Technologies, Inc.

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import (
	"math/rand"
	"sync"
)

// lockedSource allows a random number generator to be used by multiple goroutines concurrently.
// The code is very similar to math/rand.lockedSource, which is unfortunately not exposed.
type lockedSource struct {
	mut sync.Mutex
	src rand.Source
}

// NewRand returns a rand.Rand that is threadsafe.
func NewRand(seed int64) *rand.Rand {
	return rand.New(&lockedSource{src: rand.NewSource(seed)})
}

func (r *lockedSource) Int63() (n int64) {
	r.mut.Lock()
	n = r.src.Int63()
	r.mut.Unlock()
	return
}

func (r *lockedSource) Seed(seed int64) {
	r.mut.Lock()
	r.src.Seed(seed)
	r.mut.Unlock()
}
<|endoftext|>


<commit_before>package main

import (
  "github.com/ricallinson/forgery"
  "github.com/spacedock-io/index/models"
)

func CreateRepo(req *f.Request, res *f.Response, next func()) {
  ns := req.Params["namespace"]
  repo := req.Params["repo"]

  images := req.Map["json"]

  r := &models.Repo{}
  ts, err := r.Create(repo, ns, "1", req.Map["_uid"].(int64), images.([]interface{}))
  if err != nil {
    res.Send(err.Error(), 400)
  }

  res.Set("X-Docker-Token", ts)
  res.Set("WWW-Authenticate", "Token " + ts)
  res.Set("X-Docker-Endpoints", "reg22.spacedock.io, reg41.spacedock.io")

  res.Send("Created", 200)
}

func DeleteRepo(req *f.Request, res *f.Response, next func()) {
  res.Send("Not implemented yet.")
}

func GetUserImage(req *f.Request, res *f.Response, next func()) {
  res.Send("Not implemented yet.")
}

func RepoAuth(req *f.Request, res *f.Response, next func()) {
  res.Send(200)
}

func UpdateUserImage(req *f.Request, res *f.Response, next func()) {
  res.Send("Not implemented yet.")
}
<commit_msg>GET user repo images now works<commit_after>package main

import (
  "encoding/json"
  "github.com/ricallinson/forgery"
  "github.com/spacedock-io/index/models"
)

func CreateRepo(req *f.Request, res *f.Response, next func()) {
  ns := req.Params["namespace"]
  repo := req.Params["repo"]

  images := req.Map["json"]

  r := &models.Repo{}
  ts, err := r.Create(repo, ns, "1", req.Map["_uid"].(int64), images.([]interface{}))
  if err != nil {
    res.Send(err.Error(), 400)
  }

  res.Set("X-Docker-Token", ts)
  res.Set("WWW-Authenticate", "Token " + ts)
  res.Set("X-Docker-Endpoints", "reg22.spacedock.io, reg41.spacedock.io")

  res.Send("Created", 200)
}

func DeleteRepo(req *f.Request, res *f.Response, next func()) {
  res.Send("Not implemented yet.")
}

func GetUserImage(req *f.Request, res *f.Response, next func()) {
  repo := req.Params["repo"]
  ns := req.Params["ns"]

  r, err := models.GetRepo(ns, repo)
  if err != nil {
    res.Send(err.Error(), 400)
  }

  images, e := r.GetImages()
  if e != nil {
    res.Send(e.Error(), 400)
  }

  j, jsonErr := json.Marshal(images)
  if jsonErr != nil {
    res.Send("Error returning data", 400)
  }
  res.Send(string(j), 200)
}

func RepoAuth(req *f.Request, res *f.Response, next func()) {
  res.Send(200)
}

func UpdateUserImage(req *f.Request, res *f.Response, next func()) {
  res.Send("Not implemented yet.")
}
<|endoftext|>


<commit_before>package main

import (
  "encoding/json"
  "github.com/ricallinson/forgery"
  "github.com/spacedock-io/index/models"
)

func CreateRepo(req *f.Request, res *f.Response, next func()) {
  images := req.Map["json"]
  u := req.Map["_user"].(*models.User)

  r := &models.Repo{
    Namespace: req.Params["namespace"],
    Name: req.Params["repo"],
  }

  ts, err := r.Create("1", u, images.([]interface{}))
  if err != nil {
    res.Send(err.Error(), 400)
  }

  res.Set("X-Docker-Token", ts)
  res.Set("WWW-Authenticate", "Token " + ts)
  res.Set("X-Docker-Endpoints", "staging.spacedock.io:8081")

  res.Send("\"\"", 200)
}

func DeleteRepo(req *f.Request, res *f.Response, next func()) {
  namespace := req.Params["namespace"]
  repo := req.Params["repo"]

  r, err := models.GetRepo(namespace, repo)
  if err != nil {
    res.Send(err.Error(), 400)
    return
  }

  if !r.Deleted {
    ts, err := r.MarkAsDeleted(req.Map["_uid"].(int64))
    if err != nil {
      res.Send(err.Error(), 400)
      return
    }

    res.Set("X-Docker-Token", ts)
    res.Set("WWW-Authenticate", "Token " + ts)
    res.Set("X-Docker-Endpoints", "staging.spacedock.io:8081")

    res.Send(202)
    return
  }

  err = r.Delete()
  if err != nil {
    res.Send(err.Error(), 400)
    return
  }

  res.Send(200)
}

func GetUserImage(req *f.Request, res *f.Response, next func()) {
  repo := req.Params["repo"]
  ns := req.Params["ns"]

  r, err := models.GetRepo(ns, repo)
  if err != nil {
    res.Send(err.Error(), 400)
  }

  images, e := r.GetImages()
  if e != nil {
    res.Send(e.Error(), 400)
  }

  j, jsonErr := json.Marshal(images)
  if jsonErr != nil {
    res.Send("Error returning data", 400)
  }
  res.Send(string(j), 200)
}

func RepoAuth(req *f.Request, res *f.Response, next func()) {
  res.Send(200)
}

func UpdateUserImage(req *f.Request, res *f.Response, next func()) {
  repo := req.Params["repo"]
  ns := req.Params["namespace"]
  json := req.Map["json"].([]interface{})

  r, err := models.GetRepo(ns, repo)
  if err != nil {
    res.Send(err.Error(), 400)
  }

  er := r.UpdateImages(json)
  if er != nil {
    res.Send(err.Error(), 400)
  }

  res.Send("\"\"", 204)
}
<commit_msg>Let's try a mix of 201 and 200<commit_after>package main

import (
  "encoding/json"
  "github.com/ricallinson/forgery"
  "github.com/spacedock-io/index/models"
)

func CreateRepo(req *f.Request, res *f.Response, next func()) {
  images := req.Map["json"]
  u := req.Map["_user"].(*models.User)

  r := &models.Repo{
    Namespace: req.Params["namespace"],
    Name: req.Params["repo"],
  }

  ts, err := r.Create("1", u, images.([]interface{}))
  if err == models.AlreadyExistsErr {
    res.Send("\"\"", 200)
    return
  } else if err != nil {
    res.Send(err.Error(), 400)
    return
  }

  res.Set("X-Docker-Token", ts)
  res.Set("WWW-Authenticate", "Token " + ts)
  res.Set("X-Docker-Endpoints", "staging.spacedock.io:8081")

  res.Send("\"\"", 201)
}

func DeleteRepo(req *f.Request, res *f.Response, next func()) {
  namespace := req.Params["namespace"]
  repo := req.Params["repo"]

  r, err := models.GetRepo(namespace, repo)
  if err != nil {
    res.Send(err.Error(), 400)
    return
  }

  if !r.Deleted {
    ts, err := r.MarkAsDeleted(req.Map["_uid"].(int64))
    if err != nil {
      res.Send(err.Error(), 400)
      return
    }

    res.Set("X-Docker-Token", ts)
    res.Set("WWW-Authenticate", "Token " + ts)
    res.Set("X-Docker-Endpoints", "staging.spacedock.io:8081")

    res.Send(202)
    return
  }

  err = r.Delete()
  if err != nil {
    res.Send(err.Error(), 400)
    return
  }

  res.Send(200)
}

func GetUserImage(req *f.Request, res *f.Response, next func()) {
  repo := req.Params["repo"]
  ns := req.Params["ns"]

  r, err := models.GetRepo(ns, repo)
  if err != nil {
    res.Send(err.Error(), 400)
  }

  images, e := r.GetImages()
  if e != nil {
    res.Send(e.Error(), 400)
  }

  j, jsonErr := json.Marshal(images)
  if jsonErr != nil {
    res.Send("Error returning data", 400)
  }
  res.Send(string(j), 200)
}

func RepoAuth(req *f.Request, res *f.Response, next func()) {
  res.Send(200)
}

func UpdateUserImage(req *f.Request, res *f.Response, next func()) {
  repo := req.Params["repo"]
  ns := req.Params["namespace"]
  json := req.Map["json"].([]interface{})

  r, err := models.GetRepo(ns, repo)
  if err != nil {
    res.Send(err.Error(), 400)
  }

  er := r.UpdateImages(json)
  if er != nil {
    res.Send(err.Error(), 400)
  }

  res.Send("\"\"", 204)
}
<|endoftext|>


<commit_before>package dnsr

var root = `
;       This file holds the information on root name servers needed to
;       initialize cache of Internet domain name servers
;       (e.g. reference this file in the "cache  .  <file>"
;       configuration file of BIND domain name servers).
;
;       This file is made available by InterNIC
;       under anonymous FTP as
;           file                /domain/named.cache
;           on server           FTP.INTERNIC.NET
;       -OR-                    RS.INTERNIC.NET
;
;       last update:     October 23, 2017
;       related version of root zone:     2017102301
;
; FORMERLY NS.INTERNIC.NET
;
.                        3600000      NS    A.ROOT-SERVERS.NET.
A.ROOT-SERVERS.NET.      3600000      A     198.41.0.4
A.ROOT-SERVERS.NET.      3600000      AAAA  2001:503:ba3e::2:30
;
; FORMERLY NS1.ISI.EDU
;
.                        3600000      NS    B.ROOT-SERVERS.NET.
B.ROOT-SERVERS.NET.      3600000      A     192.228.79.201
B.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:200::b
;
; FORMERLY C.PSI.NET
;
.                        3600000      NS    C.ROOT-SERVERS.NET.
C.ROOT-SERVERS.NET.      3600000      A     192.33.4.12
C.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:2::c
;
; FORMERLY TERP.UMD.EDU
;
.                        3600000      NS    D.ROOT-SERVERS.NET.
D.ROOT-SERVERS.NET.      3600000      A     199.7.91.13
D.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:2d::d
;
; FORMERLY NS.NASA.GOV
;
.                        3600000      NS    E.ROOT-SERVERS.NET.
E.ROOT-SERVERS.NET.      3600000      A     192.203.230.10
E.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:a8::e
;
; FORMERLY NS.ISC.ORG
;
.                        3600000      NS    F.ROOT-SERVERS.NET.
F.ROOT-SERVERS.NET.      3600000      A     192.5.5.241
F.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:2f::f
;
; FORMERLY NS.NIC.DDN.MIL
;
.                        3600000      NS    G.ROOT-SERVERS.NET.
G.ROOT-SERVERS.NET.      3600000      A     192.112.36.4
G.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:12::d0d
;
; FORMERLY AOS.ARL.ARMY.MIL
;
.                        3600000      NS    H.ROOT-SERVERS.NET.
H.ROOT-SERVERS.NET.      3600000      A     198.97.190.53
H.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:1::53
;
; FORMERLY NIC.NORDU.NET
;
.                        3600000      NS    I.ROOT-SERVERS.NET.
I.ROOT-SERVERS.NET.      3600000      A     192.36.148.17
I.ROOT-SERVERS.NET.      3600000      AAAA  2001:7fe::53
;
; OPERATED BY VERISIGN, INC.
;
.                        3600000      NS    J.ROOT-SERVERS.NET.
J.ROOT-SERVERS.NET.      3600000      A     192.58.128.30
J.ROOT-SERVERS.NET.      3600000      AAAA  2001:503:c27::2:30
;
; OPERATED BY RIPE NCC
;
.                        3600000      NS    K.ROOT-SERVERS.NET.
K.ROOT-SERVERS.NET.      3600000      A     193.0.14.129
K.ROOT-SERVERS.NET.      3600000      AAAA  2001:7fd::1
;
; OPERATED BY ICANN
;
.                        3600000      NS    L.ROOT-SERVERS.NET.
L.ROOT-SERVERS.NET.      3600000      A     199.7.83.42
L.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:9f::42
;
; OPERATED BY WIDE
;
.                        3600000      NS    M.ROOT-SERVERS.NET.
M.ROOT-SERVERS.NET.      3600000      A     202.12.27.33
M.ROOT-SERVERS.NET.      3600000      AAAA  2001:dc3::35
; End of file`
<commit_msg>autopull: 2017-10-24T23:30:17Z<commit_after>package dnsr

var root = `
;       This file holds the information on root name servers needed to
;       initialize cache of Internet domain name servers
;       (e.g. reference this file in the "cache  .  <file>"
;       configuration file of BIND domain name servers).
;
;       This file is made available by InterNIC
;       under anonymous FTP as
;           file                /domain/named.cache
;           on server           FTP.INTERNIC.NET
;       -OR-                    RS.INTERNIC.NET
;
;       last update:     October 24, 2017
;       related version of root zone:     2017102400
;
; FORMERLY NS.INTERNIC.NET
;
.                        3600000      NS    A.ROOT-SERVERS.NET.
A.ROOT-SERVERS.NET.      3600000      A     198.41.0.4
A.ROOT-SERVERS.NET.      3600000      AAAA  2001:503:ba3e::2:30
;
; FORMERLY NS1.ISI.EDU
;
.                        3600000      NS    B.ROOT-SERVERS.NET.
B.ROOT-SERVERS.NET.      3600000      A     199.9.14.201
B.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:200::b
;
; FORMERLY C.PSI.NET
;
.                        3600000      NS    C.ROOT-SERVERS.NET.
C.ROOT-SERVERS.NET.      3600000      A     192.33.4.12
C.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:2::c
;
; FORMERLY TERP.UMD.EDU
;
.                        3600000      NS    D.ROOT-SERVERS.NET.
D.ROOT-SERVERS.NET.      3600000      A     199.7.91.13
D.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:2d::d
;
; FORMERLY NS.NASA.GOV
;
.                        3600000      NS    E.ROOT-SERVERS.NET.
E.ROOT-SERVERS.NET.      3600000      A     192.203.230.10
E.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:a8::e
;
; FORMERLY NS.ISC.ORG
;
.                        3600000      NS    F.ROOT-SERVERS.NET.
F.ROOT-SERVERS.NET.      3600000      A     192.5.5.241
F.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:2f::f
;
; FORMERLY NS.NIC.DDN.MIL
;
.                        3600000      NS    G.ROOT-SERVERS.NET.
G.ROOT-SERVERS.NET.      3600000      A     192.112.36.4
G.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:12::d0d
;
; FORMERLY AOS.ARL.ARMY.MIL
;
.                        3600000      NS    H.ROOT-SERVERS.NET.
H.ROOT-SERVERS.NET.      3600000      A     198.97.190.53
H.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:1::53
;
; FORMERLY NIC.NORDU.NET
;
.                        3600000      NS    I.ROOT-SERVERS.NET.
I.ROOT-SERVERS.NET.      3600000      A     192.36.148.17
I.ROOT-SERVERS.NET.      3600000      AAAA  2001:7fe::53
;
; OPERATED BY VERISIGN, INC.
;
.                        3600000      NS    J.ROOT-SERVERS.NET.
J.ROOT-SERVERS.NET.      3600000      A     192.58.128.30
J.ROOT-SERVERS.NET.      3600000      AAAA  2001:503:c27::2:30
;
; OPERATED BY RIPE NCC
;
.                        3600000      NS    K.ROOT-SERVERS.NET.
K.ROOT-SERVERS.NET.      3600000      A     193.0.14.129
K.ROOT-SERVERS.NET.      3600000      AAAA  2001:7fd::1
;
; OPERATED BY ICANN
;
.                        3600000      NS    L.ROOT-SERVERS.NET.
L.ROOT-SERVERS.NET.      3600000      A     199.7.83.42
L.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:9f::42
;
; OPERATED BY WIDE
;
.                        3600000      NS    M.ROOT-SERVERS.NET.
M.ROOT-SERVERS.NET.      3600000      A     202.12.27.33
M.ROOT-SERVERS.NET.      3600000      AAAA  2001:dc3::35
; End of file`
<|endoftext|>


<commit_before>package sqlutil

import (
	"database/sql"
	"strings"
)

// Creates a result holder for a query result as an array of raw bytes
func ResultHolder(rows *sql.Rows) []interface{} {
	cols, _ := rows.Columns()
	l := len(cols)
	result := make([]interface{}, l, l)
	for i, _ := range cols {
		result[i] = new(sql.RawBytes)
	}
	return result
}

type rawResult map[string][]byte

// Converts a query results row for each row resultt as a map of column to raw bytes
func RawResultMap(rows *sql.Rows) []rawResult {
	cols, _ := rows.Columns()
	result := ResultHolder(rows)
	results := make([]rawResult, 0)
	c := 0
	for rows.Next() {
		c++
		resultMap := make(map[string][]byte)
		rows.Scan(result...)
		for i, v := range result {
			f := v.(*sql.RawBytes)
			resultMap[cols[i]] = (*f)[:]
		}
		results = append(results, resultMap)
	}

	return results
}
<commit_msg>removed an unused import<commit_after>package sqlutil

import (
	"database/sql"
)

// Creates a result holder for a query result as an array of raw bytes
func ResultHolder(rows *sql.Rows) []interface{} {
	cols, _ := rows.Columns()
	l := len(cols)
	result := make([]interface{}, l, l)
	for i, _ := range cols {
		result[i] = new(sql.RawBytes)
	}
	return result
}

type rawResult map[string][]byte

// Converts a query results row for each row resultt as a map of column to raw bytes
func RawResultMap(rows *sql.Rows) []rawResult {
	cols, _ := rows.Columns()
	result := ResultHolder(rows)
	results := make([]rawResult, 0)
	c := 0
	for rows.Next() {
		c++
		resultMap := make(map[string][]byte)
		rows.Scan(result...)
		for i, v := range result {
			f := v.(*sql.RawBytes)
			resultMap[cols[i]] = (*f)[:]
		}
		results = append(results, resultMap)
	}

	return results
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"log"
	"os"
	"os/exec"
	"strings"

	"github.com/codegangsta/cli"
)

func assert(err error) {
	if err != nil {
		log.Fatal(err)
	}
}

func stringInSlice(a string, list []string) bool {
	for _, b := range list {
		if b == a {
			return true
		}
	}
	return false
}

// RunCommand runs cmd on file
func RunCommand(cmd string, path string) string {

	cmdOut, err := exec.Command(cmd, path).Output()
	assert(err)

	return string(cmdOut)
}

// ParseExiftoolOutput convert exiftool output into JSON
func ParseExiftoolOutput(exifout string) []byte {

	var ignoreTags = []string{
		"Directory",
		"File Name",
		"File Permissions",
		"File Modification Date/Time",
	}

	exifJSON := make(map[string]map[string]string)
	lines := strings.Split(exifout, "\n")
	datas := make(map[string]string, len(lines))

	for _, line := range lines {
		keyvalue := strings.Split(line, ":")
		if len(keyvalue) != 2 {
			continue
		}
		if !stringInSlice(strings.TrimSpace(keyvalue[0]), ignoreTags) {
			datas[strings.TrimSpace(keyvalue[0])] = strings.TrimSpace(keyvalue[1])
		}
	}

	exifJSON["exiftool"] = datas
	jsonExif, err := json.Marshal(exifJSON)
	assert(err)

	return jsonExif
}

// ParseSsdeepOutput convert ssdeep output into JSON
func ParseSsdeepOutput(ssdout string) []byte {

	datas := make(map[string]string, 1)
	// Break output into lines
	lines := strings.Split(ssdout, "\n")
	// Break second line into hash and path
	hashAndPath := strings.Split(lines[1], ",")
	// Add hash to map
	datas["ssdeep"] = strings.TrimSpace(hashAndPath[0])

	jsonSsdeep, err := json.Marshal(datas)
	assert(err)

	return jsonSsdeep
}

// ParseTRiDOutput convert trid output into JSON
func ParseTRiDOutput(tridout string) []byte {
	lines := strings.Split(tridout, "\n")
	lines = lines[5:]

	// fmt.Println(lines)

	datas := make(map[string][]string, 1)
	j, err := json.Marshal(datas)
	assert(err)

	return j
}

func main() {
	// argPath := os.Args[1]
	app := cli.NewApp()
	app.Name = "greet"
	app.Usage = "fight the loneliness!"
	app.Action = func(c *cli.Context) {
		path := c.Args().First()
		if _, err := os.Stat(path); os.IsNotExist(err) {
			assert(err)
		}
		ssdeepJSON := ParseSsdeepOutput(RunCommand("ssdeep", path))
		tridJSON := ParseTRiDOutput(RunCommand("trid", path))
		exiftoolJSON := ParseExiftoolOutput(RunCommand("exiftool", path))
		fmt.Println(string(ssdeepJSON))
		fmt.Println(string(tridJSON))
		fmt.Println(string(exiftoolJSON))
	}

	app.Run(os.Args)
}
<commit_msg>get rid of codegangsta/cli<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"log"
	"os"
	"os/exec"
	"strings"
)

func assert(err error) {
	if err != nil {
		log.Fatal(err)
	}
}

func stringInSlice(a string, list []string) bool {
	for _, b := range list {
		if b == a {
			return true
		}
	}
	return false
}

// RunCommand runs cmd on file
func RunCommand(cmd string, path string) string {

	cmdOut, err := exec.Command(cmd, path).Output()
	assert(err)

	return string(cmdOut)
}

// ParseExiftoolOutput convert exiftool output into JSON
func ParseExiftoolOutput(exifout string) []byte {

	var ignoreTags = []string{
		"Directory",
		"File Name",
		"File Permissions",
		"File Modification Date/Time",
	}

	exifJSON := make(map[string]map[string]string)
	lines := strings.Split(exifout, "\n")
	datas := make(map[string]string, len(lines))

	for _, line := range lines {
		keyvalue := strings.Split(line, ":")
		if len(keyvalue) != 2 {
			continue
		}
		if !stringInSlice(strings.TrimSpace(keyvalue[0]), ignoreTags) {
			datas[strings.TrimSpace(keyvalue[0])] = strings.TrimSpace(keyvalue[1])
		}
	}

	exifJSON["exiftool"] = datas
	jsonExif, err := json.Marshal(exifJSON)
	assert(err)

	return jsonExif
}

// ParseSsdeepOutput convert ssdeep output into JSON
func ParseSsdeepOutput(ssdout string) []byte {

	datas := make(map[string]string, 1)
	// Break output into lines
	lines := strings.Split(ssdout, "\n")
	// Break second line into hash and path
	hashAndPath := strings.Split(lines[1], ",")
	// Add hash to map
	datas["ssdeep"] = strings.TrimSpace(hashAndPath[0])

	jsonSsdeep, err := json.Marshal(datas)
	assert(err)

	return jsonSsdeep
}

// ParseTRiDOutput convert trid output into JSON
func ParseTRiDOutput(tridout string) []byte {
	lines := strings.Split(tridout, "\n")
	lines = lines[5:]

	// fmt.Println(lines)

	datas := make(map[string][]string, 1)
	j, err := json.Marshal(datas)
	assert(err)

	return j
}

func main() {
	path := os.Args[1]

	if _, err := os.Stat(path); os.IsNotExist(err) {
		assert(err)
	}
	ssdeepJSON := ParseSsdeepOutput(RunCommand("ssdeep", path))
	tridJSON := ParseTRiDOutput(RunCommand("trid", path))
	exiftoolJSON := ParseExiftoolOutput(RunCommand("exiftool", path))
	fmt.Println(string(ssdeepJSON))
	fmt.Println(string(tridJSON))
	fmt.Println(string(exiftoolJSON))
}
<|endoftext|>


<commit_before>package gomail

import (
	"errors"
	"fmt"
	"io"
	"net/mail"
)

// Sender is the interface that wraps the Send method.
//
// Send sends an email to the given addresses.
type Sender interface {
	Send(from string, to []string, msg io.WriterTo) error
}

// SendCloser is the interface that groups the Send and Close methods.
type SendCloser interface {
	Sender
	Close() error
}

// A SendFunc is a function that sends emails to the given adresses.
//
// The SendFunc type is an adapter to allow the use of ordinary functions as
// email senders. If f is a function with the appropriate signature, SendFunc(f)
// is a Sender object that calls f.
type SendFunc func(from string, to []string, msg io.WriterTo) error

// Send calls f(from, to, msg).
func (f SendFunc) Send(from string, to []string, msg io.WriterTo) error {
	return f(from, to, msg)
}

// Send sends emails using the given Sender.
func Send(s Sender, msg ...*Message) error {
	for i, m := range msg {
		if err := send(s, m); err != nil {
			return fmt.Errorf("gomail: could not send email %d: %v", i+1, err)
		}
	}

	return nil
}

func send(s Sender, m *Message) error {
	from, err := m.getFrom()
	if err != nil {
		return err
	}

	to, err := m.getRecipients()
	if err != nil {
		return err
	}

	if err := s.Send(from, to, m); err != nil {
		return err
	}

	return nil
}

func (m *Message) getFrom() (string, error) {
	from := m.header["Sender"]
	if len(from) == 0 {
		from = m.header["From"]
		if len(from) == 0 {
			return "", errors.New(`gomail: invalid message, "From" field is absent`)
		}
	}

	return parseAddress(from[0])
}

func (m *Message) getRecipients() ([]string, error) {
	n := 0
	for _, field := range []string{"To", "Cc", "Bcc"} {
		if addresses, ok := m.header[field]; ok {
			n += len(addresses)
		}
	}
	list := make([]string, 0, n)

	for _, field := range []string{"To", "Cc", "Bcc"} {
		if addresses, ok := m.header[field]; ok {
			for _, a := range addresses {
				addr, err := parseAddress(a)
				if err != nil {
					return nil, err
				}
				list = addAddress(list, addr)
			}
		}
	}

	return list, nil
}

func addAddress(list []string, addr string) []string {
	for _, a := range list {
		if addr == a {
			return list
		}
	}

	return append(list, addr)
}

func parseAddress(field string) (string, error) {
	a, err := mail.ParseAddress(field)
	if a == nil {
		return "", err
	}

	return a.Address, err
}
<commit_msg>Made the error clearer when an address is invalid<commit_after>package gomail

import (
	"errors"
	"fmt"
	"io"
	"net/mail"
)

// Sender is the interface that wraps the Send method.
//
// Send sends an email to the given addresses.
type Sender interface {
	Send(from string, to []string, msg io.WriterTo) error
}

// SendCloser is the interface that groups the Send and Close methods.
type SendCloser interface {
	Sender
	Close() error
}

// A SendFunc is a function that sends emails to the given adresses.
//
// The SendFunc type is an adapter to allow the use of ordinary functions as
// email senders. If f is a function with the appropriate signature, SendFunc(f)
// is a Sender object that calls f.
type SendFunc func(from string, to []string, msg io.WriterTo) error

// Send calls f(from, to, msg).
func (f SendFunc) Send(from string, to []string, msg io.WriterTo) error {
	return f(from, to, msg)
}

// Send sends emails using the given Sender.
func Send(s Sender, msg ...*Message) error {
	for i, m := range msg {
		if err := send(s, m); err != nil {
			return fmt.Errorf("gomail: could not send email %d: %v", i+1, err)
		}
	}

	return nil
}

func send(s Sender, m *Message) error {
	from, err := m.getFrom()
	if err != nil {
		return err
	}

	to, err := m.getRecipients()
	if err != nil {
		return err
	}

	if err := s.Send(from, to, m); err != nil {
		return err
	}

	return nil
}

func (m *Message) getFrom() (string, error) {
	from := m.header["Sender"]
	if len(from) == 0 {
		from = m.header["From"]
		if len(from) == 0 {
			return "", errors.New(`gomail: invalid message, "From" field is absent`)
		}
	}

	return parseAddress(from[0])
}

func (m *Message) getRecipients() ([]string, error) {
	n := 0
	for _, field := range []string{"To", "Cc", "Bcc"} {
		if addresses, ok := m.header[field]; ok {
			n += len(addresses)
		}
	}
	list := make([]string, 0, n)

	for _, field := range []string{"To", "Cc", "Bcc"} {
		if addresses, ok := m.header[field]; ok {
			for _, a := range addresses {
				addr, err := parseAddress(a)
				if err != nil {
					return nil, err
				}
				list = addAddress(list, addr)
			}
		}
	}

	return list, nil
}

func addAddress(list []string, addr string) []string {
	for _, a := range list {
		if addr == a {
			return list
		}
	}

	return append(list, addr)
}

func parseAddress(field string) (string, error) {
	addr, err := mail.ParseAddress(field)
	if err != nil {
		return "", fmt.Errorf("gomail: invalid address %q: %v", field, err)
	}
	return addr.Address, nil
}
<|endoftext|>


<commit_before>package main

import (
	_ "time"
	"crypto/rand"
	"encoding/binary"
	"fmt"
	"github.com/gorilla/sessions"
	"io"
	"net/http"
	"encoding/json"
	"database/sql"
	_ "github.com/go-sql-driver/mysql"
	"runtime"
	"errors"
	"html/template"
)

var templates = template.Must(template.ParseFiles("./HackMIT2/index.html"))

const MESSAGE_QUEUE_SIZE = 10

var authKey = []byte("somesecretauth")
var store sessions.Store
var pool *Pool
var clients map[int64]*Client

var db *sql.DB
// var tv syscall.Timeval

type Pool struct {
	in  chan *Client
	out chan *Room
}

type Client struct {
	id      int64
	in      chan string
	out     chan string
	retChan chan *Room
}

type Room struct {
	id      int64
	client1 *Client
	client2 *Client
}

func (p *Pool) Pair() {
	for {
		c1, c2 := <-p.in, <-p.in

		fmt.Println("match found for ", c1.id, " and ", c2.id)

		b := make([]byte, 8)
		n, err := io.ReadFull(rand.Reader, b)
		if err != nil || n != 8 {
			return
		}
		crId, _ := binary.Varint(b)

		room := &Room{crId, c1, c2}

		c1.in, c2.in = c2.out, c1.out

		c1.retChan <- room
		c2.retChan <- room
	}
}

func newPool() *Pool {
	pool := &Pool{
		in:  make(chan *Client),
		out: make(chan *Room),
	}

	go pool.Pair()

	return pool
}

func UIDFromSession(w http.ResponseWriter, r *http.Request) (int64, error) {
	session, _ := store.Get(r, "session")
	userid := session.Values["userid"]

	fmt.Println(session.Values)
	if userid == nil {
		return 0, errors.New("no cookie set")
	}
	return userid.(int64), nil
}

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

	db, _ = sql.Open("mysql", "root:pass@/suitup")
	defer db.Close()

	store = sessions.NewCookieStore(authKey)

	pool = newPool()
	clients = make(map[int64]*Client)

	http.HandleFunc("/", mainHandle)

	http.HandleFunc("/login", login)

	http.HandleFunc("/message/check", checkMessage)
	http.HandleFunc("/message/send", sendMessage)

	http.HandleFunc("/chatroom/join", joinChatRoom)
	http.HandleFunc("/chatroom/leave", leaveChatRoom)

	http.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir("/home/suitup/hackmit/HackMIT2/"))))
	http.ListenAndServe(":8080", nil)
}

type IdQuery struct {
    Id            int64      `json:"id"`

}

func mainHandle(w http.ResponseWriter, r *http.Request) {
	templates.ExecuteTemplate(w, "./HackMIT2/index.html", nil)
}

func joinChatRoom(w http.ResponseWriter, r *http.Request) {
	uid, err := UIDFromSession(w, r)
	handleError(err)

  	fmt.Println("uid: ", uid)
	retChan := make(chan *Room)
	client := &Client{
		id:      uid,
		in:      nil,
		out:     make(chan string, MESSAGE_QUEUE_SIZE),
		retChan: retChan,
	}
	clients[uid] = client
	pool.in <- client

	fmt.Println("added ", uid, " to queue")
	chatroom := <- retChan

	fmt.Fprint(w, "{\"status\":\"success\",\"crid\":", chatroom.id, "}")
}

func leaveChatRoom(w http.ResponseWriter, r *http.Request) {
	uid, _ := UIDFromSession(w, r)
	fmt.Fprint(w, uid)
}

func sendMessage(w http.ResponseWriter, r *http.Request) {
	uid, err := UIDFromSession(w, r)
	handleError(err)

	fmt.Println(uid)

	message := r.FormValue("s")

	// message := r.PostFormValue("message")

	client := clients[uid]

	if client != nil {
		client.out <- message
		fmt.Fprint(w, "{\"status\":\"success\"}-", message)
	} else {
		fmt.Fprint(w, "{\"status\":\"failure\"}-", message)
	}
}

func checkMessage(w http.ResponseWriter, r *http.Request) {
	uid, err := UIDFromSession(w, r)
	handleError(err)

	client := clients[uid]

	if client != nil {
		fmt.Println("client found")
		select {
		case message, ok := <- clients[uid].in:
			fmt.Println("message pulled from channel")
			if ok {
				fmt.Fprint(w, message)
			} else {
				fmt.Fprint(w, "")
			}
		default:
			fmt.Println("")
			fmt.Fprint(w, "")
		}

	} else {
		fmt.Println("client not found")
		fmt.Fprint(w, "")
	}
}

func login(w http.ResponseWriter, r *http.Request) {
	inputToken := r.FormValue("access_token")
	if len(inputToken) != 0 {
		uid := GetMe(inputToken)

		// row := db.QueryRow("SELECT id FROM users")
		row := db.QueryRow("SELECT id FROM users WHERE facebook_id=?", string(uid))
		iq := new(IdQuery)
		err := row.Scan(&iq.Id)

		if err != nil {
			_, err = db.Exec("insert into users (facebook_id, username, email, level, points) values (?, ?, ?, 0, 0)", uid, "", "")
			if err != nil {
				fmt.Fprint(w, "{\"status\":\"failure\"}")
				return
			} else {
				row = db.QueryRow("SELECT id FROM users WHERE facebook_id=?", string(uid))
				err = row.Scan(&iq.Id)
				if err != nil {
					fmt.Fprint(w, "{\"status\":\"failure\"}")
					return
				}
			}

		}

		fmt.Println("session-id: ", iq.Id)

		session, _ := store.Get(r, "session")
		session.Values["userid"] = iq.Id
		session.Save(r, w)

		fmt.Println(session.Values)

		fmt.Fprint(w, "{\"status\":\"success\"}")

	// 	if err == nil {
	// 		fmt.Fprint(w, "{\"status\":\"success\",\"uid\":", iq.Id, "}")
	// 	} else {
	// 		_, err = db.Exec("insert into users (facebook_id, username, email, level, points) values (?, ?, ?, 0, 0)", uid, "", "")
	// 		if err == nil {
	// 			row = db.QueryRow("SELECT id FROM users WHERE facebook_id=?", string(uid))
	// 			err = row.Scan(&iq.Id)
	// 			if err == nil {
	// 				fmt.Fprint(w, "{\"status\":\"success\"},\"uid\":", iq.Id, "}")
	// 			} else {
	// 				fmt.Fprint(w, "{\"status\":\"failure\"}")
	// 			}
	// 		} else {
	// 			fmt.Fprint(w, "{\"status\":\"failure\"}")
	// 		}
	// 	}
	// } else {
	// 	fmt.Fprint(w, "{\"status\":\"failure\"}")
	}
}

func readHttpBody(response *http.Response) string {
	bodyBuffer := make([]byte, 1000)
	var str string

	count, err := response.Body.Read(bodyBuffer)

	for ; count > 0; count, err = response.Body.Read(bodyBuffer) {

		if err != nil {

		}

		str += string(bodyBuffer[:count])
	}

	return str

}

func getUncachedResponse(uri string) (*http.Response, error) {
	request, err := http.NewRequest("GET", uri, nil)

	if err == nil {
		request.Header.Add("Cache-Control", "no-cache")

		client := new(http.Client)

		return client.Do(request)
	}

	if (err != nil) {
	}
	return nil, err

}

func GetMe(token string) string {
	response, err := getUncachedResponse("https://graph.facebook.com/me?access_token="+token)

	if err == nil {

		var jsonBlob interface{}

		responseBody := readHttpBody(response)

		if responseBody != "" {
			err = json.Unmarshal([]byte(responseBody), &jsonBlob)

			if err == nil {
				jsonObj := jsonBlob.(map[string]interface{})
				return jsonObj["id"].(string)
			}
		}
		return err.Error()
	}

	return err.Error()
}

func handleError(err error) {
	if err != nil {
		fmt.Println(err)
	}
}
<commit_msg>index.html<commit_after>package main

import (
	_ "time"
	"crypto/rand"
	"encoding/binary"
	"fmt"
	"github.com/gorilla/sessions"
	"io"
	"net/http"
	"encoding/json"
	"database/sql"
	_ "github.com/go-sql-driver/mysql"
	"runtime"
	"errors"
	"html/template"
)

var templates = template.Must(template.ParseFiles("index.html"))

const MESSAGE_QUEUE_SIZE = 10

var authKey = []byte("somesecretauth")
var store sessions.Store
var pool *Pool
var clients map[int64]*Client

var db *sql.DB
// var tv syscall.Timeval

type Pool struct {
	in  chan *Client
	out chan *Room
}

type Client struct {
	id      int64
	in      chan string
	out     chan string
	retChan chan *Room
}

type Room struct {
	id      int64
	client1 *Client
	client2 *Client
}

func (p *Pool) Pair() {
	for {
		c1, c2 := <-p.in, <-p.in

		fmt.Println("match found for ", c1.id, " and ", c2.id)

		b := make([]byte, 8)
		n, err := io.ReadFull(rand.Reader, b)
		if err != nil || n != 8 {
			return
		}
		crId, _ := binary.Varint(b)

		room := &Room{crId, c1, c2}

		c1.in, c2.in = c2.out, c1.out

		c1.retChan <- room
		c2.retChan <- room
	}
}

func newPool() *Pool {
	pool := &Pool{
		in:  make(chan *Client),
		out: make(chan *Room),
	}

	go pool.Pair()

	return pool
}

func UIDFromSession(w http.ResponseWriter, r *http.Request) (int64, error) {
	session, _ := store.Get(r, "session")
	userid := session.Values["userid"]

	fmt.Println(session.Values)
	if userid == nil {
		return 0, errors.New("no cookie set")
	}
	return userid.(int64), nil
}

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

	db, _ = sql.Open("mysql", "root:pass@/suitup")
	defer db.Close()

	store = sessions.NewCookieStore(authKey)

	pool = newPool()
	clients = make(map[int64]*Client)

	http.HandleFunc("/", mainHandle)

	http.HandleFunc("/login", login)

	http.HandleFunc("/message/check", checkMessage)
	http.HandleFunc("/message/send", sendMessage)

	http.HandleFunc("/chatroom/join", joinChatRoom)
	http.HandleFunc("/chatroom/leave", leaveChatRoom)

	http.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir("/home/suitup/hackmit/assets/"))))
	http.ListenAndServe(":8080", nil)
}

type IdQuery struct {
    Id            int64      `json:"id"`

}

func mainHandle(w http.ResponseWriter, r *http.Request) {
	templates.ExecuteTemplate(w, "index.html", nil)
}

func joinChatRoom(w http.ResponseWriter, r *http.Request) {
	uid, err := UIDFromSession(w, r)
	handleError(err)

  	fmt.Println("uid: ", uid)
	retChan := make(chan *Room)
	client := &Client{
		id:      uid,
		in:      nil,
		out:     make(chan string, MESSAGE_QUEUE_SIZE),
		retChan: retChan,
	}
	clients[uid] = client
	pool.in <- client

	fmt.Println("added ", uid, " to queue")
	chatroom := <- retChan

	fmt.Fprint(w, "{\"status\":\"success\",\"crid\":", chatroom.id, "}")
}

func leaveChatRoom(w http.ResponseWriter, r *http.Request) {
	uid, _ := UIDFromSession(w, r)
	fmt.Fprint(w, uid)
}

func sendMessage(w http.ResponseWriter, r *http.Request) {
	uid, err := UIDFromSession(w, r)
	handleError(err)

	fmt.Println(uid)

	message := r.FormValue("s")

	// message := r.PostFormValue("message")

	client := clients[uid]

	if client != nil {
		client.out <- message
		fmt.Fprint(w, "{\"status\":\"success\"}-", message)
	} else {
		fmt.Fprint(w, "{\"status\":\"failure\"}-", message)
	}
}

func checkMessage(w http.ResponseWriter, r *http.Request) {
	uid, err := UIDFromSession(w, r)
	handleError(err)

	client := clients[uid]

	if client != nil {
		fmt.Println("client found")
		select {
		case message, ok := <- clients[uid].in:
			fmt.Println("message pulled from channel")
			if ok {
				fmt.Fprint(w, message)
			} else {
				fmt.Fprint(w, "")
			}
		default:
			fmt.Println("")
			fmt.Fprint(w, "")
		}

	} else {
		fmt.Println("client not found")
		fmt.Fprint(w, "")
	}
}

func login(w http.ResponseWriter, r *http.Request) {
	inputToken := r.FormValue("access_token")
	if len(inputToken) != 0 {
		uid := GetMe(inputToken)

		// row := db.QueryRow("SELECT id FROM users")
		row := db.QueryRow("SELECT id FROM users WHERE facebook_id=?", string(uid))
		iq := new(IdQuery)
		err := row.Scan(&iq.Id)

		if err != nil {
			_, err = db.Exec("insert into users (facebook_id, username, email, level, points) values (?, ?, ?, 0, 0)", uid, "", "")
			if err != nil {
				fmt.Fprint(w, "{\"status\":\"failure\"}")
				return
			} else {
				row = db.QueryRow("SELECT id FROM users WHERE facebook_id=?", string(uid))
				err = row.Scan(&iq.Id)
				if err != nil {
					fmt.Fprint(w, "{\"status\":\"failure\"}")
					return
				}
			}

		}

		fmt.Println("session-id: ", iq.Id)

		session, _ := store.Get(r, "session")
		session.Values["userid"] = iq.Id
		session.Save(r, w)

		fmt.Println(session.Values)

		fmt.Fprint(w, "{\"status\":\"success\"}")

	// 	if err == nil {
	// 		fmt.Fprint(w, "{\"status\":\"success\",\"uid\":", iq.Id, "}")
	// 	} else {
	// 		_, err = db.Exec("insert into users (facebook_id, username, email, level, points) values (?, ?, ?, 0, 0)", uid, "", "")
	// 		if err == nil {
	// 			row = db.QueryRow("SELECT id FROM users WHERE facebook_id=?", string(uid))
	// 			err = row.Scan(&iq.Id)
	// 			if err == nil {
	// 				fmt.Fprint(w, "{\"status\":\"success\"},\"uid\":", iq.Id, "}")
	// 			} else {
	// 				fmt.Fprint(w, "{\"status\":\"failure\"}")
	// 			}
	// 		} else {
	// 			fmt.Fprint(w, "{\"status\":\"failure\"}")
	// 		}
	// 	}
	// } else {
	// 	fmt.Fprint(w, "{\"status\":\"failure\"}")
	}
}

func readHttpBody(response *http.Response) string {
	bodyBuffer := make([]byte, 1000)
	var str string

	count, err := response.Body.Read(bodyBuffer)

	for ; count > 0; count, err = response.Body.Read(bodyBuffer) {

		if err != nil {

		}

		str += string(bodyBuffer[:count])
	}

	return str

}

func getUncachedResponse(uri string) (*http.Response, error) {
	request, err := http.NewRequest("GET", uri, nil)

	if err == nil {
		request.Header.Add("Cache-Control", "no-cache")

		client := new(http.Client)

		return client.Do(request)
	}

	if (err != nil) {
	}
	return nil, err

}

func GetMe(token string) string {
	response, err := getUncachedResponse("https://graph.facebook.com/me?access_token="+token)

	if err == nil {

		var jsonBlob interface{}

		responseBody := readHttpBody(response)

		if responseBody != "" {
			err = json.Unmarshal([]byte(responseBody), &jsonBlob)

			if err == nil {
				jsonObj := jsonBlob.(map[string]interface{})
				return jsonObj["id"].(string)
			}
		}
		return err.Error()
	}

	return err.Error()
}

func handleError(err error) {
	if err != nil {
		fmt.Println(err)
	}
}
<|endoftext|>