github.com/nathanielks/terraform@v0.6.1-0.20170509030759-13e1a62319dc/builtin/providers/http/data_source.go (about) 1 package http 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "net/http" 7 "regexp" 8 "time" 9 10 "github.com/hashicorp/terraform/helper/schema" 11 ) 12 13 func dataSource() *schema.Resource { 14 return &schema.Resource{ 15 Read: dataSourceRead, 16 17 Schema: map[string]*schema.Schema{ 18 "url": &schema.Schema{ 19 Type: schema.TypeString, 20 Required: true, 21 Elem: &schema.Schema{ 22 Type: schema.TypeString, 23 }, 24 }, 25 26 "request_headers": &schema.Schema{ 27 Type: schema.TypeMap, 28 Optional: true, 29 Elem: &schema.Schema{ 30 Type: schema.TypeString, 31 }, 32 }, 33 34 "body": &schema.Schema{ 35 Type: schema.TypeString, 36 Computed: true, 37 Elem: &schema.Schema{ 38 Type: schema.TypeString, 39 }, 40 }, 41 }, 42 } 43 } 44 45 func dataSourceRead(d *schema.ResourceData, meta interface{}) error { 46 47 url := d.Get("url").(string) 48 headers := d.Get("request_headers").(map[string]interface{}) 49 50 client := &http.Client{} 51 52 req, err := http.NewRequest("GET", url, nil) 53 if err != nil { 54 return fmt.Errorf("Error creating request: %s", err) 55 } 56 57 for name, value := range headers { 58 req.Header.Set(name, value.(string)) 59 } 60 61 resp, err := client.Do(req) 62 if err != nil { 63 return fmt.Errorf("Error during making a request: %s", url) 64 } 65 66 defer resp.Body.Close() 67 68 if resp.StatusCode != 200 { 69 return fmt.Errorf("HTTP request error. Response code: %d", resp.StatusCode) 70 } 71 72 contentType := resp.Header.Get("Content-Type") 73 if contentType == "" || isContentTypeAllowed(contentType) == false { 74 return fmt.Errorf("Content-Type is not a text type. Got: %s", contentType) 75 } 76 77 bytes, err := ioutil.ReadAll(resp.Body) 78 if err != nil { 79 return fmt.Errorf("Error while reading response body. %s", err) 80 } 81 82 d.Set("body", string(bytes)) 83 d.SetId(time.Now().UTC().String()) 84 85 return nil 86 } 87 88 // This is to prevent potential issues w/ binary files 89 // and generally unprintable characters 90 // See https://github.com/hashicorp/terraform/pull/3858#issuecomment-156856738 91 func isContentTypeAllowed(contentType string) bool { 92 allowedContentTypes := []*regexp.Regexp{ 93 regexp.MustCompile("^text/.+"), 94 regexp.MustCompile("^application/json$"), 95 } 96 97 for _, r := range allowedContentTypes { 98 if r.MatchString(contentType) { 99 return true 100 } 101 } 102 103 return false 104 }