src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

checksum_middleware.go (1984B)


      1 package http
      2 
      3 import (
      4 	"context"
      5 	"fmt"
      6 
      7 	"github.com/aws/smithy-go/middleware"
      8 )
      9 
     10 const contentMD5Header = "Content-Md5"
     11 
     12 // contentMD5Checksum provides a middleware to compute and set
     13 // content-md5 checksum for a http request
     14 type contentMD5Checksum struct {
     15 }
     16 
     17 // AddContentChecksumMiddleware adds checksum middleware to middleware's
     18 // build step.
     19 func AddContentChecksumMiddleware(stack *middleware.Stack) error {
     20 	// This middleware must be executed before request body is set.
     21 	return stack.Build.Add(&contentMD5Checksum{}, middleware.Before)
     22 }
     23 
     24 // ID returns the identifier for the checksum middleware
     25 func (m *contentMD5Checksum) ID() string { return "ContentChecksum" }
     26 
     27 // HandleBuild adds behavior to compute md5 checksum and add content-md5 header
     28 // on http request
     29 func (m *contentMD5Checksum) HandleBuild(
     30 	ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler,
     31 ) (
     32 	out middleware.BuildOutput, metadata middleware.Metadata, err error,
     33 ) {
     34 	req, ok := in.Request.(*Request)
     35 	if !ok {
     36 		return out, metadata, fmt.Errorf("unknown request type %T", req)
     37 	}
     38 
     39 	// if Content-MD5 header is already present, return
     40 	if v := req.Header.Get(contentMD5Header); len(v) != 0 {
     41 		return next.HandleBuild(ctx, in)
     42 	}
     43 
     44 	// fetch the request stream.
     45 	stream := req.GetStream()
     46 	// compute checksum if payload is explicit
     47 	if stream != nil {
     48 		if !req.IsStreamSeekable() {
     49 			return out, metadata, fmt.Errorf(
     50 				"unseekable stream is not supported for computing md5 checksum")
     51 		}
     52 
     53 		v, err := computeMD5Checksum(stream)
     54 		if err != nil {
     55 			return out, metadata, fmt.Errorf("error computing md5 checksum, %w", err)
     56 		}
     57 
     58 		// reset the request stream
     59 		if err := req.RewindStream(); err != nil {
     60 			return out, metadata, fmt.Errorf(
     61 				"error rewinding request stream after computing md5 checksum, %w", err)
     62 		}
     63 
     64 		// set the 'Content-MD5' header
     65 		req.Header.Set(contentMD5Header, string(v))
     66 	}
     67 
     68 	// set md5 header value
     69 	return next.HandleBuild(ctx, in)
     70 }