void VirtuinoEsp8266_WebServer::wifiRun(){
   if(espSerial->available()){                       
    char c=espSerial->read();
    commandBuffer.concat(c);
    if (c=='\n') {                                            // check command line to line
          if (DEBUG) Serial.print(commandBuffer);
          int pos = commandBuffer.indexOf("+IPD,");
          if (pos>=0){                                        // check for GET command from Virtuino app
              clearESP_buffer(500);
              int connectionId = commandBuffer.charAt(pos+5)-48;  // get connection ID
              if (DEBUG) Serial.println("ID="+ String(connectionId));
              pos = commandBuffer.indexOf("GET /");
              if (pos!=-1){                                   // We have a GET message
                  String responce = checkNetworkCommand(commandBuffer.substring(pos+5));
                  boolean b=wifiSendData(connectionId,responce);
                  // -----------  Close client connection     -------------
                  clearESP_buffer(100);
                  closeClientConnection(connectionId);           
                    
                  
              } 
          } 
        
        commandBuffer="";                                     // clear buffer for the next line
  
      }  
    
   }
}
void ScriptEngineServer::stop()
{
	try
	{
		_stopServer = true;
		GD::bl->threadManager.join(_mainThread);
		_out.printDebug("Debug: Waiting for script engine server's client threads to finish.");
		{
			std::lock_guard<std::mutex> stateGuard(_stateMutex);
			for(std::map<int32_t, std::shared_ptr<ClientData>>::iterator i = _clients.begin(); i != _clients.end(); ++i)
			{
				closeClientConnection(i->second);
			}
		}
		while(_clients.size() > 0)
		{
			collectGarbage();
			if(_clients.size() > 0) std::this_thread::sleep_for(std::chrono::milliseconds(100));
		}
		unlink(GD::socketPath.c_str());
	}
	catch(const std::exception& ex)
	{
		_out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
	}
	catch(BaseLib::Exception& ex)
	{
		_out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
	}
	catch(...)
	{
		_out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
	}
}
Example #3
0
static void sendResponse(EXTENSION_CONTROL_BLOCK *p, HTTPResponse *resp)
{
   String *resphdrs;
   char status[128];
   int browserStatus = 0;
   DWORD len;

   p->dwHttpStatusCode = resp->status;
   sprintf(status, "%d %s",resp->status, resp->statusMsg);

   /*
    *	send the headers (collected into one buffer)
    */
   resphdrs = resp_packageHeaders(resp);
   if (resphdrs)
   {
      len = resphdrs->length;
      /* ccording to the Microsoft web site, HSE_REQ_SEND_RESPONSE_HEADER is depreciated */
      /* HSE_REQ_SEND_RESPONSE_HEADER_EX is preferred. */
      /* However, moving to HSE_REQ_SEND_RESPONSE_HEADER_EX will not work if we must support IIS 3.0. */
      if (p->ServerSupportFunction(p->ConnID, HSE_REQ_SEND_RESPONSE_HEADER,
                                   status, &len, (LPDWORD)resphdrs->text) != TRUE)
      {
         browserStatus = -1;
         WOLog(WO_ERR,"Failed to send response headers (%d)", GetLastError());
      } else {
         len = 2;
         // 2009/06/10: The 4th. parameter is only allowed to be '0' if
         //             this code would belong to a filter plugin.  But
         //             this code realizes an IIS extension and therefore
         //             only HSE_IO_SYNC and ..._ASYNC is allowed!
         if (p->WriteClient(p->ConnID, CRLF, &len, HSE_IO_SYNC) != TRUE)
         {
            browserStatus = -1;
            WOLog(WO_ERR,"Failed to send \\r\\n (%d)", GetLastError());
         }

         /* resp->content_valid will be 0 for HEAD requests and empty responses */
         if (resp->content_valid) {
            long count;
            while (resp->content_read < resp->content_length &&
                   (resp->flags & RESP_LENGTH_INVALID) != RESP_LENGTH_INVALID &&
                   browserStatus == 0) {
                len = resp->content_valid;
                // 2009/06/10: The 4th. parameter is only allowed to be '0' if
                //             this code would belong to a filter plugin.  But
                //             this code realizes an IIS extension and therefore
                //             only HSE_IO_SYNC and ..._ASYNC is allowed!
                if (len && (p->WriteClient(p->ConnID, resp->content, &len, HSE_IO_SYNC) != TRUE))
                {
                   browserStatus = -1;
                   WOLog(WO_ERR,"Failed to send content (%d)", GetLastError());
                }

                if(browserStatus == 0)
                {
                   // read next response chunk from the WebObjects application
                   count = resp_getResponseContent(resp, 1);
                   if(count > 0)
                   {
                       // 2009/06/09: handle situations where content_length is wrong or
                       //             unset.  Read as much data as possible from the
                       //             WebObjects application and send the data to the
                       //             client-side.
                      resp->content_read += count;
                      resp->content_valid = count;
                   }
                   if(count != 0)
                   {
                      // 2009/04/30: error while reading response content (this can happen
                      //             if the instance dies during sending the response - e.g.
                      //             during a file download - or if the content_length is
                      //             wrong/unset).  Stop the loop to avoid endless looping!
                      WOLog(WO_WARN, "sendResponse(): received an incomplete data package.  Please look for a dead instance or adjust content-length value.");
                   }
                }
            }
            if(browserStatus == 0)
            {
               len = resp->content_valid;
               // 2009/06/10: The 4th. parameter is only allowed to be '0' if
               //             this code would belong to a filter plugin.  But
               //             this code realizes an IIS extension and therefore
               //             only HSE_IO_SYNC and ..._ASYNC is allowed!
               if (len && (p->WriteClient(p->ConnID, resp->content, &len, HSE_IO_SYNC) != TRUE))
               {
                  browserStatus = -1;
                  WOLog(WO_ERR,"Failed to send content (%d)", GetLastError());
               }
            }
         }
      }
      str_free(resphdrs);
   } /* else? return warning */

   if(resp->content_read < resp->content_length)
   {
      // 2009/06/08: in case of an unset/wrong content length value, we
      //             must close the client socket connection to signalize
      //             the client application the end-of-stream.
      closeClientConnection(p, resp);

      if(resp->keepConnection != 0)
      {
         // 2009/04/30: it is possible, that the user (=browser) cancels the last started
         //             request.  The existing mechanism of the nbsocket.c implementation
         //             (starting a reset operation that cleans/consumes the remaining
         //             content of the socket buffer) fails sometimes in such situations.
         //             E.g. during an huge file download, the reset operation doesn't consume
         //             the complete download stream (such a behaviour would be very expensive!),
         //             but only the local socket buffer.  If such a connection is reused
         //             in another request-response-cycle, the adaptor/browser gets unexpected
         //             data garbage.  This can lead to situations, where the adaptor marks an
         //             existing and fully functional instance as death.  Therefore: dump
         //             such connections!
         WOLog(WO_INFO, "Forget the existing connection.");
         resp->keepConnection = 0;
         resp->flags |= RESP_CLOSE_CONNECTION;
         // after calling the resp_free function, the connection doesn't longer exist!
      }
   }

   return;
}
void ScriptEngineServer::readClient(std::shared_ptr<ClientData> clientData)
{
	try
	{
		int32_t bufferMax = 1024;
		char buffer[bufferMax + 1];
		std::shared_ptr<std::vector<char>> packet(new std::vector<char>());
		int32_t bytesRead;
		_out.printDebug("Debug: Listening for incoming commands from client number " + std::to_string(clientData->fileDescriptor->id) + ".");
		while(!_stopServer)
		{
			//Timeout needs to be set every time, so don't put it outside of the while loop
			timeval timeout;
			timeout.tv_sec = 2;
			timeout.tv_usec = 0;
			fd_set readFileDescriptor;
			FD_ZERO(&readFileDescriptor);
			GD::bl->fileDescriptorManager.lock();
			int32_t nfds = clientData->fileDescriptor->descriptor + 1;
			if(nfds <= 0)
			{
				GD::bl->fileDescriptorManager.unlock();
				_out.printDebug("Connection to client number " + std::to_string(clientData->fileDescriptor->id) + " closed.");
				closeClientConnection(clientData);
				return;
			}
			FD_SET(clientData->fileDescriptor->descriptor, &readFileDescriptor);
			GD::bl->fileDescriptorManager.unlock();
			bytesRead = select(nfds, &readFileDescriptor, NULL, NULL, &timeout);
			if(bytesRead == 0) continue;
			if(bytesRead != 1)
			{
				_out.printDebug("Connection to client number " + std::to_string(clientData->fileDescriptor->id) + " closed.");
				closeClientConnection(clientData);
				return;
			}

			bytesRead = read(clientData->fileDescriptor->descriptor, buffer, bufferMax);
			if(bytesRead <= 0)
			{
				_out.printDebug("Connection to client number " + std::to_string(clientData->fileDescriptor->id) + " closed.");
				closeClientConnection(clientData);
				//If we close the socket, the socket file gets deleted. We don't want that
				//GD::bl->fileDescriptorManager.close(_serverFileDescriptor);
				return;
			}

			std::string command;
			command.insert(command.end(), buffer, buffer + bytesRead);
			//handleCommand(command, clientData);
		}
		closeClientConnection(clientData);
	}
    catch(const std::exception& ex)
    {
    	_out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
    }
    catch(BaseLib::Exception& ex)
    {
    	_out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
    }
    catch(...)
    {
    	_out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
    }
}