I wrote:

Given that the XMLURL type has getUser and getPassword, what about
supporting basic authentication in the NetAccessors classes? I have
tried a piece of code but I'm not particularly familiar with the memory
management and internationalization mechanisms in Xerces so I'm probably
writing bad code. ;^>


Ok, figgered it out and it works like a charm (I can now specify http://user:[EMAIL PROTECTED]:port URL's). Stumbled over some XMLCh vs. char * and using the Base64 class (needs better docs, namely that Base64::encode returns a UTF-8, null-terminated string with a CRLF at the end of it).

Here's the diffs, feel free to incorporate into the official distribution. Apologies for not complying with the variable naming, indention, etc...I spend far more time with httpd and C modules than C++. Note that these diffs are to the 2.6.0 release of UnixHTTPURLInputStream.cpp .

If there are any bugs introduced by this code, please correct me. (Is there a memory leak? I'm assuming the fMemoryManager is a pooling memory manager so I need not worry about freeing what I allocate.)

---diff below---

*** util/NetAccessors/Socket/UnixHTTPURLInputStream.cpp 2004-09-08 06:56:35.000000000 -0700 --- /home/xdb/UnixHTTPURLInputStream.cpp 2005-08-05 14:21:01.000000000 -0700
***************
*** 127,132 ****
--- 127,133 ----
 #include <xercesc/util/TransService.hpp>
 #include <xercesc/util/TranscodingException.hpp>
 #include <xercesc/util/PlatformUtils.hpp>
+ #include <xercesc/util/Base64.hpp>

 XERCES_CPP_NAMESPACE_BEGIN

***************
*** 211,216 ****
--- 212,219 ----
     const XMLCh*        path = urlSource.getPath();
     const XMLCh*        fragment = urlSource.getFragment();
const XMLCh* query = urlSource.getQuery(); + const XMLCh* username = urlSource.getUser();
+     const XMLCh*      password = urlSource.getPassword();

     //
// Convert the hostName to the platform's code page for gethostbyname and
***************
*** 371,376 ****
--- 374,399 ----
     }
     strcat(fBuffer, CRLF);

+     if (username && password)
+     {
+ unsigned int len = XMLString::stringLen(username) + XMLString::stringLen(password) + 1; + char* userPass = (char *)fMemoryManager->allocate((len + 1) * sizeof(*userPass));
+       char* encodedData;
+
+       userPass[0] = '\0';
+       strcat(userPass, XMLString::transcode(username, fMemoryManager));
+       strcat(userPass, ":");
+       strcat(userPass, XMLString::transcode(password, fMemoryManager));
+ encodedData = (char *)Base64::encode((XMLByte *)userPass, strlen(userPass), &len, fMemoryManager);
+
+       if (encodedData)
+       {
+ char *authorization = (char *)fMemoryManager->allocate((strlen("Authorization: Basic ") + len + 3) * sizeof(*authorization));
+           sprintf(authorization, "Authorization: Basic %s", encodedData);
+           strcat(fBuffer, authorization);
+       }
+     }
+
     if(httpInfo!=0 && httpInfo->fHeaders!=0)
         strncat(fBuffer,httpInfo->fHeaders,httpInfo->fHeadersLen);

Reply via email to