123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- // package store_client -- HTTP-клиент для выполнения запросов на сервер
- package store_client
- /*
- import (
- "context"
- "encoding/json"
- "fmt"
- "io"
- "log"
- "net"
- "net/http"
- "os"
- "time"
- "git.p78su.freemyip.com/svi/gostore/internal/store_user"
- )
- // IClient -- HTTP-клиент для выполнения запросов на сервер
- type IClient interface {
- // Get -- получить значени ключа
- Get(key string) ([]byte, error)
- // Put -- разместить ключ на сервере
- Put(key string, val []byte) error
- // Del -- удаляет запись по ключу
- Del(key string)
- // Find -- найти ключи по префиксу
- Find(prefixKey string) ([]string, error)
- // Time -- возвращает время сервера
- Time() (string, error)
- }
- // StoreClient -- HTTP-клиент для выполнения запросов на сервер
- type StoreClient struct {
- login string
- pass string
- url string
- urlParam string // Сумма логина и пароль
- client *http.Client
- }
- // NewStoreClient -- возвращает новый HTTP-клиент для выполнения запросов на сервер
- func NewStoreClient() (IClient, error) {
- user, err := store_user.NewStoreUser()
- if err != nil {
- return nil, fmt.Errorf("NewStoreClient(): in create IStoreUser, err=\n\t%w", err)
- }
- url := os.Getenv("STORE_URL")
- if url == "" {
- return nil, fmt.Errorf("NewStoreClient(): env STORE_URL not set")
- }
- sf := &StoreClient{
- login: user.Login(),
- pass: user.Pass(),
- url: url,
- client: &http.Client{
- Transport: &http.Transport{
- Dial: (&net.Dialer{
- Timeout: 3 * time.Second,
- KeepAlive: 6 * time.Second,
- }).Dial,
- IdleConnTimeout: 10 * time.Second,
- },
- },
- }
- sf.urlParam = "/" + sf.login + "/" + sf.pass + "/"
- if _, err := sf.Time(); err != nil {
- return nil, fmt.Errorf("NewStoreClient(): in check connect, err=\n\t%w", err)
- }
- go sf.ping()
- return sf, nil
- }
- type ListValRequest struct {
- Val_ []string `json:"val" form:"val"`
- }
- // Find -- поиск ключей по префиксу
- func (sf *StoreClient) Find(prefixKey string) ([]string, error) {
- ctx, fnCancel := context.WithTimeout(context.Background(), time.Second*6)
- defer fnCancel()
- req, err := http.NewRequestWithContext(ctx, http.MethodPost, sf.url+sf.urlParam+prefixKey, nil)
- if err != nil {
- return nil, fmt.Errorf("StoreClient.Find(): in create HTTP-request, err=\n\t%w", err)
- }
- req.Header.Set("Content-Type", "application/json")
- resp, err := sf.client.Do(req)
- if err != nil {
- return nil, fmt.Errorf("StoreClient.Find(): in exec HTTP-request, err=\n\t%w", err)
- }
- defer resp.Body.Close()
- if resp.StatusCode != http.StatusOK {
- return nil, fmt.Errorf("StoreClient.Find(): bad status HTTP-request, code=%v", resp.Status)
- }
- binBody, err := io.ReadAll(resp.Body)
- if err != nil {
- return nil, fmt.Errorf("StoreClient.Find(): in read body HTTP-request, err\n\t%w", err)
- }
- _resp := &ListValRequest{
- Val_: []string{},
- }
- err = json.Unmarshal(binBody, _resp)
- if err != nil {
- return nil, fmt.Errorf("StoreClient.Find(): in unmarshal body HTTP-response, err\n\t%w", err)
- }
- return _resp.Val_, nil
- }
- // Del -- удаляет ключ с сервера
- func (sf *StoreClient) Del(key string) {
- ctx, fnCancel := context.WithTimeout(context.Background(), time.Second*6)
- defer fnCancel()
- req, err := http.NewRequestWithContext(ctx, http.MethodPost, sf.url+sf.urlParam+key, nil)
- if err != nil {
- log.Printf("StoreClient.Del(): in create HTTP-request, err=\n\t%w", err)
- return
- }
- req.Header.Set("Content-Type", "application/json")
- resp, err := sf.client.Do(req)
- if err != nil {
- log.Printf("StoreClient.Del(): in exec HTTP-request, err=\n\t%w", err)
- return
- }
- defer resp.Body.Close()
- if resp.StatusCode != http.StatusOK {
- log.Printf("StoreClient.Del(): bad status HTTP-request, code=%v", resp.Status)
- return
- }
- }
- // Time -- проверяет время сервера
- func (sf *StoreClient) Time() (string, error) {
- ctx, fnCancel := context.WithTimeout(context.Background(), time.Second*6)
- defer fnCancel()
- req, err := http.NewRequestWithContext(ctx, http.MethodGet, sf.url+"/time", nil)
- if err != nil {
- fmt.Println(err)
- return "", fmt.Errorf("StoreClient.Time(): in create HTTP-request, err=\n\t%w", err)
- }
- resp, err := sf.client.Do(req)
- if err != nil {
- return "", fmt.Errorf("StoreClient.Time(): in exec HTTP-request, err=\n\t%w", err)
- }
- defer resp.Body.Close()
- if resp.StatusCode != http.StatusOK {
- return "", fmt.Errorf("StoreClient.Time(): bad status HTTP-request, code=%v", resp.Status)
- }
- binBody, err := io.ReadAll(resp.Body)
- if err != nil {
- return "", fmt.Errorf("StoreClient.Time(): in read body HTTP-request, err\n\t%w", err)
- }
- return string(binBody), nil
- }
- // Пингует в фоне сервер, чтобы не оборвался коннект
- func (sf *StoreClient) ping() {
- for {
- _, _ = sf.Time()
- time.Sleep(time.Second * 7)
- }
- }
- */
|