コード例 #1
0
PRBool HttpResponse::processResponse()
{
    RecvBuf buf(_socket, 1024);

    try
	{
        char tmp[1024];
        char ch;
        int index;
        PRBool doneParsing = PR_FALSE;
        char name[1024], value[1024];
        PRBool atEOL = PR_FALSE;
        PRBool inName = PR_TRUE;

        // Get protocol string
        index = 0;
        while ( !isspace(ch = buf.getChar()) )
            tmp[index++] = ch;
        tmp[index] = '\0';
        _protocol = strdup(tmp);

        // Get status num
        index = 0;
        while ( !isspace(ch = buf.getChar()) )
            tmp[index++] = ch;
        tmp[index] = '\0';
        _statusNum = strdup(tmp);
		retcode=atoi(tmp);

        // Get status string
        if (ch != '\r')
		{
            index = 0;
            while ( (ch = buf.getChar()) != '\r' ) 
                tmp[index++] = ch;
            tmp[index] = '\0';
            _statusString = strdup(tmp);
        } ;

        // Skip CRLF
        (void)buf.getChar();

        // loop over response headers
        index = 0;
        while (!doneParsing)
		{
            ch = buf.getChar();
            switch(ch)
			{
                case ':':
                      if (inName)
					  {
                          name[index] = '\0';
                          index = 0;
                          inName = PR_FALSE;

                          // skip whitespace
                          while( isspace(ch = buf.getChar()) );
                          value[index++] = ch;
                      }
					  else
					  {
                          value[index++] = ch;
                      };
                      break;
                case '\r':
                      if (inName && !atEOL)
					  {
                           Logger::logError(LOGERROR, "name without value header");
                           return PR_FALSE;
                      };
                      break;
                case '\n':
                      if (atEOL)
					  {
                          doneParsing = PR_TRUE;
                          break;
                      };
                      if (inName)
					  {
                           Logger::logError(LOGERROR, "name without value header");
                           return PR_FALSE;
                      };
                      value[index] = '\0';
                      index = 0;
                      inName = PR_TRUE;
                      _headers.insert((void *)name, (void *)strdup(value));
                      atEOL = PR_TRUE;
                      break;
                default:
                    atEOL = PR_FALSE;
                    if (inName)
                         name[index++] = ch;
                    else
                         value[index++] = ch;
                    break;
            };
        };


    }
	catch (RecvBuf::EndOfFile &)
	{
        if (!_request->isHangupOk())
            Logger::logError(LOGERROR, "Received unexpected end of file from server");
        return PR_FALSE;
    }

    // Read the body (HEAD requests don't have bodies)
    // jpierre 1xx, 204 and 304 don't have bodies either
    if ( 
		strcmp(_request->getMethod(), "HEAD") &&
		(!((retcode>=100) && (retcode<200))) &&
		(retcode!=204) &&
		(retcode!=304)
		)
	{
        if (_handleBody(buf) == PR_FALSE)
            return PR_FALSE;
    }

    if (checkConnection() && !checkKeepAlive())
	{
        // if connection is still open, and we didn't expect a keepalive,
        // read another byte to see if the connection has closed.
        try
		{
            char ch;
            ch = buf.getChar();
            buf.putBack();
            // conflict!
            Logger::logError(LOGERROR, "connection kept alive when it shouldn't");
        }
		catch (RecvBuf::EndOfFile &)
		{
            _connectionClosed = 1;
        };
    };

    _checkResponseSanity();

    return PR_TRUE;
};
コード例 #2
0
ファイル: ixpc_main.c プロジェクト: lanian09/mysource
/*------------------------------------------------------------------------------
* - ixpc는 application process들이 시스템 내부 및 다른 시스템에 있는 다른 application으로
*	메시지를 전송할 수 있도록 메시지를 routing해주는 기능을 담당한다.
* - 다른 시스템으로 routing을 위해 다른 시스템에 있는 ixpc와 tcp로 접속한다.
* - 자신의 message queue에 들어온 메시지의 destination 정보를 확인하여 시스템 내부에
*	있는 application으로 routing하는 경우 해당 application의 message queue에 메시지를
*	기록한다.
* - 다른 시스템에 있는 application으로 routing하는 경우에는 해당 시스템으로 연결된
*	socket fd로 전달하여, remote에 있는 ixpc가 해당 application의 message queue를
*	통해 전달할 수 있도록 한다.
* - ixpc간 접속은 초기기동시 자신이 bind port를 열고 remote ixpc로 접속한다.
*	접속되지 않는 경우 일정 시간마다 재접속을 시도한다.
* - 자신과 remote의 ixpc 모두 서로서로 연결하므로, 자신이 remote로 접속한 connection과
*	remote에서 접속해온 connection이 각각 존재한다. 단, 자신이 접속한 fd는 송신용으로,
*	remote에서 접속해온 fd는 수신용으로 사용된다.
* - 어떠한 원인에서 든 routing되지 못한 메시지는 즉시 폐기되며, error log를 남긴다. 
* - 일정기간 동안 송신할 메시지가 없으면 connection check를 위해 ixpc간 정해진
*	dummy 메시지를 보낸다. 정상적인 상태에서는 서로서로 송신 port에 대해 check 메시지를
*	보내므로 수신 port에 일정기간 이상 수신된 메시지가 없으면 remote ixpc가 hangup
*	되었다고 판단하고 송수신 port를 모두 강제로 끊는다.
* - remote ixpc 상태와 무관하게 LAN Cable의 이상 등으로 인한 통신장애를 감지하기 위해
*	주기적으로 ping test를 하고 접속되지 않으면 송수신 port를 모두 강제로 끊는다.
* - 메시지큐로 통신하는 경우 모든 메시지에 long형의 mtype이 반드시 포함되는데, 시스템마다
*	long이 4 또는 8byte로 다르다. 이를 고려하지 않고 그대로 socket을 통해 보내면 메시지가
*	제대로 읽혀지지 않는 문제가 발생한다. 이를 위해 다른 시스템으로 routing하는 경우
*	메시지큐에서 읽은 데이터중 long형인 mtype을 떼어내 socket header에 4byte로 변환하여
*	넣어서 보내고, 수신측에서 다시 떼어내 자신에 맞는 long형으로 변환하여 메시지큐로
*	보낸다.
------------------------------------------------------------------------------*/
int main (int ac, char *av[])
{
	GeneralQMsgType	rxGenQMsg;
	SockLibMsgType	rxSockMsg;
	int		ret, actFd; 
// 07.17 jjinri	int check_Index;
	time_t		prev;

//  	if((check_Index = check_my_run_status("IXPC")) < 0)
 //  		exit(0);

	if (ixpc_initial() < 0) {
		fprintf(stderr,">>>>>> ixpc_initial fail\n");
		return -1;
	}

	/* clear previous queue messages
	*/
	while (msgrcv(ixpcQid, &rxGenQMsg, sizeof(rxGenQMsg), 0, IPC_NOWAIT) > 0);

	prev = currentTime;
	while (1)
	{
		/* remote 시스템들과 연결된 socket port들을 확인하여 메시지를 처리한다.
		*/
		ret = socklib_action ((char*)&rxSockMsg, &actFd);

if (ret != 0)
//printf ("OMP HERE0 ret=%d\n", ret);

		switch (ret)
		{
			case SOCKLIB_NEW_CONNECTION:
				ixpc_newConnEvent (actFd); /* remote ixpc가 접속해온 경우 */
				break;

			case SOCKLIB_CLIENT_MSG_RECEIVED:
				ixpc_recvEventRxPort (actFd, &rxSockMsg); /* remote ixpc로부터 data를 수신한 경우 */
				break;

			case SOCKLIB_SERVER_MSG_RECEIVED:
				ixpc_recvEventTxPort (actFd); /* remote로 접속한 port로 data가 들어온 경우 */
				break;

			case SOCKLIB_CLIENT_DISCONNECTED:
				ixpc_disconnEventRxPort (actFd); /* remote ixpc가 접속해온 fd가 끊어진 경우 */
				break;

			case SOCKLIB_SERVER_DISCONNECTED:
				ixpc_disconnEventTxPort (actFd); /* remote ixpc로 접속한 fd가(송신port) 끊어진 경우 */
				break;

			case SOCKLIB_NO_EVENT:
				break;

			default:
				break;
		} /* end of socklib_action */

		/* 자신의 msgQ에 들어오는 메시지를 처리한다.
		*/
		if (msgrcv(ixpcQid, &rxGenQMsg, sizeof(rxGenQMsg), 0, IPC_NOWAIT) < 0) {
			if (errno != ENOMSG) {
				sprintf(trcBuf,"[ixpc_main] msgrcv fail; err=%d(%s)\n", errno, strerror(errno));
				return -1;
			}
		} else {
			ixpc_exeRxQMsg (&rxGenQMsg);
		}

		/*
		* - 주기적(1초)으로 sockRoutTbl을 확인하여 접속되지 못한 곳으로 재접속을 시도한다.
		* - currentTime을 update한다.
		* - 일정시간 동안 송신할 메시지가 없으면 connection check 메시지를 보낸다.
		* - 일정시간 동안 수신된 메시지가 없으면 송수신 port 모두 강제 해제한다.
		* - 주기적으로 ping test하고 접속실패시 송수신 port 모두 강제 해제한다.
		*/
//printf("size: %d\n", sizeof(int));
//		if(sockRoutTbl[0].sockRxFd)
//			socklib_sndMsg(sockRoutTbl[0].sockRxFd,buf,len);
		currentTime = time(0);
		if (prev == currentTime)
			continue;

		prev = currentTime;
		keepalivelib_increase ();
		ixpc_checkConnections ();

		/* samd process check For watch dog */
		checkKeepAlive();

	} /* end of while(1) */
	return 1;

} /** End of main **/