@@ -3,31 +3,39 @@ package pcurl
33import (
44 "net/http"
55 "os"
6+ "sort"
67 "strings"
78
89 "github.com/guonaihong/clop"
910 "github.com/guonaihong/gout"
10- "github.com/guonaihong/gout/dataflow"
1111)
1212
1313// Curl结构体
1414type Curl struct {
15- Method string `clop:"-X; --request" usage:"Specify request command to use"`
16- Get bool `clop:"-G; --get" usage:"Put the post data in the URL and use GET"`
17- Header []string `clop:"-H; --header" usage:"Pass custom header(s) to server"`
18- Data string `clop:"-d; --data" usage:"HTTP POST data"`
19- DataRaw string `clop:"--data-raw" usage:"HTTP POST data, '@' allowed"`
20- Form []string `clop:"-F; --form" usage:"Specify multipart MIME data"`
21- URL2 string `clop:"args=url2" usage:"url2"`
22- URL string `clop:"--url" usage:"URL to work with"`
23- Location bool `clop:"-L; --location" usage:"Follow redirects"` //TODO
15+ Method string `clop:"-X; --request" usage:"Specify request command to use"`
16+ Get bool `clop:"-G; --get" usage:"Put the post data in the URL and use GET"`
17+ Header []string `clop:"-H; --header" usage:"Pass custom header(s) to server"`
18+ Data string `clop:"-d; --data" usage:"HTTP POST data"`
19+ DataRaw string `clop:"--data-raw" usage:"HTTP POST data, '@' allowed"`
20+ Form []string `clop:"-F; --form" usage:"Specify multipart MIME data"`
21+ URL2 string `clop:"args=url2" usage:"url2"`
22+ URL string `clop:"--url" usage:"URL to work with"`
23+ Location bool `clop:"-L; --location" usage:"Follow redirects"` //TODO
24+ DataUrlencode []string `clop:"--data-urlencode" usage:"HTTP POST data url encoded"`
2425
2526 Compressed bool `clop:"--compressed" usage:"Request compressed response"`
2627 Insecure bool `clop:"-k; --insecure" "Allow insecure server connections when using SSL"`
2728 Err error
2829 p * clop.Clop
2930}
3031
32+ const (
33+ bodyURLEncode = "data-urlencode"
34+ bodyForm = "form"
35+ bodyData = "data"
36+ bodyDataRaw = "data-raw"
37+ )
38+
3139// 解析curl字符串形式表达式,并返回*http.Request
3240func ParseAndRequest (curl string ) (* http.Request , error ) {
3341 return ParseString (curl ).Request ()
@@ -69,6 +77,56 @@ func (c *Curl) createHeader() []string {
6977 return header
7078}
7179
80+ func (c * Curl ) findHighestPriority () string {
81+
82+ // 获取 --data-urlencoded,-F or --form, -d or --data, --data-raw的命令行优先级别
83+ m := map [uint64 ]string {
84+ c .p .GetIndex (bodyURLEncode ): bodyURLEncode ,
85+ c .p .GetIndex (bodyForm ): bodyForm ,
86+ c .p .GetIndex (bodyData ): bodyData ,
87+ c .p .GetIndex (bodyDataRaw ): bodyDataRaw ,
88+ }
89+
90+ index := []uint64 {
91+ c .p .GetIndex (bodyURLEncode ),
92+ c .p .GetIndex (bodyForm ),
93+ c .p .GetIndex (bodyData ),
94+ c .p .GetIndex (bodyDataRaw ),
95+ }
96+
97+ // 排序
98+ sort .Slice (index , func (i , j int ) bool {
99+ return index [i ] < index [j ]
100+ })
101+
102+ // 取优先级最高的选项
103+ max := index [len (index )- 1 ]
104+
105+ return m [max ]
106+ }
107+
108+ func (c * Curl ) createWWWForm () ([]interface {}, error ) {
109+ if len (c .DataUrlencode ) == 0 {
110+ return nil , nil
111+ }
112+
113+ form := make ([]interface {}, len (c .DataUrlencode )* 2 )
114+ index := 0
115+ for _ , v := range c .DataUrlencode {
116+ pos := strings .IndexByte (v , '=' )
117+ if pos == - 1 {
118+ continue
119+ }
120+
121+ form [index ] = v [:pos ]
122+ index ++
123+ form [index ] = v [pos + 1 :]
124+ index ++
125+ }
126+
127+ return form , nil
128+ }
129+
72130func (c * Curl ) createForm () ([]interface {}, error ) {
73131 if len (c .Form ) == 0 {
74132 return nil , nil
@@ -130,7 +188,10 @@ func (c *Curl) setMethod() {
130188func (c * Curl ) Request () (req * http.Request , err error ) {
131189
132190 var (
133- data interface {}
191+ data interface {}
192+ form []interface {}
193+ wwwForm []interface {}
194+ dataRaw string
134195 )
135196
136197 defer func () {
@@ -143,21 +204,38 @@ func (c *Curl) Request() (req *http.Request, err error) {
143204
144205 header := c .createHeader ()
145206
146- form , err := c .createForm ()
147- if err != nil {
148- return nil , err
207+ switch c .findHighestPriority () {
208+ case bodyURLEncode :
209+ if wwwForm , err = c .createWWWForm (); err != nil {
210+ return nil , err
211+ }
212+ case bodyForm :
213+ if form , err = c .createForm (); err != nil {
214+ return nil , err
215+ }
216+ case bodyData :
217+ dataRaw = c .Data
218+ case bodyDataRaw :
219+ dataRaw = c .DataRaw
149220 }
150221
151- var dataRaw string
152- dataRaw = c .Data
153- // --data 和--data-raw同时出现的话, 取后面的选项
154- // --data-raw @./a.file --data @./b.file 这里取-data @./b.file
155- // --data-raw @./a.file -data @./b.file 这里取-data-raw @./a.file
156- if c .p .GetIndex ("data-raw" ) > c .p .GetIndex ("data" ) {
157- dataRaw = c .DataRaw
222+ var hc * http.Client
223+
224+ if c .Insecure {
225+ hc = & defaultInsecureSkipVerify
158226 }
159227
160- data = dataRaw
228+ g := gout .New (hc )
229+ g .SetMethod (c .Method ) //设置method POST or GET or DELETE
230+
231+ if c .Compressed {
232+ header = append (header , "Accept-Encoding" , "deflate, gzip" )
233+ //header = append(header, "Accept-Encoding", "deflate, gzip")
234+ }
235+
236+ if len (dataRaw ) > 0 {
237+ data = dataRaw
238+ }
161239 if len (dataRaw ) > 0 && dataRaw [0 ] == '@' {
162240 fd , err := os .Open (dataRaw [1 :])
163241 if err != nil {
@@ -169,34 +247,26 @@ func (c *Curl) Request() (req *http.Request, err error) {
169247 data = fd
170248 }
171249
172- var g * dataflow.Gout
173- if c .Insecure {
174- g = gout .New (& defaultInsecureSkipVerify )
175- } else {
176- g = gout .New ()
250+ if len (header ) > 0 {
251+ g .SetHeader (header ) //设置http header
177252 }
178253
179- g .SetMethod (c .Method ). //设置method POST or GET or DELETE
180- Debug (true ) //打开debug模式
181-
182- if c .Compressed {
183- header = append (header , "Accept-Encoding" , "deflate, gzip" )
184- //header = append(header, "Accept-Encoding", "deflate, gzip")
254+ if len (form ) > 0 {
255+ g .SetForm (form ) //设置formdata
185256 }
186257
187- if header != nil {
188- g .SetHeader ( header ) //设置http header
258+ if len ( wwwForm ) > 0 {
259+ g .SetWWWForm ( wwwForm ) // 设置x-www-form-urlencoded格式数据
189260 }
190261
191- if len ( form ) > 0 {
192- g .SetForm ( form ) //设置formdata
262+ if data != nil {
263+ g .SetBody ( data )
193264 }
194265
195266 url := c .getURL ()
196267
197268 return g .SetURL (url ). //设置url
198- SetBody (data ). //设置http body
199- Request () //获取*http.Request
269+ Request () //获取*http.Request
200270}
201271
202272func parseSlice (curl []string , c * Curl ) * Curl {
0 commit comments