curl.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. package subcmd
  2. import (
  3. "fmt"
  4. "log"
  5. "net/http"
  6. "net/url"
  7. "regexp"
  8. "strings"
  9. "time"
  10. "github.com/alecthomas/kingpin"
  11. "github.com/codeskyblue/goreq"
  12. )
  13. type HTTPHeaderValue http.Header
  14. func (h *HTTPHeaderValue) Set(value string) error {
  15. parts := strings.SplitN(value, ":", 2)
  16. if len(parts) != 2 {
  17. return fmt.Errorf("expected HEADER:VALUE got '%s'", value)
  18. }
  19. (*http.Header)(h).Add(parts[0], parts[1])
  20. return nil
  21. }
  22. func (h *HTTPHeaderValue) String() string {
  23. return ""
  24. }
  25. func (h *HTTPHeaderValue) IsCumulative() bool {
  26. return true
  27. }
  28. func HTTPHeader(s kingpin.Settings) (target *http.Header) {
  29. target = &http.Header{}
  30. s.SetValue((*HTTPHeaderValue)(target))
  31. return
  32. }
  33. type HTTPURLValue url.Values
  34. func (h *HTTPURLValue) Set(value string) error {
  35. parts := strings.SplitN(value, "=", 2)
  36. if len(parts) != 2 {
  37. return fmt.Errorf("expected KEY=VALUE got '%s'", value)
  38. }
  39. (*url.Values)(h).Add(parts[0], parts[1])
  40. return nil
  41. }
  42. func (h *HTTPURLValue) String() string {
  43. return ""
  44. }
  45. func (h *HTTPURLValue) IsCumulative() bool {
  46. return true
  47. }
  48. func HTTPValue(s kingpin.Settings) (target *url.Values) {
  49. target = &url.Values{}
  50. s.SetValue((*HTTPURLValue)(target))
  51. return
  52. }
  53. var (
  54. method string
  55. reqUrl string
  56. headers *http.Header
  57. values *url.Values
  58. bodyData string
  59. duration time.Duration
  60. )
  61. func RegisterCurl(curl *kingpin.CmdClause) {
  62. curl.Flag("request", "Specify request command to use").Short('X').Default("GET").StringVar(&method)
  63. curl.Arg("url", "url string").Required().StringVar(&reqUrl)
  64. curl.Flag("data", "body data").StringVar(&bodyData)
  65. curl.Flag("timeout", "timeout send and receive response").Default("10s").DurationVar(&duration)
  66. headers = HTTPHeader(curl.Flag("header", "Add a HTTP header to the request.").Short('H'))
  67. values = HTTPValue(curl.Flag("form", "Add a HTTP form values").Short('F'))
  68. }
  69. func DoCurl() {
  70. if !regexp.MustCompile(`^https?://`).MatchString(reqUrl) {
  71. reqUrl = "http://" + reqUrl
  72. }
  73. request := goreq.Request{
  74. Method: method,
  75. Uri: reqUrl,
  76. }
  77. request.ShowDebug = true
  78. request.Timeout = duration
  79. for k, values := range *headers {
  80. for _, v := range values {
  81. request.AddHeader(k, v)
  82. }
  83. }
  84. if method == "GET" {
  85. request.QueryString = *values
  86. } else if method == "POST" {
  87. request.AddHeader("Content-Type", "application/x-www-form-urlencoded")
  88. if bodyData != "" {
  89. request.Body = bodyData
  90. } else {
  91. request.Body = *values
  92. }
  93. } else {
  94. log.Fatalf("Unsupported method: %s", method)
  95. }
  96. res, err := request.Do()
  97. if err != nil {
  98. log.Fatal(err)
  99. }
  100. log.Println(res.Body.ToString())
  101. }