<commit_before>package algoliasearch

import (
	"bytes"
	_ "crypto/sha512" // Fix certificates
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"math/rand"
	"net"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"time"
)

const (
	version = "2.0.0"
)

const (
	search = 1 << iota
	write
	read
)

// Transport defines low level functions to trade with Algolia servers.
type Transport struct {
	apiKey        string
	appID         string
	headers       map[string]string
	hosts         []string
	hostsProvided bool
	httpClient    *http.Client
}

// newHTTPClient creates and initializes an http.Client with sane defaults.
func newHTTPClient() *http.Client {
	return &http.Client{
		Timeout: time.Second * 30,
		Transport: &http.Transport{
			Dial: (&net.Dialer{
				Timeout:   2 * time.Second,
				KeepAlive: 180 * time.Second,
			}).Dial,
			DisableKeepAlives:   false,
			MaxIdleConnsPerHost: 2,
			TLSHandshakeTimeout: 2 * time.Second,
		},
	}
}

// NewTransport creates and initializes a new Transport targeting the Algolia
// application `appID` using the API key `apiKey`. The hosts are deduced from
// `appID`.
func NewTransport(appID, apiKey string) *Transport {
	hosts := []string{
		appID + "-1.algolianet.com",
		appID + "-2.algolianet.com",
		appID + "-3.algolianet.com",
	}

	// Randomize the hosts order
	randHosts := make([]string, len(hosts))
	for i, v := range rand.Perm(len(hosts)) {
		randHosts[i] = hosts[v]
	}

	return &Transport{
		apiKey:        apiKey,
		appID:         appID,
		headers:       make(map[string]string),
		hosts:         randHosts,
		hostsProvided: false,
		httpClient:    newHTTPClient(),
	}
}

// NewTransportWithHosts creates and initializes a new Transport targeting the
// Algolia application `appID` using the API key `apiKey` via the specified
// `hosts`.
func NewTransportWithHosts(appID, apiKey string, hosts []string) *Transport {
	return &Transport{
		apiKey:        apiKey,
		appID:         appID,
		headers:       make(map[string]string),
		hosts:         hosts,
		hostsProvided: true,
		httpClient:    newHTTPClient(),
	}
}

// setTimeout changes the timeouts used by the underlying HTTP client.
func (t *Transport) setTimeout(connectTimeout time.Duration, readTimeout time.Duration) {
	t.httpClient.Transport.(*http.Transport).TLSHandshakeTimeout = connectTimeout
	t.httpClient.Transport.(*http.Transport).ResponseHeaderTimeout = readTimeout
}

// setExtraHeader adds a custom header to be used when exchanging with Algolia
// servers.
func (t *Transport) setExtraHeader(key string, value string) {
	t.headers[key] = value
}

// request performs a `method` HTTP request at `path` sending `body`.
// `typeCall` represents the operation intended on the Algolia servers and can
// be one of the following constants: `search`, `write` or `read`.
func (t *Transport) request(method, path string, body interface{}, typeCall int) ([]byte, error) {
	var host string
	errorMsg := ""
	if typeCall == write {
		host = t.appID + ".algolia.net"
	} else {
		host = t.appID + "-dsn.algolia.net"
	}

	if !t.hostsProvided {
		req, err := t.buildRequest(method, host, path, body)
		if err != nil {
			return nil, err
		}

		req = t.addHeaders(req)
		resp, err := t.httpClient.Do(req)

		if err != nil {
			if len(errorMsg) > 0 {
				errorMsg = fmt.Sprintf("%s, %s:%s", errorMsg, host, err)
			} else {
				errorMsg = fmt.Sprintf("%s:%s", host, err)
			}<commit_msg>Clean transport signatures<commit_after>package algoliasearch

import (
	"bytes"
	_ "crypto/sha512" // Fix certificates
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"math/rand"
	"net"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"time"
)

const (
	version = "2.0.0"
)

const (
	search = 1 << iota
	write
	read
)

// Transport defines low level functions to trade with Algolia servers.
type Transport struct {
	apiKey        string
	appID         string
	headers       map[string]string
	hosts         []string
	hostsProvided bool
	httpClient    *http.Client
}

// newHTTPClient creates and initializes an http.Client with sane defaults.
func newHTTPClient() *http.Client {
	return &http.Client{
		Timeout: time.Second * 30,
		Transport: &http.Transport{
			Dial: (&net.Dialer{
				Timeout:   2 * time.Second,
				KeepAlive: 180 * time.Second,
			}).Dial,
			DisableKeepAlives:   false,
			MaxIdleConnsPerHost: 2,
			TLSHandshakeTimeout: 2 * time.Second,
		},
	}
}

// NewTransport creates and initializes a new Transport targeting the Algolia
// application `appID` using the API key `apiKey`. The hosts are deduced from
// `appID`.
func NewTransport(appID, apiKey string) *Transport {
	hosts := []string{
		appID + "-1.algolianet.com",
		appID + "-2.algolianet.com",
		appID + "-3.algolianet.com",
	}

	// Randomize the hosts order
	randHosts := make([]string, len(hosts))
	for i, v := range rand.Perm(len(hosts)) {
		randHosts[i] = hosts[v]
	}

	return &Transport{
		apiKey:        apiKey,
		appID:         appID,
		headers:       make(map[string]string),
		hosts:         randHosts,
		hostsProvided: false,
		httpClient:    newHTTPClient(),
	}
}

// NewTransportWithHosts creates and initializes a new Transport targeting the
// Algolia application `appID` using the API key `apiKey` via the specified
// `hosts`.
func NewTransportWithHosts(appID, apiKey string, hosts []string) *Transport {
	return &Transport{
		apiKey:        apiKey,
		appID:         appID,
		headers:       make(map[string]string),
		hosts:         hosts,
		hostsProvided: true,
		httpClient:    newHTTPClient(),
	}
}

// setTimeout changes the timeouts used by the underlying HTTP client.
func (t *Transport) setTimeout(connectTimeout, readTimeout time.Duration) {
	t.httpClient.Transport.(*http.Transport).TLSHandshakeTimeout = connectTimeout
	t.httpClient.Transport.(*http.Transport).ResponseHeaderTimeout = readTimeout
}

// setExtraHeader adds a custom header to be used when exchanging with Algolia
// servers.
func (t *Transport) setExtraHeader(key, value string) {
	t.headers[key] = value
}

// request performs a `method` HTTP request at `path` sending `body`.
// `typeCall` represents the operation intended on the Algolia servers and can
// be one of the following constants: `search`, `write` or `read`.
func (t *Transport) request(method, path string, body interface{}, typeCall int) ([]byte, error) {
	var host string
	errorMsg := ""
	if typeCall == write {
		host = t.appID + ".algolia.net"
	} else {
		host = t.appID + "-dsn.algolia.net"
	}

	if !t.hostsProvided {
		req, err := t.buildRequest(method, host, path, body)
		if err != nil {
			return nil, err
		}

		req = t.addHeaders(req)
		resp, err := t.httpClient.Do(req)

		if err != nil {
			if len(errorMsg) > 0 {
				errorMsg = fmt.Sprintf("%s, %s:%s", errorMsg, host, err)
			} else {
				errorMsg = fmt.Sprintf("%s:%s", host, err)
			}
{'fraction_non_alphanumeric': 0.12525758021783928, 'fraction_numerical': 0.005593170444509862, 'mean_word_length': 3.4123376623376624, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '485856', 'n_tokens_mistral': 2448, 'n_tokens_neox': 2273, 'n_words': 660}