105 lines
2.2 KiB
Go
105 lines
2.2 KiB
Go
package http
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"regexp"
|
|
"time"
|
|
|
|
"github.com/hashicorp/terraform/helper/schema"
|
|
)
|
|
|
|
func dataSource() *schema.Resource {
|
|
return &schema.Resource{
|
|
Read: dataSourceRead,
|
|
|
|
Schema: map[string]*schema.Schema{
|
|
"url": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Required: true,
|
|
Elem: &schema.Schema{
|
|
Type: schema.TypeString,
|
|
},
|
|
},
|
|
|
|
"request_headers": &schema.Schema{
|
|
Type: schema.TypeMap,
|
|
Optional: true,
|
|
Elem: &schema.Schema{
|
|
Type: schema.TypeString,
|
|
},
|
|
},
|
|
|
|
"body": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Computed: true,
|
|
Elem: &schema.Schema{
|
|
Type: schema.TypeString,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func dataSourceRead(d *schema.ResourceData, meta interface{}) error {
|
|
|
|
url := d.Get("url").(string)
|
|
headers := d.Get("request_headers").(map[string]interface{})
|
|
|
|
client := &http.Client{}
|
|
|
|
req, err := http.NewRequest("GET", url, nil)
|
|
if err != nil {
|
|
return fmt.Errorf("Error creating request: %s", err)
|
|
}
|
|
|
|
for name, value := range headers {
|
|
req.Header.Set(name, value.(string))
|
|
}
|
|
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
return fmt.Errorf("Error during making a request: %s", url)
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != 200 {
|
|
return fmt.Errorf("HTTP request error. Response code: %d", resp.StatusCode)
|
|
}
|
|
|
|
contentType := resp.Header.Get("Content-Type")
|
|
if contentType == "" || isContentTypeAllowed(contentType) == false {
|
|
return fmt.Errorf("Content-Type is not a text type. Got: %s", contentType)
|
|
}
|
|
|
|
bytes, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return fmt.Errorf("Error while reading response body. %s", err)
|
|
}
|
|
|
|
d.Set("body", string(bytes))
|
|
d.SetId(time.Now().UTC().String())
|
|
|
|
return nil
|
|
}
|
|
|
|
// This is to prevent potential issues w/ binary files
|
|
// and generally unprintable characters
|
|
// See https://github.com/hashicorp/terraform/pull/3858#issuecomment-156856738
|
|
func isContentTypeAllowed(contentType string) bool {
|
|
allowedContentTypes := []*regexp.Regexp{
|
|
regexp.MustCompile("^text/.+"),
|
|
regexp.MustCompile("^application/json$"),
|
|
}
|
|
|
|
for _, r := range allowedContentTypes {
|
|
if r.MatchString(contentType) {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|