Repository: netty/netty
Issue: Wish MixedAttribute support user defined charset
Labels: feature

MemoryAttribute 's constructor has no i can defined charset .

>    public MemoryAttribute(String name) {
>         super(name, HttpConstants.DEFAULT_CHARSET, 0);
>      }

when i send a utf-8 request ,the gbk encoded server can never decode it correctly !!!
i hope there is a  MemoryAttribute constructor 

>    public MemoryAttribute(String name, Charset charset ) 

so when i want yo use HttpPostRequestDecoder

>    new HttpPostRequestDecoder(new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE), httpRequest, user_define_charset);

i can use this :

>    new HttpPostRequestDecoder(new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE,user_define_charset), httpRequest, user_define_charset);

then

>    Attribute attribute = new MixedAttribute(name, minSize,user_define_charset);

then i got what i want .


Issue comments:
@BabyDuncan would you mind do the changes and submit a pullreq ?

ok , i will do that  .

hi @normanmaurer ,netty 4.x is build under jdk 1.7  , but the applications base on netty 4.x can be build under jdk 1.6 , why ? 

If your application runs on Java 7, Netty will make use of the new classes in Java 7.  Otherwise, it will only use the classes in Java 6 for maximum compatibility.

@trustin wow,it is cool ！


Pull request review comments:
Should it be?

 attribute = new DiskAttribute(name, value, charset);

yes it should be . i will fix that  .

Not sure it is better, but we could call the very same constructor inside. Something like:

```
public DefaultHttpDataFactory(long minSize, Charset charset) {
    this(minSize);
    this.charset = charset;
}
```

But really not mandatory

Agree @BabyDuncan please do the changes @fredericBregier suggested

yes , 

```
public DefaultHttpDataFactory(long minSize, Charset charset) {
    this(minSize);
    this.charset = charset;
}
```

is better .


Patch that resolved the issue:
diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/multipart/DefaultHttpDataFactory.java b/codec-http/src/main/java/io/netty/handler/codec/http/multipart/DefaultHttpDataFactory.java
index 8f6f68e18b5..24873fa4279 100644
--- a/codec-http/src/main/java/io/netty/handler/codec/http/multipart/DefaultHttpDataFactory.java
+++ b/codec-http/src/main/java/io/netty/handler/codec/http/multipart/DefaultHttpDataFactory.java
@@ -15,6 +15,7 @@
  */
 package io.netty.handler.codec.http.multipart;
 
+import io.netty.handler.codec.http.HttpConstants;
 import io.netty.handler.codec.http.HttpRequest;
 import io.netty.util.internal.PlatformDependent;
 
@@ -44,6 +45,8 @@ public class DefaultHttpDataFactory implements HttpDataFactory {
 
     private long minSize;
 
+    private Charset charset = HttpConstants.DEFAULT_CHARSET;
+
     /**
      * Keep all HttpDatas until cleanAllHttpDatas() is called.
      */
@@ -78,6 +81,11 @@ public DefaultHttpDataFactory(long minSize) {
         this.minSize = minSize;
     }
 
+    public DefaultHttpDataFactory(long minSize, Charset charset) {
+        this(minSize);
+        this.charset = charset;
+    }
+
     /**
      * @return the associated list of Files for the request
      */
@@ -93,13 +101,13 @@ private List<HttpData> getList(HttpRequest request) {
     @Override
     public Attribute createAttribute(HttpRequest request, String name) {
         if (useDisk) {
-            Attribute attribute = new DiskAttribute(name);
+            Attribute attribute = new DiskAttribute(name, charset);
             List<HttpData> fileToDelete = getList(request);
             fileToDelete.add(attribute);
             return attribute;
         }
         if (checkSize) {
-            Attribute attribute = new MixedAttribute(name, minSize);
+            Attribute attribute = new MixedAttribute(name, minSize, charset);
             List<HttpData> fileToDelete = getList(request);
             fileToDelete.add(attribute);
             return attribute;
@@ -112,23 +120,23 @@ public Attribute createAttribute(HttpRequest request, String name, String value)
         if (useDisk) {
             Attribute attribute;
             try {
-                attribute = new DiskAttribute(name, value);
+                attribute = new DiskAttribute(name, value, charset);
             } catch (IOException e) {
                 // revert to Mixed mode
-                attribute = new MixedAttribute(name, value, minSize);
+                attribute = new MixedAttribute(name, value, minSize, charset);
             }
             List<HttpData> fileToDelete = getList(request);
             fileToDelete.add(attribute);
             return attribute;
         }
         if (checkSize) {
-            Attribute attribute = new MixedAttribute(name, value, minSize);
+            Attribute attribute = new MixedAttribute(name, value, minSize, charset);
             List<HttpData> fileToDelete = getList(request);
             fileToDelete.add(attribute);
             return attribute;
         }
         try {
-            return new MemoryAttribute(name, value);
+            return new MemoryAttribute(name, value, charset);
         } catch (IOException e) {
             throw new IllegalArgumentException(e);
         }
diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/multipart/DiskAttribute.java b/codec-http/src/main/java/io/netty/handler/codec/http/multipart/DiskAttribute.java
index 28ac87044bd..d1bbd9c43b6 100644
--- a/codec-http/src/main/java/io/netty/handler/codec/http/multipart/DiskAttribute.java
+++ b/codec-http/src/main/java/io/netty/handler/codec/http/multipart/DiskAttribute.java
@@ -20,8 +20,9 @@
 import io.netty.handler.codec.http.HttpConstants;
 
 import java.io.IOException;
+import java.nio.charset.Charset;
 
-import static io.netty.buffer.Unpooled.*;
+import static io.netty.buffer.Unpooled.wrappedBuffer;
 
 /**
  * Disk implementation of Attributes
@@ -42,11 +43,20 @@ public DiskAttribute(String name) {
         super(name, HttpConstants.DEFAULT_CHARSET, 0);
     }
 
+    public DiskAttribute(String name, Charset charset) {
+        super(name, charset, 0);
+    }
+
     public DiskAttribute(String name, String value) throws IOException {
         super(name, HttpConstants.DEFAULT_CHARSET, 0); // Attribute have no default size
         setValue(value);
     }
 
+    public DiskAttribute(String name, String value, Charset charset) throws IOException {
+        super(name, charset, 0); // Attribute have no default size
+        setValue(value);
+    }
+
     @Override
     public HttpDataType getHttpDataType() {
         return HttpDataType.Attribute;
diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/multipart/MemoryAttribute.java b/codec-http/src/main/java/io/netty/handler/codec/http/multipart/MemoryAttribute.java
index e174ac91f40..9cbb9068d25 100644
--- a/codec-http/src/main/java/io/netty/handler/codec/http/multipart/MemoryAttribute.java
+++ b/codec-http/src/main/java/io/netty/handler/codec/http/multipart/MemoryAttribute.java
@@ -20,8 +20,9 @@
 import io.netty.handler.codec.http.HttpConstants;
 
 import java.io.IOException;
+import java.nio.charset.Charset;
 
-import static io.netty.buffer.Unpooled.*;
+import static io.netty.buffer.Unpooled.wrappedBuffer;
 
 /**
  * Memory implementation of Attributes
@@ -32,11 +33,20 @@ public MemoryAttribute(String name) {
         super(name, HttpConstants.DEFAULT_CHARSET, 0);
     }
 
+    public MemoryAttribute(String name, Charset charset) {
+        super(name, charset, 0);
+    }
+
     public MemoryAttribute(String name, String value) throws IOException {
         super(name, HttpConstants.DEFAULT_CHARSET, 0); // Attribute have no default size
         setValue(value);
     }
 
+    public MemoryAttribute(String name, String value, Charset charset) throws IOException {
+        super(name, charset, 0); // Attribute have no default size
+        setValue(value);
+    }
+
     @Override
     public HttpDataType getHttpDataType() {
         return HttpDataType.Attribute;
diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/multipart/MixedAttribute.java b/codec-http/src/main/java/io/netty/handler/codec/http/multipart/MixedAttribute.java
index e47e5486939..6bcf74c0156 100644
--- a/codec-http/src/main/java/io/netty/handler/codec/http/multipart/MixedAttribute.java
+++ b/codec-http/src/main/java/io/netty/handler/codec/http/multipart/MixedAttribute.java
@@ -35,6 +35,11 @@ public MixedAttribute(String name, long limitSize) {
         attribute = new MemoryAttribute(name);
     }
 
+    public MixedAttribute(String name, long limitSize, Charset charset) {
+        this.limitSize = limitSize;
+        attribute = new MemoryAttribute(name, charset);
+    }
+
     public MixedAttribute(String name, String value, long limitSize) {
         this.limitSize = limitSize;
         if (value.length() > this.limitSize) {
@@ -57,6 +62,28 @@ public MixedAttribute(String name, String value, long limitSize) {
         }
     }
 
+    public MixedAttribute(String name, String value, long limitSize, Charset charset) {
+        this.limitSize = limitSize;
+        if (value.length() > this.limitSize) {
+            try {
+                attribute = new DiskAttribute(name, value, charset);
+            } catch (IOException e) {
+                // revert to Memory mode
+                try {
+                    attribute = new MemoryAttribute(name, value, charset);
+                } catch (IOException e1) {
+                    throw new IllegalArgumentException(e);
+                }
+            }
+        } else {
+            try {
+                attribute = new MemoryAttribute(name, value, charset);
+            } catch (IOException e) {
+                throw new IllegalArgumentException(e);
+            }
+        }
+    }
+
     @Override
     public void addContent(ByteBuf buffer, boolean last) throws IOException {
         if (attribute instanceof MemoryAttribute) {


Test patch: