github.com/google/martian/v3@v3.3.3/status/status_verifier.go (about)

     1  // Copyright 2015 Google Inc. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package status
    16  
    17  import (
    18  	"encoding/json"
    19  	"fmt"
    20  	"net/http"
    21  
    22  	"github.com/google/martian/v3"
    23  	"github.com/google/martian/v3/parse"
    24  	"github.com/google/martian/v3/verify"
    25  )
    26  
    27  const errFormat = "response(%s) status code verify failure: got %d, want %d"
    28  
    29  // Verifier verifies the status codes of all responses.
    30  type Verifier struct {
    31  	statusCode int
    32  	err        *martian.MultiError
    33  }
    34  
    35  type verifierJSON struct {
    36  	StatusCode int                  `json:"statusCode"`
    37  	Scope      []parse.ModifierType `json:"scope"`
    38  }
    39  
    40  func init() {
    41  	parse.Register("status.Verifier", verifierFromJSON)
    42  }
    43  
    44  // NewVerifier returns a new status.Verifier for statusCode.
    45  func NewVerifier(statusCode int) verify.ResponseVerifier {
    46  	return &Verifier{
    47  		statusCode: statusCode,
    48  		err:        martian.NewMultiError(),
    49  	}
    50  }
    51  
    52  // ModifyResponse verifies that the status code for all requests
    53  // matches statusCode.
    54  func (v *Verifier) ModifyResponse(res *http.Response) error {
    55  	ctx := martian.NewContext(res.Request)
    56  	if ctx.IsAPIRequest() {
    57  		return nil
    58  	}
    59  
    60  	if res.StatusCode != v.statusCode {
    61  		v.err.Add(fmt.Errorf(errFormat, res.Request.URL, res.StatusCode, v.statusCode))
    62  	}
    63  
    64  	return nil
    65  }
    66  
    67  // VerifyResponses returns an error if verification for any
    68  // request failed.
    69  // If an error is returned it will be of type *martian.MultiError.
    70  func (v *Verifier) VerifyResponses() error {
    71  	if v.err.Empty() {
    72  		return nil
    73  	}
    74  
    75  	return v.err
    76  }
    77  
    78  // ResetResponseVerifications clears all failed response verifications.
    79  func (v *Verifier) ResetResponseVerifications() {
    80  	v.err = martian.NewMultiError()
    81  }
    82  
    83  // verifierFromJSON builds a status.Verifier from JSON.
    84  //
    85  // Example JSON:
    86  // {
    87  //   "status.Verifier": {
    88  //     "scope": ["response"],
    89  //     "statusCode": 401
    90  //   }
    91  // }
    92  func verifierFromJSON(b []byte) (*parse.Result, error) {
    93  	msg := &verifierJSON{}
    94  	if err := json.Unmarshal(b, msg); err != nil {
    95  		return nil, err
    96  	}
    97  
    98  	return parse.NewResult(NewVerifier(msg.StatusCode), msg.Scope)
    99  }