<commit_before>package exporter

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
)

// cert and key created with openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -nodes

const defaultCert = `-----<KEY>
-----END CERTIFICATE-----
`

const defaultKey = `-----BEGIN RSA PRIVATE KEY-----
<KEY>
/<KEY>
`

func RunHttpsServerWithDefaultKeys(port int, path string, handler http.Handler) error {
	cert, err := createTempFile("cert", []byte(defaultCert))
	if err != nil {
		return err
	}
	defer os.Remove(cert)
	key, err := createTempFile("key", []byte(defaultKey))
	if err != nil {
		return err
	}
	defer os.Remove(key)
	return RunHttpsServer(port, cert, key, path, handler)
}

func RunHttpsServer(port int, cert, key, path string, handler http.Handler) error {
	http.Handle(path, handler)
	return http.ListenAndServeTLS(fmt.Sprintf(":%v", port), cert, key, nil)
}

func RunHttpServer(port int, path string, handler http.Handler) error {
	http.Handle(path, handler)
	return http.ListenAndServe(fmt.Sprintf(":%v", port), nil)
}

func createTempFile(prefix string, data []byte) (string, error) {
	tempFile, err := ioutil.TempFile(os.TempDir(), prefix)
	if err != nil {<commit_msg>Better error handling when port in use.<commit_after>package exporter

import (
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"os"
)

// cert and key created with openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -nodes

const defaultCert = `-----BEGIN CERTIFICATE-----
MIIDtTCCAp2gAwIBAgIJAP9eE4ZtnJZnMA0GCSqGSIb3DQEBBQUAMEUxC<KEY>
-----END CERTIFICATE-----
`

const defaultKey = `-----<KEY>
-----END RSA PRIVATE KEY-----
`

func RunHttpsServerWithDefaultKeys(port int, path string, handler http.Handler) error {
	cert, err := createTempFile("cert", []byte(defaultCert))
	if err != nil {
		return err
	}
	defer os.Remove(cert)
	key, err := createTempFile("key", []byte(defaultKey))
	if err != nil {
		return err
	}
	defer os.Remove(key)
	return RunHttpsServer(port, cert, key, path, handler)
}

func RunHttpsServer(port int, cert, key, path string, handler http.Handler) error {
	err := tryOpenPort(port)
	if err != nil {
		return fmt.Errorf("Cannot open port %v: %v", port, err)
	}
	http.Handle(path, handler)
	return http.ListenAndServeTLS(fmt.Sprintf(":%v", port), cert, key, nil)
}

func RunHttpServer(port int, path string, handler http.Handler) error {
	err := tryOpenPort(port)
	if err != nil {
		return fmt.Errorf("Cannot open port %v: %v", port, err)
	}
	http.Handle(path, handler)
	return http.ListenAndServe(fmt.Sprintf(":%v", port), nil)
}

// Golang's http.ListenAndServe() has an unexpected behaviour when the port is in use:
// Instead of returning an error, it tries to open an IPv6-only listener.
// If this works (because the other application on that port is IPv4-only), no error is returned.
// This is confusing for the user, we want an error if the IPv4 port is in use.
func tryOpenPort(port int) error {
	ln, err := net.Listen("tcp4", fmt.Sprintf(":%v", port))
	if err != nil {
		return err
	}
	return ln.Close()
}

func createTempFile(prefix string, data []byte) (string, error) {
	tempFile, err := ioutil.TempFile(os.TempDir(), prefix)
	if err != nil {
{'fraction_non_alphanumeric': 0.1479028697571744, 'fraction_numerical': 0.007253232418795333, 'mean_word_length': 4.1410048622366284, 'pattern_counts': {'":': 5, '<': 8, '<?xml version=': 0, '>': 8, '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': '7416831', 'n_tokens_mistral': 1153, 'n_tokens_neox': 1119, 'n_words': 341}