Browse Source

- Switch to block-based processing of http-content

git-svn-id: trunk@49359 -
joost 4 years ago
parent
commit
6db4ab5012

+ 6 - 0
.gitattributes

@@ -4875,6 +4875,12 @@ packages/fcl-web/tests/cgigateway.lpi svneol=native#text/plain
 packages/fcl-web/tests/cgigateway.pp svneol=native#text/plain
 packages/fcl-web/tests/fpcunithpack.lpi svneol=native#text/plain
 packages/fcl-web/tests/fpcunithpack.lpr svneol=native#text/plain
+packages/fcl-web/tests/integrationtests/README.md svneol=native#text/markdown
+packages/fcl-web/tests/integrationtests/UploadFile1.txt svneol=native#text/plain
+packages/fcl-web/tests/integrationtests/UploadFile2.txt svneol=native#text/plain
+packages/fcl-web/tests/integrationtests/UploadFile3.txt svneol=native#text/plain
+packages/fcl-web/tests/integrationtests/fcgi_dump_request.pp svneol=native#text/pascal
+packages/fcl-web/tests/integrationtests/fcl-web_integrationtests.jmx svneol=native#text/xml
 packages/fcl-web/tests/tchttproute.pp svneol=native#text/plain
 packages/fcl-web/tests/testcgiapp.lpi svneol=native#text/plain
 packages/fcl-web/tests/testcgiapp.pp svneol=native#text/plain

+ 30 - 6
packages/fcl-web/src/base/custfcgi.pp

@@ -62,6 +62,10 @@ Type
     FUR: TUnknownRecordEvent;
     FLog : TLogEvent;
     FSTDin : String;
+    FSTDinRead: Integer;
+
+    FRequestHeadersInitialized: Boolean;
+    FStreamingContentReceived: Boolean;
   Protected
     function DoGetCGIVar(AVarName: String): String; override;
     procedure GetNameValuePairsFromContentRecord(const ARecord : PFCGI_ContentRecord; NameValueList : TStrings); virtual;
@@ -247,6 +251,7 @@ end;
 
 function TFCGIRequest.ProcessFCGIRecord(AFCGIRecord: PFCGI_Header): boolean;
 var cl,rcl : Integer;
+  State: TContentStreamingState;
 begin
   Result := False;
   case AFCGIRecord^.reqtype of
@@ -257,6 +262,7 @@ begin
 //           log(etDebug,Format('Begin request body role & flags: %d %d',[Beton(Role),Flags]));
          end;
     FCGI_PARAMS :       begin
+                        FRequestHeadersInitialized := False;
                         if AFCGIRecord^.contentLength=0 then
                           Result := False
                         else
@@ -267,14 +273,34 @@ begin
                           end;
                         end;
     FCGI_STDIN :        begin
+                        if not FRequestHeadersInitialized then
+                          begin
+                          InitHeaderRequestVars;
+                          FRequestHeadersInitialized := True;
+                          end;
                         Result:=AFCGIRecord^.contentLength=0;
                         if not Result then
                           begin
-                          cl := length(FSTDin);
                           rcl := BetoN(PFCGI_ContentRecord(AFCGIRecord)^.header.contentLength);
-                          SetLength(FSTDin, rcl+cl);
-                          move(PFCGI_ContentRecord(AFCGIRecord)^.ContentData[0],FSTDin[cl+1],rcl);
-                          InitContent(FSTDin);
+                          if FStreamingContentReceived then
+                            State := cssData
+                          else
+                            State := cssStart;
+                          FStreamingContentReceived := True;
+
+                          ProcessStreamingContent(State, PFCGI_ContentRecord(AFCGIRecord)^.ContentData[0], rcl);
+                          end
+                        else
+                          begin
+                          if not FStreamingContentReceived then
+                            begin
+                            ProcessStreamingContent(cssStart, PFCGI_ContentRecord(AFCGIRecord)^.ContentData[0], 0);
+                            ProcessStreamingContent(cssEnd, PFCGI_ContentRecord(AFCGIRecord)^.ContentData[0], 0);
+                            end
+                          else
+                            begin
+                            ProcessStreamingContent(cssEnd, PFCGI_ContentRecord(AFCGIRecord)^.ContentData[0], 0);
+                            end;
                           end;
                         end;
   else
@@ -284,8 +310,6 @@ begin
       if poFailonUnknownRecord in FPO then
         TFCgiHandler.DoError('Unknown FASTCGI record type: %s',[AFCGIRecord^.reqtype]);
   end;
-  if Result then
-    InitRequestVars;
 end;
 
 function TFCGIRequest.DoGetCGIVar(AVarName: String): String;

+ 512 - 15
packages/fcl-web/src/base/httpdefs.pp

@@ -143,6 +143,8 @@ Const
                        22,23,24,
                        34,0,36,26) deprecated;
 
+type
+  TContentStreamingState = (cssStart, cssData, cssEnd);
 
 
 type
@@ -249,7 +251,10 @@ type
   TMimeItem = Class(TCollectionItem)
   private
   protected
+    FLocalFilename: string;
+
     Function CreateUploadedFile(Files : TUploadedFiles) : TUploadedFile; virtual;
+    function CreateFile(Files: TUploadedFiles): TUploadedFile; virtual;
     Function ProcessHeader(Const AHeader,AValue : String) : Boolean; virtual;
     procedure SaveToFile(const AFileName: String); virtual;
     function GetIsFile: Boolean; virtual;
@@ -258,6 +263,7 @@ type
     function GetHeader(AIndex: Integer): String; virtual; abstract;
     Procedure SetHeader(AIndex: Integer; Const AValue: String); virtual; abstract;
   Public
+    Procedure ProcessStreaming(const State: TContentStreamingState; const Buf; const Size: Integer); virtual; abstract;
     Procedure Process(Stream : TStream); virtual; abstract;
     Property Data : String index 0 Read GetHeader Write SetHeader;
     Property Name : String index 1 Read GetHeader Write SetHeader;
@@ -273,17 +279,41 @@ type
 
   TMimeItems = Class(TCollection)
   private
+    FBoundary: string;
+    FFiles: TUploadedFiles;
+    FPreamble: string;
     function GetP(AIndex : Integer): TMimeItem;
   Protected
     Procedure CreateUploadFiles(Files : TUploadedFiles; Vars : TStrings); virtual;
     procedure FormSplit(var Cnt: String; boundary: String); virtual;
+    procedure ProcessStreamingMultiPart(const State: TContentStreamingState; const Buf; const Size: Integer); virtual; abstract;
+    class function SupportsStreamingProcessing: Boolean; virtual;
+    procedure SetBoundary(AValue: string); virtual;
   Public
     Function First : TMimeItem;
     Function Last : TMimeItem;
     Property Parts[AIndex : Integer] : TMimeItem Read GetP; default;
+    property Preamble: string read FPreamble;
+    Property Boundary: string read FBoundary write SetBoundary;
+    Property Files: TUploadedFiles read FFiles write FFiles;
   end;
   TMimeItemsClass = Class of TMimeItems;
 
+  { TStreamingMimeItems }
+
+  TStreamingMimeItems = class(TMimeItems)
+  private
+    FBuffer: string;
+    FBufferCount: SizeInt;
+    FCurrentItem: TMimeItem;
+    FMimeEndFound: Boolean;
+    FAtStart: Boolean;
+  protected
+    procedure SetBoundary(AValue: string); override;
+    procedure ProcessStreamingMultiPart(const State: TContentStreamingState; const Buf; const Size: Integer); override;
+    class function SupportsStreamingProcessing: Boolean; override;
+  end;
+
   { THTTPHeader }
 
   THTTPHeader = class(TObject)
@@ -403,6 +433,8 @@ type
     Property CustomHeaders: TStringList read GetCustomHeaders;
   end;
 
+  TStreamingContentType = (sctUnknown, sctMultipart, sctFormUrlEncoded);
+  TOnStreamEncodingEvent = Procedure (Sender : TRequest; const State: TContentStreamingState; const Buf; const Size: Integer) of object;
   TOnUnknownEncodingEvent = Procedure (Sender : TRequest; Const ContentType : String;Stream : TStream) of object;
   { TRequest }
 
@@ -417,6 +449,13 @@ type
     FLocalPathPrefix : string;
     FContentRead : Boolean;
     FRouteParams : TStrings;
+
+    FStreamingContentType: TStreamingContentType;
+    FMimeItems: TMimeItems;
+    FKeepFullContents: Boolean;
+    FStreamingContent: string;
+    FStreamingContentRead: Integer;
+    FOnStreamEncodingEvent: TOnStreamEncodingEvent;
     function GetLocalPathPrefix: string;
     function GetFirstHeaderLine: String;
     function GetRP(AParam : String): String;
@@ -426,6 +465,7 @@ type
     Function CreateUploadedFiles : TUploadedFiles; virtual;
     Function CreateMimeItems : TMimeItems; virtual;
     procedure HandleUnknownEncoding(Const AContentType : String;Stream : TStream); virtual;
+    procedure HandleStreamEncoding(const State: TContentStreamingState; const Buf; const Size: Integer); virtual;
     procedure ParseFirstHeaderLine(const line: String);override;
     procedure ReadContent; virtual;
     Procedure ProcessMultiPart(Stream : TStream; Const Boundary : String;SL:TStrings); virtual;
@@ -435,10 +475,22 @@ type
     Function GetTempUploadFileName(Const AName, AFileName : String; ASize : Int64) : String; virtual;
     // This will free any TUPloadedFile.Streams that may exist, as they may lock the files and thus prevent them
     Procedure DeleteTempUploadedFiles; virtual;
+
     Procedure InitRequestVars; virtual;
+    procedure InitContentRequestVars; virtual;
+    procedure InitHeaderRequestVars; virtual;
+
     Procedure InitPostVars; virtual;
     Procedure InitGetVars; virtual;
-    Procedure InitContent(Var AContent : String);
+    Procedure InitContent(const AContent : String);
+
+    procedure ProcessStreamingContent(const State: TContentStreamingState; const Buf; const Size: Integer); virtual;
+    function DerriveStreamingContentType(): TStreamingContentType;
+    procedure ProcessStreamingURLEncoded(const State: TContentStreamingState; const Buf; const Size: Integer); virtual;
+    procedure ProcessStreamingMultiPart(const State: TContentStreamingState; const Buf; const Size: Integer); virtual;
+    // ProcessStreamingSetContent collects all data and stores it into Content
+    procedure ProcessStreamingSetContent(const State: TContentStreamingState; const Buf; const Size: Integer); virtual;
+    procedure HandleStreamingUnknownEncoding(const State: TContentStreamingState; const Buf; const Size: Integer);
     Property ContentRead : Boolean Read FContentRead Write FContentRead;
   public
     Class Var DefaultRequestUploadDir : String;
@@ -456,6 +508,7 @@ type
     Property Files : TUploadedFiles Read FFiles;
     Property HandleGetOnPost : Boolean Read FHandleGetOnPost Write FHandleGetOnPost;
     Property OnUnknownEncoding : TOnUnknownEncodingEvent Read FOnUnknownEncoding Write FOnUnknownEncoding;
+    Property OnStreamEncodingEvent: TOnStreamEncodingEvent read FOnStreamEncodingEvent write FOnStreamEncodingEvent;
     Property IfMatch : String Index ord(hhIfMatch) Read GetHeaderValue Write SetHeaderValue;
     Property IfNoneMatch : String  Index ord(hhIfNoneMatch) Read GetHeaderValue Write SetHeaderValue;
     Property IfRange : String  Index ord(hhIfRange) Read GetHeaderValue Write SetHeaderValue;
@@ -463,6 +516,7 @@ type
     Property ContentRange : String Index ord(hhContentRange) Read GetHeaderValue Write SetHeaderValue;
     Property TE : String Index ord(hhTE) Read GetHeaderValue Write SetHeaderValue;
     Property Upgrade : String Index ord(hhUpgrade) Read GetHeaderValue Write SetHeaderValue;
+    property KeepFullContents: Boolean read FKeepFullContents write FKeepFullContents;
   end;
 
 
@@ -647,7 +701,7 @@ Var
   // Default classes used when instantiating the collections.
   UploadedFilesClass : TUploadedFilesClass = TUploadedFiles;
   UploadedFileClass : TUploadedFileClass = TUploadedFile;
-  MimeItemsClass : TMimeItemsClass = TMimeItems;
+  MimeItemsClass : TMimeItemsClass = TStreamingMimeItems;
   MimeItemClass : TMimeItemClass = nil;
 
 Const
@@ -726,15 +780,141 @@ Type
   THTTPMimeItem = Class(TMimeItem)
   private
     FData : Array[0..5] of string;
+    FHeadersProcessed: Boolean;
+    FBuffer: string;
+    FStream: TStream;
+    FDataSize: Int64;
   protected
     Procedure SetHeader(AIndex: Integer; Const AValue: String); override;
     function GetDataSize: Int64; override;
     function GetHeader(AIndex: Integer): String; override;
     function GetIsFile: Boolean; override;
   public
+    destructor Destroy; override;
     Procedure Process(Stream : TStream); override;
+    Procedure ProcessStreaming(const State: TContentStreamingState; const Buf; const Size: Integer); override;
+  end;
+
+  { THTTPStreamingMimeItem }
+  THTTPStreamingMimeItem = Class(THTTPMimeItem)
+  protected
+    function GetDataSize: Int64; override;
   end;
 
+function THTTPStreamingMimeItem.GetDataSize: Int64;
+begin
+  if GetIsFile then
+    Result:=FDataSize
+  else
+    Result:=Length(Data);
+end;
+
+
+{ TStreamingMimeItems }
+
+procedure TStreamingMimeItems.ProcessStreamingMultiPart(const State: TContentStreamingState; const Buf; const Size: Integer);
+var
+  bl: SizeInt;
+  p: SizeInt;
+  BufEnd: SizeInt;
+  LeadingLineEndMissing: Boolean;
+begin
+  // The length of the boundary, including the leading CR/LF, '--' and trailing '--' or
+  // CR/LF.
+  bl := Length(FBoundary)+6;
+  LeadingLineEndMissing:=False;
+  if State=cssStart then
+    begin
+    FMimeEndFound := False;
+    FAtStart := True;
+    end;
+
+  // Allocate enough memory to hold the buffer-size, and the lenght of the
+  // boundary (bl). To be able to find a boundary-string at which is divided between
+  // two calls to this function, the last bl-amount of characters at the end of
+  // the buffer, are stored to be handled in the next call to this function.
+  SetLength(FBuffer, Size+bl);
+  if Size > 0 then
+    System.Move(Buf, FBuffer[FBufferCount+1], Size);
+
+  BufEnd := FBufferCount+1+Size;
+
+  FBufferCount := 1;
+  repeat
+  if FAtStart and CompareMem(@FBuffer[1], PChar('--'+FBoundary), Length(FBoundary)+2) then
+    begin
+    // Sometimes a mime-message (mistakenly) does not start with CR/LF.
+    p := 1;
+    LeadingLineEndMissing := True;
+    end
+  else
+    p := Pos(#13#10'--'+FBoundary, FBuffer, FBufferCount);
+  if (P > 0) and (P < Size) then
+    begin
+    if Assigned(FCurrentItem) then
+      begin
+      FCurrentItem.ProcessStreaming(cssEnd, FBuffer[FBufferCount], P-FBufferCount);
+      FCurrentItem := Nil;
+      end
+    else
+      begin
+      if FAtStart and (P > 1) then
+        // Add the preamble to the content
+        FPreamble := Copy(FBuffer, FBufferCount, P-1);
+      end;
+    FAtStart := False;
+    Inc(P, bl);
+    if LeadingLineEndMissing then
+      begin
+      Dec(P, 2);
+      LeadingLineEndMissing := False;
+      end;
+    FBufferCount := P;
+    if (Copy(FBuffer,p-2,2)='--') then
+      FMimeEndFound := True;
+    end;
+  if not Assigned(FCurrentItem) and not FMimeEndFound then
+    begin
+    FCurrentItem := Add as TMimeItem;
+    FCurrentItem.ProcessStreaming(cssStart, FBuffer[p], 0)
+    end
+  until (P < 1) or FMimeEndFound;
+
+  if Assigned(FCurrentItem) then
+    begin
+    if state<>cssEnd then
+      begin
+      // Call FCurrentItem.ProcessStreaming with the current buffer, excluding
+      // the last bl bytes. Keep those at the start of FBuffer, to be handled
+      // in the next call to this function.
+      FCurrentItem.ProcessStreaming(cssData, FBuffer[FBufferCount], BufEnd-FBufferCount-bl);
+      System.Move(FBuffer[BufEnd-bl], FBuffer[1], bl);
+      FBufferCount := bl;
+      end
+    else
+      begin
+      // This function won't be called again. Call FCurrentItem.ProcessStreaming
+      // with the complete remaining buffer.
+      FCurrentItem.ProcessStreaming(cssEnd, FBuffer[FBufferCount], BufEnd-FBufferCount+bl);
+      FBufferCount := 0;
+      end;
+    end
+  else
+    FBufferCount := 0;
+end;
+
+class function TStreamingMimeItems.SupportsStreamingProcessing: Boolean;
+begin
+  Result := True;
+end;
+
+procedure TStreamingMimeItems.SetBoundary(AValue: string);
+begin
+  if Length(FBuffer) > 0 then
+    Raise Exception.Create('It is not possible to adapt the binary when the evaluation of streaming data has already been started.');
+  inherited SetBoundary(AValue);
+end;
+
 { TCORSSupport }
 
 procedure TCORSSupport.SetAllowedMethods(AValue: String);
@@ -944,6 +1124,140 @@ begin
   {$ifdef CGIDEBUG}SendMethodExit('THTTPMimeItem.Process');{$ENDIF}
 end;
 
+procedure THTTPMimeItem.ProcessStreaming(const State: TContentStreamingState; const Buf; const Size: Integer);
+
+  Function GetLine(Var S : String) : String;
+
+  Var
+    P : Integer;
+
+  begin
+    P:=Pos(#13#10,S);
+    If (P<>0) then
+      begin
+      Result:=Copy(S,1,P-1);
+      Delete(S,1,P+1);
+      end;
+  end;
+
+  Function GetWord(Var S : String) : String;
+
+  Var
+    I,len : Integer;
+    Quoted : Boolean;
+    C : Char;
+
+  begin
+    len:=length(S);
+    quoted:=false;
+    Result:='';
+    for i:=1 to len do
+      Begin
+      c:=S[i];
+      if (c='"') then
+        Quoted:=Not Quoted
+      else
+        begin
+        if not (c in [' ','=',';',':']) or Quoted then
+          Result:=Result+C;
+        if (c in [';',':','=']) and (not quoted) then
+          begin
+          Delete(S,1,I);
+          Exit;
+          end;
+        end;
+      end;
+     S:='';
+  end;
+
+  procedure AddData(const Buf; Size: SizeInt);
+  var
+    S: string;
+    i: SizeInt;
+    Files: TUploadedFiles;
+  begin
+    if Size > 0 then
+      begin
+      if GetIsFile then
+        begin
+        // Stream directly to file
+        if not Assigned(FStream) then
+          begin
+          Files := (Collection as TMimeItems).Files;
+          if Assigned(Files) then
+            FLocalFilename := Files.GetTempUploadFileName(Name, FileName, -1)
+          else
+            FLocalFilename := GetTempFileName('', '');
+          FStream := TFileStream.Create(FLocalFilename, fmCreate);
+          FDataSize := 0;
+          end;
+
+        FStream.Write(Buf, Size);
+        Inc(FDataSize, Size);
+        end
+      else
+        begin
+        S := Data;
+        i := Length(S);
+        SetLength(S, i+Size);
+        Move(Buf, S[i+1], Size);
+        Data := S;
+        end;
+      end;
+  end;
+
+var
+  i: SizeInt;
+  Line, S: string;
+begin
+  if not FHeadersProcessed then
+    begin
+    if Size>0 then
+      begin
+      i := Length(FBuffer);
+      SetLength(FBuffer, i + Size);
+      Move(Buf, FBuffer[i+1], Size);
+      if Copy(FBuffer, 1, 2) = #13#10 then
+        i := 3
+      else
+        i := Pos(#13#10#13#10, FBuffer)+4;
+      if i <> 4 then
+        begin
+        // The full headers are in the buffer now.
+        Line:=GetLine(FBuffer);
+        While (Line<>'') do
+          begin
+          {$ifdef CGIDEBUG}SendDebug('Process data line: '+line);{$ENDIF}
+          S:=GetWord(Line);
+          While (S<>'') do
+            begin
+            ProcessHeader(lowercase(S),GetWord(Line));
+            S:=GetWord(Line);
+            end;
+          Line:=GetLine(FBuffer);
+          end;
+        FHeadersProcessed := True;
+
+        AddData(FBuffer[1], Length(FBuffer));
+        end;
+      end;
+    end
+  else
+    AddData(Buf, Size);
+
+  if State=cssEnd then
+    begin
+    if GetIsFile then
+      FreeAndNil(FStream);
+    end;
+end;
+
+destructor THTTPMimeItem.Destroy;
+begin
+  FStream.Free;
+  inherited Destroy;
+end;
+
 { ---------------------------------------------------------------------
   THTTPHeader
   ---------------------------------------------------------------------}
@@ -1432,7 +1746,10 @@ begin
     else
       begin
       Value:=P.FileName;
-      P.CreateUploadedFile(Files);
+      if SupportsStreamingProcessing then
+        P.CreateFile(Files)
+      else
+        P.CreateUploadedFile(Files);
       end;
     Vars.Add(Name+'='+Value)
     end;
@@ -1481,7 +1798,6 @@ Var
   D,LFN : String;
 
 begin
-  Result:=Nil;
   D:=Data;
   J:=DataSize;
   if (J=0){zero lenght file} or
@@ -1491,8 +1807,15 @@ begin
     begin
     LFN:=Files.GetTempUploadFileName(Name,FileName,J);
     SaveToFile(LFN);
+    FLocalFilename := LFN;
     end;
-  if (LFN<>'') then
+  Result := CreateFile(Files);
+end;
+
+function TMimeItem.CreateFile(Files: TUploadedFiles): TUploadedFile;
+begin
+  Result:=Nil;
+  if (FLocalFileName<>'') then
    begin
    Result:=Files.Add as TUploadedFile;
    with Result do
@@ -1502,7 +1825,7 @@ begin
      ContentType:=Self.ContentType;
      Disposition:=Self.Disposition;
      Size:=Self.Datasize;
-     LocalFileName:=LFN;
+     LocalFileName:=self.FLocalFileName;
      Description:=Self.Description;
      end;
    end;
@@ -1527,6 +1850,8 @@ var
 
 begin
   {$ifdef CGIDEBUG}SendMethodEnter('TMimeItems.FormSplit');{$ENDIF}
+  FBoundary := boundary;
+
   Sep:='--'+boundary+#13+#10;
   Slen:=length(Sep);
   CLen:=Pos('--'+Boundary+'--',Cnt);
@@ -1569,6 +1894,16 @@ begin
     Result := Parts[Count - 1];
 end;
 
+class function TMimeItems.SupportsStreamingProcessing: Boolean;
+begin
+  Result := False;
+end;
+
+procedure TMimeItems.SetBoundary(AValue: string);
+begin
+  FBoundary := AValue;
+end;
+
 { -------------------------------------------------------------------
   TRequest
   -------------------------------------------------------------------}
@@ -1612,12 +1947,14 @@ begin
   if (CI=Nil) then
     CI:=TMimeItem;
   Result:=CC.Create(CI);
+  Result.Files := Files;
 end;
 
 destructor TRequest.destroy;
 begin
   FreeAndNil(FRouteParams);
   FreeAndNil(FFiles);
+  FreeAndNil(FMimeItems);
   inherited destroy;
 end;
 
@@ -1864,29 +2201,52 @@ begin
   FFiles.DeleteTempUploadedFiles;
 end;
 
-procedure TRequest.InitRequestVars;
+procedure TRequest.InitHeaderRequestVars;
 
 var
   R : String;
 
 begin
 {$ifdef CGIDEBUG}
-  SendMethodEnter('TRequest.InitRequestVars');
+  SendMethodEnter('TRequest.InitHeaderRequestVars');
 {$endif}
   R:=Method;
   if (R='') then
     Raise EHTTP.CreateHelp(SErrNoRequestMethod,400);
   // Always process QUERYSTRING.
   InitGetVars;
+{$ifdef CGIDEBUG}
+  SendMethodExit('TRequest.InitHeaderRequestVars');
+{$endif}
+end;
+
+procedure TRequest.InitContentRequestVars;
+
+var
+  R : String;
+
+begin
+{$ifdef CGIDEBUG}
+  SendMethodEnter('TRequest.InitContentRequestVars');
+{$endif}
+  R:=Method;
   // POST and PUT, force post var treatment.
   // To catch other methods we do not treat specially, we'll do the same if contentlength>0
   if (CompareText(R,'POST')=0) or (CompareText(R,'PUT')=0) or (ContentLength>0) then
     InitPostVars;
 {$ifdef CGIDEBUG}
-  SendMethodExit('TRequest.InitRequestVars');
+  SendMethodExit('TRequest.InitContentRequestVars');
 {$endif}
 end;
 
+
+procedure TRequest.InitRequestVars;
+
+begin
+  InitHeaderRequestVars;
+  InitContentRequestVars;
+end;
+
 Type
   TCapacityStream = Class(TMemoryStream)
   Public
@@ -1913,12 +2273,13 @@ begin
       M.WriteBuffer(Content[1], Cl);
       M.Position:=0;
       CT:=ContentType;
-      if Pos('MULTIPART/FORM-DATA',Uppercase(CT))<>0 then
-        ProcessMultiPart(M,CT, ContentFields)
-      else if Pos('APPLICATION/X-WWW-FORM-URLENCODED',Uppercase(CT))<>0 then
-        ProcessUrlEncoded(M, ContentFields)
+      FStreamingContentType := DerriveStreamingContentType;
+      case FStreamingContentType of
+        sctMultipart:       ProcessMultiPart(M, CT, ContentFields);
+        sctFormUrlEncoded:  ProcessUrlEncoded(M, ContentFields);
       else
         HandleUnknownEncoding(CT,M)
+      end;
     finally
       M.Free;
     end;
@@ -1944,7 +2305,7 @@ begin
 {$endif}
 end;
 
-procedure TRequest.InitContent(var AContent: String);
+procedure TRequest.InitContent(const AContent: String);
 begin
   FVariables[hvContent]:=AContent;
   FContentRead:=True;
@@ -2007,6 +2368,142 @@ begin
 {$ifdef CGIDEBUG} SendMethodEnter('ProcessURLEncoded');{$endif CGIDEBUG}
 end;
 
+procedure TRequest.ProcessStreamingContent(const State: TContentStreamingState; const Buf; const Size: Integer);
+begin
+  if state = cssStart then
+    FStreamingContentType := DerriveStreamingContentType;
+  case FStreamingContentType of
+    sctMultipart:       ProcessStreamingMultiPart(State, Buf, Size);
+    sctFormUrlEncoded:  ProcessStreamingUrlEncoded(State, Buf, Size);
+  else
+    HandleStreamingUnknownEncoding(State, Buf, Size)
+  end;
+  HandleStreamEncoding(State, Buf, Size);
+end;
+
+function TRequest.DerriveStreamingContentType(): TStreamingContentType;
+var
+  CT: string;
+begin
+  CT:=ContentType;
+  if Pos('MULTIPART/FORM-DATA',Uppercase(CT))<>0 then
+    Result := sctMultipart
+  else if Pos('APPLICATION/X-WWW-FORM-URLENCODED',Uppercase(CT))<>0 then
+    Result := sctFormUrlEncoded
+  else
+    Result := sctUnknown
+end;
+
+procedure TRequest.ProcessStreamingMultiPart(const State: TContentStreamingState; const Buf; const Size: Integer);
+Var
+  ST: TStrings;
+  S, CT, B: String;
+  I: Integer;
+begin
+{$ifdef CGIDEBUG} SendMethodEnter('ProcessStreamingMultiPart');{$endif CGIDEBUG}
+  if State=cssStart then
+    begin
+    CT := ContentType;
+    i:=Pos('=',CT);
+    B:=Copy(CT,I+1,Length(CT)-I);
+    I:=Length(B);
+    If (I>0) and (B[1]='"') then
+      B:=Copy(B,2,I-2);
+    FMimeItems := CreateMimeItems;
+    FMimeItems.Boundary := B;
+    end;
+
+  if FKeepFullContents or not FMimeItems.SupportsStreamingProcessing then
+    ProcessStreamingSetContent(State, Buf, Size);
+
+  if FMimeItems.SupportsStreamingProcessing then
+    FMimeItems.ProcessStreamingMultiPart(State, Buf, Size);
+
+  if State=cssEnd then
+    begin
+    FMimeItems.CreateUploadFiles(Files, ContentFields);
+    if not FMimeItems.SupportsStreamingProcessing then
+      begin
+      S := Content;
+      FMimeItems.FormSplit(S, FMimeItems.Boundary);
+      FMimeItems.CreateUploadFiles(Files, ContentFields);
+      end
+    else if not FKeepFullContents then
+      Content := FMimeItems.Preamble;
+    FreeAndNil(FMimeItems);
+    FContentRead := True;
+    end;
+end;
+
+procedure TRequest.ProcessStreamingURLEncoded(const State: TContentStreamingState; const Buf; const Size: Integer);
+begin
+  // This implementation simply collects the contents, and then parses this
+  // content.
+  // ToDo: replace this with some code that really parses the content
+  // block-by-block.
+  ProcessStreamingSetContent(State, Buf, Size);
+  if state=cssEnd then
+    begin
+    ProcessQueryString(Content, ContentFields);
+    if not KeepFullContents then
+      Content := '';
+    end;
+end;
+
+procedure TRequest.HandleStreamingUnknownEncoding(const State: TContentStreamingState; const Buf; const Size: Integer);
+var
+  S: TStream;
+begin
+  if Assigned(FOnUnknownEncoding) then
+    begin
+    ProcessStreamingSetContent(State, Buf, Size);
+
+    if state=cssEnd then
+      begin
+      try
+        S := TStringStream.Create(Content);
+        FOnUnknownEncoding(Self,ContentType,nil);
+      finally
+        S.Free;
+      end;
+      end;
+    end;
+end;
+
+procedure TRequest.ProcessStreamingSetContent(const State: TContentStreamingState; const Buf; const Size: Integer);
+var
+  CL: LongInt;
+begin
+  {$ifdef CGIDEBUG} SendMethodEnter('ProcessStreamingSetContent');{$endif CGIDEBUG}
+  if State=cssStart then
+    begin
+    // First time this code is called. Search for a content-length
+    // header and use it as hint for the content-length.
+    if HeaderIsSet(hhContentLength) and TryStrToInt(GetHeader(hhContentLength), CL) and (CL>0) then
+      SetLength(FStreamingContent, CL);
+    end;
+
+  CL := FStreamingContentRead;
+  FStreamingContentRead := CL+Size;
+  if Length(FStreamingContent) < FStreamingContentRead then
+    SetLength(FStreamingContent, FStreamingContentRead);
+  if Size > 0 then
+    Move(Buf, FStreamingContent[CL+1], Size);
+
+  if State=cssEnd then
+    begin
+    SetLength(FStreamingContent, FStreamingContentRead);
+    Content := FStreamingContent;
+    FStreamingContent := '';
+    end;
+end;
+
+procedure TRequest.HandleStreamEncoding(const State: TContentStreamingState; const Buf; const Size: Integer);
+begin
+  if Assigned(FOnStreamEncodingEvent) then
+    FOnStreamEncodingEvent(Self, State, Buf, Size);
+end;
+
 { ---------------------------------------------------------------------
   TUploadedFiles
   ---------------------------------------------------------------------}
@@ -2507,5 +3004,5 @@ begin
 end;
 
 initialization
-  MimeItemClass:=THTTPMimeItem;
+  MimeItemClass:=THTTPStreamingMimeItem;
 end.

+ 21 - 0
packages/fcl-web/tests/integrationtests/README.md

@@ -0,0 +1,21 @@
+# Fcl-web integration tests
+
+This is an attempt to test the data-processing inside fcl-web.
+
+There are two parts: A fpc-application (fcgi_dump_request) that returns the
+received http-data in a Json-format. And an Apache jMeter test-script.
+
+The open-source tool jMeter form Apache is used to send http-requests to the
+fpc-application, and to do several assertions on the results.
+
+To run, you have to create a setup that supports the fcgi_dump_request
+application. For example using a Apache or NGINX setup.
+
+Then check the local-settings within the jMeter test script, and run it.
+
+In principle it is also possible to test plain CGI or the embeddes web-server
+with small changes to fcgi_dump_request.pp.
+
+Note that at the end of the jMeter script a call is made that makes the
+fcgi_dump_request terminate. When compiled with heap-trace information
+this can help locating memory leaks

+ 1 - 0
packages/fcl-web/tests/integrationtests/UploadFile1.txt

@@ -0,0 +1 @@
+Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Magna eget est lorem ipsum dolor. Enim sit amet venenatis urna cursus eget nunc scelerisque viverra. Non blandit massa enim nec. Nunc eget lorem dolor sed. Fringilla est ullamcorper eget nulla facilisi etiam dignissim. Donec ultrices tincidunt arcu non sodales neque sodales. Elementum facilisis leo vel fringilla est. Amet commodo nulla facilisi nullam. Fusce ut placerat orci nulla pellentesque dignissim enim. Convallis a cras semper auctor neque vitae tempus. Justo eget magna fermentum iaculis eu. Dapibus ultrices in iaculis nunc sed augue lacus viverra vitae. Pellentesque diam volutpat commodo sed egestas egestas fringilla phasellus faucibus. Viverra aliquet eget sit amet. Platea dictumst vestibulum rhoncus est pellentesque.

+ 3 - 0
packages/fcl-web/tests/integrationtests/UploadFile2.txt

@@ -0,0 +1,3 @@
+Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Laoreet suspendisse interdum consectetur libero id faucibus. Felis eget nunc lobortis mattis. Id interdum velit laoreet id. Eget mi proin sed libero enim sed faucibus turpis. Sed risus pretium quam vulputate dignissim suspendisse in est. Integer malesuada nunc vel risus commodo viverra maecenas. Sit amet justo donec enim diam vulputate. Laoreet non curabitur gravida arcu ac tortor dignissim convallis aenean. Rhoncus mattis rhoncus urna neque. Aliquet sagittis id consectetur purus ut faucibus.
+
+Sit amet consectetur adipiscing elit duis tristique sollicitudin. Integer quis auctor elit sed vulputate. Dui accumsan sit amet nulla facilisi morbi tempus iaculis. A scelerisque purus semper eget duis at tellus. Purus sit amet volutpat consequat. Non diam phasellus vestibulum lorem sed risus. Adipiscing elit pellentesque habitant morbi tristique. Interdum posuere lorem ipsum dolor sit amet consectetur adipiscing. Nunc aliquet bibendum enim facilisis gravida neque. Fringilla urna porttitor rhoncus dolor purus. Felis donec et odio pellentesque diam volutpat. Mauris in aliquam sem fringilla ut morbi tincidunt. Turpis massa sed elementum tempus. Quisque id diam vel quam elementum pulvinar etiam. Nisl pretium fusce id velit ut. Lacus sed turpis tincidunt id aliquet risus feugiat in ante.

+ 199 - 0
packages/fcl-web/tests/integrationtests/UploadFile3.txt

@@ -0,0 +1,199 @@
+Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Tellus id interdum velit laoreet id donec ultrices. In ornare quam viverra orci sagittis eu volutpat odio facilisis. Ullamcorper morbi tincidunt ornare massa eget egestas purus. Volutpat lacus laoreet non curabitur gravida arcu ac tortor. Mi bibendum neque egestas congue. A condimentum vitae sapien pellentesque. Mattis aliquam faucibus purus in massa tempor nec feugiat. Ullamcorper malesuada proin libero nunc consequat interdum varius. A cras semper auctor neque vitae tempus quam. Magnis dis parturient montes nascetur ridiculus mus. Habitant morbi tristique senectus et netus et malesuada fames. Condimentum id venenatis a condimentum vitae sapien pellentesque habitant morbi.
+
+Dolor sit amet consectetur adipiscing elit ut aliquam purus sit. Nam libero justo laoreet sit amet cursus sit. Nunc eget lorem dolor sed viverra ipsum nunc aliquet bibendum. Nulla aliquet enim tortor at auctor urna. Quis lectus nulla at volutpat diam ut. Neque viverra justo nec ultrices dui sapien eget mi proin. Tortor consequat id porta nibh. Aliquam vestibulum morbi blandit cursus risus at. Tellus cras adipiscing enim eu turpis egestas. Magna fermentum iaculis eu non diam phasellus vestibulum. Aenean vel elit scelerisque mauris pellentesque pulvinar pellentesque. Eget egestas purus viverra accumsan in nisl nisi. Placerat in egestas erat imperdiet. Sed enim ut sem viverra aliquet eget. Diam vulputate ut pharetra sit amet aliquam id diam maecenas.
+
+Tempor commodo ullamcorper a lacus vestibulum sed arcu non. Pellentesque nec nam aliquam sem et tortor consequat. Sed viverra tellus in hac habitasse platea dictumst vestibulum rhoncus. Pretium aenean pharetra magna ac placerat vestibulum lectus mauris ultrices. Nisl nunc mi ipsum faucibus. Aliquam ultrices sagittis orci a scelerisque purus semper eget duis. Turpis massa tincidunt dui ut ornare lectus sit. Mus mauris vitae ultricies leo integer malesuada nunc. Non pulvinar neque laoreet suspendisse interdum consectetur libero id faucibus. Massa sed elementum tempus egestas sed sed risus pretium. Tincidunt tortor aliquam nulla facilisi cras fermentum odio eu feugiat. Sed viverra ipsum nunc aliquet bibendum enim facilisis. Odio pellentesque diam volutpat commodo sed egestas egestas. Eget dolor morbi non arcu. Quam adipiscing vitae proin sagittis nisl rhoncus mattis. Vitae elementum curabitur vitae nunc sed. Dolor magna eget est lorem ipsum dolor sit amet consectetur.
+
+Sit amet risus nullam eget. Mi quis hendrerit dolor magna. Mauris a diam maecenas sed enim. Libero volutpat sed cras ornare arcu dui vivamus arcu felis. Integer vitae justo eget magna. Senectus et netus et malesuada fames ac. Tellus integer feugiat scelerisque varius morbi enim. Suspendisse ultrices gravida dictum fusce ut placerat orci nulla. Pulvinar mattis nunc sed blandit libero volutpat sed cras. Sed ullamcorper morbi tincidunt ornare massa. Convallis tellus id interdum velit laoreet id donec ultrices. Porttitor eget dolor morbi non arcu risus quis varius.
+
+Venenatis tellus in metus vulputate eu scelerisque felis. Sed elementum tempus egestas sed sed risus pretium quam. Tortor pretium viverra suspendisse potenti nullam ac tortor vitae. Eget duis at tellus at urna condimentum. Ultricies tristique nulla aliquet enim tortor at auctor urna nunc. In egestas erat imperdiet sed euismod nisi porta lorem mollis. Vel risus commodo viverra maecenas accumsan lacus vel. Purus non enim praesent elementum. Hac habitasse platea dictumst vestibulum rhoncus est. Feugiat sed lectus vestibulum mattis ullamcorper. Sagittis eu volutpat odio facilisis mauris sit amet massa vitae. Aliquet risus feugiat in ante metus dictum at tempor commodo. Quis commodo odio aenean sed adipiscing diam donec adipiscing tristique. Dignissim enim sit amet venenatis urna cursus.
+
+Fames ac turpis egestas maecenas pharetra. Viverra nibh cras pulvinar mattis nunc sed. Et netus et malesuada fames ac turpis egestas maecenas. Sed nisi lacus sed viverra tellus in hac habitasse platea. Ac felis donec et odio. Ullamcorper velit sed ullamcorper morbi tincidunt ornare massa eget. Libero justo laoreet sit amet cursus. Amet consectetur adipiscing elit duis tristique sollicitudin nibh sit amet. Aliquet sagittis id consectetur purus ut faucibus pulvinar elementum. Morbi non arcu risus quis varius quam quisque. Sit amet purus gravida quis blandit turpis cursus in. Pharetra diam sit amet nisl suscipit. Maecenas ultricies mi eget mauris pharetra et ultrices neque.
+
+Dui id ornare arcu odio ut. Ac placerat vestibulum lectus mauris ultrices eros in cursus turpis. Blandit aliquam etiam erat velit scelerisque in dictum non. Feugiat in fermentum posuere urna nec tincidunt. In fermentum et sollicitudin ac orci. A pellentesque sit amet porttitor eget dolor morbi non. Adipiscing elit pellentesque habitant morbi. Viverra orci sagittis eu volutpat odio facilisis mauris sit amet. Id velit ut tortor pretium viverra suspendisse potenti nullam ac. Hac habitasse platea dictumst quisque sagittis. Metus dictum at tempor commodo ullamcorper a. Ut venenatis tellus in metus vulputate eu scelerisque. Vitae auctor eu augue ut lectus. Pulvinar elementum integer enim neque volutpat ac. Nunc mattis enim ut tellus elementum sagittis vitae et. Sem viverra aliquet eget sit amet tellus cras. Porttitor eget dolor morbi non arcu.
+
+Netus et malesuada fames ac turpis egestas integer eget aliquet. Sapien nec sagittis aliquam malesuada bibendum arcu vitae elementum. Tristique et egestas quis ipsum. Vitae nunc sed velit dignissim sodales ut eu sem integer. Arcu cursus euismod quis viverra nibh cras pulvinar mattis nunc. Sed blandit libero volutpat sed. Porttitor eget dolor morbi non. Venenatis tellus in metus vulputate eu. Nisi scelerisque eu ultrices vitae auctor eu augue. Lectus quam id leo in vitae turpis massa sed. Et ligula ullamcorper malesuada proin libero nunc consequat interdum varius. Ac placerat vestibulum lectus mauris ultrices eros in cursus turpis.
+
+Egestas sed tempus urna et. Nisl nisi scelerisque eu ultrices vitae auctor. Scelerisque purus semper eget duis at. Risus quis varius quam quisque id diam vel quam elementum. Ut consequat semper viverra nam libero justo laoreet. Duis ut diam quam nulla. Mattis molestie a iaculis at erat pellentesque. Ac tortor vitae purus faucibus ornare suspendisse sed. Etiam erat velit scelerisque in dictum non consectetur a erat. Elit at imperdiet dui accumsan sit amet. Sociis natoque penatibus et magnis dis parturient. Ut ornare lectus sit amet est placerat in egestas erat. Nullam non nisi est sit amet facilisis magna.
+
+A condimentum vitae sapien pellentesque habitant morbi. Enim tortor at auctor urna nunc id cursus metus. Ullamcorper morbi tincidunt ornare massa. Quis auctor elit sed vulputate mi sit amet. Dolor morbi non arcu risus quis. Semper eget duis at tellus at urna condimentum. Mi proin sed libero enim sed faucibus turpis. Sed risus ultricies tristique nulla aliquet enim tortor at auctor. Ridiculus mus mauris vitae ultricies leo integer malesuada nunc. Sit amet justo donec enim diam vulputate ut pharetra sit.
+
+Fames ac turpis egestas sed tempus urna et. In massa tempor nec feugiat. Pharetra pharetra massa massa ultricies mi quis hendrerit dolor. Lacinia quis vel eros donec. Curabitur vitae nunc sed velit dignissim sodales ut eu sem. Gravida dictum fusce ut placerat orci nulla. Tincidunt augue interdum velit euismod in. Vitae congue eu consequat ac felis donec et. Ac auctor augue mauris augue neque gravida in fermentum. Sed viverra tellus in hac habitasse platea dictumst vestibulum. Massa tempor nec feugiat nisl pretium fusce id velit. Est placerat in egestas erat imperdiet sed euismod nisi porta. Convallis posuere morbi leo urna. Enim neque volutpat ac tincidunt vitae semper. Turpis in eu mi bibendum neque. Diam donec adipiscing tristique risus nec feugiat in fermentum. Congue nisi vitae suscipit tellus mauris a diam maecenas.
+
+Lorem ipsum dolor sit amet consectetur. Risus commodo viverra maecenas accumsan lacus vel facilisis. Suspendisse faucibus interdum posuere lorem ipsum dolor sit. In nibh mauris cursus mattis. Ut morbi tincidunt augue interdum velit. Amet venenatis urna cursus eget nunc scelerisque viverra mauris in. Ullamcorper eget nulla facilisi etiam dignissim diam. Pellentesque eu tincidunt tortor aliquam nulla. Mattis vulputate enim nulla aliquet porttitor lacus luctus accumsan. Sit amet luctus venenatis lectus magna fringilla urna porttitor. Faucibus pulvinar elementum integer enim neque volutpat ac tincidunt vitae. Felis bibendum ut tristique et egestas.
+
+Suspendisse sed nisi lacus sed viverra tellus in hac habitasse. Aliquam sem fringilla ut morbi tincidunt augue interdum velit euismod. Mattis aliquam faucibus purus in massa tempor nec. Feugiat vivamus at augue eget arcu dictum varius duis. In hendrerit gravida rutrum quisque non tellus. Dui ut ornare lectus sit. Egestas erat imperdiet sed euismod nisi porta lorem. Faucibus vitae aliquet nec ullamcorper sit amet risus nullam. Massa sed elementum tempus egestas sed sed risus. Ornare lectus sit amet est placerat in egestas erat. Arcu bibendum at varius vel. Ullamcorper sit amet risus nullam eget felis. Lorem donec massa sapien faucibus et molestie ac feugiat sed.
+
+Aliquet risus feugiat in ante metus dictum at. Platea dictumst quisque sagittis purus sit amet volutpat consequat. Dui faucibus in ornare quam viverra orci sagittis eu. Et ligula ullamcorper malesuada proin. Amet consectetur adipiscing elit duis tristique. Fermentum dui faucibus in ornare quam viverra orci. Feugiat vivamus at augue eget arcu. Diam sit amet nisl suscipit adipiscing bibendum. Dolor morbi non arcu risus. Morbi tristique senectus et netus et. Accumsan sit amet nulla facilisi morbi tempus iaculis urna id. Volutpat ac tincidunt vitae semper quis lectus nulla at. Natoque penatibus et magnis dis parturient montes nascetur ridiculus mus. Scelerisque felis imperdiet proin fermentum leo vel orci porta. Diam maecenas ultricies mi eget mauris pharetra et ultrices.
+
+Facilisis magna etiam tempor orci eu lobortis elementum nibh tellus. Consequat ac felis donec et. Cras pulvinar mattis nunc sed blandit libero volutpat sed cras. Sed viverra ipsum nunc aliquet bibendum enim facilisis. Molestie a iaculis at erat pellentesque adipiscing commodo elit at. Habitasse platea dictumst quisque sagittis purus. Tincidunt id aliquet risus feugiat. Facilisis magna etiam tempor orci eu lobortis. Vel eros donec ac odio tempor orci dapibus ultrices in. Mauris rhoncus aenean vel elit scelerisque mauris. Egestas dui id ornare arcu odio ut sem. Tortor aliquam nulla facilisi cras fermentum odio eu. Pharetra et ultrices neque ornare. Id velit ut tortor pretium viverra suspendisse potenti nullam ac. Dictum sit amet justo donec enim diam vulputate. Diam vel quam elementum pulvinar etiam non quam lacus suspendisse. Nibh tortor id aliquet lectus proin nibh nisl. Mattis vulputate enim nulla aliquet porttitor lacus. At auctor urna nunc id cursus metus aliquam eleifend mi. Viverra aliquet eget sit amet tellus cras.
+
+Neque volutpat ac tincidunt vitae semper. Magna fringilla urna porttitor rhoncus dolor purus non enim. Natoque penatibus et magnis dis parturient montes. Elementum facilisis leo vel fringilla est ullamcorper eget. Sit amet justo donec enim diam vulputate ut. Diam quis enim lobortis scelerisque fermentum. Sit amet risus nullam eget felis eget nunc lobortis. Quis hendrerit dolor magna eget est. Blandit massa enim nec dui nunc mattis enim. Sed faucibus turpis in eu mi bibendum neque egestas congue. Imperdiet proin fermentum leo vel orci porta. Egestas sed tempus urna et pharetra pharetra. Lacinia quis vel eros donec ac. Id venenatis a condimentum vitae sapien pellentesque habitant morbi. Nisl rhoncus mattis rhoncus urna neque viverra justo. Facilisis mauris sit amet massa vitae tortor. Dignissim suspendisse in est ante in nibh. Nascetur ridiculus mus mauris vitae ultricies leo integer malesuada nunc. Congue mauris rhoncus aenean vel elit scelerisque mauris pellentesque pulvinar.
+
+Quis eleifend quam adipiscing vitae proin sagittis. Mi eget mauris pharetra et ultrices neque ornare aenean. Ipsum dolor sit amet consectetur. Mauris in aliquam sem fringilla ut morbi. Nulla malesuada pellentesque elit eget gravida cum sociis natoque. A condimentum vitae sapien pellentesque habitant morbi tristique senectus et. Pulvinar proin gravida hendrerit lectus a. Metus vulputate eu scelerisque felis. Vivamus arcu felis bibendum ut tristique et egestas. Duis convallis convallis tellus id. Neque ornare aenean euismod elementum nisi quis. Ultricies lacus sed turpis tincidunt id.
+
+Vel fringilla est ullamcorper eget nulla facilisi etiam. Pellentesque massa placerat duis ultricies lacus sed turpis tincidunt id. Enim ut tellus elementum sagittis vitae et. Mattis vulputate enim nulla aliquet porttitor lacus luctus. Eget lorem dolor sed viverra. Pellentesque habitant morbi tristique senectus et netus et. Dolor sit amet consectetur adipiscing elit pellentesque habitant. Nisl vel pretium lectus quam id leo. Id faucibus nisl tincidunt eget nullam non. Gravida arcu ac tortor dignissim convallis aenean. Pellentesque diam volutpat commodo sed egestas egestas fringilla phasellus. Sed arcu non odio euismod lacinia at quis risus. Quis lectus nulla at volutpat. Augue interdum velit euismod in pellentesque massa placerat duis. Commodo quis imperdiet massa tincidunt nunc. Ullamcorper malesuada proin libero nunc consequat interdum varius sit amet. Libero id faucibus nisl tincidunt eget nullam. Blandit cursus risus at ultrices. Faucibus nisl tincidunt eget nullam non nisi. Aenean et tortor at risus viverra adipiscing.
+
+Egestas congue quisque egestas diam. Odio tempor orci dapibus ultrices in iaculis nunc sed. Volutpat blandit aliquam etiam erat velit scelerisque. Bibendum ut tristique et egestas quis ipsum suspendisse ultrices gravida. Viverra adipiscing at in tellus. At augue eget arcu dictum varius duis at. Sagittis aliquam malesuada bibendum arcu vitae. Nam at lectus urna duis convallis convallis tellus id interdum. Neque aliquam vestibulum morbi blandit cursus. Sagittis id consectetur purus ut faucibus pulvinar elementum integer enim. Dictum non consectetur a erat nam at lectus. Maecenas sed enim ut sem viverra. Nisi porta lorem mollis aliquam ut porttitor leo. Malesuada nunc vel risus commodo viverra maecenas. Sed vulputate mi sit amet mauris commodo quis imperdiet massa. Neque volutpat ac tincidunt vitae semper quis lectus nulla at. Vehicula ipsum a arcu cursus vitae congue mauris rhoncus. Volutpat diam ut venenatis tellus in metus vulputate eu scelerisque.
+
+Et malesuada fames ac turpis egestas maecenas. Ultrices mi tempus imperdiet nulla malesuada. Id eu nisl nunc mi ipsum faucibus vitae aliquet. Amet volutpat consequat mauris nunc congue nisi. Nisi quis eleifend quam adipiscing vitae proin sagittis nisl. Dictum non consectetur a erat nam. Eget dolor morbi non arcu risus quis varius. Nisi scelerisque eu ultrices vitae auctor eu augue. Lorem ipsum dolor sit amet consectetur adipiscing elit. Eu feugiat pretium nibh ipsum consequat nisl vel. Eget aliquet nibh praesent tristique magna sit amet purus. Sed arcu non odio euismod lacinia at. Nisi vitae suscipit tellus mauris. Accumsan lacus vel facilisis volutpat est velit egestas. Faucibus in ornare quam viverra orci sagittis. Odio ut enim blandit volutpat maecenas volutpat blandit aliquam etiam.
+
+Cursus vitae congue mauris rhoncus aenean vel elit. Eget magna fermentum iaculis eu non diam phasellus vestibulum lorem. Mi in nulla posuere sollicitudin aliquam ultrices sagittis orci a. Dui nunc mattis enim ut. Velit euismod in pellentesque massa placerat duis ultricies lacus. Massa vitae tortor condimentum lacinia quis vel. Rhoncus mattis rhoncus urna neque viverra justo. Pellentesque habitant morbi tristique senectus et netus et malesuada fames. Vitae aliquet nec ullamcorper sit amet risus nullam eget. Pellentesque pulvinar pellentesque habitant morbi tristique senectus. Eget duis at tellus at urna. Faucibus a pellentesque sit amet porttitor eget.
+
+Iaculis urna id volutpat lacus laoreet. Lacinia quis vel eros donec ac odio tempor. Etiam dignissim diam quis enim lobortis scelerisque fermentum. Feugiat nisl pretium fusce id velit. Velit ut tortor pretium viverra suspendisse potenti nullam. Neque ornare aenean euismod elementum. Semper auctor neque vitae tempus. Nisl pretium fusce id velit ut. Neque egestas congue quisque egestas diam in. Nunc sed augue lacus viverra vitae congue eu. Diam vel quam elementum pulvinar etiam non quam lacus suspendisse. Gravida rutrum quisque non tellus orci. Senectus et netus et malesuada fames. Nisl purus in mollis nunc sed id semper risus.
+
+Interdum velit euismod in pellentesque massa placerat duis ultricies lacus. Arcu risus quis varius quam quisque id diam vel. Nec ullamcorper sit amet risus nullam eget. Tristique senectus et netus et malesuada. Eget lorem dolor sed viverra ipsum nunc aliquet bibendum enim. Aliquet eget sit amet tellus cras adipiscing enim eu. Cursus in hac habitasse platea dictumst quisque sagittis. Augue lacus viverra vitae congue eu. Duis convallis convallis tellus id interdum velit laoreet id donec. Rhoncus aenean vel elit scelerisque mauris pellentesque pulvinar pellentesque habitant. Auctor neque vitae tempus quam pellentesque nec nam. At risus viverra adipiscing at in. Libero volutpat sed cras ornare arcu. Leo integer malesuada nunc vel risus. Ut tellus elementum sagittis vitae et.
+
+Id venenatis a condimentum vitae sapien. Lorem dolor sed viverra ipsum nunc aliquet. At in tellus integer feugiat. Quam id leo in vitae turpis massa sed. Donec ultrices tincidunt arcu non sodales neque. Nulla malesuada pellentesque elit eget gravida cum sociis natoque penatibus. Pharetra pharetra massa massa ultricies mi quis hendrerit. Habitasse platea dictumst vestibulum rhoncus est pellentesque elit ullamcorper. Arcu odio ut sem nulla pharetra diam. Nullam vehicula ipsum a arcu cursus vitae congue mauris. Consectetur adipiscing elit pellentesque habitant morbi. Morbi tristique senectus et netus et malesuada fames. Mauris ultrices eros in cursus turpis massa. Hendrerit dolor magna eget est lorem. Facilisi morbi tempus iaculis urna id. Nascetur ridiculus mus mauris vitae ultricies leo integer. Blandit cursus risus at ultrices mi. Aenean vel elit scelerisque mauris pellentesque pulvinar pellentesque habitant. Est lorem ipsum dolor sit amet consectetur adipiscing.
+
+Leo vel orci porta non pulvinar neque laoreet suspendisse interdum. Cursus vitae congue mauris rhoncus aenean vel elit scelerisque mauris. Urna id volutpat lacus laoreet non curabitur gravida. Aliquet porttitor lacus luctus accumsan tortor. Lectus sit amet est placerat in egestas erat. Lacus sed viverra tellus in. Leo in vitae turpis massa sed. Interdum varius sit amet mattis vulputate enim. Tincidunt vitae semper quis lectus nulla. Turpis egestas maecenas pharetra convallis posuere morbi. Mauris pellentesque pulvinar pellentesque habitant morbi tristique senectus et. Enim blandit volutpat maecenas volutpat blandit. Duis ut diam quam nulla porttitor. Enim nulla aliquet porttitor lacus luctus accumsan. In vitae turpis massa sed. Malesuada proin libero nunc consequat interdum varius sit.
+
+Elit ullamcorper dignissim cras tincidunt lobortis. Duis ut diam quam nulla porttitor. Tellus rutrum tellus pellentesque eu tincidunt tortor. In fermentum posuere urna nec tincidunt praesent semper feugiat nibh. Nunc mattis enim ut tellus elementum sagittis. Amet tellus cras adipiscing enim eu turpis egestas pretium. Nunc pulvinar sapien et ligula ullamcorper malesuada proin. Sed libero enim sed faucibus turpis in eu mi. In massa tempor nec feugiat nisl pretium fusce id. Sit amet porttitor eget dolor. Molestie a iaculis at erat pellentesque adipiscing commodo elit at. Eleifend quam adipiscing vitae proin sagittis nisl rhoncus. Amet est placerat in egestas. Consequat nisl vel pretium lectus. Vulputate sapien nec sagittis aliquam malesuada bibendum arcu vitae. Massa tincidunt dui ut ornare.
+
+Cras semper auctor neque vitae. Enim sed faucibus turpis in eu mi. Posuere morbi leo urna molestie. Sed cras ornare arcu dui vivamus arcu felis bibendum. Amet est placerat in egestas erat imperdiet sed. Odio facilisis mauris sit amet. Amet facilisis magna etiam tempor orci eu lobortis. Sagittis id consectetur purus ut faucibus pulvinar elementum. Eu tincidunt tortor aliquam nulla facilisi cras fermentum. Amet mauris commodo quis imperdiet. Vitae tortor condimentum lacinia quis vel eros. Facilisis leo vel fringilla est ullamcorper eget nulla facilisi. Ut diam quam nulla porttitor. Nam libero justo laoreet sit. Porttitor rhoncus dolor purus non enim praesent elementum facilisis. Ut placerat orci nulla pellentesque dignissim.
+
+Velit dignissim sodales ut eu. Tincidunt id aliquet risus feugiat in ante. Eu nisl nunc mi ipsum faucibus. Interdum velit euismod in pellentesque massa. Sollicitudin aliquam ultrices sagittis orci a scelerisque purus semper. Sit amet justo donec enim diam vulputate ut pharetra. Accumsan lacus vel facilisis volutpat est velit. Fringilla est ullamcorper eget nulla facilisi etiam. Sed euismod nisi porta lorem mollis aliquam ut porttitor. Nec sagittis aliquam malesuada bibendum arcu vitae elementum curabitur vitae. Viverra maecenas accumsan lacus vel facilisis volutpat est. Et netus et malesuada fames ac turpis. Dolor morbi non arcu risus quis varius. Velit scelerisque in dictum non consectetur a erat. Ac ut consequat semper viverra nam libero justo. Odio tempor orci dapibus ultrices.
+
+Aliquam etiam erat velit scelerisque in dictum non consectetur a. Suspendisse faucibus interdum posuere lorem. Ultrices eros in cursus turpis massa tincidunt dui ut. Euismod nisi porta lorem mollis. Vel fringilla est ullamcorper eget. Bibendum est ultricies integer quis auctor. Lacus vestibulum sed arcu non odio. Eget sit amet tellus cras adipiscing enim eu turpis. Accumsan lacus vel facilisis volutpat est velit egestas dui. Vitae et leo duis ut diam quam nulla porttitor massa. Justo donec enim diam vulputate ut pharetra sit amet aliquam. Ac odio tempor orci dapibus ultrices in. Dis parturient montes nascetur ridiculus. Sit amet volutpat consequat mauris nunc congue nisi. Vitae sapien pellentesque habitant morbi tristique senectus. Metus dictum at tempor commodo ullamcorper a lacus. Sed viverra tellus in hac habitasse platea dictumst. Rhoncus est pellentesque elit ullamcorper. Nunc sed velit dignissim sodales ut. Vitae turpis massa sed elementum tempus egestas.
+
+Egestas quis ipsum suspendisse ultrices gravida dictum fusce ut. Aliquet nec ullamcorper sit amet. Eget sit amet tellus cras adipiscing enim eu turpis egestas. Orci phasellus egestas tellus rutrum. Vel facilisis volutpat est velit egestas dui id ornare arcu. Sit amet porttitor eget dolor morbi non arcu. Viverra mauris in aliquam sem fringilla ut morbi. Semper eget duis at tellus at. Lectus magna fringilla urna porttitor rhoncus dolor purus non. Urna duis convallis convallis tellus id interdum velit laoreet. Mi eget mauris pharetra et ultrices neque ornare aenean. Erat velit scelerisque in dictum non consectetur a erat. Quis ipsum suspendisse ultrices gravida. Tortor dignissim convallis aenean et. Sit amet nisl purus in mollis nunc. In massa tempor nec feugiat nisl pretium fusce id.
+
+Massa tincidunt dui ut ornare lectus. Molestie at elementum eu facilisis sed odio morbi. Lacus sed turpis tincidunt id aliquet risus feugiat. Viverra tellus in hac habitasse platea dictumst. Risus pretium quam vulputate dignissim suspendisse in. Risus quis varius quam quisque id diam vel quam elementum. Ultricies leo integer malesuada nunc vel risus commodo viverra. Justo donec enim diam vulputate. Diam vel quam elementum pulvinar etiam non quam lacus suspendisse. Dictum fusce ut placerat orci nulla pellentesque dignissim enim sit. Lacus vestibulum sed arcu non. In hac habitasse platea dictumst vestibulum rhoncus est. Scelerisque fermentum dui faucibus in. Scelerisque eu ultrices vitae auctor eu. Viverra nibh cras pulvinar mattis.
+
+Pulvinar neque laoreet suspendisse interdum consectetur libero id faucibus. Tristique sollicitudin nibh sit amet commodo nulla. Nulla porttitor massa id neque aliquam. Rutrum quisque non tellus orci. Sit amet luctus venenatis lectus magna fringilla urna porttitor. Amet venenatis urna cursus eget nunc scelerisque viverra mauris. Sed euismod nisi porta lorem mollis aliquam ut. Dictum non consectetur a erat nam at. Morbi tincidunt augue interdum velit euismod in pellentesque massa. Lorem donec massa sapien faucibus. At augue eget arcu dictum varius duis at. Arcu cursus vitae congue mauris. Magna eget est lorem ipsum dolor sit amet consectetur. Amet commodo nulla facilisi nullam vehicula ipsum a arcu. Dui ut ornare lectus sit amet est placerat in egestas. Suspendisse potenti nullam ac tortor vitae purus faucibus. Ut eu sem integer vitae justo eget magna. Bibendum est ultricies integer quis auctor.
+
+Odio euismod lacinia at quis risus sed vulputate odio ut. Morbi quis commodo odio aenean sed adipiscing diam. Neque sodales ut etiam sit amet nisl purus. Mi sit amet mauris commodo quis imperdiet. In hendrerit gravida rutrum quisque non tellus orci ac. Ultrices gravida dictum fusce ut placerat orci nulla pellentesque dignissim. Nibh mauris cursus mattis molestie a iaculis at erat. Nibh venenatis cras sed felis. Tincidunt vitae semper quis lectus nulla at volutpat diam ut. Quis commodo odio aenean sed adipiscing. Risus in hendrerit gravida rutrum quisque non tellus orci ac. Et netus et malesuada fames ac turpis egestas. Pulvinar pellentesque habitant morbi tristique senectus et netus. Turpis tincidunt id aliquet risus feugiat in ante.
+
+Nisl purus in mollis nunc sed id. Elit ut aliquam purus sit amet luctus venenatis. Ut eu sem integer vitae justo eget magna. Ac placerat vestibulum lectus mauris ultrices eros. Ultrices mi tempus imperdiet nulla malesuada. Consequat id porta nibh venenatis cras. Nisl pretium fusce id velit ut tortor pretium. Et netus et malesuada fames ac. Enim nulla aliquet porttitor lacus luctus accumsan tortor posuere. Bibendum at varius vel pharetra. Nec ullamcorper sit amet risus nullam. Amet risus nullam eget felis eget. Eros in cursus turpis massa tincidunt dui ut. Enim nec dui nunc mattis enim ut tellus. Quam pellentesque nec nam aliquam sem et tortor consequat. Nulla facilisi morbi tempus iaculis urna id. Magnis dis parturient montes nascetur ridiculus mus mauris vitae ultricies.
+
+Ac turpis egestas maecenas pharetra convallis posuere morbi leo. Eget duis at tellus at. Netus et malesuada fames ac turpis. Sagittis nisl rhoncus mattis rhoncus urna neque viverra justo nec. Erat nam at lectus urna duis convallis convallis tellus id. Quis blandit turpis cursus in hac habitasse platea dictumst. Sed euismod nisi porta lorem mollis. Ridiculus mus mauris vitae ultricies leo integer malesuada nunc vel. Tristique senectus et netus et malesuada. Est ullamcorper eget nulla facilisi etiam dignissim. Egestas quis ipsum suspendisse ultrices gravida dictum fusce ut. Metus aliquam eleifend mi in nulla posuere. Dictumst quisque sagittis purus sit amet volutpat consequat mauris nunc. Lectus sit amet est placerat in egestas erat. At erat pellentesque adipiscing commodo elit at. Pretium viverra suspendisse potenti nullam ac. Volutpat sed cras ornare arcu dui vivamus arcu felis.
+
+Malesuada fames ac turpis egestas integer eget. Tellus orci ac auctor augue mauris augue. Faucibus in ornare quam viverra orci. Sagittis aliquam malesuada bibendum arcu vitae elementum curabitur. Vel turpis nunc eget lorem. Mus mauris vitae ultricies leo integer malesuada nunc vel. Nisl suscipit adipiscing bibendum est ultricies integer quis. Ultrices vitae auctor eu augue ut lectus arcu bibendum at. Nulla pellentesque dignissim enim sit amet venenatis urna cursus eget. Potenti nullam ac tortor vitae purus faucibus. Morbi tempus iaculis urna id. Phasellus faucibus scelerisque eleifend donec pretium. Ultrices sagittis orci a scelerisque purus. Sit amet nulla facilisi morbi. Massa sapien faucibus et molestie ac feugiat. Vitae purus faucibus ornare suspendisse sed nisi. Ut ornare lectus sit amet est placerat in egestas erat. Lobortis mattis aliquam faucibus purus.
+
+Eu facilisis sed odio morbi quis commodo odio aenean. Faucibus a pellentesque sit amet porttitor eget dolor. Arcu bibendum at varius vel pharetra vel. Etiam dignissim diam quis enim lobortis scelerisque fermentum. Porttitor rhoncus dolor purus non. Vel elit scelerisque mauris pellentesque pulvinar. Porttitor eget dolor morbi non. Aliquam ultrices sagittis orci a scelerisque purus semper eget duis. In vitae turpis massa sed elementum tempus egestas sed. Elit eget gravida cum sociis natoque penatibus. Pulvinar sapien et ligula ullamcorper malesuada proin libero nunc. Elit pellentesque habitant morbi tristique senectus et netus. Ut etiam sit amet nisl purus in mollis nunc. Platea dictumst quisque sagittis purus sit amet volutpat consequat. Facilisis gravida neque convallis a. Ac feugiat sed lectus vestibulum mattis ullamcorper velit sed ullamcorper. Non arcu risus quis varius quam quisque id.
+
+Diam phasellus vestibulum lorem sed risus ultricies tristique nulla aliquet. Nec sagittis aliquam malesuada bibendum arcu vitae elementum. Id aliquet lectus proin nibh. Consectetur purus ut faucibus pulvinar elementum. Id aliquet risus feugiat in ante metus dictum at. Nulla porttitor massa id neque aliquam vestibulum morbi blandit. Eget aliquet nibh praesent tristique magna sit amet purus. Enim nunc faucibus a pellentesque. Tellus in hac habitasse platea. Adipiscing diam donec adipiscing tristique risus nec. Id consectetur purus ut faucibus pulvinar elementum. Sodales ut eu sem integer vitae. Eu nisl nunc mi ipsum faucibus.
+
+Consequat id porta nibh venenatis. Convallis aenean et tortor at risus viverra adipiscing at. Etiam sit amet nisl purus in mollis nunc. Ornare quam viverra orci sagittis eu volutpat odio facilisis. Egestas egestas fringilla phasellus faucibus scelerisque. Proin libero nunc consequat interdum varius sit amet mattis vulputate. Non blandit massa enim nec. Vestibulum morbi blandit cursus risus at ultrices. Et malesuada fames ac turpis egestas integer. Commodo viverra maecenas accumsan lacus vel facilisis. Morbi tristique senectus et netus et malesuada. Dui vivamus arcu felis bibendum ut tristique et. Neque laoreet suspendisse interdum consectetur libero. Donec massa sapien faucibus et molestie ac feugiat sed. Lectus nulla at volutpat diam ut venenatis. Mi eget mauris pharetra et ultrices neque ornare aenean. Ullamcorper a lacus vestibulum sed arcu. Vel facilisis volutpat est velit. Porttitor eget dolor morbi non arcu risus quis. Sodales ut etiam sit amet nisl purus.
+
+Consectetur libero id faucibus nisl tincidunt eget nullam non nisi. Sapien faucibus et molestie ac feugiat sed lectus vestibulum mattis. Lectus nulla at volutpat diam ut. Suspendisse in est ante in nibh mauris cursus mattis molestie. Ornare suspendisse sed nisi lacus sed. Feugiat nibh sed pulvinar proin gravida hendrerit. Nec feugiat nisl pretium fusce id velit. Eget mauris pharetra et ultrices neque ornare aenean euismod elementum. Quam vulputate dignissim suspendisse in. Sed nisi lacus sed viverra tellus in. Hendrerit gravida rutrum quisque non tellus orci. Ac turpis egestas maecenas pharetra convallis. Lectus sit amet est placerat in. Id eu nisl nunc mi ipsum faucibus vitae aliquet.
+
+A arcu cursus vitae congue mauris rhoncus. Vitae nunc sed velit dignissim sodales ut eu sem. Amet nulla facilisi morbi tempus iaculis urna id volutpat lacus. Vitae aliquet nec ullamcorper sit amet risus nullam. Pulvinar mattis nunc sed blandit. Ac feugiat sed lectus vestibulum mattis ullamcorper. Lorem ipsum dolor sit amet consectetur adipiscing elit. Magna fermentum iaculis eu non diam phasellus vestibulum. Elementum sagittis vitae et leo duis ut. Sociis natoque penatibus et magnis dis. Eu scelerisque felis imperdiet proin fermentum leo vel orci. Ultricies integer quis auctor elit sed vulputate mi sit. Id consectetur purus ut faucibus pulvinar elementum integer enim. Risus sed vulputate odio ut. Vivamus arcu felis bibendum ut tristique. Fermentum posuere urna nec tincidunt praesent. Leo vel orci porta non. Turpis egestas sed tempus urna et. Sed velit dignissim sodales ut eu sem. Rhoncus dolor purus non enim praesent elementum facilisis leo vel.
+
+Tempus quam pellentesque nec nam aliquam sem. Pellentesque massa placerat duis ultricies lacus. In est ante in nibh mauris cursus mattis molestie a. Id leo in vitae turpis. Ac turpis egestas integer eget aliquet nibh praesent. Sit amet justo donec enim diam vulputate ut pharetra. Sapien et ligula ullamcorper malesuada proin libero nunc. Mauris vitae ultricies leo integer malesuada nunc. Sem viverra aliquet eget sit amet tellus cras adipiscing. Aliquam sem fringilla ut morbi tincidunt augue interdum. Tincidunt tortor aliquam nulla facilisi cras fermentum odio eu feugiat.
+
+Nunc consequat interdum varius sit amet mattis vulputate enim nulla. Et odio pellentesque diam volutpat. Faucibus interdum posuere lorem ipsum dolor. Urna duis convallis convallis tellus id interdum velit laoreet. Hac habitasse platea dictumst quisque sagittis. Cras fermentum odio eu feugiat pretium nibh ipsum consequat. Nisl suscipit adipiscing bibendum est ultricies. Tempor commodo ullamcorper a lacus. Rutrum quisque non tellus orci ac auctor augue. In arcu cursus euismod quis viverra. Aenean vel elit scelerisque mauris pellentesque pulvinar pellentesque habitant. Massa tincidunt dui ut ornare lectus sit amet. Vitae aliquet nec ullamcorper sit amet. Faucibus in ornare quam viverra orci sagittis eu volutpat. Porta nibh venenatis cras sed felis eget velit aliquet. Tincidunt augue interdum velit euismod. In mollis nunc sed id semper risus in hendrerit gravida. Eget dolor morbi non arcu risus.
+
+Nunc vel risus commodo viverra maecenas accumsan. Ornare suspendisse sed nisi lacus sed viverra tellus in. Magna sit amet purus gravida. Scelerisque viverra mauris in aliquam sem fringilla ut. Fermentum leo vel orci porta non pulvinar neque laoreet. Sed blandit libero volutpat sed cras. Congue quisque egestas diam in arcu cursus euismod quis viverra. Donec et odio pellentesque diam volutpat. Faucibus scelerisque eleifend donec pretium vulputate sapien. Mattis enim ut tellus elementum sagittis. Ipsum faucibus vitae aliquet nec ullamcorper.
+
+Quis hendrerit dolor magna eget. Magna eget est lorem ipsum dolor sit amet consectetur. Aliquet lectus proin nibh nisl. Vel pharetra vel turpis nunc eget lorem dolor sed. Fringilla phasellus faucibus scelerisque eleifend. Eget nunc lobortis mattis aliquam faucibus. Libero enim sed faucibus turpis in eu mi. Dui faucibus in ornare quam. Mollis aliquam ut porttitor leo. At risus viverra adipiscing at. Mattis aliquam faucibus purus in massa tempor. In egestas erat imperdiet sed.
+
+Ipsum nunc aliquet bibendum enim facilisis. Rhoncus dolor purus non enim praesent elementum facilisis leo. Nibh venenatis cras sed felis eget velit aliquet sagittis. Feugiat in fermentum posuere urna nec tincidunt. Risus pretium quam vulputate dignissim suspendisse. Suspendisse in est ante in nibh. Amet est placerat in egestas erat imperdiet sed euismod. Eleifend mi in nulla posuere sollicitudin aliquam. Est pellentesque elit ullamcorper dignissim. Volutpat est velit egestas dui id ornare arcu odio ut. Gravida cum sociis natoque penatibus et magnis dis. Aliquet porttitor lacus luctus accumsan. Arcu non sodales neque sodales ut etiam sit. Tincidunt dui ut ornare lectus sit amet est. Sem et tortor consequat id porta nibh venenatis cras. Eu turpis egestas pretium aenean pharetra magna ac placerat. Eu ultrices vitae auctor eu augue. Egestas diam in arcu cursus euismod quis viverra nibh.
+
+Sed id semper risus in hendrerit. Quam adipiscing vitae proin sagittis nisl rhoncus mattis. Sed velit dignissim sodales ut eu. Volutpat sed cras ornare arcu dui. Nisl pretium fusce id velit ut tortor pretium. Interdum velit laoreet id donec ultrices. Commodo odio aenean sed adipiscing diam donec adipiscing tristique risus. Iaculis nunc sed augue lacus. Turpis nunc eget lorem dolor sed viverra ipsum nunc. Enim nec dui nunc mattis enim ut. Mollis nunc sed id semper risus. Cum sociis natoque penatibus et magnis dis parturient montes nascetur. Volutpat consequat mauris nunc congue nisi vitae suscipit tellus. In arcu cursus euismod quis viverra.
+
+Aliquet eget sit amet tellus cras adipiscing. Sed viverra ipsum nunc aliquet bibendum enim facilisis gravida neque. A condimentum vitae sapien pellentesque habitant morbi. In est ante in nibh mauris cursus. Sagittis nisl rhoncus mattis rhoncus urna. Semper eget duis at tellus at urna. Sit amet consectetur adipiscing elit. Amet dictum sit amet justo. Tortor id aliquet lectus proin. Volutpat sed cras ornare arcu.
+
+Quam id leo in vitae turpis. Cursus turpis massa tincidunt dui ut. Feugiat scelerisque varius morbi enim nunc. Amet justo donec enim diam. Montes nascetur ridiculus mus mauris vitae ultricies leo. Lorem mollis aliquam ut porttitor leo a. At auctor urna nunc id cursus metus aliquam eleifend. Nisl nisi scelerisque eu ultrices vitae auctor eu augue. Tristique et egestas quis ipsum suspendisse ultrices gravida dictum fusce. Egestas tellus rutrum tellus pellentesque eu. Nibh tellus molestie nunc non blandit.
+
+Morbi tempus iaculis urna id volutpat lacus. Posuere ac ut consequat semper viverra nam. Ac auctor augue mauris augue neque gravida in fermentum. Sit amet aliquam id diam maecenas ultricies mi eget mauris. Purus in massa tempor nec feugiat nisl. Non nisi est sit amet facilisis. Tincidunt augue interdum velit euismod in pellentesque massa placerat duis. Sit amet purus gravida quis. Proin nibh nisl condimentum id venenatis a condimentum vitae. Cras adipiscing enim eu turpis egestas pretium. Risus commodo viverra maecenas accumsan. Elementum curabitur vitae nunc sed velit dignissim sodales ut eu. Condimentum vitae sapien pellentesque habitant morbi tristique senectus. Mattis vulputate enim nulla aliquet porttitor lacus luctus accumsan. Elementum eu facilisis sed odio morbi.
+
+Nisl nunc mi ipsum faucibus vitae aliquet nec ullamcorper sit. Cursus risus at ultrices mi tempus. Eu non diam phasellus vestibulum. Nisl vel pretium lectus quam id. Sodales ut etiam sit amet nisl purus in mollis. Vulputate enim nulla aliquet porttitor lacus luctus accumsan tortor. Ut placerat orci nulla pellentesque dignissim enim sit amet. Nec nam aliquam sem et tortor consequat id porta nibh. At tempor commodo ullamcorper a lacus vestibulum. Ac tortor dignissim convallis aenean et tortor at risus. Praesent semper feugiat nibh sed pulvinar. Est ullamcorper eget nulla facilisi etiam dignissim diam. Lorem donec massa sapien faucibus. Lectus proin nibh nisl condimentum id venenatis a condimentum. Aliquam eleifend mi in nulla posuere sollicitudin. Ultricies leo integer malesuada nunc vel risus commodo viverra. Aliquet lectus proin nibh nisl condimentum id venenatis a. Cursus mattis molestie a iaculis at erat pellentesque adipiscing commodo. Tellus cras adipiscing enim eu turpis egestas pretium aenean pharetra. Sit amet luctus venenatis lectus magna.
+
+Vel pretium lectus quam id leo in vitae turpis massa. Sit amet nulla facilisi morbi. Eu ultrices vitae auctor eu augue ut lectus arcu. Dictum non consectetur a erat. Id velit ut tortor pretium viverra suspendisse potenti. Ut faucibus pulvinar elementum integer enim neque. Lorem mollis aliquam ut porttitor leo. Etiam non quam lacus suspendisse faucibus. Faucibus a pellentesque sit amet porttitor eget. Fermentum leo vel orci porta non pulvinar neque laoreet suspendisse.
+
+Purus non enim praesent elementum facilisis leo vel fringilla. Mi sit amet mauris commodo quis imperdiet massa. Ultrices sagittis orci a scelerisque purus semper eget duis at. Vulputate dignissim suspendisse in est ante in nibh mauris. Fames ac turpis egestas sed tempus urna et pharetra. Diam vulputate ut pharetra sit amet. Quisque non tellus orci ac auctor augue. Sed viverra ipsum nunc aliquet bibendum enim facilisis. Habitant morbi tristique senectus et. Risus in hendrerit gravida rutrum quisque non tellus orci ac. Senectus et netus et malesuada fames. Semper eget duis at tellus at urna condimentum. At elementum eu facilisis sed odio morbi quis commodo odio. Eu turpis egestas pretium aenean pharetra magna ac placerat vestibulum. Tellus cras adipiscing enim eu turpis egestas pretium aenean. Sagittis nisl rhoncus mattis rhoncus urna neque viverra justo nec. Eu non diam phasellus vestibulum lorem sed risus ultricies tristique.
+
+Pulvinar pellentesque habitant morbi tristique senectus. Eget magna fermentum iaculis eu non diam phasellus vestibulum. Quis risus sed vulputate odio ut. A pellentesque sit amet porttitor eget dolor morbi. Sed turpis tincidunt id aliquet. Mattis enim ut tellus elementum. Eleifend donec pretium vulputate sapien. Convallis posuere morbi leo urna molestie at. Quam elementum pulvinar etiam non quam. Aliquam etiam erat velit scelerisque. Tincidunt arcu non sodales neque sodales. In iaculis nunc sed augue lacus viverra. Vel facilisis volutpat est velit egestas dui. Faucibus a pellentesque sit amet porttitor eget dolor morbi. In ante metus dictum at tempor commodo ullamcorper a lacus.
+
+Malesuada fames ac turpis egestas integer eget. Consectetur adipiscing elit duis tristique sollicitudin nibh. Tristique risus nec feugiat in fermentum posuere. Mauris vitae ultricies leo integer malesuada nunc vel risus. Pellentesque adipiscing commodo elit at imperdiet. Nulla facilisi etiam dignissim diam quis. Nulla porttitor massa id neque aliquam. At elementum eu facilisis sed odio morbi. A pellentesque sit amet porttitor eget dolor morbi non arcu. Nunc eget lorem dolor sed viverra ipsum nunc aliquet bibendum. Sapien faucibus et molestie ac feugiat sed lectus vestibulum. Et sollicitudin ac orci phasellus. Ultrices gravida dictum fusce ut placerat.
+
+At risus viverra adipiscing at in. In fermentum posuere urna nec tincidunt praesent semper feugiat nibh. Vitae turpis massa sed elementum tempus egestas sed sed risus. Leo urna molestie at elementum eu facilisis. Molestie at elementum eu facilisis sed odio morbi. Ipsum nunc aliquet bibendum enim facilisis gravida neque convallis a. Sit amet luctus venenatis lectus. Enim eu turpis egestas pretium aenean pharetra magna ac. Sed euismod nisi porta lorem mollis aliquam ut porttitor. In fermentum posuere urna nec tincidunt. Mollis aliquam ut porttitor leo a diam sollicitudin tempor. Elementum nibh tellus molestie nunc. Id donec ultrices tincidunt arcu. Dui ut ornare lectus sit amet est placerat in. Pellentesque pulvinar pellentesque habitant morbi tristique senectus et netus et.
+
+Curabitur vitae nunc sed velit dignissim sodales ut eu sem. Ultricies tristique nulla aliquet enim tortor. Feugiat in ante metus dictum at tempor. Lacinia at quis risus sed vulputate odio ut. Donec massa sapien faucibus et molestie ac feugiat sed lectus. Erat nam at lectus urna duis convallis convallis. Laoreet sit amet cursus sit amet dictum sit amet. Feugiat vivamus at augue eget arcu dictum varius. Velit dignissim sodales ut eu sem integer vitae justo. Phasellus vestibulum lorem sed risus. Enim sit amet venenatis urna cursus eget nunc scelerisque. Euismod lacinia at quis risus. Nulla pharetra diam sit amet nisl suscipit adipiscing. Eget velit aliquet sagittis id consectetur purus ut faucibus. Odio eu feugiat pretium nibh ipsum consequat nisl vel pretium. Euismod nisi porta lorem mollis. Ut enim blandit volutpat maecenas volutpat. Sit amet consectetur adipiscing elit pellentesque habitant morbi. Est lorem ipsum dolor sit amet consectetur adipiscing. At imperdiet dui accumsan sit amet nulla facilisi morbi.
+
+Nec nam aliquam sem et tortor consequat. A lacus vestibulum sed arcu non odio euismod. Dictum fusce ut placerat orci nulla pellentesque dignissim. Cursus metus aliquam eleifend mi in nulla posuere sollicitudin. Id ornare arcu odio ut. Eu facilisis sed odio morbi quis commodo odio aenean sed. Risus commodo viverra maecenas accumsan lacus vel facilisis volutpat. Auctor urna nunc id cursus metus aliquam. Hendrerit gravida rutrum quisque non. Id velit ut tortor pretium. Dignissim suspendisse in est ante in nibh mauris cursus mattis. Vestibulum rhoncus est pellentesque elit ullamcorper dignissim cras. Ultricies lacus sed turpis tincidunt id aliquet risus feugiat in. Duis at tellus at urna condimentum mattis pellentesque id. Sem nulla pharetra diam sit amet nisl suscipit adipiscing bibendum. Mattis nunc sed blandit libero volutpat sed cras ornare. Sit amet cursus sit amet dictum sit amet. Faucibus ornare suspendisse sed nisi lacus. Rutrum quisque non tellus orci.
+
+Mattis rhoncus urna neque viverra justo nec. Tristique senectus et netus et malesuada fames. Vitae tortor condimentum lacinia quis vel eros donec ac odio. Adipiscing commodo elit at imperdiet dui accumsan sit. Facilisis sed odio morbi quis commodo. Purus in massa tempor nec. Arcu felis bibendum ut tristique et. Netus et malesuada fames ac turpis egestas sed tempus. Bibendum neque egestas congue quisque. Non curabitur gravida arcu ac tortor dignissim convallis aenean. Sed felis eget velit aliquet sagittis id consectetur purus. Condimentum lacinia quis vel eros donec. Enim tortor at auctor urna. Ac turpis egestas integer eget aliquet nibh praesent. Ac turpis egestas sed tempus urna et pharetra. Imperdiet massa tincidunt nunc pulvinar sapien. Velit scelerisque in dictum non consectetur a erat. Velit scelerisque in dictum non consectetur a erat nam at. In eu mi bibendum neque egestas congue quisque.
+
+Non quam lacus suspendisse faucibus interdum posuere lorem ipsum dolor. Commodo quis imperdiet massa tincidunt nunc pulvinar sapien. Facilisi morbi tempus iaculis urna id volutpat lacus laoreet. Sit amet tellus cras adipiscing enim eu turpis egestas pretium. Ut morbi tincidunt augue interdum velit euismod in pellentesque. Eu non diam phasellus vestibulum. In nibh mauris cursus mattis. Convallis a cras semper auctor neque vitae. Eros in cursus turpis massa tincidunt. Sit amet consectetur adipiscing elit duis tristique sollicitudin nibh sit. Risus commodo viverra maecenas accumsan lacus vel.
+
+In hac habitasse platea dictumst quisque sagittis purus sit amet. Ipsum faucibus vitae aliquet nec ullamcorper sit amet risus. Ac turpis egestas maecenas pharetra convallis posuere. Dui vivamus arcu felis bibendum ut tristique et egestas quis. Ipsum dolor sit amet consectetur adipiscing elit duis tristique. Et magnis dis parturient montes nascetur ridiculus mus mauris vitae. Nunc vel risus commodo viverra maecenas accumsan lacus. Condimentum lacinia quis vel eros donec ac odio. Sit amet mattis vulputate enim nulla aliquet porttitor. Ultricies mi eget mauris pharetra et ultrices neque ornare. Porta non pulvinar neque laoreet suspendisse interdum consectetur libero.
+
+Erat imperdiet sed euismod nisi porta lorem mollis aliquam. Tincidunt arcu non sodales neque sodales ut etiam sit amet. Posuere urna nec tincidunt praesent semper. Posuere sollicitudin aliquam ultrices sagittis orci a scelerisque purus semper. In dictum non consectetur a erat nam at. Faucibus pulvinar elementum integer enim neque volutpat ac tincidunt vitae. Euismod lacinia at quis risus sed vulputate odio ut enim. Tempor commodo ullamcorper a lacus vestibulum sed arcu non. Amet tellus cras adipiscing enim eu turpis egestas. Suspendisse potenti nullam ac tortor. Sit amet commodo nulla facilisi nullam vehicula ipsum a arcu. Mattis molestie a iaculis at erat. Non tellus orci ac auctor augue mauris augue.
+
+Suspendisse faucibus interdum posuere lorem ipsum dolor. Quam id leo in vitae turpis massa sed elementum. Malesuada proin libero nunc consequat interdum varius sit. Amet venenatis urna cursus eget. Egestas congue quisque egestas diam in. Sed elementum tempus egestas sed sed risus pretium quam. Commodo odio aenean sed adipiscing diam donec adipiscing. Mauris rhoncus aenean vel elit scelerisque mauris pellentesque pulvinar pellentesque. Sit amet nulla facilisi morbi tempus. Ut aliquam purus sit amet luctus. Id velit ut tortor pretium viverra. In hac habitasse platea dictumst quisque sagittis purus sit amet. Diam in arcu cursus euismod quis viverra. A arcu cursus vitae congue mauris rhoncus aenean vel elit. Nunc sed blandit libero volutpat sed cras ornare. Commodo quis imperdiet massa tincidunt nunc pulvinar sapien et. Aliquam vestibulum morbi blandit cursus risus at ultrices. Tellus elementum sagittis vitae et. Eleifend quam adipiscing vitae proin.
+
+Nullam non nisi est sit amet facilisis magna. Parturient montes nascetur ridiculus mus mauris. Augue ut lectus arcu bibendum at varius vel pharetra vel. Placerat orci nulla pellentesque dignissim enim sit amet venenatis. Sed lectus vestibulum mattis ullamcorper. Sit amet nulla facilisi morbi tempus iaculis urna. Amet massa vitae tortor condimentum lacinia. Volutpat maecenas volutpat blandit aliquam etiam. At urna condimentum mattis pellentesque id. Enim sit amet venenatis urna cursus eget nunc scelerisque. Sed nisi lacus sed viverra tellus in. Proin libero nunc consequat interdum varius sit amet mattis. Vulputate ut pharetra sit amet. Scelerisque eleifend donec pretium vulputate sapien nec. Quam pellentesque nec nam aliquam sem et tortor consequat. Massa massa ultricies mi quis hendrerit. A pellentesque sit amet porttitor eget dolor. Malesuada bibendum arcu vitae elementum.
+
+Sit amet volutpat consequat mauris. Eu feugiat pretium nibh ipsum consequat nisl. Pharetra et ultrices neque ornare aenean euismod elementum nisi. Vel risus commodo viverra maecenas accumsan lacus vel. Amet nulla facilisi morbi tempus iaculis urna id volutpat. Malesuada proin libero nunc consequat interdum varius sit. Laoreet id donec ultrices tincidunt arcu non. Non pulvinar neque laoreet suspendisse. Et netus et malesuada fames ac. Vel elit scelerisque mauris pellentesque pulvinar. Congue nisi vitae suscipit tellus mauris a diam maecenas. Duis tristique sollicitudin nibh sit. Cursus vitae congue mauris rhoncus aenean vel elit. Viverra maecenas accumsan lacus vel facilisis volutpat est velit egestas.
+
+Mauris augue neque gravida in fermentum et. Cras pulvinar mattis nunc sed. Suspendisse ultrices gravida dictum fusce ut placerat orci. Urna et pharetra pharetra massa massa ultricies mi quis. Pulvinar sapien et ligula ullamcorper malesuada proin libero. Nec feugiat nisl pretium fusce id. Semper risus in hendrerit gravida. Cursus metus aliquam eleifend mi in nulla. Consectetur purus ut faucibus pulvinar elementum integer enim neque volutpat. Id cursus metus aliquam eleifend mi in nulla posuere sollicitudin. Adipiscing commodo elit at imperdiet dui accumsan. Eget nunc scelerisque viverra mauris in aliquam sem fringilla. Volutpat diam ut venenatis tellus in metus vulputate eu. Accumsan tortor posuere ac ut. Augue mauris augue neque gravida in fermentum et sollicitudin.
+
+Fringilla est ullamcorper eget nulla facilisi etiam dignissim diam quis. Ut tortor pretium viverra suspendisse potenti nullam. Ut porttitor leo a diam sollicitudin tempor id eu nisl. Proin libero nunc consequat interdum varius sit amet. Praesent tristique magna sit amet purus gravida. Magna fringilla urna porttitor rhoncus dolor purus. Elit ullamcorper dignissim cras tincidunt lobortis feugiat vivamus at augue. Sit amet est placerat in egestas erat imperdiet sed euismod. Tellus cras adipiscing enim eu turpis egestas pretium. Pretium viverra suspendisse potenti nullam ac tortor vitae. Arcu ac tortor dignissim convallis aenean et tortor. Fermentum leo vel orci porta. Eu sem integer vitae justo eget. Ut diam quam nulla porttitor massa id neque. Ultrices gravida dictum fusce ut placerat orci nulla pellentesque. Sed adipiscing diam donec adipiscing tristique risus. Faucibus ornare suspendisse sed nisi lacus sed viverra tellus in. Rutrum quisque non tellus orci. Malesuada fames ac turpis egestas integer eget. Viverra tellus in hac habitasse platea dictumst vestibulum.
+
+Faucibus et molestie ac feugiat sed lectus vestibulum mattis ullamcorper. Fames ac turpis egestas maecenas pharetra convallis posuere morbi. Risus quis varius quam quisque id diam vel quam elementum. Sagittis id consectetur purus ut faucibus. Blandit volutpat maecenas volutpat blandit aliquam etiam. Ut ornare lectus sit amet. Id venenatis a condimentum vitae sapien pellentesque. Consequat interdum varius sit amet mattis vulputate enim. Ut pharetra sit amet aliquam. Ac felis donec et odio pellentesque diam volutpat commodo sed. Vivamus at augue eget arcu dictum. Dictum sit amet justo donec. Nisi vitae suscipit tellus mauris.
+
+Elementum nibh tellus molestie nunc non. Mollis nunc sed id semper risus in. Pharetra magna ac placerat vestibulum lectus mauris ultrices eros in. Volutpat maecenas volutpat blandit aliquam etiam. Donec ultrices tincidunt arcu non sodales neque sodales ut etiam. Tortor id aliquet lectus proin. Vitae et leo duis ut diam quam nulla porttitor massa. Quis ipsum suspendisse ultrices gravida dictum fusce ut. Proin libero nunc consequat interdum varius sit. Nunc faucibus a pellentesque sit amet porttitor eget dolor morbi. Eu volutpat odio facilisis mauris sit. Mi sit amet mauris commodo quis imperdiet massa.
+
+Sem integer vitae justo eget magna fermentum iaculis. Dui id ornare arcu odio ut sem nulla pharetra. Risus in hendrerit gravida rutrum quisque. Volutpat diam ut venenatis tellus in. Enim facilisis gravida neque convallis a. Enim eu turpis egestas pretium aenean. At risus viverra adipiscing at in tellus integer feugiat scelerisque. Consequat nisl vel pretium lectus quam id leo in vitae. Felis imperdiet proin fermentum leo vel orci. Quis commodo odio aenean sed adipiscing diam. Adipiscing elit duis tristique sollicitudin. Vel pharetra vel turpis nunc. A pellentesque sit amet porttitor eget dolor. Arcu bibendum at varius vel pharetra vel turpis nunc eget. Ac orci phasellus egestas tellus rutrum tellus. Vel risus commodo viverra maecenas accumsan lacus vel facilisis volutpat.
+
+Vel risus commodo viverra maecenas accumsan lacus vel facilisis volutpat. Tincidunt nunc pulvinar sapien et ligula. Amet nisl purus in mollis nunc sed id. Sit amet nulla facilisi morbi tempus. Fermentum iaculis eu non diam. Purus sit amet luctus venenatis lectus magna fringilla urna porttitor. Molestie at elementum eu facilisis. Ut venenatis tellus in metus vulputate. Eu augue ut lectus arcu bibendum at varius vel. Orci sagittis eu volutpat odio facilisis mauris. Id leo in vitae turpis massa sed elementum. Quisque id diam vel quam elementum pulvinar etiam non quam. Mattis molestie a iaculis at erat pellentesque adipiscing commodo elit. Sed elementum tempus egestas sed sed risus pretium. Donec pretium vulputate sapien nec sagittis aliquam malesuada bibendum arcu. Tortor condimentum lacinia quis vel eros donec. In massa tempor nec feugiat nisl pretium fusce. Ut porttitor leo a diam sollicitudin tempor. Morbi blandit cursus risus at ultrices mi tempus. Eget mauris pharetra et ultrices neque ornare.
+
+Pellentesque habitant morbi tristique senectus et netus et. Diam phasellus vestibulum lorem sed risus ultricies tristique nulla aliquet. Tempor orci eu lobortis elementum nibh tellus molestie nunc. Interdum consectetur libero id faucibus nisl tincidunt eget nullam. Posuere morbi leo urna molestie at elementum. Amet aliquam id diam maecenas ultricies mi eget mauris pharetra. Commodo quis imperdiet massa tincidunt. Dignissim diam quis enim lobortis scelerisque. Placerat orci nulla pellentesque dignissim enim sit. Posuere ac ut consequat semper viverra nam. Tristique sollicitudin nibh sit amet commodo.
+
+Ac feugiat sed lectus vestibulum mattis ullamcorper velit. Adipiscing enim eu turpis egestas pretium aenean pharetra magna ac. Egestas sed sed risus pretium quam vulputate dignissim. Pellentesque massa placerat duis ultricies lacus sed turpis. Semper viverra nam libero justo laoreet. Sed egestas egestas fringilla phasellus faucibus scelerisque eleifend. Nulla porttitor massa id neque aliquam vestibulum morbi blandit cursus. Ac tortor vitae purus faucibus ornare. Ac placerat vestibulum lectus mauris. Volutpat est velit egestas dui id ornare. Etiam tempor orci eu lobortis elementum. Massa sed elementum tempus egestas sed sed risus pretium. Commodo quis imperdiet massa tincidunt.
+
+Dolor sit amet consectetur adipiscing elit. Nulla at volutpat diam ut. Id velit ut tortor pretium viverra suspendisse. Ipsum dolor sit amet consectetur adipiscing elit. Varius morbi enim nunc faucibus a pellentesque. Dolor sit amet consectetur adipiscing elit ut aliquam purus sit. Orci a scelerisque purus semper eget duis at tellus. Egestas purus viverra accumsan in nisl. Purus sit amet luctus venenatis lectus magna fringilla. Pretium vulputate sapien nec sagittis aliquam malesuada bibendum. Mattis rhoncus urna neque viverra justo. Vulputate sapien nec sagittis aliquam malesuada bibendum arcu vitae elementum. Tincidunt tortor aliquam nulla facilisi cras fermentum odio eu feugiat. Leo urna molestie at elementum eu. Mattis aliquam faucibus purus in. Id porta nibh venenatis cras sed felis eget. Nisl purus in mollis nunc sed id. Velit egestas dui id ornare arcu odio. Tincidunt eget nullam non nisi est. Augue ut lectus arcu bibendum at.
+
+Et ultrices neque ornare aenean euismod elementum nisi. Nibh ipsum consequat nisl vel pretium. Diam maecenas sed enim ut sem viverra aliquet eget sit. Vitae proin sagittis nisl rhoncus mattis rhoncus urna neque viverra. Nisl rhoncus mattis rhoncus urna. Nec nam aliquam sem et tortor. Nisi est sit amet facilisis magna etiam tempor orci eu. Imperdiet proin fermentum leo vel orci. Dui sapien eget mi proin sed. Volutpat odio facilisis mauris sit amet massa vitae. A lacus vestibulum sed arcu non odio euismod. At lectus urna duis convallis convallis. Lectus sit amet est placerat in egestas. Egestas dui id ornare arcu odio ut sem nulla pharetra. Purus in mollis nunc sed id semper risus. Laoreet sit amet cursus sit. Mi proin sed libero enim sed faucibus turpis in. Ipsum dolor sit amet consectetur adipiscing elit ut aliquam. Sed risus ultricies tristique nulla aliquet enim tortor at. Congue eu consequat ac felis donec et odio pellentesque diam.
+
+Pellentesque habitant morbi tristique senectus. Sit amet luctus venenatis lectus magna fringilla. Sed risus ultricies tristique nulla aliquet enim tortor. Posuere sollicitudin aliquam ultrices sagittis orci a scelerisque purus. Sit amet venenatis urna cursus eget nunc. Eget felis eget nunc lobortis mattis aliquam faucibus purus in. Pretium aenean pharetra magna ac placerat vestibulum lectus mauris. Diam vel quam elementum pulvinar etiam non quam lacus. Rhoncus urna neque viverra justo nec ultrices dui sapien. Tellus id interdum velit laoreet id donec ultrices tincidunt arcu. Turpis massa sed elementum tempus egestas sed sed risus. Sit amet mattis vulputate enim nulla aliquet porttitor lacus. At quis risus sed vulputate. Pellentesque nec nam aliquam sem et tortor consequat id porta. Sed velit dignissim sodales ut eu. Rhoncus urna neque viverra justo. Ac turpis egestas sed tempus urna et.
+
+Risus sed vulputate odio ut. Diam in arcu cursus euismod. Ac turpis egestas maecenas pharetra convallis posuere morbi. Ac turpis egestas maecenas pharetra convallis. Risus feugiat in ante metus. Mattis molestie a iaculis at erat pellentesque adipiscing. Magna etiam tempor orci eu lobortis elementum. Purus sit amet luctus venenatis lectus magna fringilla urna. Morbi tempus iaculis urna id volutpat lacus laoreet non curabitur. Sagittis vitae et leo duis ut diam quam. Lectus quam id leo in vitae turpis massa sed elementum. Augue mauris augue neque gravida in. Ac ut consequat semper viverra nam. Tristique et egestas quis ipsum suspendisse ultrices gravida. Id neque aliquam vestibulum morbi blandit cursus risus. Dignissim cras tincidunt lobortis feugiat vivamus. Eu facilisis sed odio morbi quis commodo odio aenean. Nunc sed blandit libero volutpat sed cras ornare arcu. Neque volutpat ac tincidunt vitae semper quis lectus.
+
+Dignissim enim sit amet venenatis urna cursus eget nunc. Rutrum quisque non tellus orci ac auctor augue mauris augue. Amet est placerat in egestas erat. Massa tempor nec feugiat nisl pretium. Integer feugiat scelerisque varius morbi enim nunc. Massa enim nec dui nunc. Nulla facilisi cras fermentum odio eu feugiat pretium. Ac placerat vestibulum lectus mauris ultrices eros. Amet tellus cras adipiscing enim eu turpis. In nisl nisi scelerisque eu ultrices vitae auctor eu augue. Sollicitudin ac orci phasellus egestas tellus rutrum tellus pellentesque eu. Ac auctor augue mauris augue neque gravida in fermentum et. In arcu cursus euismod quis viverra nibh. Non consectetur a erat nam at lectus urna duis convallis. Amet nulla facilisi morbi tempus iaculis urna. Fermentum leo vel orci porta non pulvinar neque laoreet suspendisse. Arcu cursus euismod quis viverra nibh. Sed risus ultricies tristique nulla aliquet enim tortor at auctor. Cursus sit amet dictum sit amet justo. Lacus vestibulum sed arcu non odio.
+
+Consectetur adipiscing elit ut aliquam purus. Elit eget gravida cum sociis natoque penatibus et magnis dis. Ut porttitor leo a diam sollicitudin tempor id eu. Faucibus turpis in eu mi bibendum neque egestas congue. Proin fermentum leo vel orci porta non pulvinar neque. Id velit ut tortor pretium viverra suspendisse potenti nullam ac. Eu ultrices vitae auctor eu augue ut. Tincidunt tortor aliquam nulla facilisi cras. Nunc id cursus metus aliquam eleifend. Consequat id porta nibh venenatis cras sed felis. Aliquet enim tortor at auctor. Tristique senectus et netus et malesuada. Aliquet porttitor lacus luctus accumsan tortor posuere ac. Egestas congue quisque egestas diam in. Sed faucibus turpis in eu mi bibendum neque. Ut faucibus pulvinar elementum integer enim neque volutpat.
+
+Laoreet non curabitur gravida arcu ac tortor dignissim convallis. At risus viverra adipiscing at in tellus. Morbi non arcu risus quis varius quam quisque id diam. Cras adipiscing enim eu turpis. Integer feugiat scelerisque varius morbi enim nunc. Phasellus vestibulum lorem sed risus ultricies. A iaculis at erat pellentesque adipiscing commodo elit at. Mauris vitae ultricies leo integer malesuada nunc vel. Ultricies integer quis auctor elit sed vulputate mi sit. Id porta nibh venenatis cras sed. Mi in nulla posuere sollicitudin aliquam. Nulla facilisi morbi tempus iaculis urna id volutpat lacus laoreet. Egestas congue quisque egestas diam in. Lectus magna fringilla urna porttitor rhoncus dolor purus non enim. Nibh tortor id aliquet lectus proin nibh. Pretium lectus quam id leo in vitae turpis massa. Dictum fusce ut placerat orci nulla pellentesque dignissim enim. Amet luctus venenatis lectus magna fringilla urna porttitor.
+
+Egestas purus viverra accumsan in nisl. Nibh tellus molestie nunc non blandit massa. Metus aliquam eleifend mi in nulla. Ultrices mi tempus imperdiet nulla malesuada. Turpis in eu mi bibendum neque egestas congue quisque egestas. Morbi enim nunc faucibus a pellentesque. Auctor urna nunc id cursus. Vitae auctor eu augue ut lectus arcu bibendum at. Faucibus vitae aliquet nec ullamcorper sit amet risus nullam eget. Tristique et egestas quis ipsum suspendisse. Mattis aliquam faucibus purus in massa tempor. Sit amet facilisis magna etiam tempor orci eu.
+
+Porttitor rhoncus dolor purus non. Lacus luctus accumsan tortor posuere. Malesuada bibendum arcu vitae elementum curabitur vitae. Nibh sit amet commodo nulla facilisi. Dictumst quisque sagittis purus sit amet volutpat consequat mauris. Est placerat in egestas erat imperdiet sed euismod nisi porta. Ut etiam sit amet nisl. Montes nascetur ridiculus mus mauris vitae ultricies leo. Neque vitae tempus quam pellentesque nec nam. Luctus venenatis lectus magna fringilla urna porttitor rhoncus dolor.
+
+Malesuada proin libero nunc consequat interdum varius sit. Donec massa sapien faucibus et. Ut tristique et egestas quis ipsum. Diam ut venenatis tellus in metus. Leo urna molestie at elementum eu facilisis sed odio morbi. Est ullamcorper eget nulla facilisi etiam. Et egestas quis ipsum suspendisse ultrices gravida dictum fusce. Congue mauris rhoncus aenean vel elit scelerisque mauris pellentesque. Adipiscing elit duis tristique sollicitudin nibh sit amet. Lectus urna duis convallis convallis tellus id interdum. Integer feugiat scelerisque varius morbi enim nunc faucibus a pellentesque. Ac felis donec et odio pellentesque diam volutpat commodo. Dui faucibus in ornare quam viverra orci sagittis eu. Senectus et netus et malesuada. Amet risus nullam eget felis eget. Accumsan in nisl nisi scelerisque eu ultrices vitae auctor. Ut tristique et egestas quis ipsum suspendisse ultrices gravida. Nibh mauris cursus mattis molestie a iaculis at.
+
+Venenatis cras sed felis eget velit. Vitae congue eu consequat ac felis donec et. At augue eget arcu dictum varius duis at consectetur lorem. Justo eget magna fermentum iaculis eu non diam phasellus. Netus et malesuada fames ac turpis. Mi bibendum neque egestas congue quisque. Vel risus commodo viverra maecenas accumsan lacus vel. Est ullamcorper eget nulla facilisi. Facilisi nullam vehicula ipsum a arcu. Nisi est sit amet facilisis magna. Adipiscing tristique risus nec feugiat in fermentum posuere. Ultrices eros in cursus turpis. Dolor purus non enim praesent elementum facilisis. Viverra nam libero justo laoreet sit amet. Arcu vitae elementum curabitur vitae.
+
+Diam ut venenatis tellus in metus vulputate. Fermentum dui faucibus in ornare quam viverra orci sagittis. Id semper risus in hendrerit. Magna sit amet purus gravida quis blandit turpis cursus in. Enim ut tellus elementum sagittis vitae et leo. Pharetra convallis posuere morbi leo urna molestie. Nunc congue nisi vitae suscipit tellus. Quis hendrerit dolor magna eget est lorem ipsum. Tortor condimentum lacinia quis vel eros donec ac. Tempor orci eu lobortis elementum nibh tellus molestie nunc. Nulla pellentesque dignissim enim sit amet venenatis urna cursus. Vitae sapien pellentesque habitant morbi tristique senectus. Viverra justo nec ultrices dui sapien. Nunc scelerisque viverra mauris in aliquam sem fringilla ut. Odio aenean sed adipiscing diam donec adipiscing.
+
+Est placerat in egestas erat imperdiet sed euismod nisi. Non consectetur a erat nam at lectus urna. Mauris nunc congue nisi vitae suscipit tellus mauris a diam. Enim diam vulputate ut pharetra. Proin fermentum leo vel orci. Pellentesque habitant morbi tristique senectus et netus et. Quis ipsum suspendisse ultrices gravida dictum fusce. Nisi scelerisque eu ultrices vitae auctor. Tempor commodo ullamcorper a lacus vestibulum sed arcu non. Eget aliquet nibh praesent tristique magna. Amet facilisis magna etiam tempor. Nisi vitae suscipit tellus mauris a diam maecenas sed.
+
+Nunc aliquet bibendum enim facilisis gravida. Blandit cursus risus at ultrices mi. Tortor aliquam nulla facilisi cras fermentum odio eu feugiat pretium. Aliquet nibh praesent tristique magna sit amet. Massa placerat duis ultricies lacus sed turpis. Morbi non arcu risus quis varius quam quisque. Morbi tempus iaculis urna id. Facilisis mauris sit amet massa vitae tortor condimentum. Faucibus in ornare quam viverra orci sagittis eu volutpat odio. Vulputate dignissim suspendisse in est ante in nibh mauris. Lorem ipsum dolor sit amet consectetur adipiscing elit duis. Cras fermentum odio eu feugiat pretium nibh. Morbi blandit cursus risus at ultrices. Leo in vitae turpis massa sed elementum tempus egestas.
+
+Amet volutpat consequat mauris nunc congue nisi vitae suscipit. Nunc pulvinar sapien et ligula ullamcorper malesuada. Egestas pretium aenean pharetra magna ac. At varius vel pharetra vel turpis nunc eget lorem dolor. Etiam dignissim diam quis enim lobortis scelerisque fermentum dui faucibus. Ut tortor pretium viverra suspendisse potenti. Lacus suspendisse faucibus interdum posuere lorem ipsum dolor sit amet. Mauris pharetra et ultrices neque ornare aenean euismod elementum. Vel pretium lectus quam id leo in vitae turpis massa. Netus et malesuada fames ac turpis. Leo duis ut diam quam nulla porttitor massa id. Velit egestas dui id ornare arcu odio. Turpis massa tincidunt dui ut ornare. Enim sit amet venenatis urna cursus. Fames ac turpis egestas maecenas pharetra convallis. Pharetra massa massa ultricies mi quis hendrerit dolor magna eget. Ornare lectus sit amet est placerat in egestas erat.
+
+Ultrices gravida dictum fusce ut placerat orci nulla pellentesque. Sit amet commodo nulla facilisi nullam vehicula ipsum. Neque viverra justo nec ultrices dui. Posuere lorem ipsum dolor sit amet. Consectetur a erat nam at lectus urna duis convallis convallis. Enim nunc faucibus a pellentesque. Sed risus ultricies tristique nulla aliquet enim tortor at auctor. Blandit volutpat maecenas volutpat blandit aliquam etiam erat velit scelerisque. Maecenas sed enim ut sem viverra aliquet eget. At erat pellentesque adipiscing commodo elit at. Enim nulla aliquet porttitor lacus.
+
+Justo eget magna fermentum iaculis eu non diam phasellus. Vitae et leo duis ut diam quam nulla. Mi quis hendrerit dolor magna eget. Feugiat in fermentum posuere urna nec tincidunt praesent semper feugiat. Rhoncus dolor purus non enim praesent. Sodales ut etiam sit amet nisl. Arcu odio ut sem nulla pharetra diam. Cursus sit amet dictum sit amet justo donec enim diam. Eu facilisis sed odio morbi quis commodo odio. Placerat duis ultricies lacus sed. Ac auctor augue mauris augue neque gravida in fermentum et.
+
+Lectus magna fringilla urna porttitor rhoncus dolor. Imperdiet proin fermentum leo vel orci porta non pulvinar neque. Sem nulla pharetra diam sit amet nisl suscipit adipiscing bibendum. Amet luctus venenatis lectus magna fringilla urna porttitor rhoncus dolor. Vestibulum lorem sed risus ultricies tristique nulla aliquet enim. Consequat nisl vel pretium lectus quam id leo. Cursus sit amet dictum sit. Hendrerit dolor magna eget est lorem. Pellentesque diam volutpat commodo sed. Arcu cursus euismod quis viverra nibh. Id venenatis a condimentum vitae sapien pellentesque. Massa massa ultricies mi quis hendrerit dolor magna. Laoreet id donec ultrices tincidunt arcu non sodales neque. Sagittis orci a scelerisque purus semper. Mauris vitae ultricies leo integer malesuada. A cras semper auctor neque vitae tempus. Neque viverra justo nec ultrices dui sapien eget mi proin. Malesuada fames ac turpis egestas integer eget aliquet. Non curabitur gravida arcu ac tortor.
+
+Sed viverra ipsum nunc aliquet bibendum enim facilisis gravida neque. Venenatis lectus magna fringilla urna porttitor rhoncus dolor purus. Magnis dis parturient montes nascetur ridiculus. Egestas tellus rutrum tellus pellentesque. Volutpat consequat mauris nunc congue nisi. Ullamcorper malesuada proin libero nunc consequat. Viverra tellus in hac habitasse platea dictumst vestibulum rhoncus. Gravida neque convallis a cras semper auctor neque vitae. Sed turpis tincidunt id aliquet. Vestibulum rhoncus est pellentesque elit ullamcorper dignissim. Ut aliquam purus sit amet luctus. Velit egestas dui id ornare arcu odio ut sem nulla. Bibendum ut tristique et egestas quis. Neque vitae tempus quam pellentesque. Amet consectetur adipiscing elit ut aliquam purus sit amet. Nisi vitae suscipit tellus mauris a diam maecenas sed enim.
+
+Nulla posuere sollicitudin aliquam ultrices sagittis orci a. Tempus imperdiet nulla malesuada pellentesque elit. Fringilla urna porttitor rhoncus dolor purus non enim. Tincidunt arcu non sodales neque sodales ut. Ac placerat vestibulum lectus mauris. Venenatis cras sed felis eget. Auctor eu augue ut lectus arcu bibendum at. Arcu felis bibendum ut tristique et egestas. Elementum nibh tellus molestie nunc non. Ut venenatis tellus in metus vulputate eu scelerisque felis. Tempus iaculis urna id volutpat lacus laoreet non curabitur gravida. In ante metus dictum at tempor commodo ullamcorper a. Porttitor rhoncus dolor purus non. Dolor magna eget est lorem ipsum dolor sit. Eget nulla facilisi etiam dignissim diam quis enim. Morbi enim nunc faucibus a pellentesque. Dui ut ornare lectus sit amet est placerat. Pellentesque adipiscing commodo elit at imperdiet dui accumsan sit.
+
+Elit at imperdiet dui accumsan sit amet nulla facilisi. Lectus sit amet est placerat. Massa tempor nec feugiat nisl pretium fusce id velit ut. Ipsum suspendisse ultrices gravida dictum fusce ut placerat. Consectetur adipiscing elit duis tristique sollicitudin nibh. Velit laoreet id donec ultrices tincidunt arcu non sodales. At elementum eu facilisis sed odio morbi. At erat pellentesque adipiscing commodo elit at imperdiet. Imperdiet nulla malesuada pellentesque elit. Mattis rhoncus urna neque viverra justo nec ultrices.
+
+Venenatis urna cursus eget nunc scelerisque. Quis auctor elit sed vulputate mi sit amet mauris. Nec feugiat in fermentum posuere urna nec tincidunt praesent. At augue eget arcu dictum varius duis. Congue quisque egestas diam in arcu. Nulla facilisi cras fermentum odio eu feugiat pretium nibh ipsum. Id aliquet risus feugiat in ante metus dictum at tempor. Urna condimentum mattis pellentesque id nibh tortor id. Lectus proin nibh nisl condimentum. A scelerisque purus semper eget duis at tellus at urna. Arcu dui vivamus arcu felis bibendum ut tristique et egestas. Amet volutpat consequat mauris nunc congue nisi vitae suscipit. Varius duis at consectetur lorem donec massa. Sed vulputate odio ut enim blandit volutpat maecenas volutpat blandit. Praesent semper feugiat nibh sed pulvinar proin gravida hendrerit. Felis bibendum ut tristique et egestas quis.
+
+Pulvinar etiam non quam lacus. Lobortis feugiat vivamus at augue eget. Adipiscing enim eu turpis egestas pretium aenean. A cras semper auctor neque. Molestie nunc non blandit massa. Tincidunt augue interdum velit euismod in. Nulla aliquet porttitor lacus luctus accumsan tortor posuere ac ut. Eget lorem dolor sed viverra ipsum nunc aliquet bibendum enim. Ac tincidunt vitae semper quis lectus nulla. Leo duis ut diam quam nulla porttitor. Ultricies mi eget mauris pharetra et ultrices neque ornare aenean. Commodo nulla facilisi nullam vehicula ipsum a arcu cursus. Tortor posuere ac ut consequat semper viverra nam. Adipiscing elit ut aliquam purus sit amet luctus venenatis. Ut sem nulla pharetra diam sit. Eget duis at tellus at urna condimentum mattis.
+
+Cras semper auctor neque vitae tempus quam. Dolor sit amet consectetur adipiscing elit pellentesque habitant. Neque volutpat ac tincidunt vitae semper quis lectus. Vitae sapien pellentesque habitant morbi tristique senectus et netus. Libero nunc consequat interdum varius sit amet mattis vulputate enim. Pharetra et ultrices neque ornare aenean euismod elementum. Maecenas sed enim ut sem viverra. Consectetur a erat nam at lectus urna duis. Ac orci phasellus egestas tellus rutrum tellus pellentesque. Et malesuada fames ac turpis. Dui sapien eget mi proin sed libero enim sed. Cras adipiscing enim eu turpis egestas pretium aenean pharetra. Egestas purus viverra accumsan in nisl nisi scelerisque eu. Posuere sollicitudin aliquam ultrices sagittis. Orci nulla pellentesque dignissim enim sit amet. Diam sit amet nisl suscipit adipiscing bibendum. Nunc sed id semper risus in. Tortor pretium viverra suspendisse potenti nullam. Nec feugiat in fermentum posuere urna nec tincidunt praesent semper. Viverra vitae congue eu consequat ac felis.
+
+Massa massa ultricies mi quis hendrerit dolor magna eget. Vitae turpis massa sed elementum tempus. Dignissim sodales ut eu sem. Lacus luctus accumsan tortor posuere ac ut. Velit euismod in pellentesque massa placerat duis ultricies. Pulvinar pellentesque habitant morbi tristique senectus et netus. Condimentum mattis pellentesque id nibh tortor id aliquet lectus proin. Morbi tincidunt augue interdum velit euismod in pellentesque massa placerat. Pellentesque pulvinar pellentesque habitant morbi. Magna fermentum iaculis eu non diam. Sollicitudin tempor id eu nisl nunc mi ipsum faucibus vitae. Euismod quis viverra nibh cras pulvinar. Purus ut faucibus pulvinar elementum integer enim neque volutpat ac. Amet risus nullam eget felis.
+
+Pellentesque id nibh tortor id aliquet lectus. Eu ultrices vitae auctor eu. Ut tristique et egestas quis ipsum suspendisse. In nibh mauris cursus mattis molestie a iaculis at erat. Tincidunt augue interdum velit euismod in pellentesque massa placerat. Vestibulum mattis ullamcorper velit sed. Porttitor eget dolor morbi non arcu risus quis varius quam. In hendrerit gravida rutrum quisque non. Faucibus purus in massa tempor nec feugiat. Semper eget duis at tellus at urna condimentum mattis pellentesque. Sed vulputate mi sit amet mauris commodo quis. Nunc id cursus metus aliquam eleifend mi in. Nibh nisl condimentum id venenatis a condimentum. Neque convallis a cras semper auctor neque vitae tempus.
+
+Arcu cursus vitae congue mauris rhoncus. Vitae aliquet nec ullamcorper sit amet risus nullam eget felis. Arcu bibendum at varius vel pharetra vel turpis nunc. Id faucibus nisl tincidunt eget nullam non nisi est sit. Ac felis donec et odio. Sollicitudin tempor id eu nisl nunc mi ipsum faucibus. Metus vulputate eu scelerisque felis imperdiet proin fermentum leo vel. Sed augue lacus viverra vitae congue eu. Eget mauris pharetra et ultrices neque ornare aenean euismod elementum. Cursus turpis massa tincidunt dui. Tortor condimentum lacinia quis vel eros donec ac odio.

+ 184 - 0
packages/fcl-web/tests/integrationtests/fcgi_dump_request.pp

@@ -0,0 +1,184 @@
+program fcgi_dump_request;
+
+{$mode objfpc}{$H+}
+
+uses
+  Classes,
+  SysUtils,
+  httpDefs,
+  fpweb,
+  custweb,
+  custfcgi,
+  httpprotocol,
+  fpjson,
+  sha1;
+
+Type
+
+  { TMyCGIHandler }
+
+  TMyCGIHandler = Class(TFCgiHandler)
+  protected
+   function GetSHA1FileHash(const AFileName: string): string;
+  Public
+    procedure HandleRequest(ARequest : TRequest; AResponse : TResponse); override;
+    function DumpHeaders(ARequest: TRequest): TJSONObject;
+    function DumpContent(ARequest: TRequest): TJSONObject;
+    function DumpFiles(ARequest: TRequest): TJSONArray;
+  end;
+
+  TMyCGIApp = Class(TCustomFCgiApplication)
+  Protected
+   function InitializeWebHandler: TWebHandler; override;
+  end;
+
+var
+  WebApp: TMyCGIApp;
+
+Procedure TMyCGIHandler.HandleRequest(ARequest : Trequest; AResponse : TResponse);
+var
+  ResponseJson: TJSONObject;
+  ShouldShutdown: Boolean;
+begin
+  if not TryStrToBool(ARequest.QueryFields.Values['shutdown'], ShouldShutdown) then
+    ShouldShutdown := False;
+
+  ResponseJson := TJSONObject.Create();
+  try
+    ResponseJson.Add('headers', DumpHeaders(ARequest));
+    ResponseJson.Add('content', DumpContent(ARequest));
+    ResponseJson.Add('files', DumpFiles(ARequest));
+    if ShouldShutdown then
+      ResponseJson.Add('shutdown', True);
+    AResponse.Content := ResponseJson.AsJSON;
+  finally
+    ResponseJson.Free;
+  end;
+
+  // Usefull for testing of memory-leaks
+  if ShouldShutdown then
+    WebApp.Terminate;
+end;
+
+function TMyCGIHandler.DumpHeaders(ARequest: TRequest): TJSONObject;
+var
+  HeaderJson: TJSONObject;
+  CustomHeaderJson: TJSONObject;
+  Header: THeader;
+  i: Integer;
+begin
+  HeaderJson := TJSONObject.Create;
+  try
+    for Header := Low(Header) to High(Header) do
+      if ARequest.HeaderIsSet(Header) then
+        HeaderJson.Add(HTTPHeaderNames[Header], ARequest.GetHeader(Header));
+
+    if ARequest.CustomHeaders.Count > 0 then
+      begin
+      CustomHeaderJson := TJSONObject.Create;
+      HeaderJson.Add('custom', CustomHeaderJson);
+      for i := 0 to ARequest.CustomHeaders.Count -1 do
+        CustomHeaderJson.Add(ARequest.CustomHeaders.Names[i], ARequest.CustomHeaders.ValueFromIndex[i]);
+      end;
+
+    Result := HeaderJson;
+    HeaderJson := nil;
+  finally
+    HeaderJson.Free;
+  end;
+end;
+
+function TMyCGIHandler.DumpContent(ARequest: TRequest): TJSONObject;
+var
+  ContentJson: TJSONObject;
+  ContentFieldJson: TJSONArray;
+  i: Integer;
+begin
+  ContentJson := TJSONObject.Create;
+  try
+    if Length(ARequest.Content) > 250 then
+      ContentJson.Add('rawTrimmed', TJSONObject.Create([
+        'length', Length(ARequest.Content),
+        'start', Copy(ARequest.Content, 1, 120),
+        'end', Copy(ARequest.Content, Length(ARequest.Content)-79, 120)
+      ]))
+    else
+      ContentJson.Add('raw', ARequest.Content);
+
+    if ARequest.ContentFields.Count > 0 then
+      begin
+      ContentFieldJson := TJSONArray.Create;
+      ContentJson.Add('fields', ContentFieldJson);
+      for i := 0 to ARequest.ContentFields.Count -1 do
+        begin
+        ContentFieldJson.Add(TJSONObject.Create([
+          'name', ARequest.ContentFields.Names[i],
+          'value' , ARequest.ContentFields.ValueFromIndex[i]]));
+        end;
+      end;
+
+    Result := ContentJson;
+    ContentJson := nil;
+  finally
+    ContentJson.Free;
+  end;
+end;
+
+function TMyCGIHandler.DumpFiles(ARequest: TRequest): TJSONArray;
+var
+  FileJsonArr: TJSONArray;
+  FileJson: TJSONObject;
+  i: Integer;
+  UploadedFile: TUploadedFile;
+begin
+  FileJsonArr := TJSONArray.Create;
+  try
+    for i := 0 to ARequest.Files.Count -1 do
+      begin
+      UploadedFile := ARequest.Files.Files[i];
+      FileJson := TJSONObject.Create([
+        'filename', UploadedFile.FileName,
+        'localFillename', UploadedFile.LocalFileName,
+        'description', UploadedFile.Description,
+        'contentType', UploadedFile.ContentType,
+        'size', UploadedFile.Size,
+        'disposition', UploadedFile.Disposition,
+        'fieldname', UploadedFile.FieldName,
+        'sha1', GetSHA1FileHash(UploadedFile.LocalFileName)
+      ]);
+      FileJsonArr.Add(FileJson);
+      DeleteFile(UploadedFile.LocalFileName);
+      end;
+
+    Result := FileJsonArr;
+    FileJsonArr := nil;
+  finally
+    FileJsonArr.Free;
+  end;
+end;
+
+function TMyCGIHandler.GetSHA1FileHash(const AFileName: string): string;
+begin
+  if FileExists(AFileName) then
+    Result := SHA1Print(SHA1File(AFileName));
+end;
+
+Function TMyCGIApp.InitializeWebHandler: TWebHandler; 
+begin
+  Result:=TMyCgiHandler.Create(self);
+end;
+
+begin
+  WebApp := TMyCGIApp.Create(Nil);
+  With WebApp do
+    try
+      { Uncomment the port setting here if you want to run the
+       FastCGI application stand-alone (e.g. for NGINX) }
+      Port := 7005;
+      ProtocolOptions := [poReuseAddress];
+      Initialize;
+      Run;
+    finally
+      Free;
+    end;
+end.

+ 887 - 0
packages/fcl-web/tests/integrationtests/fcl-web_integrationtests.jmx

@@ -0,0 +1,887 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.4.1">
+  <hashTree>
+    <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
+      <stringProp name="TestPlan.comments"></stringProp>
+      <boolProp name="TestPlan.functional_mode">false</boolProp>
+      <boolProp name="TestPlan.tearDown_on_shutdown">true</boolProp>
+      <boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
+      <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
+        <collectionProp name="Arguments.arguments"/>
+      </elementProp>
+      <stringProp name="TestPlan.user_define_classpath"></stringProp>
+    </TestPlan>
+    <hashTree>
+      <Arguments guiclass="ArgumentsPanel" testclass="Arguments" testname="Local settings" enabled="true">
+        <collectionProp name="Arguments.arguments">
+          <elementProp name="host" elementType="Argument">
+            <stringProp name="Argument.name">host</stringProp>
+            <stringProp name="Argument.value">127.0.0.1</stringProp>
+            <stringProp name="Argument.metadata">=</stringProp>
+          </elementProp>
+          <elementProp name="protocol" elementType="Argument">
+            <stringProp name="Argument.name">protocol</stringProp>
+            <stringProp name="Argument.value">http</stringProp>
+            <stringProp name="Argument.metadata">=</stringProp>
+          </elementProp>
+          <elementProp name="uri" elementType="Argument">
+            <stringProp name="Argument.name">uri</stringProp>
+            <stringProp name="Argument.value">fcgi</stringProp>
+            <stringProp name="Argument.metadata">=</stringProp>
+          </elementProp>
+          <elementProp name="files_path" elementType="Argument">
+            <stringProp name="Argument.name">files_path</stringProp>
+            <stringProp name="Argument.value">${__BeanShell(import org.apache.jmeter.services.FileServer; FileServer.getFileServer().getBaseDir();)}${__BeanShell(File.separator,)}</stringProp>
+            <stringProp name="Argument.metadata">=</stringProp>
+            <stringProp name="Argument.desc">Location of the upload-files</stringProp>
+          </elementProp>
+        </collectionProp>
+      </Arguments>
+      <hashTree/>
+      <ConfigTestElement guiclass="HttpDefaultsGui" testclass="ConfigTestElement" testname="HTTP Request Defaults" enabled="true">
+        <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
+          <collectionProp name="Arguments.arguments"/>
+        </elementProp>
+        <stringProp name="HTTPSampler.domain">${host}</stringProp>
+        <stringProp name="HTTPSampler.port"></stringProp>
+        <stringProp name="HTTPSampler.protocol">${protocol}</stringProp>
+        <stringProp name="HTTPSampler.contentEncoding"></stringProp>
+        <stringProp name="HTTPSampler.path">${uri}</stringProp>
+        <stringProp name="HTTPSampler.concurrentPool">6</stringProp>
+        <stringProp name="HTTPSampler.connect_timeout"></stringProp>
+        <stringProp name="HTTPSampler.response_timeout"></stringProp>
+      </ConfigTestElement>
+      <hashTree/>
+      <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true">
+        <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
+        <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
+          <boolProp name="LoopController.continue_forever">false</boolProp>
+          <stringProp name="LoopController.loops">1</stringProp>
+        </elementProp>
+        <stringProp name="ThreadGroup.num_threads">1</stringProp>
+        <stringProp name="ThreadGroup.ramp_time">1</stringProp>
+        <boolProp name="ThreadGroup.scheduler">false</boolProp>
+        <stringProp name="ThreadGroup.duration"></stringProp>
+        <stringProp name="ThreadGroup.delay"></stringProp>
+        <boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
+      </ThreadGroup>
+      <hashTree>
+        <GenericController guiclass="LogicControllerGui" testclass="GenericController" testname="Post small file" enabled="true"/>
+        <hashTree>
+          <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true">
+            <collectionProp name="HeaderManager.headers">
+              <elementProp name="" elementType="Header">
+                <stringProp name="Header.name">Content-Type</stringProp>
+                <stringProp name="Header.value">multipart/form-data; boundary=------------------------e6d533842bd07008</stringProp>
+              </elementProp>
+            </collectionProp>
+          </HeaderManager>
+          <hashTree/>
+          <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Post small file" enabled="true">
+            <boolProp name="HTTPSampler.postBodyRaw">true</boolProp>
+            <elementProp name="HTTPsampler.Arguments" elementType="Arguments">
+              <collectionProp name="Arguments.arguments">
+                <elementProp name="" elementType="HTTPArgument">
+                  <boolProp name="HTTPArgument.always_encode">false</boolProp>
+                  <stringProp name="Argument.value">--------------------------e6d533842bd07008&#xd;
+Content-Disposition: form-data; name=&quot;upload&quot;; filename=&quot;UploadFileSmall.txt&quot;&#xd;
+Content-Type: text/plain&#xd;
+&#xd;
+Small&#xd;
+&#xd;
+--------------------------e6d533842bd07008--</stringProp>
+                  <stringProp name="Argument.metadata">=</stringProp>
+                </elementProp>
+              </collectionProp>
+            </elementProp>
+            <stringProp name="HTTPSampler.domain"></stringProp>
+            <stringProp name="HTTPSampler.port"></stringProp>
+            <stringProp name="HTTPSampler.protocol"></stringProp>
+            <stringProp name="HTTPSampler.contentEncoding"></stringProp>
+            <stringProp name="HTTPSampler.path"></stringProp>
+            <stringProp name="HTTPSampler.method">POST</stringProp>
+            <boolProp name="HTTPSampler.follow_redirects">false</boolProp>
+            <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
+            <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
+            <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
+            <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
+            <stringProp name="HTTPSampler.connect_timeout"></stringProp>
+            <stringProp name="HTTPSampler.response_timeout"></stringProp>
+          </HTTPSamplerProxy>
+          <hashTree>
+            <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+              <stringProp name="JSON_PATH">$.files[0].size</stringProp>
+              <stringProp name="EXPECTED_VALUE">7</stringProp>
+              <boolProp name="JSONVALIDATION">true</boolProp>
+              <boolProp name="EXPECT_NULL">false</boolProp>
+              <boolProp name="INVERT">false</boolProp>
+              <boolProp name="ISREGEX">false</boolProp>
+            </JSONPathAssertion>
+            <hashTree/>
+            <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+              <stringProp name="JSON_PATH">$.files[0].sha1</stringProp>
+              <stringProp name="EXPECTED_VALUE">d9ce7590765717c47c737add2ac11e0665eabbea</stringProp>
+              <boolProp name="JSONVALIDATION">true</boolProp>
+              <boolProp name="EXPECT_NULL">false</boolProp>
+              <boolProp name="INVERT">false</boolProp>
+              <boolProp name="ISREGEX">false</boolProp>
+            </JSONPathAssertion>
+            <hashTree/>
+            <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+              <stringProp name="JSON_PATH">$.files[0].contentType</stringProp>
+              <stringProp name="EXPECTED_VALUE">text/plain</stringProp>
+              <boolProp name="JSONVALIDATION">true</boolProp>
+              <boolProp name="EXPECT_NULL">false</boolProp>
+              <boolProp name="INVERT">false</boolProp>
+              <boolProp name="ISREGEX">false</boolProp>
+            </JSONPathAssertion>
+            <hashTree/>
+            <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+              <stringProp name="JSON_PATH">$.files[0].fieldname</stringProp>
+              <stringProp name="EXPECTED_VALUE">upload</stringProp>
+              <boolProp name="JSONVALIDATION">true</boolProp>
+              <boolProp name="EXPECT_NULL">false</boolProp>
+              <boolProp name="INVERT">false</boolProp>
+              <boolProp name="ISREGEX">false</boolProp>
+            </JSONPathAssertion>
+            <hashTree/>
+            <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+              <stringProp name="JSON_PATH">$.files[0].filename</stringProp>
+              <stringProp name="EXPECTED_VALUE">UploadFileSmall.txt</stringProp>
+              <boolProp name="JSONVALIDATION">true</boolProp>
+              <boolProp name="EXPECT_NULL">false</boolProp>
+              <boolProp name="INVERT">false</boolProp>
+              <boolProp name="ISREGEX">false</boolProp>
+            </JSONPathAssertion>
+            <hashTree/>
+            <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+              <stringProp name="JSON_PATH">$.content.raw</stringProp>
+              <stringProp name="EXPECTED_VALUE"></stringProp>
+              <boolProp name="JSONVALIDATION">true</boolProp>
+              <boolProp name="EXPECT_NULL">false</boolProp>
+              <boolProp name="INVERT">false</boolProp>
+              <boolProp name="ISREGEX">false</boolProp>
+            </JSONPathAssertion>
+            <hashTree/>
+          </hashTree>
+          <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Post small file with preamble" enabled="true">
+            <boolProp name="HTTPSampler.postBodyRaw">true</boolProp>
+            <elementProp name="HTTPsampler.Arguments" elementType="Arguments">
+              <collectionProp name="Arguments.arguments">
+                <elementProp name="" elementType="HTTPArgument">
+                  <boolProp name="HTTPArgument.always_encode">false</boolProp>
+                  <stringProp name="Argument.value">This is a message with multiple parts in MIME format.&#xd;
+--------------------------e6d533842bd07008&#xd;
+Content-Disposition: form-data; name=&quot;upload&quot;; filename=&quot;UploadFileSmall.txt&quot;&#xd;
+Content-Type: text/plain&#xd;
+&#xd;
+Small&#xd;
+&#xd;
+--------------------------e6d533842bd07008--</stringProp>
+                  <stringProp name="Argument.metadata">=</stringProp>
+                </elementProp>
+              </collectionProp>
+            </elementProp>
+            <stringProp name="HTTPSampler.domain"></stringProp>
+            <stringProp name="HTTPSampler.port"></stringProp>
+            <stringProp name="HTTPSampler.protocol"></stringProp>
+            <stringProp name="HTTPSampler.contentEncoding"></stringProp>
+            <stringProp name="HTTPSampler.path"></stringProp>
+            <stringProp name="HTTPSampler.method">POST</stringProp>
+            <boolProp name="HTTPSampler.follow_redirects">false</boolProp>
+            <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
+            <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
+            <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
+            <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
+            <stringProp name="HTTPSampler.connect_timeout"></stringProp>
+            <stringProp name="HTTPSampler.response_timeout"></stringProp>
+          </HTTPSamplerProxy>
+          <hashTree>
+            <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+              <stringProp name="JSON_PATH">$.files[0].size</stringProp>
+              <stringProp name="EXPECTED_VALUE">7</stringProp>
+              <boolProp name="JSONVALIDATION">true</boolProp>
+              <boolProp name="EXPECT_NULL">false</boolProp>
+              <boolProp name="INVERT">false</boolProp>
+              <boolProp name="ISREGEX">false</boolProp>
+            </JSONPathAssertion>
+            <hashTree/>
+            <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+              <stringProp name="JSON_PATH">$.files[0].sha1</stringProp>
+              <stringProp name="EXPECTED_VALUE">d9ce7590765717c47c737add2ac11e0665eabbea</stringProp>
+              <boolProp name="JSONVALIDATION">true</boolProp>
+              <boolProp name="EXPECT_NULL">false</boolProp>
+              <boolProp name="INVERT">false</boolProp>
+              <boolProp name="ISREGEX">false</boolProp>
+            </JSONPathAssertion>
+            <hashTree/>
+            <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+              <stringProp name="JSON_PATH">$.files[0].contentType</stringProp>
+              <stringProp name="EXPECTED_VALUE">text/plain</stringProp>
+              <boolProp name="JSONVALIDATION">true</boolProp>
+              <boolProp name="EXPECT_NULL">false</boolProp>
+              <boolProp name="INVERT">false</boolProp>
+              <boolProp name="ISREGEX">false</boolProp>
+            </JSONPathAssertion>
+            <hashTree/>
+            <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+              <stringProp name="JSON_PATH">$.files[0].fieldname</stringProp>
+              <stringProp name="EXPECTED_VALUE">upload</stringProp>
+              <boolProp name="JSONVALIDATION">true</boolProp>
+              <boolProp name="EXPECT_NULL">false</boolProp>
+              <boolProp name="INVERT">false</boolProp>
+              <boolProp name="ISREGEX">false</boolProp>
+            </JSONPathAssertion>
+            <hashTree/>
+            <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+              <stringProp name="JSON_PATH">$.files[0].filename</stringProp>
+              <stringProp name="EXPECTED_VALUE">UploadFileSmall.txt</stringProp>
+              <boolProp name="JSONVALIDATION">true</boolProp>
+              <boolProp name="EXPECT_NULL">false</boolProp>
+              <boolProp name="INVERT">false</boolProp>
+              <boolProp name="ISREGEX">false</boolProp>
+            </JSONPathAssertion>
+            <hashTree/>
+            <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+              <stringProp name="JSON_PATH">$.content.raw</stringProp>
+              <stringProp name="EXPECTED_VALUE">This is a message with multiple parts in MIME format.</stringProp>
+              <boolProp name="JSONVALIDATION">true</boolProp>
+              <boolProp name="EXPECT_NULL">false</boolProp>
+              <boolProp name="INVERT">false</boolProp>
+              <boolProp name="ISREGEX">false</boolProp>
+            </JSONPathAssertion>
+            <hashTree/>
+          </hashTree>
+        </hashTree>
+        <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Post UploadFile1.txt" enabled="true">
+          <elementProp name="HTTPsampler.Files" elementType="HTTPFileArgs">
+            <collectionProp name="HTTPFileArgs.files">
+              <elementProp name="${files_path}/UploadFile1.txt" elementType="HTTPFileArg">
+                <stringProp name="File.path">${files_path}/UploadFile1.txt</stringProp>
+                <stringProp name="File.paramname">upload</stringProp>
+                <stringProp name="File.mimetype">text/plain</stringProp>
+              </elementProp>
+            </collectionProp>
+          </elementProp>
+          <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
+            <collectionProp name="Arguments.arguments"/>
+          </elementProp>
+          <stringProp name="HTTPSampler.domain"></stringProp>
+          <stringProp name="HTTPSampler.port"></stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
+          <stringProp name="HTTPSampler.path"></stringProp>
+          <stringProp name="HTTPSampler.method">POST</stringProp>
+          <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
+          <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
+          <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
+          <boolProp name="HTTPSampler.DO_MULTIPART_POST">true</boolProp>
+          <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
+          <stringProp name="HTTPSampler.connect_timeout"></stringProp>
+          <stringProp name="HTTPSampler.response_timeout"></stringProp>
+        </HTTPSamplerProxy>
+        <hashTree>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[0].sha1</stringProp>
+            <stringProp name="EXPECTED_VALUE">3752bdd4053e56cc7a22ccc66b887cae20299171</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[0].size</stringProp>
+            <stringProp name="EXPECTED_VALUE">860</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[0].contentType</stringProp>
+            <stringProp name="EXPECTED_VALUE">text/plain</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[0].filename</stringProp>
+            <stringProp name="EXPECTED_VALUE">UploadFile1.txt</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[0].fieldname</stringProp>
+            <stringProp name="EXPECTED_VALUE">upload</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+        </hashTree>
+        <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Post UploadFile2.txt" enabled="true">
+          <elementProp name="HTTPsampler.Files" elementType="HTTPFileArgs">
+            <collectionProp name="HTTPFileArgs.files">
+              <elementProp name="${files_path}/UploadFile2.txt" elementType="HTTPFileArg">
+                <stringProp name="File.path">${files_path}/UploadFile2.txt</stringProp>
+                <stringProp name="File.paramname">upload</stringProp>
+                <stringProp name="File.mimetype">text/plain</stringProp>
+              </elementProp>
+            </collectionProp>
+          </elementProp>
+          <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
+            <collectionProp name="Arguments.arguments"/>
+          </elementProp>
+          <stringProp name="HTTPSampler.domain"></stringProp>
+          <stringProp name="HTTPSampler.port"></stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
+          <stringProp name="HTTPSampler.path"></stringProp>
+          <stringProp name="HTTPSampler.method">POST</stringProp>
+          <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
+          <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
+          <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
+          <boolProp name="HTTPSampler.DO_MULTIPART_POST">true</boolProp>
+          <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
+          <stringProp name="HTTPSampler.connect_timeout"></stringProp>
+          <stringProp name="HTTPSampler.response_timeout"></stringProp>
+        </HTTPSamplerProxy>
+        <hashTree>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[0].sha1</stringProp>
+            <stringProp name="EXPECTED_VALUE">7f125c999a6e0f78434d52f6658664e8de40b1c0</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[0].size</stringProp>
+            <stringProp name="EXPECTED_VALUE">1418</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[0].contentType</stringProp>
+            <stringProp name="EXPECTED_VALUE">text/plain</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[0].filename</stringProp>
+            <stringProp name="EXPECTED_VALUE">UploadFile2.txt</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[0].fieldname</stringProp>
+            <stringProp name="EXPECTED_VALUE">upload</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+        </hashTree>
+        <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Post UploadFile3.txt" enabled="true">
+          <elementProp name="HTTPsampler.Files" elementType="HTTPFileArgs">
+            <collectionProp name="HTTPFileArgs.files">
+              <elementProp name="${files_path}/UploadFile3.txt" elementType="HTTPFileArg">
+                <stringProp name="File.path">${files_path}/UploadFile3.txt</stringProp>
+                <stringProp name="File.paramname">upload</stringProp>
+                <stringProp name="File.mimetype">text/plain</stringProp>
+              </elementProp>
+            </collectionProp>
+          </elementProp>
+          <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
+            <collectionProp name="Arguments.arguments"/>
+          </elementProp>
+          <stringProp name="HTTPSampler.domain"></stringProp>
+          <stringProp name="HTTPSampler.port"></stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
+          <stringProp name="HTTPSampler.path"></stringProp>
+          <stringProp name="HTTPSampler.method">POST</stringProp>
+          <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
+          <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
+          <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
+          <boolProp name="HTTPSampler.DO_MULTIPART_POST">true</boolProp>
+          <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
+          <stringProp name="HTTPSampler.connect_timeout"></stringProp>
+          <stringProp name="HTTPSampler.response_timeout"></stringProp>
+        </HTTPSamplerProxy>
+        <hashTree>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[0].sha1</stringProp>
+            <stringProp name="EXPECTED_VALUE">a074ac7a91209126796b4cae95e31ada7e58b5c0</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[0].size</stringProp>
+            <stringProp name="EXPECTED_VALUE">77756</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[0].contentType</stringProp>
+            <stringProp name="EXPECTED_VALUE">text/plain</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[0].filename</stringProp>
+            <stringProp name="EXPECTED_VALUE">UploadFile3.txt</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[0].fieldname</stringProp>
+            <stringProp name="EXPECTED_VALUE">upload</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+        </hashTree>
+        <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Post UploadFile1.txt multiple times" enabled="true">
+          <elementProp name="HTTPsampler.Files" elementType="HTTPFileArgs">
+            <collectionProp name="HTTPFileArgs.files">
+              <elementProp name="${files_path}/UploadFile1.txt" elementType="HTTPFileArg">
+                <stringProp name="File.path">${files_path}/UploadFile1.txt</stringProp>
+                <stringProp name="File.paramname">upload1</stringProp>
+                <stringProp name="File.mimetype">text/plain</stringProp>
+              </elementProp>
+              <elementProp name="${files_path}/UploadFile1.txt" elementType="HTTPFileArg">
+                <stringProp name="File.path">${files_path}/UploadFile1.txt</stringProp>
+                <stringProp name="File.paramname">upload2</stringProp>
+                <stringProp name="File.mimetype">text/plain</stringProp>
+              </elementProp>
+              <elementProp name="${files_path}/UploadFile1.txt" elementType="HTTPFileArg">
+                <stringProp name="File.path">${files_path}/UploadFile1.txt</stringProp>
+                <stringProp name="File.paramname">upload3</stringProp>
+                <stringProp name="File.mimetype">text/plain</stringProp>
+              </elementProp>
+              <elementProp name="${files_path}/UploadFile1.txt" elementType="HTTPFileArg">
+                <stringProp name="File.path">${files_path}/UploadFile1.txt</stringProp>
+                <stringProp name="File.paramname">upload4</stringProp>
+                <stringProp name="File.mimetype">text/plain</stringProp>
+              </elementProp>
+            </collectionProp>
+          </elementProp>
+          <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
+            <collectionProp name="Arguments.arguments"/>
+          </elementProp>
+          <stringProp name="HTTPSampler.domain"></stringProp>
+          <stringProp name="HTTPSampler.port"></stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
+          <stringProp name="HTTPSampler.path"></stringProp>
+          <stringProp name="HTTPSampler.method">POST</stringProp>
+          <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
+          <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
+          <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
+          <boolProp name="HTTPSampler.DO_MULTIPART_POST">true</boolProp>
+          <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
+          <stringProp name="HTTPSampler.connect_timeout"></stringProp>
+          <stringProp name="HTTPSampler.response_timeout"></stringProp>
+        </HTTPSamplerProxy>
+        <hashTree>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[0].sha1</stringProp>
+            <stringProp name="EXPECTED_VALUE">3752bdd4053e56cc7a22ccc66b887cae20299171</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[2].sha1</stringProp>
+            <stringProp name="EXPECTED_VALUE">3752bdd4053e56cc7a22ccc66b887cae20299171</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[3].sha1</stringProp>
+            <stringProp name="EXPECTED_VALUE">3752bdd4053e56cc7a22ccc66b887cae20299171</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[1].sha1</stringProp>
+            <stringProp name="EXPECTED_VALUE">3752bdd4053e56cc7a22ccc66b887cae20299171</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[3].size</stringProp>
+            <stringProp name="EXPECTED_VALUE">860</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[0].size</stringProp>
+            <stringProp name="EXPECTED_VALUE">860</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[0].contentType</stringProp>
+            <stringProp name="EXPECTED_VALUE">text/plain</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[0].filename</stringProp>
+            <stringProp name="EXPECTED_VALUE">UploadFile1.txt</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[3].fieldname</stringProp>
+            <stringProp name="EXPECTED_VALUE">upload1</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+        </hashTree>
+        <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Post UploadFile1.txt in combination with field" enabled="true">
+          <elementProp name="HTTPsampler.Files" elementType="HTTPFileArgs">
+            <collectionProp name="HTTPFileArgs.files">
+              <elementProp name="${files_path}/UploadFile1.txt" elementType="HTTPFileArg">
+                <stringProp name="File.path">${files_path}/UploadFile1.txt</stringProp>
+                <stringProp name="File.paramname">upload</stringProp>
+                <stringProp name="File.mimetype">text/plain</stringProp>
+              </elementProp>
+            </collectionProp>
+          </elementProp>
+          <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
+            <collectionProp name="Arguments.arguments">
+              <elementProp name="Param1" elementType="HTTPArgument">
+                <boolProp name="HTTPArgument.always_encode">false</boolProp>
+                <stringProp name="Argument.value">Value1</stringProp>
+                <stringProp name="Argument.metadata">=</stringProp>
+                <boolProp name="HTTPArgument.use_equals">true</boolProp>
+                <stringProp name="Argument.name">Param1</stringProp>
+              </elementProp>
+            </collectionProp>
+          </elementProp>
+          <stringProp name="HTTPSampler.domain"></stringProp>
+          <stringProp name="HTTPSampler.port"></stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
+          <stringProp name="HTTPSampler.path"></stringProp>
+          <stringProp name="HTTPSampler.method">POST</stringProp>
+          <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
+          <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
+          <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
+          <boolProp name="HTTPSampler.DO_MULTIPART_POST">true</boolProp>
+          <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
+          <stringProp name="HTTPSampler.connect_timeout"></stringProp>
+          <stringProp name="HTTPSampler.response_timeout"></stringProp>
+        </HTTPSamplerProxy>
+        <hashTree>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[0].sha1</stringProp>
+            <stringProp name="EXPECTED_VALUE">3752bdd4053e56cc7a22ccc66b887cae20299171</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[0].size</stringProp>
+            <stringProp name="EXPECTED_VALUE">860</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[0].contentType</stringProp>
+            <stringProp name="EXPECTED_VALUE">text/plain</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[0].filename</stringProp>
+            <stringProp name="EXPECTED_VALUE">UploadFile1.txt</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.files[0].fieldname</stringProp>
+            <stringProp name="EXPECTED_VALUE">upload</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.content.fields[1].name</stringProp>
+            <stringProp name="EXPECTED_VALUE">Param1</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.content.fields[1].value</stringProp>
+            <stringProp name="EXPECTED_VALUE">Value1</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+        </hashTree>
+        <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Post urlencoded" enabled="true">
+          <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
+            <collectionProp name="Arguments.arguments">
+              <elementProp name="Param1" elementType="HTTPArgument">
+                <boolProp name="HTTPArgument.always_encode">true</boolProp>
+                <stringProp name="Argument.value">Value1</stringProp>
+                <stringProp name="Argument.metadata">=</stringProp>
+                <boolProp name="HTTPArgument.use_equals">true</boolProp>
+                <stringProp name="Argument.name">Param1</stringProp>
+              </elementProp>
+            </collectionProp>
+          </elementProp>
+          <stringProp name="HTTPSampler.domain"></stringProp>
+          <stringProp name="HTTPSampler.port"></stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
+          <stringProp name="HTTPSampler.path"></stringProp>
+          <stringProp name="HTTPSampler.method">POST</stringProp>
+          <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
+          <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
+          <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
+          <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
+          <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
+          <stringProp name="HTTPSampler.connect_timeout"></stringProp>
+          <stringProp name="HTTPSampler.response_timeout"></stringProp>
+        </HTTPSamplerProxy>
+        <hashTree>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.content.fields[0].name</stringProp>
+            <stringProp name="EXPECTED_VALUE">Param1</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.content.fields[0].value</stringProp>
+            <stringProp name="EXPECTED_VALUE">Value1</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.content.raw</stringProp>
+            <stringProp name="EXPECTED_VALUE"></stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+        </hashTree>
+      </hashTree>
+      <PostThreadGroup guiclass="PostThreadGroupGui" testclass="PostThreadGroup" testname="tearDown Thread Group" enabled="true">
+        <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
+        <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
+          <boolProp name="LoopController.continue_forever">false</boolProp>
+          <stringProp name="LoopController.loops">1</stringProp>
+        </elementProp>
+        <stringProp name="ThreadGroup.num_threads">1</stringProp>
+        <stringProp name="ThreadGroup.ramp_time">1</stringProp>
+        <boolProp name="ThreadGroup.scheduler">false</boolProp>
+        <stringProp name="ThreadGroup.duration"></stringProp>
+        <stringProp name="ThreadGroup.delay"></stringProp>
+        <boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
+      </PostThreadGroup>
+      <hashTree>
+        <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Request shutdown (check for memory leaks manually)" enabled="true">
+          <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
+            <collectionProp name="Arguments.arguments">
+              <elementProp name="shutdown" elementType="HTTPArgument">
+                <boolProp name="HTTPArgument.always_encode">true</boolProp>
+                <stringProp name="Argument.value">true</stringProp>
+                <stringProp name="Argument.metadata">=</stringProp>
+                <boolProp name="HTTPArgument.use_equals">true</boolProp>
+                <stringProp name="Argument.name">shutdown</stringProp>
+              </elementProp>
+            </collectionProp>
+          </elementProp>
+          <stringProp name="HTTPSampler.domain"></stringProp>
+          <stringProp name="HTTPSampler.port"></stringProp>
+          <stringProp name="HTTPSampler.protocol"></stringProp>
+          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
+          <stringProp name="HTTPSampler.path"></stringProp>
+          <stringProp name="HTTPSampler.method">GET</stringProp>
+          <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
+          <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
+          <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
+          <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
+          <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
+          <stringProp name="HTTPSampler.connect_timeout"></stringProp>
+          <stringProp name="HTTPSampler.response_timeout"></stringProp>
+        </HTTPSamplerProxy>
+        <hashTree>
+          <JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion" enabled="true">
+            <stringProp name="JSON_PATH">$.shutdown</stringProp>
+            <stringProp name="EXPECTED_VALUE">true</stringProp>
+            <boolProp name="JSONVALIDATION">true</boolProp>
+            <boolProp name="EXPECT_NULL">false</boolProp>
+            <boolProp name="INVERT">false</boolProp>
+            <boolProp name="ISREGEX">false</boolProp>
+          </JSONPathAssertion>
+          <hashTree/>
+        </hashTree>
+      </hashTree>
+      <ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true">
+        <boolProp name="ResultCollector.error_logging">false</boolProp>
+        <objProp>
+          <name>saveConfig</name>
+          <value class="SampleSaveConfiguration">
+            <time>true</time>
+            <latency>true</latency>
+            <timestamp>true</timestamp>
+            <success>true</success>
+            <label>true</label>
+            <code>true</code>
+            <message>true</message>
+            <threadName>true</threadName>
+            <dataType>true</dataType>
+            <encoding>false</encoding>
+            <assertions>true</assertions>
+            <subresults>true</subresults>
+            <responseData>false</responseData>
+            <samplerData>false</samplerData>
+            <xml>false</xml>
+            <fieldNames>true</fieldNames>
+            <responseHeaders>false</responseHeaders>
+            <requestHeaders>false</requestHeaders>
+            <responseDataOnError>false</responseDataOnError>
+            <saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
+            <assertionsResultsToSave>0</assertionsResultsToSave>
+            <bytes>true</bytes>
+            <sentBytes>true</sentBytes>
+            <url>true</url>
+            <threadCounts>true</threadCounts>
+            <idleTime>true</idleTime>
+            <connectTime>true</connectTime>
+          </value>
+        </objProp>
+        <stringProp name="filename"></stringProp>
+      </ResultCollector>
+      <hashTree/>
+      <ResultCollector guiclass="SummaryReport" testclass="ResultCollector" testname="Summary Report" enabled="true">
+        <boolProp name="ResultCollector.error_logging">false</boolProp>
+        <objProp>
+          <name>saveConfig</name>
+          <value class="SampleSaveConfiguration">
+            <time>true</time>
+            <latency>true</latency>
+            <timestamp>true</timestamp>
+            <success>true</success>
+            <label>true</label>
+            <code>true</code>
+            <message>true</message>
+            <threadName>true</threadName>
+            <dataType>true</dataType>
+            <encoding>false</encoding>
+            <assertions>true</assertions>
+            <subresults>true</subresults>
+            <responseData>false</responseData>
+            <samplerData>false</samplerData>
+            <xml>false</xml>
+            <fieldNames>true</fieldNames>
+            <responseHeaders>false</responseHeaders>
+            <requestHeaders>false</requestHeaders>
+            <responseDataOnError>false</responseDataOnError>
+            <saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
+            <assertionsResultsToSave>0</assertionsResultsToSave>
+            <bytes>true</bytes>
+            <sentBytes>true</sentBytes>
+            <url>true</url>
+            <threadCounts>true</threadCounts>
+            <idleTime>true</idleTime>
+            <connectTime>true</connectTime>
+          </value>
+        </objProp>
+        <stringProp name="filename"></stringProp>
+      </ResultCollector>
+      <hashTree/>
+    </hashTree>
+  </hashTree>
+</jmeterTestPlan>