Keith Willis wrote: > 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.
It's probably stable unless posted data size exceeds receive buffer size. Also the MemoryManager should be instantiated once (on application start), and memory allocated by the MemoryManager should be freed by the manager. In my sample below I use malloc and free (stdlib.h) which is most likely slower than proper use of MemoryManager. {code} class TMyHttpConnection : public THttpConnection { public: char *PostedDataBuffer; // Will hold dynamically allocated buffer int PostedDataSize; // Databuffer size int DataLen; // Keep track of received byte count. public: virtual __fastcall ~TMyHttpConnection(); }; //--- // We need to override parent class destructor because we have allocated // memory for our data buffer. __fastcall TMyHttpConnection::~TMyHttpConnection() { if (PostedDataBuffer != NULL) { free(PostedDataBuffer); PostedDataBuffer = NULL; } } //--------------------------------------------------------------------------- [..] void __fastcall TWebServForm::HttpServer1PostDocument( TObject *Sender, TObject *Client, THttpGetFlag &Flags) { TMyHttpConnection* ClientCnx = (TMyHttpConnection*)Client; // We only accept data for '/post.bin' if (CompareText(ClientCnx->Path, "/post.bin") == 0) { // Tell HTTP server that we will accept posted data // OnPostedData event will be triggered when data comes in Flags = hgAcceptData; // We want to receive any data type. So we turn line mode off ClientCnx->LineMode = false; // We need a buffer to store posted data. We allocate as much as the // size of posted data plus one byte for the terminating nul char // since we expect just a few bytes posted in this sample. // We should also check for ContentLength = 0 and handle this case... if (ClientCnx->PostedDataSize < ClientCnx->RequestContentLength + 1) { if (ClientCnx->PostedDataBuffer) free(ClientCnx->PostedDataBuffer); ClientCnx->PostedDataBuffer = (char*)malloc(ClientCnx->RequestContentLength + 1); if (ClientCnx->PostedDataBuffer) ClientCnx->PostedDataSize = ClientCnx->RequestContentLength + 1; else { ClientCnx->PostedDataSize = 0; // ERROR! } } // Clear received length ClientCnx->DataLen = 0; } else Flags = hg404; } //--------------------------------------------------------------------------- void __fastcall TWebServForm::HttpServer1PostedData( TObject *Sender, TObject *Client, WORD Error) { int Len, Remains; char Junk [1024]; THttpGetFlag Dummy = hgSendDoc; TMyHttpConnection* ClientCnx = (TMyHttpConnection*)Client; Remains = ClientCnx->RequestContentLength - ClientCnx->DataLen; // We MUST receive any data and throw away the garbage! if (Remains <= 0) { ClientCnx->Receive(&Junk, sizeof(Junk)); return; } Len = ClientCnx->Receive(&ClientCnx->PostedDataBuffer[ClientCnx->DataLen], Remains); if (Len <= 0) return; ClientCnx->DataLen += Len; // Everything received? If true, let's process the stuff if (ClientCnx->DataLen == ClientCnx->RequestContentLength) { // First we must tell the component that we've got all the data ClientCnx->PostedDataReceived(); // Do something with the received data, here we just display, we expect // just short text data in this demo! ClientCnx->PostedDataBuffer[ClientCnx->DataLen] = 0; Display(ClientCnx->PostedDataBuffer); // Send the response ClientCnx->AnswerString(Dummy, "", // Default Status '200 OK' "", // Default Content-Type: text/html "", // Default header "<HTML><HEAD>" "<TITLE>ICS WebServer POST Demo</TITLE>" "</HEAD><BODY>" "<H1>Your data has been recorded</H1>" "</BODY></HTML>\r\n"); } } //--------------------------------------------------------------------------- {code} -- Arno Garrels -- 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