Factor out context.go from wfe and wfe2. (#3086)
* Move probs.go to web. * Move probs_test.go * Factor out probs.go from wfe * Move context.go * Extract context.go into web package. * Add a constructor for TopHandler.
This commit is contained in:
parent
966e02313f
commit
97265c9184
|
@ -1,4 +1,4 @@
|
|||
package wfe
|
||||
package web
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
@ -7,11 +7,10 @@ import (
|
|||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/jmhodges/clock"
|
||||
blog "github.com/letsencrypt/boulder/log"
|
||||
)
|
||||
|
||||
type requestEvent struct {
|
||||
type RequestEvent struct {
|
||||
RealIP string `json:",omitempty"`
|
||||
Endpoint string `json:",omitempty"`
|
||||
Method string `json:",omitempty"`
|
||||
|
@ -26,29 +25,35 @@ type requestEvent struct {
|
|||
Extra map[string]interface{} `json:",omitempty"`
|
||||
}
|
||||
|
||||
func (e *requestEvent) AddError(msg string, args ...interface{}) {
|
||||
func (e *RequestEvent) AddError(msg string, args ...interface{}) {
|
||||
e.Errors = append(e.Errors, fmt.Sprintf(msg, args...))
|
||||
}
|
||||
|
||||
type wfeHandlerFunc func(context.Context, *requestEvent, http.ResponseWriter, *http.Request)
|
||||
type WFEHandlerFunc func(context.Context, *RequestEvent, http.ResponseWriter, *http.Request)
|
||||
|
||||
func (f wfeHandlerFunc) ServeHTTP(e *requestEvent, w http.ResponseWriter, r *http.Request) {
|
||||
func (f WFEHandlerFunc) ServeHTTP(e *RequestEvent, w http.ResponseWriter, r *http.Request) {
|
||||
ctx := context.TODO()
|
||||
f(ctx, e, w, r)
|
||||
}
|
||||
|
||||
type wfeHandler interface {
|
||||
ServeHTTP(e *requestEvent, w http.ResponseWriter, r *http.Request)
|
||||
ServeHTTP(e *RequestEvent, w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
type topHandler struct {
|
||||
type TopHandler struct {
|
||||
wfe wfeHandler
|
||||
log blog.Logger
|
||||
clk clock.Clock
|
||||
}
|
||||
|
||||
func (th *topHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
logEvent := &requestEvent{
|
||||
func NewTopHandler(log blog.Logger, wfe wfeHandler) *TopHandler {
|
||||
return &TopHandler{
|
||||
wfe: wfe,
|
||||
log: log,
|
||||
}
|
||||
}
|
||||
|
||||
func (th *TopHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
logEvent := &RequestEvent{
|
||||
RealIP: r.Header.Get("X-Real-IP"),
|
||||
Method: r.Method,
|
||||
UserAgent: r.Header.Get("User-Agent"),
|
||||
|
@ -59,7 +64,7 @@ func (th *topHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
th.wfe.ServeHTTP(logEvent, w, r)
|
||||
}
|
||||
|
||||
func (th *topHandler) logEvent(logEvent *requestEvent) {
|
||||
func (th *TopHandler) logEvent(logEvent *RequestEvent) {
|
||||
var msg string
|
||||
if len(logEvent.Errors) != 0 {
|
||||
msg = "Terminated request"
|
||||
|
@ -78,7 +83,7 @@ func (th *topHandler) logEvent(logEvent *requestEvent) {
|
|||
// request, starting with the original requestor and ending with the
|
||||
// remote end of our TCP connection (which is typically our own
|
||||
// proxy).
|
||||
func getClientAddr(r *http.Request) string {
|
||||
func GetClientAddr(r *http.Request) string {
|
||||
if xff := r.Header.Get("X-Forwarded-For"); xff != "" {
|
||||
return xff + "," + r.RemoteAddr
|
||||
}
|
62
wfe/wfe.go
62
wfe/wfe.go
|
@ -148,7 +148,7 @@ func NewWebFrontEndImpl(
|
|||
// * Never send a body in response to a HEAD request. Anything
|
||||
// written by the handler will be discarded if the method is HEAD.
|
||||
// Also, all handlers that accept GET automatically accept HEAD.
|
||||
func (wfe *WebFrontEndImpl) HandleFunc(mux *http.ServeMux, pattern string, h wfeHandlerFunc, methods ...string) {
|
||||
func (wfe *WebFrontEndImpl) HandleFunc(mux *http.ServeMux, pattern string, h web.WFEHandlerFunc, methods ...string) {
|
||||
methodsMap := make(map[string]bool)
|
||||
for _, m := range methods {
|
||||
methodsMap[m] = true
|
||||
|
@ -159,10 +159,8 @@ func (wfe *WebFrontEndImpl) HandleFunc(mux *http.ServeMux, pattern string, h wfe
|
|||
methodsMap["HEAD"] = true
|
||||
}
|
||||
methodsStr := strings.Join(methods, ", ")
|
||||
handler := http.StripPrefix(pattern, &topHandler{
|
||||
log: wfe.log,
|
||||
clk: clock.Default(),
|
||||
wfe: wfeHandlerFunc(func(ctx context.Context, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
handler := http.StripPrefix(pattern, web.NewTopHandler(wfe.log,
|
||||
web.WFEHandlerFunc(func(ctx context.Context, logEvent *web.RequestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
// We do not propagate errors here, because (1) they should be
|
||||
// transient, and (2) they fail closed.
|
||||
nonce, err := wfe.nonceService.Nonce()
|
||||
|
@ -210,7 +208,7 @@ func (wfe *WebFrontEndImpl) HandleFunc(mux *http.ServeMux, pattern string, h wfe
|
|||
h(ctx, logEvent, response, request)
|
||||
cancel()
|
||||
}),
|
||||
})
|
||||
))
|
||||
mux.Handle(pattern, handler)
|
||||
}
|
||||
|
||||
|
@ -218,7 +216,7 @@ func marshalIndent(v interface{}) ([]byte, error) {
|
|||
return json.MarshalIndent(v, "", " ")
|
||||
}
|
||||
|
||||
func (wfe *WebFrontEndImpl) writeJsonResponse(response http.ResponseWriter, logEvent *requestEvent, status int, v interface{}) error {
|
||||
func (wfe *WebFrontEndImpl) writeJsonResponse(response http.ResponseWriter, logEvent *web.RequestEvent, status int, v interface{}) error {
|
||||
jsonReply, err := marshalIndent(v)
|
||||
if err != nil {
|
||||
return err // All callers are responsible for handling this error
|
||||
|
@ -324,18 +322,14 @@ func (wfe *WebFrontEndImpl) Handler() http.Handler {
|
|||
// We don't use our special HandleFunc for "/" because it matches everything,
|
||||
// meaning we can wind up returning 405 when we mean to return 404. See
|
||||
// https://github.com/letsencrypt/boulder/issues/717
|
||||
m.Handle("/", &topHandler{
|
||||
log: wfe.log,
|
||||
clk: clock.Default(),
|
||||
wfe: wfeHandlerFunc(wfe.Index),
|
||||
})
|
||||
m.Handle("/", web.NewTopHandler(wfe.log, web.WFEHandlerFunc(wfe.Index)))
|
||||
return measured_http.New(m, wfe.clk)
|
||||
}
|
||||
|
||||
// Method implementations
|
||||
|
||||
// Index serves a simple identification page. It is not part of the ACME spec.
|
||||
func (wfe *WebFrontEndImpl) Index(ctx context.Context, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
func (wfe *WebFrontEndImpl) Index(ctx context.Context, logEvent *web.RequestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
// http://golang.org/pkg/net/http/#example_ServeMux_Handle
|
||||
// The "/" pattern matches everything, so we need to check
|
||||
// that we're at the root here.
|
||||
|
@ -378,7 +372,7 @@ func addRequesterHeader(w http.ResponseWriter, requester int64) {
|
|||
// Directory is an HTTP request handler that provides the directory
|
||||
// object stored in the WFE's DirectoryEndpoints member with paths prefixed
|
||||
// using the `request.Host` of the HTTP request.
|
||||
func (wfe *WebFrontEndImpl) Directory(ctx context.Context, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
func (wfe *WebFrontEndImpl) Directory(ctx context.Context, logEvent *web.RequestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
directoryEndpoints := map[string]interface{}{
|
||||
"new-reg": newRegPath,
|
||||
"new-authz": newAuthzPath,
|
||||
|
@ -463,10 +457,10 @@ func (wfe *WebFrontEndImpl) extractJWSKey(body string) (*jose.JSONWebKey, *jose.
|
|||
// registration object is found, verifyPOST will attempt to verify the JWS using
|
||||
// the key in the JWS headers, and return the key plus a dummy registration if
|
||||
// successful. If a caller passes regCheck = false, it should plan on validating
|
||||
// the key itself. verifyPOST also appends its errors to requestEvent.Errors so
|
||||
// the key itself. verifyPOST also appends its errors to web.RequestEvent.Errors so
|
||||
// code calling it does not need to if they immediately return a response to the
|
||||
// user.
|
||||
func (wfe *WebFrontEndImpl) verifyPOST(ctx context.Context, logEvent *requestEvent, request *http.Request, regCheck bool, resource core.AcmeResource) ([]byte, *jose.JSONWebKey, core.Registration, *probs.ProblemDetails) {
|
||||
func (wfe *WebFrontEndImpl) verifyPOST(ctx context.Context, logEvent *web.RequestEvent, request *http.Request, regCheck bool, resource core.AcmeResource) ([]byte, *jose.JSONWebKey, core.Registration, *probs.ProblemDetails) {
|
||||
// TODO: We should return a pointer to a registration, which can be nil,
|
||||
// rather the a registration value with a sentinel value.
|
||||
// https://github.com/letsencrypt/boulder/issues/877
|
||||
|
@ -589,7 +583,7 @@ func (wfe *WebFrontEndImpl) verifyPOST(ctx context.Context, logEvent *requestEve
|
|||
// and, if the ProblemDetails.Type is ServerInternalProblem, audit logs the
|
||||
// internal ierr. The rendered Problem will have its Type prefixed with the ACME
|
||||
// v1 namespace.
|
||||
func (wfe *WebFrontEndImpl) sendError(response http.ResponseWriter, logEvent *requestEvent, prob *probs.ProblemDetails, ierr error) {
|
||||
func (wfe *WebFrontEndImpl) sendError(response http.ResponseWriter, logEvent *web.RequestEvent, prob *probs.ProblemDetails, ierr error) {
|
||||
// Determine the HTTP status code to use for this problem
|
||||
code := probs.ProblemDetailsToStatusCode(prob)
|
||||
|
||||
|
@ -628,7 +622,7 @@ func link(url, relation string) string {
|
|||
}
|
||||
|
||||
// NewRegistration is used by clients to submit a new registration/account
|
||||
func (wfe *WebFrontEndImpl) NewRegistration(ctx context.Context, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
func (wfe *WebFrontEndImpl) NewRegistration(ctx context.Context, logEvent *web.RequestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
|
||||
body, key, _, prob := wfe.verifyPOST(ctx, logEvent, request, false, core.ResourceNewReg)
|
||||
addRequesterHeader(response, logEvent.Requester)
|
||||
|
@ -698,7 +692,7 @@ func (wfe *WebFrontEndImpl) NewRegistration(ctx context.Context, logEvent *reque
|
|||
}
|
||||
|
||||
// NewAuthorization is used by clients to submit a new ID Authorization
|
||||
func (wfe *WebFrontEndImpl) NewAuthorization(ctx context.Context, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
func (wfe *WebFrontEndImpl) NewAuthorization(ctx context.Context, logEvent *web.RequestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
body, _, currReg, prob := wfe.verifyPOST(ctx, logEvent, request, true, core.ResourceNewAuthz)
|
||||
addRequesterHeader(response, logEvent.Requester)
|
||||
if prob != nil {
|
||||
|
@ -762,7 +756,7 @@ func (wfe *WebFrontEndImpl) regHoldsAuthorizations(ctx context.Context, regID in
|
|||
}
|
||||
|
||||
// RevokeCertificate is used by clients to request the revocation of a cert.
|
||||
func (wfe *WebFrontEndImpl) RevokeCertificate(ctx context.Context, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
func (wfe *WebFrontEndImpl) RevokeCertificate(ctx context.Context, logEvent *web.RequestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
// We don't ask verifyPOST to verify there is a corresponding registration,
|
||||
// because anyone with the right private key can revoke a certificate.
|
||||
body, requestKey, registration, prob := wfe.verifyPOST(ctx, logEvent, request, false, core.ResourceRevokeCert)
|
||||
|
@ -861,7 +855,7 @@ func (wfe *WebFrontEndImpl) logCsr(request *http.Request, cr core.CertificateReq
|
|||
CSR string
|
||||
Registration core.Registration
|
||||
}{
|
||||
ClientAddr: getClientAddr(request),
|
||||
ClientAddr: web.GetClientAddr(request),
|
||||
CSR: hex.EncodeToString(cr.Bytes),
|
||||
Registration: registration,
|
||||
}
|
||||
|
@ -870,7 +864,7 @@ func (wfe *WebFrontEndImpl) logCsr(request *http.Request, cr core.CertificateReq
|
|||
|
||||
// NewCertificate is used by clients to request the issuance of a cert for an
|
||||
// authorized identifier.
|
||||
func (wfe *WebFrontEndImpl) NewCertificate(ctx context.Context, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
func (wfe *WebFrontEndImpl) NewCertificate(ctx context.Context, logEvent *web.RequestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
body, _, reg, prob := wfe.verifyPOST(ctx, logEvent, request, true, core.ResourceNewCert)
|
||||
addRequesterHeader(response, logEvent.Requester)
|
||||
if prob != nil {
|
||||
|
@ -981,7 +975,7 @@ func (wfe *WebFrontEndImpl) NewCertificate(ctx context.Context, logEvent *reques
|
|||
// responses to the server's challenges.
|
||||
func (wfe *WebFrontEndImpl) Challenge(
|
||||
ctx context.Context,
|
||||
logEvent *requestEvent,
|
||||
logEvent *web.RequestEvent,
|
||||
response http.ResponseWriter,
|
||||
request *http.Request) {
|
||||
|
||||
|
@ -1079,7 +1073,7 @@ func (wfe *WebFrontEndImpl) getChallenge(
|
|||
request *http.Request,
|
||||
authz core.Authorization,
|
||||
challenge *core.Challenge,
|
||||
logEvent *requestEvent) {
|
||||
logEvent *web.RequestEvent) {
|
||||
|
||||
wfe.prepChallengeForDisplay(request, authz, challenge)
|
||||
|
||||
|
@ -1102,7 +1096,7 @@ func (wfe *WebFrontEndImpl) postChallenge(
|
|||
request *http.Request,
|
||||
authz core.Authorization,
|
||||
challengeIndex int,
|
||||
logEvent *requestEvent) {
|
||||
logEvent *web.RequestEvent) {
|
||||
body, _, currReg, prob := wfe.verifyPOST(ctx, logEvent, request, true, core.ResourceChallenge)
|
||||
addRequesterHeader(response, logEvent.Requester)
|
||||
if prob != nil {
|
||||
|
@ -1160,7 +1154,7 @@ func (wfe *WebFrontEndImpl) postChallenge(
|
|||
}
|
||||
|
||||
// Registration is used by a client to submit an update to their registration.
|
||||
func (wfe *WebFrontEndImpl) Registration(ctx context.Context, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
func (wfe *WebFrontEndImpl) Registration(ctx context.Context, logEvent *web.RequestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
|
||||
body, _, currReg, prob := wfe.verifyPOST(ctx, logEvent, request, true, core.ResourceRegistration)
|
||||
addRequesterHeader(response, logEvent.Requester)
|
||||
|
@ -1251,7 +1245,7 @@ func (wfe *WebFrontEndImpl) Registration(ctx context.Context, logEvent *requestE
|
|||
}
|
||||
}
|
||||
|
||||
func (wfe *WebFrontEndImpl) deactivateAuthorization(ctx context.Context, authz *core.Authorization, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) bool {
|
||||
func (wfe *WebFrontEndImpl) deactivateAuthorization(ctx context.Context, authz *core.Authorization, logEvent *web.RequestEvent, response http.ResponseWriter, request *http.Request) bool {
|
||||
body, _, reg, prob := wfe.verifyPOST(ctx, logEvent, request, true, core.ResourceAuthz)
|
||||
addRequesterHeader(response, logEvent.Requester)
|
||||
if prob != nil {
|
||||
|
@ -1288,7 +1282,7 @@ func (wfe *WebFrontEndImpl) deactivateAuthorization(ctx context.Context, authz *
|
|||
|
||||
// Authorization is used by clients to submit an update to one of their
|
||||
// authorizations.
|
||||
func (wfe *WebFrontEndImpl) Authorization(ctx context.Context, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
func (wfe *WebFrontEndImpl) Authorization(ctx context.Context, logEvent *web.RequestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
// Requests to this handler should have a path that leads to a known authz
|
||||
id := request.URL.Path
|
||||
authz, err := wfe.SA.GetAuthorization(ctx, id)
|
||||
|
@ -1335,7 +1329,7 @@ var allHex = regexp.MustCompile("^[0-9a-f]+$")
|
|||
|
||||
// Certificate is used by clients to request a copy of their current certificate, or to
|
||||
// request a reissuance of the certificate.
|
||||
func (wfe *WebFrontEndImpl) Certificate(ctx context.Context, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
func (wfe *WebFrontEndImpl) Certificate(ctx context.Context, logEvent *web.RequestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
|
||||
serial := request.URL.Path
|
||||
// Certificate paths consist of the CertBase path, plus exactly sixteen hex
|
||||
|
@ -1384,12 +1378,12 @@ func (wfe *WebFrontEndImpl) Certificate(ctx context.Context, logEvent *requestEv
|
|||
|
||||
// Terms is used by the client to obtain the current Terms of Service /
|
||||
// Subscriber Agreement to which the subscriber must agree.
|
||||
func (wfe *WebFrontEndImpl) Terms(ctx context.Context, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
func (wfe *WebFrontEndImpl) Terms(ctx context.Context, logEvent *web.RequestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
http.Redirect(response, request, wfe.SubscriberAgreementURL, http.StatusFound)
|
||||
}
|
||||
|
||||
// Issuer obtains the issuer certificate used by this instance of Boulder.
|
||||
func (wfe *WebFrontEndImpl) Issuer(ctx context.Context, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
func (wfe *WebFrontEndImpl) Issuer(ctx context.Context, logEvent *web.RequestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
// TODO Content negotiation
|
||||
response.Header().Set("Content-Type", "application/pkix-cert")
|
||||
response.WriteHeader(http.StatusOK)
|
||||
|
@ -1400,7 +1394,7 @@ func (wfe *WebFrontEndImpl) Issuer(ctx context.Context, logEvent *requestEvent,
|
|||
}
|
||||
|
||||
// BuildID tells the requestor what build we're running.
|
||||
func (wfe *WebFrontEndImpl) BuildID(ctx context.Context, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
func (wfe *WebFrontEndImpl) BuildID(ctx context.Context, logEvent *web.RequestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
response.Header().Set("Content-Type", "text/plain")
|
||||
response.WriteHeader(http.StatusOK)
|
||||
detailsString := fmt.Sprintf("Boulder=(%s %s)", core.GetBuildID(), core.GetBuildTime())
|
||||
|
@ -1465,7 +1459,7 @@ func (wfe *WebFrontEndImpl) setCORSHeaders(response http.ResponseWriter, request
|
|||
}
|
||||
|
||||
// KeyRollover allows a user to change their signing key
|
||||
func (wfe *WebFrontEndImpl) KeyRollover(ctx context.Context, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
func (wfe *WebFrontEndImpl) KeyRollover(ctx context.Context, logEvent *web.RequestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
body, _, reg, prob := wfe.verifyPOST(ctx, logEvent, request, true, core.ResourceKeyChange)
|
||||
addRequesterHeader(response, logEvent.Requester)
|
||||
if prob != nil {
|
||||
|
@ -1526,7 +1520,7 @@ func (wfe *WebFrontEndImpl) KeyRollover(ctx context.Context, logEvent *requestEv
|
|||
response.Write(jsonReply)
|
||||
}
|
||||
|
||||
func (wfe *WebFrontEndImpl) deactivateRegistration(ctx context.Context, reg core.Registration, response http.ResponseWriter, request *http.Request, logEvent *requestEvent) {
|
||||
func (wfe *WebFrontEndImpl) deactivateRegistration(ctx context.Context, reg core.Registration, response http.ResponseWriter, request *http.Request, logEvent *web.RequestEvent) {
|
||||
err := wfe.RA.DeactivateRegistration(ctx, reg)
|
||||
if err != nil {
|
||||
wfe.sendError(response, logEvent, web.ProblemDetailsForError(err, "Error deactivating registration"), err)
|
||||
|
|
|
@ -38,6 +38,7 @@ import (
|
|||
"github.com/letsencrypt/boulder/revocation"
|
||||
"github.com/letsencrypt/boulder/test"
|
||||
vaPB "github.com/letsencrypt/boulder/va/proto"
|
||||
"github.com/letsencrypt/boulder/web"
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
@ -457,7 +458,7 @@ func TestHandleFunc(t *testing.T) {
|
|||
mux = http.NewServeMux()
|
||||
rw = httptest.NewRecorder()
|
||||
stubCalled = false
|
||||
wfe.HandleFunc(mux, "/test", func(context.Context, *requestEvent, http.ResponseWriter, *http.Request) {
|
||||
wfe.HandleFunc(mux, "/test", func(context.Context, *web.RequestEvent, http.ResponseWriter, *http.Request) {
|
||||
stubCalled = true
|
||||
}, allowed...)
|
||||
req.URL = mustParseURL("/test")
|
||||
|
@ -752,7 +753,7 @@ func TestRandomDirectoryKey(t *testing.T) {
|
|||
|
||||
responseWriter := httptest.NewRecorder()
|
||||
url, _ := url.Parse("/directory")
|
||||
wfe.Directory(ctx, &requestEvent{}, responseWriter, &http.Request{
|
||||
wfe.Directory(ctx, &web.RequestEvent{}, responseWriter, &http.Request{
|
||||
Method: "GET",
|
||||
URL: url,
|
||||
Host: "127.0.0.1:4300",
|
||||
|
@ -778,7 +779,7 @@ func TestRandomDirectoryKey(t *testing.T) {
|
|||
headers := map[string][]string{
|
||||
"User-Agent": {"LetsEncryptPythonClient"},
|
||||
}
|
||||
wfe.Directory(ctx, &requestEvent{}, responseWriter, &http.Request{
|
||||
wfe.Directory(ctx, &web.RequestEvent{}, responseWriter, &http.Request{
|
||||
Method: "GET",
|
||||
URL: url,
|
||||
Host: "127.0.0.1:4300",
|
||||
|
@ -2182,8 +2183,8 @@ func TestGetCertificateHEADHasCorrectBodyLength(t *testing.T) {
|
|||
test.AssertEquals(t, 0, len(body))
|
||||
}
|
||||
|
||||
func newRequestEvent() *requestEvent {
|
||||
return &requestEvent{Extra: make(map[string]interface{})}
|
||||
func newRequestEvent() *web.RequestEvent {
|
||||
return &web.RequestEvent{Extra: make(map[string]interface{})}
|
||||
}
|
||||
|
||||
func TestVerifyPOSTInvalidJWK(t *testing.T) {
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
package wfe2
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/jmhodges/clock"
|
||||
blog "github.com/letsencrypt/boulder/log"
|
||||
)
|
||||
|
||||
type requestEvent struct {
|
||||
RealIP string `json:",omitempty"`
|
||||
Endpoint string `json:",omitempty"`
|
||||
Method string `json:",omitempty"`
|
||||
Errors []string `json:",omitempty"`
|
||||
Requester int64 `json:",omitempty"`
|
||||
Contacts *[]string `json:",omitempty"`
|
||||
RequestNonce string `json:",omitempty"`
|
||||
ResponseNonce string `json:",omitempty"`
|
||||
UserAgent string `json:",omitempty"`
|
||||
Code int
|
||||
Payload string `json:",omitempty"`
|
||||
Extra map[string]interface{} `json:",omitempty"`
|
||||
}
|
||||
|
||||
func (e *requestEvent) AddError(msg string, args ...interface{}) {
|
||||
e.Errors = append(e.Errors, fmt.Sprintf(msg, args...))
|
||||
}
|
||||
|
||||
type wfeHandlerFunc func(context.Context, *requestEvent, http.ResponseWriter, *http.Request)
|
||||
|
||||
func (f wfeHandlerFunc) ServeHTTP(e *requestEvent, w http.ResponseWriter, r *http.Request) {
|
||||
ctx := context.TODO()
|
||||
f(ctx, e, w, r)
|
||||
}
|
||||
|
||||
type wfeHandler interface {
|
||||
ServeHTTP(e *requestEvent, w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
type topHandler struct {
|
||||
wfe wfeHandler
|
||||
log blog.Logger
|
||||
clk clock.Clock
|
||||
}
|
||||
|
||||
func (th *topHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
logEvent := &requestEvent{
|
||||
RealIP: r.Header.Get("X-Real-IP"),
|
||||
Method: r.Method,
|
||||
UserAgent: r.Header.Get("User-Agent"),
|
||||
Extra: make(map[string]interface{}, 0),
|
||||
}
|
||||
defer th.logEvent(logEvent)
|
||||
|
||||
th.wfe.ServeHTTP(logEvent, w, r)
|
||||
}
|
||||
|
||||
func (th *topHandler) logEvent(logEvent *requestEvent) {
|
||||
var msg string
|
||||
if len(logEvent.Errors) != 0 {
|
||||
msg = "Terminated request"
|
||||
} else {
|
||||
msg = "Successful request"
|
||||
}
|
||||
jsonEvent, err := json.Marshal(logEvent)
|
||||
if err != nil {
|
||||
th.log.AuditErr(fmt.Sprintf("%s - failed to marshal logEvent - %s", msg, err))
|
||||
return
|
||||
}
|
||||
th.log.Info(fmt.Sprintf("%s JSON=%s", msg, jsonEvent))
|
||||
}
|
||||
|
||||
// Comma-separated list of HTTP clients involved in making this
|
||||
// request, starting with the original requestor and ending with the
|
||||
// remote end of our TCP connection (which is typically our own
|
||||
// proxy).
|
||||
func getClientAddr(r *http.Request) string {
|
||||
if xff := r.Header.Get("X-Forwarded-For"); xff != "" {
|
||||
return xff + "," + r.RemoteAddr
|
||||
}
|
||||
return r.RemoteAddr
|
||||
}
|
|
@ -20,6 +20,7 @@ import (
|
|||
"github.com/letsencrypt/boulder/core"
|
||||
berrors "github.com/letsencrypt/boulder/errors"
|
||||
"github.com/letsencrypt/boulder/probs"
|
||||
"github.com/letsencrypt/boulder/web"
|
||||
)
|
||||
|
||||
var sigAlgErr = errors.New("no signature algorithms suitable for given key type")
|
||||
|
@ -162,7 +163,7 @@ func (wfe *WebFrontEndImpl) validPOSTRequest(request *http.Request) *probs.Probl
|
|||
// provided logEvent is mutated to set the observed RequestNonce.
|
||||
// NOTE: this function assumes the JWS has already been verified with the
|
||||
// correct public key.
|
||||
func (wfe *WebFrontEndImpl) validNonce(jws *jose.JSONWebSignature, logEvent *requestEvent) *probs.ProblemDetails {
|
||||
func (wfe *WebFrontEndImpl) validNonce(jws *jose.JSONWebSignature, logEvent *web.RequestEvent) *probs.ProblemDetails {
|
||||
// validNonce is called after validPOSTRequest() and parseJWS() which
|
||||
// defend against the incorrect number of signatures.
|
||||
header := jws.Signatures[0].Header
|
||||
|
@ -366,7 +367,7 @@ func (wfe *WebFrontEndImpl) lookupJWK(
|
|||
jws *jose.JSONWebSignature,
|
||||
ctx context.Context,
|
||||
request *http.Request,
|
||||
logEvent *requestEvent) (*jose.JSONWebKey, *core.Registration, *probs.ProblemDetails) {
|
||||
logEvent *web.RequestEvent) (*jose.JSONWebKey, *core.Registration, *probs.ProblemDetails) {
|
||||
// We expect the request to be using an embedded Key ID auth type and to not
|
||||
// contain the mutually exclusive embedded JWK.
|
||||
if prob := wfe.enforceJWSAuthType(jws, embeddedKeyID); prob != nil {
|
||||
|
@ -427,7 +428,7 @@ func (wfe *WebFrontEndImpl) validJWSForKey(
|
|||
jws *jose.JSONWebSignature,
|
||||
jwk *jose.JSONWebKey,
|
||||
request *http.Request,
|
||||
logEvent *requestEvent) ([]byte, *probs.ProblemDetails) {
|
||||
logEvent *web.RequestEvent) ([]byte, *probs.ProblemDetails) {
|
||||
|
||||
// Check that the public key and JWS algorithms match expected
|
||||
if err := checkAlgorithm(jwk, jws); err != nil {
|
||||
|
@ -484,7 +485,7 @@ func (wfe *WebFrontEndImpl) validJWSForAccount(
|
|||
jws *jose.JSONWebSignature,
|
||||
request *http.Request,
|
||||
ctx context.Context,
|
||||
logEvent *requestEvent) ([]byte, *jose.JSONWebSignature, *core.Registration, *probs.ProblemDetails) {
|
||||
logEvent *web.RequestEvent) ([]byte, *jose.JSONWebSignature, *core.Registration, *probs.ProblemDetails) {
|
||||
// Lookup the account and JWK for the key ID that authenticated the JWS
|
||||
pubKey, account, prob := wfe.lookupJWK(jws, ctx, request, logEvent)
|
||||
if prob != nil {
|
||||
|
@ -505,7 +506,7 @@ func (wfe *WebFrontEndImpl) validJWSForAccount(
|
|||
func (wfe *WebFrontEndImpl) validPOSTForAccount(
|
||||
request *http.Request,
|
||||
ctx context.Context,
|
||||
logEvent *requestEvent) ([]byte, *jose.JSONWebSignature, *core.Registration, *probs.ProblemDetails) {
|
||||
logEvent *web.RequestEvent) ([]byte, *jose.JSONWebSignature, *core.Registration, *probs.ProblemDetails) {
|
||||
// Parse the JWS from the POST request
|
||||
jws, prob := wfe.parseJWSRequest(request)
|
||||
if prob != nil {
|
||||
|
@ -528,7 +529,7 @@ func (wfe *WebFrontEndImpl) validPOSTForAccount(
|
|||
func (wfe *WebFrontEndImpl) validSelfAuthenticatedJWS(
|
||||
jws *jose.JSONWebSignature,
|
||||
request *http.Request,
|
||||
logEvent *requestEvent) ([]byte, *jose.JSONWebKey, *probs.ProblemDetails) {
|
||||
logEvent *web.RequestEvent) ([]byte, *jose.JSONWebKey, *probs.ProblemDetails) {
|
||||
// Extract the embedded JWK from the parsed JWS
|
||||
pubKey, prob := wfe.extractJWK(jws)
|
||||
if prob != nil {
|
||||
|
@ -554,7 +555,7 @@ func (wfe *WebFrontEndImpl) validSelfAuthenticatedJWS(
|
|||
// using `validSelfAuthenticatedJWS`.
|
||||
func (wfe *WebFrontEndImpl) validSelfAuthenticatedPOST(
|
||||
request *http.Request,
|
||||
logEvent *requestEvent) ([]byte, *jose.JSONWebKey, *probs.ProblemDetails) {
|
||||
logEvent *web.RequestEvent) ([]byte, *jose.JSONWebKey, *probs.ProblemDetails) {
|
||||
// Parse the JWS from the POST request
|
||||
jws, prob := wfe.parseJWSRequest(request)
|
||||
if prob != nil {
|
||||
|
@ -588,7 +589,7 @@ type rolloverRequest struct {
|
|||
func (wfe *WebFrontEndImpl) validKeyRollover(
|
||||
outerJWS *jose.JSONWebSignature,
|
||||
innerJWS *jose.JSONWebSignature,
|
||||
logEvent *requestEvent) (*rolloverRequest, *probs.ProblemDetails) {
|
||||
logEvent *web.RequestEvent) (*rolloverRequest, *probs.ProblemDetails) {
|
||||
|
||||
// Extract the embedded JWK from the inner JWS
|
||||
jwk, prob := wfe.extractJWK(innerJWS)
|
||||
|
@ -616,7 +617,7 @@ func (wfe *WebFrontEndImpl) validKeyRollover(
|
|||
wfe.stats.joseErrorCount.With(prometheus.Labels{"type": "KeyRolloverJWSVerifyFailed"}).Inc()
|
||||
return nil, probs.Malformed("Inner JWS does not verify with embedded JWK")
|
||||
}
|
||||
// NOTE(@cpu): we do not stomp the requestEvent's payload here since that is set
|
||||
// NOTE(@cpu): we do not stomp the web.RequestEvent's payload here since that is set
|
||||
// from the outerJWS in validPOSTForAccount and contains the inner JWS and inner
|
||||
// payload already.
|
||||
|
||||
|
|
64
wfe2/wfe.go
64
wfe2/wfe.go
|
@ -136,7 +136,7 @@ func NewWebFrontEndImpl(
|
|||
// * Never send a body in response to a HEAD request. Anything
|
||||
// written by the handler will be discarded if the method is HEAD.
|
||||
// Also, all handlers that accept GET automatically accept HEAD.
|
||||
func (wfe *WebFrontEndImpl) HandleFunc(mux *http.ServeMux, pattern string, h wfeHandlerFunc, methods ...string) {
|
||||
func (wfe *WebFrontEndImpl) HandleFunc(mux *http.ServeMux, pattern string, h web.WFEHandlerFunc, methods ...string) {
|
||||
methodsMap := make(map[string]bool)
|
||||
for _, m := range methods {
|
||||
methodsMap[m] = true
|
||||
|
@ -147,10 +147,8 @@ func (wfe *WebFrontEndImpl) HandleFunc(mux *http.ServeMux, pattern string, h wfe
|
|||
methodsMap["HEAD"] = true
|
||||
}
|
||||
methodsStr := strings.Join(methods, ", ")
|
||||
handler := http.StripPrefix(pattern, &topHandler{
|
||||
log: wfe.log,
|
||||
clk: clock.Default(),
|
||||
wfe: wfeHandlerFunc(func(ctx context.Context, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
handler := http.StripPrefix(pattern, web.NewTopHandler(wfe.log,
|
||||
web.WFEHandlerFunc(func(ctx context.Context, logEvent *web.RequestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
// We do not propagate errors here, because (1) they should be
|
||||
// transient, and (2) they fail closed.
|
||||
nonce, err := wfe.nonceService.Nonce()
|
||||
|
@ -198,7 +196,7 @@ func (wfe *WebFrontEndImpl) HandleFunc(mux *http.ServeMux, pattern string, h wfe
|
|||
h(ctx, logEvent, response, request)
|
||||
cancel()
|
||||
}),
|
||||
})
|
||||
))
|
||||
mux.Handle(pattern, handler)
|
||||
}
|
||||
|
||||
|
@ -206,7 +204,7 @@ func marshalIndent(v interface{}) ([]byte, error) {
|
|||
return json.MarshalIndent(v, "", " ")
|
||||
}
|
||||
|
||||
func (wfe *WebFrontEndImpl) writeJsonResponse(response http.ResponseWriter, logEvent *requestEvent, status int, v interface{}) error {
|
||||
func (wfe *WebFrontEndImpl) writeJsonResponse(response http.ResponseWriter, logEvent *web.RequestEvent, status int, v interface{}) error {
|
||||
jsonReply, err := marshalIndent(v)
|
||||
if err != nil {
|
||||
return err // All callers are responsible for handling this error
|
||||
|
@ -319,18 +317,14 @@ func (wfe *WebFrontEndImpl) Handler() http.Handler {
|
|||
// We don't use our special HandleFunc for "/" because it matches everything,
|
||||
// meaning we can wind up returning 405 when we mean to return 404. See
|
||||
// https://github.com/letsencrypt/boulder/issues/717
|
||||
m.Handle("/", &topHandler{
|
||||
log: wfe.log,
|
||||
clk: clock.Default(),
|
||||
wfe: wfeHandlerFunc(wfe.Index),
|
||||
})
|
||||
m.Handle("/", web.NewTopHandler(wfe.log, web.WFEHandlerFunc(wfe.Index)))
|
||||
return measured_http.New(m, wfe.clk)
|
||||
}
|
||||
|
||||
// Method implementations
|
||||
|
||||
// Index serves a simple identification page. It is not part of the ACME spec.
|
||||
func (wfe *WebFrontEndImpl) Index(ctx context.Context, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
func (wfe *WebFrontEndImpl) Index(ctx context.Context, logEvent *web.RequestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
// http://golang.org/pkg/net/http/#example_ServeMux_Handle
|
||||
// The "/" pattern matches everything, so we need to check
|
||||
// that we're at the root here.
|
||||
|
@ -373,7 +367,7 @@ func addRequesterHeader(w http.ResponseWriter, requester int64) {
|
|||
// Directory is an HTTP request handler that provides the directory
|
||||
// object stored in the WFE's DirectoryEndpoints member with paths prefixed
|
||||
// using the `request.Host` of the HTTP request.
|
||||
func (wfe *WebFrontEndImpl) Directory(ctx context.Context, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
func (wfe *WebFrontEndImpl) Directory(ctx context.Context, logEvent *web.RequestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
directoryEndpoints := map[string]interface{}{
|
||||
"new-account": newAcctPath,
|
||||
"revoke-cert": revokeCertPath,
|
||||
|
@ -409,7 +403,7 @@ func (wfe *WebFrontEndImpl) Directory(ctx context.Context, logEvent *requestEven
|
|||
// and, if the ProblemDetails.Type is ServerInternalProblem, audit logs the
|
||||
// internal ierr. The rendered Problem will have its Type prefixed with the ACME
|
||||
// v2 error namespace.
|
||||
func (wfe *WebFrontEndImpl) sendError(response http.ResponseWriter, logEvent *requestEvent, prob *probs.ProblemDetails, ierr error) {
|
||||
func (wfe *WebFrontEndImpl) sendError(response http.ResponseWriter, logEvent *web.RequestEvent, prob *probs.ProblemDetails, ierr error) {
|
||||
// Determine the HTTP status code to use for this problem
|
||||
code := probs.ProblemDetailsToStatusCode(prob)
|
||||
|
||||
|
@ -450,7 +444,7 @@ func link(url, relation string) string {
|
|||
// NewAccount is used by clients to submit a new account
|
||||
func (wfe *WebFrontEndImpl) NewAccount(
|
||||
ctx context.Context,
|
||||
logEvent *requestEvent,
|
||||
logEvent *web.RequestEvent,
|
||||
response http.ResponseWriter,
|
||||
request *http.Request) {
|
||||
|
||||
|
@ -562,7 +556,7 @@ func (wfe *WebFrontEndImpl) processRevocation(
|
|||
acctID int64,
|
||||
authorizedToRevoke authorizedToRevokeCert,
|
||||
request *http.Request,
|
||||
logEvent *requestEvent) *probs.ProblemDetails {
|
||||
logEvent *web.RequestEvent) *probs.ProblemDetails {
|
||||
// Read the revoke request from the JWS payload
|
||||
var revokeRequest struct {
|
||||
CertificateDER core.JSONBuffer `json:"certificate"`
|
||||
|
@ -642,7 +636,7 @@ func (wfe *WebFrontEndImpl) revokeCertByKeyID(
|
|||
ctx context.Context,
|
||||
outerJWS *jose.JSONWebSignature,
|
||||
request *http.Request,
|
||||
logEvent *requestEvent) *probs.ProblemDetails {
|
||||
logEvent *web.RequestEvent) *probs.ProblemDetails {
|
||||
// For Key ID revocations we authenticate the outer JWS by using
|
||||
// `validJWSForAccount` similar to other WFE endpoints
|
||||
jwsBody, _, acct, prob := wfe.validJWSForAccount(outerJWS, request, ctx, logEvent)
|
||||
|
@ -674,7 +668,7 @@ func (wfe *WebFrontEndImpl) revokeCertByJWK(
|
|||
ctx context.Context,
|
||||
outerJWS *jose.JSONWebSignature,
|
||||
request *http.Request,
|
||||
logEvent *requestEvent) *probs.ProblemDetails {
|
||||
logEvent *web.RequestEvent) *probs.ProblemDetails {
|
||||
// We maintain the requestKey as a var that is closed-over by the
|
||||
// `authorizedToRevoke` function to use
|
||||
var requestKey *jose.JSONWebKey
|
||||
|
@ -707,7 +701,7 @@ func (wfe *WebFrontEndImpl) revokeCertByJWK(
|
|||
// used.
|
||||
func (wfe *WebFrontEndImpl) RevokeCertificate(
|
||||
ctx context.Context,
|
||||
logEvent *requestEvent,
|
||||
logEvent *web.RequestEvent,
|
||||
response http.ResponseWriter,
|
||||
request *http.Request) {
|
||||
|
||||
|
@ -755,7 +749,7 @@ func (wfe *WebFrontEndImpl) logCsr(request *http.Request, cr core.CertificateReq
|
|||
CSR string
|
||||
Registration core.Registration
|
||||
}{
|
||||
ClientAddr: getClientAddr(request),
|
||||
ClientAddr: web.GetClientAddr(request),
|
||||
CSR: hex.EncodeToString(cr.Bytes),
|
||||
Registration: account,
|
||||
}
|
||||
|
@ -766,7 +760,7 @@ func (wfe *WebFrontEndImpl) logCsr(request *http.Request, cr core.CertificateReq
|
|||
// responses to the server's challenges.
|
||||
func (wfe *WebFrontEndImpl) Challenge(
|
||||
ctx context.Context,
|
||||
logEvent *requestEvent,
|
||||
logEvent *web.RequestEvent,
|
||||
response http.ResponseWriter,
|
||||
request *http.Request) {
|
||||
|
||||
|
@ -864,7 +858,7 @@ func (wfe *WebFrontEndImpl) getChallenge(
|
|||
request *http.Request,
|
||||
authz core.Authorization,
|
||||
challenge *core.Challenge,
|
||||
logEvent *requestEvent) {
|
||||
logEvent *web.RequestEvent) {
|
||||
|
||||
wfe.prepChallengeForDisplay(request, authz, challenge)
|
||||
|
||||
|
@ -887,7 +881,7 @@ func (wfe *WebFrontEndImpl) postChallenge(
|
|||
request *http.Request,
|
||||
authz core.Authorization,
|
||||
challengeIndex int,
|
||||
logEvent *requestEvent) {
|
||||
logEvent *web.RequestEvent) {
|
||||
body, _, currAcct, prob := wfe.validPOSTForAccount(request, ctx, logEvent)
|
||||
addRequesterHeader(response, logEvent.Requester)
|
||||
if prob != nil {
|
||||
|
@ -947,7 +941,7 @@ func (wfe *WebFrontEndImpl) postChallenge(
|
|||
// Account is used by a client to submit an update to their account.
|
||||
func (wfe *WebFrontEndImpl) Account(
|
||||
ctx context.Context,
|
||||
logEvent *requestEvent,
|
||||
logEvent *web.RequestEvent,
|
||||
response http.ResponseWriter,
|
||||
request *http.Request) {
|
||||
body, _, currAcct, prob := wfe.validPOSTForAccount(request, ctx, logEvent)
|
||||
|
@ -1045,7 +1039,7 @@ func (wfe *WebFrontEndImpl) Account(
|
|||
func (wfe *WebFrontEndImpl) deactivateAuthorization(
|
||||
ctx context.Context,
|
||||
authz *core.Authorization,
|
||||
logEvent *requestEvent,
|
||||
logEvent *web.RequestEvent,
|
||||
response http.ResponseWriter,
|
||||
request *http.Request) bool {
|
||||
body, _, acct, prob := wfe.validPOSTForAccount(request, ctx, logEvent)
|
||||
|
@ -1085,7 +1079,7 @@ func (wfe *WebFrontEndImpl) deactivateAuthorization(
|
|||
|
||||
// Authorization is used by clients to submit an update to one of their
|
||||
// authorizations.
|
||||
func (wfe *WebFrontEndImpl) Authorization(ctx context.Context, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
func (wfe *WebFrontEndImpl) Authorization(ctx context.Context, logEvent *web.RequestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
// Requests to this handler should have a path that leads to a known authz
|
||||
id := request.URL.Path
|
||||
authz, err := wfe.SA.GetAuthorization(ctx, id)
|
||||
|
@ -1129,7 +1123,7 @@ var allHex = regexp.MustCompile("^[0-9a-f]+$")
|
|||
|
||||
// Certificate is used by clients to request a copy of their current certificate, or to
|
||||
// request a reissuance of the certificate.
|
||||
func (wfe *WebFrontEndImpl) Certificate(ctx context.Context, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
func (wfe *WebFrontEndImpl) Certificate(ctx context.Context, logEvent *web.RequestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
|
||||
serial := request.URL.Path
|
||||
// Certificate paths consist of the CertBase path, plus exactly sixteen hex
|
||||
|
@ -1176,12 +1170,12 @@ func (wfe *WebFrontEndImpl) Certificate(ctx context.Context, logEvent *requestEv
|
|||
|
||||
// Terms is used by the client to obtain the current Terms of Service /
|
||||
// Subscriber Agreement to which the subscriber must agree.
|
||||
func (wfe *WebFrontEndImpl) Terms(ctx context.Context, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
func (wfe *WebFrontEndImpl) Terms(ctx context.Context, logEvent *web.RequestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
http.Redirect(response, request, wfe.SubscriberAgreementURL, http.StatusFound)
|
||||
}
|
||||
|
||||
// Issuer obtains the issuer certificate used by this instance of Boulder.
|
||||
func (wfe *WebFrontEndImpl) Issuer(ctx context.Context, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
func (wfe *WebFrontEndImpl) Issuer(ctx context.Context, logEvent *web.RequestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
// TODO Content negotiation
|
||||
response.Header().Set("Content-Type", "application/pkix-cert")
|
||||
response.WriteHeader(http.StatusOK)
|
||||
|
@ -1192,7 +1186,7 @@ func (wfe *WebFrontEndImpl) Issuer(ctx context.Context, logEvent *requestEvent,
|
|||
}
|
||||
|
||||
// BuildID tells the requestor what build we're running.
|
||||
func (wfe *WebFrontEndImpl) BuildID(ctx context.Context, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
func (wfe *WebFrontEndImpl) BuildID(ctx context.Context, logEvent *web.RequestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
response.Header().Set("Content-Type", "text/plain")
|
||||
response.WriteHeader(http.StatusOK)
|
||||
detailsString := fmt.Sprintf("Boulder=(%s %s)", core.GetBuildID(), core.GetBuildTime())
|
||||
|
@ -1259,7 +1253,7 @@ func (wfe *WebFrontEndImpl) setCORSHeaders(response http.ResponseWriter, request
|
|||
// KeyRollover allows a user to change their signing key
|
||||
func (wfe *WebFrontEndImpl) KeyRollover(
|
||||
ctx context.Context,
|
||||
logEvent *requestEvent,
|
||||
logEvent *web.RequestEvent,
|
||||
response http.ResponseWriter,
|
||||
request *http.Request) {
|
||||
// Validate the outer JWS on the key rollover in standard fashion using
|
||||
|
@ -1343,7 +1337,7 @@ func (wfe *WebFrontEndImpl) deactivateAccount(
|
|||
acct core.Registration,
|
||||
response http.ResponseWriter,
|
||||
request *http.Request,
|
||||
logEvent *requestEvent) {
|
||||
logEvent *web.RequestEvent) {
|
||||
err := wfe.RA.DeactivateRegistration(ctx, acct)
|
||||
if err != nil {
|
||||
wfe.sendError(response, logEvent,
|
||||
|
@ -1388,7 +1382,7 @@ type orderJSON struct {
|
|||
// NewOrder is used by clients to create a new order object from a CSR
|
||||
func (wfe *WebFrontEndImpl) NewOrder(
|
||||
ctx context.Context,
|
||||
logEvent *requestEvent,
|
||||
logEvent *web.RequestEvent,
|
||||
response http.ResponseWriter,
|
||||
request *http.Request) {
|
||||
body, _, acct, prob := wfe.validPOSTForAccount(request, ctx, logEvent)
|
||||
|
@ -1460,7 +1454,7 @@ func (wfe *WebFrontEndImpl) NewOrder(
|
|||
}
|
||||
|
||||
// Order is used to retrieve a existing order object
|
||||
func (wfe *WebFrontEndImpl) Order(ctx context.Context, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
func (wfe *WebFrontEndImpl) Order(ctx context.Context, logEvent *web.RequestEvent, response http.ResponseWriter, request *http.Request) {
|
||||
fields := strings.SplitN(request.URL.Path, "/", 2)
|
||||
if len(fields) != 2 {
|
||||
wfe.sendError(response, logEvent, probs.Malformed("Invalid request path"), nil)
|
||||
|
|
|
@ -37,6 +37,7 @@ import (
|
|||
rapb "github.com/letsencrypt/boulder/ra/proto"
|
||||
"github.com/letsencrypt/boulder/revocation"
|
||||
"github.com/letsencrypt/boulder/test"
|
||||
"github.com/letsencrypt/boulder/web"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -403,7 +404,7 @@ func TestHandleFunc(t *testing.T) {
|
|||
mux = http.NewServeMux()
|
||||
rw = httptest.NewRecorder()
|
||||
stubCalled = false
|
||||
wfe.HandleFunc(mux, "/test", func(context.Context, *requestEvent, http.ResponseWriter, *http.Request) {
|
||||
wfe.HandleFunc(mux, "/test", func(context.Context, *web.RequestEvent, http.ResponseWriter, *http.Request) {
|
||||
stubCalled = true
|
||||
}, allowed...)
|
||||
req.URL = mustParseURL("/test")
|
||||
|
@ -1563,8 +1564,8 @@ func TestGetCertificateHEADHasCorrectBodyLength(t *testing.T) {
|
|||
test.AssertEquals(t, 0, len(body))
|
||||
}
|
||||
|
||||
func newRequestEvent() *requestEvent {
|
||||
return &requestEvent{Extra: make(map[string]interface{})}
|
||||
func newRequestEvent() *web.RequestEvent {
|
||||
return &web.RequestEvent{Extra: make(map[string]interface{})}
|
||||
}
|
||||
|
||||
func TestHeaderBoulderRequester(t *testing.T) {
|
||||
|
|
Loading…
Reference in New Issue