Ensure query strings are escaped properly; fixes #324
diff --git a/params.go b/params.go
index 68c17eb..a980903 100644
--- a/params.go
+++ b/params.go
@@ -103,7 +103,8 @@
 		optsType = optsType.Elem()
 	}
 
-	var optsSlice []string
+	params := url.Values{}
+
 	if optsValue.Kind() == reflect.Struct {
 		for i := 0; i < optsValue.NumField(); i++ {
 			v := optsValue.Field(i)
@@ -118,11 +119,11 @@
 				if !isZero(v) {
 					switch v.Kind() {
 					case reflect.String:
-						optsSlice = append(optsSlice, tags[0]+"="+v.String())
+						params.Add(tags[0], v.String())
 					case reflect.Int:
-						optsSlice = append(optsSlice, tags[0]+"="+strconv.FormatInt(v.Int(), 10))
+						params.Add(tags[0], strconv.FormatInt(v.Int(), 10))
 					case reflect.Bool:
-						optsSlice = append(optsSlice, tags[0]+"="+strconv.FormatBool(v.Bool()))
+						params.Add(tags[0], strconv.FormatBool(v.Bool()))
 					}
 				} else {
 					// Otherwise, the field is not set.
@@ -132,18 +133,9 @@
 					}
 				}
 			}
+		}
 
-		}
-		// URL encode the string for safety.
-		s := strings.Join(optsSlice, "&")
-		if s != "" {
-			s = "?" + s
-		}
-		u, err := url.Parse(s)
-		if err != nil {
-			return nil, err
-		}
-		return u, nil
+		return &url.URL{RawQuery: params.Encode()}, nil
 	}
 	// Return an error if the underlying type of 'opts' isn't a struct.
 	return nil, fmt.Errorf("Options type is not a struct.")