📄 osphttp.c
字号:
*ospvHttp = (OSPTHTTP *)OSPPListFirst( (OSPTLIST *)&(ospvComm->HttpConnList)); if (*ospvHttp == (OSPTHTTP *)OSPC_OSNULL) { /* no current connections */ createnew = OSPC_TRUE; } else { /* * check for idle connections. The first idle HTTP connection * will be returned. If NULL is returned, all queues are busy. */ *ospvHttp = osppHttpIdleCheck(&(ospvComm->HttpConnList), *ospvHttp); if (*ospvHttp == (OSPTHTTP *)OSPC_OSNULL) { /* * no connections are idle. All are in use */ /* * see if we can add a new one */ (void)OSPPCommGetHttpConnCount(ospvComm, &httpcount); (void)OSPPCommGetMaxConnections(ospvComm, &maxcount); if (httpcount < maxcount) { createnew = OSPC_TRUE; } else { /* * connection limit has been reached. Find the connection * with the least number of transactions in queue and use * it. */ errorcode = osppHttpMinTransCheck(&(ospvComm->HttpConnList), &(*ospvHttp), ospvComm->HttpTimeout); if ((*ospvHttp == (OSPTHTTP *)OSPC_OSNULL)||(errorcode != OSPC_ERR_NO_ERROR)) { if(errorcode == OSPC_ERR_HTTP_BAD_QUEUE) { OSPM_DBGERRORLOG(errorcode, "http msg queue corrupted"); } else { OSPM_DBGERRORLOG(errorcode, "search for connection timedout"); } } } } else { /* * check connection type. make sure it syncs up with the type of * msginfo we are about to send. */ if ((ospvMsgInfoType & OSPC_MSGINFO_AUDIT_TYPE) == 0) { if (((*ospvHttp)->Flags & OSPC_HTTP_AUDIT_TYPE) == OSPC_HTTP_AUDIT_TYPE) createnew = OSPC_TRUE; } else { if (((*ospvHttp)->Flags & OSPC_HTTP_AUDIT_TYPE) != OSPC_HTTP_AUDIT_TYPE) createnew = OSPC_TRUE; } } } if (createnew) { /* * create the new http connection object. In doing so, * setup a persistance socket to the selected Service * point */ errorcode = OSPPHttpNew(ospvComm, ospvHttp); if (errorcode == OSPC_ERR_NO_ERROR) { /* set up the connection type */ if((ospvMsgInfoType & OSPC_MSGINFO_AUDIT_TYPE) == OSPC_MSGINFO_AUDIT_TYPE) { (*ospvHttp)->Flags |= OSPC_HTTP_AUDIT_TYPE; } /* * add the new http connection object to the HttpConnList */ OSPPListAppend((OSPTLIST *)&(ospvComm->HttpConnList), (void *)*ospvHttp); (void)OSPPCommIncrementHttpConnCount(ospvComm); /* * startup the http connection monitor thread for the * new connection. */ errorcode = osppHttpStartWorker(*ospvHttp); } if (errorcode != OSPC_ERR_NO_ERROR) { errorcode = OSPC_ERR_HTTP_NEWCONN_FAILED; OSPM_DBGERRORLOG(errorcode, "new http connection failed"); } } OSPM_DBGNET(("HTTP connection: %s\n", (createnew ? "created" : "reused"))); OSPM_DBGEXIT(("EXIT : osppHttpSelectConnection\n")); return errorcode;}staticintosppHttpAddRequest( OSPTHTTP *ospvHttp, OSPTMSGINFO *ospvMsgInfo){ int errorcode = OSPC_ERR_NO_ERROR; OSPM_DBGENTER(("ENTER : osppHttpAddRequest\n")); /* * obtain the HTTP connection mutex. This could fail when * an idle HTTP connection is passed to this function and * the connection thread is in the process of closing itself * down. if this timing issue occurs, this function will return * a failure code and the calling function will attempt to add * the transaction to another HTTP connection object. */ OSPM_MUTEX_LOCK(ospvHttp->Mutex, errorcode); if (errorcode == OSPC_ERR_NO_ERROR) { OSPPListAppend((OSPTLIST *)&(ospvHttp->MsgInfoList), (void *)ospvMsgInfo); ospvHttp->NumberOfTransactions++; OSPM_MUTEX_UNLOCK(ospvHttp->Mutex, errorcode); assert(errorcode == OSPC_ERR_NO_ERROR); } OSPM_DBGEXIT(("EXIT : osppHttpAddRequest\n")); return errorcode;}intOSPPHttpRequestHandoff( OSPTCOMM *ospvComm, OSPTMSGQUEUE *ospvMsgQueue){ int errorcode = OSPC_ERR_NO_ERROR; OSPTMSGINFO *msginfo = OSPC_OSNULL; OSPTHTTP *httpconn = OSPC_OSNULL; int attempts = 0; OSPM_DBGENTER(("ENTER : OSPPHttpRequestHandoff\n")); /* * because this function is called by the Comm Msg monitor, * we currently have exclusive access to the message queue. * we need to hand-off the work as quickly as possible to avoid * creating a transaction bottleneck. */ /* * get the first msginfo item from the msg queue list */ msginfo = (OSPTMSGINFO *)OSPPListFirst( (OSPTLIST *)&(ospvMsgQueue->MsgInfoList)); if (msginfo == (OSPTMSGINFO *)OSPC_OSNULL) { errorcode = OSPC_ERR_HTTP_BAD_QUEUE; OSPM_DBGERRORLOG(errorcode, "msg queue prematurely empty"); } else { /* * Now remove the message info item from the comm * message queue */ msginfo = (OSPTMSGINFO *)OSPPListRemove( (OSPTLIST *)&(ospvMsgQueue->MsgInfoList)); if (msginfo == (OSPTMSGINFO *)OSPC_OSNULL) { errorcode = OSPC_ERR_HTTP_MALLOC_FAILED; OSPM_DBGERRORLOG(errorcode, "msg queue item delete failed"); } /* * decrement the message queue transaction count */ OSPPMsgQueueDecrementNumberOfTransactions(ospvMsgQueue); /* * try at most 3 times to get an HTTP connection object. in * almost all cases, the httpconn object will be obtained on * the first pass. however, there is a race condition between * an existing idle HTTP connection thread and the * osppHttpAddRequest thread. if osppHttpAddRequest is waiting * for an idle connection mutex and this connection in is the * process of shutting down, osppHttpAddRequest will fail. * try 2 more times to get another connection or create a * new one. The race condition will never occur when a new * HTTP connection is created. */ for (attempts = 0; attempts < 3; attempts++) { /* * determine which HTTP connection object to hand the * request off to. */ errorcode = osppHttpSelectConnection(ospvComm, &httpconn, msginfo->Flags); if (errorcode != OSPC_ERR_NO_ERROR) { msginfo->ErrorCode = OSPC_ERR_HTTP_MALLOC_FAILED; OSPM_DBGERRORLOG(msginfo->ErrorCode, "httpconn is NULL"); } else { /* * add the msginfo item to the selected HTTP connection * queue and increment the count. This is alittle tricky * because the msginfo structure is shared between the * comm message queue and the http connection queue. * The link to msginfo has been broken by the above * call to OSPPListRemove. A new link will be added for * the http connection queue. */ msginfo->ErrorCode = osppHttpAddRequest(httpconn, msginfo); if (msginfo->ErrorCode == OSPC_ERR_NO_ERROR) break; } } /* * signal the HTTP connection that a new transaction is now available * this must be done for both successful and non-successful requests */ if (msginfo->ErrorCode == OSPC_ERR_NO_ERROR) { OSPM_MUTEX_LOCK(httpconn->Mutex, errorcode); if (errorcode == OSPC_ERR_NO_ERROR) { OSPM_CONDVAR_SIGNAL(httpconn->CondVar, errorcode); assert(errorcode == OSPC_ERR_NO_ERROR); OSPM_MUTEX_UNLOCK(httpconn->Mutex, errorcode); assert(errorcode == OSPC_ERR_NO_ERROR); } } } OSPM_DBGEXIT(("EXIT : OSPPHttpRequestHandoff\n")); return errorcode;}voidOSPPHttpParseHeader( unsigned char *ospvInBuffer, unsigned char **ospvOutBuffer, unsigned *ospvLength, int ospvHeaderType, int *ospvError){ char *begptr = OSPC_OSNULL, *endptr = OSPC_OSNULL; OSPM_DBGENTER(("ENTER : OSPPHttpParseHeader\n")); switch(ospvHeaderType) { case OSPC_HTTP_CONTENT_LENGTH: /* * Parse Content-Length: */ begptr = OSPM_STRSTR((const char *)ospvInBuffer, "content-length: "); if (begptr != OSPC_OSNULL) { if ((OSPM_SSCANF(begptr + 16, "%u", ospvLength)) != 1) { *ospvError = OSPC_ERR_HTTP_BAD_HEADER_200; OSPM_DBGERRORLOG(*ospvError, "bad http header"); } else { OSPM_MALLOC(*ospvOutBuffer, unsigned char, *ospvLength + 1); if (*ospvOutBuffer == (unsigned char *)OSPC_OSNULL) { *ospvError = OSPC_ERR_HTTP_MALLOC_FAILED; OSPM_DBGERRORLOG(*ospvError, "bad http header"); } else OSPM_MEMSET(*ospvOutBuffer, 0, *ospvLength + 1); } } else { *ospvError = OSPC_ERR_HTTP_BAD_HEADER_200; OSPM_DBGERRORLOG(*ospvError, "bad http header"); } break; case OSPC_HTTP_CONTENT_TYPE: /* * Parse Content-Type: */ begptr = OSPM_STRSTR((const char*)ospvInBuffer, "content-type: "); if (begptr != OSPC_OSNULL) { endptr = OSPM_STRSTR(begptr, "\r\n"); if (endptr != OSPC_OSNULL) { *ospvLength = endptr - begptr; OSPM_MALLOC(*ospvOutBuffer, unsigned char, *ospvLength+1); if (*ospvOutBuffer != (unsigned char *)OSPC_OSNULL) { OSPM_MEMSET(*ospvOutBuffer, 0, *ospvLength+1); OSPM_MEMCPY(*ospvOutBuffer, begptr, *ospvLength); } else { *ospvError = OSPC_ERR_HTTP_MALLOC_FAILED; OSPM_DBGERRORLOG(*ospvError, "bad http header"); } } else { *ospvError = OSPC_ERR_HTTP_BAD_HEADER_200; OSPM_DBGERRORLOG(*ospvError, "bad http header"); } } else { *ospvError = OSPC_ERR_HTTP_BAD_HEADER_200; OSPM_DBGERRORLOG(*ospvError, "content-type not found\n"); } break; /* * The Connection type is optional in the header. As a result, * we do not generate an error if it does not exist. When it * does not exist, assume Connection: Keep-alive. */ case OSPC_HTTP_CONNECTION_TYPE: /* * Parse Connection: */ begptr = OSPM_STRSTR((const char *)ospvInBuffer, "connection: "); if (begptr != OSPC_OSNULL) { endptr = OSPM_STRSTR(begptr, "\r\n"); if (endptr != OSPC_OSNULL) { *ospvLength = endptr - begptr; OSPM_MALLOC(*ospvOutBuffer, unsigned char, *ospvLength+1); if (*ospvOutBuffer != (unsigned char *)OSPC_OSNULL) { OSPM_MEMSET(*ospvOutBuffer, 0, *ospvLength+1); OSPM_MEMCPY(*ospvOutBuffer, begptr, *ospvLength); } else { *ospvError = OSPC_ERR_HTTP_MALLOC_FAILED; OSPM_DBGERRORLOG(*ospvError, "bad http header"); } } else { *ospvError = OSPC_ERR_HTTP_BAD_HEADER_200; OSPM_DBGERRORLOG(*ospvError, "bad http header"); } } break; default: *ospvError = OSPC_ERR_HTTP_BAD_HEADER_200; OSPM_DBGERRORLOG(*ospvError, "bad http header"); } OSPM_DBGEXIT(("EXIT : OSPPHttpParseHeader\n")); return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -