query-part: ignore the URI part for given protocols
authorJonas Schnelli <jonas.schnelli@include7.ch>
Thu, 24 Nov 2011 22:28:54 +0000 (23:28 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Thu, 24 Nov 2011 22:31:19 +0000 (23:31 +0100)
By setting PROTOPT_NOURLQUERY in the protocol handler struct, the
protocol will get the "query part" of the URL cut off before the data is
handled by the protocol-specific code. This makes libcurl adhere to
RFC3986 section 2.2.

Test 1220 is added to verify a file:// URL with query-part.

13 files changed:
lib/dict.c
lib/file.c
lib/ftp.c
lib/imap.c
lib/pop3.c
lib/smtp.c
lib/ssh.c
lib/telnet.c
lib/tftp.c
lib/url.c
lib/urldata.h
tests/data/Makefile.am
tests/data/test1220 [new file with mode: 0644]

index b326054..0fad32b 100644 (file)
@@ -98,7 +98,7 @@ const struct Curl_handler Curl_handler_dict = {
   ZERO_NULL,                            /* readwrite */
   PORT_DICT,                            /* defport */
   CURLPROTO_DICT,                       /* protocol */
-  PROTOPT_NONE                          /* flags */
+  PROTOPT_NONE | PROTOPT_NOURLQUERY      /* flags */
 };
 
 static char *unescape_word(struct SessionHandle *data, const char *inputbuff)
index 9421c44..4447c73 100644 (file)
@@ -119,7 +119,7 @@ const struct Curl_handler Curl_handler_file = {
   ZERO_NULL,                            /* readwrite */
   0,                                    /* defport */
   CURLPROTO_FILE,                       /* protocol */
-  PROTOPT_NONETWORK                     /* flags */
+  PROTOPT_NONETWORK | PROTOPT_NOURLQUERY /* flags */
 };
 
 
index e5b1682..05f6f45 100644 (file)
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -178,7 +178,8 @@ const struct Curl_handler Curl_handler_ftp = {
   ZERO_NULL,                       /* readwrite */
   PORT_FTP,                        /* defport */
   CURLPROTO_FTP,                   /* protocol */
-  PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD /* flags */
+  PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD
+  | PROTOPT_NOURLQUERY /* flags */
 };
 
 
@@ -205,7 +206,7 @@ const struct Curl_handler Curl_handler_ftps = {
   PORT_FTPS,                       /* defport */
   CURLPROTO_FTP | CURLPROTO_FTPS,  /* protocol */
   PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION |
-  PROTOPT_NEEDSPWD /* flags */
+  PROTOPT_NEEDSPWD | PROTOPT_NOURLQUERY /* flags */
 };
 #endif
 
index ab53c9d..c98730c 100644 (file)
@@ -125,7 +125,8 @@ const struct Curl_handler Curl_handler_imap = {
   ZERO_NULL,                        /* readwrite */
   PORT_IMAP,                        /* defport */
   CURLPROTO_IMAP,                   /* protocol */
-  PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD /* flags */
+  PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD
+  | PROTOPT_NOURLQUERY              /* flags */
 };
 
 
@@ -151,7 +152,8 @@ const struct Curl_handler Curl_handler_imaps = {
   ZERO_NULL,                        /* readwrite */
   PORT_IMAPS,                       /* defport */
   CURLPROTO_IMAP | CURLPROTO_IMAPS, /* protocol */
-  PROTOPT_CLOSEACTION | PROTOPT_SSL | PROTOPT_NEEDSPWD /* flags */
+  PROTOPT_CLOSEACTION | PROTOPT_SSL | PROTOPT_NEEDSPWD
+  | PROTOPT_NOURLQUERY              /* flags */
 };
 #endif
 
index 6cda3bc..8fd8ab0 100644 (file)
@@ -125,7 +125,7 @@ const struct Curl_handler Curl_handler_pop3 = {
   ZERO_NULL,                        /* readwrite */
   PORT_POP3,                        /* defport */
   CURLPROTO_POP3,                   /* protocol */
-  PROTOPT_CLOSEACTION               /* flags */
+  PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY /* flags */
 };
 
 
@@ -151,7 +151,8 @@ const struct Curl_handler Curl_handler_pop3s = {
   ZERO_NULL,                        /* readwrite */
   PORT_POP3S,                       /* defport */
   CURLPROTO_POP3 | CURLPROTO_POP3S, /* protocol */
-  PROTOPT_CLOSEACTION | PROTOPT_SSL /* flags */
+  PROTOPT_CLOSEACTION | PROTOPT_SSL
+  | PROTOPT_NOURLQUERY              /* flags */
 };
 #endif
 
index ea6bafa..7512f1d 100644 (file)
@@ -133,7 +133,7 @@ const struct Curl_handler Curl_handler_smtp = {
   ZERO_NULL,                        /* readwrite */
   PORT_SMTP,                        /* defport */
   CURLPROTO_SMTP,                   /* protocol */
-  PROTOPT_CLOSEACTION               /* flags */
+  PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY /* flags */
 };
 
 #ifdef USE_SSL
@@ -158,7 +158,8 @@ const struct Curl_handler Curl_handler_smtps = {
   ZERO_NULL,                        /* readwrite */
   PORT_SMTPS,                       /* defport */
   CURLPROTO_SMTP | CURLPROTO_SMTPS, /* protocol */
-  PROTOPT_CLOSEACTION | PROTOPT_SSL /* flags */
+  PROTOPT_CLOSEACTION | PROTOPT_SSL
+  | PROTOPT_NOURLQUERY              /* flags */
 };
 #endif
 
index 410f397..91aa440 100644 (file)
--- a/lib/ssh.c
+++ b/lib/ssh.c
@@ -171,7 +171,8 @@ const struct Curl_handler Curl_handler_scp = {
   ZERO_NULL,                            /* readwrite */
   PORT_SSH,                             /* defport */
   CURLPROTO_SCP,                        /* protocol */
-  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION /* flags */
+  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
+  | PROTOPT_NOURLQUERY                  /* flags */
 };
 
 
@@ -196,7 +197,8 @@ const struct Curl_handler Curl_handler_sftp = {
   ZERO_NULL,                            /* readwrite */
   PORT_SSH,                             /* defport */
   CURLPROTO_SFTP,                       /* protocol */
-  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION /* flags */
+  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
+  | PROTOPT_NOURLQUERY                  /* flags */
 };
 
 
index 59094b6..bbad08d 100644 (file)
@@ -188,7 +188,7 @@ const struct Curl_handler Curl_handler_telnet = {
   ZERO_NULL,                            /* readwrite */
   PORT_TELNET,                          /* defport */
   CURLPROTO_TELNET,                     /* protocol */
-  PROTOPT_NONE                          /* flags */
+  PROTOPT_NONE | PROTOPT_NOURLQUERY     /* flags */
 };
 
 
index 9b44a9b..370665a 100644 (file)
@@ -190,7 +190,7 @@ const struct Curl_handler Curl_handler_tftp = {
   ZERO_NULL,                            /* readwrite */
   PORT_TFTP,                            /* defport */
   CURLPROTO_TFTP,                       /* protocol */
-  PROTOPT_NONE                          /* flags */
+  PROTOPT_NONE | PROTOPT_NOURLQUERY     /* flags */
 };
 
 /**********************************************************
index 517dc18..2c5cb39 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -4824,6 +4824,25 @@ static CURLcode create_conn(struct SessionHandle *data,
   if(result != CURLE_OK)
     return result;
 
+
+  /*************************************************************
+   * If the protocol can't handle url query strings, then cut
+   * of the unhandable part
+   *************************************************************/
+  if((conn->given->flags&PROTOPT_NOURLQUERY)) {
+    char *path_q_sep = strchr(conn->data->state.path, '?');
+    if(path_q_sep) {
+      /* according to rfc3986, allow the query (?foo=bar)
+         also on protocols that can't handle it.
+
+        cut the string-part after '?'
+         */
+
+      /* terminate the string */
+      path_q_sep[0] = 0;
+    }
+  }
+
 #ifndef CURL_DISABLE_PROXY
   /*************************************************************
    * Extract the user and password from the authentication string
index 3e7db25..55f0a7b 100644 (file)
@@ -713,6 +713,8 @@ struct Curl_handler {
 #define PROTOPT_NONETWORK (1<<4)   /* protocol doesn't use the network! */
 #define PROTOPT_NEEDSPWD (1<<5)    /* needs a password, and if none is set it
                                       gets a default */
+#define PROTOPT_NOURLQUERY (1<<6)   /* protocol can't handle
+                                        url query strings (?foo=bar) ! */
 
 
 /* return the count of bytes sent, or -1 on error */
index c52ef24..2d86aa1 100644 (file)
@@ -78,6 +78,7 @@ test1118 test1119 test1120 test1121 test1122 test1123 test1124 test1125       \
 test1126 test1127 test1128 test1129 test1130 test1131 \
 test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 \
 test1208 test1209 test1210 \
+test1220 \
 test1300 test1301 test1302 test1303 test1304 test1305  \
 test1306 test1307 test1308 test1309 test1310 test1311 test1312 test1313 \
 test1314 \
diff --git a/tests/data/test1220 b/tests/data/test1220
new file mode 100644 (file)
index 0000000..d365249
--- /dev/null
@@ -0,0 +1,30 @@
+<testcase>
+# Server-side
+<reply>
+<data>
+</data>
+</reply>
+
+# Client-side
+<client>
+<server>
+file
+</server>
+ <name>
+file:// URLs with query string
+ </name>
+ <command>
+file://localhost/%PWD/log/test1220.txt?a_query=foobar#afragment
+</command>
+<file name="log/test1220.txt">
+contents in a single file
+</file>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+<stdout>
+contents in a single file
+</stdout>
+</verify>
+</testcase>