5 Commits

Author SHA1 Message Date
b612 b92288bbc9 update go mod 2023-02-03 13:18:53 +08:00
b612 0805549006 add origin request/response http method 2022-09-06 15:15:33 +08:00
b612 033272f38a add tls config 2022-08-22 16:22:22 +08:00
b612 93b756d9fb add no auto redirect config 2022-06-06 11:18:42 +08:00
b612 d71eacdc91 optional function add 2022-03-14 15:43:56 +08:00
3 changed files with 240 additions and 47 deletions
+231 -44
View File
@@ -4,6 +4,7 @@ import (
"bytes"
"context"
"crypto/rand"
"crypto/tls"
"errors"
"fmt"
"io"
@@ -28,42 +29,205 @@ type RequestFile struct {
UploadForm map[string]string
UploadName string
}
type Request struct {
TimeOut int
DialTimeOut int
Url string
RespURL string
Method string
RecvData []byte
RecvContentLength int64
WriteRecvData bool
RecvIo io.Writer
ReqHeader http.Header
ReqCookies []*http.Cookie
RespHeader http.Header
RespCookies []*http.Cookie
RequestFile
RespHttpCode int
PostBuffer *bytes.Buffer
CircleBuffer *stario.StarBuffer
Proxy string
Process func(float64)
respReader io.ReadCloser
RespHttpCode int
Location *url.URL
CircleBuffer *stario.StarBuffer
respReader io.ReadCloser
respOrigin *http.Response
reqOrigin *http.Request
RequestOpts
}
func NewRequests(url string, postdata []byte, method string) Request {
type RequestOpts struct {
RequestFile
PostBuffer io.Reader
Process func(float64)
Proxy string
Timeout time.Duration
DialTimeout time.Duration
ReqHeader http.Header
ReqCookies []*http.Cookie
WriteRecvData bool
SkipTLSVerify bool
CustomTransport *http.Transport
Queries map[string]string
DisableRedirect bool
TlsConfig *tls.Config
}
type RequestOpt func(opt *RequestOpts)
func WithDialTimeout(timeout time.Duration) RequestOpt {
return func(opt *RequestOpts) {
opt.DialTimeout = timeout
}
}
func WithTimeout(timeout time.Duration) RequestOpt {
return func(opt *RequestOpts) {
opt.Timeout = timeout
}
}
func WithHeader(key, val string) RequestOpt {
return func(opt *RequestOpts) {
opt.ReqHeader.Set(key, val)
}
}
func WithTlsConfig(tlscfg *tls.Config) RequestOpt {
return func(opt *RequestOpts) {
opt.TlsConfig = tlscfg
}
}
func WithHeaderMap(header map[string]string) RequestOpt {
return func(opt *RequestOpts) {
for key, val := range header {
opt.ReqHeader.Set(key, val)
}
}
}
func WithHeaderAdd(key, val string) RequestOpt {
return func(opt *RequestOpts) {
opt.ReqHeader.Add(key, val)
}
}
func WithReader(r io.Reader) RequestOpt {
return func(opt *RequestOpts) {
opt.PostBuffer = r
}
}
func WithFetchRespBody(fetch bool) RequestOpt {
return func(opt *RequestOpts) {
opt.WriteRecvData = fetch
}
}
func WithCookies(ck []*http.Cookie) RequestOpt {
return func(opt *RequestOpts) {
opt.ReqCookies = ck
}
}
func WithCookie(key, val, path string) RequestOpt {
return func(opt *RequestOpts) {
opt.ReqCookies = append(opt.ReqCookies, &http.Cookie{Name: key, Value: val, Path: path})
}
}
func WithCookieMap(header map[string]string, path string) RequestOpt {
return func(opt *RequestOpts) {
for key, val := range header {
opt.ReqCookies = append(opt.ReqCookies, &http.Cookie{Name: key, Value: val, Path: path})
}
}
}
func WithQueries(queries map[string]string) RequestOpt {
return func(opt *RequestOpts) {
opt.Queries = queries
}
}
func WithProxy(proxy string) RequestOpt {
return func(opt *RequestOpts) {
opt.Proxy = proxy
}
}
func WithProcess(fn func(float64)) RequestOpt {
return func(opt *RequestOpts) {
opt.Process = fn
}
}
func WithContentType(ct string) RequestOpt {
return func(opt *RequestOpts) {
opt.ReqHeader.Set("Content-Type", ct)
}
}
func WithUserAgent(ua string) RequestOpt {
return func(opt *RequestOpts) {
opt.ReqHeader.Set("User-Agent", ua)
}
}
func WithCustomTransport(hs *http.Transport) RequestOpt {
return func(opt *RequestOpts) {
opt.CustomTransport = hs
}
}
func WithSkipTLSVerify(skip bool) RequestOpt {
return func(opt *RequestOpts) {
opt.SkipTLSVerify = skip
}
}
func WithDisableRedirect(disable bool) RequestOpt {
return func(opt *RequestOpts) {
opt.DisableRedirect = disable
}
}
func NewRequests(url string, rawdata []byte, method string, opts ...RequestOpt) Request {
req := Request{
TimeOut: 30,
DialTimeOut: 15,
Url: url,
PostBuffer: bytes.NewBuffer(postdata),
Method: method,
WriteRecvData: true,
RequestOpts: RequestOpts{
Timeout: 30 * time.Second,
DialTimeout: 15 * time.Second,
WriteRecvData: true,
},
Url: url,
Method: method,
}
if rawdata != nil {
req.PostBuffer = bytes.NewBuffer(rawdata)
}
req.ReqHeader = make(http.Header)
if strings.ToUpper(method) == "POST" {
req.ReqHeader.Set("Content-Type", HEADER_FORM_URLENCODE)
}
req.ReqHeader.Set("User-Agent", "B612 / 1.1.0")
for _, v := range opts {
v(&req.RequestOpts)
}
if req.CustomTransport == nil {
req.CustomTransport = &http.Transport{}
}
if req.SkipTLSVerify {
if req.CustomTransport.TLSClientConfig == nil {
req.CustomTransport.TLSClientConfig = &tls.Config{}
}
req.CustomTransport.TLSClientConfig.InsecureSkipVerify = true
}
if req.TlsConfig != nil {
req.CustomTransport.TLSClientConfig = req.TlsConfig
}
req.CustomTransport.DialContext = func(ctx context.Context, netw, addr string) (net.Conn, error) {
c, err := net.DialTimeout(netw, addr, req.DialTimeout)
if err != nil {
return nil, err
}
if req.Timeout != 0 {
c.SetDeadline(time.Now().Add(req.Timeout))
}
return c, nil
}
return req
}
@@ -78,6 +242,9 @@ func (curl *Request) ResetReqCookies() {
func (curl *Request) AddSimpleCookie(key, value string) {
curl.ReqCookies = append(curl.ReqCookies, &http.Cookie{Name: key, Value: value, Path: "/"})
}
func (curl *Request) AddCookie(key, value, path string) {
curl.ReqCookies = append(curl.ReqCookies, &http.Cookie{Name: key, Value: value, Path: path})
}
func randomBoundary() string {
var buf [30]byte
@@ -142,13 +309,16 @@ func Curl(curl Request) (resps Request, err error) {
curl.CircleBuffer = fpdst
curl.ReqHeader.Set("Content-Type", "multipart/form-data;boundary="+boundary)
}
resp, err := netcurl(curl)
req, resp, err := netcurl(curl)
if err != nil {
return Request{}, err
}
curl.PostBuffer = nil
curl.CircleBuffer = nil
if resp.Request != nil && resp.Request.URL != nil {
curl.RespURL = resp.Request.URL.String()
}
curl.reqOrigin = req
curl.respOrigin = resp
curl.Location, _ = resp.Location()
curl.RespHttpCode = resp.StatusCode
curl.RespHeader = resp.Header
curl.RespCookies = resp.Cookies()
@@ -205,21 +375,28 @@ func (curl *Request) RespBodyReader() io.ReadCloser {
return curl.respReader
}
func netcurl(curl Request) (*http.Response, error) {
func netcurl(curl Request) (*http.Request, *http.Response, error) {
var req *http.Request
var err error
if curl.Method == "" {
return nil, errors.New("Error Method Not Entered")
return nil, nil, errors.New("Error Method Not Entered")
}
if curl.PostBuffer != nil && curl.PostBuffer.Len() > 0 {
if curl.PostBuffer != nil {
req, err = http.NewRequest(curl.Method, curl.Url, curl.PostBuffer)
} else if curl.CircleBuffer != nil && curl.CircleBuffer.Len() > 0 {
req, err = http.NewRequest(curl.Method, curl.Url, curl.CircleBuffer)
} else {
req, err = http.NewRequest(curl.Method, curl.Url, nil)
}
if curl.Queries != nil {
sid := req.URL.Query()
for k, v := range curl.Queries {
sid.Add(k, v)
}
req.URL.RawQuery = sid.Encode()
}
if err != nil {
return nil, err
return nil, nil, err
}
req.Header = curl.ReqHeader
if len(curl.ReqCookies) != 0 {
@@ -227,30 +404,24 @@ func netcurl(curl Request) (*http.Response, error) {
req.AddCookie(v)
}
}
transport := &http.Transport{
DialContext: func(ctx context.Context, netw, addr string) (net.Conn, error) {
c, err := net.DialTimeout(netw, addr, time.Second*time.Duration(curl.DialTimeOut))
if err != nil {
return nil, err
}
if curl.TimeOut != 0 {
c.SetDeadline(time.Now().Add(time.Duration(curl.TimeOut) * time.Second))
}
return c, nil
},
}
if curl.Proxy != "" {
purl, err := url.Parse(curl.Proxy)
if err != nil {
return nil, err
return nil, nil, err
}
transport.Proxy = http.ProxyURL(purl)
curl.CustomTransport.Proxy = http.ProxyURL(purl)
}
client := &http.Client{
Transport: transport,
Transport: curl.CustomTransport,
}
if curl.DisableRedirect {
client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
}
}
resp, err := client.Do(req)
return resp, err
return req, resp, err
}
func UrlEncodeRaw(str string) string {
@@ -266,10 +437,26 @@ func UrlDecode(str string) (string, error) {
return url.QueryUnescape(str)
}
func Build_Query(queryData map[string]string) string {
func BuildQuery(queryData map[string]string) string {
query := url.Values{}
for k, v := range queryData {
query.Add(k, v)
}
return query.Encode()
}
func BuildPostForm(queryMap map[string]string) []byte {
query := url.Values{}
for k, v := range queryMap {
query.Add(k, v)
}
return []byte(query.Encode())
}
func (r Request) Resopnse() *http.Response {
return r.respOrigin
}
func (r Request) Request() *http.Request {
return r.reqOrigin
}
+7 -1
View File
@@ -2,4 +2,10 @@ module b612.me/starnet
go 1.16
require b612.me/stario v0.0.5
require b612.me/stario v0.0.7
require (
golang.org/x/crypto v0.0.0-20220313003712-b769efc7c000 // indirect
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 // indirect
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect
)
+2 -2
View File
@@ -1,5 +1,5 @@
b612.me/stario v0.0.5 h1:Q1OGF+8eOoK49zMzkyh80GWaMuknhey6+PWJJL9ZuNo=
b612.me/stario v0.0.5/go.mod h1:or4ssWcxQSjMeu+hRKEgtp0X517b3zdlEOAms8Qscvw=
b612.me/stario v0.0.7 h1:QbQcsHCVLE6vRgVrPN4+9DGiSaC6IWdtm4ClL2tpMUg=
b612.me/stario v0.0.7/go.mod h1:or4ssWcxQSjMeu+hRKEgtp0X517b3zdlEOAms8Qscvw=
golang.org/x/crypto v0.0.0-20220313003712-b769efc7c000 h1:SL+8VVnkqyshUSz5iNnXtrBQzvFF2SkROm6t5RczFAE=
golang.org/x/crypto v0.0.0-20220313003712-b769efc7c000/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=