working commit
This commit is contained in:
+57
-57
@@ -77,6 +77,63 @@ func (oper *Operator) CreateAccount(ctx context.Context, params *CreateAccountPa
|
|||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GetAccountParams struct {
|
||||||
|
Username string `json:"username"`
|
||||||
|
AccountID string `json:"accountId"`
|
||||||
|
}
|
||||||
|
type GetAccountResult struct {
|
||||||
|
Account *descr.AccountShort `json:"account"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (oper *Operator) GetAccount(ctx context.Context, params *GetAccountParams) (*GetAccountResult, error) {
|
||||||
|
var err error
|
||||||
|
res := &GetAccountResult{}
|
||||||
|
|
||||||
|
var accountDescr *descr.Account
|
||||||
|
var accountExists bool
|
||||||
|
switch {
|
||||||
|
case params.AccountID != "":
|
||||||
|
accountExists, accountDescr, err = oper.mdb.GetAccountByID(ctx, params.AccountID)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
if !accountExists {
|
||||||
|
err := fmt.Errorf("Account with ID %s dont exists", params.AccountID)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
case params.Username != "":
|
||||||
|
accountExists, accountDescr, err = oper.mdb.GetAccountByUsername(ctx, params.Username)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
if !accountExists {
|
||||||
|
err := fmt.Errorf("Account with name %s dont exists", params.Username)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
accountShort := &descr.AccountShort{
|
||||||
|
Username: accountDescr.Username,
|
||||||
|
Disabled: accountDescr.Disabled,
|
||||||
|
CreatedAt: accountDescr.CreatedAt,
|
||||||
|
UpdatedAt: accountDescr.UpdatedAt,
|
||||||
|
Grants: make([]descr.GrantShort, 0),
|
||||||
|
}
|
||||||
|
grantDescrs, err := oper.mdb.ListGrantsByAccountID(ctx, accountDescr.ID)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
for _, grantDescrs := range grantDescrs {
|
||||||
|
grantShorts := descr.GrantShort{
|
||||||
|
Operation: grantDescrs.Operation,
|
||||||
|
CreatedAt: grantDescrs.CreatedAt,
|
||||||
|
}
|
||||||
|
accountShort.Grants = append(accountShort.Grants, grantShorts)
|
||||||
|
}
|
||||||
|
|
||||||
|
res.Account = accountShort
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
type UpdateAccountParams struct {
|
type UpdateAccountParams struct {
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
AccountID string `json:"accountId"`
|
AccountID string `json:"accountId"`
|
||||||
@@ -216,60 +273,3 @@ func (oper *Operator) ListAccounts(ctx context.Context, params *ListAccountsPara
|
|||||||
}
|
}
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetAccountParams struct {
|
|
||||||
Username string `json:"username"`
|
|
||||||
AccountID string `json:"accountId"`
|
|
||||||
}
|
|
||||||
type GetAccountResult struct {
|
|
||||||
Account *descr.AccountShort `json:"account"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (oper *Operator) GetAccount(ctx context.Context, params *GetAccountParams) (*GetAccountResult, error) {
|
|
||||||
var err error
|
|
||||||
res := &GetAccountResult{}
|
|
||||||
|
|
||||||
var accountDescr *descr.Account
|
|
||||||
var accountExists bool
|
|
||||||
switch {
|
|
||||||
case params.AccountID != "":
|
|
||||||
accountExists, accountDescr, err = oper.mdb.GetAccountByID(ctx, params.AccountID)
|
|
||||||
if err != nil {
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
if !accountExists {
|
|
||||||
err := fmt.Errorf("Account with ID %s dont exists", params.AccountID)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
case params.Username != "":
|
|
||||||
accountExists, accountDescr, err = oper.mdb.GetAccountByUsername(ctx, params.Username)
|
|
||||||
if err != nil {
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
if !accountExists {
|
|
||||||
err := fmt.Errorf("Account with name %s dont exists", params.Username)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
accountShort := &descr.AccountShort{
|
|
||||||
Username: accountDescr.Username,
|
|
||||||
Disabled: accountDescr.Disabled,
|
|
||||||
CreatedAt: accountDescr.CreatedAt,
|
|
||||||
UpdatedAt: accountDescr.UpdatedAt,
|
|
||||||
Grants: make([]descr.GrantShort, 0),
|
|
||||||
}
|
|
||||||
grantDescrs, err := oper.mdb.ListGrantsByAccountID(ctx, accountDescr.ID)
|
|
||||||
if err != nil {
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
for _, grantDescrs := range grantDescrs {
|
|
||||||
grantShorts := descr.GrantShort{
|
|
||||||
Operation: grantDescrs.Operation,
|
|
||||||
CreatedAt: grantDescrs.CreatedAt,
|
|
||||||
}
|
|
||||||
accountShort.Grants = append(accountShort.Grants, grantShorts)
|
|
||||||
}
|
|
||||||
|
|
||||||
res.Account = accountShort
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|||||||
+10
-10
@@ -99,17 +99,17 @@ func (svc *Service) Build() error {
|
|||||||
svc.rout.Get(`/v2/{name}/tags/list`, svc.hand.GetTags)
|
svc.rout.Get(`/v2/{name}/tags/list`, svc.hand.GetTags)
|
||||||
svc.rout.Get(`/v2/{name}/referrers/{digest}`, svc.hand.GetReferer)
|
svc.rout.Get(`/v2/{name}/referrers/{digest}`, svc.hand.GetReferer)
|
||||||
|
|
||||||
svc.rout.Post(`/v3/account/create`, svc.hand.CreateAccount)
|
svc.rout.Post(`/v3/api/account/create`, svc.hand.CreateAccount)
|
||||||
svc.rout.Post(`/v3/account/get`, svc.hand.GetAccount)
|
svc.rout.Post(`/v3/api/account/get`, svc.hand.GetAccount)
|
||||||
svc.rout.Post(`/v3/account/update`, svc.hand.UpdateAccount)
|
svc.rout.Post(`/v3/api/account/update`, svc.hand.UpdateAccount)
|
||||||
svc.rout.Post(`/v3/account/delete`, svc.hand.DeleteAccount)
|
svc.rout.Post(`/v3/api/account/delete`, svc.hand.DeleteAccount)
|
||||||
svc.rout.Post(`/v3/accounts/list`, svc.hand.ListAccounts)
|
svc.rout.Post(`/v3/api/accounts/list`, svc.hand.ListAccounts)
|
||||||
|
|
||||||
svc.rout.Post(`/v3/grant/create`, svc.hand.CreateGrant)
|
svc.rout.Post(`/v3/api/grant/create`, svc.hand.CreateGrant)
|
||||||
svc.rout.Post(`/v3/grant/get`, svc.hand.GetGrant)
|
svc.rout.Post(`/v3/api/grant/get`, svc.hand.GetGrant)
|
||||||
svc.rout.Post(`/v3/grant/update`, svc.hand.UpdateGrant)
|
svc.rout.Post(`/v3/api/grant/update`, svc.hand.UpdateGrant)
|
||||||
svc.rout.Post(`/v3/grant/delete`, svc.hand.DeleteGrant)
|
svc.rout.Post(`/v3/api/grant/delete`, svc.hand.DeleteGrant)
|
||||||
svc.rout.Post(`/v3/grants/list`, svc.hand.ListGrants)
|
svc.rout.Post(`/v3/api/grants/list`, svc.hand.ListGrants)
|
||||||
|
|
||||||
svc.rout.NotFound(svc.hand.NotFound)
|
svc.rout.NotFound(svc.hand.NotFound)
|
||||||
|
|
||||||
|
|||||||
+49
-14
@@ -15,16 +15,18 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
|
"mstore/app/descr"
|
||||||
"mstore/app/handler"
|
"mstore/app/handler"
|
||||||
"mstore/app/operator"
|
"mstore/app/operator"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (cli *Client) CreateAccount(ctx context.Context, hosturi, username, password string) error {
|
func (cli *Client) CreateAccount(ctx context.Context, hosturi, username, password string) (string, error) {
|
||||||
var err error
|
var err error
|
||||||
|
var res string
|
||||||
|
|
||||||
apiuri, err := url.JoinPath(hosturi, "/v3/api/account/create")
|
apiuri, err := setApiPath(hosturi, "/v3/api/account/create")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return res, err
|
||||||
}
|
}
|
||||||
operParams := operator.CreateAccountParams{
|
operParams := operator.CreateAccountParams{
|
||||||
Username: username,
|
Username: username,
|
||||||
@@ -32,26 +34,60 @@ func (cli *Client) CreateAccount(ctx context.Context, hosturi, username, passwor
|
|||||||
}
|
}
|
||||||
paramsJson, err := json.Marshal(operParams)
|
paramsJson, err := json.Marshal(operParams)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return res, err
|
||||||
}
|
}
|
||||||
respBytes, err := doHTTPCall(ctx, apiuri, paramsJson)
|
respBytes, err := doHTTPCall(ctx, apiuri, paramsJson)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
operRes := handler.NewResponse[operator.CreateAccountResult]()
|
operRes := handler.NewResponse[operator.CreateAccountResult]()
|
||||||
err = json.Unmarshal(respBytes, operRes)
|
err = json.Unmarshal(respBytes, operRes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return res, err
|
||||||
}
|
}
|
||||||
if !operRes.Error {
|
if operRes.Error {
|
||||||
err = fmt.Errorf("%s", operRes.Message)
|
err = fmt.Errorf("%s", operRes.Message)
|
||||||
return err
|
return res, err
|
||||||
}
|
}
|
||||||
return err
|
res = operRes.Result.AccountID
|
||||||
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *Client) GetAccount(ctx context.Context, hosturi, id, username string) error {
|
func (cli *Client) GetAccountByID(ctx context.Context, hosturi, id string) (descr.AccountShort, error) {
|
||||||
|
var err error
|
||||||
|
var res descr.AccountShort
|
||||||
|
|
||||||
|
apipath, err := setApiPath(hosturi, "/v3/api/account/get")
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
operParams := operator.GetAccountParams{
|
||||||
|
AccountID: id,
|
||||||
|
}
|
||||||
|
paramsJson, err := json.Marshal(operParams)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
respBytes, err := doHTTPCall(ctx, apipath, paramsJson)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
operRes := handler.NewResponse[operator.GetAccountResult]()
|
||||||
|
err = json.Unmarshal(respBytes, operRes)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
if operRes.Error {
|
||||||
|
err = fmt.Errorf("%s", operRes.Message)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cli *Client) GetAccountByName(ctx context.Context, hosturi, username string) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
apipath, err := url.JoinPath(hosturi, "/v3/api/account/get")
|
apipath, err := url.JoinPath(hosturi, "/v3/api/account/get")
|
||||||
@@ -60,7 +96,6 @@ func (cli *Client) GetAccount(ctx context.Context, hosturi, id, username string)
|
|||||||
}
|
}
|
||||||
operParams := operator.GetAccountParams{
|
operParams := operator.GetAccountParams{
|
||||||
Username: username,
|
Username: username,
|
||||||
AccountID: id,
|
|
||||||
}
|
}
|
||||||
paramsJson, err := json.Marshal(operParams)
|
paramsJson, err := json.Marshal(operParams)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -76,7 +111,7 @@ func (cli *Client) GetAccount(ctx context.Context, hosturi, id, username string)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !operRes.Error {
|
if operRes.Error {
|
||||||
err = fmt.Errorf("%s", operRes.Message)
|
err = fmt.Errorf("%s", operRes.Message)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -109,7 +144,7 @@ func (cli *Client) UpdateAccount(ctx context.Context, hosturi, id, username, new
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !operRes.Error {
|
if operRes.Error {
|
||||||
err = fmt.Errorf("%s", operRes.Message)
|
err = fmt.Errorf("%s", operRes.Message)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -141,7 +176,7 @@ func (cli *Client) DeleteAccount(ctx context.Context, hosturi, id, username stri
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !operRes.Error {
|
if operRes.Error {
|
||||||
err = fmt.Errorf("%s", operRes.Message)
|
err = fmt.Errorf("%s", operRes.Message)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,138 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
|
||||||
|
*
|
||||||
|
* This work is published and licensed under a Creative Commons
|
||||||
|
* Attribution-NonCommercial-NoDerivatives 4.0 International License.
|
||||||
|
*
|
||||||
|
* Distribution of this work is permitted, but commercial use and
|
||||||
|
* modifications are strictly prohibited.
|
||||||
|
*/
|
||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
//"math/rand"
|
||||||
|
//"os"
|
||||||
|
//"path/filepath"
|
||||||
|
"sync"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"mstore/app/server"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccountLife(t *testing.T) {
|
||||||
|
var srvport int64 = 10250
|
||||||
|
srvdir := t.TempDir()
|
||||||
|
srvaddr := fmt.Sprintf("foouser:foopass@127.0.0.1:%d", srvport)
|
||||||
|
|
||||||
|
srv, err := server.NewServer()
|
||||||
|
require.NoError(t, err)
|
||||||
|
{
|
||||||
|
err = srv.Configure()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
srv.SetDatadir(srvdir)
|
||||||
|
srv.SetLogdir(srvdir)
|
||||||
|
srv.SetRundir(srvdir)
|
||||||
|
srv.SetPort(srvport)
|
||||||
|
|
||||||
|
err = srv.Build()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
var svcWG sync.WaitGroup
|
||||||
|
errPipe := make(chan error, 5)
|
||||||
|
|
||||||
|
startFunc := func() {
|
||||||
|
err := srv.Service().Run()
|
||||||
|
errPipe <- err
|
||||||
|
svcWG.Done()
|
||||||
|
}
|
||||||
|
|
||||||
|
stopFunc := func() {
|
||||||
|
srv.Service().Stop()
|
||||||
|
svcWG.Wait()
|
||||||
|
err = <-errPipe
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
defer stopFunc()
|
||||||
|
|
||||||
|
svcWG.Add(1)
|
||||||
|
go startFunc()
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// ServiceHello
|
||||||
|
fmt.Printf("=== ServiceHello ===\n")
|
||||||
|
cli := NewClient()
|
||||||
|
ctx := context.Background()
|
||||||
|
helloRes, err := cli.ServiceHello(ctx, srvaddr+"/hello", 1*time.Second)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.True(t, helloRes)
|
||||||
|
}
|
||||||
|
|
||||||
|
username := "testuser"
|
||||||
|
password := "testpass"
|
||||||
|
|
||||||
|
var accountID string
|
||||||
|
{
|
||||||
|
// CreateAccount
|
||||||
|
fmt.Printf("=== CreateAccount ===\n")
|
||||||
|
cli := NewClient()
|
||||||
|
ctx := context.Background()
|
||||||
|
ctx, _ = context.WithTimeout(ctx, 1*time.Second)
|
||||||
|
|
||||||
|
accountID, err = cli.CreateAccount(ctx, srvaddr, username, password)
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// GetAccount
|
||||||
|
fmt.Printf("=== GetAccount ===\n")
|
||||||
|
cli := NewClient()
|
||||||
|
ctx := context.Background()
|
||||||
|
ctx, _ = context.WithTimeout(ctx, 1*time.Second)
|
||||||
|
|
||||||
|
_, err = cli.GetAccountByID(ctx, srvaddr, accountID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
// ListAccounts
|
||||||
|
fmt.Printf("=== ListAccounts ===\n")
|
||||||
|
cli := NewClient()
|
||||||
|
ctx := context.Background()
|
||||||
|
ctx, _ = context.WithTimeout(ctx, 1*time.Second)
|
||||||
|
|
||||||
|
files, err := cli.ListAccounts(ctx, srvaddr+"/")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotZero(t, len(files))
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// DeleteAccount
|
||||||
|
fmt.Printf("=== DeleteAccount ===\n")
|
||||||
|
cli := NewClient()
|
||||||
|
ctx := context.Background()
|
||||||
|
ctx, _ = context.WithTimeout(ctx, 1*time.Second)
|
||||||
|
|
||||||
|
err = cli.DeleteAccount(ctx, srvaddr+"/foo.bin")
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// !AccountExists
|
||||||
|
fmt.Printf("=== AccountExists ===\n")
|
||||||
|
cli := NewClient()
|
||||||
|
ctx := context.Background()
|
||||||
|
ctx, _ = context.WithTimeout(ctx, 1*time.Second)
|
||||||
|
|
||||||
|
exists, _, err := cli.AccountInfo(ctx, srvaddr+"/foo.bin")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.False(t, exists)
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
@@ -24,7 +24,7 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestFileLife(t *testing.T) {
|
func xxxTestFileLife(t *testing.T) {
|
||||||
var srvport int64 = 10250
|
var srvport int64 = 10250
|
||||||
srvdir := t.TempDir()
|
srvdir := t.TempDir()
|
||||||
srvaddr := fmt.Sprintf("testuser:testpass@127.0.0.1:%d", srvport)
|
srvaddr := fmt.Sprintf("testuser:testpass@127.0.0.1:%d", srvport)
|
||||||
@@ -74,8 +74,6 @@ func TestFileLife(t *testing.T) {
|
|||||||
require.True(t, helloRes)
|
require.True(t, helloRes)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
filesize := 32
|
filesize := 32
|
||||||
{
|
{
|
||||||
// PutFile
|
// PutFile
|
||||||
@@ -98,8 +96,8 @@ func TestFileLife(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// FileExists
|
// FileInfo
|
||||||
fmt.Printf("=== FileExists ===\n")
|
fmt.Printf("=== FileInfo ===\n")
|
||||||
cli := NewClient()
|
cli := NewClient()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
ctx, _ = context.WithTimeout(ctx, 1*time.Second)
|
ctx, _ = context.WithTimeout(ctx, 1*time.Second)
|
||||||
@@ -146,8 +144,8 @@ func TestFileLife(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// !FileExists
|
// !FileInfo
|
||||||
fmt.Printf("=== FileExists ===\n")
|
fmt.Printf("=== FileInfo ===\n")
|
||||||
cli := NewClient()
|
cli := NewClient()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
ctx, _ = context.WithTimeout(ctx, 1*time.Second)
|
ctx, _ = context.WithTimeout(ctx, 1*time.Second)
|
||||||
+21
-4
@@ -13,17 +13,34 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
//"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
//"net/url"
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
|
||||||
//"mstore/app/handler"
|
|
||||||
//"mstore/app/operator"
|
|
||||||
"mstore/pkg/auxhttp"
|
"mstore/pkg/auxhttp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func setApiPath(base, apipath string) (string, error) {
|
||||||
|
var res string
|
||||||
|
if !strings.Contains(base, "://") {
|
||||||
|
base = "https://" + base
|
||||||
|
}
|
||||||
|
uri, err := url.Parse(base)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
uri.Path = "/"
|
||||||
|
uri.Path, err = url.JoinPath(uri.Path, apipath)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
res = uri.String()
|
||||||
|
return res, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func doHTTPCall(ctx context.Context, apiuri string, reqBytes []byte) ([]byte, error) {
|
func doHTTPCall(ctx context.Context, apiuri string, reqBytes []byte) ([]byte, error) {
|
||||||
var err error
|
var err error
|
||||||
respBytes := make([]byte, 0)
|
respBytes := make([]byte, 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user