From 010183b26f1dd2d382ed736f9f0abd42ae504636 Mon Sep 17 00:00:00 2001 From: Tinny Ng <tng@apache.org> Date: Tue, 25 Feb 2003 21:22:36 +0000 Subject: [PATCH] Modify UnixHTTPURLInputStream for it to work on ebcdic platform. Patch from Steve Dulin git-svn-id: https://svn.apache.org/repos/asf/xerces/c/trunk@174814 13f79535-47bb-0310-9956-ffa450edef68 --- .../Socket/UnixHTTPURLInputStream.cpp | 168 ++++++++++++++---- 1 file changed, 131 insertions(+), 37 deletions(-) diff --git a/src/xercesc/util/NetAccessors/Socket/UnixHTTPURLInputStream.cpp b/src/xercesc/util/NetAccessors/Socket/UnixHTTPURLInputStream.cpp index d9ff53141..d25362163 100644 --- a/src/xercesc/util/NetAccessors/Socket/UnixHTTPURLInputStream.cpp +++ b/src/xercesc/util/NetAccessors/Socket/UnixHTTPURLInputStream.cpp @@ -56,6 +56,9 @@ /* * $Log$ + * Revision 1.10 2003/02/25 21:22:36 tng + * Modify UnixHTTPURLInputStream for it to work on ebcdic platform. Patch from Steve Dulin + * * Revision 1.9 2002/12/09 13:12:12 tng * Fix compilation error. * @@ -137,6 +140,9 @@ #include <xercesc/util/XMLExceptMsgs.hpp> #include <xercesc/util/Janitor.hpp> #include <xercesc/util/XMLUniDefs.hpp> +#include <xercesc/util/TransService.hpp> +#include <xercesc/util/TranscodingException.hpp> +#include <xercesc/util/PlatformUtils.hpp> XERCES_CPP_NAMESPACE_BEGIN @@ -145,39 +151,130 @@ UnixHTTPURLInputStream::UnixHTTPURLInputStream(const XMLURL& urlSource) : fSocket(0) , fBytesProcessed(0) { + // - // Pull all of the parts of the URL out of th urlSource object, and transcode them - // and transcode them back to ASCII. + // Constants in ASCII to send/check in the HTTP request/response // + + const char GET[] = + { + chLatin_G, chLatin_E, chLatin_T, chSpace, chNull + }; + + const char HTTP[] = + { + chLatin_H, chLatin_T, chLatin_T, chLatin_P, chNull + }; + + const char HTTP10[] = + { + chSpace, chLatin_H, chLatin_T, chLatin_T, chLatin_P, chForwardSlash, chDigit_1, chPeriod, chDigit_0, chCR, chLF, chNull + }; + + const char CRLF2X[] = + { + chCR, chLF, chCR, chLF, chNull + }; + + const char LF2X[] = + { + chLF, chLF, chNull + }; + + const char HOST[] = + { + chLatin_H, chLatin_o, chLatin_s, chLatin_t, chColon, chSpace, chNull + }; + + const char COLON[] = + { + chColon, chNull + }; + + const char resp200 [] = + { + chSpace, chDigit_2, chDigit_0, chDigit_0, chSpace, chNull + }; + + unsigned int charsEaten; + unsigned int transSize; + XMLTransService::Codes failReason; + const unsigned int blockSize = 2048; + const unsigned int bufSize = 5; + static XMLCh portBuffer[bufSize+1]; + + // + // Pull all of the parts of the URL out of the urlSource object + // + const XMLCh* hostName = urlSource.getHost(); + const XMLCh* path = urlSource.getPath(); + const XMLCh* fragment = urlSource.getFragment(); + const XMLCh* query = urlSource.getQuery(); + + // + // Convert the hostName to the platform's code page for gethostbyname and + // inet_addr functions. + // + char* hostNameAsCharStar = XMLString::transcode(hostName); ArrayJanitor<char> janBuf1(hostNameAsCharStar); - const XMLCh* path = urlSource.getPath(); - char* pathAsCharStar = XMLString::transcode(path); - ArrayJanitor<char> janBuf2(pathAsCharStar); + // + // Convert all the parts of the urlSource object to ASCII so they can be + // sent to the remote host in that format + // - const XMLCh* fragment = urlSource.getFragment(); - char* fragmentAsCharStar = 0; + transSize = XMLString::stringLen(hostName)+1; + char* hostNameAsASCII = new char[transSize+1]; + ArrayJanitor<char> janBuf2(hostNameAsASCII); + + XMLTranscoder* trans = XMLPlatformUtils::fgTransService->makeNewTranscoderFor("ISO8859-1", failReason, blockSize); + trans->transcodeTo(hostName, transSize, (unsigned char *) hostNameAsASCII, transSize, charsEaten, XMLTranscoder::UnRep_Throw); + + transSize = XMLString::stringLen(path)+1; + char* pathAsASCII = new char[transSize+1]; + ArrayJanitor<char> janBuf3(pathAsASCII); + trans->transcodeTo(path, transSize, (unsigned char *) pathAsASCII, transSize, charsEaten, XMLTranscoder::UnRep_Throw); + + char* fragmentAsASCII = 0; if (fragment) - fragmentAsCharStar = XMLString::transcode(fragment); - ArrayJanitor<char> janBuf3(fragmentAsCharStar); + { + transSize = XMLString::stringLen(fragment)+1; + fragmentAsASCII = new char[transSize+1]; + ArrayJanitor<char> janBuf4(fragmentAsASCII); + trans->transcodeTo(fragment, transSize, (unsigned char *) fragmentAsASCII, transSize, charsEaten, XMLTranscoder::UnRep_Throw); + } - const XMLCh* query = urlSource.getQuery(); - char* queryAsCharStar = 0; + char* queryAsASCII = 0; + ArrayJanitor<char> janBuf5(queryAsASCII); if (query) - queryAsCharStar = XMLString::transcode(query); - ArrayJanitor<char> janBuf4(queryAsCharStar); + { + transSize = XMLString::stringLen(query)+1; + queryAsASCII = new char[transSize+1]; + trans->transcodeTo(query, transSize, (unsigned char *) queryAsASCII, transSize, charsEaten, XMLTranscoder::UnRep_Throw); + } unsigned short portNumber = (unsigned short) urlSource.getPortNum(); + // + // Convert port number integer to unicode so we can transcode it to ASCII + // + + XMLString::binToText((unsigned int) portNumber, portBuffer, bufSize, 10); + transSize = XMLString::stringLen(portBuffer)+1; + char* portAsASCII = new char[transSize+1]; + trans->transcodeTo(portBuffer, transSize, (unsigned char *) portAsASCII, transSize, charsEaten, XMLTranscoder::UnRep_Throw); + + delete trans; + // // Set up a socket. // struct hostent* hostEntPtr = 0; struct sockaddr_in sa; - + // Use the hostName in the local code page .... if ((hostEntPtr = gethostbyname(hostNameAsCharStar)) == NULL) { unsigned long numAddress = inet_addr(hostNameAsCharStar); @@ -195,6 +292,7 @@ UnixHTTPURLInputStream::UnixHTTPURLInputStream(const XMLURL& urlSource) } } + memset(&sa, '\0', sizeof(sockaddr_in)); // iSeries fix ?? memcpy((void *) &sa.sin_addr, (const void *) hostEntPtr->h_addr, hostEntPtr->h_length); sa.sin_family = hostEntPtr->h_addrtype; @@ -217,37 +315,36 @@ UnixHTTPURLInputStream::UnixHTTPURLInputStream(const XMLURL& urlSource) // Build up the http GET command to send to the server. // To do: We should really support http 1.1. This implementation // is weak. - strcpy(fBuffer, "GET "); - strcat(fBuffer, pathAsCharStar); + strcpy(fBuffer, GET); + strcat(fBuffer, pathAsASCII); - if (queryAsCharStar != 0) + if (queryAsASCII != 0) { size_t n = strlen(fBuffer); fBuffer[n] = chQuestion; fBuffer[n+1] = chNull; - strcat(fBuffer, queryAsCharStar); + strcat(fBuffer, queryAsASCII); } - if (fragmentAsCharStar != 0) + if (fragmentAsASCII != 0) { - strcat(fBuffer, fragmentAsCharStar); + strcat(fBuffer, fragmentAsASCII); } - strcat(fBuffer, " HTTP/1.0\r\n"); - + strcat(fBuffer, HTTP10); - strcat(fBuffer, "Host: "); - strcat(fBuffer, hostNameAsCharStar); + strcat(fBuffer, HOST); + strcat(fBuffer, hostNameAsASCII); if (portNumber != 80) { - int i = strlen(fBuffer); - sprintf(fBuffer+i, ":%d", portNumber); - // _itoa(portNumber, fBuffer+i, 10); + strcat(fBuffer,COLON); + strcat(fBuffer,portAsASCII); } - strcat(fBuffer, "\r\n\r\n"); + strcat(fBuffer, CRLF2X); // Send the http request int lent = strlen(fBuffer); int aLent = 0; + if ((aLent = write(s, (void *) fBuffer, lent)) != lent) { ThrowXML1(NetAccessorException, @@ -270,7 +367,7 @@ UnixHTTPURLInputStream::UnixHTTPURLInputStream(const XMLURL& urlSource) // (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"); + fBufferPos = strstr(fBuffer, CRLF2X); if (fBufferPos != 0) { fBufferPos += 4; @@ -278,7 +375,7 @@ UnixHTTPURLInputStream::UnixHTTPURLInputStream(const XMLURL& urlSource) } else { - fBufferPos = strstr(fBuffer, "\n\n"); + fBufferPos = strstr(fBuffer, LF2X); if (fBufferPos != 0) { fBufferPos += 2; @@ -290,20 +387,19 @@ UnixHTTPURLInputStream::UnixHTTPURLInputStream(const XMLURL& urlSource) // Make sure the header includes an HTTP 200 OK response. // - char *p = strstr(fBuffer, "HTTP"); + char *p = strstr(fBuffer, HTTP); if (p == 0) { ThrowXML1(NetAccessorException, XMLExcepts::NetAcc_ReadSocket, urlSource.getURLText()); } - p = strchr(p, ' '); + p = strchr(p, chSpace); if (p == 0) { ThrowXML1(NetAccessorException, XMLExcepts::NetAcc_ReadSocket, urlSource.getURLText()); } - - int httpResponse = atoi(p); - if (httpResponse != 200) + + if (memcmp(p, resp200, strlen(resp200))) { // Most likely a 404 Not Found error. // Should recognize and handle the forwarding responses. @@ -311,13 +407,11 @@ UnixHTTPURLInputStream::UnixHTTPURLInputStream(const XMLURL& urlSource) ThrowXML1(NetAccessorException, XMLExcepts::File_CouldNotOpenFile, urlSource.getURLText()); } - fSocket = s; } - UnixHTTPURLInputStream::~UnixHTTPURLInputStream() { shutdown(fSocket, 2); -- GitLab