File Annotation
Not logged in
dbda8d6ce9 2007-07-21       drh: /*
dbda8d6ce9 2007-07-21       drh: ** Copyright (c) 2007 D. Richard Hipp
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: ** This program is free software; you can redistribute it and/or
dbda8d6ce9 2007-07-21       drh: ** modify it under the terms of the GNU General Public
dbda8d6ce9 2007-07-21       drh: ** License version 2 as published by the Free Software Foundation.
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: ** This program is distributed in the hope that it will be useful,
dbda8d6ce9 2007-07-21       drh: ** but WITHOUT ANY WARRANTY; without even the implied warranty of
dbda8d6ce9 2007-07-21       drh: ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
dbda8d6ce9 2007-07-21       drh: ** General Public License for more details.
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: ** You should have received a copy of the GNU General Public
dbda8d6ce9 2007-07-21       drh: ** License along with this library; if not, write to the
dbda8d6ce9 2007-07-21       drh: ** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
dbda8d6ce9 2007-07-21       drh: ** Boston, MA  02111-1307, USA.
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: ** Author contact information:
dbda8d6ce9 2007-07-21       drh: **   drh@hwaci.com
dbda8d6ce9 2007-07-21       drh: **   http://www.hwaci.com/drh/
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: *******************************************************************************
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: ** This file contains code for parsing URLs that appear on the command-line
dbda8d6ce9 2007-07-21       drh: */
dbda8d6ce9 2007-07-21       drh: #include "config.h"
dbda8d6ce9 2007-07-21       drh: #include "url.h"
dbda8d6ce9 2007-07-21       drh: 
dbda8d6ce9 2007-07-21       drh: /*
dbda8d6ce9 2007-07-21       drh: ** Parse the given URL.  Populate variables in the global "g" structure.
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: **      g.urlIsFile      True if this is a file URL
dbda8d6ce9 2007-07-21       drh: **      g.urlName        Hostname for HTTP:.  Filename for FILE:
dbda8d6ce9 2007-07-21       drh: **      g.urlPort        Port name for HTTP.
dbda8d6ce9 2007-07-21       drh: **      g.urlPath        Path name for HTTP.
e621b6dbe3 2007-07-30       drh: **      g.urlUser        Userid.
e621b6dbe3 2007-07-30       drh: **      g.urlPasswd      Password.
dbda8d6ce9 2007-07-21       drh: **      g.urlCanonical   The URL in canonical form
3dcaed8d86 2007-07-28       dan: **
e621b6dbe3 2007-07-30       drh: ** HTTP url format is:
3dcaed8d86 2007-07-28       dan: **
e621b6dbe3 2007-07-30       drh: **     http://userid:password@host:port/path?query#fragment
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: */
dbda8d6ce9 2007-07-21       drh: void url_parse(const char *zUrl){
dbda8d6ce9 2007-07-21       drh:   int i, j, c;
e621b6dbe3 2007-07-30       drh:   char *zFile = 0;
797d680ef5 2009-01-13       drh:   if( strncmp(zUrl, "http://", 7)==0 || strncmp(zUrl, "https://", 8)==0 ){
797d680ef5 2009-01-13       drh:     int iStart;
dbda8d6ce9 2007-07-21       drh:     g.urlIsFile = 0;
797d680ef5 2009-01-13       drh:     if( zUrl[4]=='s' ){
797d680ef5 2009-01-13       drh:       g.urlIsHttps = 1;
797d680ef5 2009-01-13       drh:       g.urlProtocol = "https";
797d680ef5 2009-01-13       drh:       g.urlDfltPort = 443;
797d680ef5 2009-01-13       drh:       iStart = 8;
797d680ef5 2009-01-13       drh:     }else{
797d680ef5 2009-01-13       drh:       g.urlIsHttps = 0;
797d680ef5 2009-01-13       drh:       g.urlProtocol = "http";
797d680ef5 2009-01-13       drh:       g.urlDfltPort = 80;
797d680ef5 2009-01-13       drh:       iStart = 7;
797d680ef5 2009-01-13       drh:     }
797d680ef5 2009-01-13       drh:     for(i=iStart; (c=zUrl[i])!=0 && c!='/' && c!='@'; i++){}
e621b6dbe3 2007-07-30       drh:     if( c=='@' ){
797d680ef5 2009-01-13       drh:       for(j=iStart; j<i && zUrl[j]!=':'; j++){}
797d680ef5 2009-01-13       drh:       g.urlUser = mprintf("%.*s", j-iStart, &zUrl[iStart]);
e621b6dbe3 2007-07-30       drh:       if( j<i ){
e621b6dbe3 2007-07-30       drh:         g.urlPasswd = mprintf("%.*s", i-j-1, &zUrl[j+1]);
e621b6dbe3 2007-07-30       drh:       }
e621b6dbe3 2007-07-30       drh:       for(j=i+1; (c=zUrl[j])!=0 && c!='/' && c!=':'; j++){}
e621b6dbe3 2007-07-30       drh:       g.urlName = mprintf("%.*s", j-i-1, &zUrl[i+1]);
e621b6dbe3 2007-07-30       drh:       i = j;
e621b6dbe3 2007-07-30       drh:     }else{
797d680ef5 2009-01-13       drh:       for(i=iStart; (c=zUrl[i])!=0 && c!='/' && c!=':'; i++){}
797d680ef5 2009-01-13       drh:       g.urlName = mprintf("%.*s", i-iStart, &zUrl[iStart]);
e621b6dbe3 2007-07-30       drh:     }
dbda8d6ce9 2007-07-21       drh:     for(j=0; g.urlName[j]; j++){ g.urlName[j] = tolower(g.urlName[j]); }
dbda8d6ce9 2007-07-21       drh:     if( c==':' ){
dbda8d6ce9 2007-07-21       drh:       g.urlPort = 0;
dbda8d6ce9 2007-07-21       drh:       i++;
dbda8d6ce9 2007-07-21       drh:       while( (c = zUrl[i])!=0 && isdigit(c) ){
dbda8d6ce9 2007-07-21       drh:         g.urlPort = g.urlPort*10 + c - '0';
dbda8d6ce9 2007-07-21       drh:         i++;
dbda8d6ce9 2007-07-21       drh:       }
1dbf332352 2008-05-05       drh:       g.urlHostname = mprintf("%s:%d", g.urlName, g.urlPort);
dbda8d6ce9 2007-07-21       drh:     }else{
797d680ef5 2009-01-13       drh:       g.urlPort = g.urlDfltPort;
1dbf332352 2008-05-05       drh:       g.urlHostname = g.urlName;
dbda8d6ce9 2007-07-21       drh:     }
dbda8d6ce9 2007-07-21       drh:     g.urlPath = mprintf(&zUrl[i]);
dbda8d6ce9 2007-07-21       drh:     dehttpize(g.urlName);
dbda8d6ce9 2007-07-21       drh:     dehttpize(g.urlPath);
797d680ef5 2009-01-13       drh:     g.urlCanonical = mprintf("%s://%T:%d%T",
797d680ef5 2009-01-13       drh:          g.urlProtocol, g.urlName, g.urlPort, g.urlPath);
dbda8d6ce9 2007-07-21       drh:   }else if( strncmp(zUrl, "file:", 5)==0 ){
dbda8d6ce9 2007-07-21       drh:     g.urlIsFile = 1;
dbda8d6ce9 2007-07-21       drh:     if( zUrl[5]=='/' && zUrl[6]=='/' ){
dbda8d6ce9 2007-07-21       drh:       i = 7;
dbda8d6ce9 2007-07-21       drh:     }else{
dbda8d6ce9 2007-07-21       drh:       i = 5;
dbda8d6ce9 2007-07-21       drh:     }
dbda8d6ce9 2007-07-21       drh:     zFile = mprintf("%s", &zUrl[i]);
dbda8d6ce9 2007-07-21       drh:   }else if( file_isfile(zUrl) ){
dbda8d6ce9 2007-07-21       drh:     g.urlIsFile = 1;
dbda8d6ce9 2007-07-21       drh:     zFile = mprintf("%s", zUrl);
dbda8d6ce9 2007-07-21       drh:   }else if( file_isdir(zUrl)==1 ){
dbda8d6ce9 2007-07-21       drh:     zFile = mprintf("%s/FOSSIL", zUrl);
dbda8d6ce9 2007-07-21       drh:     if( file_isfile(zFile) ){
dbda8d6ce9 2007-07-21       drh:       g.urlIsFile = 1;
dbda8d6ce9 2007-07-21       drh:     }else{
dbda8d6ce9 2007-07-21       drh:       free(zFile);
dbda8d6ce9 2007-07-21       drh:       fossil_panic("unknown repository: %s", zUrl);
dbda8d6ce9 2007-07-21       drh:     }
dbda8d6ce9 2007-07-21       drh:   }else{
dbda8d6ce9 2007-07-21       drh:     fossil_panic("unknown repository: %s", zUrl);
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   if( g.urlIsFile ){
dbda8d6ce9 2007-07-21       drh:     Blob cfile;
dbda8d6ce9 2007-07-21       drh:     dehttpize(zFile);
dbda8d6ce9 2007-07-21       drh:     file_canonical_name(zFile, &cfile);
dbda8d6ce9 2007-07-21       drh:     free(zFile);
945ecd1a8b 2009-04-11       drh:     g.urlProtocol = "file";
945ecd1a8b 2009-04-11       drh:     g.urlPath = "";
dbda8d6ce9 2007-07-21       drh:     g.urlName = mprintf("%b", &cfile);
dbda8d6ce9 2007-07-21       drh:     g.urlCanonical = mprintf("file://%T", g.urlName);
dbda8d6ce9 2007-07-21       drh:     blob_reset(&cfile);
dbda8d6ce9 2007-07-21       drh:   }
e621b6dbe3 2007-07-30       drh: }
e621b6dbe3 2007-07-30       drh: 
e621b6dbe3 2007-07-30       drh: /*
e621b6dbe3 2007-07-30       drh: ** COMMAND: test-urlparser
e621b6dbe3 2007-07-30       drh: */
e621b6dbe3 2007-07-30       drh: void cmd_test_urlparser(void){
1dbf332352 2008-05-05       drh:   int i;
f652599003 2008-05-06       drh:   url_proxy_options();
676fdd088a 2008-05-01       drh:   if( g.argc!=3 && g.argc!=4 ){
e621b6dbe3 2007-07-30       drh:     usage("URL");
e621b6dbe3 2007-07-30       drh:   }
e621b6dbe3 2007-07-30       drh:   url_parse(g.argv[2]);
1dbf332352 2008-05-05       drh:   for(i=0; i<2; i++){
1dbf332352 2008-05-05       drh:     printf("g.urlIsFile    = %d\n", g.urlIsFile);
797d680ef5 2009-01-13       drh:     printf("g.urlIsHttps   = %d\n", g.urlIsHttps);
797d680ef5 2009-01-13       drh:     printf("g.urlProtocol  = %s\n", g.urlProtocol);
1dbf332352 2008-05-05       drh:     printf("g.urlName      = %s\n", g.urlName);
1dbf332352 2008-05-05       drh:     printf("g.urlPort      = %d\n", g.urlPort);
797d680ef5 2009-01-13       drh:     printf("g.urlDfltPort  = %d\n", g.urlDfltPort);
1dbf332352 2008-05-05       drh:     printf("g.urlHostname  = %s\n", g.urlHostname);
1dbf332352 2008-05-05       drh:     printf("g.urlPath      = %s\n", g.urlPath);
1dbf332352 2008-05-05       drh:     printf("g.urlUser      = %s\n", g.urlUser);
1dbf332352 2008-05-05       drh:     printf("g.urlPasswd    = %s\n", g.urlPasswd);
1dbf332352 2008-05-05       drh:     printf("g.urlCanonical = %s\n", g.urlCanonical);
1dbf332352 2008-05-05       drh:     if( i==0 ){
1dbf332352 2008-05-05       drh:       printf("********\n");
1dbf332352 2008-05-05       drh:       url_enable_proxy("Using proxy: ");
1dbf332352 2008-05-05       drh:     }
1dbf332352 2008-05-05       drh:   }
1dbf332352 2008-05-05       drh: }
1dbf332352 2008-05-05       drh: 
1dbf332352 2008-05-05       drh: /*
f652599003 2008-05-06       drh: ** Proxy specified on the command-line.
f652599003 2008-05-06       drh: */
f652599003 2008-05-06       drh: static const char *zProxyOpt = 0;
f652599003 2008-05-06       drh: 
f652599003 2008-05-06       drh: /*
f652599003 2008-05-06       drh: ** Extra any proxy options from the command-line.
f652599003 2008-05-06       drh: **
f652599003 2008-05-06       drh: **    --proxy URL|off
f652599003 2008-05-06       drh: **
f652599003 2008-05-06       drh: */
f652599003 2008-05-06       drh: void url_proxy_options(void){
f652599003 2008-05-06       drh:   zProxyOpt = find_option("proxy", 0, 1);
ec82a32b80 2008-05-10       drh:   if( find_option("nosync",0,0) ) g.fNoSync = 1;
676fdd088a 2008-05-01       drh: }
676fdd088a 2008-05-01       drh: 
676fdd088a 2008-05-01       drh: /*
676fdd088a 2008-05-01       drh: ** If the "proxy" setting is defined, then change the URL to refer
676fdd088a 2008-05-01       drh: ** to the proxy server.
797d680ef5 2009-01-13       drh: **
797d680ef5 2009-01-13       drh: ** If the protocol is "https://" then start stunnel to handle the SSL
797d680ef5 2009-01-13       drh: ** and make the url setting refer to stunnel rather than the original
797d680ef5 2009-01-13       drh: ** destination.
676fdd088a 2008-05-01       drh: */
676fdd088a 2008-05-01       drh: void url_enable_proxy(const char *zMsg){
f652599003 2008-05-06       drh:   const char *zProxy;
f652599003 2008-05-06       drh:   zProxy = zProxyOpt;
f652599003 2008-05-06       drh:   if( zProxy==0 ){
f652599003 2008-05-06       drh:     zProxy = db_get("proxy", 0);
d65d619d94 2008-10-25  a0756885:     if( zProxy==0 || zProxy[0]==0 || is_truth(zProxy) ){
f652599003 2008-05-06       drh:       zProxy = getenv("http_proxy");
f652599003 2008-05-06       drh:     }
387cbeda3f 2008-05-05       drh:   }
676fdd088a 2008-05-01       drh:   if( zProxy && zProxy[0] && !is_false(zProxy) ){
676fdd088a 2008-05-01       drh:     char *zOriginalUrl = g.urlCanonical;
1dbf332352 2008-05-05       drh:     char *zOriginalHost = g.urlHostname;
676fdd088a 2008-05-01       drh:     if( zMsg ) printf("%s%s\n", zMsg, zProxy);
676fdd088a 2008-05-01       drh:     url_parse(zProxy);
676fdd088a 2008-05-01       drh:     g.urlPath = zOriginalUrl;
1dbf332352 2008-05-05       drh:     g.urlHostname = zOriginalHost;
1dbf332352 2008-05-05       drh:   }
c9cd128c2c 2008-11-02       drh: }
c9cd128c2c 2008-11-02       drh: 
c9cd128c2c 2008-11-02       drh: #if INTERFACE
c9cd128c2c 2008-11-02       drh: /*
c9cd128c2c 2008-11-02       drh: ** An instance of this object is used to build a URL with query parameters.
c9cd128c2c 2008-11-02       drh: */
c9cd128c2c 2008-11-02       drh: struct HQuery {
c9cd128c2c 2008-11-02       drh:   Blob url;                  /* The URL */
c9cd128c2c 2008-11-02       drh:   const char *zBase;         /* The base URL */
c9cd128c2c 2008-11-02       drh:   int nParam;                /* Number of parameters.  Max 10 */
c9cd128c2c 2008-11-02       drh:   const char *azName[10];    /* Parameter names */
c9cd128c2c 2008-11-02       drh:   const char *azValue[10];   /* Parameter values */
c9cd128c2c 2008-11-02       drh: };
c9cd128c2c 2008-11-02       drh: #endif
c9cd128c2c 2008-11-02       drh: 
c9cd128c2c 2008-11-02       drh: /*
c9cd128c2c 2008-11-02       drh: ** Initialize the URL object.
c9cd128c2c 2008-11-02       drh: */
c9cd128c2c 2008-11-02       drh: void url_initialize(HQuery *p, const char *zBase){
c9cd128c2c 2008-11-02       drh:   blob_zero(&p->url);
c9cd128c2c 2008-11-02       drh:   p->zBase = zBase;
c9cd128c2c 2008-11-02       drh:   p->nParam = 0;
c9cd128c2c 2008-11-02       drh: }
c9cd128c2c 2008-11-02       drh: 
c9cd128c2c 2008-11-02       drh: /*
c9cd128c2c 2008-11-02       drh: ** Add a fixed parameter to an HQuery.
c9cd128c2c 2008-11-02       drh: */
c9cd128c2c 2008-11-02       drh: void url_add_parameter(HQuery *p, const char *zName, const char *zValue){
c9cd128c2c 2008-11-02       drh:   assert( p->nParam < count(p->azName) );
c9cd128c2c 2008-11-02       drh:   assert( p->nParam < count(p->azValue) );
c9cd128c2c 2008-11-02       drh:   p->azName[p->nParam] = zName;
c9cd128c2c 2008-11-02       drh:   p->azValue[p->nParam] = zValue;
c9cd128c2c 2008-11-02       drh:   p->nParam++;
c9cd128c2c 2008-11-02       drh: }
c9cd128c2c 2008-11-02       drh: 
c9cd128c2c 2008-11-02       drh: /*
c9cd128c2c 2008-11-02       drh: ** Render the URL with a parameter override.
c9cd128c2c 2008-11-02       drh: */
c9cd128c2c 2008-11-02       drh: char *url_render(
c9cd128c2c 2008-11-02       drh:   HQuery *p,              /* Base URL */
c9cd128c2c 2008-11-02       drh:   const char *zName1,     /* First override */
c9cd128c2c 2008-11-02       drh:   const char *zValue1,    /* First override value */
c9cd128c2c 2008-11-02       drh:   const char *zName2,     /* Second override */
c9cd128c2c 2008-11-02       drh:   const char *zValue2     /* Second override value */
c9cd128c2c 2008-11-02       drh: ){
c9cd128c2c 2008-11-02       drh:   const char *zSep = "?";
c9cd128c2c 2008-11-02       drh:   int i;
c9cd128c2c 2008-11-02       drh: 
c9cd128c2c 2008-11-02       drh:   blob_reset(&p->url);
c9cd128c2c 2008-11-02       drh:   blob_appendf(&p->url, "%s/%s", g.zBaseURL, p->zBase);
c9cd128c2c 2008-11-02       drh:   for(i=0; i<p->nParam; i++){
c9cd128c2c 2008-11-02       drh:     const char *z = p->azValue[i];
c9cd128c2c 2008-11-02       drh:     if( zName1 && strcmp(zName1,p->azName[i])==0 ){
c9cd128c2c 2008-11-02       drh:       zName1 = 0;
c9cd128c2c 2008-11-02       drh:       z = zValue1;
c9cd128c2c 2008-11-02       drh:       if( z==0 ) continue;
c9cd128c2c 2008-11-02       drh:     }
c9cd128c2c 2008-11-02       drh:     if( zName2 && strcmp(zName2,p->azName[i])==0 ){
c9cd128c2c 2008-11-02       drh:       zName2 = 0;
c9cd128c2c 2008-11-02       drh:       z = zValue2;
c9cd128c2c 2008-11-02       drh:       if( z==0 ) continue;
c9cd128c2c 2008-11-02       drh:     }
c9cd128c2c 2008-11-02       drh:     blob_appendf(&p->url, "%s%s=%T", zSep, p->azName[i], z);
c9cd128c2c 2008-11-02       drh:     zSep = "&";
c9cd128c2c 2008-11-02       drh:   }
c9cd128c2c 2008-11-02       drh:   if( zName1 && zValue1 ){
c9cd128c2c 2008-11-02       drh:     blob_appendf(&p->url, "%s%s=%T", zSep, zName1, zValue1);
c9cd128c2c 2008-11-02       drh:   }
c9cd128c2c 2008-11-02       drh:   if( zName2 && zValue2 ){
c9cd128c2c 2008-11-02       drh:     blob_appendf(&p->url, "%s%s=%T", zSep, zName2, zValue2);
676fdd088a 2008-05-01       drh:   }
c9cd128c2c 2008-11-02       drh:   return blob_str(&p->url);
dbda8d6ce9 2007-07-21       drh: }