binhttpurlinputstream.cpp

来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 552 行 · 第 1/2 页

CPP
552
字号
                delete tmpMutex;            }         }         XMLMutexLock lock(fInitMutex);         if (!fInitialized)         {             Initialize(urlSource.getMemoryManager());         }    }    fMemoryManager = urlSource.getMemoryManager();    //    // Pull all of the parts of the URL out of th urlSource object, and transcode them    //   and transcode them back to ASCII.    //    const XMLCh*        hostName = urlSource.getHost();    char*               hostNameAsCharStar = XMLString::transcode(hostName, urlSource.getMemoryManager());    ArrayJanitor<char>  janBuf1(hostNameAsCharStar, urlSource.getMemoryManager());    const XMLCh*        path = urlSource.getPath();    char*               pathAsCharStar = XMLString::transcode(path, urlSource.getMemoryManager());    ArrayJanitor<char>  janBuf2(pathAsCharStar, urlSource.getMemoryManager());    const XMLCh*        fragment = urlSource.getFragment();    char*               fragmentAsCharStar = 0;    if (fragment)        fragmentAsCharStar = XMLString::transcode(fragment, urlSource.getMemoryManager());    ArrayJanitor<char>  janBuf3(fragmentAsCharStar, urlSource.getMemoryManager());    const XMLCh*        query = urlSource.getQuery();    char*               queryAsCharStar = 0;    if (query)        queryAsCharStar = XMLString::transcode(query, urlSource.getMemoryManager());    ArrayJanitor<char>  janBuf4(queryAsCharStar, urlSource.getMemoryManager());		    unsigned short      portNumber = (unsigned short) urlSource.getPortNum();    //    // Set up a socket.    //    struct hostent*     hostEntPtr = 0;    struct sockaddr_in  sa;    if ((hostEntPtr = gethostbyname(hostNameAsCharStar)) == NULL)    {        unsigned long  numAddress = inet_addr(hostNameAsCharStar);        if (numAddress == INADDR_NONE)        {            // Call WSAGetLastError() to get the error number.            ThrowXMLwithMemMgr1(NetAccessorException,                     XMLExcepts::NetAcc_TargetResolution, hostName, fMemoryManager);        }        if ((hostEntPtr =                gethostbyaddr((const char *) &numAddress,                              sizeof(unsigned long), AF_INET)) == NULL)        {            // Call WSAGetLastError() to get the error number.            ThrowXMLwithMemMgr1(NetAccessorException,                     XMLExcepts::NetAcc_TargetResolution, hostName, fMemoryManager);        }    }    memcpy((void *) &sa.sin_addr,           (const void *) hostEntPtr->h_addr, hostEntPtr->h_length);    sa.sin_family = hostEntPtr->h_addrtype;    sa.sin_port = htons(portNumber);    SOCKET s = socket(hostEntPtr->h_addrtype, SOCK_STREAM, 0);    if (s == INVALID_SOCKET)    {        // Call WSAGetLastError() to get the error number.        ThrowXMLwithMemMgr1(NetAccessorException,                 XMLExcepts::NetAcc_CreateSocket, urlSource.getURLText(), fMemoryManager);    }    if (connect(s, (struct sockaddr *) &sa, sizeof(sa)) == SOCKET_ERROR)    {        // Call WSAGetLastError() to get the error number.        ThrowXMLwithMemMgr1(NetAccessorException,                 XMLExcepts::NetAcc_ConnSocket, urlSource.getURLText(), fMemoryManager);    }    // Set a flag so we know that the headers have not been read yet.    bool fHeaderRead = false;    // The port is open and ready to go.    // Build up the http GET command to send to the server.    // To do:  We should really support http 1.1.  This implementation    //         is weak.    memset(fBuffer, 0, sizeof(fBuffer));    if(httpInfo==0)        strcpy(fBuffer, "GET ");    else {        switch(httpInfo->fHTTPMethod) {        case XMLNetHTTPInfo::GET:   strcpy(fBuffer, "GET "); break;        case XMLNetHTTPInfo::PUT:   strcpy(fBuffer, "PUT "); break;        case XMLNetHTTPInfo::POST:  strcpy(fBuffer, "POST "); break;        }    }    strcat(fBuffer, pathAsCharStar);    if (queryAsCharStar != 0)    {        // Tack on a ? before the fragment        strcat(fBuffer,"?");        strcat(fBuffer, queryAsCharStar);    }    if (fragmentAsCharStar != 0)    {        strcat(fBuffer, fragmentAsCharStar);    }    strcat(fBuffer, " HTTP/1.0\r\n");    strcat(fBuffer, "Host: ");    strcat(fBuffer, hostNameAsCharStar);    if (portNumber != 80)    {        strcat(fBuffer, ":");        int i = strlen(fBuffer);        _itoa(portNumber, fBuffer+i, 10);    }    strcat(fBuffer, "\r\n");    if(httpInfo!=0 && httpInfo->fHeaders!=0)        strncat(fBuffer,httpInfo->fHeaders,httpInfo->fHeadersLen);    strcat(fBuffer, "\r\n");    // Send the http request    int lent = strlen(fBuffer);    int  aLent = 0;    if ((aLent = send(s, fBuffer, lent, 0)) != lent)    {        // Call WSAGetLastError() to get the error number.        ThrowXMLwithMemMgr1(NetAccessorException,                 XMLExcepts::NetAcc_WriteSocket, urlSource.getURLText(), fMemoryManager);    }    if(httpInfo!=0 && httpInfo->fPayload!=0) {        int  aLent = 0;        if ((aLent = send(s, httpInfo->fPayload, httpInfo->fPayloadLen, 0)) != httpInfo->fPayloadLen)        {            // Call WSAGetLastError() to get the error number.            ThrowXMLwithMemMgr1(NetAccessorException,                     XMLExcepts::NetAcc_WriteSocket, urlSource.getURLText(), fMemoryManager);        }    }    //    // get the response, check the http header for errors from the server.    //    memset(fBuffer, 0, sizeof(fBuffer));    aLent = recv(s, fBuffer, sizeof(fBuffer)-1, 0);    if (aLent == SOCKET_ERROR || aLent == 0)    {        // Call WSAGetLastError() to get the error number.        ThrowXMLwithMemMgr1(NetAccessorException, XMLExcepts::NetAcc_ReadSocket, urlSource.getURLText(), fMemoryManager);    }    fBufferEnd = fBuffer+aLent;    *fBufferEnd = 0;    do {        // Find the break between the returned http header and any data.        //  (Delimited by a blank line)        // Hang on to any data for use by the first read from this BinHTTPURLInputStream.        //        fBufferPos = strstr(fBuffer, "\r\n\r\n");        if (fBufferPos != 0)        {            fBufferPos += 4;            *(fBufferPos-2) = 0;            fHeaderRead = true;        }        else        {            fBufferPos = strstr(fBuffer, "\n\n");            if (fBufferPos != 0)            {                fBufferPos += 2;                *(fBufferPos-1) = 0;                fHeaderRead = true;            }            else            {                //                // Header is not yet read, do another recv() to get more data...                aLent = recv(s, fBufferEnd, (sizeof(fBuffer) - 1) - (fBufferEnd - fBuffer), 0);                if (aLent == SOCKET_ERROR || aLent == 0)                {                    // Call WSAGetLastError() to get the error number.                    ThrowXMLwithMemMgr1(NetAccessorException, XMLExcepts::NetAcc_ReadSocket, urlSource.getURLText(), fMemoryManager);                }                fBufferEnd = fBufferEnd + aLent;                *fBufferEnd = 0;            }        }    } while(fHeaderRead == false);    // Make sure the header includes an HTTP 200 OK response.    //    char *p = strstr(fBuffer, "HTTP");    if (p == 0)    {        ThrowXMLwithMemMgr1(NetAccessorException, XMLExcepts::NetAcc_ReadSocket, urlSource.getURLText(), fMemoryManager);    }    p = strchr(p, ' ');    if (p == 0)    {        ThrowXMLwithMemMgr1(NetAccessorException, XMLExcepts::NetAcc_ReadSocket, urlSource.getURLText(), fMemoryManager);    }    int httpResponse = atoi(p);    if (httpResponse != 200)    {        // Most likely a 404 Not Found error.        //   Should recognize and handle the forwarding responses.        //        ThrowXMLwithMemMgr1(NetAccessorException, XMLExcepts::File_CouldNotOpenFile, urlSource.getURLText(), fMemoryManager);    }    fSocketHandle = (unsigned int) s;}BinHTTPURLInputStream::~BinHTTPURLInputStream(){    shutdown(fSocketHandle, SD_BOTH);    closesocket(fSocketHandle);}////  readBytes//unsigned int BinHTTPURLInputStream::readBytes(XMLByte* const    toFill                                    , const unsigned int    maxToRead){    unsigned int len = fBufferEnd - fBufferPos;    if (len > 0)    {        // If there's any data left over in the buffer into which we first        //   read from the server (to get the http header), return that.        if (len > maxToRead)            len = maxToRead;        memcpy(toFill, fBufferPos, len);        fBufferPos += len;    }    else    {        // There was no data in the local buffer.        // Read some from the socket, straight into our caller's buffer.        //        len = recv((SOCKET) fSocketHandle, (char *) toFill, maxToRead, 0);        if (len == SOCKET_ERROR)        {            // Call WSAGetLastError() to get the error number.            ThrowXMLwithMemMgr(NetAccessorException, XMLExcepts::NetAcc_ReadSocket, fMemoryManager);        }    }    fBytesProcessed += len;    return len;}XERCES_CPP_NAMESPACE_END

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?