Index: mapserver.h
===================================================================
--- mapserver.h	(revision 7494)
+++ mapserver.h	(working copy)
@@ -1605,6 +1605,8 @@
 MS_DLL_EXPORT char *msIntToString(int value);
 MS_DLL_EXPORT void msStringToUpper(char *string);
 MS_DLL_EXPORT void msStringToLower(char *string);
+MS_DLL_EXPORT int msEncodeChar(const char);
+MS_DLL_EXPORT char *msEncodeUrlExcept(const char*, const char);
 MS_DLL_EXPORT char *msEncodeUrl(const char*);
 MS_DLL_EXPORT char *msEncodeHTMLEntities(const char *string);
 MS_DLL_EXPORT void msDecodeHTMLEntities(const char *string);
Index: mapwmslayer.c
===================================================================
--- mapwmslayer.c	(revision 7494)
+++ mapwmslayer.c	(working copy)
@@ -85,7 +85,33 @@
     if (urlencode)
     {
         char *pszTmp;
-        pszTmp = msEncodeUrl(value);
+
+        /*
+         *  Special case handling for characters the WMS specification
+         *  says should not be encoded, when they occur in certain
+         *  parameters.
+         *  
+         *  TODO: WMS 1.3 removes SRS and FORMAT from the set of 
+         *        exceptional cases.
+         */
+        if( strcmp(name,"LAYERS") == 0 ||
+            strcmp(name,"STYLES") == 0 ||
+            strcmp(name,"BBOX") == 0 )
+        {
+            pszTmp = msEncodeUrlExcept(value,',');
+        }
+        else if ( strcmp(name,"SRS") == 0 )
+        {
+            pszTmp = msEncodeUrlExcept(value,':');
+        }
+        else if ( strcmp(name,"FORMAT") == 0 )
+        {
+            pszTmp = msEncodeUrlExcept(value,'/');
+        }
+        else {
+            pszTmp = msEncodeUrl(value);
+        }
+
         msInsertHashTable(psWMSParams->params, name, pszTmp);
         msFree(pszTmp);
     }
@@ -172,6 +198,7 @@
     /* Get rid of trailing '&'*/
     pszURL[nLen-1] = '\0';
 
+
     return pszURL;
 }
 
@@ -235,7 +262,7 @@
 
     psWMSParams->onlineresource = strdup(pszOnlineResource);
 
-    if (strncmp(pszVersion, "1.0.7", 5) < 0)
+    if (strncmp(pszVersion, "1.0.7", 5) < 0) 
         pszVersionKeyword = "WMTVER";
     else
         pszVersionKeyword = "VERSION";
@@ -980,7 +1007,6 @@
  * ------------------------------------------------------------------ */
     pszURL = msBuildURLFromWMSParams(&sThisWMSParams);
 
-
     if (bOkToMerge && (*numRequests)>0)
     {
 /* ------------------------------------------------------------------
Index: mapstring.c
===================================================================
--- mapstring.c	(revision 7494)
+++ mapstring.c	(working copy)
@@ -609,6 +609,40 @@
 
 char *msEncodeUrl(const char *data)
 {
+	return(msEncodeUrlExcept(data, '\0'));
+}
+
+/**********************************************************************
+ *                       msEncodeChar()
+ *
+ * Return 1 if the character argument should be encoded for safety
+ * in URL use and 0 otherwise. Specific character map taken from 
+ * http://www.ietf.org/rfc/rfc2396.txt
+ *
+ **********************************************************************/
+
+int msEncodeChar(const char c)
+{
+  if ( 
+       (c >= 0x61 && c <= 0x7A ) ||   /* Letters a-z */
+       (c >= 0x41 && c <= 0x5A ) ||   /* Letters A-Z */
+       (c >= 0x30 && c <= 0x39 ) ||   /* Numbers 0-9 */
+       (c >= 0x27 && c <= 0x2A ) ||   /* * ' ( )     */
+       (c >= 0x2D && c <= 0x2E ) ||   /* - .         */
+       (c == 0x5F ) ||                /* _           */
+       (c == 0x21 ) ||                /* !           */
+       (c == 0x7E ) )                 /* ~           */
+  {
+    return(0);
+  }
+  else 
+  {
+    return(1);
+  }
+}
+
+char *msEncodeUrlExcept(const char *data, const char except)
+{
   char *hex = "0123456789ABCDEF";
   const char *i;
   char  *j, *code;
@@ -627,7 +661,12 @@
       if (*i == ' ')
 	*j = '+';
       else
-      if (!isalnum(*i))
+      if ( except != '\0' && *i == except )
+        {
+	  *j = except;
+        }
+      else 
+      if (msEncodeChar(*i))
 	{
 	  ch = *i;
 	  *j++ = '%';

