-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
af1b83a
commit 2ac9e6c
Showing
8 changed files
with
495 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
name: build | ||
|
||
on: | ||
push: | ||
tags: | ||
- v* | ||
branches: | ||
- master | ||
- dev | ||
pull_request: | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Setup Go environment | ||
uses: actions/setup-go@v3.0.0 | ||
with: | ||
go-version: 1.18 | ||
|
||
- name: checkout | ||
uses: actions/checkout@v3.0.0 | ||
|
||
- name: build and test | ||
run: | | ||
go get -v | ||
go test -timeout=60s | ||
go build -race | ||
- name: Run golangci-lint | ||
uses: golangci/golangci-lint-action@v3.1.0 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// Package correlationid provides handler for getting correlationid header from request or generate new and set it to request context. | ||
package correlationid | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net/http" | ||
|
||
"github.com/google/uuid" | ||
) | ||
|
||
const ( | ||
// Header name. Can be overridden in Middlware struct. | ||
DefaultHeaderName = "Correlation-Id" | ||
// Key used for correlation id value in context. | ||
ContextKey = "CorrelationId" | ||
) | ||
|
||
// Middlware struct with handler settings. | ||
type Middleware struct { | ||
// Used for correlation id. Default "Correlation-Id". | ||
HeaderName string | ||
// Used for indicating should correlation id be included in response headers. Default "true". | ||
IncludeInResponse bool | ||
// Used for enforcing client include correlation id header in request. If "true" and header is absent - middlware will return BadRequest status code. | ||
// Default "false". | ||
EnforceHeader bool | ||
// Used for correlation id generation if id is not included in request. By default uses github.com/google/uuid. | ||
IdGenerator func() string | ||
} | ||
|
||
// Initialize default value of middleware. By default uses github.com/google/uuid for correlation id value. | ||
func New() Middleware { | ||
return Middleware{ | ||
HeaderName: DefaultHeaderName, | ||
IncludeInResponse: true, | ||
EnforceHeader: false, | ||
IdGenerator: defaultGenerator, | ||
} | ||
} | ||
|
||
// Handles http request and proceed correlation id based on Middlware settings. | ||
func (m *Middleware) Handle(next http.Handler) http.Handler { | ||
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { | ||
headerName := m.getHeaderName() | ||
corrId := r.Header.Get(headerName) | ||
if corrId == "" { | ||
if m.EnforceHeader { | ||
http.Error(rw, fmt.Sprintf("%s header is required.", headerName), http.StatusBadRequest) | ||
return | ||
} | ||
|
||
corrId = m.generateId() | ||
} | ||
|
||
if m.IncludeInResponse { | ||
rw.Header().Set(headerName, corrId) | ||
} | ||
|
||
updCtx := WithCorrelationId(r.Context(), corrId) | ||
next.ServeHTTP(rw, r.WithContext(updCtx)) | ||
}) | ||
} | ||
|
||
// Returns correlation id from context if present. Otherwise "". | ||
func FromContext(ctx context.Context) string { | ||
corrId, ok := ctx.Value(ContextKey).(string) | ||
if ok { | ||
return corrId | ||
} | ||
return "" | ||
} | ||
|
||
// Sets correlation id to context | ||
func WithCorrelationId(ctx context.Context, correlationId string) context.Context { | ||
return context.WithValue(ctx, ContextKey, correlationId) | ||
} | ||
|
||
func defaultGenerator() string { | ||
return uuid.NewString() | ||
} | ||
|
||
func (m *Middleware) getHeaderName() string { | ||
if m.HeaderName == "" { | ||
return DefaultHeaderName | ||
} | ||
|
||
return m.HeaderName | ||
} | ||
|
||
func (m *Middleware) generateId() string { | ||
if m.IdGenerator != nil { | ||
return m.IdGenerator() | ||
} | ||
|
||
return defaultGenerator() | ||
} |
Oops, something went wrong.