8 #include <sys/select.h>
10 #include <sys/types.h>
11 #include "libcitadel.h"
14 * @defgroup URLHandling ParsedURL object to handle connection data
18 * @ingroup URLHandling
19 * @brief frees a linked list of ParsedURL
20 * @param Url (list) of ParsedURL to be freet; Pointer is NULL'ed for the caller.
22 void FreeURL(ParsedURL** Url)
25 FreeStrBuf(&(*Url)->URL);
26 FreeStrBuf(&(*Url)->UrlWithoutCred);
27 FreeStrBuf(&(*Url)->CurlCreds);
28 if ((*Url)->Next != NULL)
29 FreeURL(&(*Url)->Next);
36 * @ingroup URLHandling
37 * @brief parses the string provided with UrlStr into *Url
38 * @param Url on success this contains the parsed object; needs to be free'd by caller.
39 * @param UrlStr String we should parse into parts
40 * @param DefaultPort Which is the default port here?
42 int ParseURL(ParsedURL **Url, StrBuf *UrlStr, unsigned short DefaultPort)
44 const char *pch, *pEndHost, *pPort, *pCredEnd, *pUserEnd;
45 ParsedURL *url = (ParsedURL *)malloc(sizeof(ParsedURL));
46 memset(url, 0, sizeof(ParsedURL));
49 url->Port = DefaultPort;
51 * http://username:passvoid@[ipv6]:port/url
53 url->URL = NewStrBufDup(UrlStr);
54 url->Host = pch = ChrPtr(url->URL);
55 url->LocalPart = strchr(pch, '/');
56 if (url->LocalPart != NULL) {
57 if ((*(url->LocalPart + 1) == '/') &&
58 (*(url->LocalPart - 1) == ':')) { /* TODO: find default port for this protocol... */
59 url->Host = url->LocalPart + 2;
60 url->LocalPart = strchr(url->Host, '/');
61 if (url->LocalPart != NULL)
63 StrBufPeek(url->URL, url->LocalPart, 0, '\0');
68 if (url->LocalPart == NULL) {
69 url->LocalPart = pch + StrLength(url->URL);
72 pCredEnd = strchr(pch, '@');
73 if (pCredEnd >= url->LocalPart)
77 url->User = url->Host;
78 url->Host = pCredEnd + 1;
79 pUserEnd = strchr(url->User, ':');
81 if (pUserEnd > pCredEnd)
84 url->Pass = pUserEnd + 1;
86 StrBufPeek(url->URL, pUserEnd, 0, '\0');
87 StrBufPeek(url->URL, pCredEnd, 0, '\0');
91 if (*url->Host == '[') {
93 pEndHost = strchr(url->Host, ']');
94 if (pEndHost == NULL) {
95 FreeStrBuf(&url->URL);
97 return 0; /* invalid syntax, no ipv6 */
99 StrBufPeek(url->URL, pEndHost, 0, '\0');
100 if (*(pEndHost + 1) == ':'){
101 StrBufPeek(url->URL, pEndHost + 1, 0, '\0');
102 pPort = pEndHost + 2;
107 pPort = strchr(url->Host, ':');
109 StrBufPeek(url->URL, pPort, 0, '\0');
114 url->Port = atol(pPort);
115 url->IsIP = inet_pton(url->af, url->Host, &url->Addr.sin6_addr);
120 void CurlPrepareURL(ParsedURL *Url)
122 if (!strcmp(ChrPtr(Url->URL), "http"))
123 Url->UrlWithoutCred = NewStrBufPlain(ChrPtr(Url->URL), -1);
125 Url->UrlWithoutCred = NewStrBufPlain(HKEY("http://"));
126 StrBufAppendBufPlain(Url->UrlWithoutCred, Url->Host, -1, 0);
128 StrBufAppendBufPlain(Url->UrlWithoutCred, HKEY(":"), 0);
130 StrBufAppendPrintf(Url->UrlWithoutCred, "%u", Url->Port);
132 StrBufAppendBufPlain(Url->UrlWithoutCred, HKEY("/"), 0);
135 StrBufAppendBufPlain(Url->UrlWithoutCred, Url->LocalPart, -1, 0);
137 if (Url->User != NULL)
139 Url->CurlCreds = NewStrBufPlain(Url->User, -1);
140 StrBufAppendBufPlain(Url->CurlCreds, HKEY(":"), 0);
141 if (Url->Pass != NULL)
142 StrBufAppendBufPlain(Url->CurlCreds, Url->Pass, -1, 0);
144 Url->PlainUrl = ChrPtr(Url->UrlWithoutCred);