225 lines
5.3 KiB
Go
225 lines
5.3 KiB
Go
package curl2info
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"474420502.top/eson/requests"
|
|
)
|
|
|
|
func init() {
|
|
optionTrie = newTrie()
|
|
oelist := []*optionExecute{
|
|
{"-H", 10, parseHeader, nil},
|
|
{"-X", 10, parseOptX, nil},
|
|
{"-A", 15, parseUserAgent, &extract{re: "^-A +(.+)", execute: extractData}},
|
|
{"-I", 15, parseOptI, nil},
|
|
{"-d", 10, parseBodyASCII, &extract{re: "^-d +(.+)", execute: extractData}},
|
|
{"-u", 15, parseUser, &extract{re: "^-u +(.+)", execute: extractData}},
|
|
{"-k", 15, parseInsecure, nil},
|
|
// Body
|
|
{"--data", 10, parseBodyASCII, &extract{re: "--data +(.+)", execute: extractData}},
|
|
{"--data-urlencode", 10, parseBodyURLEncode, &extract{re: "--data-urlencode +(.+)", execute: extractData}},
|
|
{"--data-binary", 10, parseBodyBinary, &extract{re: "--data-binary +(.+)", execute: extractData}},
|
|
{"--data-ascii", 10, parseBodyASCII, &extract{re: "--data-ascii +(.+)", execute: extractData}},
|
|
{"--data-raw", 10, parseBodyRaw, &extract{re: "--data-raw +(.+)", execute: extractData}},
|
|
//"--"
|
|
{"--header", 10, parseHeader, nil},
|
|
{"--insecure", 15, parseInsecure, nil},
|
|
{"--user-agent", 15, parseUserAgent, &extract{re: "--user-agent +(.+)", execute: extractData}},
|
|
{"--user", 15, parseUser, &extract{re: "--user +(.+)", execute: extractData}},
|
|
{"--connect-timeout", 15, parseTimeout, &extract{re: "--connect-timeout +(.+)", execute: extractData}},
|
|
// 自定义
|
|
{"--task", 10, parseITask, &extract{re: "--task +(.+)", execute: extractData}},
|
|
{"--crontab", 10, parseCrontab, &extract{re: "--crontab +(.+)", execute: extractData}},
|
|
{"--name", 10, parseName, &extract{re: "--name +(.+)", execute: extractData}},
|
|
}
|
|
|
|
for _, oe := range oelist {
|
|
optionTrie.Insert(oe)
|
|
}
|
|
|
|
// log.Println("support options:", optionTrie.AllWords())
|
|
}
|
|
|
|
// extract 用于提取设置的数据
|
|
type extract struct {
|
|
re string
|
|
execute func(re, soption string) string
|
|
}
|
|
|
|
func (et *extract) Execute(soption string) string {
|
|
return et.execute(et.re, soption)
|
|
}
|
|
|
|
// OptionTrie 设置的前缀树
|
|
var optionTrie *hTrie
|
|
|
|
type optionExecute struct {
|
|
Prefix string
|
|
|
|
Priority int
|
|
|
|
Parse func(*CURL, string) // 执行函数
|
|
Extract *extract // 提取的方法结构与参数
|
|
}
|
|
|
|
func (oe *optionExecute) GetWord() string {
|
|
return oe.Prefix + " "
|
|
}
|
|
|
|
func (oe *optionExecute) BuildFunction(curl *CURL, soption string) *parseFunction {
|
|
data := soption
|
|
if oe.Extract != nil {
|
|
data = oe.Extract.Execute(data)
|
|
}
|
|
return &parseFunction{ParamCURL: curl, ParamData: data, ExecuteFunction: oe.Parse, Priority: oe.Priority}
|
|
}
|
|
|
|
func judgeOptions(u *CURL, soption string) *parseFunction {
|
|
word := trieStrWord(soption)
|
|
if ioe := optionTrie.SearchDepth(&word); ioe != nil {
|
|
oe := ioe.(*optionExecute)
|
|
return oe.BuildFunction(u, soption)
|
|
}
|
|
|
|
log.Println(soption, " not this option")
|
|
return nil
|
|
}
|
|
|
|
func extractData(re, soption string) string {
|
|
datas := regexp.MustCompile(re).FindStringSubmatch(soption)
|
|
return strings.Trim(datas[1], "'\"")
|
|
}
|
|
|
|
func parseName(u *CURL, value string) {
|
|
u.Name = value
|
|
}
|
|
|
|
func parseCrontab(u *CURL, value string) {
|
|
u.Crontab = value
|
|
}
|
|
|
|
func parseITask(u *CURL, value string) {
|
|
u.ITask = value
|
|
}
|
|
|
|
func parseTimeout(u *CURL, value string) {
|
|
timeout, err := strconv.Atoi(value)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
u.Timeout = timeout
|
|
}
|
|
|
|
func parseInsecure(u *CURL, soption string) {
|
|
u.Insecure = true
|
|
}
|
|
|
|
func parseUser(u *CURL, soption string) {
|
|
auth := strings.Split(soption, ":")
|
|
u.Auth = &requests.BasicAuth{User: auth[0], Password: auth[1]}
|
|
}
|
|
|
|
func parseUserAgent(u *CURL, value string) {
|
|
u.Header.Add("User-Agent", value)
|
|
}
|
|
|
|
func parseOptI(u *CURL, soption string) {
|
|
u.Method = "HEAD"
|
|
}
|
|
|
|
func parseOptX(u *CURL, soption string) {
|
|
matches := regexp.MustCompile("-X +(.+)").FindStringSubmatch(soption)
|
|
method := strings.Trim(matches[1], "'")
|
|
u.Method = method
|
|
}
|
|
|
|
func parseBodyURLEncode(u *CURL, data string) {
|
|
if u.Method != "" {
|
|
u.Method = "POST"
|
|
}
|
|
|
|
u.Body.SetPrefix(requests.TypeURLENCODED)
|
|
u.Body.SetIOBody(data)
|
|
}
|
|
|
|
func parseBodyRaw(u *CURL, data string) {
|
|
if u.Method != "" {
|
|
u.Method = "POST"
|
|
}
|
|
|
|
u.Body.SetPrefix(requests.TypeURLENCODED)
|
|
u.Body.SetIOBody(data)
|
|
}
|
|
|
|
func parseBodyASCII(u *CURL, data string) {
|
|
if u.Method != "" {
|
|
u.Method = "POST"
|
|
}
|
|
|
|
u.Body.SetPrefix(requests.TypeURLENCODED)
|
|
|
|
if data[0] != '@' {
|
|
u.Body.SetIOBody(data)
|
|
} else {
|
|
f, err := os.Open(data[1:])
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer f.Close()
|
|
|
|
bdata, err := ioutil.ReadAll(f)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
u.Body.SetIOBody(bdata)
|
|
}
|
|
}
|
|
|
|
// 处理@ 并且替/r/n符号
|
|
func parseBodyBinary(u *CURL, data string) {
|
|
if u.Method != "" {
|
|
u.Method = "POST"
|
|
}
|
|
|
|
u.Body.SetPrefix(requests.TypeURLENCODED)
|
|
|
|
if data[0] != '@' {
|
|
u.Body.SetIOBody(data)
|
|
} else {
|
|
f, err := os.Open(data[1:])
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer f.Close()
|
|
bdata, err := ioutil.ReadAll(f)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
bdata = regexp.MustCompile("\n|\r").ReplaceAll(bdata, []byte(""))
|
|
u.Body.SetIOBody(bdata)
|
|
}
|
|
}
|
|
|
|
func parseHeader(u *CURL, soption string) {
|
|
matches := regexp.MustCompile(`'([^:]+): ([^']+)'`).FindAllStringSubmatch(soption, 1)[0]
|
|
key := matches[1]
|
|
value := matches[2]
|
|
|
|
switch key {
|
|
case "Cookie":
|
|
u.Cookies = ReadRawCookies(value, "")
|
|
u.CookieJar.SetCookies(u.ParsedURL, u.Cookies)
|
|
case "Content-Type":
|
|
u.Body.SetPrefix(value)
|
|
default:
|
|
u.Header.Add(key, value)
|
|
}
|
|
|
|
}
|