// LogRequest creates a request logger middleware. // This middleware is aware of the RequestID middleware and if registered after it leverages the // request ID for logging. // If verbose is true then the middlware logs the request and response bodies. func LogRequest(verbose bool) goa.Middleware { return func(h goa.Handler) goa.Handler { return func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error { reqID := ctx.Value(reqIDKey) if reqID == nil { reqID = shortID() } ctx = goa.WithLogContext(ctx, "req_id", reqID) startedAt := time.Now() r := goa.ContextRequest(ctx) goa.LogInfo(ctx, "started", r.Method, r.URL.String(), "from", from(req), "ctrl", goa.ContextController(ctx), "action", goa.ContextAction(ctx)) if verbose { if len(r.Params) > 0 { logCtx := make([]interface{}, 2*len(r.Params)) i := 0 for k, v := range r.Params { logCtx[i] = k logCtx[i+1] = interface{}(strings.Join(v, ", ")) i = i + 2 } goa.LogInfo(ctx, "params", logCtx...) } if r.ContentLength > 0 { if mp, ok := r.Payload.(map[string]interface{}); ok { logCtx := make([]interface{}, 2*len(mp)) i := 0 for k, v := range mp { logCtx[i] = k logCtx[i+1] = interface{}(v) i = i + 2 } goa.LogInfo(ctx, "payload", logCtx...) } else { // Not the most efficient but this is used for debugging js, err := json.Marshal(r.Payload) if err != nil { js = []byte("<invalid JSON>") } goa.LogInfo(ctx, "payload", "raw", string(js)) } } } err := h(ctx, rw, req) resp := goa.ContextResponse(ctx) if code := resp.ErrorCode; code != "" { goa.LogInfo(ctx, "completed", "status", resp.Status, "error", code, "bytes", resp.Length, "time", time.Since(startedAt).String()) } else { goa.LogInfo(ctx, "completed", "status", resp.Status, "bytes", resp.Length, "time", time.Since(startedAt).String()) } return err } } }
// Run downloads files with given paths. func (cmd *DownloadCommand) Run(c *client.Client, args []string) error { var ( fnf func(context.Context, string) (int64, error) fnd func(context.Context, string, string) (int64, error) rpath = args[0] outfile = cmd.OutFile logger = goa.NewLogger(log.New(os.Stderr, "", log.LstdFlags)) ctx = goa.WithLogger(context.Background(), logger) err error ) if rpath[0] != '/' { rpath = "/" + rpath } if rpath == "/swagger.json" { fnf = c.DownloadSwaggerJSON if outfile == "" { outfile = "swagger.json" } goto found } if strings.HasPrefix(rpath, "/swagger-ui/") { fnd = c.DownloadSwaggerUI rpath = rpath[12:] if outfile == "" { _, outfile = path.Split(rpath) } goto found } return fmt.Errorf("don't know how to download %s", rpath) found: ctx = goa.WithLogContext(ctx, "file", outfile) if fnf != nil { _, err = fnf(ctx, outfile) } else { _, err = fnd(ctx, rpath, outfile) } if err != nil { goa.LogError(ctx, "failed", "err", err) return err } return nil }
// handleSpecOrigin applies the CORS response headers corresponding to the origin. func handleSpecOrigin(h goa.Handler) goa.Handler { return func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error { origin := req.Header.Get("Origin") if origin == "" { // Not a CORS request return h(ctx, rw, req) } if cors.MatchOrigin(origin, "*") { ctx = goa.WithLogContext(ctx, "origin", origin) rw.Header().Set("Access-Control-Allow-Origin", origin) rw.Header().Set("Access-Control-Allow-Credentials", "false") if acrm := req.Header.Get("Access-Control-Request-Method"); acrm != "" { // We are handling a preflight request rw.Header().Set("Access-Control-Allow-Methods", "GET") } return h(ctx, rw, req) } return h(ctx, rw, req) } }