The error lies in your Execute method, probably as a result of copy n'
paste from the demo:
...for n := 0 to Headers.Count - 1 do
     Sock.SendString(Headers[n] + CRLF);

if the Socket is forcefully closed, your loop will hang.

Here is a modified unit which works fine no matter how many times you
press F5, in summary, you have to check the socket error after *all*
IO:

unit http;

interface

uses
  Classes, blcksock, winsock, Synautil, SysUtils, SyncObjs;

type
  TTCPHttpDaemon = class(TThread)
  private
    Sock: TTCPBlockSocket;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Execute; override;
  end;

  TTCPHttpThrd = class(TThread)
  private
    Sock: TTCPBlockSocket;
  public
    Headers: TStringList;
    InputData, OutputData: TMemoryStream;
    constructor Create(hsock: tSocket);
    destructor Destroy; override;
    procedure Execute; override;
    function ProcessHttpRequest(Request, URI: string): Integer;
  end;

procedure CWrite(const S: string);

implementation

var
  ConsoleLock: TCriticalSection;
const
  ImagePath = 'C:\Temp\serv\info.bmp';

procedure CWrite(const S: string);
begin
  ConsoleLock.Enter;
  try
    Writeln(S);
  finally
    ConsoleLock.Leave;
  end;
end;

{ TTCPHttpDaemon }

constructor TTCPHttpDaemon.Create;
begin
  Sock := TTCPBlockSocket.Create;
  FreeOnTerminate := True;
  Priority := tpNormal;
  inherited Create(False);
end;

destructor TTCPHttpDaemon.Destroy;
begin
  Sock.Free;
  inherited Destroy;
end;

procedure TTCPHttpDaemon.Execute;
var
  ClientSock: tSocket;
begin
  with Sock do
  begin
    CreateSocket;
    setLinger(True, 10000);
    bind('0.0.0.0', '80');
    listen;
    repeat
      if Terminated then Break;
      if canread(1000) and (LastError = 0) then
      begin
        ClientSock := accept;
        if LastError = 0 then TTCPHttpThrd.Create(ClientSock);
      end;
    until False;
  end;
end;

{ TTCPHttpThrd }

constructor TTCPHttpThrd.Create(hsock: tSocket);
begin
  Sock := TTCPBlockSocket.Create;
  Headers := TStringList.Create;
  InputData := TMemoryStream.Create;
  OutputData := TMemoryStream.Create;
  Sock.socket := hsock;
  FreeOnTerminate := True;
  Priority := tpNormal;
  inherited Create(False);
end;

destructor TTCPHttpThrd.Destroy;
begin
  Sock.Free;
  Headers.Free;
  InputData.Free;
  OutputData.Free;
  inherited Destroy;
end;

procedure TTCPHttpThrd.Execute;
var
  b: Byte;
  timeout: Integer;
  S: Ansistring;
  method, URI, protocol: string;
  Size: Integer;
  x, n: Integer;
  resultcode: Integer;
begin
  CWrite('Thread starting, TID: ' + IntToStr(ThreadID));
  try
    timeout := 120000;
    //read request line
    S := Sock.RecvString(timeout);
    if Sock.LastError <> 0 then
      Exit;
    if S = '' then
      Exit;
    method := fetch(S, ' ');
    if (S = '') or (method = '') then
      Exit;
    URI := fetch(S, ' ');
    if URI = '' then
      Exit;
    protocol := fetch(S, ' ');
    Headers.Clear;
    Size := -1;
    //read request headers
    if protocol <> '' then
    begin
      if Pos('HTTP/', protocol) <> 1 then
        Exit;
      repeat
        S := Sock.RecvString(timeout);
        if Sock.LastError <> 0 then
          Exit;
        if S <> '' then
          Headers.Add(S);
        if Pos('CONTENT-LENGTH:', UpperCase(S)) = 1 then
          Size := StrToIntDef(SeparateRight(S, ' '), -1);
      until S = '';
    end;
    //recv document...
    InputData.Clear;
    if Size >= 0 then
    begin
      InputData.SetSize(Size);
      x := Sock.RecvBufferEx(InputData.Memory, Size, timeout);
      InputData.SetSize(x);
      if Sock.LastError <> 0 then
        Exit;
    end;
    OutputData.Clear;
    resultcode := ProcessHttpRequest(method, URI);
    Sock.SendString('HTTP/1.0 ' + IntToStr(resultcode) + CRLF);
    if protocol <> '' then
    begin
      Headers.Add('Content-length: ' + IntToStr(OutputData.Size));
      Headers.Add('Connection: close');
      Headers.Add('Date: ' + Rfc822DateTime(now));
      Headers.Add('Server: Synapse HTTP server demo');
      Headers.Add('');
      for n := 0 to Headers.Count - 1 do
      begin
        Sock.SendString(Headers[n] + CRLF);

        if Sock.LastError <> 0 then
        begin
          CWrite('Error here by any chance?');
          break;
        end;
      end;
    end;
    if Sock.LastError <> 0 then
      Exit;
    Sock.SendBuffer(OutputData.Memory, OutputData.Size);
  finally
    CWrite('Thread exiting, TID: ' + IntToStr(ThreadID) + ' Err: ' +
      IntToStr(Sock.LastError) + ' ' + Sock.LastErrorDesc);
  end;
end;

function TTCPHttpThrd.ProcessHttpRequest(Request, URI: string): Integer;
var
  l: TStringList;
begin
  //sample of precessing HTTP request:
  // InputData is uploaded document, headers is stringlist with request headers.
  // Request is type of request and URI is URI of request
  // OutputData is document with reply, headers is stringlist with
reply headers.
  // Result is result code
  Result := 504;
  if Request = 'GET' then
  begin
    Headers.Clear;
    Headers.Add('Content-type: Text/Html');
    if (ExtractFileExt(URI) = '.html') or (ExtractFileExt(URI) = '.htm') then
    begin
      l := TStringList.Create;
      try
        l.Add('<html>');
        l.Add('<head></head>');
        l.Add('<body>');
        l.Add('Request Uri: ' + URI);
        l.Add('<br>');
        l.Add('This document is generated by Synapse HTTP server demo!<br>');
        l.Add('<img src="info.bmp" alt="x" border="2"><br/>example-1<br/>');
        l.Add('</body>');
        l.Add('</html>');
        l.SaveToStream(OutputData);
      finally
        l.Free;
      end;
      Result := 200;
    end
    else
    begin
      try
        OutputData.LoadFromFile(ImagePath); //Add path were the image is saved
        Result := 200;
      finally
      end;
    end;
  end;
end;

initialization
  begin
    ConsoleLock := TCriticalSection.Create;
  end;
finalization
  ConsoleLock.Free;
end.







On 07/02/07, Deborah <[EMAIL PROTECTED]> wrote:
> Does anybody know how to solve that problem? Wether immedeately nor
> after a timeout the thread is closed. It stays got stuck and does
> nothing anymore.
>
> CCRDude schrieb:
> >> As we said before, presing F5 in your web server abanond existing TCp
> >> connection and open new. So, depending on how good is abandoned
> >> connection closed, handling thread onserver may be closed immediately
> >> or will be cloded after some timeout.
> >>
> >>
> > If I may interrupt, how good the connection will be closed is a question
> > how good the official httpserv demo is, since her attached demo is
> > exactly that, only slightly modified to raise the likelyhood of this to
> > appear ;)
> >
> > -------------------------------------------------------------------------
> > Using Tomcat but need to do more? Need to support web services, security?
> > Get stuff done quickly with pre-integrated technology to make your job 
> > easier.
> > Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
> > http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
> > _______________________________________________
> > synalist-public mailing list
> > [email protected]
> > https://lists.sourceforge.net/lists/listinfo/synalist-public
> >
> >
>
>
> -------------------------------------------------------------------------
> Using Tomcat but need to do more? Need to support web services, security?
> Get stuff done quickly with pre-integrated technology to make your job easier.
> Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
> http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
> _______________________________________________
> synalist-public mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/synalist-public
>

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
synalist-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/synalist-public

Reply via email to