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; };
/*------------------------------------------------------------------------------ * - 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 **/