http.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. package js
  2. import (
  3. "bytes"
  4. "fmt"
  5. "io"
  6. "io/ioutil"
  7. "net/http"
  8. "net/url"
  9. "strings"
  10. "github.com/robertkrimen/otto"
  11. )
  12. type httpPackage struct {
  13. }
  14. type httpResponse struct {
  15. Error error
  16. Response *http.Response
  17. Raw []byte
  18. Body string
  19. JSON interface{}
  20. }
  21. func (c httpPackage) Encode(s string) string {
  22. return url.QueryEscape(s)
  23. }
  24. func (c httpPackage) Request(method string, uri string,
  25. headers map[string]string,
  26. form map[string]string,
  27. json string) httpResponse {
  28. var reader io.Reader
  29. if form != nil {
  30. data := url.Values{}
  31. for k, v := range form {
  32. data.Set(k, v)
  33. }
  34. reader = bytes.NewBufferString(data.Encode())
  35. } else if json != "" {
  36. reader = strings.NewReader(json)
  37. }
  38. req, err := http.NewRequest(method, uri, reader)
  39. if err != nil {
  40. return httpResponse{Error: err}
  41. }
  42. if form != nil {
  43. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  44. } else if json != "" {
  45. req.Header.Set("Content-Type", "application/json")
  46. }
  47. for name, value := range headers {
  48. req.Header.Add(name, value)
  49. }
  50. resp, err := http.DefaultClient.Do(req)
  51. if err != nil {
  52. return httpResponse{Error: err}
  53. }
  54. defer resp.Body.Close()
  55. raw, err := ioutil.ReadAll(resp.Body)
  56. if err != nil {
  57. return httpResponse{Error: err}
  58. }
  59. res := httpResponse{
  60. Response: resp,
  61. Raw: raw,
  62. Body: string(raw),
  63. }
  64. if resp.StatusCode != http.StatusOK {
  65. res.Error = fmt.Errorf("%s", resp.Status)
  66. }
  67. return res
  68. }
  69. func (c httpPackage) Get(url string, headers map[string]string) httpResponse {
  70. return c.Request("GET", url, headers, nil, "")
  71. }
  72. func (c httpPackage) PostForm(url string, headers map[string]string, form map[string]string) httpResponse {
  73. return c.Request("POST", url, headers, form, "")
  74. }
  75. func (c httpPackage) PostJSON(url string, headers map[string]string, json string) httpResponse {
  76. return c.Request("POST", url, headers, nil, json)
  77. }
  78. func httpRequest(call otto.FunctionCall) otto.Value {
  79. argv := call.ArgumentList
  80. argc := len(argv)
  81. if argc < 2 {
  82. return ReportError("httpRequest: expected 2 or more, %d given instead.", argc)
  83. }
  84. method := argv[0].String()
  85. url := argv[1].String()
  86. client := &http.Client{}
  87. req, err := http.NewRequest(method, url, nil)
  88. if argc >= 3 {
  89. data := argv[2].String()
  90. req, err = http.NewRequest(method, url, bytes.NewBuffer([]byte(data)))
  91. if err != nil {
  92. return ReportError("Could create request to url %s: %s", url, err)
  93. }
  94. if argc > 3 {
  95. headers := argv[3].Object()
  96. for _, key := range headers.Keys() {
  97. v, err := headers.Get(key)
  98. if err != nil {
  99. return ReportError("Could add header %s to request: %s", key, err)
  100. }
  101. req.Header.Add(key, v.String())
  102. }
  103. }
  104. } else if err != nil {
  105. return ReportError("Could create request to url %s: %s", url, err)
  106. }
  107. resp, err := client.Do(req)
  108. if err != nil {
  109. return ReportError("Could not request url %s: %s", url, err)
  110. }
  111. defer resp.Body.Close()
  112. body, err := ioutil.ReadAll(resp.Body)
  113. if err != nil {
  114. return ReportError("Could not read response: %s", err)
  115. }
  116. object, err := otto.New().Object("({})")
  117. if err != nil {
  118. return ReportError("Could not create response object: %s", err)
  119. }
  120. err = object.Set("body", string(body))
  121. if err != nil {
  122. return ReportError("Could not populate response object: %s", err)
  123. }
  124. v, err := otto.ToValue(object)
  125. if err != nil {
  126. return ReportError("Could not convert to object: %s", err)
  127. }
  128. return v
  129. }