Factor out JSON writing in WFE (#2226)
This PR, removes some duplication in the WFE in regards to writing a JSON response. Fixes #2156
This commit is contained in:
parent
5fabc90a16
commit
00708708e4
118
wfe/wfe.go
118
wfe/wfe.go
|
@ -193,6 +193,24 @@ func marshalIndent(v interface{}) ([]byte, error) {
|
|||
return json.MarshalIndent(v, "", " ")
|
||||
}
|
||||
|
||||
func (wfe *WebFrontEndImpl) writeJsonResponse(response http.ResponseWriter, logEvent *requestEvent, status int, v interface{}) error {
|
||||
jsonReply, err := marshalIndent(v)
|
||||
if err != nil {
|
||||
return err // All callers are responsible for handling this error
|
||||
}
|
||||
|
||||
response.Header().Set("Content-Type", "application/json")
|
||||
response.WriteHeader(status)
|
||||
_, err = response.Write(jsonReply)
|
||||
if err != nil {
|
||||
// Don't worry about returning this error because the caller will
|
||||
// never handle it.
|
||||
wfe.log.Warning(fmt.Sprintf("Could not write response: %s", err))
|
||||
logEvent.AddError(fmt.Sprintf("failed to write response: %s", err))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (wfe *WebFrontEndImpl) relativeEndpoint(request *http.Request, endpoint string) string {
|
||||
var result string
|
||||
proto := "http"
|
||||
|
@ -602,7 +620,14 @@ func (wfe *WebFrontEndImpl) NewRegistration(ctx context.Context, logEvent *reque
|
|||
// Use an explicitly typed variable. Otherwise `go vet' incorrectly complains
|
||||
// that reg.ID is a string being passed to %d.
|
||||
regURL := wfe.relativeEndpoint(request, fmt.Sprintf("%s%d", regPath, reg.ID))
|
||||
responseBody, err := marshalIndent(reg)
|
||||
|
||||
response.Header().Add("Location", regURL)
|
||||
response.Header().Add("Link", link(wfe.relativeEndpoint(request, newAuthzPath), "next"))
|
||||
if len(wfe.SubscriberAgreementURL) > 0 {
|
||||
response.Header().Add("Link", link(wfe.SubscriberAgreementURL, "terms-of-service"))
|
||||
}
|
||||
|
||||
err = wfe.writeJsonResponse(response, logEvent, http.StatusCreated, reg)
|
||||
if err != nil {
|
||||
// ServerInternal because we just created this registration, and it
|
||||
// should be OK.
|
||||
|
@ -610,16 +635,6 @@ func (wfe *WebFrontEndImpl) NewRegistration(ctx context.Context, logEvent *reque
|
|||
wfe.sendError(response, logEvent, probs.ServerInternal("Error marshaling registration"), err)
|
||||
return
|
||||
}
|
||||
|
||||
response.Header().Add("Location", regURL)
|
||||
response.Header().Set("Content-Type", "application/json")
|
||||
response.Header().Add("Link", link(wfe.relativeEndpoint(request, newAuthzPath), "next"))
|
||||
if len(wfe.SubscriberAgreementURL) > 0 {
|
||||
response.Header().Add("Link", link(wfe.SubscriberAgreementURL, "terms-of-service"))
|
||||
}
|
||||
|
||||
response.WriteHeader(http.StatusCreated)
|
||||
response.Write(responseBody)
|
||||
}
|
||||
|
||||
// NewAuthorization is used by clients to submit a new ID Authorization
|
||||
|
@ -659,21 +674,16 @@ func (wfe *WebFrontEndImpl) NewAuthorization(ctx context.Context, logEvent *requ
|
|||
// Make a URL for this authz, then blow away the ID and RegID before serializing
|
||||
authzURL := wfe.relativeEndpoint(request, authzPath+string(authz.ID))
|
||||
wfe.prepAuthorizationForDisplay(request, &authz)
|
||||
responseBody, err := marshalIndent(authz)
|
||||
|
||||
response.Header().Add("Location", authzURL)
|
||||
response.Header().Add("Link", link(wfe.relativeEndpoint(request, newCertPath), "next"))
|
||||
|
||||
err = wfe.writeJsonResponse(response, logEvent, http.StatusCreated, authz)
|
||||
if err != nil {
|
||||
// ServerInternal because we generated the authz, it should be OK
|
||||
wfe.sendError(response, logEvent, probs.ServerInternal("Error marshaling authz"), err)
|
||||
return
|
||||
}
|
||||
|
||||
response.Header().Add("Location", authzURL)
|
||||
response.Header().Add("Link", link(wfe.relativeEndpoint(request, newCertPath), "next"))
|
||||
response.Header().Set("Content-Type", "application/json")
|
||||
response.WriteHeader(http.StatusCreated)
|
||||
if _, err = response.Write(responseBody); err != nil {
|
||||
logEvent.AddError(err.Error())
|
||||
wfe.log.Warning(fmt.Sprintf("Could not write response: %s", err))
|
||||
}
|
||||
}
|
||||
|
||||
// RevokeCertificate is used by clients to request the revocation of a cert.
|
||||
|
@ -986,7 +996,11 @@ func (wfe *WebFrontEndImpl) getChallenge(
|
|||
|
||||
wfe.prepChallengeForDisplay(request, authz, challenge)
|
||||
|
||||
jsonReply, err := marshalIndent(challenge)
|
||||
authzURL := wfe.relativeEndpoint(request, authzPath+string(authz.ID))
|
||||
response.Header().Add("Location", challenge.URI)
|
||||
response.Header().Add("Link", link(authzURL, "up"))
|
||||
|
||||
err := wfe.writeJsonResponse(response, logEvent, http.StatusAccepted, challenge)
|
||||
if err != nil {
|
||||
// InternalServerError because this is a failure to decode data passed in
|
||||
// by the caller, which got it from the DB.
|
||||
|
@ -994,17 +1008,6 @@ func (wfe *WebFrontEndImpl) getChallenge(
|
|||
wfe.sendError(response, logEvent, probs.ServerInternal("Failed to marshal challenge"), err)
|
||||
return
|
||||
}
|
||||
|
||||
authzURL := wfe.relativeEndpoint(request, authzPath+string(authz.ID))
|
||||
response.Header().Add("Location", challenge.URI)
|
||||
response.Header().Set("Content-Type", "application/json")
|
||||
response.Header().Add("Link", link(authzURL, "up"))
|
||||
response.WriteHeader(http.StatusAccepted)
|
||||
if _, err := response.Write(jsonReply); err != nil {
|
||||
wfe.log.Warning(fmt.Sprintf("Could not write response: %s", err))
|
||||
logEvent.AddError(err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (wfe *WebFrontEndImpl) postChallenge(
|
||||
|
@ -1059,24 +1062,18 @@ func (wfe *WebFrontEndImpl) postChallenge(
|
|||
// assumption: UpdateAuthorization does not modify order of challenges
|
||||
challenge := updatedAuthorization.Challenges[challengeIndex]
|
||||
wfe.prepChallengeForDisplay(request, authz, &challenge)
|
||||
jsonReply, err := marshalIndent(challenge)
|
||||
|
||||
authzURL := wfe.relativeEndpoint(request, authzPath+string(authz.ID))
|
||||
response.Header().Add("Location", challenge.URI)
|
||||
response.Header().Add("Link", link(authzURL, "up"))
|
||||
|
||||
err = wfe.writeJsonResponse(response, logEvent, http.StatusAccepted, challenge)
|
||||
if err != nil {
|
||||
// ServerInternal because we made the challenges, they should be OK
|
||||
logEvent.AddError("failed to marshal challenge: %s", err)
|
||||
wfe.sendError(response, logEvent, probs.ServerInternal("Failed to marshal challenge"), err)
|
||||
return
|
||||
}
|
||||
|
||||
authzURL := wfe.relativeEndpoint(request, authzPath+string(authz.ID))
|
||||
response.Header().Add("Location", challenge.URI)
|
||||
response.Header().Set("Content-Type", "application/json")
|
||||
response.Header().Add("Link", link(authzURL, "up"))
|
||||
response.WriteHeader(http.StatusAccepted)
|
||||
if _, err = response.Write(jsonReply); err != nil {
|
||||
logEvent.AddError(err.Error())
|
||||
wfe.log.Warning(fmt.Sprintf("Could not write response: %s", err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Registration is used by a client to submit an update to their registration.
|
||||
|
@ -1163,20 +1160,18 @@ func (wfe *WebFrontEndImpl) Registration(ctx context.Context, logEvent *requestE
|
|||
return
|
||||
}
|
||||
|
||||
jsonReply, err := marshalIndent(updatedReg)
|
||||
response.Header().Add("Link", link(wfe.relativeEndpoint(request, newAuthzPath), "next"))
|
||||
if len(wfe.SubscriberAgreementURL) > 0 {
|
||||
response.Header().Add("Link", link(wfe.SubscriberAgreementURL, "terms-of-service"))
|
||||
}
|
||||
|
||||
err = wfe.writeJsonResponse(response, logEvent, http.StatusAccepted, updatedReg)
|
||||
if err != nil {
|
||||
// ServerInternal because we just generated the reg, it should be OK
|
||||
logEvent.AddError("unable to marshal updated registration: %s", err)
|
||||
wfe.sendError(response, logEvent, probs.ServerInternal("Failed to marshal registration"), err)
|
||||
return
|
||||
}
|
||||
response.Header().Set("Content-Type", "application/json")
|
||||
response.Header().Add("Link", link(wfe.relativeEndpoint(request, newAuthzPath), "next"))
|
||||
if len(wfe.SubscriberAgreementURL) > 0 {
|
||||
response.Header().Add("Link", link(wfe.SubscriberAgreementURL, "terms-of-service"))
|
||||
}
|
||||
response.WriteHeader(http.StatusAccepted)
|
||||
response.Write(jsonReply)
|
||||
}
|
||||
|
||||
func (wfe *WebFrontEndImpl) deactivateAuthorization(ctx context.Context, authz *core.Authorization, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) bool {
|
||||
|
@ -1254,20 +1249,15 @@ func (wfe *WebFrontEndImpl) Authorization(ctx context.Context, logEvent *request
|
|||
|
||||
wfe.prepAuthorizationForDisplay(request, &authz)
|
||||
|
||||
jsonReply, err := marshalIndent(authz)
|
||||
response.Header().Add("Link", link(wfe.relativeEndpoint(request, newCertPath), "next"))
|
||||
|
||||
err = wfe.writeJsonResponse(response, logEvent, http.StatusOK, authz)
|
||||
if err != nil {
|
||||
// InternalServerError because this is a failure to decode from our DB.
|
||||
logEvent.AddError("Failed to JSON marshal authz: %s", err)
|
||||
wfe.sendError(response, logEvent, probs.ServerInternal("Failed to JSON marshal authz"), err)
|
||||
return
|
||||
}
|
||||
response.Header().Add("Link", link(wfe.relativeEndpoint(request, newCertPath), "next"))
|
||||
response.Header().Set("Content-Type", "application/json")
|
||||
response.WriteHeader(http.StatusOK)
|
||||
if _, err = response.Write(jsonReply); err != nil {
|
||||
logEvent.AddError(err.Error())
|
||||
wfe.log.Warning(fmt.Sprintf("Could not write response: %s", err))
|
||||
}
|
||||
}
|
||||
|
||||
var allHex = regexp.MustCompile("^[0-9a-f]+$")
|
||||
|
@ -1400,14 +1390,12 @@ func (wfe *WebFrontEndImpl) deactivateRegistration(ctx context.Context, reg core
|
|||
return
|
||||
}
|
||||
reg.Status = core.StatusDeactivated
|
||||
jsonReply, err := marshalIndent(reg)
|
||||
|
||||
err = wfe.writeJsonResponse(response, logEvent, http.StatusOK, reg)
|
||||
if err != nil {
|
||||
// ServerInternal because registration is from DB and should be fine
|
||||
logEvent.AddError("unable to marshal updated registration: %s", err)
|
||||
wfe.sendError(response, logEvent, probs.ServerInternal("Failed to marshal registration"), err)
|
||||
return
|
||||
}
|
||||
response.Header().Set("Content-Type", "application/json")
|
||||
response.WriteHeader(http.StatusOK)
|
||||
response.Write(jsonReply)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue