Esempio n. 1
0
void CMessageTemplate::processMacro( LPCSTR str, int len, int fill, IWriteSink & f )
{
  if ( FarSF::LStricmp( str, M_SUBJECT ) == 0 )
    processSubject( len, fill, f );
  else if ( FarSF::LStricmp( str, M_FROM ) == 0 )
    processFrom( len, fill, f );
  else if ( FarSF::LStricmp( str, M_TO ) == 0 )
    processTo( len, fill, f );
  else if ( FarSF::LStricmp( str, M_DATE ) == 0 )
    processDate( len, fill, f );
  else if ( FarSF::LStricmp( str, M_ORGANIZATION ) == 0 )
    processOrganization( len, fill, f );
  else if ( FarSF::LStricmp( str, M_MAILER ) == 0 )
    processMailer( len, fill, f );
  else if ( FarSF::LStricmp( str, M_OSUBJECT ) == 0 )
    processOSubject( len, fill, f );
  else if ( FarSF::LStricmp( str, M_MESSAGEID ) == 0 )
    processMessageId( len, fill, f );
  else if ( FarSF::LStricmp( str, M_FROM_NAME ) == 0 )
    processFromName( len, fill, f );
  else if ( FarSF::LStricmp( str, M_FROM_ADDR ) == 0 )
    processFromAddr( len, fill, f );
  else if ( FarSF::LStricmp( str, M_TO_NAME ) == 0 )
    processToName( len, fill, f );
  else if ( FarSF::LStricmp( str, M_TO_ADDR ) == 0 )
    processToAddr( len, fill, f );
  else if ( FarSF::LStricmp( str, M_SENT_DATE ) == 0 )
    processSentDate( len, fill, f );
  else if ( FarSF::LStricmp( str, M_SENT_TIME ) == 0 )
    processSentTime( len, fill, f );
  else if ( FarSF::LStricmp( str, M_RECEIVED_DATE ) == 0 )
    processReceivedDate( len, fill, f );
  else if ( FarSF::LStricmp( str, M_RECEIVED_TIME ) == 0 )
    processReceivedTime( len, fill, f );
  else if ( FarSF::LStricmp( str, M_TEXT ) == 0 )
    processText( len, f );
  else if ( FarSF::LStricmp( str, M_HEADERS ) == 0 )
    processHeaders( f );
  else if ( FarSF::LStrnicmp( str, M_KLUDGE, strlen(M_KLUDGE) ) == 0 )
  {
    str += _countof(M_KLUDGE);

    while ( *str && ( isspace( (unsigned char)*str ) || *str == '(' ||
      *str == '\"' || *str == '\'' ) ) str ++;

    if ( *str )
    {
      LPCSTR end = str + 1;

      while ( *end && !isspace( (unsigned char)*end ) && *end != ')' &&
        *end != '\"' && *end != '\'' ) end ++;

      processKludge( FarString( str, end - str ), f );
    }
  }
}
Esempio n. 2
0
boolean CmdProcessor::processLine(){
  //do a simple check to see if it looks like json
  if(input_buffer_pos > 0 && input_buffer[0] == '{' && input_buffer[input_buffer_pos - 1] == '}'){
    socketMode = RAW;
    processJSON();
    return true;
  }else if(processHeaders()){
    return true;
  }
  
  if(httpState == WEBSOCKET_READY){
    return false;
  }else{
    return true;
  }
}
Esempio n. 3
0
void WebServer::processConnection(char *buff, int *bufflen)
{
  m_client = m_server.available();

  if (m_client) {
    m_readingContent = false;
    buff[0] = 0;
    ConnectionType requestType = INVALID;
#if WEBDUINO_SERIAL_DEBUGGING > 1
    Serial.println("*** checking request ***");
#endif
    getRequest(requestType, buff, bufflen);
#if WEBDUINO_SERIAL_DEBUGGING > 1
    Serial.print("*** requestType = ");
    Serial.print((int)requestType);
    Serial.println(", request = \"");
    Serial.print(buff);
    Serial.println("\" ***");
#endif
    processHeaders();
#if WEBDUINO_SERIAL_DEBUGGING > 1
    Serial.println("*** headers complete ***");
#endif

    int urlPrefixLen = strlen(m_urlPrefix);
    if (strcmp(buff, "/robots.txt") == 0)
    {
      noRobots(requestType);
    }
    else if (requestType == INVALID ||
             strncmp(buff, m_urlPrefix, urlPrefixLen) != 0 ||
             !dispatchCommand(requestType, buff + urlPrefixLen,
                              (*bufflen) >= 0))
    {
      m_failureCmd(*this, requestType, buff, (*bufflen) >= 0);
    }

#if WEBDUINO_SERIAL_DEBUGGING > 1
    Serial.println("*** stopping connection ***");
#endif
    m_client.stop();
  }
}
Esempio n. 4
0
void WebServer::processConnection(char *buff, int *bufflen) {
	int urlPrefixLen = strlen(m_urlPrefix);

	m_client = m_server.available();

	if (m_client) {
		m_readingContent = false;
		buff[0] = 0;
		ConnectionType requestType = INVALID;
		getRequest(requestType, buff, bufflen);

		// don't even look further at invalid requests.
		// this is done to prevent Webduino from hanging
		// - when there are illegal requests,
		// - when someone contacts it through telnet rather than proper HTTP,
		// - etc.
		if (requestType != INVALID) {
			processHeaders();

			if (strcmp(buff, "/robots.txt") == 0) {
				noRobots(requestType);
			} else if (strcmp(buff, "/favicon.ico") == 0) {
				favicon(requestType);
			}
		}
		if (requestType == INVALID || strncmp(buff, m_urlPrefix, urlPrefixLen) != 0
				|| !dispatchCommand(requestType, buff + urlPrefixLen, (*bufflen) >= 0)) {
			m_failureCmd(*this, requestType, buff, (*bufflen) >= 0);
		}
		reset();
		if(this->finalCommand != NULL){
			this->finalCommand(requestType, this->currentCollection, this->currentModel);
			this->finalCommand = NULL;
		}

	}
}
Esempio n. 5
0
string Socket::receive(int sizeToReceive){ //=0 async read
	if(closed) {
		string ret=readBuffer;
		readBuffer="";
		if(ret.size()){
			syslog(LOG_INFO,"Received %lu",(long unsigned int)ret.size());
		}
		return ret;
	}
	if(header.size()==0)
		sizeToReceive = JAIL_HEADERS_SIZE_LIMIT;
	if(sizeToReceive){
		syslog(LOG_INFO,"Receiving until %d bytes",sizeToReceive);
	}
	//If already read, return data
	if(sizeToReceive>0 && readBuffer.size()>=sizeToReceive
			&& header.size()!=0){
		string ret = readBuffer.substr(0,sizeToReceive);
		readBuffer.erase(0,sizeToReceive);
		return ret;
	}
	struct pollfd devices[1];
	devices[0].fd=socket;
	devices[0].events=POLLIN;
	const int MAX=JAIL_NET_BUFFER_SIZE;
	char buf[MAX];
	const int wait=10; // 10 milisec
	const int bad=POLLERR|POLLNVAL;
	time_t timeLimit=time(NULL)+JAIL_SOCKET_TIMEOUT;
	time_t fullTimeLimit=time(NULL)+JAIL_SOCKET_REQUESTTIMEOUT;
	while(true){
		int res=poll(devices,1,wait);
		if(res==-1) {
			syslog(LOG_INFO,"poll fail reading %m");
			throw HttpException(internalServerErrorCode
					,"Error poll reading data"); //Error
		}
		time_t currentTime=time(NULL);
		if(currentTime>timeLimit || currentTime>fullTimeLimit){
			if(sizeToReceive==0){
				syslog(LOG_DEBUG,"Socket read timeout, closed connection?");
				return "";
			}else
				throw HttpException(requestTimeoutCode
						,"Socket read timeout");
		}
		if(res==0 && sizeToReceive==0) break; //Nothing to read
		if(res==0) continue; //Nothing to do
		syslog(LOG_DEBUG,"poll return: %d",res);
		if(devices[0].revents & POLLIN){ //Read from net
			int sizeRead=netRead(buf,MAX);
			if(sizeRead >0) {
				string sread(buf,sizeRead);
				if(sread.size()!=sizeRead){
					syslog(LOG_ERR,"read net decode error");
				}
				readBuffer += sread;
				if(header.size()==0){
					size_t pos;
					if((pos=readBuffer.find("\r\n\r\n")) != string::npos){
						header=readBuffer.substr(0,pos+4);
						syslog(LOG_INFO,"Received header %lu",(long unsigned int)pos+4);
						processHeaders(header);
						readBuffer.erase(0,pos+4);
						return ""; //End of process
					}else if(readBuffer.size()>JAIL_HEADERS_SIZE_LIMIT){
						throw HttpException(requestEntityTooLargeCode,"Http headers too large");
					}
				}else if(sizeToReceive==0 || readBuffer.size()>=sizeToReceive){ //Receive complete
					break;
				}
				timeLimit=currentTime+JAIL_SOCKET_TIMEOUT; //Reset timeout
			}
			else if(sizeRead<0){
				throw HttpException(badRequestCode
						,"Error reading data");
			}
			else {
				syslog(LOG_INFO,"sizeRead==0");
				closed=true;
				break;
			}
		}
		if(devices[0].revents & POLLHUP){ //socket close
			closed=true;
			syslog(LOG_INFO,"POLLHUP");
			break;
		}
		if(devices[0].revents & bad) {
			throw HttpException(internalServerErrorCode
					,"Error reading data");
		}
	}
	string ret=readBuffer;
	readBuffer="";
	if(ret.size()){
		syslog(LOG_INFO,"Received %lu",(long unsigned int)ret.size());
	}
	return ret;
}
int WebSocketHandshake::readServerHandshake(const char* header, size_t len)
{
    m_mode = Incomplete;
    if (len < sizeof(webSocketServerHandshakeHeader) - 1) {
        // Just hasn't been received fully yet.
        return -1;
    }
    if (!memcmp(header, webSocketServerHandshakeHeader, sizeof(webSocketServerHandshakeHeader) - 1))
        m_mode = Normal;
    else {
        const String& code = extractResponseCode(header, len);
        if (code.isNull()) {
            m_context->addMessage(ConsoleDestination, JSMessageSource, LogMessageType, ErrorMessageLevel, "Short server handshake: " + String(header, len), 0, clientOrigin());
            return -1;
        }
        if (code.isEmpty()) {
            m_mode = Failed;
            m_context->addMessage(ConsoleDestination, JSMessageSource, LogMessageType, ErrorMessageLevel, "No response code found: " + String(header, len), 0, clientOrigin());
            return len;
        }
        LOG(Network, "response code: %s", code.utf8().data());
        if (code == "401") {
            m_mode = Failed;
            m_context->addMessage(ConsoleDestination, JSMessageSource, LogMessageType, ErrorMessageLevel, "Authentication required, but not implemented yet.", 0, clientOrigin());
            return len;
        } else {
            m_mode = Failed;
            m_context->addMessage(ConsoleDestination, JSMessageSource, LogMessageType, ErrorMessageLevel, "Unexpected response code:" + code, 0, clientOrigin());
            return len;
        }
    }
    const char* p = header + sizeof(webSocketServerHandshakeHeader) - 1;
    const char* end = header + len + 1;

    if (m_mode == Normal) {
        size_t headerSize = end - p;
        if (headerSize < sizeof(webSocketUpgradeHeader) - 1) {
            m_mode = Incomplete;
            return 0;
        }
        if (memcmp(p, webSocketUpgradeHeader, sizeof(webSocketUpgradeHeader) - 1)) {
            m_mode = Failed;
            m_context->addMessage(ConsoleDestination, JSMessageSource, LogMessageType, ErrorMessageLevel, "Bad Upgrade header: " + String(p, end - p), 0, clientOrigin());
            return p - header + sizeof(webSocketUpgradeHeader) - 1;
        }
        p += sizeof(webSocketUpgradeHeader) - 1;

        headerSize = end - p;
        if (headerSize < sizeof(webSocketConnectionHeader) - 1) {
            m_mode = Incomplete;
            return -1;
        }
        if (memcmp(p, webSocketConnectionHeader, sizeof(webSocketConnectionHeader) - 1)) {
            m_mode = Failed;
            m_context->addMessage(ConsoleDestination, JSMessageSource, LogMessageType, ErrorMessageLevel, "Bad Connection header: " + String(p, end - p), 0, clientOrigin());
            return p - header + sizeof(webSocketConnectionHeader) - 1;
        }
        p += sizeof(webSocketConnectionHeader) - 1;
    }

    if (!strnstr(p, "\r\n\r\n", end - p)) {
        // Just hasn't been received fully yet.
        m_mode = Incomplete;
        return -1;
    }
    HTTPHeaderMap headers;
    p = readHTTPHeaders(p, end, &headers);
    if (!p) {
        LOG(Network, "readHTTPHeaders failed");
        m_mode = Failed;
        return len;
    }
    if (!processHeaders(headers)) {
        LOG(Network, "header process failed");
        m_mode = Failed;
        return p - header;
    }
    switch (m_mode) {
    case Normal:
        checkResponseHeaders();
        break;
    default:
        m_mode = Failed;
        break;
    }
    return p - header;
}
void DeferredData::processDeferredData()
{
    if (m_inProcessDeferredData)
        return;

    RecursionGuard guard(m_inProcessDeferredData);

    // Sending data to webkit causes it to be parsed and javascript executed,
    // which might cause it to cancel the job or set defersLoading again. So
    // to be safe, check this after every step.
    if (m_job.isDeferringLoading() || m_job.isCancelled())
        return;

    if (m_deferredStatusReceived) {
        m_job.handleNotifyStatusReceived(m_status, m_message);
        m_deferredStatusReceived = false;
        if (m_job.isDeferringLoading() || m_job.isCancelled())
            return;
    }

    if (!processHeaders(m_headerKeys, m_headerValues, &NetworkJob::handleNotifyHeaderReceived)
        || !processHeaders(m_multipartHeaderKeys, m_multipartheaderValues, &NetworkJob::handleNotifyMultipartHeaderReceived))
        return;

    // Only process 32k of data at a time to avoid blocking the event loop for too long.
    static const unsigned maxData = 32 * 1024;

    unsigned totalData = 0;
    while (!m_dataSegments.isEmpty()) {
        const Vector<char>& buffer = m_dataSegments.first();
        m_job.handleNotifyDataReceived(buffer.data(), buffer.size());
        totalData += buffer.size();

        if (m_job.isCancelled()) {
            // Don't bother removing segment; job will be deleted.
            return;
        }

        m_dataSegments.removeFirst();

        if (m_job.isDeferringLoading()) {
            // Stop processing until deferred loading is turned off again.
            return;
        }

        if (totalData >= maxData && !m_dataSegments.isEmpty()) {
            // Pause for now, and schedule a timer to continue after running the event loop.
            scheduleProcessDeferredData();
            return;
        }
    }

    if (m_totalBytesToBeSent) {
        m_job.handleNotifyDataSent(m_bytesSent, m_totalBytesToBeSent);
        m_bytesSent = 0;
        m_totalBytesToBeSent = 0;
    }

    if (m_deferredClose) {
        m_job.handleNotifyClose(m_deferredCloseStatus);
        m_deferredClose = false;
        if (m_job.isDeferringLoading() || m_job.isCancelled())
            return;
    }
}