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 free(buf);
00123 s=p;
00124 }
00125
00126
00127 if (*s==':') {
00128 p=++s;
00129 while(*p && *p!='?' && *p!='/')
00130 p++;
00131 if (p!=s) {
00132 char *buf;
00133 int port;
00134
00135
00136 buf=(char*)malloc(p-s+1);
00137 assert(buf);
00138 memmove(buf, s, p-s+1);
00139 buf[p-s]=0;
00140 if (sscanf(buf, "%d", &port)!=1) {
00141 DBG_ERROR(GWEN_LOGDOMAIN, "Bad port (%s) in url \"%s\"", buf, str);
00142 free(buf);
00143 GWEN_Url_free(url);
00144 return 0;
00145 }
00146 url->port=port;
00147 free(buf);
00148 s=p;
00149 }
00150 }
00151 else {
00152 if (url->protocol) {
00153 if (strcasecmp(url->protocol, "http")==0)
00154 url->port=80;
00155 else if (strcasecmp(url->protocol, "https")==0)
00156 url->port=443;
00157 }
00158 }
00159
00160
00161 if (starts_with_drive_letter || *s=='/') {
00162 p=s;
00163 while(*p && *p!='?')
00164 p++;
00165 if (p!=s) {
00166 char *buf;
00167
00168
00169 buf=(char*)malloc(p-s+1);
00170 assert(buf);
00171 memmove(buf, s, p-s+1);
00172 buf[p-s]=0;
00173 GWEN_Url_SetPath(url, buf);
00174 free(buf);
00175 s=p;
00176 }
00177 }
00178 else {
00179 GWEN_Url_SetPath(url, "/");
00180 if (*s)
00181 s++;
00182 }
00183
00184
00185 while(*s && *s=='?') {
00186 GWEN_BUFFER *bName;
00187 GWEN_BUFFER *bValue;
00188
00189 bName=GWEN_Buffer_new(0, 256, 0, 1);
00190 bValue=GWEN_Buffer_new(0, 256, 0, 1);
00191 s++;
00192 p=s;
00193 while(*p && *p!='?' && *p!='=')
00194 p++;
00195 if (p!=s)
00196 GWEN_Buffer_AppendBytes(bName, s, (p-s));
00197 s=p;
00198 if (*p=='=') {
00199 s++;
00200 p=s;
00201 while(*p && *p!='?')
00202 p++;
00203 if (p!=s)
00204 GWEN_Buffer_AppendBytes(bValue, s, (p-s));
00205 s=p;
00206 }
00207
00208 if (GWEN_Buffer_GetUsedBytes(bName))
00209 GWEN_DB_SetCharValue(GWEN_Url_GetVars(url),
00210 GWEN_DB_FLAGS_DEFAULT,
00211 GWEN_Buffer_GetStart(bName),
00212 GWEN_Buffer_GetStart(bValue));
00213 GWEN_Buffer_free(bValue);
00214 GWEN_Buffer_free(bName);
00215 }
00216
00217 url->url=strdup(str);
00218 url->_modified=0;
00219 return url;
00220 }
00221
00222
00223
00224 int GWEN_Url_toString(const GWEN_URL *url, GWEN_BUFFER *buf) {
00225 assert(url);
00226 if (!url->_modified && !(url->url==0 || url->url[0]==0)) {
00227 GWEN_Buffer_AppendString(buf, url->url);
00228 }
00229 else {
00230 GWEN_DB_NODE *dbV;
00231
00232 if (url->protocol) {
00233 GWEN_Buffer_AppendString(buf, url->protocol);
00234 GWEN_Buffer_AppendString(buf, "://");
00235 }
00236 if (url->server) {
00237 GWEN_Buffer_AppendString(buf, url->server);
00238 }
00239 if (url->port) {
00240 char numbuf[32];
00241
00242 snprintf(numbuf, sizeof(numbuf), "%d", url->port);
00243 GWEN_Buffer_AppendString(buf, ":");
00244 GWEN_Buffer_AppendString(buf, numbuf);
00245 }
00246 if (url->path) {
00247 GWEN_Buffer_AppendString(buf, url->path);
00248 }
00249 if (url->vars) {
00250 dbV=GWEN_DB_GetFirstVar(url->vars);
00251 while(dbV) {
00252 const char *s;
00253
00254 s=GWEN_DB_VariableName(dbV);
00255 if (s) {
00256 GWEN_DB_NODE *dbVal;
00257
00258 GWEN_Buffer_AppendString(buf, "?");
00259 GWEN_Buffer_AppendString(buf, s);
00260 dbVal=GWEN_DB_GetFirstValue(dbV);
00261 if (dbVal) {
00262 s=GWEN_DB_GetCharValueFromNode(dbVal);
00263 if (s) {
00264 GWEN_Buffer_AppendString(buf, "=");
00265 GWEN_Buffer_AppendString(buf, s);
00266 }
00267 }
00268 }
00269 dbV=GWEN_DB_GetNextVar(dbV);
00270 }
00271 }
00272 }
00273 return 0;
00274 }
00275
00276
00277
00278 GWEN_URL *GWEN_Url_fromCommandString(const char *str) {
00279 GWEN_URL *url;
00280 GWEN_DB_NODE *dbVars;
00281 const char *s;
00282 const char *p;
00283
00284 url=GWEN_Url_new();
00285 dbVars=GWEN_DB_Group_new("vars");
00286 GWEN_Url_SetVars(url, dbVars);
00287 GWEN_DB_Group_free(dbVars);
00288 dbVars=0;
00289
00290 s=str;
00291
00292
00293 if (*s=='/') {
00294 p=s;
00295 while(*p && *p!='?')
00296 p++;
00297 if (p!=s) {
00298 char *buf;
00299
00300
00301 buf=(char*)malloc(p-s+1);
00302 assert(buf);
00303 memmove(buf, s, p-s+1);
00304 buf[p-s]=0;
00305 GWEN_Url_SetPath(url, buf);
00306 free(buf);
00307 s=p;
00308 }
00309 }
00310 else {
00311 GWEN_Url_SetPath(url, "/");
00312 if (*s)
00313 s++;
00314 }
00315
00316
00317 while(*s && *s=='?') {
00318 GWEN_BUFFER *bName;
00319 GWEN_BUFFER *bValue;
00320
00321 bName=GWEN_Buffer_new(0, 256, 0, 1);
00322 bValue=GWEN_Buffer_new(0, 256, 0, 1);
00323 s++;
00324 p=s;
00325 while(*p && *p!='?' && *p!='=')
00326 p++;
00327 if (p!=s)
00328 GWEN_Buffer_AppendBytes(bName, s, (p-s));
00329 s=p;
00330 if (*p=='=') {
00331 s++;
00332 p=s;
00333 while(*p && *p!='?')
00334 p++;
00335 if (p!=s)
00336 GWEN_Buffer_AppendBytes(bValue, s, (p-s));
00337 s=p;
00338 }
00339
00340 if (GWEN_Buffer_GetUsedBytes(bName))
00341 GWEN_DB_SetCharValue(GWEN_Url_GetVars(url),
00342 GWEN_DB_FLAGS_DEFAULT,
00343 GWEN_Buffer_GetStart(bName),
00344 GWEN_Buffer_GetStart(bValue));
00345 GWEN_Buffer_free(bValue);
00346 GWEN_Buffer_free(bName);
00347 }
00348
00349 url->url=strdup(str);
00350
00351 return url;
00352 }
00353
00354
00355
00356 int GWEN_Url_toCommandString(const GWEN_URL *url, GWEN_BUFFER *buf) {
00357 GWEN_DB_NODE *dbV;
00358
00359 assert(url);
00360
00361 if (url->path) {
00362 GWEN_Buffer_AppendString(buf, url->path);
00363 }
00364 if (url->vars) {
00365 dbV=GWEN_DB_GetFirstVar(url->vars);
00366 while(dbV) {
00367 const char *s;
00368
00369 s=GWEN_DB_VariableName(dbV);
00370 if (s) {
00371 GWEN_DB_NODE *dbVal;
00372
00373 GWEN_Buffer_AppendString(buf, "?");
00374 GWEN_Buffer_AppendString(buf, s);
00375 dbVal=GWEN_DB_GetFirstValue(dbV);
00376 if (dbVal) {
00377 s=GWEN_DB_GetCharValueFromNode(dbVal);
00378 if (s) {
00379 GWEN_Buffer_AppendString(buf, "=");
00380 GWEN_Buffer_AppendString(buf, s);
00381 }
00382 }
00383 }
00384 dbV=GWEN_DB_GetNextVar(dbV);
00385 }
00386 }
00387
00388 return 0;
00389 }
00390
00391
00392