unit XData.Web.Headers;

interface

uses
  Types, SysUtils, Bcl.Collections.Common;

type
  THttpHeaderInfo = class
  private
    FName: string;
    FValue: string;
  public
    constructor Create(const AName, AValue: string); reintroduce;
    property Name: string read FName;
    property Value: string read FValue;
  end;

  THttpHeaders = class
  strict private
    FHeaders: TStringMap;
  private
    function GetHeaderNames: TStringDynArray;
  public
    constructor Create; reintroduce;
    destructor Destroy; override;
    procedure SetValue(const HeaderName, HeaderValue: string);
    procedure AddValue(const HeaderName, HeaderValue: string);
    function Get(const HeaderName: string): string;
    function Exists(const HeaderName: string): boolean;
    function GetIfExists(const HeaderName: string; var HeaderValue: string): Boolean;
    procedure Remove(const HeaderName: string);
    procedure Clear;
    property HeaderNames: TStringDynArray read GetHeaderNames;
  end;

implementation

{ THttpHeaderInfo }

constructor THttpHeaderInfo.Create(const AName, AValue: string);
begin
  FName := AName;
  FValue := AValue;
end;

{ THttpHeaders }

procedure THttpHeaders.AddValue(const HeaderName, HeaderValue: string);
begin
  if Exists(HeaderName) then
    SetValue(HeaderName, Get(HeaderName) + ',' + HeaderValue)
  else
    SetValue(HeaderName, HeaderValue);
end;

procedure THttpHeaders.Clear;
begin
  FHeaders.Clear;
end;

constructor THttpHeaders.Create;
begin
  FHeaders := TStringMap.Create(True);
end;

destructor THttpHeaders.Destroy;
begin
  FHeaders.Free;
  inherited;
end;

function THttpHeaders.Exists(const HeaderName: string): boolean;
begin
  Result := FHeaders.ContainsKey(LowerCase(HeaderName));
end;

function THttpHeaders.Get(const HeaderName: string): string;
begin
  if FHeaders.ContainsKey(Lowercase(HeaderName)) then
    Result := THttpHeaderInfo(FHeaders[Lowercase(HeaderName)]).Value
  else
    Result := '';
end;

function THttpHeaders.GetHeaderNames: TStringDynArray;
begin
  Result := FHeaders.Keys;
end;

function THttpHeaders.GetIfExists(const HeaderName: string;
  var HeaderValue: string): Boolean;
begin
  Result := Exists(HeaderName);
  if Result then
    HeaderValue := Get(HeaderName);
end;

procedure THttpHeaders.Remove(const HeaderName: string);
begin
  if FHeaders.ContainsKey(LowerCase(HeaderName)) then
    FHeaders.Remove(LowerCase(HeaderName));
end;

procedure THttpHeaders.SetValue(const HeaderName, HeaderValue: string);
begin
  if HeaderName <> '' then
    FHeaders.AddOrSetValue(Lowercase(HeaderName),
      THttpHeaderInfo.Create(Lowercase(HeaderName), Trim(HeaderValue)));
end;

end.