by DmitryBogdanov » Sun Jul 15, 2012 12:23 pm
Currently, if you have HTMLForm with attachments added through HTMLForm::addPart, then you call HTMLForm::write, and then call HTMLForm::write second time - second write will not write parts' content. This is because streams used to read part content are in eof state after the first read.
User may want to write the form twice, for example, to calculate size it is going to write, and then use that size in Content-Length header. We had this need because proxy we tested our software with did not understand HTTP 1.1 and Transfer-Encoding: chunked, used by POCO when sending multipart form. Thus, we had to use HTTP 1.0, send everything in one shot (nature of our application is such that attachments are a few KB), and include Content-Length header. Of course we could reverse-engineer how POCO writes multipart form and guess what Content-Length would be, but what if in the next release of POCO something would change and our estimate will be no longer accurate? Thus, we decided to write form to a file, and use file size as source of Content-Length header of HTTPRequest. However, once we wrote form to the file, second write to ostream returned by HTTPClientSession::write did not write any attachment.
Workaround is simple, however is required modifying POCO sources.We have added one method:
for (PartVec::iterator ita = _parts.begin(); ita != _parts.end(); ++ita)
ita->pSource->stream().clear(); // need to clear eof flag
ita->pSource->stream().seekg(0, std::ios::beg); // rewind to beginning
With the help of that method called after HTMLForm::write, HTMLForm::write becomes reenterable.