Hi Arno,

> You never check PostedDataSize, the size of your receive buffer.
> The pascal demo allocates this buffer dynamically depending on the
RequestContentLength plus one byte for the null terminator in the
OnPostDocument event handler.
> What is the value of RcvdByteCount when the error happens?


I originally did it like that, but it kept crashing with AV's so I embarked
on a process of elimination of suspect code until I ended up with an
(almost) stable version where PostedDataBuffer  was statically allocated in
the class declaration.

The version I released in my original posting in this mailing list was the
penultimate iteration where I was still dynamically allocating memory, but
only once in TMyHttpConnection's constructor. This drastically simplified
version still generates AV's so I thought it would be more relevant to the
discussion.

My original code is included below for reference:



<< CODE SNIPPETS >>>
//--------------------------------------------------------------------------
-

class TMyHttpConnection : public THttpConnection
{
 public:
  char* Junk;
  char* PostedDataBuffer;     // Will hold dynamically allocated buffer
  int  PostedDataSize;        // Databuffer size
  int  RcvdByteCount;         // Keep track of received byte count.
  
 public:
  __fastcall TMyHttpConnection(Classes::TComponent* AOwner);
  virtual __fastcall ~TMyHttpConnection();
};
//--------------------------------------------------------------------------
-



//--------------------------------------------------------------------------
-
__fastcall TMyHttpConnection::TMyHttpConnection(Classes::TComponent* AOwner)
: THttpConnection(AOwner)
{
 try
 {
  Junk = new char(65536);
  PostedDataBuffer = NULL;
  PostedDataSize = 0;
 }
 catch(...) {}
}
//--------------------------------------------------------------------------
-

__fastcall TMyHttpConnection::~TMyHttpConnection()
{
 try
 {
  delete [] Junk;

  if (PostedDataBuffer != NULL)
  {
   delete [] PostedDataBuffer;
   PostedDataBuffer = NULL;
   PostedDataSize = 0;
  }
 }
 catch(...) {}
}
//--------------------------------------------------------------------------
-

void __fastcall TAegisWebServerForm::HttpServerPostDocument(TObject *Sender,
      TObject *Client, THttpGetFlag &Flags)
{
 try
 {
  TMyHttpConnection* Connection = (TMyHttpConnection*)Client;

  FCountRequests++;  // Count request and display a message

  if (CompareText(Connection->Path, "/content/home.html") == 0)    // This
page is not cached
  {
   Flags = hgAcceptData;
   Connection->LineMode = false;

   TMemoryManager* MemoryManager = new TMemoryManager();

   try
   {
    GetMemoryManager(*MemoryManager);

    if (Connection->PostedDataSize == 0)
    {
     Connection->PostedDataSize = Connection->RequestContentLength + 1;
     Connection->PostedDataBuffer =
(char*)(MemoryManager->GetMem(Connection->PostedDataSize));
    }
    else
    {
     Connection->PostedDataSize = Connection->RequestContentLength + 1;
     Connection->PostedDataBuffer =
(char*)(MemoryManager->ReallocMem(Connection->PostedDataBuffer,
Connection->PostedDataSize));
    }
   }
   __finally {delete MemoryManager;}

   Connection->RcvdByteCount = 0;
  }
 }
 catch (Exception &E)
{HandleError("TAegisWebServerForm::HttpServerPostDocument", E.Message);}
 catch (const exception &e)
{HandleError("TAegisWebServerForm::HttpServerPostDocument", e.what());}
 catch (...) {HandleError("TAegisWebServerForm::HttpServerPostDocument",
"Unknown Exception");}
}
//--------------------------------------------------------------------------
-

void __fastcall TAegisWebServerForm::HttpServerPostedData(TObject *Sender,
      TObject *Client, WORD Error)
{
 try
 {
  int Len, Remains;

  TMyHttpConnection* Connection = (TMyHttpConnection*)Client;

  Remains = Connection->RequestContentLength - Connection->RcvdByteCount;

  if (Remains <= 0)
  {
   Len = Connection->Receive(Connection->Junk, sizeof(Connection->Junk)- 1);
   if (Len >= 0) Connection->Junk[Len] = 0;
   return;
  }

//  Len = Connection->Receive(Connection->PostedDataBuffer +
Connection->RcvdByteCount, Remains);
  Len =
Connection->Receive(&(Connection->PostedDataBuffer[Connection->RcvdByteCount
]), Remains);
  if (Len <= 0) return;

  Connection->RcvdByteCount += Len;

  if (Connection->RcvdByteCount > Connection->RequestContentLength)
Connection->RcvdByteCount = Connection->RequestContentLength;

  if (Connection->RcvdByteCount == Connection->RequestContentLength)
  {
   Connection->PostedDataBuffer[Connection->RcvdByteCount] = 0;

   if (CompareText(Connection->Path, "/content/home.html") == 0)
ProcessPostedData(Connection);
//   else Connection->Answer404();  // I need to make Answer404 accessible
   else
   {
    AnsiString Body = AnsiString("<HTML><HEAD><TITLE>404 Not
Found</TITLE></HEAD><BODY><H1>404 Not Found</H1>The requested URL ") +
TextToHtmlText(Connection->Path) + " was not found on this
server.<P></BODY></HTML>\r\n";
    Connection->SendHeader(Connection->Version + " 404 Not
Found\r\nContent-Type: text/html\r\nContent-Length: " +
Utility->IntToStrEx(Body.Length()) + "\r\n\r\n");
    Connection->SendStr(Body);
   }

   Connection->PostedDataReceived();
  }
 }
 catch (Exception &E)
{HandleError("TAegisWebServerForm::HttpServerPostedData", E.Message);}
 catch (const exception &e)
{HandleError("TAegisWebServerForm::HttpServerPostedData", e.what());}
 catch (...) {HandleError("TAegisWebServerForm::HttpServerPostedData",
"Unknown Exception");}
}

-- 
To unsubscribe or change your settings for TWSocket mailing list
please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket
Visit our website at http://www.overbyte.be

Reply via email to