hunk.code_window: 	_, err := w.w.Write(args)
   	return err
   }
   func (w *httpResponseWriterRPCServer) WriteHeader(args int, reply *struct{}) error {
   	w.w.WriteHeader(args)
   	return nil
   }
  
hunk.labels: keep keep keep keep add keep keep keep keep
hunk.after_edit: 	// Check if args is a valid http status code. This prevents plugins from crashing the server with a panic.
   	// This is a copy of the checkWriteHeaderCode function in net/http/server.go in the go source.
   	if args < 100 || args > 999 {
   		w.log.Error(fmt.Sprintf("Plugin tried to write an invalid http status code: %v. Did not write the invalid header.", args))
   		return errors.New("invalid http status code")
   	}
  
hunk.file_path: plugin/http.go
hunk.type: add
file: package hclog
  
  import (
  	"io"
  	"log"
  	"os"
  	"strings"
  	"sync"
  )
  
  var (
  	//DefaultOutput is used as the default log output.
  	DefaultOutput io.Writer = os.Stderr
  
  	// DefaultLevel is used as the default log level.
  	DefaultLevel = Info
  )
  
  // Level represents a log level.
  type Level int32
  
  const (
  	// NoLevel is a special level used to indicate that no level has been
  	// set and allow for a default to be used.
  	NoLevel Level = 0
  
  	// Trace is the most verbose level. Intended to be used for the tracing
  	// of actions in code, such as function enters/exits, etc.
  	Trace Level = 1
  
  	// Debug information for programmer lowlevel analysis.
  	Debug Level = 2
  
  	// Info information about steady state operations.
  	Info Level = 3
  
  	// Warn information about rare but handled events.
  	Warn Level = 4
  
  	// Error information about unrecoverable events.
  	Error Level = 5
  )
  
  // Format is a simple convience type for when formatting is required. When
  // processing a value of this type, the logger automatically treats the first
  // argument as a Printf formatting string and passes the rest as the values
  // to be formatted. For example: L.Info(Fmt{"%d beans/day", beans}).
  type Format []interface{}
  
  // Fmt returns a Format type. This is a convience function for creating a Format
  // type.
  func Fmt(str string, args ...interface{}) Format {
  	return append(Format{str}, args...)
  }
  
  // LevelFromString returns a Level type for the named log level, or "NoLevel" if
  // the level string is invalid. This facilitates setting the log level via
  // config or environment variable by name in a predictable way.
  func LevelFromString(levelStr string) Level {
  	// We don't care about case. Accept both "INFO" and "info".
  	levelStr = strings.ToLower(strings.TrimSpace(levelStr))
  	switch levelStr {
  	case "trace":
  		return Trace
  	case "debug":
  		return Debug
  	case "info":
  		return Info
  	case "warn":
  		return Warn
  	case "error":
  		return Error
  	default:
  		return NoLevel
  	}
  }
  
  // Logger describes the interface that must be implemeted by all loggers.
  type Logger interface {
  	// Args are alternating key, val pairs
  	// keys must be strings
  	// vals can be any type, but display is implementation specific
  	// Emit a message and key/value pairs at the TRACE level
  	Trace(msg string, args ...interface{})
  
  	// Emit a message and key/value pairs at the DEBUG level
  	Debug(msg string, args ...interface{})
  
  	// Emit a message and key/value pairs at the INFO level
  	Info(msg string, args ...interface{})
  
  	// Emit a message and key/value pairs at the WARN level
  	Warn(msg string, args ...interface{})
  
  	// Emit a message and key/value pairs at the ERROR level
  	Error(msg string, args ...interface{})
  
  	// Indicate if TRACE logs would be emitted. This and the other Is* guards
  	// are used to elide expensive logging code based on the current level.
  	IsTrace() bool
  
  	// Indicate if DEBUG logs would be emitted. This and the other Is* guards
  	IsDebug() bool
  
  	// Indicate if INFO logs would be emitted. This and the other Is* guards
  	IsInfo() bool
  
  	// Indicate if WARN logs would be emitted. This and the other Is* guards
  	IsWarn() bool
  
  	// Indicate if ERROR logs would be emitted. This and the other Is* guards
  	IsError() bool
  
  	// Creates a sublogger that will always have the given key/value pairs
  	With(args ...interface{}) Logger
  
  	// Create a logger that will prepend the name string on the front of all messages.
  	// If the logger already has a name, the new value will be appended to the current
  	// name. That way, a major subsystem can use this to decorate all it's own logs
  	// without losing context.
  	Named(name string) Logger
  
  	// Create a logger that will prepend the name string on the front of all messages.
  	// This sets the name of the logger to the value directly, unlike Named which honor
  	// the current name as well.
  	ResetNamed(name string) Logger
  
  	// Updates the level. This should affect all sub-loggers as well. If an
  	// implementation cannot update the level on the fly, it should no-op.
  	SetLevel(level Level)
  
  	// Return a value that conforms to the stdlib log.Logger interface
  	StandardLogger(opts *StandardLoggerOptions) *log.Logger
  
  	// Return a value that conforms to io.Writer, which can be passed into log.SetOutput()
  	StandardWriter(opts *StandardLoggerOptions) io.Writer
  }
  
  // StandardLoggerOptions can be used to configure a new standard logger.
  type StandardLoggerOptions struct {
  	// Indicate that some minimal parsing should be done on strings to try
  	// and detect their level and re-emit them.
  	// This supports the strings like [ERROR], [ERR] [TRACE], [WARN], [INFO],
  	// [DEBUG] and strip it off before reapplying it.
  	InferLevels bool
  
  	// ForceLevel is used to force all output from the standard logger to be at
  	// the specified level. Similar to InferLevels, this will strip any level
  	// prefix contained in the logged string before applying the forced level.
  	// If set, this override InferLevels.
  	ForceLevel Level
  }
  
  // LoggerOptions can be used to configure a new logger.
  type LoggerOptions struct {
  	// Name of the subsystem to prefix logs with
  	Name string
  
  	// The threshold for the logger. Anything less severe is supressed
  	Level Level
  
  	// Where to write the logs to. Defaults to os.Stderr if nil
  	Output io.Writer
  
  	// An optional mutex pointer in case Output is shared
  	Mutex *sync.Mutex
  
  	// Control if the output should be in JSON.
  	JSONFormat bool
  
  	// Include file and line information in each log line
  	IncludeLocation bool
  
  	// The time format to use instead of the default
  	TimeFormat string
  }
  