Back to index

libcitadel  8.12
urlhandling.c
Go to the documentation of this file.
00001 #include "sysdep.h"
00002 #include <ctype.h>
00003 #include <errno.h>
00004 #include <string.h>
00005 #include <unistd.h>
00006 #include <string.h>
00007 #include <stdio.h>
00008 #include <sys/select.h>
00009 #include <fcntl.h>
00010 #include <sys/types.h>
00011 #include "libcitadel.h"
00012 #include <sys/socket.h>
00013 
00023 void FreeURL(ParsedURL** Url)
00024 {
00025        if (*Url != NULL) {
00026               FreeStrBuf(&(*Url)->URL);
00027               FreeStrBuf(&(*Url)->UrlWithoutCred);
00028               FreeStrBuf(&(*Url)->CurlCreds);
00029               if ((*Url)->Next != NULL)
00030                      FreeURL(&(*Url)->Next);
00031               free(*Url);
00032               *Url = NULL;
00033        }
00034 }
00035 
00043 int ParseURL(ParsedURL **Url, StrBuf *UrlStr, unsigned short DefaultPort)
00044 {
00045        const char *pch, *pEndHost, *pPort, *pCredEnd, *pUserEnd;
00046        ParsedURL *url = (ParsedURL *)malloc(sizeof(ParsedURL));
00047        memset(url, 0, sizeof(ParsedURL));
00048 
00049        url->af = AF_INET;
00050        url->Port =  DefaultPort;
00051        /*
00052         * http://username:passvoid@[ipv6]:port/url 
00053         */
00054        url->URL = NewStrBufDup(UrlStr);
00055        url->Host = pch = ChrPtr(url->URL);
00056        url->LocalPart = strchr(pch, '/');
00057        if (url->LocalPart != NULL) {
00058               if ((*(url->LocalPart + 1) == '/') && 
00059                   (*(url->LocalPart - 1) == ':')) { /* TODO: find default port for this protocol... */
00060                      url->Host = url->LocalPart + 2;
00061                      url->LocalPart = strchr(url->Host, '/');
00062                      if (url->LocalPart != NULL)
00063                      {
00064                          StrBufPeek(url->URL, url->LocalPart, 0, '\0');
00065                          url->LocalPart++;
00066                      }
00067               }
00068        }
00069        if (url->LocalPart == NULL) {
00070               url->LocalPart = pch + StrLength(url->URL);
00071        }
00072 
00073        pCredEnd = strchr(pch, '@');
00074        if (pCredEnd >= url->LocalPart)
00075               pCredEnd = NULL;
00076        if (pCredEnd != NULL)
00077        {
00078               url->User = url->Host;
00079               url->Host = pCredEnd + 1;
00080               pUserEnd = strchr(url->User, ':');
00081               
00082               if (pUserEnd > pCredEnd)
00083                      pUserEnd = pCredEnd;
00084               else {
00085                      url->Pass = pUserEnd + 1;
00086               }
00087               StrBufPeek(url->URL, pUserEnd, 0, '\0');
00088               StrBufPeek(url->URL, pCredEnd, 0, '\0');         
00089        }
00090        
00091        pPort = NULL;
00092        if (*url->Host == '[') {
00093               url->Host ++;
00094               pEndHost = strchr(url->Host, ']');
00095               if (pEndHost == NULL) {
00096                      FreeStrBuf(&url->URL);
00097                      free(url);
00098                      return 0; /* invalid syntax, no ipv6 */
00099               }
00100               StrBufPeek(url->URL, pEndHost, 0, '\0');
00101               if (*(pEndHost + 1) == ':'){
00102                      StrBufPeek(url->URL, pEndHost + 1, 0, '\0');
00103                      pPort = pEndHost + 2;
00104               }
00105               url->af = AF_INET6;
00106        }
00107        else {
00108               pPort = strchr(url->Host, ':');
00109               if (pPort != NULL) {
00110                      StrBufPeek(url->URL, pPort, 0, '\0');
00111                      pPort ++;
00112               }
00113        }
00114        if (pPort != NULL)
00115               url->Port = atol(pPort);
00116        if (url->IPv6)
00117        {
00118            url->IsIP = inet_pton(AF_INET6, url->Host, &url->Addr.sin6_addr);
00119            if (url->IsIP)
00120            {
00121               url->Addr.sin6_port = htons(url->Port);
00122               url->Addr.sin6_port = AF_INET6;
00123            }
00124        }
00125        else
00126        {
00127            url->IsIP = inet_pton(AF_INET, url->Host, &((struct sockaddr_in *)&(url->Addr))->sin_addr);
00128            if (url->IsIP)
00129            {
00130               ((struct sockaddr_in *)&(url->Addr))->sin_port = htons(url->Port);
00131               ((struct sockaddr_in *)&(url->Addr))->sin_family = AF_INET;
00132            }  
00133        }      
00134        *Url = url;
00135        return 1;
00136 }
00137 
00138 void CurlPrepareURL(ParsedURL *Url)
00139 {
00140        if (!strcmp(ChrPtr(Url->URL), "http"))
00141               Url->UrlWithoutCred = NewStrBufPlain(ChrPtr(Url->URL), -1);
00142        else 
00143               Url->UrlWithoutCred = NewStrBufPlain(HKEY("http://"));
00144        StrBufAppendBufPlain(Url->UrlWithoutCred, Url->Host, -1, 0);
00145 
00146        StrBufAppendBufPlain(Url->UrlWithoutCred, HKEY(":"), 0);
00147 
00148        StrBufAppendPrintf(Url->UrlWithoutCred, "%u", Url->Port);
00149 
00150        StrBufAppendBufPlain(Url->UrlWithoutCred, HKEY("/"), 0);
00151        if (Url->LocalPart)
00152        {
00153            StrBufAppendBufPlain(Url->UrlWithoutCred, Url->LocalPart, -1, 0);
00154        }
00155        if (Url->User != NULL)
00156        {
00157               Url->CurlCreds = NewStrBufPlain(Url->User, -1);
00158               StrBufAppendBufPlain(Url->CurlCreds, HKEY(":"), 0);
00159               if (Url->Pass != NULL)
00160                      StrBufAppendBufPlain(Url->CurlCreds, Url->Pass, -1, 0);
00161        }
00162        Url->PlainUrl = ChrPtr(Url->UrlWithoutCred);
00163 }