<commit_before>package acme

import (
	"crypto/tls"
	"encoding/json"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"

	"github.com/square/go-jose"
)

func TestSimpleHTTPCanSolve(t *testing.T) {
	challenge := &simpleHTTPChallenge{}

	// determine public ip
	resp, err := http.Get("https://icanhazip.com/")
	if err != nil {
		t.Errorf("Could not get public IP -> %v", err)
	}

	ip, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Errorf("Could not get public IP -> %v", err)
	}
	ipStr := string(ip)

	if expected, actual := false, challenge.CanSolve("google.com"); expected != actual {
		t.Errorf("Expected CanSolve to return %t for domain 'google.com' but was %t", expected, actual)
	}

	localResolv := strings.Replace(ipStr, "\n", "", -1) + ".xip.io"
	if expected, actual := true, challenge.CanSolve(localResolv); expected != actual {
		t.Errorf("Expected CanSolve to return %t for domain 'localhost' but was %t", expected, actual)
	}
}

func TestSimpleHTTP(t *testing.T) {
	privKey, err := generatePrivateKey(512)
	if err != nil {
		t.Errorf("Could not generate public key -> %v", err)
	}
	jws := &jws{privKey: privKey}

	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Add("Replay-Nonce", "12345")
	}))

	solver := &simpleHTTPChallenge{jws: jws}
	clientChallenge := challenge{Type: "simpleHttp", Status: "pending", URI: ts.URL, Token: "<PASSWORD>"}

	// validate error on non-root bind to 443
	if err = solver.Solve(clientChallenge, "test.domain"); err == nil {
		t.Error("BIND: Expected Solve to return an error but the error was nil.")
	}

	// Validate error on unexpected state
	solver.optPort = "8080"
	if err = solver.Solve(clientChallenge, "test.domain"); err == nil {
		t.Error("UNEXPECTED: Expected Solve to return an error but the error was nil.")
	}

	// Validate error on invalid status
	ts.Config.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Add("Replay-Nonce", "12345")
		failed := challenge{Type: "simpleHttp", Status: "invalid", URI: ts.URL, Token: "1<PASSWORD>"}
		jsonBytes, _ := json.Marshal(&failed)
		w.Write(jsonBytes)
	})
	clientChallenge.Token = "1<PASSWORD>"
	if err = solver.Solve(clientChallenge, "test.domain"); err == nil {
		t.Error("FAILED: Expected Solve to return an error but the error was nil.")
	}

	// Validate no error on valid response
	ts.Config.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Add("Replay-Nonce", "12345")
		valid := challenge{Type: "simpleHttp", Status: "valid", URI: ts.URL, Token: "1<PASSWORD>"}
		jsonBytes, _ := json.Marshal(&valid)
		w.Write(jsonBytes)
	})
	clientChallenge.Token = "1<PASSWORD>"
	if err = solver.Solve(clientChallenge, "test.domain"); err != nil {
		t.Errorf("VALID: Expected Solve to return no error but the error was -> %v", err)
	}

	// Validate server on port 8080 which responds appropriately
	clientChallenge.Token = "123<PASSWORD>2"
	ts.Config.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		var request challenge
		w.Header().Add("Replay-Nonce", "12345")

		if r.Method == "HEAD" {
			return
		}

		clientJws, _ := ioutil.ReadAll(r.Body)
		j, err := jose.ParseSigned(string(clientJws))
		if err != nil {
			t.Errorf("Client sent invalid JWS to the server.\n\t%v", err)
			return
		}
		output, err := j.Verify(&privKey.PublicKey)
		if err != nil {
			t.Errorf("Unable to verify client data -> %v", err)
		}
		json.Unmarshal(output, &request)

		transport := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}
		client := &http.Client{Transport: transport}

		reqURL := "https://localhost:8080/.well-known/acme-challenge/" + clientChallenge.Token
		t.Logf("Request URL is: %s", reqURL)
		req, _ := http.NewRequest("GET", reqURL, nil)
		req.Host = "test.domain"
		resp, err := client.Do(req)
		if err != nil {
			t.Errorf("Expected the solver to listen on port 8080 -> %v", err)
		}

		body, _ := ioutil.ReadAll(resp.Body)
		bodyStr := string(body)
		clientResponse, err := jose.ParseSigned(bodyStr)
		if err != nil {
			t.Errorf("Client answered with invalid JWS.\n\t%v", err)
			return
		}
		_, err = clientResponse.Verify(&privKey.PublicKey)
		if err != nil {
			t.Errorf("Unable to verify client data -> %v", err)
		}

		valid := challenge{Type: "simpleHttp", Status: "valid", URI: ts.URL, Token: "<PASSWORD>"}
		jsonBytes, _ := json.Marshal(&valid)
		w.Write(jsonBytes)
	})
	if err = solver.Solve(clientChallenge, "test.domain"); err != nil {
		t.Errorf("VALID: Expected Solve to return no error but the error was -> %v", err)
	}
}<commit_msg>Move the tests to a different port.<commit_after>package acme

import (
	"crypto/tls"
	"encoding/json"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"

	"github.com/square/go-jose"
)

func TestSimpleHTTPCanSolve(t *testing.T) {
	challenge := &simpleHTTPChallenge{}

	// determine public ip
	resp, err := http.Get("https://icanhazip.com/")
	if err != nil {
		t.Errorf("Could not get public IP -> %v", err)
	}

	ip, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Errorf("Could not get public IP -> %v", err)
	}
	ipStr := string(ip)

	if expected, actual := false, challenge.CanSolve("google.com"); expected != actual {
		t.Errorf("Expected CanSolve to return %t for domain 'google.com' but was %t", expected, actual)
	}

	localResolv := strings.Replace(ipStr, "\n", "", -1) + ".xip.io"
	if expected, actual := true, challenge.CanSolve(localResolv); expected != actual {
		t.Errorf("Expected CanSolve to return %t for domain 'localhost' but was %t", expected, actual)
	}
}

func TestSimpleHTTP(t *testing.T) {
	privKey, err := generatePrivateKey(512)
	if err != nil {
		t.Errorf("Could not generate public key -> %v", err)
	}
	jws := &jws{privKey: privKey}

	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Add("Replay-Nonce", "12345")
	}))

	solver := &simpleHTTPChallenge{jws: jws}
	clientChallenge := challenge{Type: "simpleHttp", Status: "pending", URI: ts.URL, Token: "<PASSWORD>"}

	// validate error on non-root bind to 443
	if err = solver.Solve(clientChallenge, "test.domain"); err == nil {
		t.Error("BIND: Expected Solve to return an error but the error was nil.")
	}

	// Validate error on unexpected state
	solver.optPort = "23456"
	if err = solver.Solve(clientChallenge, "test.domain"); err == nil {
		t.Error("UNEXPECTED: Expected Solve to return an error but the error was nil.")
	}

	// Validate error on invalid status
	ts.Config.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Add("Replay-Nonce", "12345")
		failed := challenge{Type: "simpleHttp", Status: "invalid", URI: ts.URL, Token: "<PASSWORD>"}
		jsonBytes, _ := json.Marshal(&failed)
		w.Write(jsonBytes)
	})
	clientChallenge.Token = "<PASSWORD>"
	if err = solver.Solve(clientChallenge, "test.domain"); err == nil {
		t.Error("FAILED: Expected Solve to return an error but the error was nil.")
	}

	// Validate no error on valid response
	ts.Config.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Add("Replay-Nonce", "12345")
		valid := challenge{Type: "simpleHttp", Status: "valid", URI: ts.URL, Token: "1<PASSWORD>"}
		jsonBytes, _ := json.Marshal(&valid)
		w.Write(jsonBytes)
	})
	clientChallenge.Token = "<PASSWORD>"
	if err = solver.Solve(clientChallenge, "test.domain"); err != nil {
		t.Errorf("VALID: Expected Solve to return no error but the error was -> %v", err)
	}

	// Validate server on port 23456 which responds appropriately
	clientChallenge.Token = "<PASSWORD>"
	ts.Config.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		var request challenge
		w.Header().Add("Replay-Nonce", "12345")

		if r.Method == "HEAD" {
			return
		}

		clientJws, _ := ioutil.ReadAll(r.Body)
		j, err := jose.ParseSigned(string(clientJws))
		if err != nil {
			t.Errorf("Client sent invalid JWS to the server.\n\t%v", err)
			return
		}
		output, err := j.Verify(&privKey.PublicKey)
		if err != nil {
			t.Errorf("Unable to verify client data -> %v", err)
		}
		json.Unmarshal(output, &request)

		transport := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}
		client := &http.Client{Transport: transport}

		reqURL := "https://localhost:23456/.well-known/acme-challenge/" + clientChallenge.Token
		t.Logf("Request URL is: %s", reqURL)
		req, _ := http.NewRequest("GET", reqURL, nil)
		req.Host = "test.domain"
		resp, err := client.Do(req)
		if err != nil {
			t.Errorf("Expected the solver to listen on port 23456 -> %v", err)
		}

		body, _ := ioutil.ReadAll(resp.Body)
		bodyStr := string(body)
		clientResponse, err := jose.ParseSigned(bodyStr)
		if err != nil {
			t.Errorf("Client answered with invalid JWS.\n\t%v", err)
			return
		}
		_, err = clientResponse.Verify(&privKey.PublicKey)
		if err != nil {
			t.Errorf("Unable to verify client data -> %v", err)
		}

		valid := challenge{Type: "simpleHttp", Status: "valid", URI: ts.URL, Token: "<PASSWORD>"}
		jsonBytes, _ := json.Marshal(&valid)
		w.Write(jsonBytes)
	})
	if err = solver.Solve(clientChallenge, "test.domain"); err != nil {
		t.Errorf("VALID: Expected Solve to return no error but the error was -> %v", err)
	}
}
{'fraction_non_alphanumeric': 0.1599871064789943, 'fraction_numerical': 0.010637154829698077, 'mean_word_length': 4.091903719912473, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 33, 'https://': 4, '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': '5505676', 'n_tokens_mistral': 3509, 'n_tokens_neox': 3209, 'n_words': 852}