<commit_before>// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package azidentity

import (
	"context"
	"errors"
	"fmt"
	"math/rand"
	"net/http"
)

const okPage = `
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Login Succeeded</title>
</head>
<body>
    <h4>You have logged into Microsoft Azure!</h4>
    <p>You can now close this window.</p>
</body>
</html>
`

const failPage = `
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Login Failed</title>
</head>
<body>
    <h4>An error occurred during authentication</h4>
    <p>Please open an issue in the <a href="https://github.com/azure/go-autorest/issues">Go Autorest repo</a> for assistance.</p>
</body>
</html>
`

type server struct {
	done chan struct{}
	s    *http.Server
	code string
	err  error
}

// NewServer creates an object that satisfies the Server interface.
func newServer() *server {
	rs := &server{
		done: make(chan struct{}),
		s:    &http.Server{},
	}
	return rs
}

// Start starts the local HTTP server on a separate go routine.
// The return value is the full URL plus port number.
func (s *server) Start(reqState string, port int) string {
	if port == 0 {
		port = rand.Intn(600) + 8400
	}
	s.s.Addr = fmt.Sprintf(":%d", port)
	s.s.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		defer func() {
			s.done <- struct{}{}
		}()
		qp := r.URL.Query()
		if respState, ok := qp["state"]; !ok {
			s.err = errors.New("missing OAuth state")
			return
		} else if respState[0] != reqState {
			s.err = errors.New("mismatched OAuth state")
			return
		}
		if err, ok := qp["error"]; ok {
			w.Write([]byte(failPage))
			s.err = fmt.Errorf("authentication error: %s; description: %s", err[0], qp.Get("error_description"))
			return
		}
		if code, ok := qp["code"]; ok {
			w.Write([]byte(okPage))
			s.code = code[0]
		} else {
			s.err = errors.New("authorization code missing in query string")
		}
	})
	go s.s.ListenAndServe()
	return fmt.Sprintf("http://localhost:%d", port)
}

// Stop will shut down the local HTTP server.<commit_msg>azidentity: simplify auth_code flow cb code (#14587)<commit_after>// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package azidentity

import (
	"context"
	"errors"
	"fmt"
	"math/rand"
	"net/http"
)

const okPage = `
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Login Succeeded</title>
</head>
<body>
    <h4>You have logged into Microsoft Azure!</h4>
    <p>You can now close this window.</p>
</body>
</html>
`

const failPage = `
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Login Failed</title>
</head>
<body>
    <h4>An error occurred during authentication</h4>
    <p>Please open an issue in the <a href="https://github.com/azure/go-autorest/issues">Go Autorest repo</a> for assistance.</p>
</body>
</html>
`

type server struct {
	done chan struct{}
	s    *http.Server
	code string
	err  error
}

// NewServer creates an object that satisfies the Server interface.
func newServer() *server {
	rs := &server{
		done: make(chan struct{}),
		s:    &http.Server{},
	}
	return rs
}

// Start starts the local HTTP server on a separate go routine.
// The return value is the full URL plus port number.
func (s *server) Start(reqState string, port int) string {
	if port == 0 {
		port = rand.Intn(600) + 8400
	}
	s.s.Addr = fmt.Sprintf(":%d", port)
	s.s.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		defer func() {
			s.done <- struct{}{}

			page := okPage
			if s.err != nil {
				page = failPage
			}
			w.Write([]byte(page))
		}()

		qp := r.URL.Query()
		if reqState != qp.Get("state") {
			s.err = errors.New("mismatched OAuth state")
			return
		}
		if err := qp.Get("error"); err != "" {
			errMsg := fmt.Sprintf("authentication error: %s", err)
			if detail := qp.Get("error_description"); detail != "" {
				errMsg = fmt.Sprintf("%s; description: %s", errMsg, detail)
			}
			s.err = fmt.Errorf("%s", errMsg)
			return
		}

		code := qp.Get("code")
		if code == "" {
			s.err = errors.New("authorization code missing in query string")
			return
		}
		s.code = code
	})
	go s.s.ListenAndServe()
	return fmt.Sprintf("http://localhost:%d", port)
}

// Stop will shut down the local HTTP server.
{'fraction_non_alphanumeric': 0.16295104573661226, 'fraction_numerical': 0.008273960009193289, 'mean_word_length': 3.313181367690783, 'pattern_counts': {'":': 2, '<': 65, '<?xml version=': 0, '>': 63, 'https://': 2, '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': '3216002', 'n_tokens_mistral': 1662, 'n_tokens_neox': 1534, 'n_words': 454}