Fossil SCM

Add code to understand the "https://" prefix on server URLs. Any attempt to use https gives an error at this point, however. This is a work in progress.

drh 2009-01-13 18:43 trunk
Commit 797d680ef52b7f88390b82f106275fa6ec55af32
+45
--- src/file.c
+++ src/file.c
@@ -429,5 +429,50 @@
429429
blob_set(pPath, &zUri[i]);
430430
}else{
431431
blob_set(pPath, "/");
432432
}
433433
}
434
+
435
+/*
436
+** Construct a random temporary filename into zBuf[].
437
+*/
438
+void file_tempname(int nBuf, char *zBuf){
439
+ static const char *azDirs[] = {
440
+ "/var/tmp",
441
+ "/usr/tmp",
442
+ "/tmp",
443
+ "/temp",
444
+ ".",
445
+ };
446
+ static const unsigned char zChars[] =
447
+ "abcdefghijklmnopqrstuvwxyz"
448
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
449
+ "0123456789";
450
+ unsigned int i, j;
451
+ struct stat buf;
452
+ const char *zDir = ".";
453
+
454
+ for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
455
+ if( stat(azDirs[i], &buf) ) continue;
456
+ if( !S_ISDIR(buf.st_mode) ) continue;
457
+ if( access(azDirs[i], 07) ) continue;
458
+ zDir = azDirs[i];
459
+ break;
460
+ }
461
+
462
+ /* Check that the output buffer is large enough for the temporary file
463
+ ** name. If it is not, return SQLITE_ERROR.
464
+ */
465
+ if( (strlen(zDir) + 17) >= (size_t)nBuf ){
466
+ fossil_fatal("insufficient space for temporary filename");
467
+ }
468
+
469
+ do{
470
+ sqlite3_snprintf(nBuf-17, zBuf, "%s/", zDir);
471
+ j = (int)strlen(zBuf);
472
+ sqlite3_randomness(15, &zBuf[j]);
473
+ for(i=0; i<15; i++, j++){
474
+ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
475
+ }
476
+ zBuf[j] = 0;
477
+ }while( access(zBuf,0)==0 );
478
+}
434479
--- src/file.c
+++ src/file.c
@@ -429,5 +429,50 @@
429 blob_set(pPath, &zUri[i]);
430 }else{
431 blob_set(pPath, "/");
432 }
433 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
434
--- src/file.c
+++ src/file.c
@@ -429,5 +429,50 @@
429 blob_set(pPath, &zUri[i]);
430 }else{
431 blob_set(pPath, "/");
432 }
433 }
434
435 /*
436 ** Construct a random temporary filename into zBuf[].
437 */
438 void file_tempname(int nBuf, char *zBuf){
439 static const char *azDirs[] = {
440 "/var/tmp",
441 "/usr/tmp",
442 "/tmp",
443 "/temp",
444 ".",
445 };
446 static const unsigned char zChars[] =
447 "abcdefghijklmnopqrstuvwxyz"
448 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
449 "0123456789";
450 unsigned int i, j;
451 struct stat buf;
452 const char *zDir = ".";
453
454 for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
455 if( stat(azDirs[i], &buf) ) continue;
456 if( !S_ISDIR(buf.st_mode) ) continue;
457 if( access(azDirs[i], 07) ) continue;
458 zDir = azDirs[i];
459 break;
460 }
461
462 /* Check that the output buffer is large enough for the temporary file
463 ** name. If it is not, return SQLITE_ERROR.
464 */
465 if( (strlen(zDir) + 17) >= (size_t)nBuf ){
466 fossil_fatal("insufficient space for temporary filename");
467 }
468
469 do{
470 sqlite3_snprintf(nBuf-17, zBuf, "%s/", zDir);
471 j = (int)strlen(zBuf);
472 sqlite3_randomness(15, &zBuf[j]);
473 for(i=0; i<15; i++, j++){
474 zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
475 }
476 zBuf[j] = 0;
477 }while( access(zBuf,0)==0 );
478 }
479
+3 -2
--- src/http.c
+++ src/http.c
@@ -78,14 +78,15 @@
7878
static int http_open_socket(void){
7979
static struct sockaddr_in addr; /* The server address */
8080
static int addrIsInit = 0; /* True once addr is initialized */
8181
int s;
8282
83
+ if( g.urlIsHttps ){
84
+ fossil_fatal("SSL/TLS is not yet implemented.");
85
+ }
8386
ws_init();
84
-
8587
if( !addrIsInit ){
86
-
8788
addr.sin_family = AF_INET;
8889
addr.sin_port = htons(g.urlPort);
8990
*(int*)&addr.sin_addr = inet_addr(g.urlName);
9091
if( -1 == *(int*)&addr.sin_addr ){
9192
#ifndef FOSSIL_STATIC_LINK
9293
--- src/http.c
+++ src/http.c
@@ -78,14 +78,15 @@
78 static int http_open_socket(void){
79 static struct sockaddr_in addr; /* The server address */
80 static int addrIsInit = 0; /* True once addr is initialized */
81 int s;
82
 
 
 
83 ws_init();
84
85 if( !addrIsInit ){
86
87 addr.sin_family = AF_INET;
88 addr.sin_port = htons(g.urlPort);
89 *(int*)&addr.sin_addr = inet_addr(g.urlName);
90 if( -1 == *(int*)&addr.sin_addr ){
91 #ifndef FOSSIL_STATIC_LINK
92
--- src/http.c
+++ src/http.c
@@ -78,14 +78,15 @@
78 static int http_open_socket(void){
79 static struct sockaddr_in addr; /* The server address */
80 static int addrIsInit = 0; /* True once addr is initialized */
81 int s;
82
83 if( g.urlIsHttps ){
84 fossil_fatal("SSL/TLS is not yet implemented.");
85 }
86 ws_init();
 
87 if( !addrIsInit ){
 
88 addr.sin_family = AF_INET;
89 addr.sin_port = htons(g.urlPort);
90 *(int*)&addr.sin_addr = inet_addr(g.urlName);
91 if( -1 == *(int*)&addr.sin_addr ){
92 #ifndef FOSSIL_STATIC_LINK
93
+4 -1
--- src/main.c
+++ src/main.c
@@ -83,13 +83,16 @@
8383
int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */
8484
8585
int *aCommitFile; /* Array of files to be committed */
8686
8787
int urlIsFile; /* True if a "file:" url */
88
+ int urlIsHttps; /* True if a "https:" url */
8889
char *urlName; /* Hostname for http: or filename for file: */
8990
char *urlHostname; /* The HOST: parameter on http headers */
90
- int urlPort; /* TCP port number for http: */
91
+ char *urlProtocol; /* "http" or "https" */
92
+ int urlPort; /* TCP port number for http: or https: */
93
+ int urlDfltPort; /* The default port for the given protocol */
9194
char *urlPath; /* Pathname for http: */
9295
char *urlUser; /* User id for http: */
9396
char *urlPasswd; /* Password for http: */
9497
char *urlCanonical; /* Canonical representation of the URL */
9598
9699
--- src/main.c
+++ src/main.c
@@ -83,13 +83,16 @@
83 int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */
84
85 int *aCommitFile; /* Array of files to be committed */
86
87 int urlIsFile; /* True if a "file:" url */
 
88 char *urlName; /* Hostname for http: or filename for file: */
89 char *urlHostname; /* The HOST: parameter on http headers */
90 int urlPort; /* TCP port number for http: */
 
 
91 char *urlPath; /* Pathname for http: */
92 char *urlUser; /* User id for http: */
93 char *urlPasswd; /* Password for http: */
94 char *urlCanonical; /* Canonical representation of the URL */
95
96
--- src/main.c
+++ src/main.c
@@ -83,13 +83,16 @@
83 int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */
84
85 int *aCommitFile; /* Array of files to be committed */
86
87 int urlIsFile; /* True if a "file:" url */
88 int urlIsHttps; /* True if a "https:" url */
89 char *urlName; /* Hostname for http: or filename for file: */
90 char *urlHostname; /* The HOST: parameter on http headers */
91 char *urlProtocol; /* "http" or "https" */
92 int urlPort; /* TCP port number for http: or https: */
93 int urlDfltPort; /* The default port for the given protocol */
94 char *urlPath; /* Pathname for http: */
95 char *urlUser; /* User id for http: */
96 char *urlPasswd; /* Password for http: */
97 char *urlCanonical; /* Canonical representation of the URL */
98
99
+8 -6
--- src/sync.c
+++ src/sync.c
@@ -55,14 +55,15 @@
5555
}
5656
url_parse(zUrl);
5757
if( g.urlIsFile ){
5858
return; /* Network sync only */
5959
}
60
- if( g.urlPort!=80 ){
61
- printf("Autosync: http://%s:%d%s\n", g.urlName, g.urlPort, g.urlPath);
60
+ if( g.urlPort!=g.urlDfltPort ){
61
+ printf("Autosync: %s://%s:%d%s\n",
62
+ g.urlProtocol, g.urlName, g.urlPort, g.urlPath);
6263
}else{
63
- printf("Autosync: http://%s%s\n", g.urlName, g.urlPath);
64
+ printf("Autosync: %s://%s%s\n", g.urlProtocol, g.urlName, g.urlPath);
6465
}
6566
url_enable_proxy("via proxy: ");
6667
client_sync((flags & AUTOSYNC_PUSH)!=0, 1, 0, 0, 0);
6768
}
6869
@@ -91,14 +92,15 @@
9192
fossil_fatal("network sync only");
9293
}
9394
db_set("last-sync-url", zUrl, 0);
9495
user_select();
9596
if( g.argc==2 ){
96
- if( g.urlPort!=80 ){
97
- printf("Server: http://%s:%d%s\n", g.urlName, g.urlPort, g.urlPath);
97
+ if( g.urlPort!=g.urlDfltPort ){
98
+ printf("Server: %s://%s:%d%s\n",
99
+ g.urlProtocol, g.urlName, g.urlPort, g.urlPath);
98100
}else{
99
- printf("Server: http://%s%s\n", g.urlName, g.urlPath);
101
+ printf("Server: %s://%s%s\n", g.urlProtocol, g.urlName, g.urlPath);
100102
}
101103
}
102104
url_enable_proxy("via proxy: ");
103105
}
104106
105107
--- src/sync.c
+++ src/sync.c
@@ -55,14 +55,15 @@
55 }
56 url_parse(zUrl);
57 if( g.urlIsFile ){
58 return; /* Network sync only */
59 }
60 if( g.urlPort!=80 ){
61 printf("Autosync: http://%s:%d%s\n", g.urlName, g.urlPort, g.urlPath);
 
62 }else{
63 printf("Autosync: http://%s%s\n", g.urlName, g.urlPath);
64 }
65 url_enable_proxy("via proxy: ");
66 client_sync((flags & AUTOSYNC_PUSH)!=0, 1, 0, 0, 0);
67 }
68
@@ -91,14 +92,15 @@
91 fossil_fatal("network sync only");
92 }
93 db_set("last-sync-url", zUrl, 0);
94 user_select();
95 if( g.argc==2 ){
96 if( g.urlPort!=80 ){
97 printf("Server: http://%s:%d%s\n", g.urlName, g.urlPort, g.urlPath);
 
98 }else{
99 printf("Server: http://%s%s\n", g.urlName, g.urlPath);
100 }
101 }
102 url_enable_proxy("via proxy: ");
103 }
104
105
--- src/sync.c
+++ src/sync.c
@@ -55,14 +55,15 @@
55 }
56 url_parse(zUrl);
57 if( g.urlIsFile ){
58 return; /* Network sync only */
59 }
60 if( g.urlPort!=g.urlDfltPort ){
61 printf("Autosync: %s://%s:%d%s\n",
62 g.urlProtocol, g.urlName, g.urlPort, g.urlPath);
63 }else{
64 printf("Autosync: %s://%s%s\n", g.urlProtocol, g.urlName, g.urlPath);
65 }
66 url_enable_proxy("via proxy: ");
67 client_sync((flags & AUTOSYNC_PUSH)!=0, 1, 0, 0, 0);
68 }
69
@@ -91,14 +92,15 @@
92 fossil_fatal("network sync only");
93 }
94 db_set("last-sync-url", zUrl, 0);
95 user_select();
96 if( g.argc==2 ){
97 if( g.urlPort!=g.urlDfltPort ){
98 printf("Server: %s://%s:%d%s\n",
99 g.urlProtocol, g.urlName, g.urlPort, g.urlPath);
100 }else{
101 printf("Server: %s://%s%s\n", g.urlProtocol, g.urlName, g.urlPath);
102 }
103 }
104 url_enable_proxy("via proxy: ");
105 }
106
107
+28 -8
--- src/url.c
+++ src/url.c
@@ -43,25 +43,37 @@
4343
**
4444
*/
4545
void url_parse(const char *zUrl){
4646
int i, j, c;
4747
char *zFile = 0;
48
- if( strncmp(zUrl, "http:", 5)==0 ){
48
+ if( strncmp(zUrl, "http://", 7)==0 || strncmp(zUrl, "https://", 8)==0 ){
49
+ int iStart;
4950
g.urlIsFile = 0;
50
- for(i=7; (c=zUrl[i])!=0 && c!='/' && c!='@'; i++){}
51
+ if( zUrl[4]=='s' ){
52
+ g.urlIsHttps = 1;
53
+ g.urlProtocol = "https";
54
+ g.urlDfltPort = 443;
55
+ iStart = 8;
56
+ }else{
57
+ g.urlIsHttps = 0;
58
+ g.urlProtocol = "http";
59
+ g.urlDfltPort = 80;
60
+ iStart = 7;
61
+ }
62
+ for(i=iStart; (c=zUrl[i])!=0 && c!='/' && c!='@'; i++){}
5163
if( c=='@' ){
52
- for(j=7; j<i && zUrl[j]!=':'; j++){}
53
- g.urlUser = mprintf("%.*s", j-7, &zUrl[7]);
64
+ for(j=iStart; j<i && zUrl[j]!=':'; j++){}
65
+ g.urlUser = mprintf("%.*s", j-iStart, &zUrl[iStart]);
5466
if( j<i ){
5567
g.urlPasswd = mprintf("%.*s", i-j-1, &zUrl[j+1]);
5668
}
5769
for(j=i+1; (c=zUrl[j])!=0 && c!='/' && c!=':'; j++){}
5870
g.urlName = mprintf("%.*s", j-i-1, &zUrl[i+1]);
5971
i = j;
6072
}else{
61
- for(i=7; (c=zUrl[i])!=0 && c!='/' && c!=':'; i++){}
62
- g.urlName = mprintf("%.*s", i-7, &zUrl[7]);
73
+ for(i=iStart; (c=zUrl[i])!=0 && c!='/' && c!=':'; i++){}
74
+ g.urlName = mprintf("%.*s", i-iStart, &zUrl[iStart]);
6375
}
6476
for(j=0; g.urlName[j]; j++){ g.urlName[j] = tolower(g.urlName[j]); }
6577
if( c==':' ){
6678
g.urlPort = 0;
6779
i++;
@@ -69,17 +81,18 @@
6981
g.urlPort = g.urlPort*10 + c - '0';
7082
i++;
7183
}
7284
g.urlHostname = mprintf("%s:%d", g.urlName, g.urlPort);
7385
}else{
74
- g.urlPort = 80;
86
+ g.urlPort = g.urlDfltPort;
7587
g.urlHostname = g.urlName;
7688
}
7789
g.urlPath = mprintf(&zUrl[i]);
7890
dehttpize(g.urlName);
7991
dehttpize(g.urlPath);
80
- g.urlCanonical = mprintf("http://%T:%d%T", g.urlName, g.urlPort, g.urlPath);
92
+ g.urlCanonical = mprintf("%s://%T:%d%T",
93
+ g.urlProtocol, g.urlName, g.urlPort, g.urlPath);
8194
}else if( strncmp(zUrl, "file:", 5)==0 ){
8295
g.urlIsFile = 1;
8396
if( zUrl[5]=='/' && zUrl[6]=='/' ){
8497
i = 7;
8598
}else{
@@ -121,12 +134,15 @@
121134
usage("URL");
122135
}
123136
url_parse(g.argv[2]);
124137
for(i=0; i<2; i++){
125138
printf("g.urlIsFile = %d\n", g.urlIsFile);
139
+ printf("g.urlIsHttps = %d\n", g.urlIsHttps);
140
+ printf("g.urlProtocol = %s\n", g.urlProtocol);
126141
printf("g.urlName = %s\n", g.urlName);
127142
printf("g.urlPort = %d\n", g.urlPort);
143
+ printf("g.urlDfltPort = %d\n", g.urlDfltPort);
128144
printf("g.urlHostname = %s\n", g.urlHostname);
129145
printf("g.urlPath = %s\n", g.urlPath);
130146
printf("g.urlUser = %s\n", g.urlUser);
131147
printf("g.urlPasswd = %s\n", g.urlPasswd);
132148
printf("g.urlCanonical = %s\n", g.urlCanonical);
@@ -154,10 +170,14 @@
154170
}
155171
156172
/*
157173
** If the "proxy" setting is defined, then change the URL to refer
158174
** to the proxy server.
175
+**
176
+** If the protocol is "https://" then start stunnel to handle the SSL
177
+** and make the url setting refer to stunnel rather than the original
178
+** destination.
159179
*/
160180
void url_enable_proxy(const char *zMsg){
161181
const char *zProxy;
162182
zProxy = zProxyOpt;
163183
if( zProxy==0 ){
164184
--- src/url.c
+++ src/url.c
@@ -43,25 +43,37 @@
43 **
44 */
45 void url_parse(const char *zUrl){
46 int i, j, c;
47 char *zFile = 0;
48 if( strncmp(zUrl, "http:", 5)==0 ){
 
49 g.urlIsFile = 0;
50 for(i=7; (c=zUrl[i])!=0 && c!='/' && c!='@'; i++){}
 
 
 
 
 
 
 
 
 
 
 
51 if( c=='@' ){
52 for(j=7; j<i && zUrl[j]!=':'; j++){}
53 g.urlUser = mprintf("%.*s", j-7, &zUrl[7]);
54 if( j<i ){
55 g.urlPasswd = mprintf("%.*s", i-j-1, &zUrl[j+1]);
56 }
57 for(j=i+1; (c=zUrl[j])!=0 && c!='/' && c!=':'; j++){}
58 g.urlName = mprintf("%.*s", j-i-1, &zUrl[i+1]);
59 i = j;
60 }else{
61 for(i=7; (c=zUrl[i])!=0 && c!='/' && c!=':'; i++){}
62 g.urlName = mprintf("%.*s", i-7, &zUrl[7]);
63 }
64 for(j=0; g.urlName[j]; j++){ g.urlName[j] = tolower(g.urlName[j]); }
65 if( c==':' ){
66 g.urlPort = 0;
67 i++;
@@ -69,17 +81,18 @@
69 g.urlPort = g.urlPort*10 + c - '0';
70 i++;
71 }
72 g.urlHostname = mprintf("%s:%d", g.urlName, g.urlPort);
73 }else{
74 g.urlPort = 80;
75 g.urlHostname = g.urlName;
76 }
77 g.urlPath = mprintf(&zUrl[i]);
78 dehttpize(g.urlName);
79 dehttpize(g.urlPath);
80 g.urlCanonical = mprintf("http://%T:%d%T", g.urlName, g.urlPort, g.urlPath);
 
81 }else if( strncmp(zUrl, "file:", 5)==0 ){
82 g.urlIsFile = 1;
83 if( zUrl[5]=='/' && zUrl[6]=='/' ){
84 i = 7;
85 }else{
@@ -121,12 +134,15 @@
121 usage("URL");
122 }
123 url_parse(g.argv[2]);
124 for(i=0; i<2; i++){
125 printf("g.urlIsFile = %d\n", g.urlIsFile);
 
 
126 printf("g.urlName = %s\n", g.urlName);
127 printf("g.urlPort = %d\n", g.urlPort);
 
128 printf("g.urlHostname = %s\n", g.urlHostname);
129 printf("g.urlPath = %s\n", g.urlPath);
130 printf("g.urlUser = %s\n", g.urlUser);
131 printf("g.urlPasswd = %s\n", g.urlPasswd);
132 printf("g.urlCanonical = %s\n", g.urlCanonical);
@@ -154,10 +170,14 @@
154 }
155
156 /*
157 ** If the "proxy" setting is defined, then change the URL to refer
158 ** to the proxy server.
 
 
 
 
159 */
160 void url_enable_proxy(const char *zMsg){
161 const char *zProxy;
162 zProxy = zProxyOpt;
163 if( zProxy==0 ){
164
--- src/url.c
+++ src/url.c
@@ -43,25 +43,37 @@
43 **
44 */
45 void url_parse(const char *zUrl){
46 int i, j, c;
47 char *zFile = 0;
48 if( strncmp(zUrl, "http://", 7)==0 || strncmp(zUrl, "https://", 8)==0 ){
49 int iStart;
50 g.urlIsFile = 0;
51 if( zUrl[4]=='s' ){
52 g.urlIsHttps = 1;
53 g.urlProtocol = "https";
54 g.urlDfltPort = 443;
55 iStart = 8;
56 }else{
57 g.urlIsHttps = 0;
58 g.urlProtocol = "http";
59 g.urlDfltPort = 80;
60 iStart = 7;
61 }
62 for(i=iStart; (c=zUrl[i])!=0 && c!='/' && c!='@'; i++){}
63 if( c=='@' ){
64 for(j=iStart; j<i && zUrl[j]!=':'; j++){}
65 g.urlUser = mprintf("%.*s", j-iStart, &zUrl[iStart]);
66 if( j<i ){
67 g.urlPasswd = mprintf("%.*s", i-j-1, &zUrl[j+1]);
68 }
69 for(j=i+1; (c=zUrl[j])!=0 && c!='/' && c!=':'; j++){}
70 g.urlName = mprintf("%.*s", j-i-1, &zUrl[i+1]);
71 i = j;
72 }else{
73 for(i=iStart; (c=zUrl[i])!=0 && c!='/' && c!=':'; i++){}
74 g.urlName = mprintf("%.*s", i-iStart, &zUrl[iStart]);
75 }
76 for(j=0; g.urlName[j]; j++){ g.urlName[j] = tolower(g.urlName[j]); }
77 if( c==':' ){
78 g.urlPort = 0;
79 i++;
@@ -69,17 +81,18 @@
81 g.urlPort = g.urlPort*10 + c - '0';
82 i++;
83 }
84 g.urlHostname = mprintf("%s:%d", g.urlName, g.urlPort);
85 }else{
86 g.urlPort = g.urlDfltPort;
87 g.urlHostname = g.urlName;
88 }
89 g.urlPath = mprintf(&zUrl[i]);
90 dehttpize(g.urlName);
91 dehttpize(g.urlPath);
92 g.urlCanonical = mprintf("%s://%T:%d%T",
93 g.urlProtocol, g.urlName, g.urlPort, g.urlPath);
94 }else if( strncmp(zUrl, "file:", 5)==0 ){
95 g.urlIsFile = 1;
96 if( zUrl[5]=='/' && zUrl[6]=='/' ){
97 i = 7;
98 }else{
@@ -121,12 +134,15 @@
134 usage("URL");
135 }
136 url_parse(g.argv[2]);
137 for(i=0; i<2; i++){
138 printf("g.urlIsFile = %d\n", g.urlIsFile);
139 printf("g.urlIsHttps = %d\n", g.urlIsHttps);
140 printf("g.urlProtocol = %s\n", g.urlProtocol);
141 printf("g.urlName = %s\n", g.urlName);
142 printf("g.urlPort = %d\n", g.urlPort);
143 printf("g.urlDfltPort = %d\n", g.urlDfltPort);
144 printf("g.urlHostname = %s\n", g.urlHostname);
145 printf("g.urlPath = %s\n", g.urlPath);
146 printf("g.urlUser = %s\n", g.urlUser);
147 printf("g.urlPasswd = %s\n", g.urlPasswd);
148 printf("g.urlCanonical = %s\n", g.urlCanonical);
@@ -154,10 +170,14 @@
170 }
171
172 /*
173 ** If the "proxy" setting is defined, then change the URL to refer
174 ** to the proxy server.
175 **
176 ** If the protocol is "https://" then start stunnel to handle the SSL
177 ** and make the url setting refer to stunnel rather than the original
178 ** destination.
179 */
180 void url_enable_proxy(const char *zMsg){
181 const char *zProxy;
182 zProxy = zProxyOpt;
183 if( zProxy==0 ){
184

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button