<commit_before>package main

import (
	"errors"
	"fmt"
	"net"
	"os"
	"strings"

	"github.com/Symantec/Dominator/lib/json"
	"github.com/Symantec/Dominator/lib/log"
	libnet "github.com/Symantec/Dominator/lib/net"
	"github.com/Symantec/Dominator/lib/net/configurator"
	"github.com/Symantec/Dominator/lib/srpc"
	fm_proto "github.com/Symantec/Dominator/proto/fleetmanager"
)

type networkInterface struct {
	HardwareAddr string
	Name         string
}

func showNetworkConfigurationSubcommand(args []string,
	logger log.DebugLogger) error {
	err := showNetworkConfiguration(logger)
	if err != nil {
		return fmt.Errorf("Error showing network configuration: %s", err)
	}
	return nil
}

func getInfoForhost(hostname string) (fm_proto.GetMachineInfoResponse, error) {
	fmCR := srpc.NewClientResource("tcp",
		fmt.Sprintf("%s:%d", *fleetManagerHostname, *fleetManagerPortNum))
	defer fmCR.ScheduleClose()
	if hostname != "" && hostname != "localhost" {
		return getInfoForMachine(fmCR, hostname)
	}
	if hostname, err := os.Hostname(); err != nil {
		return fm_proto.GetMachineInfoResponse{}, err
	} else if info, err := getInfoForMachine(fmCR, hostname); err == nil {
		return info, nil
	} else if !strings.Contains(err.Error(), "unknown machine") {
		return fm_proto.GetMachineInfoResponse{}, err
	} else if hostname, err := getHostname(); err != nil {
		return fm_proto.GetMachineInfoResponse{}, err
	} else {
		return getInfoForMachine(fmCR, hostname)
	}
}

func getNetworkConfiguration(hostname string, logger log.DebugLogger) (
	*configurator.NetworkConfig, error) {
	info, err := getInfoForhost(hostname)
	if err != nil {
		return nil, err
	}
	var interfacesMap map[string]net.Interface
	if *networkInterfacesFile == "" {
		if hostname != "" && hostname != "localhost" {
			return nil, errors.New("no networkInterfacesFile specified")
		}
		_, interfacesMap, err = getUpInterfaces(logger)
		if err != nil {
			return nil, err
		}
	} else {
		var networkInterfaces []networkInterface
		err := json.ReadFromFile(*networkInterfacesFile, &networkInterfaces)
		if err != nil {
			return nil, err
		}
		interfacesMap = make(map[string]net.Interface, len(networkInterfaces))
		for _, netInterface := range networkInterfaces {
			macAddress, err := net.ParseMAC(netInterface.HardwareAddr)
			if err != nil {
				return nil, err
			}
			interfacesMap[netInterface.Name] = net.Interface{
				Name:         netInterface.Name,
				HardwareAddr: macAddress,
			}
		}
	}
	return configurator.Compute(info, interfacesMap, logger)
}

func getUpInterfaces(logger log.DebugLogger) (
	[]net.Interface, map[string]net.Interface, error) {
	interfaceList, interfaceMap, err := libnet.ListBroadcastInterfaces(
		libnet.InterfaceTypeEtherNet, logger)
	if err != nil {
		return nil, nil, err
	}
	newList := make([]net.Interface, 0, len(interfaceList))
	for _, iface := range interfaceList {
		if libnet.TestCarrier(iface.Name) {
			newList = append(newList, iface)
			logger.Debugf(1, "will generate configuration including: %s\n",
				iface.Name)
		} else {
			delete(interfaceMap, iface.Name)
		}
	}
	return newList, interfaceMap, nil
}

func showNetworkConfiguration(logger log.DebugLogger) error {
	netconf, err := getNetworkConfiguration(*hypervisorHostname, logger)
	if err != nil {
		return err
	}
	if netconf.DefaultSubnet == nil {
		return errors.New("no default subnet found")
	}
	fmt.Println("=============================================================")
	fmt.Println("Network configuration:")
	if err := netconf.PrintDebian(os.Stdout); err != nil {
		return err
	}
	fmt.Println("=============================================================")
	fmt.Println("DNS configuration:")
	return configurator.PrintResolvConf(os.Stdout, netconf.DefaultSubnet)
}
<commit_msg>hyper-control: include up/down status for -networkInterfacesFile data.<commit_after>package main

import (
	"errors"
	"fmt"
	"net"
	"os"
	"strings"

	"github.com/Symantec/Dominator/lib/json"
	"github.com/Symantec/Dominator/lib/log"
	libnet "github.com/Symantec/Dominator/lib/net"
	"github.com/Symantec/Dominator/lib/net/configurator"
	"github.com/Symantec/Dominator/lib/srpc"
	fm_proto "github.com/Symantec/Dominator/proto/fleetmanager"
)

type networkInterface struct {
	HardwareAddr string
	Name         string
	Up           bool
}

func showNetworkConfigurationSubcommand(args []string,
	logger log.DebugLogger) error {
	err := showNetworkConfiguration(logger)
	if err != nil {
		return fmt.Errorf("Error showing network configuration: %s", err)
	}
	return nil
}

func getInfoForhost(hostname string) (fm_proto.GetMachineInfoResponse, error) {
	fmCR := srpc.NewClientResource("tcp",
		fmt.Sprintf("%s:%d", *fleetManagerHostname, *fleetManagerPortNum))
	defer fmCR.ScheduleClose()
	if hostname != "" && hostname != "localhost" {
		return getInfoForMachine(fmCR, hostname)
	}
	if hostname, err := os.Hostname(); err != nil {
		return fm_proto.GetMachineInfoResponse{}, err
	} else if info, err := getInfoForMachine(fmCR, hostname); err == nil {
		return info, nil
	} else if !strings.Contains(err.Error(), "unknown machine") {
		return fm_proto.GetMachineInfoResponse{}, err
	} else if hostname, err := getHostname(); err != nil {
		return fm_proto.GetMachineInfoResponse{}, err
	} else {
		return getInfoForMachine(fmCR, hostname)
	}
}

func getNetworkConfiguration(hostname string, logger log.DebugLogger) (
	*configurator.NetworkConfig, error) {
	info, err := getInfoForhost(hostname)
	if err != nil {
		return nil, err
	}
	var interfacesMap map[string]net.Interface
	if *networkInterfacesFile == "" {
		if hostname != "" && hostname != "localhost" {
			return nil, errors.New("no networkInterfacesFile specified")
		}
		_, interfacesMap, err = getUpInterfaces(logger)
		if err != nil {
			return nil, err
		}
	} else {
		var networkInterfaces []networkInterface
		err := json.ReadFromFile(*networkInterfacesFile, &networkInterfaces)
		if err != nil {
			return nil, err
		}
		interfacesMap = make(map[string]net.Interface, len(networkInterfaces))
		for _, netInterface := range networkInterfaces {
			macAddress, err := net.ParseMAC(netInterface.HardwareAddr)
			if err != nil {
				return nil, err
			}
			netIf := net.Interface{
				Name:         netInterface.Name,
				HardwareAddr: macAddress,
			}
			if netInterface.Up {
				netIf.Flags = net.FlagUp
			}
			interfacesMap[netInterface.Name] = netIf
		}
	}
	return configurator.Compute(info, interfacesMap, logger)
}

func getUpInterfaces(logger log.DebugLogger) (
	[]net.Interface, map[string]net.Interface, error) {
	interfaceList, interfaceMap, err := libnet.ListBroadcastInterfaces(
		libnet.InterfaceTypeEtherNet, logger)
	if err != nil {
		return nil, nil, err
	}
	newList := make([]net.Interface, 0, len(interfaceList))
	for _, iface := range interfaceList {
		if libnet.TestCarrier(iface.Name) {
			newList = append(newList, iface)
			logger.Debugf(1, "will generate configuration including: %s\n",
				iface.Name)
		} else {
			delete(interfaceMap, iface.Name)
		}
	}
	return newList, interfaceMap, nil
}

func showNetworkConfiguration(logger log.DebugLogger) error {
	netconf, err := getNetworkConfiguration(*hypervisorHostname, logger)
	if err != nil {
		return err
	}
	if netconf.DefaultSubnet == nil {
		return errors.New("no default subnet found")
	}
	fmt.Println("=============================================================")
	fmt.Println("Network configuration:")
	if err := netconf.PrintDebian(os.Stdout); err != nil {
		return err
	}
	fmt.Println("=============================================================")
	fmt.Println("DNS configuration:")
	return configurator.PrintResolvConf(os.Stdout, netconf.DefaultSubnet)
}
<|endoftext|>


<commit_before>package osm

import (
	"fmt"
	"reflect"
	"strconv"
	"strings"
)

// DeleteBySQL 执行删除sql
//
//代码
//   count, err := o.DeleteBySQL(`DELETE FROM res_user WHERE id in #{Ids};`, []int64{1, 2})
//   if err != nil {
// 	   log.Println(err)
//   }
//   log.Println("count:", count)
//结果
//
//   count: 2
//删除id为1和2的用户数据
func (o *osmBase) DeleteBySQL(sql string, params ...interface{}) (int64, error) {
	sql, sqlParams, err := o.readSQLParamsBySQL(sql, params...)
	if err != nil {
		return 0, err
	}
	stmt, err := o.db.Prepare(sql)
	if err != nil {
		return 0, err
	}
	result, err := stmt.Exec(sqlParams...)
	if err != nil {
		return 0, err
	}
	defer stmt.Close()
	return result.RowsAffected()
}

// UpdateBySQL 执行更新sql
//
//代码
//   count, err := o.UpdateBySQL(`UPDATE res_user SET email=#{Email} WHERE id=#{ID};`, "test2@foxmail.com", 3)
//   if err != nil {
// 	  log.Println(err)
//   }
//   log.Println("count:", count)
//结果
//   count: 1
//
//将id为1的用户email更新为"test2@foxmail.com"
func (o *osmBase) UpdateBySQL(sql string, params ...interface{}) (int64, error) {
	sql, sqlParams, err := o.readSQLParamsBySQL(sql, params...)
	if err != nil {
		return 0, err
	}
	stmt, err := o.db.Prepare(sql)
	if err != nil {
		return 0, err
	}
	result, err := stmt.Exec(sqlParams...)
	if err != nil {
		return 0, err
	}
	defer stmt.Close()
	return result.RowsAffected()
}

// UpdateMultiBySQL 批量执行更新sql
//
//代码
//  user := User{Id: 3, Id2: 4, Email: "test@foxmail.com"}
//  err := o.UpdateMultiBySQL(`
//       UPDATE user SET email='{{.Email}}' where id = {{.Id}};
//       UPDATE user SET email='{{.Email}}' where id = {{.Id2}};`, user)
//将id为3和4的用户email更新为"test@foxmail.com"
func (o *osmBase) UpdateMultiBySQL(sql string, params ...interface{}) error {
	sql, sqlParams, err := o.readSQLParamsBySQL(sql, params...)
	if err != nil {
		return err
	}
	_, err = o.db.Exec(sql, sqlParams...)
	return err
}

// InsertBySQL 执行添加sql
//
//代码
//   insertResUser := ResUser{
// 	  Email: "test@foxmail.com",
//   }
//   insertID, count, err := o.InsertBySQL("INSERT INTO res_user (email) VALUES(#{Email});", insertResUser)
//   if err != nil {
// 	  log.Println(err)
//   }
//   log.Println("insertID:", insertID, "count:", count)
//结果
//   insertID: 3 count: 1
//
//添加一个用户数据，email为"test@foxmail.com"
func (o *osmBase) InsertBySQL(sql string, params ...interface{}) (int64, int64, error) {
	sql, sqlParams, err := o.readSQLParamsBySQL(sql, params...)
	if err != nil {
		return 0, 0, err
	}
	stmt, err := o.db.Prepare(sql)
	if err != nil {
		return 0, 0, err
	}

	result, err := stmt.Exec(sqlParams...)
	if err != nil {
		return 0, 0, err
	}
	defer stmt.Close()

	var insertID int64
	if o.dbType == dbTypeMysql {
		insertID, err = result.LastInsertId()
		if err != nil {
			logger.Println(err)
		}
	}

	count, err := result.RowsAffected()
	return insertID, count, err
}

// SelectValue 执行查询sql
//
//查出的结果为单行,并存入不定长的变量上(...)，可以是指针，如var r1,r2 string、var r1,r2 *string
//
//代码
//   var email string
//   _, err = o.SelectValue(`SELECT email FROM res_user WHERE id=#{Id};`, 1)(&email)
//   if err != nil {
// 	   log.Println(err)
//   }
//   log.Printf("email: %s \n", email)
//结果
//   email: test@foxmail.com
func (o *osmBase) SelectValue(sql string, params ...interface{}) func(containers ...interface{}) (int64, error) {
	return o.selectBySQL(sql, resultTypeValue, params)
}

// SelectValues 执行查询sql
//
// 查出的结果为多行,并存入不定长的变量上(...，每个都为array)，元素可以是指针，如var r1,r2 []string、var r1,r2 []*string都允许
//
//代码
//   var emails []string
//   _, err = o.SelectValues(`SELECT email FROM res_user WHERE id in #{Ids};`, []int64{1, 2})(&emails)
//   if err != nil {
// 	   log.Println(err)
//   }
//   log.Printf("emails: %v \n", emails)
//结果
//   emails: [test@foxmail.com test@foxmail.com]
func (o *osmBase) SelectValues(sql string, params ...interface{}) func(containers ...interface{}) (int64, error) {
	return o.selectBySQL(sql, resultTypeValues, params)
}

// SelectStruct 执行查询sql
//
// 查出的结果为单行,并存入struct，可以是指针，如var r User、var r *User
//
//代码
//   var users []ResUser
//   _, err = o.SelectStruct(`SELECT id,email,create_time FROM res_user WHERE id=#{Id};`, 1)(&users)
//   if err != nil {
// 	   log.Println(err)
//   }
//   log.Printf("user: %#v \n", users)
//结果
//   user: ResUser{ID:1, Email:"test@foxmail.com", Mobile:"", Nickname:""}
func (o *osmBase) SelectStruct(sql string, params ...interface{}) func(containers ...interface{}) (int64, error) {
	return o.selectBySQL(sql, resultTypeStruct, params)
}

// SelectStructs 执行查询sql
//
// 查出的结果为多行,并存入struct array，元素可以是指针，如var r []User、var r []*User
//
//代码
//   var users []ResUser
//   _, err = o.SelectStructs(`SELECT id,email,create_time FROM res_user WHERE id=#{Id};`, 1)(&users)
//   if err != nil {
// 	   log.Println(err)
//   }
//   log.Printf("users: %#v \n", users)
//结果
//   users: []ResUser{ResUser{ID:1, Email:"test@foxmail.com", Mobile:"", Nickname:""}}
func (o *osmBase) SelectStructs(sql string, params ...interface{}) func(containers ...interface{}) (int64, error) {
	return o.selectBySQL(sql, resultTypeStructs, params)
}

// SelectKVS 执行查询sql
//
// 查出的结果为多行,每行有两个字段,前者为key,后者为value,存入map (双列)，Key、Value可以是指针，如var r map[string]time.Time、var r map[*string]time.Time、var r map[string]*time.Time
//
//代码
//   var idEmailMap = map[int64]string{}
//   _, err = o.SelectKVS(`SELECT id,email FROM res_user WHERE id in #{Ids};`, []int64{1, 2})(&idEmailMap)
//   if err != nil {
// 	  log.Println(err)
//   }
//   log.Printf("idEmailMap: %v \n", idEmailMap)
//结果
//   idEmailMap: map[1:test@foxmail.com 2:test@foxmail.com]
func (o *osmBase) SelectKVS(sql string, params ...interface{}) func(containers ...interface{}) (int64, error) {
	return o.selectBySQL(sql, resultTypeKvs, params)
}

func (o *osmBase) selectBySQL(sql, resultType string, params []interface{}) func(containers ...interface{}) (int64, error) {
	sql, sqlParams, err := o.readSQLParamsBySQL(sql, params...)

	if err != nil {
		return func(containers ...interface{}) (int64, error) {
			return 0, err
		}
	}
	callback := func(containers ...interface{}) (int64, error) {
		var err error
		switch resultType {
		case resultTypeStructs:
			if len(containers) == 1 {
				return resultStructs(o, sql, sql, sqlParams, containers[0])
			}
			err = fmt.Errorf("sql '%s' error : resultTypeStructs ,len(containers) != 1", sql)
		case resultTypeStruct:
			if len(containers) == 1 {
				return resultStruct(o, sql, sql, sqlParams, containers[0])
			}
			err = fmt.Errorf("sql '%s' error : resultTypeStruct ,len(containers) != 1", sql)
		case resultTypeValue:
			if len(containers) > 0 {
				return resultValue(o, sql, sql, sqlParams, containers)
			}
			err = fmt.Errorf("sql '%s' error : resultTypeValue ,len(containers) < 1", sql)
		case resultTypeValues:
			if len(containers) > 0 {
				return resultValues(o, sql, sql, sqlParams, containers)
			}
			err = fmt.Errorf("sql '%s' error : resultTypeValues ,len(containers) < 1", sql)
		case resultTypeKvs:
			if len(containers) == 1 {
				return resultKvs(o, sql, sql, sqlParams, containers[0])
			}
			err = fmt.Errorf("sql '%s' error : resultTypeKvs ,len(containers) != 1", sql)
		}

		if err == nil {
			err = fmt.Errorf("sql '%s' error : sql resultTypeType no in ['value','struct','values','structs','kvs']", sql)
		}
		return 0, err
	}
	return callback
}

func (o *osmBase) readSQLParamsBySQL(sqlOrg string, params ...interface{}) (sql string, sqlParams []interface{}, err error) {
	var param interface{}
	paramsSize := len(params)
	if paramsSize > 0 {
		if paramsSize == 1 {
			param = params[0]
		} else {
			param = params
		}

		//sql start
		sqls := []*sqlFragment{}
		paramNames := []*sqlFragment{}
		defer func() {
			if ShowSQL {
				go logger.Printf(`sql:"%s", params:"%+v", dbSQL:"%s", dbParams:"%+v"`, sqlOrg, param, sql, sqlParams)
			}
		}()
		sqlTemp := sqlOrg
		errorIndex := 0
		for strings.Contains(sqlTemp, "#{") {
			si := strings.Index(sqlTemp, "#{")
			lastSQLText := sqlTemp[0:si]
			sqls = append(sqls, &sqlFragment{
				content: lastSQLText,
			})
			sqlTemp = sqlTemp[si+2:]
			errorIndex += si + 2

			ei := strings.Index(sqlTemp, "}")
			if ei != -1 {
				pni := &sqlFragment{
					content: strings.TrimSpace(sqlTemp[0:ei]),
					isParam: true,
					isIn:    sqlIsIn(lastSQLText),
				}
				sqls = append(sqls, pni)
				paramNames = append(paramNames, pni)
				sqlTemp = sqlTemp[ei+1:]
				errorIndex += ei + 1
			} else {
				logger.Printf("sql read error \"%v\"", markSQLError(sqlOrg, errorIndex))
				return
			}
		}
		sqls = append(sqls, &sqlFragment{
			content: sqlTemp,
		})
		//sql end

		v := reflect.ValueOf(param)

		kind := v.Kind()
		switch {
		case kind == reflect.Array || kind == reflect.Slice:
			if len(paramNames) == 1 && paramNames[0].isIn {
				setDataToParamName(paramNames[0], v)
			} else {
				for i := 0; i < v.Len() && i < len(paramNames); i++ {
					vv := v.Index(i)
					if vv.IsValid() {
						setDataToParamName(paramNames[i], v.Index(i))
					}
				}
			}
		case kind == reflect.Map:
			for _, paramName := range paramNames {
				vv := v.MapIndex(reflect.ValueOf(paramName.content))
				if vv.IsValid() {
					setDataToParamName(paramName, vv)
				} else {
					err = fmt.Errorf("sql '%s' error : Key '%s' no exist", sqlOrg, paramName.content)
					return
				}
			}
		case kind == reflect.Struct:
			for _, paramName := range paramNames {
				firstChar := paramName.content[0]
				if firstChar < 'A' || firstChar > 'Z' {
					err = fmt.Errorf("sql '%s' error : Field '%s' unexported", sqlOrg, paramName.content)
					return
				}
				vv := v.FieldByName(paramName.content)
				if vv.IsValid() {
					setDataToParamName(paramName, vv)
				} else {
					err = fmt.Errorf("sql '%s' error : Field '%s' no exist", sqlOrg, paramName.content)
					return
				}
			}
		case kind == reflect.Bool ||
			kind == reflect.Int ||
			kind == reflect.Int8 ||
			kind == reflect.Int16 ||
			kind == reflect.Int32 ||
			kind == reflect.Int64 ||
			kind == reflect.Uint ||
			kind == reflect.Uint8 ||
			kind == reflect.Uint16 ||
			kind == reflect.Uint32 ||
			kind == reflect.Uint64 ||
			kind == reflect.Uintptr ||
			kind == reflect.Float32 ||
			kind == reflect.Float64 ||
			kind == reflect.Complex64 ||
			kind == reflect.Complex128 ||
			kind == reflect.String:
			for _, paramName := range paramNames {
				setDataToParamName(paramName, v)
			}
		default:
		}

		var sqlTexts []string
		signIndex := 1
		for _, sql := range sqls {
			if sql.isParam {
				if sql.isIn {
					sqlTexts = append(sqlTexts, "(")
					for index, pv := range sql.paramValues {
						if index > 0 {
							sqlTexts = append(sqlTexts, ",")
						}
						if o.dbType == dbTypeMysql {
							sqlTexts = append(sqlTexts, "?")
						} else {
							sqlTexts = append(sqlTexts, "$"+strconv.Itoa(signIndex))
							signIndex++
						}
						sqlParams = append(sqlParams, pv)
					}
					sqlTexts = append(sqlTexts, ")")
				} else {
					if o.dbType == dbTypeMysql {
						sqlTexts = append(sqlTexts, "?")
					} else {
						sqlTexts = append(sqlTexts, "$"+strconv.Itoa(signIndex))
						signIndex++
					}
					sqlParams = append(sqlParams, sql.paramValue)
				}
			} else {
				sqlTexts = append(sqlTexts, sql.content)
			}
		}

		sql = strings.Join(sqlTexts, "")
	} else {
		sql = sqlOrg
		if ShowSQL {
			go logger.Printf(`sql:"%s"`, sqlOrg)
		}
	}
	return
}
<commit_msg>UpdateMultiBySQL<commit_after>package osm

import (
	"fmt"
	"reflect"
	"strconv"
	"strings"
)

// DeleteBySQL 执行删除sql
//
//代码
//   count, err := o.DeleteBySQL(`DELETE FROM res_user WHERE id in #{Ids};`, []int64{1, 2})
//   if err != nil {
// 	   log.Println(err)
//   }
//   log.Println("count:", count)
//结果
//
//   count: 2
//删除id为1和2的用户数据
func (o *osmBase) DeleteBySQL(sql string, params ...interface{}) (int64, error) {
	sql, sqlParams, err := o.readSQLParamsBySQL(sql, params...)
	if err != nil {
		return 0, err
	}
	stmt, err := o.db.Prepare(sql)
	if err != nil {
		return 0, err
	}
	result, err := stmt.Exec(sqlParams...)
	if err != nil {
		return 0, err
	}
	defer stmt.Close()
	return result.RowsAffected()
}

// UpdateBySQL 执行更新sql
//
//代码
//   count, err := o.UpdateBySQL(`UPDATE res_user SET email=#{Email} WHERE id=#{ID};`, "test2@foxmail.com", 3)
//   if err != nil {
// 	  log.Println(err)
//   }
//   log.Println("count:", count)
//结果
//   count: 1
//
//将id为1的用户email更新为"test2@foxmail.com"
func (o *osmBase) UpdateBySQL(sql string, params ...interface{}) (int64, error) {
	sql, sqlParams, err := o.readSQLParamsBySQL(sql, params...)
	if err != nil {
		return 0, err
	}
	stmt, err := o.db.Prepare(sql)
	if err != nil {
		return 0, err
	}
	result, err := stmt.Exec(sqlParams...)
	if err != nil {
		return 0, err
	}
	defer stmt.Close()
	return result.RowsAffected()
}

// InsertBySQL 执行添加sql
//
//代码
//   insertResUser := ResUser{
// 	  Email: "test@foxmail.com",
//   }
//   insertID, count, err := o.InsertBySQL("INSERT INTO res_user (email) VALUES(#{Email});", insertResUser)
//   if err != nil {
// 	  log.Println(err)
//   }
//   log.Println("insertID:", insertID, "count:", count)
//结果
//   insertID: 3 count: 1
//
//添加一个用户数据，email为"test@foxmail.com"
func (o *osmBase) InsertBySQL(sql string, params ...interface{}) (int64, int64, error) {
	sql, sqlParams, err := o.readSQLParamsBySQL(sql, params...)
	if err != nil {
		return 0, 0, err
	}
	stmt, err := o.db.Prepare(sql)
	if err != nil {
		return 0, 0, err
	}

	result, err := stmt.Exec(sqlParams...)
	if err != nil {
		return 0, 0, err
	}
	defer stmt.Close()

	var insertID int64
	if o.dbType == dbTypeMysql {
		insertID, err = result.LastInsertId()
		if err != nil {
			logger.Println(err)
		}
	}

	count, err := result.RowsAffected()
	return insertID, count, err
}

// SelectValue 执行查询sql
//
//查出的结果为单行,并存入不定长的变量上(...)，可以是指针，如var r1,r2 string、var r1,r2 *string
//
//代码
//   var email string
//   _, err = o.SelectValue(`SELECT email FROM res_user WHERE id=#{Id};`, 1)(&email)
//   if err != nil {
// 	   log.Println(err)
//   }
//   log.Printf("email: %s \n", email)
//结果
//   email: test@foxmail.com
func (o *osmBase) SelectValue(sql string, params ...interface{}) func(containers ...interface{}) (int64, error) {
	return o.selectBySQL(sql, resultTypeValue, params)
}

// SelectValues 执行查询sql
//
// 查出的结果为多行,并存入不定长的变量上(...，每个都为array)，元素可以是指针，如var r1,r2 []string、var r1,r2 []*string都允许
//
//代码
//   var emails []string
//   _, err = o.SelectValues(`SELECT email FROM res_user WHERE id in #{Ids};`, []int64{1, 2})(&emails)
//   if err != nil {
// 	   log.Println(err)
//   }
//   log.Printf("emails: %v \n", emails)
//结果
//   emails: [test@foxmail.com test@foxmail.com]
func (o *osmBase) SelectValues(sql string, params ...interface{}) func(containers ...interface{}) (int64, error) {
	return o.selectBySQL(sql, resultTypeValues, params)
}

// SelectStruct 执行查询sql
//
// 查出的结果为单行,并存入struct，可以是指针，如var r User、var r *User
//
//代码
//   var users []ResUser
//   _, err = o.SelectStruct(`SELECT id,email,create_time FROM res_user WHERE id=#{Id};`, 1)(&users)
//   if err != nil {
// 	   log.Println(err)
//   }
//   log.Printf("user: %#v \n", users)
//结果
//   user: ResUser{ID:1, Email:"test@foxmail.com", Mobile:"", Nickname:""}
func (o *osmBase) SelectStruct(sql string, params ...interface{}) func(containers ...interface{}) (int64, error) {
	return o.selectBySQL(sql, resultTypeStruct, params)
}

// SelectStructs 执行查询sql
//
// 查出的结果为多行,并存入struct array，元素可以是指针，如var r []User、var r []*User
//
//代码
//   var users []ResUser
//   _, err = o.SelectStructs(`SELECT id,email,create_time FROM res_user WHERE id=#{Id};`, 1)(&users)
//   if err != nil {
// 	   log.Println(err)
//   }
//   log.Printf("users: %#v \n", users)
//结果
//   users: []ResUser{ResUser{ID:1, Email:"test@foxmail.com", Mobile:"", Nickname:""}}
func (o *osmBase) SelectStructs(sql string, params ...interface{}) func(containers ...interface{}) (int64, error) {
	return o.selectBySQL(sql, resultTypeStructs, params)
}

// SelectKVS 执行查询sql
//
// 查出的结果为多行,每行有两个字段,前者为key,后者为value,存入map (双列)，Key、Value可以是指针，如var r map[string]time.Time、var r map[*string]time.Time、var r map[string]*time.Time
//
//代码
//   var idEmailMap = map[int64]string{}
//   _, err = o.SelectKVS(`SELECT id,email FROM res_user WHERE id in #{Ids};`, []int64{1, 2})(&idEmailMap)
//   if err != nil {
// 	  log.Println(err)
//   }
//   log.Printf("idEmailMap: %v \n", idEmailMap)
//结果
//   idEmailMap: map[1:test@foxmail.com 2:test@foxmail.com]
func (o *osmBase) SelectKVS(sql string, params ...interface{}) func(containers ...interface{}) (int64, error) {
	return o.selectBySQL(sql, resultTypeKvs, params)
}

func (o *osmBase) selectBySQL(sql, resultType string, params []interface{}) func(containers ...interface{}) (int64, error) {
	sql, sqlParams, err := o.readSQLParamsBySQL(sql, params...)

	if err != nil {
		return func(containers ...interface{}) (int64, error) {
			return 0, err
		}
	}
	callback := func(containers ...interface{}) (int64, error) {
		var err error
		switch resultType {
		case resultTypeStructs:
			if len(containers) == 1 {
				return resultStructs(o, sql, sql, sqlParams, containers[0])
			}
			err = fmt.Errorf("sql '%s' error : resultTypeStructs ,len(containers) != 1", sql)
		case resultTypeStruct:
			if len(containers) == 1 {
				return resultStruct(o, sql, sql, sqlParams, containers[0])
			}
			err = fmt.Errorf("sql '%s' error : resultTypeStruct ,len(containers) != 1", sql)
		case resultTypeValue:
			if len(containers) > 0 {
				return resultValue(o, sql, sql, sqlParams, containers)
			}
			err = fmt.Errorf("sql '%s' error : resultTypeValue ,len(containers) < 1", sql)
		case resultTypeValues:
			if len(containers) > 0 {
				return resultValues(o, sql, sql, sqlParams, containers)
			}
			err = fmt.Errorf("sql '%s' error : resultTypeValues ,len(containers) < 1", sql)
		case resultTypeKvs:
			if len(containers) == 1 {
				return resultKvs(o, sql, sql, sqlParams, containers[0])
			}
			err = fmt.Errorf("sql '%s' error : resultTypeKvs ,len(containers) != 1", sql)
		}

		if err == nil {
			err = fmt.Errorf("sql '%s' error : sql resultTypeType no in ['value','struct','values','structs','kvs']", sql)
		}
		return 0, err
	}
	return callback
}

func (o *osmBase) readSQLParamsBySQL(sqlOrg string, params ...interface{}) (sql string, sqlParams []interface{}, err error) {
	var param interface{}
	paramsSize := len(params)
	if paramsSize > 0 {
		if paramsSize == 1 {
			param = params[0]
		} else {
			param = params
		}

		//sql start
		sqls := []*sqlFragment{}
		paramNames := []*sqlFragment{}
		defer func() {
			if ShowSQL {
				go logger.Printf(`sql:"%s", params:"%+v", dbSQL:"%s", dbParams:"%+v"`, sqlOrg, param, sql, sqlParams)
			}
		}()
		sqlTemp := sqlOrg
		errorIndex := 0
		for strings.Contains(sqlTemp, "#{") {
			si := strings.Index(sqlTemp, "#{")
			lastSQLText := sqlTemp[0:si]
			sqls = append(sqls, &sqlFragment{
				content: lastSQLText,
			})
			sqlTemp = sqlTemp[si+2:]
			errorIndex += si + 2

			ei := strings.Index(sqlTemp, "}")
			if ei != -1 {
				pni := &sqlFragment{
					content: strings.TrimSpace(sqlTemp[0:ei]),
					isParam: true,
					isIn:    sqlIsIn(lastSQLText),
				}
				sqls = append(sqls, pni)
				paramNames = append(paramNames, pni)
				sqlTemp = sqlTemp[ei+1:]
				errorIndex += ei + 1
			} else {
				logger.Printf("sql read error \"%v\"", markSQLError(sqlOrg, errorIndex))
				return
			}
		}
		sqls = append(sqls, &sqlFragment{
			content: sqlTemp,
		})
		//sql end

		v := reflect.ValueOf(param)

		kind := v.Kind()
		switch {
		case kind == reflect.Array || kind == reflect.Slice:
			if len(paramNames) == 1 && paramNames[0].isIn {
				setDataToParamName(paramNames[0], v)
			} else {
				for i := 0; i < v.Len() && i < len(paramNames); i++ {
					vv := v.Index(i)
					if vv.IsValid() {
						setDataToParamName(paramNames[i], v.Index(i))
					}
				}
			}
		case kind == reflect.Map:
			for _, paramName := range paramNames {
				vv := v.MapIndex(reflect.ValueOf(paramName.content))
				if vv.IsValid() {
					setDataToParamName(paramName, vv)
				} else {
					err = fmt.Errorf("sql '%s' error : Key '%s' no exist", sqlOrg, paramName.content)
					return
				}
			}
		case kind == reflect.Struct:
			for _, paramName := range paramNames {
				firstChar := paramName.content[0]
				if firstChar < 'A' || firstChar > 'Z' {
					err = fmt.Errorf("sql '%s' error : Field '%s' unexported", sqlOrg, paramName.content)
					return
				}
				vv := v.FieldByName(paramName.content)
				if vv.IsValid() {
					setDataToParamName(paramName, vv)
				} else {
					err = fmt.Errorf("sql '%s' error : Field '%s' no exist", sqlOrg, paramName.content)
					return
				}
			}
		case kind == reflect.Bool ||
			kind == reflect.Int ||
			kind == reflect.Int8 ||
			kind == reflect.Int16 ||
			kind == reflect.Int32 ||
			kind == reflect.Int64 ||
			kind == reflect.Uint ||
			kind == reflect.Uint8 ||
			kind == reflect.Uint16 ||
			kind == reflect.Uint32 ||
			kind == reflect.Uint64 ||
			kind == reflect.Uintptr ||
			kind == reflect.Float32 ||
			kind == reflect.Float64 ||
			kind == reflect.Complex64 ||
			kind == reflect.Complex128 ||
			kind == reflect.String:
			for _, paramName := range paramNames {
				setDataToParamName(paramName, v)
			}
		default:
		}

		var sqlTexts []string
		signIndex := 1
		for _, sql := range sqls {
			if sql.isParam {
				if sql.isIn {
					sqlTexts = append(sqlTexts, "(")
					for index, pv := range sql.paramValues {
						if index > 0 {
							sqlTexts = append(sqlTexts, ",")
						}
						if o.dbType == dbTypeMysql {
							sqlTexts = append(sqlTexts, "?")
						} else {
							sqlTexts = append(sqlTexts, "$"+strconv.Itoa(signIndex))
							signIndex++
						}
						sqlParams = append(sqlParams, pv)
					}
					sqlTexts = append(sqlTexts, ")")
				} else {
					if o.dbType == dbTypeMysql {
						sqlTexts = append(sqlTexts, "?")
					} else {
						sqlTexts = append(sqlTexts, "$"+strconv.Itoa(signIndex))
						signIndex++
					}
					sqlParams = append(sqlParams, sql.paramValue)
				}
			} else {
				sqlTexts = append(sqlTexts, sql.content)
			}
		}

		sql = strings.Join(sqlTexts, "")
	} else {
		sql = sqlOrg
		if ShowSQL {
			go logger.Printf(`sql:"%s"`, sqlOrg)
		}
	}
	return
}
<|endoftext|>


<commit_before>package baduk

import "strconv"

//Creates a string representing an SVG
//view of the board, suitable for use
//inline in web templates. Wrap in an external
//div with particular width/height in CSS
//to control size. Yay for resolution
//independence!
func (b *Board) PrettySVG() (svg string) {
	svg += "<svg id=\"board\" width=\"100%%\" height=\"100%%\" viewBox=\"0 0 1000 1000\">\n"
	svg += `<symbol id="blackstone" viewBox="0 0 120 120">
			<circle cx=60 cy=60 r=45 fill="#000000" />
			<circle cx=80 cy=80 r=10 fill="#ffffff" />
			<circle cx=40 cy=40 r=5 fill="#999999" />
		</symbol>
		<symbol id="whitestone" viewBox="0 0 120 120">
			<circle cx=60 cy=60 r=45 fill="#ffffff" stroke="#000000" stroke-width="3"/>
			<circle cx=80 cy=40 r=10 fill="#aaaaaa" />
			<circle cx=40 cy=80 r=5 fill="#dddddd" />
		</symbol>
		<g id="grid" viewBox="0 0 1000 1000">
		`
	base := b.Size * 2
	scale := 1000 / b.Size
	begin := 1000 / base
	end := (base - 1) * begin
	//Make grid
	for i := 1; i < b.Size*2; i += 2 {
		svg += "<line x1=" + strconv.Itoa(begin) + " y1=" + strconv.Itoa(i*begin) +
			" x2=" + strconv.Itoa(end) + " y2=" + strconv.Itoa(i*begin) +
			" stroke=\"black\" stroke-width=\"10\" />\n"
		svg += "<line x1=" + strconv.Itoa(i*begin) + " y1=" + strconv.Itoa(begin) +
			" x2=" + strconv.Itoa(i*begin) + " y2=" + strconv.Itoa(end) +
			" stroke=\"black\" stroke-width=\"10\" />\n"
	}
	//Place pieces
	for y := 0; y < b.Size; y++ {
		for x := 0; x < b.Size; x++ {
			if b.Grid[y][x].Black {
				svg += "<use x=" + strconv.Itoa(x*scale) + " y=" + strconv.Itoa(y*scale) +
					" width=" + strconv.Itoa(scale) + " height=" + strconv.Itoa(scale) +
					" xlink:href=\"#blackstone\" />\n"
			} else if b.Grid[y][x].White {
				svg += "<use x=" + strconv.Itoa(x*scale) + " y=" + strconv.Itoa(y*scale) +
					" width=" + strconv.Itoa(scale) + " height=" + strconv.Itoa(scale) +
					" xlink:href=\"#whitestone\" />\n"
			} else {
				continue
			}
		}
	}
	svg += "</g>\n</svg>\n"
	return
}
<commit_msg>add empty rectangles for touch events in svgs<commit_after>package baduk

import "strconv"

//Creates a string representing an SVG
//view of the board, suitable for use
//inline in web templates. Wrap in an external
//div with particular width/height in CSS
//to control size. Yay for resolution
//independence!
func (b *Board) PrettySVG() (svg string) {
	svg += "<svg id=\"board\" width=\"100%%\" height=\"100%%\" viewBox=\"0 0 1000 1000\">\n"
	svg += `<symbol id="blackstone" viewBox="0 0 120 120">
			<circle cx=60 cy=60 r=45 fill="#000000" />
			<circle cx=80 cy=80 r=10 fill="#ffffff" />
			<circle cx=40 cy=40 r=5 fill="#999999" />
		</symbol>
		<symbol id="whitestone" viewBox="0 0 120 120">
			<circle cx=60 cy=60 r=45 fill="#ffffff" stroke="#000000" stroke-width="3"/>
			<circle cx=80 cy=40 r=10 fill="#aaaaaa" />
			<circle cx=40 cy=80 r=5 fill="#dddddd" />
		</symbol>
		<g id="grid" viewBox="0 0 1000 1000">
		`
	base := b.Size * 2
	scale := 1000 / b.Size
	begin := 1000 / base
	end := (base - 1) * begin
	//Make grid
	for i := 1; i < b.Size*2; i += 2 {
		svg += "<line x1=" + strconv.Itoa(begin) + " y1=" + strconv.Itoa(i*begin) +
			" x2=" + strconv.Itoa(end) + " y2=" + strconv.Itoa(i*begin) +
			" stroke=\"black\" stroke-width=\"10\" />\n"
		svg += "<line x1=" + strconv.Itoa(i*begin) + " y1=" + strconv.Itoa(begin) +
			" x2=" + strconv.Itoa(i*begin) + " y2=" + strconv.Itoa(end) +
			" stroke=\"black\" stroke-width=\"10\" />\n"
	}
	//Place pieces
	for y := 0; y < b.Size; y++ {
		for x := 0; x < b.Size; x++ {
			if b.Grid[y][x].Black {
				svg += "<use x=" + strconv.Itoa(x*scale) + " y=" + strconv.Itoa(y*scale) +
					" width=" + strconv.Itoa(scale) + " height=" + strconv.Itoa(scale) +
					" xlink:href=\"#blackstone\" />\n"
			} else if b.Grid[y][x].White {
				svg += "<use x=" + strconv.Itoa(x*scale) + " y=" + strconv.Itoa(y*scale) +
					" width=" + strconv.Itoa(scale) + " height=" + strconv.Itoa(scale) +
					" xlink:href=\"#whitestone\" />\n"
			} else {
				svg += "<rect id=\"empty" + strconv.Itoa(x) + "-" + strconv.Itoa(y) + "\"" +
					" x=" + strconv.Itoa(x*scale) + " y=" + strconv.Itoa(y*scale) +
					" width=" + strconv.Itoa(scale) + " height=" + strconv.Itoa(scale) +
					" opacity=\"0.0\"/>\n"
			}
		}
	}
	svg += "</g>\n</svg>\n"
	return
}
<|endoftext|>


<commit_before>// Copyright 2014 go-dockerclient authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package docker

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"strings"

	"github.com/docker/docker/pkg/archive"
	"github.com/docker/docker/pkg/fileutils"
)

func createTarStream(srcPath, dockerfilePath string) (io.ReadCloser, error) {
	excludes, err := parseDockerignore(srcPath)
	if err != nil {
		return nil, err
	}

	includes := []string{"."}

	// If .dockerignore mentions .dockerignore or the Dockerfile
	// then make sure we send both files over to the daemon
	// because Dockerfile is, obviously, needed no matter what, and
	// .dockerignore is needed to know if either one needs to be
	// removed.  The deamon will remove them for us, if needed, after it
	// parses the Dockerfile.
	//
	// https://github.com/docker/docker/issues/8330
	//
	forceIncludeFiles := []string{".dockerignore", dockerfilePath}

	for _, includeFile := range forceIncludeFiles {
		if includeFile == "" {
			continue
		}
		keepThem, err := fileutils.Matches(includeFile, excludes)
		if err != nil {
			return nil, fmt.Errorf("cannot match .dockerfile: '%s', error: %s", includeFile, err)
		}
		if keepThem {
			includes = append(includes, includeFile)
		}
	}

	if err := validateContextDirectory(srcPath, excludes); err != nil {
		return nil, err
	}
	tarOpts := &archive.TarOptions{
		ExcludePatterns: excludes,
		IncludeFiles:    includes,
		Compression:     archive.Uncompressed,
		NoLchown:        true,
	}
	return archive.TarWithOptions(srcPath, tarOpts)
}

// validateContextDirectory checks if all the contents of the directory
// can be read and returns an error if some files can't be read.
// Symlinks which point to non-existing files don't trigger an error
func validateContextDirectory(srcPath string, excludes []string) error {
	return filepath.Walk(filepath.Join(srcPath, "."), func(filePath string, f os.FileInfo, err error) error {
		// skip this directory/file if it's not in the path, it won't get added to the context
		if relFilePath, relErr := filepath.Rel(srcPath, filePath); relErr != nil {
			return relErr
		} else if skip, matchErr := fileutils.Matches(relFilePath, excludes); matchErr != nil {
			return matchErr
		} else if skip {
			if f.IsDir() {
				return filepath.SkipDir
			}
			return nil
		}

		if err != nil {
			if os.IsPermission(err) {
				return fmt.Errorf("can't stat '%s'", filePath)
			}
			if os.IsNotExist(err) {
				return nil
			}
			return err
		}

		// skip checking if symlinks point to non-existing files, such symlinks can be useful
		// also skip named pipes, because they hanging on open
		if f.Mode()&(os.ModeSymlink|os.ModeNamedPipe) != 0 {
			return nil
		}

		if !f.IsDir() {
			currentFile, err := os.Open(filePath)
			if err != nil && os.IsPermission(err) {
				return fmt.Errorf("no permission to read from '%s'", filePath)
			}
			currentFile.Close()
		}
		return nil
	})
}

func parseDockerignore(root string) ([]string, error) {
	var excludes []string
	ignore, err := ioutil.ReadFile(path.Join(root, ".dockerignore"))
	if err != nil && !os.IsNotExist(err) {
		return excludes, fmt.Errorf("error reading .dockerignore: '%s'", err)
	}
	excludes = strings.Split(string(ignore), "\n")

	return excludes, nil
}
<commit_msg>tar: use absolute path as srcPath when generating the tar stream<commit_after>// Copyright 2014 go-dockerclient authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package docker

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"strings"

	"github.com/docker/docker/pkg/archive"
	"github.com/docker/docker/pkg/fileutils"
)

func createTarStream(srcPath, dockerfilePath string) (io.ReadCloser, error) {
	srcPath, err := filepath.Abs(srcPath)
	if err != nil {
		return nil, err
	}

	excludes, err := parseDockerignore(srcPath)
	if err != nil {
		return nil, err
	}

	includes := []string{"."}

	// If .dockerignore mentions .dockerignore or the Dockerfile
	// then make sure we send both files over to the daemon
	// because Dockerfile is, obviously, needed no matter what, and
	// .dockerignore is needed to know if either one needs to be
	// removed.  The deamon will remove them for us, if needed, after it
	// parses the Dockerfile.
	//
	// https://github.com/docker/docker/issues/8330
	//
	forceIncludeFiles := []string{".dockerignore", dockerfilePath}

	for _, includeFile := range forceIncludeFiles {
		if includeFile == "" {
			continue
		}
		keepThem, err := fileutils.Matches(includeFile, excludes)
		if err != nil {
			return nil, fmt.Errorf("cannot match .dockerfile: '%s', error: %s", includeFile, err)
		}
		if keepThem {
			includes = append(includes, includeFile)
		}
	}

	if err := validateContextDirectory(srcPath, excludes); err != nil {
		return nil, err
	}
	tarOpts := &archive.TarOptions{
		ExcludePatterns: excludes,
		IncludeFiles:    includes,
		Compression:     archive.Uncompressed,
		NoLchown:        true,
	}
	return archive.TarWithOptions(srcPath, tarOpts)
}

// validateContextDirectory checks if all the contents of the directory
// can be read and returns an error if some files can't be read.
// Symlinks which point to non-existing files don't trigger an error
func validateContextDirectory(srcPath string, excludes []string) error {
	return filepath.Walk(filepath.Join(srcPath, "."), func(filePath string, f os.FileInfo, err error) error {
		// skip this directory/file if it's not in the path, it won't get added to the context
		if relFilePath, relErr := filepath.Rel(srcPath, filePath); relErr != nil {
			return relErr
		} else if skip, matchErr := fileutils.Matches(relFilePath, excludes); matchErr != nil {
			return matchErr
		} else if skip {
			if f.IsDir() {
				return filepath.SkipDir
			}
			return nil
		}

		if err != nil {
			if os.IsPermission(err) {
				return fmt.Errorf("can't stat '%s'", filePath)
			}
			if os.IsNotExist(err) {
				return nil
			}
			return err
		}

		// skip checking if symlinks point to non-existing files, such symlinks can be useful
		// also skip named pipes, because they hanging on open
		if f.Mode()&(os.ModeSymlink|os.ModeNamedPipe) != 0 {
			return nil
		}

		if !f.IsDir() {
			currentFile, err := os.Open(filePath)
			if err != nil && os.IsPermission(err) {
				return fmt.Errorf("no permission to read from '%s'", filePath)
			}
			currentFile.Close()
		}
		return nil
	})
}

func parseDockerignore(root string) ([]string, error) {
	var excludes []string
	ignore, err := ioutil.ReadFile(path.Join(root, ".dockerignore"))
	if err != nil && !os.IsNotExist(err) {
		return excludes, fmt.Errorf("error reading .dockerignore: '%s'", err)
	}
	excludes = strings.Split(string(ignore), "\n")

	return excludes, nil
}
<|endoftext|>


<commit_before>package otp

import (
	"crypto/md5"
	"crypto/sha1"
	"crypto/sha256"
	"crypto/sha512"
	"errors"
	"net/url"
	"strconv"
	"strings"
)

// ToURI returns the string representation of the Key.
// See https://code.google.com/p/google-authenticator/wiki/KeyUriFormat.
func (k Key) ToURI() string {
	uri := url.URL{
		Scheme: "otpauth",
		Host:   k.Method,
		Path:   "/" + k.Label,
	}

	params := url.Values{}
	params.Set("secret", k.Secret)

	if k.Issuer != "" {
		params.Set("issuer", k.Issuer)
	}

	hashName := strings.Split(strings.Split(getFuncName(k.Algo), ".")[0], "/")[1]
	params.Set("algo", hashName)

	params.Set("digits", strconv.Itoa(k.Digits))

	if k.Method == "totp" {
		params.Set("period", strconv.Itoa(k.Period))
	}

	if k.Method == "hotp" {
		params.Set("counter", strconv.Itoa(k.Counter))
	}

	uri.RawQuery = params.Encode()
	return uri.String()
}

// FromURI parses an otpauth URI into the Key.
func (k *Key) FromURI(uri string) error {

	u, err := url.ParseRequestURI(uri)
	if err != nil {
		return err
	}

	if u.Scheme != "otpauth" {
		return errors.New("invalid scheme")
	}

	(*k).Method = u.Host

	if u.Path == "" {
		return errors.New("missing label")
	}
	(*k).Label = u.Path[1:len(u.Path)]

	params := u.Query()
	(*k).Secret = params.Get("secret")
	(*k).Issuer = params.Get("issuer")

	// parse out hashing algo; default to sha1
	switch strings.ToUpper(params.Get("algo")) {
	case "SHA256":
		(*k).Algo = sha256.New
	case "SHA512":
		(*k).Algo = sha512.New
	case "MD5":
		(*k).Algo = md5.New
	default:
		(*k).Algo = sha1.New

	}

	digits := params.Get("digits")
	if digits != "" {
		d, err := strconv.Atoi(digits)
		if err != nil {
			return errors.New("digits is non-integer")
		}
		(*k).Digits = d
	} else {
		(*k).Digits = 6
	}

	// totp: try to get a period; else default to 30
	// hotp: try to get a counter
	if u.Host == "totp" {
		period := params.Get("period")
		if period != "" {
			p, err := strconv.Atoi(period)
			if err != nil {
				return errors.New("period is non-integer")
			}
			(*k).Period = p
		} else {
			(*k).Period = 30
		}
	} else if u.Host == "hotp" {
		counter := params.Get("counter")
		if counter != "" {
			c, err := strconv.Atoi(counter)
			if err != nil {
				return errors.New("counter is non-integer")
			}
			(*k).Counter = c
		}
	}

	return nil
}
<commit_msg>always cast secret to uppercase<commit_after>package otp

import (
	"crypto/md5"
	"crypto/sha1"
	"crypto/sha256"
	"crypto/sha512"
	"errors"
	"net/url"
	"strconv"
	"strings"
)

// ToURI returns the string representation of the Key.
// See https://code.google.com/p/google-authenticator/wiki/KeyUriFormat.
func (k Key) ToURI() string {
	uri := url.URL{
		Scheme: "otpauth",
		Host:   k.Method,
		Path:   "/" + k.Label,
	}

	params := url.Values{}
	params.Set("secret", k.Secret)

	if k.Issuer != "" {
		params.Set("issuer", k.Issuer)
	}

	hashName := strings.Split(strings.Split(getFuncName(k.Algo), ".")[0], "/")[1]
	params.Set("algo", hashName)

	params.Set("digits", strconv.Itoa(k.Digits))

	if k.Method == "totp" {
		params.Set("period", strconv.Itoa(k.Period))
	}

	if k.Method == "hotp" {
		params.Set("counter", strconv.Itoa(k.Counter))
	}

	uri.RawQuery = params.Encode()
	return uri.String()
}

// FromURI parses an otpauth URI into the Key.
func (k *Key) FromURI(uri string) error {

	u, err := url.ParseRequestURI(uri)
	if err != nil {
		return err
	}

	if u.Scheme != "otpauth" {
		return errors.New("invalid scheme")
	}

	(*k).Method = u.Host

	if u.Path == "" {
		return errors.New("missing label")
	}
	(*k).Label = u.Path[1:len(u.Path)]

	params := u.Query()
	(*k).Secret = strings.ToUpper(params.Get("secret"))
	(*k).Issuer = params.Get("issuer")

	// parse out hashing algo; default to sha1
	switch strings.ToUpper(params.Get("algo")) {
	case "SHA256":
		(*k).Algo = sha256.New
	case "SHA512":
		(*k).Algo = sha512.New
	case "MD5":
		(*k).Algo = md5.New
	default:
		(*k).Algo = sha1.New

	}

	digits := params.Get("digits")
	if digits != "" {
		d, err := strconv.Atoi(digits)
		if err != nil {
			return errors.New("digits is non-integer")
		}
		(*k).Digits = d
	} else {
		(*k).Digits = 6
	}

	// totp: try to get a period; else default to 30
	// hotp: try to get a counter
	if u.Host == "totp" {
		period := params.Get("period")
		if period != "" {
			p, err := strconv.Atoi(period)
			if err != nil {
				return errors.New("period is non-integer")
			}
			(*k).Period = p
		} else {
			(*k).Period = 30
		}
	} else if u.Host == "hotp" {
		counter := params.Get("counter")
		if counter != "" {
			c, err := strconv.Atoi(counter)
			if err != nil {
				return errors.New("counter is non-integer")
			}
			(*k).Counter = c
		}
	}

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"

	"github.com/BurntSushi/ty/fun"
	log "github.com/Sirupsen/logrus"
	"github.com/elazarl/go-bindata-assetfs"
	"github.com/gorilla/mux"
)

type WebProvider struct {
	Address           string
	CertFile, KeyFile string
}

type Page struct {
	Configurations configs
}

func (provider *WebProvider) Provide(configurationChan chan<- configMessage) error {
	systemRouter := mux.NewRouter()
	systemRouter.Methods("GET").Path("/").Handler(http.HandlerFunc(GetHTMLConfigHandler))
	systemRouter.Methods("GET").Path("/health").Handler(http.HandlerFunc(GetHealthHandler))
	systemRouter.Methods("GET").Path("/api").Handler(http.HandlerFunc(GetConfigHandler))
	systemRouter.Methods("GET").Path("/api/providers").Handler(http.HandlerFunc(GetProvidersHandler))
	systemRouter.Methods("GET").Path("/api/providers/{provider}").Handler(http.HandlerFunc(GetConfigHandler))
	systemRouter.Methods("PUT").Path("/api/providers/{provider}").Handler(http.HandlerFunc(
		func(rw http.ResponseWriter, r *http.Request) {
			vars := mux.Vars(r)
			if vars["provider"] != "web" {
				rw.WriteHeader(http.StatusBadRequest)
				fmt.Fprintf(rw, "Only 'web' provider can be updated through the REST API")
				return
			}

			configuration := new(Configuration)
			b, _ := ioutil.ReadAll(r.Body)
			err := json.Unmarshal(b, configuration)
			if err == nil {
				configurationChan <- configMessage{"web", configuration}
				GetConfigHandler(rw, r)
			} else {
				log.Errorf("Error parsing configuration %+v", err)
				http.Error(rw, fmt.Sprintf("%+v", err), http.StatusBadRequest)
			}
		}))
	systemRouter.Methods("GET").Path("/api/providers/{provider}/backends").Handler(http.HandlerFunc(GetBackendsHandler))
	systemRouter.Methods("GET").Path("/api/providers/{provider}/backends/{backend}").Handler(http.HandlerFunc(GetBackendHandler))
	systemRouter.Methods("GET").Path("/api/providers/{provider}/backends/{backend}/servers").Handler(http.HandlerFunc(GetServersHandler))
	systemRouter.Methods("GET").Path("/api/providers/{provider}/backends/{backend}/servers/{server}").Handler(http.HandlerFunc(GetServerHandler))
	systemRouter.Methods("GET").Path("/api/providers/{provider}/frontends").Handler(http.HandlerFunc(GetFrontendsHandler))
	systemRouter.Methods("GET").Path("/api/providers/{provider}/frontends/{frontend}").Handler(http.HandlerFunc(GetFrontendHandler))
	systemRouter.Methods("GET").PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(&assetfs.AssetFS{Asset: Asset, AssetDir: AssetDir, Prefix: "static"})))

	go func() {
		if len(provider.CertFile) > 0 && len(provider.KeyFile) > 0 {
			err := http.ListenAndServeTLS(provider.Address, provider.CertFile, provider.KeyFile, systemRouter)
			if err != nil {
				log.Fatal("Error creating server: ", err)
			}
		} else {
			err := http.ListenAndServe(provider.Address, systemRouter)
			if err != nil {
				log.Fatal("Error creating server: ", err)
			}
		}
	}()
	return nil
}

func GetConfigHandler(rw http.ResponseWriter, r *http.Request) {
	templatesRenderer.JSON(rw, http.StatusOK, currentConfigurations)
}

func GetHTMLConfigHandler(response http.ResponseWriter, request *http.Request) {
	templatesRenderer.HTML(response, http.StatusOK, "configuration", Page{Configurations: currentConfigurations})
}

func GetHealthHandler(rw http.ResponseWriter, r *http.Request) {
	templatesRenderer.JSON(rw, http.StatusOK, metrics.Data())
}

func GetProvidersHandler(rw http.ResponseWriter, r *http.Request) {
	templatesRenderer.JSON(rw, http.StatusOK, fun.Keys(currentConfigurations))
}

func GetBackendsHandler(rw http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	providerId := vars["provider"]
	if provider, ok := currentConfigurations[providerId]; ok {
		templatesRenderer.JSON(rw, http.StatusOK, provider.Backends)
	} else {
		http.NotFound(rw, r)
	}
}

func GetBackendHandler(rw http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	providerId := vars["provider"]
	backendId := vars["backend"]
	if provider, ok := currentConfigurations[providerId]; ok {
		if backend, ok := provider.Backends[backendId]; ok {
			templatesRenderer.JSON(rw, http.StatusOK, backend)
			return
		}
	}
	http.NotFound(rw, r)
}

func GetFrontendsHandler(rw http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	providerId := vars["provider"]
	if provider, ok := currentConfigurations[providerId]; ok {
		templatesRenderer.JSON(rw, http.StatusOK, provider.Frontends)
	} else {
		http.NotFound(rw, r)
	}
}

func GetFrontendHandler(rw http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	providerId := vars["provider"]
	frontendId := vars["frontend"]
	if provider, ok := currentConfigurations[providerId]; ok {
		if frontend, ok := provider.Frontends[frontendId]; ok {
			templatesRenderer.JSON(rw, http.StatusOK, frontend)
			return
		}
	}
	http.NotFound(rw, r)
}

func GetServersHandler(rw http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	providerId := vars["provider"]
	backendId := vars["backend"]
	if provider, ok := currentConfigurations[providerId]; ok {
		if backend, ok := provider.Backends[backendId]; ok {
			templatesRenderer.JSON(rw, http.StatusOK, backend.Servers)
			return
		}
	}
	http.NotFound(rw, r)
}

func GetServerHandler(rw http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	providerId := vars["provider"]
	backendId := vars["backend"]
	serverId := vars["server"]
	if provider, ok := currentConfigurations[providerId]; ok {
		if backend, ok := provider.Backends[backendId]; ok {
			if server, ok := backend.Servers[serverId]; ok {
				templatesRenderer.JSON(rw, http.StatusOK, server)
				return
			}
		}
	}
	http.NotFound(rw, r)
}
<commit_msg>feat: API REST endpoint review<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"

	log "github.com/Sirupsen/logrus"
	"github.com/elazarl/go-bindata-assetfs"
	"github.com/gorilla/mux"
)

type WebProvider struct {
	Address           string
	CertFile, KeyFile string
}

func (provider *WebProvider) Provide(configurationChan chan<- configMessage) error {
	systemRouter := mux.NewRouter()

	// health route
	systemRouter.Methods("GET").Path("/health").HandlerFunc(getHealthHandler)

	// API routes
	systemRouter.Methods("GET").Path("/api").HandlerFunc(getConfigHandler)
	systemRouter.Methods("GET").Path("/api/providers").HandlerFunc(getConfigHandler)
	systemRouter.Methods("GET").Path("/api/providers/{provider}").HandlerFunc(getProviderHandler)
	systemRouter.Methods("PUT").Path("/api/providers/{provider}").HandlerFunc(func(response http.ResponseWriter, request *http.Request) {
		vars := mux.Vars(request)
		if vars["provider"] != "web" {
			response.WriteHeader(http.StatusBadRequest)
			fmt.Fprintf(response, "Only 'web' provider can be updated through the REST API")
			return
		}

		configuration := new(Configuration)
		body, _ := ioutil.ReadAll(request.Body)
		err := json.Unmarshal(body, configuration)
		if err == nil {
			configurationChan <- configMessage{"web", configuration}
			getConfigHandler(response, request)
		} else {
			log.Errorf("Error parsing configuration %+v", err)
			http.Error(response, fmt.Sprintf("%+v", err), http.StatusBadRequest)
		}
	})
	systemRouter.Methods("GET").Path("/api/providers/{provider}/backends").HandlerFunc(getBackendsHandler)
	systemRouter.Methods("GET").Path("/api/providers/{provider}/backends/{backend}").HandlerFunc(getBackendHandler)
	systemRouter.Methods("GET").Path("/api/providers/{provider}/backends/{backend}/servers").HandlerFunc(getServersHandler)
	systemRouter.Methods("GET").Path("/api/providers/{provider}/backends/{backend}/servers/{server}").HandlerFunc(getServerHandler)
	systemRouter.Methods("GET").Path("/api/providers/{provider}/frontends").HandlerFunc(getFrontendsHandler)
	systemRouter.Methods("GET").Path("/api/providers/{provider}/frontends/{frontend}").HandlerFunc(getFrontendHandler)

	// Expose dashboard
	systemRouter.Methods("GET").Path("/").HandlerFunc(func(response http.ResponseWriter, request *http.Request) {
		http.Redirect(response, request, "/dashboard/", 302)
	})
	systemRouter.Methods("GET").PathPrefix("/dashboard/").Handler(http.StripPrefix("/dashboard/", http.FileServer(&assetfs.AssetFS{Asset: Asset, AssetDir: AssetDir, Prefix: "static"})))

	go func() {
		if len(provider.CertFile) > 0 && len(provider.KeyFile) > 0 {
			err := http.ListenAndServeTLS(provider.Address, provider.CertFile, provider.KeyFile, systemRouter)
			if err != nil {
				log.Fatal("Error creating server: ", err)
			}
		} else {
			err := http.ListenAndServe(provider.Address, systemRouter)
			if err != nil {
				log.Fatal("Error creating server: ", err)
			}
		}
	}()
	return nil
}

func getHealthHandler(response http.ResponseWriter, request *http.Request) {
	templatesRenderer.JSON(response, http.StatusOK, metrics.Data())
}

func getConfigHandler(response http.ResponseWriter, request *http.Request) {
	templatesRenderer.JSON(response, http.StatusOK, currentConfigurations)
}

func getProviderHandler(response http.ResponseWriter, request *http.Request) {
	vars := mux.Vars(request)
	providerID := vars["provider"]
	if provider, ok := currentConfigurations[providerID]; ok {
		templatesRenderer.JSON(response, http.StatusOK, provider)
	} else {
		http.NotFound(response, request)
	}
}

func getBackendsHandler(response http.ResponseWriter, request *http.Request) {
	vars := mux.Vars(request)
	providerID := vars["provider"]
	if provider, ok := currentConfigurations[providerID]; ok {
		templatesRenderer.JSON(response, http.StatusOK, provider.Backends)
	} else {
		http.NotFound(response, request)
	}
}

func getBackendHandler(response http.ResponseWriter, request *http.Request) {
	vars := mux.Vars(request)
	providerID := vars["provider"]
	backendID := vars["backend"]
	if provider, ok := currentConfigurations[providerID]; ok {
		if backend, ok := provider.Backends[backendID]; ok {
			templatesRenderer.JSON(response, http.StatusOK, backend)
			return
		}
	}
	http.NotFound(response, request)
}

func getFrontendsHandler(response http.ResponseWriter, request *http.Request) {
	vars := mux.Vars(request)
	providerID := vars["provider"]
	if provider, ok := currentConfigurations[providerID]; ok {
		templatesRenderer.JSON(response, http.StatusOK, provider.Frontends)
	} else {
		http.NotFound(response, request)
	}
}

func getFrontendHandler(response http.ResponseWriter, request *http.Request) {
	vars := mux.Vars(request)
	providerID := vars["provider"]
	frontendID := vars["frontend"]
	if provider, ok := currentConfigurations[providerID]; ok {
		if frontend, ok := provider.Frontends[frontendID]; ok {
			templatesRenderer.JSON(response, http.StatusOK, frontend)
			return
		}
	}
	http.NotFound(response, request)
}

func getServersHandler(response http.ResponseWriter, request *http.Request) {
	vars := mux.Vars(request)
	providerID := vars["provider"]
	backendID := vars["backend"]
	if provider, ok := currentConfigurations[providerID]; ok {
		if backend, ok := provider.Backends[backendID]; ok {
			templatesRenderer.JSON(response, http.StatusOK, backend.Servers)
			return
		}
	}
	http.NotFound(response, request)
}

func getServerHandler(response http.ResponseWriter, request *http.Request) {
	vars := mux.Vars(request)
	providerID := vars["provider"]
	backendID := vars["backend"]
	serverID := vars["server"]
	if provider, ok := currentConfigurations[providerID]; ok {
		if backend, ok := provider.Backends[backendID]; ok {
			if server, ok := backend.Servers[serverID]; ok {
				templatesRenderer.JSON(response, http.StatusOK, server)
				return
			}
		}
	}
	http.NotFound(response, request)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"math/rand"
	"net/http"
	"os"
	"regexp"
	"time"
)

var idChars = []rune("0123456789abcdef")
var idLength = 32

func randId() string {
	b := make([]rune, idLength)
	for i := range b {
		b[i] = idChars[rand.Intn(len(idChars))]
	}
	return string(b)
}

type Clients struct {
	idByClient     map[chan string]string
	clientById     map[string]chan string
	newClients     chan chan string
	defunctClients chan chan string
}

func (b *Clients) Start() {
	for {
		select {
		case s := <-b.newClients:
			id := randId()
			b.idByClient[s] = id
			b.clientById[id] = s
			fmt.Printf("connected %s %d\n", id, time.Now().Unix())
		case s := <-b.defunctClients:
			id := b.idByClient[s]
			delete(b.idByClient, s)
			delete(b.clientById, id)
			fmt.Printf("disconnected %s %d\n", id, time.Now().Unix())
		}
	}
}

func (b *Clients) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	f, ok := w.(http.Flusher)
	if !ok {
		http.Error(w, "Streaming unsupported!", http.StatusInternalServerError)
		return
	}

	messageChan := make(chan string)
	b.newClients <- messageChan

	notify := w.(http.CloseNotifier).CloseNotify()
	go func() {
		<-notify
		b.defunctClients <- messageChan
	}()

	w.Header().Set("Content-Type", "text/event-stream")
	w.Header().Set("Cache-Control", "no-cache")
	w.Header().Set("Connection", "keep-alive")
	// Tell nginx to not buffer. Without this it may take up to a minute
	// for events to arrive at the client.
	w.Header().Set("X-Accel-Buffering", "no")

	for {
		msg := <-messageChan
		fmt.Fprintf(w, "data: %s\n\n", msg)
		f.Flush()
	}
}

var pattern = regexp.MustCompile(`(\S+) (\S+) (\S+)`)

func ReadCommands(clients *Clients) {
	reader := bufio.NewReader(os.Stdin)
	for {
		line, err := reader.ReadString('\n')
		if err != nil {
			panic(err)
		}
		parts := pattern.FindStringSubmatch(line)
		if len(parts) == 0 {
			fmt.Fprintf(os.Stderr, "Invalid command format. Expected 'command id params'.\n")
			continue
		}
		command := parts[1]
		id := parts[2]
		params := parts[3]
		switch command {
		case "send":
			if id == "world" {
				for s, _ := range clients.idByClient {
					s <- params
				}
			} else {
				clients.clientById[id] <- params
			}
		default:
			fmt.Fprintf(os.Stderr, "Invalid command "+command+"\n")
		}
	}
}

func main() {
	rand.Seed(time.Now().UTC().UnixNano())

	clients := &Clients{
		make(map[chan string]string),
		make(map[string]chan string),
		make(chan (chan string)),
		make(chan (chan string)),
	}

	go clients.Start()
	http.Handle("/events/", clients)

	go ReadCommands(clients)

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		http.ServeFile(w, r, "index.html")
	})
	panic(http.ListenAndServe(":8000", nil))
}
<commit_msg>Print calls<commit_after>package main

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"os"
	"regexp"
	"time"
)

var idChars = []rune("0123456789abcdef")
var idLength = 32

func randId() string {
	b := make([]rune, idLength)
	for i := range b {
		b[i] = idChars[rand.Intn(len(idChars))]
	}
	return string(b)
}

type Clients struct {
	idByClient     map[chan string]string
	clientById     map[string]chan string
	newClients     chan chan string
	defunctClients chan chan string
}

func (b *Clients) Start() {
	for {
		select {
		case s := <-b.newClients:
			id := randId()
			b.idByClient[s] = id
			b.clientById[id] = s
			fmt.Printf("connected %s %d\n", id, time.Now().Unix())
		case s := <-b.defunctClients:
			id := b.idByClient[s]
			delete(b.idByClient, s)
			delete(b.clientById, id)
			fmt.Printf("disconnected %s %d\n", id, time.Now().Unix())
		}
	}
}

func (b *Clients) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	f, ok := w.(http.Flusher)
	if !ok {
		http.Error(w, "Streaming unsupported!", http.StatusInternalServerError)
		return
	}

	messageChan := make(chan string)
	b.newClients <- messageChan

	notify := w.(http.CloseNotifier).CloseNotify()
	go func() {
		<-notify
		b.defunctClients <- messageChan
	}()

	w.Header().Set("Content-Type", "text/event-stream")
	w.Header().Set("Cache-Control", "no-cache")
	w.Header().Set("Connection", "keep-alive")
	// Tell nginx to not buffer. Without this it may take up to a minute
	// for events to arrive at the client.
	w.Header().Set("X-Accel-Buffering", "no")

	for {
		msg := <-messageChan
		fmt.Fprintf(w, "data: %s\n\n", msg)
		f.Flush()
	}
}

var pattern = regexp.MustCompile(`(\S+) (\S+) (\S+)`)

func ReadCommands(clients *Clients) {
	reader := bufio.NewReader(os.Stdin)
	for {
		line, err := reader.ReadString('\n')
		if err != nil {
			panic(err)
		}
		parts := pattern.FindStringSubmatch(line)
		if len(parts) == 0 {
			fmt.Fprintf(os.Stderr, "Invalid command format. Expected 'command id params'.\n")
			continue
		}
		command := parts[1]
		id := parts[2]
		params := parts[3]
		switch command {
		case "send":
			if id == "world" {
				for s, _ := range clients.idByClient {
					s <- params
				}
			} else {
				clients.clientById[id] <- params
			}
		default:
			fmt.Fprintf(os.Stderr, "Invalid command "+command+"\n")
		}
	}
}

func HandleCall(w http.ResponseWriter, r *http.Request) {
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		http.Error(w, "Error reading body.", http.StatusInternalServerError)
		fmt.Fprintf(os.Stderr, err.Error())
		return
	}
	fmt.Printf("call %s\n", body)
}

func main() {
	rand.Seed(time.Now().UTC().UnixNano())

	clients := &Clients{
		make(map[chan string]string),
		make(map[string]chan string),
		make(chan (chan string)),
		make(chan (chan string)),
	}

	go clients.Start()
	http.Handle("/events/", clients)

	go ReadCommands(clients)

	http.Handle("/call", http.HandlerFunc(HandleCall))
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		http.ServeFile(w, r, "index.html")
	})
	panic(http.ListenAndServe(":8000", nil))
}
<|endoftext|>


<commit_before>package main

// Slack outgoing webhooks are handled here. Requests come in and are run through
// the markov chain to generate a response, which is sent back to Slack.
//
// Create an outgoing webhook in your Slack here:
// https://my.slack.com/services/new/outgoing-webhook

import (
	"encoding/json"
	"log"
	"math/rand"
	"net/http"
	"strconv"
	"strings"
	"time"
//	"fmt"
	"io/ioutil"
)

type whr struct {
	Token		 string `json:"token"`
	Team_ID	 string `json:"team_id"`
	ChannelID  string `json:"channel_id"`
	ChannelName string `json:"channel_name"`
	TS				string `json:"timestamp"`
	UserID		string `json:"user_id"`
	Username string `json:"user_name"`
	Text     string `json:"text"`
	Trigger  string `json:"trigger_word"`
}

func init() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
	//	incomingText := r.PostFormValue("text")

			err := r.ParseForm()
			if err != nil {
				panic(err)
			}
			//log.Println("r.Form", r.Form)

			txt := r.Form["text"]
			usr := r.Form["user_name"]
			incomingText := txt[0]
			rUsername := usr[0]
		if incomingText != "" && rUsername != "" && rUsername != "slackbot" {
			text := parseText(incomingText)
			log.Printf("Handling incoming request: %s from %s", text,rUsername )

			if text != "" {
				markovChain.Write(text)
			}

			go func() {
				markovChain.Save(stateFile)
			}()

			if rand.Intn(100) <= responseChance || strings.HasPrefix(text, botUsername) || strings.Contains(text,"Dingus") {
				var response whr
				response.Username = botUsername

				response.Text = markovChain.Generate(numWords)
				if strings.HasPrefix(text,"Dingus: compliment me"){
					url := "http://127.0.0.1:56735"
					comp, err := http.Get(url)
					if err != nil {
						log.Fatal(err)
					}
					defer comp.Body.Close()
					compData, err := ioutil.ReadAll(comp.Body)
					if err != nil {
						log.Fatal(err)
					}
					compString := string(compData)
					response.Text = rUsername + ": " + compString
				}

				if strings.HasPrefix(text, "Dingus: insult me"){
					url := "http://insult-me-dingus.herokuapp.com/"
					comp, err := http.Get(url)
					if err != nil {
						log.Fatal(err)
					}
					defer comp.Body.Close()
					compData, err := ioutil.ReadAll(comp.Body)
					if err != nil {
						log.Fatal(err)
					}
					compString := string(compData)
					response.Text = rUsername + ": " + compString
				}

				log.Printf("Sending response: %s", response.Text)

				b, err := json.Marshal(response)
				if err != nil {
					log.Fatal(err)
				}

				time.Sleep(5 * time.Second)
				w.Write(b)
				r.Body.Close()
			}
		}
	})
}

func StartServer(port int) {
	log.Printf("Starting HTTP server on %d", port)
	err := http.ListenAndServe(":"+strconv.Itoa(port), nil)
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}
<commit_msg>roast me command<commit_after>package main

// Slack outgoing webhooks are handled here. Requests come in and are run through
// the markov chain to generate a response, which is sent back to Slack.
//
// Create an outgoing webhook in your Slack here:
// https://my.slack.com/services/new/outgoing-webhook

import (
	"encoding/json"
	"log"
	"math/rand"
	"net/http"
	"strconv"
	"strings"
	"time"
//	"fmt"
	"io/ioutil"
)

type whr struct {
	Token		 string `json:"token"`
	Team_ID	 string `json:"team_id"`
	ChannelID  string `json:"channel_id"`
	ChannelName string `json:"channel_name"`
	TS				string `json:"timestamp"`
	UserID		string `json:"user_id"`
	Username string `json:"user_name"`
	Text     string `json:"text"`
	Trigger  string `json:"trigger_word"`
}

func init() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
	//	incomingText := r.PostFormValue("text")

			err := r.ParseForm()
			if err != nil {
				panic(err)
			}
			//log.Println("r.Form", r.Form)

			txt := r.Form["text"]
			usr := r.Form["user_name"]
			incomingText := txt[0]
			rUsername := usr[0]
		if incomingText != "" && rUsername != "" && rUsername != "slackbot" {
			text := parseText(incomingText)
			log.Printf("Handling incoming request: %s from %s", text,rUsername )

			if text != "" {
				markovChain.Write(text)
			}

			go func() {
				markovChain.Save(stateFile)
			}()

			if rand.Intn(100) <= responseChance || strings.HasPrefix(text, botUsername) || strings.Contains(text,"Dingus") {
				var response whr
				response.Username = botUsername

				response.Text = markovChain.Generate(numWords)
				if strings.HasPrefix(text,"Dingus: compliment me"){
					url := "http://127.0.0.1:56735"
					comp, err := http.Get(url)
					if err != nil {
						log.Fatal(err)
					}
					defer comp.Body.Close()
					compData, err := ioutil.ReadAll(comp.Body)
					if err != nil {
						log.Fatal(err)
					}
					compString := string(compData)
					response.Text = rUsername + ": " + compString
				}
				if strings.HasPrefix(text,"Dingus: roast me"){
					url := "http://127.0.0.1:56736"
					comp, err := http.Get(url)
					if err != nil {
						log.Fatal(err)
					}
					defer comp.Body.Close()
					compData, err := ioutil.ReadAll(comp.Body)
					if err != nil {
						log.Fatal(err)
					}
					compString := string(compData)
					response.Text = rUsername + ": " + compString
				}
				if strings.HasPrefix(text, "Dingus: insult me"){
					url := "http://insult-me-dingus.herokuapp.com/"
					comp, err := http.Get(url)
					if err != nil {
						log.Fatal(err)
					}
					defer comp.Body.Close()
					compData, err := ioutil.ReadAll(comp.Body)
					if err != nil {
						log.Fatal(err)
					}
					compString := string(compData)
					response.Text = rUsername + ": " + compString
				}
			 if strings.Contains(text, "slackbot"){
					response.Text = "You expected slackbot? Too Bad! It was me, Dingus! :dio:"
				}
				log.Printf("Sending response: %s", response.Text)

				b, err := json.Marshal(response)
				if err != nil {
					log.Fatal(err)
				}

				time.Sleep(5 * time.Second)
				w.Write(b)
				r.Body.Close()
			}
		}
	})
}

func StartServer(port int) {
	log.Printf("Starting HTTP server on %d", port)
	err := http.ListenAndServe(":"+strconv.Itoa(port), nil)
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}
<|endoftext|>


<commit_before>// Package web is a lightweight web framework for Go. It's ideal for
// writing simple, performant backend web services.
package web

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha1"
	"crypto/tls"
	"encoding/base64"
	"fmt"
	"golang.org/x/net/websocket"
	"io/ioutil"
	"log"
	"mime"
	"net/http"
	"os"
	"path"
	"reflect"
	"strconv"
	"strings"
	"time"
)

// A Context object is created for every incoming HTTP request, and is
// passed to handlers as an optional first argument. It provides information
// about the request, including the http.Request object, the GET and POST params,
// and acts as a Writer for the response.
type Context struct {
	Request *http.Request
	Params  map[string]string
	Server  *Server
	http.ResponseWriter
}

// WriteString writes string data into the response object.
func (ctx *Context) WriteString(content string) {
	ctx.ResponseWriter.Write([]byte(content))
}

// Abort is a helper method that sends an HTTP header and an optional
// body. It is useful for returning 4xx or 5xx errors.
// Once it has been called, any return value from the handler will
// not be written to the response.
func (ctx *Context) Abort(status int, body string) {
	ctx.SetHeader("Content-Type", "text/html; charset=utf-8", true)
	ctx.ResponseWriter.WriteHeader(status)
	ctx.ResponseWriter.Write([]byte(body))
}

// Redirect is a helper method for 3xx redirects.
func (ctx *Context) Redirect(status int, url_ string) {
	ctx.ResponseWriter.Header().Set("Location", url_)
	ctx.ResponseWriter.WriteHeader(status)
	ctx.ResponseWriter.Write([]byte("Redirecting to: " + url_))
}

//BadRequest writes a 400 HTTP response
func (ctx *Context) BadRequest() {
	ctx.ResponseWriter.WriteHeader(400)
}

// Notmodified writes a 304 HTTP response
func (ctx *Context) NotModified() {
	ctx.ResponseWriter.WriteHeader(304)
}

//Unauthorized writes a 401 HTTP response
func (ctx *Context) Unauthorized() {
	ctx.ResponseWriter.WriteHeader(401)
}

//Forbidden writes a 403 HTTP response
func (ctx *Context) Forbidden() {
	ctx.ResponseWriter.WriteHeader(403)
}

// NotFound writes a 404 HTTP response
func (ctx *Context) NotFound(message string) {
	ctx.ResponseWriter.WriteHeader(404)
	ctx.ResponseWriter.Write([]byte(message))
}

// ContentType sets the Content-Type header for an HTTP response.
// For example, ctx.ContentType("json") sets the content-type to "application/json"
// If the supplied value contains a slash (/) it is set as the Content-Type
// verbatim. The return value is the content type as it was
// set, or an empty string if none was found.
func (ctx *Context) ContentType(val string) string {
	var ctype string
	if strings.ContainsRune(val, '/') {
		ctype = val
	} else {
		if !strings.HasPrefix(val, ".") {
			val = "." + val
		}
		ctype = mime.TypeByExtension(val)
	}
	if ctype != "" {
		ctx.Header().Set("Content-Type", ctype)
	}
	return ctype
}

// SetHeader sets a response header. If `unique` is true, the current value
// of that header will be overwritten . If false, it will be appended.
func (ctx *Context) SetHeader(hdr string, val string, unique bool) {
	if unique {
		ctx.Header().Set(hdr, val)
	} else {
		ctx.Header().Add(hdr, val)
	}
}

// SetCookie adds a cookie header to the response.
func (ctx *Context) SetCookie(cookie *http.Cookie) {
	ctx.SetHeader("Set-Cookie", cookie.String(), false)
}

func getCookieSig(key string, val []byte, timestamp string) string {
	hm := hmac.New(sha1.New, []byte(key))

	hm.Write(val)
	hm.Write([]byte(timestamp))

	return fmt.Sprintf("%02x", hm.Sum(nil))
}

func (ctx *Context) SetSecureCookie(name string, val string, age int64) {
	//base64 encode the val
	if len(ctx.Server.Config.CookieSecret) == 0 {
		ctx.Server.Logger.Println("Secret Key for secure cookies has not been set. Please assign a cookie secret to web.Config.CookieSecret.")
		return
	}
	var buf bytes.Buffer
	encoder := base64.NewEncoder(base64.StdEncoding, &buf)
	encoder.Write([]byte(val))
	encoder.Close()
	vs := buf.String()
	vb := buf.Bytes()
	timestamp := strconv.FormatInt(time.Now().Unix(), 10)
	sig := getCookieSig(ctx.Server.Config.CookieSecret, vb, timestamp)
	cookie := strings.Join([]string{vs, timestamp, sig}, "|")
	ctx.SetCookie(NewCookie(name, cookie, age))
}

func (ctx *Context) GetSecureCookie(name string) (string, bool) {
	for _, cookie := range ctx.Request.Cookies() {
		if cookie.Name != name {
			continue
		}

		parts := strings.SplitN(cookie.Value, "|", 3)
		if len(parts) != 3 {
			return "", false
		}

		val := parts[0]
		timestamp := parts[1]
		sig := parts[2]

		if getCookieSig(ctx.Server.Config.CookieSecret, []byte(val), timestamp) != sig {
			return "", false
		}

		ts, _ := strconv.ParseInt(timestamp, 0, 64)

		if time.Now().Unix()-31*86400 > ts {
			return "", false
		}

		buf := bytes.NewBufferString(val)
		encoder := base64.NewDecoder(base64.StdEncoding, buf)

		res, _ := ioutil.ReadAll(encoder)
		return string(res), true
	}
	return "", false
}

// small optimization: cache the context type instead of repeteadly calling reflect.Typeof
var contextType reflect.Type

var defaultStaticDirs []string

func init() {
	contextType = reflect.TypeOf(Context{})
	//find the location of the exe file
	wd, _ := os.Getwd()
	arg0 := path.Clean(os.Args[0])
	var exeFile string
	if strings.HasPrefix(arg0, "/") {
		exeFile = arg0
	} else {
		//TODO for robustness, search each directory in $PATH
		exeFile = path.Join(wd, arg0)
	}
	parent, _ := path.Split(exeFile)
	defaultStaticDirs = append(defaultStaticDirs, path.Join(parent, "static"))
	defaultStaticDirs = append(defaultStaticDirs, path.Join(wd, "static"))
	return
}

// Process invokes the main server's routing system.
func Process(c http.ResponseWriter, req *http.Request) {
	mainServer.Process(c, req)
}

// Run starts the web application and serves HTTP requests for the main server.
func Run(addr string) {
	mainServer.Run(addr)
}

// RunTLS starts the web application and serves HTTPS requests for the main server.
func RunTLS(addr string, config *tls.Config) {
	mainServer.RunTLS(addr, config)
}

// RunScgi starts the web application and serves SCGI requests for the main server.
func RunScgi(addr string) {
	mainServer.RunScgi(addr)
}

// RunFcgi starts the web application and serves FastCGI requests for the main server.
func RunFcgi(addr string) {
	mainServer.RunFcgi(addr)
}

// Close stops the main server.
func Close() {
	mainServer.Close()
}

// Get adds a handler for the 'GET' http method in the main server.
func Get(route string, handler interface{}) {
	mainServer.Get(route, handler)
}

// Post adds a handler for the 'POST' http method in the main server.
func Post(route string, handler interface{}) {
	mainServer.addRoute(route, "POST", handler)
}

// Put adds a handler for the 'PUT' http method in the main server.
func Put(route string, handler interface{}) {
	mainServer.addRoute(route, "PUT", handler)
}

// Delete adds a handler for the 'DELETE' http method in the main server.
func Delete(route string, handler interface{}) {
	mainServer.addRoute(route, "DELETE", handler)
}

// Match adds a handler for an arbitrary http method in the main server.
func Match(method string, route string, handler interface{}) {
	mainServer.addRoute(route, method, handler)
}

// Add a custom http.Handler. Will have no effect when running as FCGI or SCGI.
func Handle(route string, method string, httpHandler http.Handler) {
	mainServer.Handle(route, method, httpHandler)
}

//Adds a handler for websockets. Only for webserver mode. Will have no effect when running as FCGI or SCGI.
func Websocket(route string, httpHandler websocket.Handler) {
	mainServer.Websocket(route, httpHandler)
}

// SetLogger sets the logger for the main server.
func SetLogger(logger *log.Logger) {
	mainServer.Logger = logger
}

// Config is the configuration of the main server.
var Config = &ServerConfig{
	RecoverPanic: true,
	ColorOutput:  true,
}

var mainServer = NewServer()
<commit_msg>Simplify base64 encoding logic in SetSecureCookie<commit_after>// Package web is a lightweight web framework for Go. It's ideal for
// writing simple, performant backend web services.
package web

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha1"
	"crypto/tls"
	"encoding/base64"
	"fmt"
	"golang.org/x/net/websocket"
	"io/ioutil"
	"log"
	"mime"
	"net/http"
	"os"
	"path"
	"reflect"
	"strconv"
	"strings"
	"time"
)

// A Context object is created for every incoming HTTP request, and is
// passed to handlers as an optional first argument. It provides information
// about the request, including the http.Request object, the GET and POST params,
// and acts as a Writer for the response.
type Context struct {
	Request *http.Request
	Params  map[string]string
	Server  *Server
	http.ResponseWriter
}

// WriteString writes string data into the response object.
func (ctx *Context) WriteString(content string) {
	ctx.ResponseWriter.Write([]byte(content))
}

// Abort is a helper method that sends an HTTP header and an optional
// body. It is useful for returning 4xx or 5xx errors.
// Once it has been called, any return value from the handler will
// not be written to the response.
func (ctx *Context) Abort(status int, body string) {
	ctx.SetHeader("Content-Type", "text/html; charset=utf-8", true)
	ctx.ResponseWriter.WriteHeader(status)
	ctx.ResponseWriter.Write([]byte(body))
}

// Redirect is a helper method for 3xx redirects.
func (ctx *Context) Redirect(status int, url_ string) {
	ctx.ResponseWriter.Header().Set("Location", url_)
	ctx.ResponseWriter.WriteHeader(status)
	ctx.ResponseWriter.Write([]byte("Redirecting to: " + url_))
}

//BadRequest writes a 400 HTTP response
func (ctx *Context) BadRequest() {
	ctx.ResponseWriter.WriteHeader(400)
}

// Notmodified writes a 304 HTTP response
func (ctx *Context) NotModified() {
	ctx.ResponseWriter.WriteHeader(304)
}

//Unauthorized writes a 401 HTTP response
func (ctx *Context) Unauthorized() {
	ctx.ResponseWriter.WriteHeader(401)
}

//Forbidden writes a 403 HTTP response
func (ctx *Context) Forbidden() {
	ctx.ResponseWriter.WriteHeader(403)
}

// NotFound writes a 404 HTTP response
func (ctx *Context) NotFound(message string) {
	ctx.ResponseWriter.WriteHeader(404)
	ctx.ResponseWriter.Write([]byte(message))
}

// ContentType sets the Content-Type header for an HTTP response.
// For example, ctx.ContentType("json") sets the content-type to "application/json"
// If the supplied value contains a slash (/) it is set as the Content-Type
// verbatim. The return value is the content type as it was
// set, or an empty string if none was found.
func (ctx *Context) ContentType(val string) string {
	var ctype string
	if strings.ContainsRune(val, '/') {
		ctype = val
	} else {
		if !strings.HasPrefix(val, ".") {
			val = "." + val
		}
		ctype = mime.TypeByExtension(val)
	}
	if ctype != "" {
		ctx.Header().Set("Content-Type", ctype)
	}
	return ctype
}

// SetHeader sets a response header. If `unique` is true, the current value
// of that header will be overwritten . If false, it will be appended.
func (ctx *Context) SetHeader(hdr string, val string, unique bool) {
	if unique {
		ctx.Header().Set(hdr, val)
	} else {
		ctx.Header().Add(hdr, val)
	}
}

// SetCookie adds a cookie header to the response.
func (ctx *Context) SetCookie(cookie *http.Cookie) {
	ctx.SetHeader("Set-Cookie", cookie.String(), false)
}

func getCookieSig(key string, val []byte, timestamp string) string {
	hm := hmac.New(sha1.New, []byte(key))

	hm.Write(val)
	hm.Write([]byte(timestamp))

	return fmt.Sprintf("%02x", hm.Sum(nil))
}

func (ctx *Context) SetSecureCookie(name string, val string, age int64) {
	if len(ctx.Server.Config.CookieSecret) == 0 {
		ctx.Server.Logger.Println("Secret Key for secure cookies has not been set. Please assign a cookie secret to web.Config.CookieSecret.")
		return
	}
	encoded := base64.StdEncoding.EncodeToString([]byte(val))
	timestamp := strconv.FormatInt(time.Now().Unix(), 10)
	sig := getCookieSig(ctx.Server.Config.CookieSecret, []byte(encoded), timestamp)
	cookie := strings.Join([]string{encoded, timestamp, sig}, "|")
	ctx.SetCookie(NewCookie(name, cookie, age))
}

func (ctx *Context) GetSecureCookie(name string) (string, bool) {
	for _, cookie := range ctx.Request.Cookies() {
		if cookie.Name != name {
			continue
		}

		parts := strings.SplitN(cookie.Value, "|", 3)
		if len(parts) != 3 {
			return "", false
		}

		val := parts[0]
		timestamp := parts[1]
		sig := parts[2]

		if getCookieSig(ctx.Server.Config.CookieSecret, []byte(val), timestamp) != sig {
			return "", false
		}

		ts, _ := strconv.ParseInt(timestamp, 0, 64)

		if time.Now().Unix()-31*86400 > ts {
			return "", false
		}

		buf := bytes.NewBufferString(val)
		encoder := base64.NewDecoder(base64.StdEncoding, buf)

		res, _ := ioutil.ReadAll(encoder)
		return string(res), true
	}
	return "", false
}

// small optimization: cache the context type instead of repeteadly calling reflect.Typeof
var contextType reflect.Type

var defaultStaticDirs []string

func init() {
	contextType = reflect.TypeOf(Context{})
	//find the location of the exe file
	wd, _ := os.Getwd()
	arg0 := path.Clean(os.Args[0])
	var exeFile string
	if strings.HasPrefix(arg0, "/") {
		exeFile = arg0
	} else {
		//TODO for robustness, search each directory in $PATH
		exeFile = path.Join(wd, arg0)
	}
	parent, _ := path.Split(exeFile)
	defaultStaticDirs = append(defaultStaticDirs, path.Join(parent, "static"))
	defaultStaticDirs = append(defaultStaticDirs, path.Join(wd, "static"))
	return
}

// Process invokes the main server's routing system.
func Process(c http.ResponseWriter, req *http.Request) {
	mainServer.Process(c, req)
}

// Run starts the web application and serves HTTP requests for the main server.
func Run(addr string) {
	mainServer.Run(addr)
}

// RunTLS starts the web application and serves HTTPS requests for the main server.
func RunTLS(addr string, config *tls.Config) {
	mainServer.RunTLS(addr, config)
}

// RunScgi starts the web application and serves SCGI requests for the main server.
func RunScgi(addr string) {
	mainServer.RunScgi(addr)
}

// RunFcgi starts the web application and serves FastCGI requests for the main server.
func RunFcgi(addr string) {
	mainServer.RunFcgi(addr)
}

// Close stops the main server.
func Close() {
	mainServer.Close()
}

// Get adds a handler for the 'GET' http method in the main server.
func Get(route string, handler interface{}) {
	mainServer.Get(route, handler)
}

// Post adds a handler for the 'POST' http method in the main server.
func Post(route string, handler interface{}) {
	mainServer.addRoute(route, "POST", handler)
}

// Put adds a handler for the 'PUT' http method in the main server.
func Put(route string, handler interface{}) {
	mainServer.addRoute(route, "PUT", handler)
}

// Delete adds a handler for the 'DELETE' http method in the main server.
func Delete(route string, handler interface{}) {
	mainServer.addRoute(route, "DELETE", handler)
}

// Match adds a handler for an arbitrary http method in the main server.
func Match(method string, route string, handler interface{}) {
	mainServer.addRoute(route, method, handler)
}

// Add a custom http.Handler. Will have no effect when running as FCGI or SCGI.
func Handle(route string, method string, httpHandler http.Handler) {
	mainServer.Handle(route, method, httpHandler)
}

//Adds a handler for websockets. Only for webserver mode. Will have no effect when running as FCGI or SCGI.
func Websocket(route string, httpHandler websocket.Handler) {
	mainServer.Websocket(route, httpHandler)
}

// SetLogger sets the logger for the main server.
func SetLogger(logger *log.Logger) {
	mainServer.Logger = logger
}

// Config is the configuration of the main server.
var Config = &ServerConfig{
	RecoverPanic: true,
	ColorOutput:  true,
}

var mainServer = NewServer()
<|endoftext|>


<commit_before>package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
	"github.com/ricardolonga/openv2/domain"
)

type Response struct {
	UserMessage string       `json:"userMessage"`
	User        *domain.User `json:"user"`
}

func main() {
	userRepository := &domain.UserRepository{}

	router := gin.Default()

	router.Use(HeadersRequired())

	router.GET("/", func(c *gin.Context) {
		c.String(200, fmt.Sprintf("Olá!"))
	})

	router.POST("/login", func(c *gin.Context) {
		user := &domain.User{Name: c.Request.Header.Get("name"), Email: c.Request.Header.Get("email")}
		userRepository.Save(user)
		c.JSON(http.StatusOK, &Response{UserMessage: "Login successful!", User: user})
	})

	err := http.ListenAndServe(":8080", router)
	if err != nil {
		panic(err)
	}
}

func HeadersRequired() gin.HandlerFunc {
	return func(c *gin.Context) {
		if _, contain := c.Request.Header["Name"]; !contain {
			c.JSON(http.StatusBadRequest, &Response{UserMessage: "Name is not defined into headers."})
			c.Abort()
		}

		if _, contain := c.Request.Header["Email"]; !contain {
			c.JSON(http.StatusBadRequest, &Response{UserMessage: "Email is not defined into headers."})
			c.Abort()
		}
	}
}
<commit_msg>Corrigido import.<commit_after>package main

import (
	"github.com/gin-gonic/gin"
	"github.com/ricardolonga/openv2/domain"
	"net/http"
)

type Response struct {
	UserMessage string       `json:"userMessage"`
	User        *domain.User `json:"user"`
}

func main() {
	userRepository := &domain.UserRepository{}

	router := gin.Default()

	gin.SetMode(gin.DebugMode)

	router.Use(HeadersRequired())

	router.GET("/", func(c *gin.Context) {
		c.String(200, "Olá, estou na AWS!")
	})

	router.POST("/login", func(c *gin.Context) {
		user := &domain.User{Name: c.Request.Header.Get("name"), Email: c.Request.Header.Get("email")}
		userRepository.Save(user)
		c.JSON(http.StatusOK, &Response{UserMessage: "Login successful!", User: user})
	})

	err := http.ListenAndServe(":8080", router)
	if err != nil {
		panic(err)
	}
}

func HeadersRequired() gin.HandlerFunc {
	return func(c *gin.Context) {
		if _, contain := c.Request.Header["Name"]; !contain {
			c.JSON(http.StatusBadRequest, &Response{UserMessage: "Name is not defined into headers."})
			c.Abort()
		}

		if _, contain := c.Request.Header["Email"]; !contain {
			c.JSON(http.StatusBadRequest, &Response{UserMessage: "Email is not defined into headers."})
			c.Abort()
		}
	}
}
<|endoftext|>


<commit_before>// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package helper

import (
	"encoding/json"
	"strconv"
	"testing"

	"github.com/stretchr/testify/require"
	yaml "gopkg.in/yaml.v2"
)

type testCase struct {
	input       string
	expected    ByteSize
	expectError bool
}

var sharedTestCases = []testCase{
	{`1`, 1, false},
	{`3.3`, 3, false},
	{`0`, 0, false},
	{`10101010`, 10101010, false},
	{`0.01`, 0, false},
	{`"1"`, 1, false},
	{`"1kb"`, 1000, false},
	{`"1KB"`, 1000, false},
	{`"1kib"`, 1024, false},
	{`"1KiB"`, 1024, false},
	{`"1mb"`, 1000 * 1000, false},
	{`"1mib"`, 1024 * 1024, false},
	{`"1gb"`, 1000 * 1000 * 1000, false},
	{`"1gib"`, 1024 * 1024 * 1024, false},
	{`"1tb"`, 1000 * 1000 * 1000 * 1000, false},
	{`"1tib"`, 1024 * 1024 * 1024 * 1024, false},
	{`"1pB"`, 1000 * 1000 * 1000 * 1000 * 1000, false},
	{`"1pib"`, 1024 * 1024 * 1024 * 1024 * 1024, false},
	{`1e3`, 1000, false},
	{`"3ii3"`, 0, true},
	{`3ii3`, 0, true},
	{`--ii3`, 0, true},
	{`{"test":"val"}`, 0, true},
	{`1e3`, 1000, false},
}

func TestByteSizeUnmarshalJSON(t *testing.T) {
	for i, tc := range sharedTestCases {
		t.Run(strconv.Itoa(i), func(t *testing.T) {
			var bs ByteSize
			err := json.Unmarshal([]byte(tc.input), &bs)
			if tc.expectError {
				require.Error(t, err)
				return
			}

			require.NoError(t, err)
			require.Equal(t, tc.expected, bs)
		})
	}
}

func TestByteSizeUnmarshalYAML(t *testing.T) {
	additionalCases := []testCase{
		{`1kb`, 1000, false},
		{`1KB`, 1000, false},
		{`1kib`, 1024, false},
		{`1KiB`, 1024, false},
		{`1mb`, 1000 * 1000, false},
		{`1mib`, 1024 * 1024, false},
		{`1gb`, 1000 * 1000 * 1000, false},
		{`1gib`, 1024 * 1024 * 1024, false},
		{`1tb`, 1000 * 1000 * 1000 * 1000, false},
		{`1tib`, 1024 * 1024 * 1024 * 1024, false},
		{`1pB`, 1000 * 1000 * 1000 * 1000 * 1000, false},
		{`1pib`, 1024 * 1024 * 1024 * 1024 * 1024, false},
		{`test: val`, 0, true},
	}

	cases := append(sharedTestCases, additionalCases...)
	for i, tc := range cases {
		t.Run(strconv.Itoa(i), func(t *testing.T) {
			var bs ByteSize
			err := yaml.Unmarshal([]byte(tc.input), &bs)
			if tc.expectError {
				require.Error(t, err)
				return
			}

			require.NoError(t, err)
			require.Equal(t, tc.expected, bs)
		})
	}
}
<commit_msg> Add mapstructure unmarshalling to bytesize type (#56)<commit_after>// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package helper

import (
	"encoding/json"
	"testing"

	"github.com/mitchellh/mapstructure"
	"github.com/stretchr/testify/require"
	yaml "gopkg.in/yaml.v2"
)

type testCase struct {
	input       string
	expected    ByteSize
	expectError bool
}

var sharedTestCases = []testCase{
	{`1`, 1, false},
	{`3.3`, 3, false},
	{`0`, 0, false},
	{`10101010`, 10101010, false},
	{`0.01`, 0, false},
	{`"1"`, 1, false},
	{`"1kb"`, 1000, false},
	{`"1KB"`, 1000, false},
	{`"1kib"`, 1024, false},
	{`"1KiB"`, 1024, false},
	{`"1mb"`, 1000 * 1000, false},
	{`"1mib"`, 1024 * 1024, false},
	{`"1gb"`, 1000 * 1000 * 1000, false},
	{`"1gib"`, 1024 * 1024 * 1024, false},
	{`"1tb"`, 1000 * 1000 * 1000 * 1000, false},
	{`"1tib"`, 1024 * 1024 * 1024 * 1024, false},
	{`"1pB"`, 1000 * 1000 * 1000 * 1000 * 1000, false},
	{`"1pib"`, 1024 * 1024 * 1024 * 1024 * 1024, false},
	{`"3ii3"`, 0, true},
	{`3ii3`, 0, true},
	{`--ii3`, 0, true},
	{`{"test":"val"}`, 0, true},
	// {`1e3`, 1000, false},   not supported in mapstructure
}

func TestByteSizeUnmarshalJSON(t *testing.T) {
	for _, tc := range sharedTestCases {
		t.Run("json/"+tc.input, func(t *testing.T) {
			var bs ByteSize
			err := json.Unmarshal([]byte(tc.input), &bs)
			if tc.expectError {
				require.Error(t, err)
				return
			}

			require.NoError(t, err)
			require.Equal(t, tc.expected, bs)
		})
	}
}

func TestByteSizeUnmarshalYAML(t *testing.T) {
	additionalCases := []testCase{
		{`1kb`, 1000, false},
		{`1KB`, 1000, false},
		{`1kib`, 1024, false},
		{`1KiB`, 1024, false},
		{`1mb`, 1000 * 1000, false},
		{`1mib`, 1024 * 1024, false},
		{`1gb`, 1000 * 1000 * 1000, false},
		{`1gib`, 1024 * 1024 * 1024, false},
		{`1tb`, 1000 * 1000 * 1000 * 1000, false},
		{`1tib`, 1024 * 1024 * 1024 * 1024, false},
		{`1pB`, 1000 * 1000 * 1000 * 1000 * 1000, false},
		{`1pib`, 1024 * 1024 * 1024 * 1024 * 1024, false},
		{`test: val`, 0, true},
	}

	cases := append(sharedTestCases, additionalCases...)

	for _, tc := range cases {
		t.Run("yaml/"+tc.input, func(t *testing.T) {
			var bs ByteSize
			yamlErr := yaml.Unmarshal([]byte(tc.input), &bs)
			if tc.expectError {
				require.Error(t, yamlErr)
				return
			}
			require.NoError(t, yamlErr)
			require.Equal(t, tc.expected, bs)
		})
		t.Run("mapstructure/"+tc.input, func(t *testing.T) {
			var bs ByteSize
			var raw string
			_ = yaml.Unmarshal([]byte(tc.input), &raw)

			dc := &mapstructure.DecoderConfig{Result: &bs, DecodeHook: JSONUnmarshalerHook()}
			ms, err := mapstructure.NewDecoder(dc)
			require.NoError(t, err)

			err = ms.Decode(raw)
			if tc.expectError {
				require.Error(t, err)
				return
			}
			require.NoError(t, err)

			require.Equal(t, tc.expected, bs)
		})
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"testing"
)

func TestOccur(t *testing.T) {
	cases := []struct {
		against, userinput, expected string
	}{
		{"brasil", "bra", "[[0] [1] [2]]"},
		{"brasil", "bRa", "[[0] [1] [2]]"},
		{"brasil", "sil", "[[3] [4] [5]]"},
		{"abba", "ab", "[[0 3] [1 2]]"},
		{"a", "a", "[[0]]"},
		{"abc", "", "[]"},
		{"aaa", "a", "[[0 1 2]]"},
		{"aaa", "A", "[[0 1 2]]"},
		{"abc", "x", "[]"},
		{"", "", "[]"},
	}
	for _, c := range cases {
		oc, _ := occur(c.against, c.userinput)
		soc := fmt.Sprint(oc)
		if soc != c.expected {
			t.Errorf("Occur(%q,%q) == %q, want %q", c.against, c.userinput, soc, c.expected)
		}
	}
}

func TestCombinations(t *testing.T) {
	cases := []struct {
		against, userinput, expected string
	}{
		{"abba", "ab", "[[0 1] [0 2] [3 1] [3 2]]"},
		{"ABCC", "abc", "[[0 1 2] [0 1 3]]"},
		{"aabbbcc", "abc", "[[0 2 5] [0 2 6] [0 3 5] [0 3 6] [0 4 5] [0 4 6] [1 2 5] [1 2 6] [1 3 5] [1 3 6] [1 4 5] [1 4 6]]"},
	}
	for _, c := range cases {
		all := make([][]int, 0)
		oc, _ := occur(c.against, c.userinput)
		combinations([]int{}, oc, &all)
		sall := fmt.Sprint(all)
		if sall != c.expected {
			t.Errorf("Combinations(%q,%q) == %q, want %q", c.against, c.userinput, sall, c.expected)
		}
	}
}

func TestScore(t *testing.T) {
	cases := []string{
		"zip",
		"azipa",
		"azxipo",
		"zixp",
		"zxixp",
		"zkkkkkkkkip",
		"zkkkkiidjasijdsap",
	}

	last := 0
	for _, c := range cases {
		best := score(c, "zip")
		s := best.score
		if s < 0 || s > 100 || (s < last) {
			t.Errorf("Score(%q,%q) == %d (previous %d)", c, "zip", s, last)
		}
		last = s
	}
}
<commit_msg>test is not working, must be rewritten<commit_after><|endoftext|>