mirror of https://github.com/statping/statping
http request updates - CLI updates
parent
439ffc293e
commit
76d56d5856
2
Makefile
2
Makefile
|
@ -1,4 +1,4 @@
|
|||
VERSION=0.79.87
|
||||
VERSION=0.79.88
|
||||
BINARY_NAME=statup
|
||||
GOPATH:=$(GOPATH)
|
||||
GOCMD=go
|
||||
|
|
|
@ -90,7 +90,7 @@ func catchCLI(args []string) error {
|
|||
return err
|
||||
}
|
||||
indexSource := ExportIndexHTML()
|
||||
core.CloseDB()
|
||||
//core.CloseDB()
|
||||
if err = utils.SaveFile(dir+"/index.html", indexSource); err != nil {
|
||||
utils.Log(4, err)
|
||||
return err
|
||||
|
@ -114,6 +114,7 @@ func catchCLI(args []string) error {
|
|||
if data, err = core.ExportSettings(); err != nil {
|
||||
return fmt.Errorf("could not export settings: %v", err.Error())
|
||||
}
|
||||
//core.CloseDB()
|
||||
if err = utils.SaveFile(dir+"/statup-export.json", data); err != nil {
|
||||
return fmt.Errorf("could not write file statup-export.json: %v", err.Error())
|
||||
}
|
||||
|
@ -136,7 +137,7 @@ func catchCLI(args []string) error {
|
|||
case "run":
|
||||
utils.Log(1, "Running 1 time and saving to database...")
|
||||
RunOnce()
|
||||
core.CloseDB()
|
||||
//core.CloseDB()
|
||||
fmt.Println("Check is complete.")
|
||||
return errors.New("end")
|
||||
case "env":
|
||||
|
@ -237,7 +238,7 @@ func HelpEcho() {
|
|||
func checkGithubUpdates() (githubResponse, error) {
|
||||
var gitResp githubResponse
|
||||
url := "https://api.github.com/repos/hunterlong/statup/releases/latest"
|
||||
contents, err := utils.HttpRequest(url, "GET", nil, nil, nil, time.Duration(10*time.Second))
|
||||
contents, _, err := utils.HttpRequest(url, "GET", nil, nil, nil, time.Duration(10*time.Second))
|
||||
if err != nil {
|
||||
return githubResponse{}, err
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ package main
|
|||
|
||||
import (
|
||||
"github.com/hunterlong/statup/core"
|
||||
"github.com/hunterlong/statup/source"
|
||||
"github.com/hunterlong/statup/utils"
|
||||
"github.com/rendon/testcli"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -35,7 +36,6 @@ func init() {
|
|||
}
|
||||
|
||||
func TestStartServerCommand(t *testing.T) {
|
||||
Clean()
|
||||
os.Setenv("DB_CONN", "sqlite")
|
||||
cmd := helperCommand(nil, "")
|
||||
var got = make(chan string)
|
||||
|
@ -124,12 +124,12 @@ func TestSassCLI(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestUpdateCLI(t *testing.T) {
|
||||
t.SkipNow()
|
||||
run := catchCLI([]string{"update"})
|
||||
assert.EqualError(t, run, "end")
|
||||
}
|
||||
|
||||
func TestTestPackageCLI(t *testing.T) {
|
||||
t.SkipNow()
|
||||
run := catchCLI([]string{"test", "plugins"})
|
||||
assert.EqualError(t, run, "end")
|
||||
}
|
||||
|
@ -140,7 +140,6 @@ func TestHelpCLI(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRunOnceCLI(t *testing.T) {
|
||||
t.SkipNow()
|
||||
run := catchCLI([]string{"run"})
|
||||
assert.EqualError(t, run, "end")
|
||||
}
|
||||
|
@ -148,7 +147,6 @@ func TestRunOnceCLI(t *testing.T) {
|
|||
func TestEnvCLI(t *testing.T) {
|
||||
run := catchCLI([]string{"env"})
|
||||
assert.Error(t, run)
|
||||
core.CloseDB()
|
||||
Clean()
|
||||
}
|
||||
|
||||
|
@ -169,3 +167,22 @@ func runCommand(c *exec.Cmd, out chan<- string) {
|
|||
bout, _ := c.CombinedOutput()
|
||||
out <- string(bout)
|
||||
}
|
||||
|
||||
func fileExists(file string) bool {
|
||||
if _, err := os.Stat(file); os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func Clean() {
|
||||
utils.DeleteFile(dir + "/config.yml")
|
||||
utils.DeleteFile(dir + "/statup.db")
|
||||
utils.DeleteDirectory(dir + "/assets")
|
||||
utils.DeleteDirectory(dir + "/logs")
|
||||
core.CoreApp = core.NewCore()
|
||||
source.Assets()
|
||||
//core.CloseDB()
|
||||
os.Unsetenv("DB_CONN")
|
||||
time.Sleep(2 * time.Second)
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ import (
|
|||
"github.com/hunterlong/statup/utils"
|
||||
"github.com/joho/godotenv"
|
||||
"os"
|
||||
"os/signal"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -75,13 +74,6 @@ func main() {
|
|||
}
|
||||
utils.Log(1, fmt.Sprintf("Starting Statup v%v", VERSION))
|
||||
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt)
|
||||
go func() {
|
||||
<-c
|
||||
os.Exit(1)
|
||||
}()
|
||||
|
||||
core.Configs, err = core.LoadConfigFile(utils.Directory)
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
|
|
612
cmd/main_test.go
612
cmd/main_test.go
|
@ -1,612 +0,0 @@
|
|||
// Statup
|
||||
// Copyright (C) 2018. Hunter Long and the project contributors
|
||||
// Written by Hunter Long <info@socialeck.com> and the project contributors
|
||||
//
|
||||
// https://github.com/hunterlong/statup
|
||||
//
|
||||
// The licenses for most software and other practical works are designed
|
||||
// to take away your freedom to share and change the works. By contrast,
|
||||
// the GNU General Public License is intended to guarantee your freedom to
|
||||
// share and change all versions of a program--to make sure it remains free
|
||||
// software for all its users.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/hunterlong/statup/core"
|
||||
"github.com/hunterlong/statup/core/notifier"
|
||||
"github.com/hunterlong/statup/handlers"
|
||||
"github.com/hunterlong/statup/source"
|
||||
"github.com/hunterlong/statup/types"
|
||||
"github.com/hunterlong/statup/utils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
route *mux.Router
|
||||
)
|
||||
|
||||
func init() {
|
||||
dir = utils.Directory
|
||||
}
|
||||
|
||||
func Clean() {
|
||||
utils.DeleteFile(dir + "/config.yml")
|
||||
utils.DeleteFile(dir + "/statup.db")
|
||||
utils.DeleteDirectory(dir + "/assets")
|
||||
utils.DeleteDirectory(dir + "/logs")
|
||||
}
|
||||
|
||||
func RunInit(db string, t *testing.T) {
|
||||
Clean()
|
||||
if db == "mssql" {
|
||||
os.Setenv("DB_DATABASE", "tempdb")
|
||||
os.Setenv("DB_PASS", "PaSsW0rD123")
|
||||
os.Setenv("DB_PORT", "1433")
|
||||
os.Setenv("DB_USER", "sa")
|
||||
}
|
||||
source.Assets()
|
||||
route = handlers.Router()
|
||||
core.CoreApp = core.NewCore()
|
||||
}
|
||||
|
||||
//func TestMain(m *testing.M) {
|
||||
// m.Run()
|
||||
//}
|
||||
|
||||
func TestRunAll(t *testing.T) {
|
||||
//t.Parallel()
|
||||
|
||||
databases := []string{"postgres", "sqlite", "mysql"}
|
||||
if os.Getenv("ONLY_DB") != "" {
|
||||
databases = []string{os.Getenv("ONLY_DB")}
|
||||
}
|
||||
|
||||
for _, dbt := range databases {
|
||||
t.Run(dbt+" init", func(t *testing.T) {
|
||||
RunInit(dbt, t)
|
||||
})
|
||||
t.Run(dbt+" Save Config", func(t *testing.T) {
|
||||
RunSaveConfig(t, dbt)
|
||||
})
|
||||
t.Run(dbt+" Load Configs", func(t *testing.T) {
|
||||
RunLoadConfig(t)
|
||||
})
|
||||
t.Run(dbt+" Connect to Database", func(t *testing.T) {
|
||||
err := core.Configs.Connect(false, dir)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
t.Run(dbt+" Drop Database", func(t *testing.T) {
|
||||
assert.NotNil(t, core.Configs)
|
||||
assert.NotNil(t, core.DbSession)
|
||||
assert.Nil(t, core.DbSession.DB().Ping())
|
||||
RunDropDatabase(t)
|
||||
})
|
||||
t.Run(dbt+" Connect to Database Again", func(t *testing.T) {
|
||||
err := core.Configs.Connect(false, dir)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
t.Run(dbt+" Inserting Database Structure", func(t *testing.T) {
|
||||
RunCreateSchema(t, dbt)
|
||||
})
|
||||
t.Run(dbt+" Inserting Seed Data", func(t *testing.T) {
|
||||
RunInsertSampleData(t)
|
||||
})
|
||||
t.Run(dbt+" Connect to Database Again", func(t *testing.T) {
|
||||
err := core.Configs.Connect(false, dir)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
t.Run(dbt+" Run Database Migrations", func(t *testing.T) {
|
||||
RunDatabaseMigrations(t, dbt)
|
||||
})
|
||||
t.Run(dbt+" Select Core", func(t *testing.T) {
|
||||
RunSelectCoreMYQL(t, dbt)
|
||||
})
|
||||
t.Run(dbt+" Select Services", func(t *testing.T) {
|
||||
RunSelectAllMysqlServices(t)
|
||||
})
|
||||
t.Run(dbt+" Select Comms", func(t *testing.T) {
|
||||
RunSelectAllNotifiers(t)
|
||||
})
|
||||
t.Run(dbt+" Create Users", func(t *testing.T) {
|
||||
RunUserCreate(t)
|
||||
})
|
||||
t.Run(dbt+" Update user", func(t *testing.T) {
|
||||
runUserUpdate(t)
|
||||
})
|
||||
t.Run(dbt+" Create Non Unique Users", func(t *testing.T) {
|
||||
t.SkipNow()
|
||||
runUserNonUniqueCreate(t)
|
||||
})
|
||||
t.Run(dbt+" Select Users", func(t *testing.T) {
|
||||
RunUserSelectAll(t)
|
||||
})
|
||||
t.Run(dbt+" Select Services", func(t *testing.T) {
|
||||
RunSelectAllServices(t)
|
||||
})
|
||||
t.Run(dbt+" Select One Service", func(t *testing.T) {
|
||||
RunOneServiceCheck(t)
|
||||
})
|
||||
t.Run(dbt+" Create Service", func(t *testing.T) {
|
||||
RunServiceCreate(t)
|
||||
})
|
||||
t.Run(dbt+" Create Hits", func(t *testing.T) {
|
||||
RunCreateServiceHits(t)
|
||||
})
|
||||
t.Run(dbt+" Service ToJSON()", func(t *testing.T) {
|
||||
RunServiceToJSON(t)
|
||||
})
|
||||
t.Run(dbt+" Avg Time", func(t *testing.T) {
|
||||
runServiceAvgTime(t)
|
||||
})
|
||||
t.Run(dbt+" Online 24h", func(t *testing.T) {
|
||||
RunServiceOnline24(t)
|
||||
})
|
||||
//t.Run(dbt+" Chart Data", func(t *testing.T) {
|
||||
// RunServiceGraphData(t)
|
||||
//})
|
||||
t.Run(dbt+" Create Failing Service", func(t *testing.T) {
|
||||
RunBadServiceCreate(t)
|
||||
})
|
||||
t.Run(dbt+" Check Bad Service", func(t *testing.T) {
|
||||
RunBadServiceCheck(t)
|
||||
})
|
||||
t.Run(dbt+" Select Hits", func(t *testing.T) {
|
||||
RunServiceHits(t)
|
||||
})
|
||||
t.Run(dbt+" Select Failures", func(t *testing.T) {
|
||||
RunServiceFailures(t)
|
||||
})
|
||||
t.Run(dbt+" Select Limited Hits", func(t *testing.T) {
|
||||
RunServiceLimitedHits(t)
|
||||
})
|
||||
t.Run(dbt+" Delete Service", func(t *testing.T) {
|
||||
RunDeleteService(t)
|
||||
})
|
||||
t.Run(dbt+" Delete user", func(t *testing.T) {
|
||||
RunUserDelete(t)
|
||||
})
|
||||
t.Run(dbt+" HTTP /", func(t *testing.T) {
|
||||
RunIndexHandler(t)
|
||||
})
|
||||
t.Run(dbt+" HTTP /service/1", func(t *testing.T) {
|
||||
RunServiceHandler(t)
|
||||
})
|
||||
t.Run(dbt+" HTTP /metrics", func(t *testing.T) {
|
||||
RunPrometheusHandler(t)
|
||||
})
|
||||
t.Run(dbt+" HTTP /metrics", func(t *testing.T) {
|
||||
RunFailingPrometheusHandler(t)
|
||||
})
|
||||
t.Run(dbt+" HTTP /login", func(t *testing.T) {
|
||||
RunLoginHandler(t)
|
||||
})
|
||||
t.Run(dbt+" HTTP /dashboard", func(t *testing.T) {
|
||||
RunDashboardHandler(t)
|
||||
})
|
||||
t.Run(dbt+" HTTP /users", func(t *testing.T) {
|
||||
RunUsersHandler(t)
|
||||
})
|
||||
t.Run(dbt+" HTTP /user/1", func(t *testing.T) {
|
||||
RunUserViewHandler(t)
|
||||
})
|
||||
t.Run(dbt+" HTTP /services", func(t *testing.T) {
|
||||
RunServicesHandler(t)
|
||||
})
|
||||
t.Run(dbt+" HTTP /help", func(t *testing.T) {
|
||||
RunHelpHandler(t)
|
||||
})
|
||||
t.Run(dbt+" HTTP /settings", func(t *testing.T) {
|
||||
RunSettingsHandler(t)
|
||||
})
|
||||
t.Run(dbt+" Cleanup", func(t *testing.T) {
|
||||
//core.CloseDB()
|
||||
if dbt == "mssql" {
|
||||
os.Setenv("DB_DATABASE", "root")
|
||||
os.Setenv("DB_PASS", "password123")
|
||||
os.Setenv("DB_PORT", "1433")
|
||||
}
|
||||
Clean()
|
||||
})
|
||||
|
||||
//<-done
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func RunSaveConfig(t *testing.T, db string) {
|
||||
var err error
|
||||
core.Configs = core.EnvToConfig()
|
||||
core.Configs.DbConn = db
|
||||
core.Configs, err = core.Configs.Save()
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func RunCreateSchema(t *testing.T, db string) {
|
||||
err := core.Configs.Connect(false, dir)
|
||||
assert.Nil(t, err)
|
||||
err = core.Configs.CreateDatabase()
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func RunDatabaseMigrations(t *testing.T, db string) {
|
||||
err := core.Configs.MigrateDatabase()
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func RunInsertSampleData(t *testing.T) {
|
||||
err := core.InsertLargeSampleData()
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func RunLoadConfig(t *testing.T) {
|
||||
var err error
|
||||
core.Configs, err = core.LoadConfigFile(dir)
|
||||
t.Log(core.Configs)
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, core.Configs)
|
||||
}
|
||||
|
||||
func RunDropDatabase(t *testing.T) {
|
||||
err := core.Configs.DropDatabase()
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func RunSelectCoreMYQL(t *testing.T, db string) {
|
||||
var err error
|
||||
core.CoreApp, err = core.SelectCore()
|
||||
if err != nil {
|
||||
t.FailNow()
|
||||
}
|
||||
assert.Nil(t, err)
|
||||
t.Log("core: ", core.CoreApp.Core)
|
||||
assert.Equal(t, "Statup Sample Data", core.CoreApp.Name)
|
||||
assert.Equal(t, db, core.CoreApp.DbConnection)
|
||||
assert.NotEmpty(t, core.CoreApp.ApiKey)
|
||||
assert.NotEmpty(t, core.CoreApp.ApiSecret)
|
||||
assert.Equal(t, VERSION, core.CoreApp.Version)
|
||||
}
|
||||
|
||||
func RunSelectAllMysqlServices(t *testing.T) {
|
||||
var err error
|
||||
services, err := core.CoreApp.SelectAllServices(false)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 15, len(services))
|
||||
}
|
||||
|
||||
func RunSelectAllNotifiers(t *testing.T) {
|
||||
var err error
|
||||
notifier.SetDB(core.DbSession, float32(-8))
|
||||
core.CoreApp.Notifications = notifier.Load()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 8, len(core.CoreApp.Notifications))
|
||||
}
|
||||
|
||||
func RunUserSelectAll(t *testing.T) {
|
||||
users, err := core.SelectAllUsers()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 4, len(users))
|
||||
}
|
||||
|
||||
func RunUserCreate(t *testing.T) {
|
||||
user := core.ReturnUser(&types.User{
|
||||
Username: "hunterlong",
|
||||
Password: "password123",
|
||||
Email: "info@gmail.com",
|
||||
Admin: types.NewNullBool(true),
|
||||
})
|
||||
id, err := user.Create()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, int64(3), id)
|
||||
user2 := core.ReturnUser(&types.User{
|
||||
Username: "superadmin",
|
||||
Password: "admin",
|
||||
Email: "info@adminer.com",
|
||||
Admin: types.NewNullBool(true),
|
||||
})
|
||||
id, err = user2.Create()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, int64(4), id)
|
||||
}
|
||||
|
||||
func runUserUpdate(t *testing.T) {
|
||||
user, err := core.SelectUser(1)
|
||||
user.Email = "info@updatedemail.com"
|
||||
assert.Nil(t, err)
|
||||
err = user.Update()
|
||||
assert.Nil(t, err)
|
||||
updatedUser, err := core.SelectUser(1)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "info@updatedemail.com", updatedUser.Email)
|
||||
}
|
||||
|
||||
func runUserNonUniqueCreate(t *testing.T) {
|
||||
user := core.ReturnUser(&types.User{
|
||||
Username: "admin",
|
||||
Password: "admin",
|
||||
Email: "info@testuser.com",
|
||||
})
|
||||
admin, err := user.Create()
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, admin)
|
||||
}
|
||||
|
||||
func RunUserDelete(t *testing.T) {
|
||||
user, err := core.SelectUser(2)
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, user)
|
||||
err = user.Delete()
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func RunSelectAllServices(t *testing.T) {
|
||||
var err error
|
||||
services, err := core.CoreApp.SelectAllServices(false)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 15, len(services))
|
||||
for _, s := range services {
|
||||
assert.NotEmpty(t, s.CreatedAt)
|
||||
}
|
||||
}
|
||||
|
||||
func RunOneServiceCheck(t *testing.T) {
|
||||
service := core.SelectService(1)
|
||||
assert.NotNil(t, service)
|
||||
assert.Equal(t, "Google", service.Name)
|
||||
}
|
||||
|
||||
func RunServiceCreate(t *testing.T) {
|
||||
service := core.ReturnService(&types.Service{
|
||||
Name: "test service",
|
||||
Domain: "https://google.com",
|
||||
ExpectedStatus: 200,
|
||||
Interval: 1,
|
||||
Port: 0,
|
||||
Type: "http",
|
||||
Method: "GET",
|
||||
Timeout: 30,
|
||||
})
|
||||
id, err := service.Create(false)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, int64(16), id)
|
||||
}
|
||||
|
||||
func RunServiceToJSON(t *testing.T) {
|
||||
service := core.SelectService(1)
|
||||
assert.NotNil(t, service)
|
||||
jsoned := service.ToJSON()
|
||||
assert.NotEmpty(t, jsoned)
|
||||
}
|
||||
|
||||
func runServiceAvgTime(t *testing.T) {
|
||||
service := core.SelectService(1)
|
||||
assert.NotNil(t, service)
|
||||
avg := service.AvgUptime24()
|
||||
assert.Equal(t, "100", avg)
|
||||
}
|
||||
|
||||
func RunServiceOnline24(t *testing.T) {
|
||||
var dayAgo = time.Now().Add(-24 * time.Hour).Add(-10 * time.Minute)
|
||||
|
||||
service := core.SelectService(1)
|
||||
assert.NotNil(t, service)
|
||||
online := service.OnlineSince(dayAgo)
|
||||
assert.NotEqual(t, float32(0), online)
|
||||
|
||||
service = core.SelectService(6)
|
||||
assert.NotNil(t, service)
|
||||
online = service.OnlineSince(dayAgo)
|
||||
assert.Equal(t, float32(100), online)
|
||||
|
||||
service = core.SelectService(13)
|
||||
assert.NotNil(t, service)
|
||||
online = service.OnlineSince(dayAgo)
|
||||
assert.True(t, online > 99)
|
||||
|
||||
service = core.SelectService(14)
|
||||
assert.NotNil(t, service)
|
||||
online = service.OnlineSince(dayAgo)
|
||||
assert.True(t, online > float32(49.00))
|
||||
}
|
||||
|
||||
func RunBadServiceCreate(t *testing.T) {
|
||||
service := core.ReturnService(&types.Service{
|
||||
Name: "Bad Service",
|
||||
Domain: "https://9839f83h72gey2g29278hd2od2d.com",
|
||||
ExpectedStatus: 200,
|
||||
Interval: 10,
|
||||
Port: 0,
|
||||
Type: "http",
|
||||
Method: "GET",
|
||||
Timeout: 30,
|
||||
})
|
||||
id, err := service.Create(false)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, int64(17), id)
|
||||
}
|
||||
|
||||
func RunBadServiceCheck(t *testing.T) {
|
||||
service := core.SelectService(17)
|
||||
assert.NotNil(t, service)
|
||||
assert.Equal(t, "Bad Service", service.Name)
|
||||
for i := 0; i <= 10; i++ {
|
||||
service.Check(true)
|
||||
}
|
||||
assert.True(t, service.IsRunning())
|
||||
}
|
||||
|
||||
func RunDeleteService(t *testing.T) {
|
||||
service := core.SelectService(4)
|
||||
assert.NotNil(t, service)
|
||||
assert.Equal(t, "JSON API Tester", service.Name)
|
||||
assert.False(t, service.IsRunning())
|
||||
err := service.Delete()
|
||||
assert.False(t, service.IsRunning())
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func RunCreateServiceHits(t *testing.T) {
|
||||
services := core.CoreApp.Services
|
||||
assert.NotNil(t, services)
|
||||
assert.Equal(t, 16, len(services))
|
||||
for _, service := range services {
|
||||
service.Check(true)
|
||||
assert.NotNil(t, service)
|
||||
}
|
||||
}
|
||||
|
||||
func RunServiceHits(t *testing.T) {
|
||||
service := core.SelectService(1)
|
||||
assert.NotNil(t, service)
|
||||
hits, err := service.Hits()
|
||||
assert.Nil(t, err)
|
||||
assert.NotZero(t, len(hits))
|
||||
}
|
||||
|
||||
func RunServiceFailures(t *testing.T) {
|
||||
service := core.SelectService(17)
|
||||
assert.NotNil(t, service)
|
||||
assert.Equal(t, "Bad Service", service.Name)
|
||||
assert.NotEmpty(t, service.AllFailures())
|
||||
}
|
||||
|
||||
func RunServiceLimitedHits(t *testing.T) {
|
||||
service := core.SelectService(1)
|
||||
assert.NotNil(t, service)
|
||||
hits, err := service.LimitedHits()
|
||||
assert.Nil(t, err)
|
||||
assert.NotZero(t, len(hits))
|
||||
}
|
||||
|
||||
func RunIndexHandler(t *testing.T) {
|
||||
req, err := http.NewRequest("GET", "/", nil)
|
||||
assert.Nil(t, err)
|
||||
rr := httptest.NewRecorder()
|
||||
route.ServeHTTP(rr, req)
|
||||
assert.True(t, strings.Contains(rr.Body.String(), "Statup"))
|
||||
assert.True(t, strings.Contains(rr.Body.String(), "footer"))
|
||||
}
|
||||
|
||||
func RunServiceHandler(t *testing.T) {
|
||||
req, err := http.NewRequest("GET", "/service/1", nil)
|
||||
assert.Nil(t, err)
|
||||
rr := httptest.NewRecorder()
|
||||
route.ServeHTTP(rr, req)
|
||||
assert.True(t, strings.Contains(rr.Body.String(), "<title>Google Status</title>"))
|
||||
assert.True(t, strings.Contains(rr.Body.String(), "footer"))
|
||||
}
|
||||
|
||||
func RunPrometheusHandler(t *testing.T) {
|
||||
req, err := http.NewRequest("GET", "/metrics", nil)
|
||||
req.Header.Set("Authorization", core.CoreApp.ApiSecret)
|
||||
assert.Nil(t, err)
|
||||
rr := httptest.NewRecorder()
|
||||
route.ServeHTTP(rr, req)
|
||||
t.Log(rr.Body.String())
|
||||
assert.True(t, strings.Contains(rr.Body.String(), "statup_total_services 16"))
|
||||
assert.True(t, handlers.IsAuthenticated(req))
|
||||
}
|
||||
|
||||
func RunFailingPrometheusHandler(t *testing.T) {
|
||||
req, err := http.NewRequest("GET", "/metrics", nil)
|
||||
assert.Nil(t, err)
|
||||
rr := httptest.NewRecorder()
|
||||
route.ServeHTTP(rr, req)
|
||||
assert.Equal(t, 303, rr.Result().StatusCode)
|
||||
assert.True(t, handlers.IsAuthenticated(req))
|
||||
}
|
||||
|
||||
func RunLoginHandler(t *testing.T) {
|
||||
form := url.Values{}
|
||||
form.Add("username", "admin")
|
||||
form.Add("password", "password123")
|
||||
req, err := http.NewRequest("POST", "/dashboard", strings.NewReader(form.Encode()))
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
assert.Nil(t, err)
|
||||
rr := httptest.NewRecorder()
|
||||
route.ServeHTTP(rr, req)
|
||||
assert.Equal(t, 200, rr.Result().StatusCode)
|
||||
assert.True(t, handlers.IsAuthenticated(req))
|
||||
}
|
||||
|
||||
func RunDashboardHandler(t *testing.T) {
|
||||
req, err := http.NewRequest("GET", "/dashboard", nil)
|
||||
assert.Nil(t, err)
|
||||
rr := httptest.NewRecorder()
|
||||
route.ServeHTTP(rr, req)
|
||||
assert.True(t, strings.Contains(rr.Body.String(), "<title>Statup | Dashboard</title>"))
|
||||
assert.True(t, strings.Contains(rr.Body.String(), "footer"))
|
||||
assert.True(t, handlers.IsAuthenticated(req))
|
||||
}
|
||||
|
||||
func RunUsersHandler(t *testing.T) {
|
||||
req, err := http.NewRequest("GET", "/users", nil)
|
||||
assert.Nil(t, err)
|
||||
rr := httptest.NewRecorder()
|
||||
route.ServeHTTP(rr, req)
|
||||
t.Log(rr.Body.String())
|
||||
assert.True(t, strings.Contains(rr.Body.String(), "<title>Statup | Users</title>"))
|
||||
assert.True(t, strings.Contains(rr.Body.String(), "footer"))
|
||||
assert.True(t, handlers.IsAuthenticated(req))
|
||||
}
|
||||
|
||||
func RunUserViewHandler(t *testing.T) {
|
||||
req, err := http.NewRequest("GET", "/user/1", nil)
|
||||
assert.Nil(t, err)
|
||||
rr := httptest.NewRecorder()
|
||||
route.ServeHTTP(rr, req)
|
||||
t.Log(rr.Body.String())
|
||||
assert.True(t, strings.Contains(rr.Body.String(), "<title>Statup | testadmin</title>"))
|
||||
assert.True(t, strings.Contains(rr.Body.String(), "footer"))
|
||||
assert.True(t, handlers.IsAuthenticated(req))
|
||||
}
|
||||
|
||||
func RunServicesHandler(t *testing.T) {
|
||||
req, err := http.NewRequest("GET", "/services", nil)
|
||||
assert.Nil(t, err)
|
||||
rr := httptest.NewRecorder()
|
||||
route.ServeHTTP(rr, req)
|
||||
assert.True(t, strings.Contains(rr.Body.String(), "<title>Statup | Services</title>"))
|
||||
assert.True(t, strings.Contains(rr.Body.String(), "footer"))
|
||||
assert.True(t, handlers.IsAuthenticated(req))
|
||||
}
|
||||
|
||||
func RunHelpHandler(t *testing.T) {
|
||||
req, err := http.NewRequest("GET", "/help", nil)
|
||||
assert.Nil(t, err)
|
||||
rr := httptest.NewRecorder()
|
||||
route.ServeHTTP(rr, req)
|
||||
assert.True(t, strings.Contains(rr.Body.String(), "<title>Statup | Help</title>"))
|
||||
assert.True(t, strings.Contains(rr.Body.String(), "footer"))
|
||||
assert.True(t, handlers.IsAuthenticated(req))
|
||||
}
|
||||
|
||||
func RunSettingsHandler(t *testing.T) {
|
||||
req, err := http.NewRequest("GET", "/settings", nil)
|
||||
assert.Nil(t, err)
|
||||
rr := httptest.NewRecorder()
|
||||
route.ServeHTTP(rr, req)
|
||||
assert.True(t, strings.Contains(rr.Body.String(), "<title>Statup | Settings</title>"))
|
||||
assert.True(t, strings.Contains(rr.Body.String(), "Theme Editor"))
|
||||
assert.True(t, strings.Contains(rr.Body.String(), "footer"))
|
||||
assert.True(t, handlers.IsAuthenticated(req))
|
||||
}
|
||||
|
||||
func fileExists(file string) bool {
|
||||
if _, err := os.Stat(file); os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
|
@ -17,12 +17,10 @@ package core
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"github.com/hunterlong/statup/core/notifier"
|
||||
"github.com/hunterlong/statup/types"
|
||||
"github.com/hunterlong/statup/utils"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
@ -159,22 +157,14 @@ func (s *Service) checkHttp(record bool) *Service {
|
|||
}
|
||||
s.PingTime = dnsLookup
|
||||
t1 := time.Now()
|
||||
timeout := time.Duration(time.Duration(s.Timeout) * time.Second)
|
||||
transport := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
},
|
||||
TLSHandshakeTimeout: timeout,
|
||||
}
|
||||
client := &http.Client{
|
||||
Transport: transport,
|
||||
Timeout: timeout,
|
||||
}
|
||||
var response *http.Response
|
||||
|
||||
timeout := time.Duration(s.Timeout) * time.Second
|
||||
var content []byte
|
||||
var res *http.Response
|
||||
if s.Method == "POST" {
|
||||
response, err = client.Post(s.Domain, "application/json", bytes.NewBuffer([]byte(s.PostData.String)))
|
||||
content, res, err = utils.HttpRequest(s.Domain, s.Method, "application/json", nil, bytes.NewBuffer([]byte(s.PostData.String)), timeout)
|
||||
} else {
|
||||
response, err = client.Get(s.Domain)
|
||||
content, res, err = utils.HttpRequest(s.Domain, s.Method, nil, nil, nil, timeout)
|
||||
}
|
||||
if err != nil {
|
||||
if record {
|
||||
|
@ -182,8 +172,6 @@ func (s *Service) checkHttp(record bool) *Service {
|
|||
}
|
||||
return s
|
||||
}
|
||||
response.Header.Set("Connection", "close")
|
||||
response.Header.Set("User-Agent", "StatupMonitor")
|
||||
t2 := time.Now()
|
||||
s.Latency = t2.Sub(t1).Seconds()
|
||||
if err != nil {
|
||||
|
@ -192,16 +180,14 @@ func (s *Service) checkHttp(record bool) *Service {
|
|||
}
|
||||
return s
|
||||
}
|
||||
defer response.Body.Close()
|
||||
contents, err := ioutil.ReadAll(response.Body)
|
||||
s.LastResponse = string(contents)
|
||||
s.LastStatusCode = response.StatusCode
|
||||
s.LastResponse = string(content)
|
||||
s.LastStatusCode = res.StatusCode
|
||||
|
||||
if s.Expected.String != "" {
|
||||
if err != nil {
|
||||
utils.Log(2, err)
|
||||
}
|
||||
match, err := regexp.MatchString(s.Expected.String, string(contents))
|
||||
match, err := regexp.MatchString(s.Expected.String, string(content))
|
||||
if err != nil {
|
||||
utils.Log(2, err)
|
||||
}
|
||||
|
@ -212,9 +198,9 @@ func (s *Service) checkHttp(record bool) *Service {
|
|||
return s
|
||||
}
|
||||
}
|
||||
if s.ExpectedStatus != response.StatusCode {
|
||||
if s.ExpectedStatus != res.StatusCode {
|
||||
if record {
|
||||
recordFailure(s, fmt.Sprintf("HTTP Status Code %v did not match %v", response.StatusCode, s.ExpectedStatus))
|
||||
recordFailure(s, fmt.Sprintf("HTTP Status Code %v did not match %v", res.StatusCode, s.ExpectedStatus))
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
|
|
@ -85,7 +85,7 @@ func messagesDb() *gorm.DB {
|
|||
// HitsBetween returns the gorm database query for a collection of service hits between a time range
|
||||
func (s *Service) HitsBetween(t1, t2 time.Time, group string, column string) *gorm.DB {
|
||||
selector := Dbtimestamp(group, column)
|
||||
if Configs.DbConn == "postgres" {
|
||||
if CoreApp.DbConnection == "postgres" {
|
||||
timeQuery := fmt.Sprintf("service = %v AND created_at BETWEEN '%v.000000' AND '%v.000000'", s.Id, t1.UTC().Format(types.POSTGRES_TIME), t2.UTC().Format(types.POSTGRES_TIME))
|
||||
return DbSession.Model(&types.Hit{}).Select(selector).Where(timeQuery)
|
||||
} else {
|
||||
|
|
|
@ -164,7 +164,7 @@ func insertSampleCore() error {
|
|||
}
|
||||
|
||||
// insertSampleUsers will create 2 admin users for a seed database
|
||||
func insertSampleUsers() {
|
||||
func insertSampleUsers() error {
|
||||
u2 := ReturnUser(&types.User{
|
||||
Username: "testadmin",
|
||||
Password: "password123",
|
||||
|
@ -179,11 +179,12 @@ func insertSampleUsers() {
|
|||
Admin: types.NewNullBool(true),
|
||||
})
|
||||
|
||||
u2.Create()
|
||||
u3.Create()
|
||||
_, err := u2.Create()
|
||||
_, err = u3.Create()
|
||||
return err
|
||||
}
|
||||
|
||||
func insertMessages() {
|
||||
func insertMessages() error {
|
||||
m1 := ReturnMessage(&types.Message{
|
||||
Title: "Routine Downtime",
|
||||
Description: "This is an example a upcoming message for a service!",
|
||||
|
@ -191,8 +192,9 @@ func insertMessages() {
|
|||
StartOn: time.Now().Add(15 * time.Minute),
|
||||
EndOn: time.Now().Add(2 * time.Hour),
|
||||
})
|
||||
m1.Create()
|
||||
|
||||
if _, err := m1.Create(); err != nil {
|
||||
return err
|
||||
}
|
||||
m2 := ReturnMessage(&types.Message{
|
||||
Title: "Server Reboot",
|
||||
Description: "This is another example a upcoming message for a service!",
|
||||
|
@ -200,16 +202,29 @@ func insertMessages() {
|
|||
StartOn: time.Now().Add(15 * time.Minute),
|
||||
EndOn: time.Now().Add(2 * time.Hour),
|
||||
})
|
||||
m2.Create()
|
||||
if _, err := m2.Create(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// InsertLargeSampleData will create the example/dummy services for testing the Statup server
|
||||
func InsertLargeSampleData() error {
|
||||
insertSampleCore()
|
||||
InsertSampleData()
|
||||
insertSampleUsers()
|
||||
insertSampleCheckins()
|
||||
insertMessages()
|
||||
if err := insertSampleCore(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := InsertSampleData(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := insertSampleUsers(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := insertSampleCheckins(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := insertMessages(); err != nil {
|
||||
return err
|
||||
}
|
||||
s6 := ReturnService(&types.Service{
|
||||
Name: "JSON Lint",
|
||||
Domain: "https://jsonlint.com",
|
||||
|
|
|
@ -268,7 +268,7 @@ func GraphDataRaw(service types.ServiceInterface, start, end time.Time, group st
|
|||
return &DateScanObj{[]DateScan{}}
|
||||
}
|
||||
model = model.Order("timeframe asc", false).Group("timeframe")
|
||||
rows, err := model.Debug().Rows()
|
||||
rows, err := model.Rows()
|
||||
if err != nil {
|
||||
utils.Log(3, fmt.Errorf("issue fetching service chart data: %v", err))
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ func init() {
|
|||
// Send will send a HTTP Post to the discord API. It accepts type: []byte
|
||||
func (u *discord) Send(msg interface{}) error {
|
||||
message := msg.(string)
|
||||
_, err := utils.HttpRequest(discorder.GetValue("host"), "POST", "application/json", nil, strings.NewReader(message), time.Duration(10*time.Second))
|
||||
_, _, err := utils.HttpRequest(discorder.GetValue("host"), "POST", "application/json", nil, strings.NewReader(message), time.Duration(10*time.Second))
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ func (u *discord) OnSave() error {
|
|||
func (u *discord) OnTest() error {
|
||||
outError := errors.New("Incorrect discord URL, please confirm URL is correct")
|
||||
message := `{"content": "Testing the discord notifier"}`
|
||||
contents, err := utils.HttpRequest(discorder.Host, "POST", "application/json", nil, bytes.NewBuffer([]byte(message)), time.Duration(10*time.Second))
|
||||
contents, _, err := utils.HttpRequest(discorder.Host, "POST", "application/json", nil, bytes.NewBuffer([]byte(message)), time.Duration(10*time.Second))
|
||||
if string(contents) == "" {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ func (u *lineNotifier) Send(msg interface{}) error {
|
|||
v := url.Values{}
|
||||
v.Set("message", message)
|
||||
headers := []string{fmt.Sprintf("Authorization=Bearer %v", u.GetValue("api_secret"))}
|
||||
_, err := utils.HttpRequest("https://notify-api.line.me/api/notify", "POST", "application/x-www-form-urlencoded", headers, strings.NewReader(v.Encode()), time.Duration(10*time.Second))
|
||||
_, _, err := utils.HttpRequest("https://notify-api.line.me/api/notify", "POST", "application/x-www-form-urlencoded", headers, strings.NewReader(v.Encode()), time.Duration(10*time.Second))
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ var mobile = &mobilePush{¬ifier.Notification{
|
|||
Method: "mobile",
|
||||
Title: "Mobile Notifications",
|
||||
Description: `Receive push notifications on your Android or iPhone devices using the Statup App. You can scan the Authentication QR Code found in Settings to get the mobile app setup in seconds.
|
||||
<p align="center"><a href="https://play.google.com/store/apps/details?id=com.statup"><img src="https://img.cjx.io/google-play.svg"></a> <a href="#"><img src="https://img.cjx.io/app-store-badge.svg"></a></p>`,
|
||||
<p align="center"><a href="https://play.google.com/store/apps/details?id=com.statup"><img src="https://img.cjx.io/google-play.svg"></a> <a href="https://testflight.apple.com/join/TuBIj25Q"><img src="https://img.cjx.io/app-store-badge.svg"></a></p>`,
|
||||
Author: "Hunter Long",
|
||||
AuthorUrl: "https://github.com/hunterlong",
|
||||
Delay: time.Duration(5 * time.Second),
|
||||
|
|
|
@ -85,7 +85,7 @@ func init() {
|
|||
// Send will send a HTTP Post to the slack webhooker API. It accepts type: string
|
||||
func (u *slack) Send(msg interface{}) error {
|
||||
message := msg.(string)
|
||||
_, err := utils.HttpRequest(u.Host, "POST", "application/json", nil, strings.NewReader(message), time.Duration(10*time.Second))
|
||||
_, _, err := utils.HttpRequest(u.Host, "POST", "application/json", nil, strings.NewReader(message), time.Duration(10*time.Second))
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ func (u *slack) Select() *notifier.Notification {
|
|||
}
|
||||
|
||||
func (u *slack) OnTest() error {
|
||||
contents, err := utils.HttpRequest(u.Host, "POST", "application/json", nil, bytes.NewBuffer([]byte(`{"text":"testing message"}`)), time.Duration(10*time.Second))
|
||||
contents, _, err := utils.HttpRequest(u.Host, "POST", "application/json", nil, bytes.NewBuffer([]byte(`{"text":"testing message"}`)), time.Duration(10*time.Second))
|
||||
if string(contents) != "ok" {
|
||||
return errors.New("The slack response was incorrect, check the URL")
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ func (u *twilio) Send(msg interface{}) error {
|
|||
v.Set("Body", message)
|
||||
rb := *strings.NewReader(v.Encode())
|
||||
|
||||
contents, err := utils.HttpRequest(twilioUrl, "POST", "application/x-www-form-urlencoded", nil, &rb, time.Duration(10*time.Second))
|
||||
contents, _, err := utils.HttpRequest(twilioUrl, "POST", "application/x-www-form-urlencoded", nil, &rb, time.Duration(10*time.Second))
|
||||
success, _ := twilioSuccess(contents)
|
||||
if !success {
|
||||
errorOut := twilioError(contents)
|
||||
|
|
|
@ -6,14 +6,14 @@
|
|||
|
||||
{{range $n.Form}}
|
||||
<div class="form-group">
|
||||
<label class="text-capitalize{{if .Hidden}} d-none{{end}}" for="{{underscore .Title}}">{{.Title}}</label>
|
||||
<label class="text-capitalize{{if .IsHidden}} d-none{{end}}" for="{{underscore .Title}}">{{.Title}}</label>
|
||||
{{if eq .Type "textarea"}}
|
||||
<textarea rows="3" class="form-control{{if .Hidden}} d-none{{end}}" name="{{underscore .DbField}}" id="{{underscore .Title}}">{{ $n.GetValue .DbField }}</textarea>
|
||||
<textarea rows="3" class="form-control{{if .IsHidden}} d-none{{end}}" name="{{underscore .DbField}}" id="{{underscore .Title}}">{{ $n.GetValue .DbField }}</textarea>
|
||||
{{else}}
|
||||
<input type="{{.Type}}" name="{{underscore .DbField}}" class="form-control{{if .Hidden}} d-none{{end}}" value="{{ $n.GetValue .DbField }}" id="{{underscore .Title}}" placeholder="{{.Placeholder}}" {{if .Required}}required{{end}}>
|
||||
<input type="{{.Type}}" name="{{underscore .DbField}}" class="form-control{{if .IsHidden}} d-none{{end}}" value="{{ $n.GetValue .DbField }}" id="{{underscore .Title}}" placeholder="{{.Placeholder}}" {{if .Required}}required{{end}}>
|
||||
{{end}}
|
||||
{{if .SmallText}}
|
||||
<small class="form-text text-muted{{if .Hidden}} d-none{{end}}">{{safe .SmallText}}</small>
|
||||
<small class="form-text text-muted{{if .IsHidden}} d-none{{end}}">{{safe .SmallText}}</small>
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
|
|
@ -225,37 +225,37 @@ func SaveFile(filename string, data []byte) error {
|
|||
}
|
||||
|
||||
// HttpRequest is a global function to send a HTTP request
|
||||
func HttpRequest(url, method string, content interface{}, headers []string, body io.Reader, timeout time.Duration) ([]byte, error) {
|
||||
func HttpRequest(url, method string, content interface{}, headers []string, body io.Reader, timeout time.Duration) ([]byte, *http.Response, error) {
|
||||
var err error
|
||||
var contentType string
|
||||
if content != nil {
|
||||
contentType = content.(string)
|
||||
}
|
||||
transport := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
},
|
||||
TLSHandshakeTimeout: timeout,
|
||||
DisableKeepAlives: true,
|
||||
ResponseHeaderTimeout: timeout,
|
||||
TLSHandshakeTimeout: timeout,
|
||||
}
|
||||
client := &http.Client{
|
||||
Transport: transport,
|
||||
Timeout: timeout,
|
||||
}
|
||||
var response *http.Response
|
||||
response.Header.Set("User-Agent", "Statup")
|
||||
r := new(http.Request)
|
||||
for _, h := range headers {
|
||||
keyVal := strings.Split(h, "=")
|
||||
response.Header.Add(keyVal[0], keyVal[1])
|
||||
r.Header.Add(keyVal[0], keyVal[1])
|
||||
}
|
||||
if method == "POST" {
|
||||
response, err = client.Post(url, contentType, body)
|
||||
} else {
|
||||
response, err = client.Get(url)
|
||||
if r, err = http.NewRequest(method, url, body); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
r.Header.Set("User-Agent", "Statup")
|
||||
if content != nil {
|
||||
r.Header.Set("Content-Type", content.(string))
|
||||
}
|
||||
defer response.Body.Close()
|
||||
contents, err := ioutil.ReadAll(response.Body)
|
||||
return contents, err
|
||||
var resp *http.Response
|
||||
if resp, err = client.Do(r); err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
contents, err := ioutil.ReadAll(resp.Body)
|
||||
return contents, resp, err
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue