📄 ospsocket.c
字号:
OSPPSockNew( OSPTHTTP *ospvHttp){ int errorcode = OSPC_ERR_NO_ERROR; OSPM_DBGENTER(("ENTER: OSPPSockNew()\n")); /* create the socket */ OSPM_SOCKET(ospvHttp->SockFd, errorcode); if (errorcode == OSPC_ERR_NO_ERROR) { errorcode = OSPPSockSetKeepAlive(ospvHttp); if (errorcode == OSPC_ERR_NO_ERROR) { errorcode = OSPPSockDisableNagle(ospvHttp); } } OSPM_DBGEXIT(("EXIT : OSPPSockNew() (%d)\n", errorcode)); return errorcode;}voidOSPPSockProcessRequest( OSPTHTTP *ospvHttp, unsigned char *ospvRequestBuffer, unsigned ospvRequestBufferSz, unsigned char **ospvResponseBuffer, unsigned *ospvResponseBufferSz, unsigned char **ospvContentBuffer, unsigned *ospvContentBufferSz, int *ospvError){ #define OSPC_RECVBUF_SZ 256 unsigned char *tmprecvbuf = OSPC_OSNULL; char recvheadbuf[OSPC_RECVBUF_SZ] = { "" }; unsigned recvbufsz = OSPC_RECVBUF_SZ; int responsetype = 0; unsigned ospvConnectionBufferSz = 0; int connectionCloseFlag = OSPC_FALSE; unsigned char *ospvConnectionBuffer = OSPC_OSNULL; unsigned char *tmpContentBuffer = OSPC_OSNULL; unsigned tmpContentBufferSz = 0; OSPM_DBGENTER(("ENTER: OSPPSockProcessRequest()\n")); *ospvError = OSPC_ERR_NO_ERROR; if (ospvHttp == (OSPTHTTP *)OSPC_OSNULL) { *ospvError = OSPC_ERR_HTTP_INVALID_ARG; } /* * send the outbound message to the service point. * this consists of the HTTP header and the multipart MIME message */ if (*ospvError == OSPC_ERR_NO_ERROR) { *ospvError = OSPPSSLSessionWrite(ospvHttp, ospvRequestBuffer, &ospvRequestBufferSz); if(*ospvError == OSPC_ERR_NO_ERROR) { /* make sure socket was not reset by peer */ OSPM_GETSOCKERR(ospvHttp, *ospvError); } } if (*ospvError == OSPC_ERR_NO_ERROR) { /* * the first response that the server may send back to us * could look like this: * * HTTP/1.1 100 Continue * Server: Microsoft-IIS/4.0 * Date: Tue, 21 Jul 1998 00:39:54 GMT * * this simply confirms that the server has received our request. * verify the '100 Continue' and continue. */ *ospvError = OSPPSSLSessionRead(ospvHttp, (unsigned char *)recvheadbuf, &recvbufsz, "\r\n\r\n"); /* ** Check this header to see what type of response we are getting. ** The type will be returned in the responsetype variable. If the ** type is something other than a 1xx or a 2xx, an errorcode will ** be returned by the function. */ if (*ospvError != OSPC_ERR_NO_ERROR) { OSPM_DBGERRORLOG(*ospvError, "http recv init header failed"); } else if ((*ospvError = OSPPHttpVerifyResponse(recvheadbuf, &responsetype)) != OSPC_ERR_NO_ERROR) { OSPM_DBGERRORLOG(*ospvError, "http response unexpected"); OSPM_DBGERROR(("expected 1XX or 2xx code: received = [%s]\n", recvheadbuf)); } else { if (responsetype == 100) { /* * Read again for the 200 header. */ recvbufsz = 256; *ospvError = OSPPSSLSessionRead(ospvHttp, (unsigned char *)recvheadbuf, &recvbufsz, "\r\n\r\n"); responsetype = 0; } /* * the header for the server response will look like this: * * HTTP/1.1 200 OK * Server: Microsoft-IIS/4.0 * Date: Tue, 21 Jul 1998 00:39:56 GMT * Connection: Keep-Alive * Content-Length: 1042 * Content-type: ..... */ /* * parse the header response and place the content-length * in the ospvInBufferSz variable. This is used to determine * the size of the inbound response message buffer. */ if (*ospvError == OSPC_ERR_NO_ERROR) { /* * make sure we get an OK response back from the server */ if (((*ospvError = OSPPHttpVerifyResponse(recvheadbuf, &responsetype)) != OSPC_ERR_NO_ERROR) || (responsetype != 200)) { OSPM_DBGERRORLOG(*ospvError, "http bad server response error"); OSPM_DBGERROR(("expected 2xx code: received = [%s]\n", recvheadbuf)); } else { /* parse the header response and place the MIME * connection-type into the ospvConnectionBuffer variable. * ospvConnectionBufferSz is set to the size of the * ospvConnectionBuffer. */ OSPPHttpParseHeader((unsigned char *) recvheadbuf, &ospvConnectionBuffer, &ospvConnectionBufferSz, OSPC_HTTP_CONNECTION_TYPE, ospvError); /* check to see if the connection type contains "close". * If so, then set a flag to eventually close the socket connection. */ if((ospvConnectionBuffer != OSPC_OSNULL)&& (ospvConnectionBufferSz > 0)) { if(OSPM_STRSTR((char *)ospvConnectionBuffer, (const char *)"close") != OSPC_OSNULL) { connectionCloseFlag = OSPC_TRUE; } } if(ospvConnectionBuffer != OSPC_OSNULL) { OSPM_FREE(ospvConnectionBuffer); } OSPM_DBGNET(("http header = [%s]", recvheadbuf)); /* * parse the header response and place the MIME * content-type into the tmpContentBuffer variable. * tmpContentBufferSz is set to the size of the * tmpContentBuffer. */ OSPPHttpParseHeader((unsigned char *)recvheadbuf, &tmpContentBuffer, &tmpContentBufferSz, OSPC_HTTP_CONTENT_TYPE, ospvError); if (*ospvError == OSPC_ERR_NO_ERROR) { /* * parse the header response and place the * content-length in the ospvResponseBufferSz * variable. This is used to determine * the size of the inbound response message * buffer. Alloc space for the tmprecvbuf in order * receive the content data. */ OSPPHttpParseHeader((unsigned char *)recvheadbuf, &tmprecvbuf, ospvResponseBufferSz, OSPC_HTTP_CONTENT_LENGTH, ospvError); if (*ospvError == OSPC_ERR_NO_ERROR) { /* * now receive the body of the HTTP response */ *ospvError = OSPPSSLSessionRead( ospvHttp, tmprecvbuf, ospvResponseBufferSz, OSPC_OSNULL); if (*ospvError != OSPC_ERR_NO_ERROR) { if (tmprecvbuf != OSPC_OSNULL) { OSPM_FREE(tmprecvbuf); tmprecvbuf = OSPC_OSNULL; } if (*ospvContentBuffer != OSPC_OSNULL) { OSPM_FREE(*ospvContentBuffer); } *ospvResponseBuffer = *ospvContentBuffer = OSPC_OSNULL; } else { /* * assign the response buffer pointer after all of the * reading is complete. This needs to be an autonomous * operation because the application thread is waiting for * the buffer to become non-null in order to indicate that * data is available to process. If the conditional variable * receives a spurous wakeup (which happens on many SMP platforms) * the buffer pointer must point to a complete response otherwise * a partial message will attempt to be processed which will reek * havoc on the request and possibly the application as well. */ *ospvResponseBuffer = tmprecvbuf; OSPM_DBGNET(("http body = [%s]", tmprecvbuf)); } } } if(*ospvContentBuffer != OSPC_OSNULL) { OSPM_FREE(*ospvContentBuffer); *ospvContentBufferSz = 0; } /* Save the content buffer and content buffer size * for the next time through this function */ *ospvContentBuffer = tmpContentBuffer; *ospvContentBufferSz = tmpContentBufferSz; } } } } /* If the Connection-Type indicated "close" in the MIME header, * then close the connection. */ if(connectionCloseFlag == OSPC_TRUE) { *ospvError = OSPPSockClose(OSPC_TRUE, &(ospvHttp->SockFd), &(ospvHttp->SSLSession)); } OSPM_DBGEXIT(("EXIT : OSPPSockProcessRequest() (%d)\n", *ospvError)); return;}intOSPPSockRead( OSPTHTTP *ospvHttp, unsigned char *ospvBuffer, unsigned int *ospvBufferSz){ int errorcode = OSPC_ERR_NO_ERROR; unsigned length = 0; struct timeval timeout; unsigned socktimeout = 0; OSPM_DBGENTER(("ENTER: OSPPSockRead()\n")); OSPM_DBGNET(("NET : OSPPSockRead() bufsz = <%d>\n", *ospvBufferSz)); do { /* * set the response timeout for the socket */ OSPPCommGetTimeout((OSPTCOMM *)ospvHttp->Comm, &socktimeout); timeout.tv_sec = socktimeout / 1000; timeout.tv_usec = socktimeout % 1000 * 1000; errorcode = OSPPSockWaitTillReady(ospvHttp->SockFd, OSPC_TRUE, &timeout); if (errorcode == OSPC_ERR_NO_ERROR) { OSPM_RECV(ospvHttp, ospvBuffer + length, *ospvBufferSz - length, errorcode); length += ospvHttp->ByteCount; } } while (errorcode == OSPC_ERR_NO_ERROR && ospvHttp->ByteCount > 0 && length < *ospvBufferSz); if (length != *ospvBufferSz || errorcode != OSPC_ERR_NO_ERROR) { OSPM_DBGNET( ("NET : OSPPSockRead() failed len = <%d> bufsz = <%d> err = <%d>\n", length, *ospvBufferSz, errorcode)); errorcode = OSPC_ERR_SOCK_RECV_FAILED; } *ospvBufferSz = length; OSPM_DBGEXIT(("EXIT : OSPPSockRead() (%d)\n", errorcode)); return errorcode;}intOSPPSockSetBlockingIO( OSPTSOCKET ospvSockFd, OSPTBOOL ospvBlocking){ int errorcode = OSPC_ERR_NO_ERROR; OSPM_DBGENTER(("ENTER: OSPPSockSetBlockingIO()\n")); OSPM_BLOCKIO(ospvSockFd, ospvBlocking, errorcode); if (errorcode != OSPC_ERR_NO_ERROR) errorcode = OSPC_ERR_SOCK_BLOCKIO_FAILED; OSPM_DBGEXIT(("EXIT : OSPPSockSetBlockingIO()\n")); return errorcode;}intOSPPSockSetKeepAlive( OSPTHTTP *ospvHttp){ int optval = 1; int errorcode = OSPC_ERR_NO_ERROR; OSPM_DBGENTER(("ENTER: OSPPSockSetKeepAlive()\n")); OSPM_SETSOCKOPT(ospvHttp->SockFd, SOL_SOCKET, SO_KEEPALIVE, optval, sizeof(optval), errorcode); OSPM_DBGEXIT(("EXIT : OSPPSockSetKeepAlive()\n")); return errorcode;}intOSPPSockWaitTillReady( OSPTSOCKET ospvSockFd, OSPTBOOL ospvWaitForRead, struct timeval *ospvTimeout){ int errorcode = OSPC_ERR_NO_ERROR; fd_set fdlist; unsigned fdready = 0; OSPM_DBGENTER(("ENTER: OSPPSockWaitTillReady()\n")); if (errorcode == OSPC_ERR_NO_ERROR) { FD_ZERO(&fdlist); FD_SET(ospvSockFd, &fdlist); /* * make sure there is data available to read */ if (ospvWaitForRead) { OSPM_SELECT(ospvSockFd +1, &fdlist, (fd_set *)OSPC_OSNULL, (fd_set *)OSPC_OSNULL, ospvTimeout, fdready); } else { /* * make sure there is data available to write */ OSPM_SELECT(ospvSockFd +1, (fd_set *)OSPC_OSNULL, &fdlist, (fd_set *)OSPC_OSNULL, ospvTimeout, fdready); } if (fdready != 1) errorcode = OSPC_ERR_SOCK_SELECT_FAILED; } OSPM_DBGEXIT(("EXIT : OSPPSockWaitTillReady() select on %s to.sec(%ld) to.usec(%ld) fdready(%d) err(%d)\n", (ospvWaitForRead ? "read" : "write"), ospvTimeout->tv_sec, ospvTimeout->tv_usec, fdready, errorcode)); return errorcode;}intOSPPSockWrite( OSPTHTTP *ospvHttp, unsigned char *ospvBuffer, unsigned int *ospvBufferSz){ int errorcode = OSPC_ERR_NO_ERROR; unsigned length = 0; struct timeval timeout; OSPM_DBGENTER(("ENTER: OSPPSockWrite()\n")); do { timeout.tv_sec = 0l; timeout.tv_usec = 0l; errorcode = OSPPSockWaitTillReady(ospvHttp->SockFd, OSPC_FALSE, &timeout); if (errorcode == OSPC_ERR_NO_ERROR) { OSPM_SEND(ospvHttp->SockFd, ospvHttp->ByteCount, ospvBuffer + length, *ospvBufferSz - length, errorcode); length += ospvHttp->ByteCount; } } while (errorcode == OSPC_ERR_NO_ERROR && ospvHttp->ByteCount > 0 && length < *ospvBufferSz); if (length != *ospvBufferSz || errorcode != OSPC_ERR_NO_ERROR) errorcode = OSPC_ERR_SOCK_SEND_FAILED; *ospvBufferSz = length; OSPM_DBGEXIT(("EXIT : OSPPSockWrite() (%d)\n", errorcode)); return errorcode;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -