<commit_before>package docker

import (
	"context"
	"crypto/tls"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"sync"
	"time"

	"github.com/containers/image/docker/reference"
	"github.com/containers/image/pkg/docker/config"
	"github.com/containers/image/pkg/sysregistriesv2"
	"github.com/containers/image/pkg/tlsclientconfig"
	"github.com/containers/image/types"
	"github.com/docker/distribution/registry/client"
	"github.com/docker/go-connections/tlsconfig"
	digest "github.com/opencontainers/go-digest"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
)

const (
	dockerHostname   = "docker.io"
	dockerV1Hostname = "index.docker.io"
	dockerRegistry   = "registry-1.docker.io"

	resolvedPingV2URL       = "%s://%s/v2/"
	resolvedPingV1URL       = "%s://%s/v1/_ping"
	tagsPath                = "/v2/%s/tags/list"
	manifestPath            = "/v2/%s/manifests/%s"
	blobsPath               = "/v2/%s/blobs/%s"
	blobUploadPath          = "/v2/%s/blobs/uploads/"
	extensionsSignaturePath = "/extensions/v2/%s/signatures/%s"

	minimumTokenLifetimeSeconds = 60

	extensionSignatureSchemaVersion = 2        // extensionSignature.Version
	extensionSignatureTypeAtomic    = "atomic" // extensionSignature.Type
)

var (
	// ErrV1NotSupported is returned when we're trying to talk to a
	// docker V1 registry.
	ErrV1NotSupported = errors.New("can't talk to a V1 docker registry")
	// ErrUnauthorizedForCredentials is returned when the status code returned is 401
	ErrUnauthorizedForCredentials = errors.New("unable to retrieve auth token: invalid username/password")
	systemPerHostCertDirPaths     = [2]string{"/etc/containers/certs.d", "/etc/docker/certs.d"}
)

// extensionSignature and extensionSignatureList come from github.com/openshift/origin/pkg/dockerregistry/server/signaturedispatcher.go:
// signature represents a Docker image signature.
type extensionSignature struct {
	Version int    `json:"schemaVersion"` // Version specifies the schema version
	Name    string `json:"name"`          // Name must be in "sha256:<digest>@signatureName" format
	Type    string `json:"type"`          // Type is optional, of not set it will be defaulted to "AtomicImageV1"
	Content []byte `json:"content"`       // Content contains the signature
}

// signatureList represents list of Docker image signatures.
type extensionSignatureList struct {
	Signatures []extensionSignature `json:"signatures"`
}

type bearerToken struct {
	Token          string    `json:"token"`
	AccessToken    string    `json:"access_token"`
	ExpiresIn      int       `json:"expires_in"`
	IssuedAt       time.Time `json:"issued_at"`
	expirationTime time.Time
}

// dockerClient is configuration for dealing with a single Docker registry.
type dockerClient struct {
	// The following members are set by newDockerClient and do not change afterwards.
	sys      *types.SystemContext
	registry string

	// tlsClientConfig is setup by newDockerClient and will be used and updated
	// by detectProperties(). Any HTTP request the dockerClient does will be done
	// by this TLS client configuration.
	// Callers can edit tlsClientConfig.InsecureSkipVerify before detectProperties().
	tlsClientConfig *tls.Config
	// The following members are not set by newDockerClient and must be set by callers if needed.
	username      string
	password      string
	signatureBase signatureStorageBase
	scope         authScope

	// The following members are detected registry properties:
	// They are set after a successful detectProperties(), and never change afterwards.
	scheme             string
	challenges         []challenge
	supportsSignatures bool

	// Private state for setupRequestAuth (key: string, value: bearerToken)
	tokenCache sync.Map
	// detectPropertiesError caches the initial error.
	detectPropertiesError error
	// detectPropertiesOnce is used to execuute detectProperties() at most once in in makeRequest().
	detectPropertiesOnce sync.Once
}<commit_msg>Clean up comments about the detectProperties* members of dockerClient<commit_after>package docker

import (
	"context"
	"crypto/tls"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"sync"
	"time"

	"github.com/containers/image/docker/reference"
	"github.com/containers/image/pkg/docker/config"
	"github.com/containers/image/pkg/sysregistriesv2"
	"github.com/containers/image/pkg/tlsclientconfig"
	"github.com/containers/image/types"
	"github.com/docker/distribution/registry/client"
	"github.com/docker/go-connections/tlsconfig"
	digest "github.com/opencontainers/go-digest"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
)

const (
	dockerHostname   = "docker.io"
	dockerV1Hostname = "index.docker.io"
	dockerRegistry   = "registry-1.docker.io"

	resolvedPingV2URL       = "%s://%s/v2/"
	resolvedPingV1URL       = "%s://%s/v1/_ping"
	tagsPath                = "/v2/%s/tags/list"
	manifestPath            = "/v2/%s/manifests/%s"
	blobsPath               = "/v2/%s/blobs/%s"
	blobUploadPath          = "/v2/%s/blobs/uploads/"
	extensionsSignaturePath = "/extensions/v2/%s/signatures/%s"

	minimumTokenLifetimeSeconds = 60

	extensionSignatureSchemaVersion = 2        // extensionSignature.Version
	extensionSignatureTypeAtomic    = "atomic" // extensionSignature.Type
)

var (
	// ErrV1NotSupported is returned when we're trying to talk to a
	// docker V1 registry.
	ErrV1NotSupported = errors.New("can't talk to a V1 docker registry")
	// ErrUnauthorizedForCredentials is returned when the status code returned is 401
	ErrUnauthorizedForCredentials = errors.New("unable to retrieve auth token: invalid username/password")
	systemPerHostCertDirPaths     = [2]string{"/etc/containers/certs.d", "/etc/docker/certs.d"}
)

// extensionSignature and extensionSignatureList come from github.com/openshift/origin/pkg/dockerregistry/server/signaturedispatcher.go:
// signature represents a Docker image signature.
type extensionSignature struct {
	Version int    `json:"schemaVersion"` // Version specifies the schema version
	Name    string `json:"name"`          // Name must be in "sha256:<digest>@signatureName" format
	Type    string `json:"type"`          // Type is optional, of not set it will be defaulted to "AtomicImageV1"
	Content []byte `json:"content"`       // Content contains the signature
}

// signatureList represents list of Docker image signatures.
type extensionSignatureList struct {
	Signatures []extensionSignature `json:"signatures"`
}

type bearerToken struct {
	Token          string    `json:"token"`
	AccessToken    string    `json:"access_token"`
	ExpiresIn      int       `json:"expires_in"`
	IssuedAt       time.Time `json:"issued_at"`
	expirationTime time.Time
}

// dockerClient is configuration for dealing with a single Docker registry.
type dockerClient struct {
	// The following members are set by newDockerClient and do not change afterwards.
	sys      *types.SystemContext
	registry string

	// tlsClientConfig is setup by newDockerClient and will be used and updated
	// by detectProperties(). Any HTTP request the dockerClient does will be done
	// by this TLS client configuration.
	// Callers can edit tlsClientConfig.InsecureSkipVerify before detectProperties().
	tlsClientConfig *tls.Config
	// The following members are not set by newDockerClient and must be set by callers if needed.
	username      string
	password      string
	signatureBase signatureStorageBase
	scope         authScope

	// The following members are detected registry properties:
	// They are set after a successful detectProperties(), and never change afterwards.
	scheme             string
	challenges         []challenge
	supportsSignatures bool

	// Private state for setupRequestAuth (key: string, value: bearerToken)
	tokenCache sync.Map
	// Private state for detectProperties:
	detectPropertiesOnce  sync.Once // detectPropertiesOnce is used to execute detectProperties() at most once.
	detectPropertiesError error     // detectPropertiesError caches the initial error.
}
{'fraction_non_alphanumeric': 0.0976882923191648, 'fraction_numerical': 0.006711409395973154, 'mean_word_length': 3.764357608052102, 'pattern_counts': {'":': 0, '<': 5, '<?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': '1423989', 'n_tokens_mistral': 2450, 'n_tokens_neox': 2341, 'n_words': 663}