00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifdef HAVE_CONFIG_H
00014 # include <config.h>
00015 #endif
00016
00017
00018 #include "url_p.h"
00019 #include "urlfns.h"
00020 #include <gwenhywfar/debug.h>
00021 #include <ctype.h>
00022
00023
00024 GWEN_URL *GWEN_Url_fromString(const char *str) {
00025 GWEN_URL *url;
00026 GWEN_DB_NODE *dbVars;
00027 const char *s;
00028 const char *p;
00029 int starts_with_drive_letter = 0;
00030
00031 url=GWEN_Url_new();
00032 dbVars=GWEN_DB_Group_new("vars");
00033 GWEN_Url_SetVars(url, dbVars);
00034 GWEN_DB_Group_free(dbVars);
00035 dbVars=0;
00036
00037 s=str;
00038
00039
00040
00041
00042 if (s && isalpha(s[0]) && s[1] == ':'
00043 && (s[2] == '/' || s[2] == '\\')) {
00044 starts_with_drive_letter = 1;
00045 }
00046
00047
00048 p = starts_with_drive_letter ? s : strchr(s, ':');
00049 if (p) {
00050 if (p[1]=='/' && p[2]=='/') {
00051 char *buf;
00052
00053
00054 buf=(char*)malloc(p-s+1);
00055 assert(buf);
00056 memmove(buf, s, p-s+1);
00057 buf[p-s]=0;
00058 GWEN_Url_SetProtocol(url, buf);
00059 free(buf);
00060 s=p+3;
00061 }
00062 }
00063
00064 if (!*s) {
00065 DBG_ERROR(GWEN_LOGDOMAIN, "No server or path given in url \"%s\"", str);
00066 GWEN_Url_free(url);
00067 return 0;
00068 }
00069
00070
00071 p=strchr(s, '@');
00072 if (p) {
00073 char *upw;
00074 char *pw;
00075 char *pat;
00076
00077 upw=(char*)malloc(p-s+1);
00078 assert(upw);
00079 memmove(upw, s, p-s);
00080 upw[p-s]=0;
00081 pw=strchr(upw, ':');
00082 if (pw) {
00083
00084 *pw=0;
00085 pw++;
00086 }
00087 pat=strchr(upw, '%');
00088 if (pat)
00089 *pat='@';
00090 GWEN_Url_SetUserName(url, upw);
00091 if (pw)
00092 GWEN_Url_SetPassword(url, pw);
00093 free(upw);
00094 s=p+1;
00095 }
00096
00097
00098 if (!starts_with_drive_letter
00099 && s && isalpha(s[0]) && s[1] == ':'
00100 && (s[2] == '/' || s[2] == '\\')) {
00101 starts_with_drive_letter = 1;
00102 }
00103
00104
00105 if (!*s) {
00106 DBG_ERROR(GWEN_LOGDOMAIN, "No server given in url \"%s\"", str);
00107 GWEN_Url_free(url);
00108 return 0;
00109 }
00110 p=s;
00111 while(!starts_with_drive_letter && *p && *p!=':' && *p!='/' && *p!='?')
00112 p++;
00113 if (p!=s) {
00114 char *buf;
00115
00116
00117 buf=(char*)malloc(p-s+1);
00118 assert(buf);
00119 memmove(buf, s, p-s+1);
00120 buf[p-s]=0;
00121 GWEN_Url_SetServer(url, buf);
00122 DBG_DEBUG(GWEN_LOGDOMAIN, "Server: [%s]", buf);
00123 free(buf);
00124 s=p;
00125 }
00126
00127
00128 if (*s==':') {
00129 p=++s;
00130 while(*p && *p!='?' && *p!='/')
00131 p++;
00132 if (p!=s) {
00133 char *buf;
00134 int port;
00135
00136
00137 buf=(char*)malloc(p-s+1);
00138 assert(buf);
00139 memmove(buf, s, p-s+1);
00140 buf[p-s]=0;
00141 if (sscanf(buf, "%d", &port)!=1) {
00142 DBG_ERROR(GWEN_LOGDOMAIN, "Bad port (%s) in url \"%s\"", buf, str);
00143 free(buf);
00144 GWEN_Url_free(url);
00145 return 0;
00146 }
00147 url->port=port;
00148 free(buf);
00149 s=p;
00150 }
00151 }
00152 else {
00153 if (url->protocol) {
00154 if (strcasecmp(url->protocol, "http")==0)
00155 url->port=80;
00156 else if (strcasecmp(url->protocol, "https")==0)
00157 url->port=443;
00158 }
00159 }
00160
00161
00162 if (starts_with_drive_letter || *s=='/') {
00163 p=s;
00164 while(*p && *p!='?')
00165 p++;
00166 if (p!=s) {
00167 char *buf;
00168
00169
00170 buf=(char*)malloc(p-s+1);
00171 assert(buf);
00172 memmove(buf, s, p-s+1);
00173 buf[p-s]=0;
00174 GWEN_Url_SetPath(url, buf);
00175 DBG_DEBUG(GWEN_LOGDOMAIN, "Path: [%s]", buf);
00176 free(buf);
00177 s=p;
00178 }
00179 }
00180 else {
00181 GWEN_Url_SetPath(url, "/");
00182 if (*s)
00183 s++;
00184 }
00185
00186
00187 while(*s && *s=='?') {
00188 GWEN_BUFFER *bName;
00189 GWEN_BUFFER *bValue;
00190
00191 bName=GWEN_Buffer_new(0, 256, 0, 1);
00192 bValue=GWEN_Buffer_new(0, 256, 0, 1);
00193 s++;
00194 p=s;
00195 while(*p && *p!='?' && *p!='=')
00196 p++;
00197 if (p!=s)
00198 GWEN_Buffer_AppendBytes(bName, s, (p-s));
00199 s=p;
00200 if (*p=='=') {
00201 s++;
00202 p=s;
00203 while(*p && *p!='?')
00204 p++;
00205 if (p!=s)
00206 GWEN_Buffer_AppendBytes(bValue, s, (p-s));
00207 s=p;
00208 }
00209
00210 if (GWEN_Buffer_GetUsedBytes(bName))
00211 GWEN_DB_SetCharValue(GWEN_Url_GetVars(url),
00212 GWEN_DB_FLAGS_DEFAULT,
00213 GWEN_Buffer_GetStart(bName),
00214 GWEN_Buffer_GetStart(bValue));
00215 GWEN_Buffer_free(bValue);
00216 GWEN_Buffer_free(bName);
00217 }
00218
00219 url->url=strdup(str);
00220 url->_modified=0;
00221 return url;
00222 }
00223
00224
00225
00226 int GWEN_Url_toString(const GWEN_URL *url, GWEN_BUFFER *buf) {
00227 assert(url);
00228 if (!url->_modified && !(url->url==0 || url->url[0]==0)) {
00229 GWEN_Buffer_AppendString(buf, url->url);
00230 }
00231 else {
00232 GWEN_DB_NODE *dbV;
00233
00234 if (url->protocol) {
00235 GWEN_Buffer_AppendString(buf, url->protocol);
00236 GWEN_Buffer_AppendString(buf, "://");
00237 }
00238 if (url->server) {
00239 GWEN_Buffer_AppendString(buf, url->server);
00240 }
00241 if (url->port) {
00242 char numbuf[32];
00243
00244 snprintf(numbuf, sizeof(numbuf), "%d", url->port);
00245 GWEN_Buffer_AppendString(buf, ":");
00246 GWEN_Buffer_AppendString(buf, numbuf);
00247 }
00248 if (url->path) {
00249 GWEN_Buffer_AppendString(buf, url->path);
00250 }
00251 if (url->vars) {
00252 dbV=GWEN_DB_GetFirstVar(url->vars);
00253 while(dbV) {
00254 const char *s;
00255
00256 s=GWEN_DB_VariableName(dbV);
00257 if (s) {
00258 GWEN_DB_NODE *dbVal;
00259
00260 GWEN_Buffer_AppendString(buf, "?");
00261 GWEN_Buffer_AppendString(buf, s);
00262 dbVal=GWEN_DB_GetFirstValue(dbV);
00263 if (dbVal) {
00264 s=GWEN_DB_GetCharValueFromNode(dbVal);
00265 if (s) {
00266 GWEN_Buffer_AppendString(buf, "=");
00267 GWEN_Buffer_AppendString(buf, s);
00268 }
00269 }
00270 }
00271 dbV=GWEN_DB_GetNextVar(dbV);
00272 }
00273 }
00274 }
00275 return 0;
00276 }
00277
00278
00279
00280 GWEN_URL *GWEN_Url_fromCommandString(const char *str) {
00281 GWEN_URL *url;
00282 GWEN_DB_NODE *dbVars;
00283 const char *s;
00284 const char *p;
00285
00286 url=GWEN_Url_new();
00287 dbVars=GWEN_DB_Group_new("vars");
00288 GWEN_Url_SetVars(url, dbVars);
00289 GWEN_DB_Group_free(dbVars);
00290 dbVars=0;
00291
00292 s=str;
00293
00294
00295 if (*s=='/') {
00296 p=s;
00297 while(*p && *p!='?')
00298 p++;
00299 if (p!=s) {
00300 char *buf;
00301
00302
00303 buf=(char*)malloc(p-s+1);
00304 assert(buf);
00305 memmove(buf, s, p-s+1);
00306 buf[p-s]=0;
00307 GWEN_Url_SetPath(url, buf);
00308 free(buf);
00309 s=p;
00310 }
00311 }
00312 else {
00313 GWEN_Url_SetPath(url, "/");
00314 if (*s)
00315 s++;
00316 }
00317
00318
00319 while(*s && *s=='?') {
00320 GWEN_BUFFER *bName;
00321 GWEN_BUFFER *bValue;
00322
00323 bName=GWEN_Buffer_new(0, 256, 0, 1);
00324 bValue=GWEN_Buffer_new(0, 256, 0, 1);
00325 s++;
00326 p=s;
00327 while(*p && *p!='?' && *p!='=')
00328 p++;
00329 if (p!=s)
00330 GWEN_Buffer_AppendBytes(bName, s, (p-s));
00331 s=p;
00332 if (*p=='=') {
00333 s++;
00334 p=s;
00335 while(*p && *p!='?')
00336 p++;
00337 if (p!=s)
00338 GWEN_Buffer_AppendBytes(bValue, s, (p-s));
00339 s=p;
00340 }
00341
00342 if (GWEN_Buffer_GetUsedBytes(bName))
00343 GWEN_DB_SetCharValue(GWEN_Url_GetVars(url),
00344 GWEN_DB_FLAGS_DEFAULT,
00345 GWEN_Buffer_GetStart(bName),
00346 GWEN_Buffer_GetStart(bValue));
00347 GWEN_Buffer_free(bValue);
00348 GWEN_Buffer_free(bName);
00349 }
00350
00351 url->url=strdup(str);
00352
00353 return url;
00354 }
00355
00356
00357
00358 int GWEN_Url_toCommandString(const GWEN_URL *url, GWEN_BUFFER *buf) {
00359 GWEN_DB_NODE *dbV;
00360
00361 assert(url);
00362
00363 if (url->path) {
00364 GWEN_Buffer_AppendString(buf, url->path);
00365 }
00366 if (url->vars) {
00367 dbV=GWEN_DB_GetFirstVar(url->vars);
00368 while(dbV) {
00369 const char *s;
00370
00371 s=GWEN_DB_VariableName(dbV);
00372 if (s) {
00373 GWEN_DB_NODE *dbVal;
00374
00375 GWEN_Buffer_AppendString(buf, "?");
00376 GWEN_Buffer_AppendString(buf, s);
00377 dbVal=GWEN_DB_GetFirstValue(dbV);
00378 if (dbVal) {
00379 s=GWEN_DB_GetCharValueFromNode(dbVal);
00380 if (s) {
00381 GWEN_Buffer_AppendString(buf, "=");
00382 GWEN_Buffer_AppendString(buf, s);
00383 }
00384 }
00385 }
00386 dbV=GWEN_DB_GetNextVar(dbV);
00387 }
00388 }
00389
00390 return 0;
00391 }
00392
00393
00394