Exemple #1
0
func makeRequest(testCase plan.TestCase) ([]byte, error) {
	callURL, err := url.Parse(fmt.Sprintf("http://%v:8080/", testCase.Client))
	if err != nil {
		return []byte(""), err
	}

	args := url.Values{}
	for k, v := range testCase.Arguments {
		args.Add(k, v)
	}
	callURL.RawQuery = args.Encode()

	ctx, _ := context.WithTimeout(
		context.Background(), testCase.Plan.Config.CallTimeout*time.Second)
	resp, err := ctxhttp.Get(ctx, nil, callURL.String())
	if err != nil {
		return []byte(""), err
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return []byte(""), err
	}

	if resp.StatusCode != 200 {
		return []byte(""), fmt.Errorf("wanted status code 200, got %v", resp.StatusCode)
	}

	return body, nil
}
Exemple #2
0
// Lookup returns rectangles for the given address. Currently the only
// implementation is the Google geocoding service.
func Lookup(ctx context.Context, address string) ([]Rect, error) {
	mu.RLock()
	rects, ok := cache[address]
	mu.RUnlock()
	if ok {
		return rects, nil
	}

	rectsi, err := sf.Do(address, func() (interface{}, error) {
		// TODO: static data files from OpenStreetMap, Wikipedia, etc?
		urlStr := "https://maps.googleapis.com/maps/api/geocode/json?address=" + url.QueryEscape(address) + "&sensor=false"
		res, err := ctxhttp.Get(ctx, ctxutil.Client(ctx), urlStr)
		if err != nil {
			return nil, err
		}
		defer res.Body.Close()
		rects, err := decodeGoogleResponse(res.Body)
		log.Printf("Google geocode lookup (%q) = %#v, %v", address, rects, err)
		if err == nil {
			mu.Lock()
			cache[address] = rects
			mu.Unlock()
		}
		return rects, err
	})
	if err != nil {
		return nil, err
	}
	return rectsi.([]Rect), nil
}
Exemple #3
0
// ContentWithContext is a helper to abstract the location concept (not thread safe)
func (obj *Object) ContentWithContext(ctx context.Context) ([]byte, error) {
	if obj == nil {
		return nil, nil
	}
	if len(obj.Blob) > 0 || obj.Location == "" {
		return obj.Blob, nil
	}
	resp, err := ctxhttp.Get(ctx, nil, obj.Location)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return nil, errors.New(resp.Status)
	}
	ct := resp.Header.Get("Content-Type")
	if ct != "" {
		obj.ContentType = ct
	}
	blob, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	obj.Blob = blob
	return blob, nil
}
Exemple #4
0
func (ds *Datasource) fetchIntervalState(ctx context.Context, interval string, n int) (State, error) {
	var url string
	if n != 0 {
		url = ds.baseIntervalURL(interval, n) + ".state.txt"
	} else {
		url = fmt.Sprintf("%s/replication/%s/state.txt", ds.baseURL(), interval)
	}

	resp, err := ctxhttp.Get(ctx, ds.client(), url)
	if err != nil {
		return State{}, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return State{}, fmt.Errorf("incorrect status code: %v", resp.StatusCode)
	}

	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return State{}, err
	}

	return decodeIntervalState(data, interval)
}
Exemple #5
0
// PluginGetURL fetches the content of a URL, which could be static or dynamic (passed in).
// It only works with an api with a simple Text/Text signature.
func PluginGetURL(static bool, uri string, model interface{}) Plugin {
	if static {
		if uri == "" {
			return nil
		}
	}
	return func(ctx context.Context, in interface{}) (out interface{}, err error) {
		inb, err := TextBytes(in)
		if err != nil {
			return nil, err
		}
		ins := string(inb)
		if static {
			ins = uri
		}
		resp, err := ctxhttp.Get(ctx, http.DefaultClient, ins) // handles context.Done() correctly
		if err != nil {
			return nil, err
		}
		byts, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			return nil, err // unable to create a simple test case for this error
		}
		err = resp.Body.Close()
		if err != nil {
			return nil, err // unable to create a simple test case for this error
		}
		return TextConvert(byts, model)
	}
}
Exemple #6
0
// Login takes a Hover username and password and returns the login cookie value
func Login(ctx context.Context, hc *http.Client, username, password string) (*http.Cookie, error) {
	v := make(url.Values)
	v.Set("username", username)
	v.Set("password", password)

	r, err := ctxhttp.Get(ctx, hc, fmt.Sprintf("%s/login?%s", defaultURL, v.Encode()))
	if err != nil {
		return nil, err
	}
	defer r.Body.Close()

	if r.StatusCode != 200 {
		return nil, InvalidLogin(fmt.Sprintf("login HTTP status code was %d", r.StatusCode))
	}
	var c *http.Cookie
	for _, cook := range r.Cookies() {
		if cook.Name == "hoverauth" && cook.Value != "" {
			c = cook
			break
		}
	}
	if c == nil {
		return nil, InvalidLogin("unable to find 'hoverauth' cookie with data in response")
	}
	return c, nil
}
// queryCAA sends the query request to the GPD API. If the return code is
// dns.RcodeSuccess the 'Answer' section is parsed for CAA records, otherwise
// an error is returned. Unlike bdns.DNSResolver.LookupCAA it will not repeat
// failed queries if the context has not expired as we expect to be running
// multiple queries in parallel and only need a M of N quorum (we also expect
// GPD to have quite good availability)
func (cdr *CAADistributedResolver) queryCAA(ctx context.Context, url string, ic *http.Client) ([]*dns.CAA, error) {
	apiResp, err := ctxhttp.Get(ctx, ic, url)
	if err != nil {
		return nil, err
	}
	defer func() {
		_ = apiResp.Body.Close()
	}()
	body, err := ioutil.ReadAll(&io.LimitedReader{R: apiResp.Body, N: 1024})
	if err != nil {
		return nil, err
	}
	if apiResp.StatusCode != http.StatusOK {
		if string(body) != "" {
			return nil, fmt.Errorf("Unexpected HTTP status code %d, body: %s", apiResp.StatusCode, body)
		}
		return nil, fmt.Errorf("Unexpected HTTP status code %d", apiResp.StatusCode)
	}
	var respObj core.GPDNSResponse
	err = json.Unmarshal(body, &respObj)
	if err != nil {
		return nil, err
	}
	if respObj.Status != dns.RcodeSuccess {
		if respObj.Comment != "" {
			return nil, fmt.Errorf("Query failed with %s: %s", dns.RcodeToString[respObj.Status], respObj.Comment)
		}
		return nil, fmt.Errorf("Query failed wtih %s", dns.RcodeToString[respObj.Status])
	}

	return parseAnswer(respObj.Answer)
}
Exemple #8
0
// FetchCert retrieves already issued certificate from the given url, in DER format.
// It retries the request until the certificate is successfully retrieved,
// context is cancelled by the caller or an error response is received.
//
// The returned value will also contain the CA (issuer) certificate if the bundle argument is true.
//
// FetchCert returns an error if the CA's response or chain was unreasonably large.
// Callers are encouraged to parse the returned value to ensure the certificate is valid
// and has expected features.
func (c *Client) FetchCert(ctx context.Context, url string, bundle bool) ([][]byte, error) {
	for {
		res, err := ctxhttp.Get(ctx, c.HTTPClient, url)
		if err != nil {
			return nil, err
		}
		defer res.Body.Close()
		if res.StatusCode == http.StatusOK {
			return responseCert(ctx, c.HTTPClient, res, bundle)
		}
		if res.StatusCode > 299 {
			return nil, responseError(res)
		}
		d, err := retryAfter(res.Header.Get("retry-after"))
		if err != nil {
			d = 3 * time.Second
		}
		select {
		case <-time.After(d):
			// retry
		case <-ctx.Done():
			return nil, ctx.Err()
		}
	}
}
Exemple #9
0
func testOnGCE() bool {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	resc := make(chan bool, 2)

	// Try two strategies in parallel.
	// See https://github.com/GoogleCloudPlatform/gcloud-golang/issues/194
	go func() {
		res, err := ctxhttp.Get(ctx, metaClient, "http://"+metadataIP)
		if err != nil {
			resc <- false
			return
		}
		defer res.Body.Close()
		resc <- res.Header.Get("Metadata-Flavor") == "Google"
	}()

	go func() {
		addrs, err := net.LookupHost("metadata.google.internal")
		if err != nil || len(addrs) == 0 {
			resc <- false
			return
		}
		resc <- strsContains(addrs, metadataIP)
	}()

	return <-resc
}
func TestContextCancel(t *testing.T) {
	// server that doesn't reply before the timeout
	wg := sync.WaitGroup{}
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		time.Sleep(2 * time.Second)
		fmt.Fprint(w, r.URL.Path)
		wg.Done()
	}))
	defer srv.Close()

	tr := NewTransport(nil, RetryAll(RetryMaxRetries(1), RetryStatusInterval(500, 600)), ConstDelay(0))
	c := &http.Client{
		Transport: tr,
	}

	ctx, cancelFn := context.WithDeadline(context.Background(), time.Now().Add(time.Second))
	defer cancelFn()

	wg.Add(1)
	res, err := ctxhttp.Get(ctx, c, srv.URL+"/test")
	require.Nil(t, res)

	assert.Equal(t, context.DeadlineExceeded, err)
	wg.Wait()
}
Exemple #11
0
// NewProvider uses the OpenID Connect discovery mechanism to construct a Provider.
//
// The issuer is the URL identifier for the service. For example: "https://accounts.google.com"
// or "https://login.salesforce.com".
func NewProvider(ctx context.Context, issuer string) (*Provider, error) {
	wellKnown := strings.TrimSuffix(issuer, "/") + "/.well-known/openid-configuration"
	resp, err := ctxhttp.Get(ctx, clientFromContext(ctx), wellKnown)
	if err != nil {
		return nil, err
	}
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("%s: %s", resp.Status, body)
	}
	defer resp.Body.Close()
	var p providerJSON
	if err := json.Unmarshal(body, &p); err != nil {
		return nil, fmt.Errorf("oidc: failed to decode provider discovery object: %v", err)
	}
	if p.Issuer != issuer {
		return nil, fmt.Errorf("oidc: issuer did not match the issuer returned by provider, expected %q got %q", issuer, p.Issuer)
	}
	return &Provider{
		issuer:       p.Issuer,
		authURL:      p.AuthURL,
		tokenURL:     p.TokenURL,
		userInfoURL:  p.UserInfoURL,
		rawClaims:    body,
		remoteKeySet: newRemoteKeySet(ctx, p.JWKSURL, time.Now),
	}, nil
}
func TestContextCancelOnRetry(t *testing.T) {
	callCnt := int32(0)
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		cnt := atomic.AddInt32(&callCnt, 1)
		switch cnt {
		case 1:
			w.WriteHeader(500)
		default:
			time.Sleep(2 * time.Second)
			fmt.Fprint(w, r.URL.Path)
		}
	}))
	defer srv.Close()

	// cancel while waiting on retry response
	tr := NewTransport(nil, RetryAll(RetryMaxRetries(1), RetryStatusInterval(500, 600)), ConstDelay(0))
	c := &http.Client{
		Transport: tr,
	}

	ctx, cancelFn := context.WithDeadline(context.Background(), time.Now().Add(time.Second))
	defer cancelFn()

	res, err := ctxhttp.Get(ctx, c, srv.URL+"/test")
	require.Nil(t, res)

	assert.Equal(t, context.DeadlineExceeded, err)
	assert.Equal(t, int32(2), atomic.LoadInt32(&callCnt))

	// cancel while waiting on delay
	atomic.StoreInt32(&callCnt, 0)
	tr = NewTransport(nil, RetryAll(RetryMaxRetries(1), RetryStatusInterval(500, 600)), ConstDelay(2*time.Second))
	c = &http.Client{
		Transport: tr,
	}

	ctx, cancelFn = context.WithDeadline(context.Background(), time.Now().Add(time.Second))
	defer cancelFn()

	res, err = ctxhttp.Get(ctx, c, srv.URL+"/test")
	require.Nil(t, res)

	assert.Equal(t, context.DeadlineExceeded, err)
	assert.Equal(t, int32(1), atomic.LoadInt32(&callCnt))
}
Exemple #13
0
func NewTHttpClientWithCtx(urlstr string, ctx context.Context) (TTransport, error) {
	parsedURL, err := url.Parse(urlstr)
	if err != nil {
		return nil, err
	}

	response, err := ctxhttp.Get(ctx, nil, urlstr)
	if err != nil {
		return nil, err
	}
	return &THttpClient{response: response, url: parsedURL, ctx: ctx}, nil
}
Exemple #14
0
func (c *ArtifactStoreClient) getAPI(path string) (io.ReadCloser, *ArtifactsError) {
	url := c.server + path
	ctx, cancel := context.WithTimeout(c.ctx, c.timeout)
	defer cancel()

	if resp, err := ctxhttp.Get(ctx, nil, url); err != nil {
		return nil, NewRetriableError(err.Error())
	} else {
		if resp.StatusCode != http.StatusOK {
			return nil, determineResponseError(resp, url, "POST")
		}
		return resp.Body, nil
	}
}
Exemple #15
0
// WaitAuthorization polls an authorization at the given URL
// until it is in one of the final states, StatusValid or StatusInvalid,
// or the context is done.
//
// It returns a non-nil Authorization only if its Status is StatusValid.
// In all other cases WaitAuthorization returns an error.
// If the Status is StatusInvalid, the returned error is ErrAuthorizationFailed.
func (c *Client) WaitAuthorization(ctx context.Context, url string) (*Authorization, error) {
	var count int
	sleep := func(v string, inc int) error {
		count += inc
		d := backoff(count, 10*time.Second)
		d = retryAfter(v, d)
		wakeup := time.NewTimer(d)
		defer wakeup.Stop()
		select {
		case <-ctx.Done():
			return ctx.Err()
		case <-wakeup.C:
			return nil
		}
	}

	for {
		res, err := ctxhttp.Get(ctx, c.HTTPClient, url)
		if err != nil {
			return nil, err
		}
		retry := res.Header.Get("retry-after")
		if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted {
			res.Body.Close()
			if err := sleep(retry, 1); err != nil {
				return nil, err
			}
			continue
		}
		var raw wireAuthz
		err = json.NewDecoder(res.Body).Decode(&raw)
		res.Body.Close()
		if err != nil {
			if err := sleep(retry, 0); err != nil {
				return nil, err
			}
			continue
		}
		if raw.Status == StatusValid {
			return raw.authorization(url), nil
		}
		if raw.Status == StatusInvalid {
			return nil, ErrAuthorizationFailed
		}
		if err := sleep(retry, 0); err != nil {
			return nil, err
		}
	}
}
Exemple #16
0
func (f Fetcher) GetAll(ctx context.Context, urls []string) ([]*FetcherResponse, error) {
	defer metrics.MeasureSince([]string{"fn.FetchRemoteData"}, time.Now())

	fetches := make([]*FetcherResponse, len(urls))

	var wg sync.WaitGroup
	wg.Add(len(urls))

	// TODO: add thruput here..

	for i, urlStr := range urls {
		fetches[i] = &FetcherResponse{}

		go func(fetch *FetcherResponse) {
			defer wg.Done()

			url, err := urlx.Parse(urlStr)
			if err != nil {
				fetch.Err = err
				return
			}
			fetch.URL = url

			lg.Infof("Fetching %s", url.String())

			resp, err := ctxhttp.Get(ctx, f.client(), url.String())
			if err != nil {
				lg.Warnf("Error fetching %s because %s", url.String(), err)
				fetch.Err = err
				return
			}
			defer resp.Body.Close()

			fetch.Status = resp.StatusCode

			body, err := ioutil.ReadAll(resp.Body)
			if err != nil {
				fetch.Err = err
				return
			}
			fetch.Data = body
			fetch.Err = nil

		}(fetches[i])
	}

	wg.Wait()
	return fetches, nil
}
Exemple #17
0
// GetChallenge retrieves the current status of an challenge.
//
// A client typically polls a challenge status using this method.
func (c *Client) GetChallenge(ctx context.Context, url string) (*Challenge, error) {
	res, err := ctxhttp.Get(ctx, c.HTTPClient, url)
	if err != nil {
		return nil, err
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted {
		return nil, responseError(res)
	}
	v := wireChallenge{URI: url}
	if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
		return nil, fmt.Errorf("acme: invalid response: %v", err)
	}
	return v.challenge(), nil
}
Exemple #18
0
// GetAuthorization retrieves an authorization identified by the given URL.
//
// If a caller needs to poll an authorization until its status is final,
// see the WaitAuthorization method.
func (c *Client) GetAuthorization(ctx context.Context, url string) (*Authorization, error) {
	res, err := ctxhttp.Get(ctx, c.HTTPClient, url)
	if err != nil {
		return nil, err
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted {
		return nil, responseError(res)
	}
	var v wireAuthz
	if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
		return nil, fmt.Errorf("acme: invalid response: %v", err)
	}
	return v.authorization(url), nil
}
Exemple #19
0
func (h *HttpProbe) Probe(c ctx.Context) error {
	resp, err := http.Get(c, nil, h.url)
	if err != nil {
		return ErrNotReachable
	} else {
		go func() {
			defer resp.Body.Close()
			io.Copy(ioutil.Discard, resp.Body)
		}()
		if resp.StatusCode != 200 {
			return fmt.Errorf("%d: %s", resp.StatusCode, h.url)
		} else {
			return nil
		}
	}
}
Exemple #20
0
func handleAddBookmark(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	var input struct {
		Url string `json:"url"`
	}
	if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
		web.JSONErr(w, err.Error(), http.StatusBadRequest)
		return
	}

	resp, err := ctxhttp.Get(ctx, &crawler, input.Url)
	if err != nil {
		log.Error("cannot crawl",
			"url", input.Url,
			"error", err.Error())
		web.StdJSONResp(w, http.StatusInternalServerError)
		return
	}
	defer resp.Body.Close()

	body := make([]byte, 1024*20)
	if n, err := resp.Body.Read(body); err != nil && err != io.EOF {
		log.Error("cannot read crawler response",
			"url", input.Url,
			"error", err.Error())
		web.StdJSONResp(w, http.StatusInternalServerError)
		return
	} else {
		body = body[:n]
	}

	title := pageTitle(body)

	var b Bookmark
	err = pg.DB(ctx).Get(&b, `
		INSERT INTO bookmarks (title, url, created)
		VALUES ($1, $2, $3)
		ON CONFLICT DO NOTHING
		RETURNING *
	`, title, input.Url, time.Now())
	if err != nil {
		log.Error("cannot create bookmark", "error", err.Error())
		web.StdJSONResp(w, http.StatusInternalServerError)
		return
	}

	web.JSONResp(w, b, http.StatusCreated)
}
Exemple #21
0
// changesetReader will return a ReadCloser with the data from the changeset.
// It will be gzip compressed, so the caller must decompress.
// It is the caller's responsibility to call Close on the Reader when done.
func (ds *Datasource) changesetReader(ctx context.Context, n ChangesetSeqNum) (io.ReadCloser, error) {
	url := ds.changesetURL(n)
	resp, err := ctxhttp.Get(ctx, ds.client(), url)
	if err != nil {
		return nil, err
	}

	if resp.StatusCode != 200 {
		resp.Body.Close()
		return nil, &UnexpectedStatusCodeError{
			Code: resp.StatusCode,
			URL:  url,
		}
	}

	return resp.Body, nil
}
Exemple #22
0
func unsealInstance(ctx context.Context, instance string) error {
	s := sealStatus{}
	r, err := ctxhttp.Get(ctx, http.DefaultClient, instance+"/v1/sys/seal-status")
	if err != nil {
		return fmt.Errorf("[%s] An error ocurred while reading seal-status: %s", instance, err)
	}
	defer r.Body.Close()

	if err := json.NewDecoder(r.Body).Decode(&s); err != nil {
		return fmt.Errorf("[%s] Unable to decode seal-status: %s", instance, err)
	}

	if s.Sealed {
		for _, token := range config.SealTokens {
			log.Printf("[%s] Vault instance is sealed (missing %d tokens), trying to unlock...", instance, s.T-s.Progress)
			body := bytes.NewBuffer([]byte{})
			json.NewEncoder(body).Encode(map[string]interface{}{
				"key": token,
			})
			r, _ := http.NewRequest("PUT", instance+"/v1/sys/unseal", body)
			resp, err := ctxhttp.Do(ctx, http.DefaultClient, r)
			if err != nil {
				return fmt.Errorf("[%s] An error ocurred while doing unseal: %s", instance, err)
			}
			defer resp.Body.Close()

			if err := json.NewDecoder(resp.Body).Decode(&s); err != nil {
				return fmt.Errorf("[%s] Unable to decode seal-status: %s", instance, err)
			}

			if !s.Sealed {
				log.Printf("[%s] Unseal successfully finished.", instance)
				break
			}
		}

		if s.Sealed {
			log.Printf("[%s] Vault instance is still sealed (missing %d tokens), I don't have any more tokens.", instance, s.T-s.Progress)
		}
	} else {
		log.Printf("[%s] Vault instance is already unsealed.", instance)
	}

	return nil
}
Exemple #23
0
// Discover performs ACME server discovery using c.DirectoryURL.
//
// It caches successful result. So, subsequent calls will not result in
// a network round-trip. This also means mutating c.DirectoryURL after successful call
// of this method will have no effect.
func (c *Client) Discover(ctx context.Context) (Directory, error) {
	c.dirMu.Lock()
	defer c.dirMu.Unlock()
	if c.dir != nil {
		return *c.dir, nil
	}

	dirURL := c.DirectoryURL
	if dirURL == "" {
		dirURL = LetsEncryptURL
	}
	res, err := ctxhttp.Get(ctx, c.HTTPClient, dirURL)
	if err != nil {
		return Directory{}, err
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusOK {
		return Directory{}, responseError(res)
	}

	var v struct {
		Reg    string `json:"new-reg"`
		Authz  string `json:"new-authz"`
		Cert   string `json:"new-cert"`
		Revoke string `json:"revoke-cert"`
		Meta   struct {
			Terms   string   `json:"terms-of-service"`
			Website string   `json:"website"`
			CAA     []string `json:"caa-identities"`
		}
	}
	if json.NewDecoder(res.Body).Decode(&v); err != nil {
		return Directory{}, err
	}
	c.dir = &Directory{
		RegURL:    v.Reg,
		AuthzURL:  v.Authz,
		CertURL:   v.Cert,
		RevokeURL: v.Revoke,
		Terms:     v.Meta.Terms,
		Website:   v.Meta.Website,
		CAA:       v.Meta.CAA,
	}
	return *c.dir, nil
}
Exemple #24
0
func ListProxyReq() (output chan *Response) {
	var (
		wg sync.WaitGroup

		root = ctx.Background()

		v = make(chan *Response, 1)
	)

	go func() {
		defer close(v)

		for _, endpoint := range Endpoint {
			wg.Add(1)
			go func(ep string) {
				defer wg.Done()

				wk, abort := ctx.WithTimeout(root, DefaultTimeout)
				defer abort()

				resp, err := ctxhttp.Get(wk, nil, ep+"/proxy/list")
				if err != nil {
					v <- &Response{Host: ep, Err: err}
					return
				}
				defer resp.Body.Close()

				inn := new(bytes.Buffer)
				_, err = inn.ReadFrom(resp.Body)
				if err != nil {
					v <- &Response{Host: ep, Err: err}
					return
				}

				v <- &Response{Host: ep, Data: inn.Bytes()}

			}(endpoint)
		}
		wg.Wait()
	}()

	return v
}
Exemple #25
0
func (ds *Datasource) fetchIntervalData(ctx context.Context, url string) (*osm.Change, error) {
	resp, err := ctxhttp.Get(ctx, ds.client(), url)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("incorrect status code: %v", resp.StatusCode)
	}

	gzReader, err := gzip.NewReader(resp.Body)
	if err != nil {
		return nil, err
	}
	defer gzReader.Close()

	change := &osm.Change{}
	err = xml.NewDecoder(gzReader).Decode(change)
	return change, err
}
Exemple #26
0
func (p *Plugin) get(path string, params url.Values, result interface{}) error {
	// Context here lets us either timeout req. or cancel it in Plugin.Close
	ctx, cancel := context.WithTimeout(p.context, pluginTimeout)
	defer cancel()
	resp, err := ctxhttp.Get(ctx, p.client, fmt.Sprintf("http://plugin%s?%s", path, params.Encode()))
	if err != nil {
		return err
	}
	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("plugin returned non-200 status code: %s", resp.Status)
	}
	defer resp.Body.Close()
	err = codec.NewDecoder(MaxBytesReader(resp.Body, maxResponseBytes, errResponseTooLarge), &codec.JsonHandle{}).Decode(&result)
	if err == errResponseTooLarge {
		return err
	}
	if err != nil {
		return fmt.Errorf("decoding error: %s", err)
	}
	return nil
}
Exemple #27
0
func (n *Ngrok) Start(subdomain, localAddr string) (string, error) {
	if n.process != nil {
		return "", errors.New("ngrok tunnel is already running")
	}

	if subdomain == "" {
		subdomain = utils.RandString(12)
	}

	p := n.cmd("-log", "stdout", "-authtoken", Test.NgrokToken, "-subdomain", subdomain, localAddr)
	if err := p.Start(); err != nil {
		return "", err
	}

	// wait for tunnel to get up
	tunnelHost := subdomain + ".ngrok.com"
	tunnelURL := "http://" + tunnelHost
	ctx, cancel := context.WithTimeout(context.Background(), n.StartTimeout)
	defer cancel()

	for {
		resp, err := ctxhttp.Get(ctx, nil, tunnelURL)
		if err == context.DeadlineExceeded {
			return "", fmt.Errorf("timed out after %s waiting for %s to be ready", n.StartTimeout, tunnelURL)
		}
		if err == nil {
			resp.Body.Close()

			// 404 means tunnel not found
			if resp.StatusCode != http.StatusNotFound {
				n.process = p
				return tunnelHost, nil
			}
		}

		time.Sleep(1 * time.Second)
	}
}
Exemple #28
0
func get(ctx context.Context, client *http.Client, url string) (gonzo.File, error) {

	resp, err := ctxhttp.Get(ctx, client, url)
	if err != nil {
		return nil, err
	}

	if resp.StatusCode < 200 || resp.StatusCode > 399 {
		return nil, fmt.Errorf("%s (%s)", resp.Status, url)
	}

	_, params, err := mime.ParseMediaType(resp.Header.Get("Content-Disposition"))
	name, ok := params["filename"]
	if !ok || err != nil {
		name = path.Base(url)
	}

	file := gonzo.NewFile(resp.Body, gonzo.NewFileInfo())
	file.FileInfo().SetName(name)
	file.FileInfo().SetSize(resp.ContentLength)

	return file, nil
}
Exemple #29
0
// CurrentChangesetState returns the current state of the changeset replication.
func (ds *Datasource) CurrentChangesetState(ctx context.Context) (ChangesetSeqNum, State, error) {
	url := ds.baseURL() + "/replication/changesets/state.yaml"
	resp, err := ctxhttp.Get(ctx, ds.client(), url)
	if err != nil {
		return 0, State{}, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return 0, State{}, &UnexpectedStatusCodeError{
			Code: resp.StatusCode,
			URL:  url,
		}
	}

	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return 0, State{}, err
	}

	s, err := decodeChangesetState(data)
	return ChangesetSeqNum(s.SeqNum), s, err
}
Exemple #30
0
// Ready returns true if the API is ready
func (f *Forensiq) Ready(ctx context.Context) (bool, error) {
	var (
		uri *url.URL
		b   []byte
		err error
		sts = xstats.FromContext(ctx)
	)

	{
		uri, err = url.Parse(f.Host)
		if err != nil {
			return false, err
		}
		uri.Path = "/ready"
	}

	{
		begin := time.Now()
		resp, err := ctxhttp.Get(ctx, f.httpClient, uri.String())
		if err != nil {
			return false, err
		}
		defer resp.Body.Close()
		sts.Timing("forensiq.request_time", time.Since(begin),
			"request:ready",
			"status:"+responseStatus(ctx, resp.StatusCode),
			"status_code:"+strconv.Itoa(resp.StatusCode),
		)

		b, err = ioutil.ReadAll(resp.Body)
		if err != nil {
			return false, err
		}
	}

	return string(b) == "1", nil
}