// should be called only after setStatus, addHeader and addContent
    void MTD_FLASHMEM HTTPResponse::flush()
    {
        // status line
        m_httpHandler->getSocket()->writeFmt(FSTR("HTTP/1.1 %s\r\n"), m_status);

        // HTTPResponse headers
        addHeader(FSTR("Connection"), FSTR("close"));			

        // user headers
        for (uint32_t i = 0; i != m_headers.getItemsCount(); ++i)
        {
            Fields::Item* item = m_headers[i];
            m_httpHandler->getSocket()->writeFmt(FSTR("%s: %s\r\n"), APtr<char>(t_strdup(item->key)).get(), APtr<char>(t_strdup(item->value)).get());
        }

        // content length header
        m_httpHandler->getSocket()->writeFmt(FSTR("%s: %d\r\n\r\n"), STR_Content_Length, m_content.getItemsCount());

        // actual content
        if (m_content.getItemsCount() > 0)
        {			
            CharChunksIterator iter = m_content.getIterator();
            CharChunkBase* chunk = iter.getCurrentChunk();
            while (chunk)
            {
                m_httpHandler->getSocket()->write((uint8_t const*)chunk->data, chunk->getItems());
                chunk = iter.moveToNextChunk();
            }
            m_content.clear();
        }
    }
// should be called only after setStatus, addHeader and addContent
void MTD_FLASHMEM HTTPResponse::flush() {
  // headers
  flushHeaders(m_content.getItemsCount());

  // actual content
  if (m_content.getItemsCount() > 0) {
    CharChunksIterator iter = m_content.getIterator();
    CharChunkBase *chunk = iter.getCurrentChunk();
    while (chunk) {
      if (m_httpHandler->getSocket()->write((uint8_t const *)chunk->data, chunk->getItems()) < 0)
        break;
      chunk = iter.moveToNextChunk();
    }
    m_content.clear();
  }
}
void MTD_FLASHMEM HTTPHandler::connectionHandler() {
  getSocket()->setTimeOut(TIMEOUT);
  while (getSocket()->isConnected()) {
    CharChunkBase *chunk = m_receivedData.addChunk(CHUNK_CAPACITY);
    int32_t bytesRecv = getSocket()->read(chunk->data, CHUNK_CAPACITY);
    if (bytesRecv <= 0)
      break;
    chunk->setItems(bytesRecv);
    if (processRequest())
      break;
  }
  m_receivedData.clear();
  m_request.query.clear();
  m_request.headers.clear();
  m_request.form.clear();
}
void MTD_FLASHMEM HTTPHandler::processXWWWFormUrlEncoded(CharChunksIterator headerEnd, int32_t contentLength) {
  // look for data (maybe POST data)
  if (contentLength > 0) {
    // download additional content
    int32_t missingBytes = headerEnd.getPosition() + contentLength - m_receivedData.getItemsCount();
    while (getSocket()->isConnected() && missingBytes > 0) {
      int32_t bytesToRead = (CHUNK_CAPACITY < missingBytes ? CHUNK_CAPACITY : missingBytes);
      CharChunkBase *chunk = m_receivedData.addChunk(bytesToRead);
      int32_t bytesRecv = getSocket()->read(chunk->data, bytesToRead);
      if (bytesRecv <= 0)
        break;
      chunk->setItems(bytesRecv);
      missingBytes -= chunk->getItems();
    }
    m_receivedData.append(0); // add additional terminating "0"

    CharChunksIterator contentStart = m_receivedData.getIterator(); // cannot use directly headerEnd because added data
    contentStart += headerEnd.getPosition();
    extractURLEncodedFields(contentStart, CharChunksIterator(), &m_request.form);
  }

  dispatch();
}