suyac

package module
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 5, 2024 License: MIT Imports: 19 Imported by: 0

README

suyac

Command-line based REST client for testing. Built out of frustration with tools such as Postman and Insomnia starting as free and useful programs and eventually moving to for-profit models when all I used them for was a quick testing environment. This tool was created to fulfill the need for testing and provide a way to do so from CLI as a bonus. The name Suyac comes from suya-suya and curl.

Installation

Get a distribution from the releases page of the GitHub repo for this project and untar it. Place the suyac command somewhere on your path.

Usage

Here are basic descriptions of commands, call suyac help or suyac help COMMAND for info on CLI flags, etc.

One-off Requests

Suyac can send one-off requests by using suyac request:

suyac request -X GET http://localhost/cool

Data and headers are specified with curl-like syntax:

suyac request -X POST https://localhost/cool -H 'Content-Type: application/json' -d '@./datafile'

For convenience, top-level subcommands for each of the common eight HTTP methods are defined. Calling one is exactly the same as calling suyac request -X METHOD and support all args except for '-X'.

suyac get http://localhost:8080/cool  # same as suyac request -X GET http://localhost:8080/cool
Project management

Commonly sent requests can be collected as templates in a project. Body data, headers, URL, and method are saved at creation and later sent with suyac send.

First, a project is created with suyac init. This puts all project files by default in a new .suyac directory in the directory it is called from.

Then, call suyac req new to create a new request, giving the name of request.

Finally, at a later time, call suyac send to actually fire it.

As an example:

suyac init   # create the project, if it doesn't yet exist

suyac req new get-google --url http://google.com/ -X GET

suyac send get-google  # actually fire it off

Templating within a body or url or header is supported. Use variables in form of ${NAME} and supply values during a call to suyac send with -V.

Saving variables during a suyac send automatically is not yet supported, but will be in a future release.

Documentation

Overview

Package suyac provides a scriptable REST client.

Index

Constants

View Source
const (
	ProjDirVar = "::PROJ_DIR::"

	DefaultProjectPath = ".suyac/project.json"
	DefaultSessionPath = ProjDirVar + "/session.json"
	DefaultHistoryPath = ProjDirVar + "/history.json"

	FiletypeProject = "SUYAC/PROJECT"
	FiletypeSession = "SUYAC/SESSION"
	FiletypeHistory = "SUYAC/HISTORY"

	CurFileVersion = 1
)
View Source
const Version = "0.0.1"

Variables

This section is empty.

Functions

This section is empty.

Types

type Flow

type Flow struct {
	Name     string
	Requests []RequestTemplate
}

type HistoryEntry

type HistoryEntry struct {
	Template string
	ReqTime  time.Time
	RespTime time.Time
	Request  http.Request
	Response http.Response
}

func LoadHistoryFromDisk

func LoadHistoryFromDisk(histFilename string) ([]HistoryEntry, error)

func (HistoryEntry) MarshalJSON

func (h HistoryEntry) MarshalJSON() ([]byte, error)

func (*HistoryEntry) UnmarshalJSON

func (h *HistoryEntry) UnmarshalJSON(data []byte) error

type Project

type Project struct {
	Name      string
	Templates map[string]RequestTemplate // note: Names must be manually synched across Templates, Flows, and History
	Flows     map[string]Flow
	Vars      VarStore
	History   []HistoryEntry
	Session   Session
	Config    Settings
}

func LoadProjectFromDisk

func LoadProjectFromDisk(projFilename string, all bool) (Project, error)

func (Project) PersistHistoryToDisk

func (p Project) PersistHistoryToDisk() error

func (Project) PersistSessionToDisk

func (p Project) PersistSessionToDisk() error

func (Project) PersistToDisk

func (p Project) PersistToDisk(all bool) error

PersistToDisk writes up to 3 files; one for the suite, one for the session, and one for the history. If p.ProjFile is empty, it will be written to the current working directory at path .suyac/suite.json. If p.SeshFile is empty, it will be written to the current working directory at path .suyac/session.json. If p.HistFile is empty, it will be written to the current working directory at path .suyac/history.json.

type RESTClient

type RESTClient struct {
	HTTP         *http.Client
	Vars         map[string]string
	VarOverrides map[string]string // Cleared after every call to SendRequest.
	VarPrefix    string

	Scrapers []VarScraper
	// contains filtered or unexported fields
}

Do not use default RESTClient, call NewRESTClient instead.

func NewRESTClient

func NewRESTClient(cookieLifetime time.Duration) *RESTClient

NewRESTClient creates a new RESTClient. 0 for cookie lifetime will default it to 24 hours.

func (*RESTClient) CreateRequest

func (r *RESTClient) CreateRequest(method string, url string, data []byte, hdrs http.Header) (*http.Request, error)

CreateRequest creates a request to the given endpoint. Values set in Vars and VarOverrides are used to fill any variables in the URL, data, and headers.

func (*RESTClient) ReadState

func (r *RESTClient) ReadState(rd io.Reader) error

func (*RESTClient) SendRequest

func (r *RESTClient) SendRequest(req *http.Request) (*http.Response, map[string]string, error)

SendRequest sends the given request and returns the response. VarOverrides will be cleared after this is called. Prior to returning, the response is scanned for var captures and those that are captured are stored in Vars and re

func (*RESTClient) Substitute

func (r *RESTClient) Substitute(s string) (string, error)

func (*RESTClient) WriteState

func (r *RESTClient) WriteState(w io.Writer) error

type RequestTemplate

type RequestTemplate struct {
	Name     string
	Captures []VarScraper
	Body     []byte
	URL      string
	Method   string
	Headers  http.Header
	AuthFlow string
}

func (RequestTemplate) Sendable

func (r RequestTemplate) Sendable() bool

type Session

type Session struct {
	Cookies []SetCookiesCall
}

func LoadSessionFromDisk

func LoadSessionFromDisk(seshFilename string) (Session, error)

func (Session) MarshalJSON

func (s Session) MarshalJSON() ([]byte, error)

func (*Session) TotalCookieSets

func (s *Session) TotalCookieSets() int

TotalCookieSets returns the total number of individual cookies that this Session has a record of being set across all URLs. This may include the same cookie being set multiple times.

func (*Session) UnmarshalJSON

func (s *Session) UnmarshalJSON(data []byte) error

type SetCookiesCall

type SetCookiesCall struct {
	Time    time.Time      `json:"time"`
	URL     *url.URL       `json:"url"`
	Cookies []*http.Cookie `json:"cookies"`
}

func (SetCookiesCall) MarshalBinary

func (sc SetCookiesCall) MarshalBinary() ([]byte, error)

func (SetCookiesCall) String

func (sc SetCookiesCall) String() string

func (*SetCookiesCall) UnmarshalBinary

func (sc *SetCookiesCall) UnmarshalBinary(data []byte) error

type Settings

type Settings struct {
	ProjFile       string        `json:"project_file"`
	HistFile       string        `json:"history_file"`
	SeshFile       string        `json:"session_file"`
	CookieLifetime time.Duration `json:"cookie_lifetime"`
}

func (Settings) HistoryFSPath

func (s Settings) HistoryFSPath() string

HistoryFSPath returns the file-system compatible path to the history file. If s.HistFile contains ProjDirVar, it will be replaced with the directory that the project file is in. If s.HistFile is empty, or if s.ProjFile is referred to with ProjDirVar and is itself empty, this will return the empty string.

func (Settings) SessionFSPath

func (s Settings) SessionFSPath() string

SessionFSPath returns the file-system compatible path to the session file. If s.SeshFile contains ProjDirVar, it will be replaced with the directory that the project file is in. If s.SeshFile is empty, or if s.ProjFile is referred to with ProjDirVar and is itself empty, this will return the empty string.

type State

type State struct {
	Cookies []SetCookiesCall
	Vars    map[string]string
}

State holds all information in a saved state file.

type TimedCookieJar

type TimedCookieJar struct {
	// contains filtered or unexported fields
}

TimedCookieJar wraps a net/http.CookieJar implementation and does quick and dirty recording of all cookies that are received. Because it cannot examine the policy of the wrapped jar, it simply records calls to SetCookies and stores enough information to reproduce all said calls, and additionally records the time that each call was made.

This record can be persisted to bytes, and later played back to restore the state of the cookie jar. Note that depending on the policy of the wrapped jar, cookies that are valid at persistence time may be invalid at playback time.

The time of each call is used for record eviction. At load time and periodically during calls to other methods, the jar will remove any records that are older than a certain threshold. This threshold is stored in the Lifetime member of the TimedCookieJar.

The zero value of TimedCookieJar is not valid. Use NewTimedCookieJar to create one.

It uses trickiness inside of unmarshal that relies on assumption that it is being called on a valid one whose wrapped cookiejar hasn't yet been called.

func (*TimedCookieJar) Cookies

func (j *TimedCookieJar) Cookies(u *url.URL) []*http.Cookie

func (*TimedCookieJar) SetCookies

func (j *TimedCookieJar) SetCookies(u *url.URL, cookies []*http.Cookie)

type TraversalStep

type TraversalStep struct {
	Key   string // if set, index is ignored
	Index int
}

func (TraversalStep) String

func (t TraversalStep) String() string

func (TraversalStep) Traverse

func (t TraversalStep) Traverse(data interface{}) (interface{}, error)

type VarScraper

type VarScraper struct {
	Name        string
	OffsetStart int
	OffsetEnd   int
	Steps       []TraversalStep // if non-nil, OffsetStart and OffsetEnd are ignored
}

func ParseVarScraper

func ParseVarScraper(s string) (VarScraper, error)

func (VarScraper) Scrape

func (v VarScraper) Scrape(data []byte) (string, error)

func (VarScraper) String

func (v VarScraper) String() string

type VarStore

type VarStore struct {
	Environment string
	// contains filtered or unexported fields
}

VarStore is a collection of variables that can be accessed by name within multiple environments. The zero value of this type is not valid; create a new VarStore with NewVarStore().

func NewVarStore

func NewVarStore() VarStore

func (*VarStore) All

func (v *VarStore) All() []string

All returns the names of all variables defined between the current environment and the default environment. If a variable is defined in both environments, it will only be included once.

func (*VarStore) Count

func (v *VarStore) Count() int

Count returns the number of variables accessible from the current environment. This includes any in the default environment that are not overridden by the current environment. This will match the number of elements returned by All().

func (*VarStore) Defined

func (v *VarStore) Defined() []string

Defined returns the names of all variables defined in the current environment. It does not include any vars that are only defined in the default environment.

func (*VarStore) EnvCount

func (v *VarStore) EnvCount() int

func (*VarStore) EnvNames

func (v *VarStore) EnvNames() []string

func (*VarStore) Get

func (v *VarStore) Get(key string) string

func (VarStore) MarshalJSON

func (v VarStore) MarshalJSON() ([]byte, error)

func (*VarStore) Remove

func (v *VarStore) Remove(key string)

Remove removes the variable from all environments, including the default one.

func (*VarStore) Set

func (v *VarStore) Set(key, value string)

func (*VarStore) UnmarshalJSON

func (v *VarStore) UnmarshalJSON(data []byte) error

func (*VarStore) Unset

func (v *VarStore) Unset(key string)

Unset removes the variable from the current environemnt. If the current environment is not the default environment, the variable will not be removed from the default environment. Use Remove to remove the variable from all environments.

If the current environment *is* the default environment, calling this method has the same effect as calling Remove, as variables are not allowed to exist in only a non-default environment.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL