Merge remote branch 'upstream/master'
This commit is contained in:
commit
fd610f2f28
18
.gitignore
vendored
18
.gitignore
vendored
@ -1,10 +1,12 @@
|
|||||||
/.project
|
.project
|
||||||
/.classpath
|
.classpath
|
||||||
/.settings
|
.settings
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
.idea/
|
||||||
|
.geany
|
||||||
/target
|
/target
|
||||||
|
*/target
|
||||||
/reports
|
/reports
|
||||||
/src/main/java/io/netty/util/Version.java
|
*/reports
|
||||||
/*.iml
|
|
||||||
/*.ipr
|
|
||||||
/*.iws
|
|
||||||
/*.geany
|
|
29
all/assembly.xml
Normal file
29
all/assembly.xml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
|
||||||
|
|
||||||
|
<id>all-in-one</id>
|
||||||
|
<formats>
|
||||||
|
<format>jar</format>
|
||||||
|
</formats>
|
||||||
|
<includeBaseDirectory>false</includeBaseDirectory>
|
||||||
|
|
||||||
|
<dependencySets>
|
||||||
|
<dependencySet>
|
||||||
|
<scope>test</scope>
|
||||||
|
<unpack>true</unpack>
|
||||||
|
<useStrictFiltering>true</useStrictFiltering>
|
||||||
|
<useProjectArtifact>false</useProjectArtifact>
|
||||||
|
<useTransitiveFiltering>true</useTransitiveFiltering>
|
||||||
|
<includes>
|
||||||
|
<include>${project.groupId}:*</include>
|
||||||
|
</includes>
|
||||||
|
<unpackOptions>
|
||||||
|
<includes>
|
||||||
|
<include>io/netty/**</include>
|
||||||
|
</includes>
|
||||||
|
</unpackOptions>
|
||||||
|
</dependencySet>
|
||||||
|
</dependencySets>
|
||||||
|
</assembly>
|
117
all/pom.xml
Normal file
117
all/pom.xml
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
~ Copyright 2011 The Netty Project
|
||||||
|
~
|
||||||
|
~ The Netty Project licenses this file to you under the Apache License,
|
||||||
|
~ version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
~ with the License. You may obtain a copy of the License at:
|
||||||
|
~
|
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
~
|
||||||
|
~ Unless required by applicable law or agreed to in writing, software
|
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
~ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
~ License for the specific language governing permissions and limitations
|
||||||
|
~ under the License.
|
||||||
|
-->
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>io.netty</groupId>
|
||||||
|
<artifactId>netty-parent</artifactId>
|
||||||
|
<version>4.0.0.Alpha1-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>io.netty</groupId>
|
||||||
|
<artifactId>netty</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>Netty/All-in-One</name>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- The example depends on all modules either directly or transitively -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>netty-example</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<version>2.2.2</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>all-in-one</id>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<appendAssemblyId>false</appendAssemblyId>
|
||||||
|
<descriptors>
|
||||||
|
<descriptor>${project.basedir}/assembly.xml</descriptor>
|
||||||
|
</descriptors>
|
||||||
|
<tarLongFileMode>gnu</tarLongFileMode>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<!-- Disable all plugin executions configured by jar packaging -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-resources-plugin</artifactId>
|
||||||
|
<version>2.4.3</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>default-resources</id>
|
||||||
|
<phase>none</phase>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>default-testResources</id>
|
||||||
|
<phase>none</phase>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>2.3.2</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>default-compile</id>
|
||||||
|
<phase>none</phase>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>default-testCompile</id>
|
||||||
|
<phase>none</phase>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>2.7.2</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>default-test</id>
|
||||||
|
<phase>none</phase>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>2.3.2</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>default-jar</id>
|
||||||
|
<phase>none</phase>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
|
|
40
buffer/pom.xml
Normal file
40
buffer/pom.xml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
~ Copyright 2011 The Netty Project
|
||||||
|
~
|
||||||
|
~ The Netty Project licenses this file to you under the Apache License,
|
||||||
|
~ version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
~ with the License. You may obtain a copy of the License at:
|
||||||
|
~
|
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
~
|
||||||
|
~ Unless required by applicable law or agreed to in writing, software
|
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
~ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
~ License for the specific language governing permissions and limitations
|
||||||
|
~ under the License.
|
||||||
|
-->
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>io.netty</groupId>
|
||||||
|
<artifactId>netty-parent</artifactId>
|
||||||
|
<version>4.0.0.Alpha1-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>io.netty</groupId>
|
||||||
|
<artifactId>netty-buffer</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>Netty/Buffer</name>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>netty-common</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
|
|
@ -135,7 +135,7 @@ public abstract class AbstractChannelBuffer implements ChannelBuffer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean getBoolean(int index) {
|
public boolean getBoolean(int index) {
|
||||||
return (getByte(index) == 1);
|
return getByte(index) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -278,7 +278,7 @@ public abstract class AbstractChannelBuffer implements ChannelBuffer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean readBoolean() {
|
public boolean readBoolean() {
|
||||||
return (readByte() == 1);
|
return readByte() != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
@ -59,67 +59,67 @@ public class BigEndianHeapChannelBuffer extends HeapChannelBuffer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public short getShort(int index) {
|
public short getShort(int index) {
|
||||||
return (short) (array[index] << 8 | array[index+1] & 0xFF);
|
return (short) (array[index] << 8 | array[index + 1] & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getUnsignedMedium(int index) {
|
public int getUnsignedMedium(int index) {
|
||||||
return (array[index] & 0xff) << 16 |
|
return (array[index] & 0xff) << 16 |
|
||||||
(array[index+1] & 0xff) << 8 |
|
(array[index + 1] & 0xff) << 8 |
|
||||||
(array[index+2] & 0xff) << 0;
|
(array[index + 2] & 0xff) << 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getInt(int index) {
|
public int getInt(int index) {
|
||||||
return (array[index] & 0xff) << 24 |
|
return (array[index] & 0xff) << 24 |
|
||||||
(array[index+1] & 0xff) << 16 |
|
(array[index + 1] & 0xff) << 16 |
|
||||||
(array[index+2] & 0xff) << 8 |
|
(array[index + 2] & 0xff) << 8 |
|
||||||
(array[index+3] & 0xff) << 0;
|
(array[index + 3] & 0xff) << 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getLong(int index) {
|
public long getLong(int index) {
|
||||||
return ((long) array[index] & 0xff) << 56 |
|
return ((long) array[index] & 0xff) << 56 |
|
||||||
((long) array[index+1] & 0xff) << 48 |
|
((long) array[index + 1] & 0xff) << 48 |
|
||||||
((long) array[index+2] & 0xff) << 40 |
|
((long) array[index + 2] & 0xff) << 40 |
|
||||||
((long) array[index+3] & 0xff) << 32 |
|
((long) array[index + 3] & 0xff) << 32 |
|
||||||
((long) array[index+4] & 0xff) << 24 |
|
((long) array[index + 4] & 0xff) << 24 |
|
||||||
((long) array[index+5] & 0xff) << 16 |
|
((long) array[index + 5] & 0xff) << 16 |
|
||||||
((long) array[index+6] & 0xff) << 8 |
|
((long) array[index + 6] & 0xff) << 8 |
|
||||||
((long) array[index+7] & 0xff) << 0;
|
((long) array[index + 7] & 0xff) << 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setShort(int index, int value) {
|
public void setShort(int index, int value) {
|
||||||
array[index ] = (byte) (value >>> 8);
|
array[index] = (byte) (value >>> 8);
|
||||||
array[index+1] = (byte) (value >>> 0);
|
array[index + 1] = (byte) (value >>> 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setMedium(int index, int value) {
|
public void setMedium(int index, int value) {
|
||||||
array[index ] = (byte) (value >>> 16);
|
array[index] = (byte) (value >>> 16);
|
||||||
array[index+1] = (byte) (value >>> 8);
|
array[index + 1] = (byte) (value >>> 8);
|
||||||
array[index+2] = (byte) (value >>> 0);
|
array[index + 2] = (byte) (value >>> 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setInt(int index, int value) {
|
public void setInt(int index, int value) {
|
||||||
array[index ] = (byte) (value >>> 24);
|
array[index] = (byte) (value >>> 24);
|
||||||
array[index+1] = (byte) (value >>> 16);
|
array[index + 1] = (byte) (value >>> 16);
|
||||||
array[index+2] = (byte) (value >>> 8);
|
array[index + 2] = (byte) (value >>> 8);
|
||||||
array[index+3] = (byte) (value >>> 0);
|
array[index + 3] = (byte) (value >>> 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setLong(int index, long value) {
|
public void setLong(int index, long value) {
|
||||||
array[index ] = (byte) (value >>> 56);
|
array[index] = (byte) (value >>> 56);
|
||||||
array[index+1] = (byte) (value >>> 48);
|
array[index + 1] = (byte) (value >>> 48);
|
||||||
array[index+2] = (byte) (value >>> 40);
|
array[index + 2] = (byte) (value >>> 40);
|
||||||
array[index+3] = (byte) (value >>> 32);
|
array[index + 3] = (byte) (value >>> 32);
|
||||||
array[index+4] = (byte) (value >>> 24);
|
array[index + 4] = (byte) (value >>> 24);
|
||||||
array[index+5] = (byte) (value >>> 16);
|
array[index + 5] = (byte) (value >>> 16);
|
||||||
array[index+6] = (byte) (value >>> 8);
|
array[index + 6] = (byte) (value >>> 8);
|
||||||
array[index+7] = (byte) (value >>> 0);
|
array[index + 7] = (byte) (value >>> 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
@ -108,8 +108,8 @@ public class ByteBufferBackedChannelBuffer extends AbstractChannelBuffer {
|
|||||||
@Override
|
@Override
|
||||||
public int getUnsignedMedium(int index) {
|
public int getUnsignedMedium(int index) {
|
||||||
return (getByte(index) & 0xff) << 16 |
|
return (getByte(index) & 0xff) << 16 |
|
||||||
(getByte(index+1) & 0xff) << 8 |
|
(getByte(index + 1) & 0xff) << 8 |
|
||||||
(getByte(index+2) & 0xff) << 0;
|
(getByte(index + 2) & 0xff) << 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -173,8 +173,8 @@ public class ByteBufferBackedChannelBuffer extends AbstractChannelBuffer {
|
|||||||
@Override
|
@Override
|
||||||
public void setMedium(int index, int value) {
|
public void setMedium(int index, int value) {
|
||||||
setByte(index, (byte) (value >>> 16));
|
setByte(index, (byte) (value >>> 16));
|
||||||
setByte(index+1, (byte) (value >>> 8));
|
setByte(index + 1, (byte) (value >>> 8));
|
||||||
setByte(index+2, (byte) (value >>> 0));
|
setByte(index + 2, (byte) (value >>> 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
@ -47,7 +47,7 @@ import java.nio.charset.UnsupportedCharsetException;
|
|||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* {@link ChannelBuffer} buffer = ...;
|
* {@link ChannelBuffer} buffer = ...;
|
||||||
* for (int i = 0; i < buffer.capacity(); i ++</strong>) {
|
* for (int i = 0; i < buffer.capacity(); i ++) {
|
||||||
* byte b = buffer.getByte(i);
|
* byte b = buffer.getByte(i);
|
||||||
* System.out.println((char) b);
|
* System.out.println((char) b);
|
||||||
* }
|
* }
|
||||||
@ -130,6 +130,8 @@ import java.nio.charset.UnsupportedCharsetException;
|
|||||||
* +-------------------+------------------+------------------+
|
* +-------------------+------------------+------------------+
|
||||||
* | | | |
|
* | | | |
|
||||||
* 0 <= readerIndex <= writerIndex <= capacity
|
* 0 <= readerIndex <= writerIndex <= capacity
|
||||||
|
*
|
||||||
|
*
|
||||||
* AFTER discardReadBytes()
|
* AFTER discardReadBytes()
|
||||||
*
|
*
|
||||||
* +------------------+--------------------------------------+
|
* +------------------+--------------------------------------+
|
||||||
@ -160,6 +162,8 @@ import java.nio.charset.UnsupportedCharsetException;
|
|||||||
* +-------------------+------------------+------------------+
|
* +-------------------+------------------+------------------+
|
||||||
* | | | |
|
* | | | |
|
||||||
* 0 <= readerIndex <= writerIndex <= capacity
|
* 0 <= readerIndex <= writerIndex <= capacity
|
||||||
|
*
|
||||||
|
*
|
||||||
* AFTER clear()
|
* AFTER clear()
|
||||||
*
|
*
|
||||||
* +---------------------------------------------------------+
|
* +---------------------------------------------------------+
|
@ -84,7 +84,7 @@ import io.netty.util.CharsetUtil;
|
|||||||
* @apiviz.landmark
|
* @apiviz.landmark
|
||||||
* @apiviz.has io.netty.buffer.ChannelBuffer oneway - - creates
|
* @apiviz.has io.netty.buffer.ChannelBuffer oneway - - creates
|
||||||
*/
|
*/
|
||||||
public class ChannelBuffers {
|
public final class ChannelBuffers {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Big endian byte order.
|
* Big endian byte order.
|
||||||
@ -307,7 +307,11 @@ public class ChannelBuffers {
|
|||||||
return EMPTY_BUFFER;
|
return EMPTY_BUFFER;
|
||||||
}
|
}
|
||||||
if (buffer.hasArray()) {
|
if (buffer.hasArray()) {
|
||||||
return wrappedBuffer(buffer.order(), buffer.array(), buffer.arrayOffset() + buffer.position(),buffer.remaining());
|
return wrappedBuffer(
|
||||||
|
buffer.order(),
|
||||||
|
buffer.array(),
|
||||||
|
buffer.arrayOffset() + buffer.position(),
|
||||||
|
buffer.remaining());
|
||||||
} else {
|
} else {
|
||||||
return new ByteBufferBackedChannelBuffer(buffer);
|
return new ByteBufferBackedChannelBuffer(buffer);
|
||||||
}
|
}
|
@ -347,7 +347,7 @@ public class CompositeChannelBuffer extends AbstractChannelBuffer {
|
|||||||
setByte(index + 2, (byte) value);
|
setByte(index + 2, (byte) value);
|
||||||
} else {
|
} else {
|
||||||
setShort(index , (short) value);
|
setShort(index , (short) value);
|
||||||
setByte (index + 2, (byte) (value >>> 16));
|
setByte(index + 2, (byte) (value >>> 16));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -57,9 +57,9 @@ public class DirectChannelBufferFactory extends AbstractChannelBufferFactory {
|
|||||||
private final Object bigEndianLock = new Object();
|
private final Object bigEndianLock = new Object();
|
||||||
private final Object littleEndianLock = new Object();
|
private final Object littleEndianLock = new Object();
|
||||||
private final int preallocatedBufferCapacity;
|
private final int preallocatedBufferCapacity;
|
||||||
private ChannelBuffer preallocatedBigEndianBuffer = null;
|
private ChannelBuffer preallocatedBigEndianBuffer;
|
||||||
private int preallocatedBigEndianBufferPosition;
|
private int preallocatedBigEndianBufferPosition;
|
||||||
private ChannelBuffer preallocatedLittleEndianBuffer = null;
|
private ChannelBuffer preallocatedLittleEndianBuffer;
|
||||||
private int preallocatedLittleEndianBufferPosition;
|
private int preallocatedLittleEndianBufferPosition;
|
||||||
|
|
||||||
/**
|
/**
|
@ -59,67 +59,67 @@ public class LittleEndianHeapChannelBuffer extends HeapChannelBuffer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public short getShort(int index) {
|
public short getShort(int index) {
|
||||||
return (short) (array[index] & 0xFF | array[index+1] << 8);
|
return (short) (array[index] & 0xFF | array[index + 1] << 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getUnsignedMedium(int index) {
|
public int getUnsignedMedium(int index) {
|
||||||
return (array[index ] & 0xff) << 0 |
|
return (array[index] & 0xff) << 0 |
|
||||||
(array[index+1] & 0xff) << 8 |
|
(array[index + 1] & 0xff) << 8 |
|
||||||
(array[index+2] & 0xff) << 16;
|
(array[index + 2] & 0xff) << 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getInt(int index) {
|
public int getInt(int index) {
|
||||||
return (array[index ] & 0xff) << 0 |
|
return (array[index] & 0xff) << 0 |
|
||||||
(array[index+1] & 0xff) << 8 |
|
(array[index + 1] & 0xff) << 8 |
|
||||||
(array[index+2] & 0xff) << 16 |
|
(array[index + 2] & 0xff) << 16 |
|
||||||
(array[index+3] & 0xff) << 24;
|
(array[index + 3] & 0xff) << 24;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getLong(int index) {
|
public long getLong(int index) {
|
||||||
return ((long) array[index] & 0xff) << 0 |
|
return ((long) array[index] & 0xff) << 0 |
|
||||||
((long) array[index+1] & 0xff) << 8 |
|
((long) array[index + 1] & 0xff) << 8 |
|
||||||
((long) array[index+2] & 0xff) << 16 |
|
((long) array[index + 2] & 0xff) << 16 |
|
||||||
((long) array[index+3] & 0xff) << 24 |
|
((long) array[index + 3] & 0xff) << 24 |
|
||||||
((long) array[index+4] & 0xff) << 32 |
|
((long) array[index + 4] & 0xff) << 32 |
|
||||||
((long) array[index+5] & 0xff) << 40 |
|
((long) array[index + 5] & 0xff) << 40 |
|
||||||
((long) array[index+6] & 0xff) << 48 |
|
((long) array[index + 6] & 0xff) << 48 |
|
||||||
((long) array[index+7] & 0xff) << 56;
|
((long) array[index + 7] & 0xff) << 56;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setShort(int index, int value) {
|
public void setShort(int index, int value) {
|
||||||
array[index ] = (byte) (value >>> 0);
|
array[index] = (byte) (value >>> 0);
|
||||||
array[index+1] = (byte) (value >>> 8);
|
array[index + 1] = (byte) (value >>> 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setMedium(int index, int value) {
|
public void setMedium(int index, int value) {
|
||||||
array[index ] = (byte) (value >>> 0);
|
array[index] = (byte) (value >>> 0);
|
||||||
array[index+1] = (byte) (value >>> 8);
|
array[index + 1] = (byte) (value >>> 8);
|
||||||
array[index+2] = (byte) (value >>> 16);
|
array[index + 2] = (byte) (value >>> 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setInt(int index, int value) {
|
public void setInt(int index, int value) {
|
||||||
array[index ] = (byte) (value >>> 0);
|
array[index] = (byte) (value >>> 0);
|
||||||
array[index+1] = (byte) (value >>> 8);
|
array[index + 1] = (byte) (value >>> 8);
|
||||||
array[index+2] = (byte) (value >>> 16);
|
array[index + 2] = (byte) (value >>> 16);
|
||||||
array[index+3] = (byte) (value >>> 24);
|
array[index + 3] = (byte) (value >>> 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setLong(int index, long value) {
|
public void setLong(int index, long value) {
|
||||||
array[index ] = (byte) (value >>> 0);
|
array[index] = (byte) (value >>> 0);
|
||||||
array[index+1] = (byte) (value >>> 8);
|
array[index + 1] = (byte) (value >>> 8);
|
||||||
array[index+2] = (byte) (value >>> 16);
|
array[index + 2] = (byte) (value >>> 16);
|
||||||
array[index+3] = (byte) (value >>> 24);
|
array[index + 3] = (byte) (value >>> 24);
|
||||||
array[index+4] = (byte) (value >>> 32);
|
array[index + 4] = (byte) (value >>> 32);
|
||||||
array[index+5] = (byte) (value >>> 40);
|
array[index + 5] = (byte) (value >>> 40);
|
||||||
array[index+6] = (byte) (value >>> 48);
|
array[index + 6] = (byte) (value >>> 48);
|
||||||
array[index+7] = (byte) (value >>> 56);
|
array[index + 7] = (byte) (value >>> 56);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
@ -69,7 +69,7 @@ public abstract class AbstractChannelBufferTest {
|
|||||||
assertEquals(0, buffer.readerIndex());
|
assertEquals(0, buffer.readerIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void readerIndexBoundaryCheck1() {
|
public void readerIndexBoundaryCheck1() {
|
||||||
try {
|
try {
|
||||||
buffer.writerIndex(0);
|
buffer.writerIndex(0);
|
||||||
@ -79,7 +79,7 @@ public abstract class AbstractChannelBufferTest {
|
|||||||
buffer.readerIndex(-1);
|
buffer.readerIndex(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void readerIndexBoundaryCheck2() {
|
public void readerIndexBoundaryCheck2() {
|
||||||
try {
|
try {
|
||||||
buffer.writerIndex(buffer.capacity());
|
buffer.writerIndex(buffer.capacity());
|
||||||
@ -89,7 +89,7 @@ public abstract class AbstractChannelBufferTest {
|
|||||||
buffer.readerIndex(buffer.capacity() + 1);
|
buffer.readerIndex(buffer.capacity() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void readerIndexBoundaryCheck3() {
|
public void readerIndexBoundaryCheck3() {
|
||||||
try {
|
try {
|
||||||
buffer.writerIndex(CAPACITY / 2);
|
buffer.writerIndex(CAPACITY / 2);
|
||||||
@ -107,12 +107,12 @@ public abstract class AbstractChannelBufferTest {
|
|||||||
buffer.readerIndex(buffer.capacity());
|
buffer.readerIndex(buffer.capacity());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void writerIndexBoundaryCheck1() {
|
public void writerIndexBoundaryCheck1() {
|
||||||
buffer.writerIndex(-1);
|
buffer.writerIndex(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void writerIndexBoundaryCheck2() {
|
public void writerIndexBoundaryCheck2() {
|
||||||
try {
|
try {
|
||||||
buffer.writerIndex(CAPACITY);
|
buffer.writerIndex(CAPACITY);
|
||||||
@ -123,7 +123,7 @@ public abstract class AbstractChannelBufferTest {
|
|||||||
buffer.writerIndex(buffer.capacity() + 1);
|
buffer.writerIndex(buffer.capacity() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void writerIndexBoundaryCheck3() {
|
public void writerIndexBoundaryCheck3() {
|
||||||
try {
|
try {
|
||||||
buffer.writerIndex(CAPACITY);
|
buffer.writerIndex(CAPACITY);
|
||||||
@ -141,72 +141,72 @@ public abstract class AbstractChannelBufferTest {
|
|||||||
buffer.writerIndex(CAPACITY);
|
buffer.writerIndex(CAPACITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void getBooleanBoundaryCheck1() {
|
public void getBooleanBoundaryCheck1() {
|
||||||
buffer.getBoolean(-1);
|
buffer.getBoolean(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void getBooleanBoundaryCheck2() {
|
public void getBooleanBoundaryCheck2() {
|
||||||
buffer.getBoolean(buffer.capacity());
|
buffer.getBoolean(buffer.capacity());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void getByteBoundaryCheck1() {
|
public void getByteBoundaryCheck1() {
|
||||||
buffer.getByte(-1);
|
buffer.getByte(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void getByteBoundaryCheck2() {
|
public void getByteBoundaryCheck2() {
|
||||||
buffer.getByte(buffer.capacity());
|
buffer.getByte(buffer.capacity());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void getShortBoundaryCheck1() {
|
public void getShortBoundaryCheck1() {
|
||||||
buffer.getShort(-1);
|
buffer.getShort(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void getShortBoundaryCheck2() {
|
public void getShortBoundaryCheck2() {
|
||||||
buffer.getShort(buffer.capacity() - 1);
|
buffer.getShort(buffer.capacity() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void getMediumBoundaryCheck1() {
|
public void getMediumBoundaryCheck1() {
|
||||||
buffer.getMedium(-1);
|
buffer.getMedium(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void getMediumBoundaryCheck2() {
|
public void getMediumBoundaryCheck2() {
|
||||||
buffer.getMedium(buffer.capacity() - 2);
|
buffer.getMedium(buffer.capacity() - 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void getIntBoundaryCheck1() {
|
public void getIntBoundaryCheck1() {
|
||||||
buffer.getInt(-1);
|
buffer.getInt(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void getIntBoundaryCheck2() {
|
public void getIntBoundaryCheck2() {
|
||||||
buffer.getInt(buffer.capacity() - 3);
|
buffer.getInt(buffer.capacity() - 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void getLongBoundaryCheck1() {
|
public void getLongBoundaryCheck1() {
|
||||||
buffer.getLong(-1);
|
buffer.getLong(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void getLongBoundaryCheck2() {
|
public void getLongBoundaryCheck2() {
|
||||||
buffer.getLong(buffer.capacity() - 7);
|
buffer.getLong(buffer.capacity() - 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void getByteArrayBoundaryCheck1() {
|
public void getByteArrayBoundaryCheck1() {
|
||||||
buffer.getBytes(-1, new byte[0]);
|
buffer.getBytes(-1, new byte[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void getByteArrayBoundaryCheck2() {
|
public void getByteArrayBoundaryCheck2() {
|
||||||
buffer.getBytes(-1, new byte[0], 0, 0);
|
buffer.getBytes(-1, new byte[0], 0, 0);
|
||||||
}
|
}
|
||||||
@ -247,42 +247,42 @@ public abstract class AbstractChannelBufferTest {
|
|||||||
assertEquals(0, dst[3]);
|
assertEquals(0, dst[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void getByteBufferBoundaryCheck() {
|
public void getByteBufferBoundaryCheck() {
|
||||||
buffer.getBytes(-1, ByteBuffer.allocate(0));
|
buffer.getBytes(-1, ByteBuffer.allocate(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void copyBoundaryCheck1() {
|
public void copyBoundaryCheck1() {
|
||||||
buffer.copy(-1, 0);
|
buffer.copy(-1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void copyBoundaryCheck2() {
|
public void copyBoundaryCheck2() {
|
||||||
buffer.copy(0, buffer.capacity() + 1);
|
buffer.copy(0, buffer.capacity() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void copyBoundaryCheck3() {
|
public void copyBoundaryCheck3() {
|
||||||
buffer.copy(buffer.capacity() + 1, 0);
|
buffer.copy(buffer.capacity() + 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void copyBoundaryCheck4() {
|
public void copyBoundaryCheck4() {
|
||||||
buffer.copy(buffer.capacity(), 1);
|
buffer.copy(buffer.capacity(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void setIndexBoundaryCheck1() {
|
public void setIndexBoundaryCheck1() {
|
||||||
buffer.setIndex(-1, CAPACITY);
|
buffer.setIndex(-1, CAPACITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void setIndexBoundaryCheck2() {
|
public void setIndexBoundaryCheck2() {
|
||||||
buffer.setIndex(CAPACITY / 2, CAPACITY / 4);
|
buffer.setIndex(CAPACITY / 2, CAPACITY / 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void setIndexBoundaryCheck3() {
|
public void setIndexBoundaryCheck3() {
|
||||||
buffer.setIndex(0, CAPACITY + 1);
|
buffer.setIndex(0, CAPACITY + 1);
|
||||||
}
|
}
|
||||||
@ -309,7 +309,7 @@ public abstract class AbstractChannelBufferTest {
|
|||||||
assertEquals(0, dst.get(3));
|
assertEquals(0, dst.get(3));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IndexOutOfBoundsException.class)
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
public void getDirectByteBufferBoundaryCheck() {
|
public void getDirectByteBufferBoundaryCheck() {
|
||||||
buffer.getBytes(-1, ByteBuffer.allocateDirect(0));
|
buffer.getBytes(-1, ByteBuffer.allocateDirect(0));
|
||||||
}
|
}
|
||||||
@ -754,7 +754,7 @@ public abstract class AbstractChannelBufferTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRandomByteArrayTransfer1() {
|
public void testRandomByteArrayTransfer1() {
|
||||||
byte[] value= new byte[BLOCK_SIZE];
|
byte[] value = new byte[BLOCK_SIZE];
|
||||||
for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
|
for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
|
||||||
random.nextBytes(value);
|
random.nextBytes(value);
|
||||||
buffer.setBytes(i, value);
|
buffer.setBytes(i, value);
|
||||||
@ -774,7 +774,7 @@ public abstract class AbstractChannelBufferTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRandomByteArrayTransfer2() {
|
public void testRandomByteArrayTransfer2() {
|
||||||
byte[] value= new byte[BLOCK_SIZE * 2];
|
byte[] value = new byte[BLOCK_SIZE * 2];
|
||||||
for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
|
for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
|
||||||
random.nextBytes(value);
|
random.nextBytes(value);
|
||||||
buffer.setBytes(i, value, random.nextInt(BLOCK_SIZE), BLOCK_SIZE);
|
buffer.setBytes(i, value, random.nextInt(BLOCK_SIZE), BLOCK_SIZE);
|
||||||
@ -891,7 +891,7 @@ public abstract class AbstractChannelBufferTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSequentialByteArrayTransfer1() {
|
public void testSequentialByteArrayTransfer1() {
|
||||||
byte[] value= new byte[BLOCK_SIZE];
|
byte[] value = new byte[BLOCK_SIZE];
|
||||||
buffer.writerIndex(0);
|
buffer.writerIndex(0);
|
||||||
for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
|
for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
|
||||||
random.nextBytes(value);
|
random.nextBytes(value);
|
||||||
@ -926,7 +926,7 @@ public abstract class AbstractChannelBufferTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
random.setSeed(seed);
|
random.setSeed(seed);
|
||||||
byte[] expectedValue= new byte[BLOCK_SIZE * 2];
|
byte[] expectedValue = new byte[BLOCK_SIZE * 2];
|
||||||
for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
|
for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
|
||||||
random.nextBytes(expectedValue);
|
random.nextBytes(expectedValue);
|
||||||
int valueOffset = random.nextInt(BLOCK_SIZE);
|
int valueOffset = random.nextInt(BLOCK_SIZE);
|
@ -102,16 +102,16 @@ public abstract class AbstractCompositeChannelBufferTest extends
|
|||||||
b.skipBytes(6);
|
b.skipBytes(6);
|
||||||
b.markReaderIndex();
|
b.markReaderIndex();
|
||||||
assertEquals(a.readerIndex(), b.readerIndex());
|
assertEquals(a.readerIndex(), b.readerIndex());
|
||||||
a.readerIndex(a.readerIndex()-1);
|
a.readerIndex(a.readerIndex() - 1);
|
||||||
b.readerIndex(b.readerIndex()-1);
|
b.readerIndex(b.readerIndex() - 1);
|
||||||
assertEquals(a.readerIndex(), b.readerIndex());
|
assertEquals(a.readerIndex(), b.readerIndex());
|
||||||
a.writerIndex(a.writerIndex()-1);
|
a.writerIndex(a.writerIndex() - 1);
|
||||||
a.markWriterIndex();
|
a.markWriterIndex();
|
||||||
b.writerIndex(b.writerIndex()-1);
|
b.writerIndex(b.writerIndex() - 1);
|
||||||
b.markWriterIndex();
|
b.markWriterIndex();
|
||||||
assertEquals(a.writerIndex(), b.writerIndex());
|
assertEquals(a.writerIndex(), b.writerIndex());
|
||||||
a.writerIndex(a.writerIndex()+1);
|
a.writerIndex(a.writerIndex() + 1);
|
||||||
b.writerIndex(b.writerIndex()+1);
|
b.writerIndex(b.writerIndex() + 1);
|
||||||
assertEquals(a.writerIndex(), b.writerIndex());
|
assertEquals(a.writerIndex(), b.writerIndex());
|
||||||
assertTrue(ChannelBuffers.equals(a, b));
|
assertTrue(ChannelBuffers.equals(a, b));
|
||||||
// now discard
|
// now discard
|
||||||
@ -256,7 +256,7 @@ public abstract class AbstractCompositeChannelBufferTest extends
|
|||||||
a = wrappedBuffer(order, new byte[] { 1 });
|
a = wrappedBuffer(order, new byte[] { 1 });
|
||||||
b = wrappedBuffer(wrappedBuffer(order, new byte[] { 1 }, new byte[1]));
|
b = wrappedBuffer(wrappedBuffer(order, new byte[] { 1 }, new byte[1]));
|
||||||
// to enable writeBytes
|
// to enable writeBytes
|
||||||
b.writerIndex(b.writerIndex()-1);
|
b.writerIndex(b.writerIndex() - 1);
|
||||||
b.writeBytes(
|
b.writeBytes(
|
||||||
wrappedBuffer(order, new byte[] { 2 }));
|
wrappedBuffer(order, new byte[] { 2 }));
|
||||||
assertFalse(ChannelBuffers.equals(a, b));
|
assertFalse(ChannelBuffers.equals(a, b));
|
||||||
@ -265,7 +265,7 @@ public abstract class AbstractCompositeChannelBufferTest extends
|
|||||||
a = wrappedBuffer(order, new byte[] { 1, 2, 3 });
|
a = wrappedBuffer(order, new byte[] { 1, 2, 3 });
|
||||||
b = wrappedBuffer(wrappedBuffer(order, new byte[] { 1 }, new byte[2]));
|
b = wrappedBuffer(wrappedBuffer(order, new byte[] { 1 }, new byte[2]));
|
||||||
// to enable writeBytes
|
// to enable writeBytes
|
||||||
b.writerIndex(b.writerIndex()-2);
|
b.writerIndex(b.writerIndex() - 2);
|
||||||
b.writeBytes(
|
b.writeBytes(
|
||||||
wrappedBuffer(order, new byte[] { 2 }));
|
wrappedBuffer(order, new byte[] { 2 }));
|
||||||
b.writeBytes(wrappedBuffer(order, new byte[] { 3 }));
|
b.writeBytes(wrappedBuffer(order, new byte[] { 3 }));
|
||||||
@ -275,7 +275,7 @@ public abstract class AbstractCompositeChannelBufferTest extends
|
|||||||
a = wrappedBuffer(order, new byte[] { 1, 2, 3 });
|
a = wrappedBuffer(order, new byte[] { 1, 2, 3 });
|
||||||
b = wrappedBuffer(wrappedBuffer(order, new byte[] { 0, 1, 2, 3, 4 }, 1, 3));
|
b = wrappedBuffer(wrappedBuffer(order, new byte[] { 0, 1, 2, 3, 4 }, 1, 3));
|
||||||
// to enable writeBytes
|
// to enable writeBytes
|
||||||
b.writerIndex(b.writerIndex()-1);
|
b.writerIndex(b.writerIndex() - 1);
|
||||||
b.writeBytes(
|
b.writeBytes(
|
||||||
wrappedBuffer(order, new byte[] { 0, 1, 2, 3, 4 }, 3, 1));
|
wrappedBuffer(order, new byte[] { 0, 1, 2, 3, 4 }, 3, 1));
|
||||||
assertTrue(ChannelBuffers.equals(a, b));
|
assertTrue(ChannelBuffers.equals(a, b));
|
||||||
@ -284,7 +284,7 @@ public abstract class AbstractCompositeChannelBufferTest extends
|
|||||||
a = wrappedBuffer(order, new byte[] { 1, 2, 3 });
|
a = wrappedBuffer(order, new byte[] { 1, 2, 3 });
|
||||||
b = wrappedBuffer(wrappedBuffer(order, new byte[] { 1, 2 }, new byte[1]));
|
b = wrappedBuffer(wrappedBuffer(order, new byte[] { 1, 2 }, new byte[1]));
|
||||||
// to enable writeBytes
|
// to enable writeBytes
|
||||||
b.writerIndex(b.writerIndex()-1);
|
b.writerIndex(b.writerIndex() - 1);
|
||||||
b.writeBytes(
|
b.writeBytes(
|
||||||
wrappedBuffer(order, new byte[] { 4 }));
|
wrappedBuffer(order, new byte[] { 4 }));
|
||||||
assertFalse(ChannelBuffers.equals(a, b));
|
assertFalse(ChannelBuffers.equals(a, b));
|
||||||
@ -293,7 +293,7 @@ public abstract class AbstractCompositeChannelBufferTest extends
|
|||||||
a = wrappedBuffer(order, new byte[] { 1, 2, 3 });
|
a = wrappedBuffer(order, new byte[] { 1, 2, 3 });
|
||||||
b = wrappedBuffer(wrappedBuffer(order, new byte[] { 0, 1, 2, 4, 5 }, 1, 3));
|
b = wrappedBuffer(wrappedBuffer(order, new byte[] { 0, 1, 2, 4, 5 }, 1, 3));
|
||||||
// to enable writeBytes
|
// to enable writeBytes
|
||||||
b.writerIndex(b.writerIndex()-1);
|
b.writerIndex(b.writerIndex() - 1);
|
||||||
b.writeBytes(
|
b.writeBytes(
|
||||||
wrappedBuffer(order, new byte[] { 0, 1, 2, 4, 5 }, 3, 1));
|
wrappedBuffer(order, new byte[] { 0, 1, 2, 4, 5 }, 3, 1));
|
||||||
assertFalse(ChannelBuffers.equals(a, b));
|
assertFalse(ChannelBuffers.equals(a, b));
|
||||||
@ -302,7 +302,7 @@ public abstract class AbstractCompositeChannelBufferTest extends
|
|||||||
a = wrappedBuffer(order, new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
|
a = wrappedBuffer(order, new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
|
||||||
b = wrappedBuffer(wrappedBuffer(order, new byte[] { 1, 2, 3 }, new byte[7]));
|
b = wrappedBuffer(wrappedBuffer(order, new byte[] { 1, 2, 3 }, new byte[7]));
|
||||||
// to enable writeBytes
|
// to enable writeBytes
|
||||||
b.writerIndex(b.writerIndex()-7);
|
b.writerIndex(b.writerIndex() - 7);
|
||||||
b.writeBytes(
|
b.writeBytes(
|
||||||
wrappedBuffer(order, new byte[] { 4, 5, 6 }));
|
wrappedBuffer(order, new byte[] { 4, 5, 6 }));
|
||||||
b.writeBytes(
|
b.writeBytes(
|
||||||
@ -313,7 +313,7 @@ public abstract class AbstractCompositeChannelBufferTest extends
|
|||||||
a = wrappedBuffer(order, new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
|
a = wrappedBuffer(order, new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
|
||||||
b = wrappedBuffer(wrappedBuffer(order, new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 1, 10));
|
b = wrappedBuffer(wrappedBuffer(order, new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 1, 10));
|
||||||
// to enable writeBytes
|
// to enable writeBytes
|
||||||
b.writerIndex(b.writerIndex()-5);
|
b.writerIndex(b.writerIndex() - 5);
|
||||||
b.writeBytes(
|
b.writeBytes(
|
||||||
wrappedBuffer(order, new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 6, 5));
|
wrappedBuffer(order, new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 6, 5));
|
||||||
assertTrue(ChannelBuffers.equals(a, b));
|
assertTrue(ChannelBuffers.equals(a, b));
|
||||||
@ -322,7 +322,7 @@ public abstract class AbstractCompositeChannelBufferTest extends
|
|||||||
a = wrappedBuffer(order, new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
|
a = wrappedBuffer(order, new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
|
||||||
b = wrappedBuffer(wrappedBuffer(order, new byte[] { 1, 2, 3, 4, 6 }, new byte[5]));
|
b = wrappedBuffer(wrappedBuffer(order, new byte[] { 1, 2, 3, 4, 6 }, new byte[5]));
|
||||||
// to enable writeBytes
|
// to enable writeBytes
|
||||||
b.writerIndex(b.writerIndex()-5);
|
b.writerIndex(b.writerIndex() - 5);
|
||||||
b.writeBytes(
|
b.writeBytes(
|
||||||
wrappedBuffer(order, new byte[] { 7, 8, 5, 9, 10 }));
|
wrappedBuffer(order, new byte[] { 7, 8, 5, 9, 10 }));
|
||||||
assertFalse(ChannelBuffers.equals(a, b));
|
assertFalse(ChannelBuffers.equals(a, b));
|
||||||
@ -331,7 +331,7 @@ public abstract class AbstractCompositeChannelBufferTest extends
|
|||||||
a = wrappedBuffer(order, new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
|
a = wrappedBuffer(order, new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
|
||||||
b = wrappedBuffer(wrappedBuffer(order, new byte[] { 0, 1, 2, 3, 4, 6, 7, 8, 5, 9, 10, 11 }, 1, 10));
|
b = wrappedBuffer(wrappedBuffer(order, new byte[] { 0, 1, 2, 3, 4, 6, 7, 8, 5, 9, 10, 11 }, 1, 10));
|
||||||
// to enable writeBytes
|
// to enable writeBytes
|
||||||
b.writerIndex(b.writerIndex()-5);
|
b.writerIndex(b.writerIndex() - 5);
|
||||||
b.writeBytes(
|
b.writeBytes(
|
||||||
wrappedBuffer(order, new byte[] { 0, 1, 2, 3, 4, 6, 7, 8, 5, 9, 10, 11 }, 6, 5));
|
wrappedBuffer(order, new byte[] { 0, 1, 2, 3, 4, 6, 7, 8, 5, 9, 10, 11 }, 6, 5));
|
||||||
assertFalse(ChannelBuffers.equals(a, b));
|
assertFalse(ChannelBuffers.equals(a, b));
|
@ -27,7 +27,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import org.easymock.classextension.EasyMock;
|
import org.easymock.EasyMock;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
/**
|
45
codec-http/pom.xml
Normal file
45
codec-http/pom.xml
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
~ Copyright 2011 The Netty Project
|
||||||
|
~
|
||||||
|
~ The Netty Project licenses this file to you under the Apache License,
|
||||||
|
~ version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
~ with the License. You may obtain a copy of the License at:
|
||||||
|
~
|
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
~
|
||||||
|
~ Unless required by applicable law or agreed to in writing, software
|
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
~ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
~ License for the specific language governing permissions and limitations
|
||||||
|
~ under the License.
|
||||||
|
-->
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>io.netty</groupId>
|
||||||
|
<artifactId>netty-parent</artifactId>
|
||||||
|
<version>4.0.0.Alpha1-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>io.netty</groupId>
|
||||||
|
<artifactId>netty-codec-http</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>Netty/Codec/HTTP</name>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>netty-codec</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>netty-handler</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
|
|
@ -32,14 +32,11 @@ import io.netty.buffer.ChannelBuffers;
|
|||||||
*/
|
*/
|
||||||
public abstract class AbstractDiskHttpData extends AbstractHttpData {
|
public abstract class AbstractDiskHttpData extends AbstractHttpData {
|
||||||
|
|
||||||
protected File file = null;
|
protected File file;
|
||||||
|
private boolean isRenamed;
|
||||||
|
private FileChannel fileChannel;
|
||||||
|
|
||||||
private boolean isRenamed = false;
|
public AbstractDiskHttpData(String name, Charset charset, long size) {
|
||||||
|
|
||||||
private FileChannel fileChannel = null;
|
|
||||||
|
|
||||||
public AbstractDiskHttpData(String name, Charset charset, long size)
|
|
||||||
throws NullPointerException, IllegalArgumentException {
|
|
||||||
super(name, charset, size);
|
super(name, charset, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,7 +188,7 @@ public abstract class AbstractDiskHttpData extends AbstractHttpData {
|
|||||||
file = tempFile();
|
file = tempFile();
|
||||||
FileOutputStream outputStream = new FileOutputStream(file);
|
FileOutputStream outputStream = new FileOutputStream(file);
|
||||||
FileChannel localfileChannel = outputStream.getChannel();
|
FileChannel localfileChannel = outputStream.getChannel();
|
||||||
byte[] bytes = new byte[4096*4];
|
byte[] bytes = new byte[4096 * 4];
|
||||||
ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
|
ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
|
||||||
int read = inputStream.read(bytes);
|
int read = inputStream.read(bytes);
|
||||||
int written = 0;
|
int written = 0;
|
@ -23,17 +23,12 @@ import java.nio.charset.Charset;
|
|||||||
public abstract class AbstractHttpData implements HttpData {
|
public abstract class AbstractHttpData implements HttpData {
|
||||||
|
|
||||||
protected final String name;
|
protected final String name;
|
||||||
|
protected long definedSize;
|
||||||
protected long definedSize = 0;
|
protected long size;
|
||||||
|
|
||||||
protected long size = 0;
|
|
||||||
|
|
||||||
protected Charset charset = HttpCodecUtil.DEFAULT_CHARSET;
|
protected Charset charset = HttpCodecUtil.DEFAULT_CHARSET;
|
||||||
|
protected boolean completed;
|
||||||
|
|
||||||
protected boolean completed = false;
|
public AbstractHttpData(String name, Charset charset, long size) {
|
||||||
|
|
||||||
public AbstractHttpData(String name, Charset charset, long size)
|
|
||||||
throws NullPointerException, IllegalArgumentException {
|
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
throw new NullPointerException("name");
|
throw new NullPointerException("name");
|
||||||
}
|
}
|
@ -32,14 +32,11 @@ import io.netty.buffer.ChannelBuffers;
|
|||||||
*/
|
*/
|
||||||
public abstract class AbstractMemoryHttpData extends AbstractHttpData {
|
public abstract class AbstractMemoryHttpData extends AbstractHttpData {
|
||||||
|
|
||||||
private ChannelBuffer channelBuffer = null;
|
private ChannelBuffer channelBuffer;
|
||||||
|
private int chunkPosition;
|
||||||
|
protected boolean isRenamed;
|
||||||
|
|
||||||
private int chunkPosition = 0;
|
public AbstractMemoryHttpData(String name, Charset charset, long size) {
|
||||||
|
|
||||||
protected boolean isRenamed = false;
|
|
||||||
|
|
||||||
public AbstractMemoryHttpData(String name, Charset charset, long size)
|
|
||||||
throws NullPointerException, IllegalArgumentException {
|
|
||||||
super(name, charset, size);
|
super(name, charset, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +61,7 @@ public abstract class AbstractMemoryHttpData extends AbstractHttpData {
|
|||||||
throw new NullPointerException("inputStream");
|
throw new NullPointerException("inputStream");
|
||||||
}
|
}
|
||||||
ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
|
ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
|
||||||
byte[] bytes = new byte[4096*4];
|
byte[] bytes = new byte[4096 * 4];
|
||||||
int read = inputStream.read(bytes);
|
int read = inputStream.read(bytes);
|
||||||
int written = 0;
|
int written = 0;
|
||||||
while (read > 0) {
|
while (read > 0) {
|
@ -18,8 +18,6 @@ package io.netty.handler.codec.http;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
final class CaseIgnoringComparator implements Comparator<String>, Serializable {
|
final class CaseIgnoringComparator implements Comparator<String>, Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 4582133183775373862L;
|
private static final long serialVersionUID = 4582133183775373862L;
|
@ -41,10 +41,10 @@ import java.util.regex.Pattern;
|
|||||||
*/
|
*/
|
||||||
public class CookieDecoder {
|
public class CookieDecoder {
|
||||||
|
|
||||||
private final static Pattern PATTERN =
|
private static final Pattern PATTERN =
|
||||||
Pattern.compile("(?:\\s|[;,])*\\$*([^;=]+)(?:=(?:[\"']((?:\\\\.|[^\"])*)[\"']|([^;,]*)))?(\\s*(?:[;,]+\\s*|$))");
|
Pattern.compile("(?:\\s|[;,])*\\$*([^;=]+)(?:=(?:[\"']((?:\\\\.|[^\"])*)[\"']|([^;,]*)))?(\\s*(?:[;,]+\\s*|$))");
|
||||||
|
|
||||||
private final static String COMMA = ",";
|
private static final String COMMA = ",";
|
||||||
|
|
||||||
private final boolean lenient;
|
private final boolean lenient;
|
||||||
|
|
@ -145,7 +145,7 @@ public class CookieEncoder {
|
|||||||
addQuoted(sb, CookieHeaderNames.COMMENTURL, cookie.getCommentUrl());
|
addQuoted(sb, CookieHeaderNames.COMMENTURL, cookie.getCommentUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!cookie.getPorts().isEmpty()) {
|
if (!cookie.getPorts().isEmpty()) {
|
||||||
sb.append(CookieHeaderNames.PORT);
|
sb.append(CookieHeaderNames.PORT);
|
||||||
sb.append((char) HttpCodecUtil.EQUALS);
|
sb.append((char) HttpCodecUtil.EQUALS);
|
||||||
sb.append((char) HttpCodecUtil.DOUBLE_QUOTE);
|
sb.append((char) HttpCodecUtil.DOUBLE_QUOTE);
|
||||||
@ -189,7 +189,7 @@ public class CookieEncoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cookie.getVersion() >= 1) {
|
if (cookie.getVersion() >= 1) {
|
||||||
if(!cookie.getPorts().isEmpty()) {
|
if (!cookie.getPorts().isEmpty()) {
|
||||||
sb.append('$');
|
sb.append('$');
|
||||||
sb.append(CookieHeaderNames.PORT);
|
sb.append(CookieHeaderNames.PORT);
|
||||||
sb.append((char) HttpCodecUtil.EQUALS);
|
sb.append((char) HttpCodecUtil.EQUALS);
|
||||||
@ -204,8 +204,10 @@ public class CookieEncoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sb.length() > 0)
|
if (sb.length() > 0) {
|
||||||
sb.setLength(sb.length() - 1);
|
sb.setLength(sb.length() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
@ -15,8 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.http;
|
package io.netty.handler.codec.http;
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
final class CookieHeaderNames {
|
final class CookieHeaderNames {
|
||||||
static final String PATH = "Path";
|
static final String PATH = "Path";
|
||||||
|
|
@ -35,11 +35,11 @@ public class DefaultHttpDataFactory implements HttpDataFactory {
|
|||||||
*/
|
*/
|
||||||
public static long MINSIZE = 0x4000;
|
public static long MINSIZE = 0x4000;
|
||||||
|
|
||||||
private boolean useDisk = false;
|
private boolean useDisk;
|
||||||
|
|
||||||
private boolean checkSize = false;
|
private boolean checkSize;
|
||||||
|
|
||||||
private long minSize = 0L;
|
private long minSize;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keep all HttpDatas until cleanAllHttpDatas() is called.
|
* Keep all HttpDatas until cleanAllHttpDatas() is called.
|
||||||
@ -91,8 +91,7 @@ public class DefaultHttpDataFactory implements HttpDataFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Attribute createAttribute(HttpRequest request, String name) throws NullPointerException,
|
public Attribute createAttribute(HttpRequest request, String name) {
|
||||||
IllegalArgumentException {
|
|
||||||
if (useDisk) {
|
if (useDisk) {
|
||||||
Attribute attribute = new DiskAttribute(name);
|
Attribute attribute = new DiskAttribute(name);
|
||||||
List<HttpData> fileToDelete = getList(request);
|
List<HttpData> fileToDelete = getList(request);
|
||||||
@ -107,12 +106,8 @@ public class DefaultHttpDataFactory implements HttpDataFactory {
|
|||||||
return new MemoryAttribute(name);
|
return new MemoryAttribute(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see io.netty.handler.codec.http2.HttpDataFactory#createAttribute(java.lang.String, java.lang.String)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Attribute createAttribute(HttpRequest request, String name, String value)
|
public Attribute createAttribute(HttpRequest request, String name, String value) {
|
||||||
throws NullPointerException, IllegalArgumentException {
|
|
||||||
if (useDisk) {
|
if (useDisk) {
|
||||||
Attribute attribute;
|
Attribute attribute;
|
||||||
try {
|
try {
|
||||||
@ -137,13 +132,10 @@ public class DefaultHttpDataFactory implements HttpDataFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see io.netty.handler.codec.http2.HttpDataFactory#createFileUpload(java.lang.String, java.lang.String, java.lang.String)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public FileUpload createFileUpload(HttpRequest request, String name, String filename,
|
public FileUpload createFileUpload(HttpRequest request, String name, String filename,
|
||||||
String contentType, String contentTransferEncoding, Charset charset,
|
String contentType, String contentTransferEncoding, Charset charset,
|
||||||
long size) throws NullPointerException, IllegalArgumentException {
|
long size) {
|
||||||
if (useDisk) {
|
if (useDisk) {
|
||||||
FileUpload fileUpload = new DiskFileUpload(name, filename, contentType,
|
FileUpload fileUpload = new DiskFileUpload(name, filename, contentType,
|
||||||
contentTransferEncoding, charset, size);
|
contentTransferEncoding, charset, size);
|
@ -96,8 +96,7 @@ public class DefaultHttpMessage implements HttpMessage {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getHeader(final String name) {
|
public String getHeader(final String name) {
|
||||||
List<String> values = getHeaders(name);
|
return headers.getHeader(name);
|
||||||
return values.size() > 0 ? values.get(0) : null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
@ -24,7 +24,7 @@ import io.netty.buffer.ChannelBuffers;
|
|||||||
* Disk implementation of Attributes
|
* Disk implementation of Attributes
|
||||||
*/
|
*/
|
||||||
public class DiskAttribute extends AbstractDiskHttpData implements Attribute {
|
public class DiskAttribute extends AbstractDiskHttpData implements Attribute {
|
||||||
public static String baseDirectory = null;
|
public static String baseDirectory;
|
||||||
|
|
||||||
public static boolean deleteOnExitTemporaryFile = true;
|
public static boolean deleteOnExitTemporaryFile = true;
|
||||||
|
|
||||||
@ -47,8 +47,7 @@ public class DiskAttribute extends AbstractDiskHttpData implements Attribute {
|
|||||||
* @throws IllegalArgumentException
|
* @throws IllegalArgumentException
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public DiskAttribute(String name, String value)
|
public DiskAttribute(String name, String value) throws IOException {
|
||||||
throws NullPointerException, IllegalArgumentException, IOException {
|
|
||||||
super(name, HttpCodecUtil.DEFAULT_CHARSET, 0); // Attribute have no default size
|
super(name, HttpCodecUtil.DEFAULT_CHARSET, 0); // Attribute have no default size
|
||||||
setValue(value);
|
setValue(value);
|
||||||
}
|
}
|
||||||
@ -133,7 +132,7 @@ public class DiskAttribute extends AbstractDiskHttpData implements Attribute {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getDiskFilename() {
|
protected String getDiskFilename() {
|
||||||
return getName()+postfix;
|
return getName() + postfix;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
@ -22,7 +22,7 @@ import java.nio.charset.Charset;
|
|||||||
* Disk FileUpload implementation that stores file into real files
|
* Disk FileUpload implementation that stores file into real files
|
||||||
*/
|
*/
|
||||||
public class DiskFileUpload extends AbstractDiskHttpData implements FileUpload {
|
public class DiskFileUpload extends AbstractDiskHttpData implements FileUpload {
|
||||||
public static String baseDirectory = null;
|
public static String baseDirectory;
|
||||||
|
|
||||||
public static boolean deleteOnExitTemporaryFile = true;
|
public static boolean deleteOnExitTemporaryFile = true;
|
||||||
|
|
||||||
@ -30,15 +30,14 @@ public class DiskFileUpload extends AbstractDiskHttpData implements FileUpload {
|
|||||||
|
|
||||||
public static String postfix = ".tmp";
|
public static String postfix = ".tmp";
|
||||||
|
|
||||||
private String filename = null;
|
private String filename;
|
||||||
|
|
||||||
private String contentType = null;
|
private String contentType;
|
||||||
|
|
||||||
private String contentTransferEncoding = null;
|
private String contentTransferEncoding;
|
||||||
|
|
||||||
public DiskFileUpload(String name, String filename, String contentType,
|
public DiskFileUpload(String name, String filename, String contentType,
|
||||||
String contentTransferEncoding, Charset charset, long size)
|
String contentTransferEncoding, Charset charset, long size) {
|
||||||
throws NullPointerException, IllegalArgumentException {
|
|
||||||
super(name, charset, size);
|
super(name, charset, size);
|
||||||
setFilename(filename);
|
setFilename(filename);
|
||||||
setContentType(contentType);
|
setContentType(contentType);
|
||||||
@ -50,17 +49,11 @@ public class DiskFileUpload extends AbstractDiskHttpData implements FileUpload {
|
|||||||
return HttpDataType.FileUpload;
|
return HttpDataType.FileUpload;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see io.netty.handler.codec.http2.FileUpload#getFilename()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String getFilename() {
|
public String getFilename() {
|
||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see io.netty.handler.codec.http2.FileUpload#setFilename(java.lang.String)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void setFilename(String filename) {
|
public void setFilename(String filename) {
|
||||||
if (filename == null) {
|
if (filename == null) {
|
||||||
@ -127,12 +120,12 @@ public class DiskFileUpload extends AbstractDiskHttpData implements FileUpload {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return HttpPostBodyUtil.CONTENT_DISPOSITION+": "+
|
return HttpPostBodyUtil.CONTENT_DISPOSITION + ": " +
|
||||||
HttpPostBodyUtil.FORM_DATA+"; "+HttpPostBodyUtil.NAME+"=\"" + getName() +
|
HttpPostBodyUtil.FORM_DATA + "; " + HttpPostBodyUtil.NAME + "=\"" + getName() +
|
||||||
"\"; "+HttpPostBodyUtil.FILENAME+"=\"" + filename + "\"\r\n" +
|
"\"; " + HttpPostBodyUtil.FILENAME + "=\"" + filename + "\"\r\n" +
|
||||||
HttpHeaders.Names.CONTENT_TYPE+": " + contentType +
|
HttpHeaders.Names.CONTENT_TYPE + ": " + contentType +
|
||||||
(charset != null? "; "+HttpHeaders.Values.CHARSET+"=" + charset + "\r\n" : "\r\n") +
|
(charset != null? "; " + HttpHeaders.Values.CHARSET + "=" + charset + "\r\n" : "\r\n") +
|
||||||
HttpHeaders.Names.CONTENT_LENGTH+": " + length() + "\r\n" +
|
HttpHeaders.Names.CONTENT_LENGTH + ": " + length() + "\r\n" +
|
||||||
"Completed: " + isCompleted() +
|
"Completed: " + isCompleted() +
|
||||||
"\r\nIsInMemory: " + isInMemory() + "\r\nRealFile: " +
|
"\r\nIsInMemory: " + isInMemory() + "\r\nRealFile: " +
|
||||||
file.getAbsolutePath() + " DefaultDeleteAfter: " +
|
file.getAbsolutePath() + " DefaultDeleteAfter: " +
|
@ -20,9 +20,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import io.netty.util.CharsetUtil;
|
import io.netty.util.CharsetUtil;
|
||||||
|
|
||||||
/**
|
final class HttpCodecUtil {
|
||||||
*/
|
|
||||||
class HttpCodecUtil {
|
|
||||||
//space ' '
|
//space ' '
|
||||||
static final byte SP = 32;
|
static final byte SP = 32;
|
||||||
|
|
@ -30,16 +30,20 @@ import io.netty.handler.codec.embedder.EncoderEmbedder;
|
|||||||
public class HttpContentCompressor extends HttpContentEncoder {
|
public class HttpContentCompressor extends HttpContentEncoder {
|
||||||
|
|
||||||
private final int compressionLevel;
|
private final int compressionLevel;
|
||||||
|
private final int windowBits;
|
||||||
|
private final int memLevel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new handler with the default compression level (<tt>6</tt>).
|
* Creates a new handler with the default compression level (<tt>6</tt>),
|
||||||
|
* default window size (<tt>15</tt>) and default memory level (<tt>8</tt>).
|
||||||
*/
|
*/
|
||||||
public HttpContentCompressor() {
|
public HttpContentCompressor() {
|
||||||
this(6);
|
this(6);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new handler with the specified compression level.
|
* Creates a new handler with the specified compression level, default
|
||||||
|
* window size (<tt>15</tt>) and default memory level (<tt>8</tt>).
|
||||||
*
|
*
|
||||||
* @param compressionLevel
|
* @param compressionLevel
|
||||||
* {@code 1} yields the fastest compression and {@code 9} yields the
|
* {@code 1} yields the fastest compression and {@code 9} yields the
|
||||||
@ -47,12 +51,45 @@ public class HttpContentCompressor extends HttpContentEncoder {
|
|||||||
* compression level is {@code 6}.
|
* compression level is {@code 6}.
|
||||||
*/
|
*/
|
||||||
public HttpContentCompressor(int compressionLevel) {
|
public HttpContentCompressor(int compressionLevel) {
|
||||||
|
this(compressionLevel, 15, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new handler with the specified compression level, window size,
|
||||||
|
* and memory level..
|
||||||
|
*
|
||||||
|
* @param compressionLevel
|
||||||
|
* {@code 1} yields the fastest compression and {@code 9} yields the
|
||||||
|
* best compression. {@code 0} means no compression. The default
|
||||||
|
* compression level is {@code 6}.
|
||||||
|
* @param windowBits
|
||||||
|
* The base two logarithm of the size of the history buffer. The
|
||||||
|
* value should be in the range {@code 9} to {@code 15} inclusive.
|
||||||
|
* Larger values result in better compression at the expense of
|
||||||
|
* memory usage. The default value is {@code 15}.
|
||||||
|
* @param memLevel
|
||||||
|
* How much memory should be allocated for the internal compression
|
||||||
|
* state. {@code 1} uses minimum memory and {@code 9} uses maximum
|
||||||
|
* memory. Larger values result in better and faster compression
|
||||||
|
* at the expense of memory usage. The default value is {@code 8}
|
||||||
|
*/
|
||||||
|
public HttpContentCompressor(int compressionLevel, int windowBits, int memLevel) {
|
||||||
if (compressionLevel < 0 || compressionLevel > 9) {
|
if (compressionLevel < 0 || compressionLevel > 9) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"compressionLevel: " + compressionLevel +
|
"compressionLevel: " + compressionLevel +
|
||||||
" (expected: 0-9)");
|
" (expected: 0-9)");
|
||||||
}
|
}
|
||||||
|
if (windowBits < 9 || windowBits > 15) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"windowBits: " + windowBits + " (expected: 9-15)");
|
||||||
|
}
|
||||||
|
if (memLevel < 1 || memLevel > 9) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"memLevel: " + memLevel + " (expected: 1-9)");
|
||||||
|
}
|
||||||
this.compressionLevel = compressionLevel;
|
this.compressionLevel = compressionLevel;
|
||||||
|
this.windowBits = windowBits;
|
||||||
|
this.memLevel = memLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -83,17 +120,47 @@ public class HttpContentCompressor extends HttpContentEncoder {
|
|||||||
return new Result(
|
return new Result(
|
||||||
targetContentEncoding,
|
targetContentEncoding,
|
||||||
new EncoderEmbedder<ChannelBuffer>(
|
new EncoderEmbedder<ChannelBuffer>(
|
||||||
new ZlibEncoder(wrapper, compressionLevel)));
|
new ZlibEncoder(wrapper, compressionLevel, windowBits, memLevel)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private ZlibWrapper determineWrapper(String acceptEncoding) {
|
protected ZlibWrapper determineWrapper(String acceptEncoding) {
|
||||||
// FIXME: Use the Q value.
|
float starQ = -1.0f;
|
||||||
if (acceptEncoding.indexOf("gzip") >= 0) {
|
float gzipQ = -1.0f;
|
||||||
|
float deflateQ = -1.0f;
|
||||||
|
for (String encoding : acceptEncoding.split(",")) {
|
||||||
|
float q = 1.0f;
|
||||||
|
int equalsPos = encoding.indexOf('=');
|
||||||
|
if (equalsPos != -1) {
|
||||||
|
try {
|
||||||
|
q = Float.valueOf(encoding.substring(equalsPos + 1));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
// Ignore encoding
|
||||||
|
q = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (encoding.indexOf("*") >= 0) {
|
||||||
|
starQ = q;
|
||||||
|
} else if (encoding.indexOf("gzip") >= 0 && q > gzipQ) {
|
||||||
|
gzipQ = q;
|
||||||
|
} else if (encoding.indexOf("deflate") >= 0 && q > deflateQ) {
|
||||||
|
deflateQ = q;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (gzipQ > 0.0f || deflateQ > 0.0f) {
|
||||||
|
if (gzipQ >= deflateQ) {
|
||||||
|
return ZlibWrapper.GZIP;
|
||||||
|
} else {
|
||||||
|
return ZlibWrapper.ZLIB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (starQ > 0.0f) {
|
||||||
|
if (gzipQ == -1.0f) {
|
||||||
return ZlibWrapper.GZIP;
|
return ZlibWrapper.GZIP;
|
||||||
}
|
}
|
||||||
if (acceptEncoding.indexOf("deflate") >= 0) {
|
if (deflateQ == -1.0f) {
|
||||||
return ZlibWrapper.ZLIB;
|
return ZlibWrapper.ZLIB;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -29,8 +29,7 @@ public interface HttpDataFactory {
|
|||||||
* @throws NullPointerException
|
* @throws NullPointerException
|
||||||
* @throws IllegalArgumentException
|
* @throws IllegalArgumentException
|
||||||
*/
|
*/
|
||||||
Attribute createAttribute(HttpRequest request, String name)
|
Attribute createAttribute(HttpRequest request, String name);
|
||||||
throws NullPointerException, IllegalArgumentException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -41,8 +40,7 @@ public interface HttpDataFactory {
|
|||||||
* @throws NullPointerException
|
* @throws NullPointerException
|
||||||
* @throws IllegalArgumentException
|
* @throws IllegalArgumentException
|
||||||
*/
|
*/
|
||||||
Attribute createAttribute(HttpRequest request, String name, String value)
|
Attribute createAttribute(HttpRequest request, String name, String value);
|
||||||
throws NullPointerException, IllegalArgumentException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -56,7 +54,7 @@ public interface HttpDataFactory {
|
|||||||
*/
|
*/
|
||||||
FileUpload createFileUpload(HttpRequest request, String name, String filename,
|
FileUpload createFileUpload(HttpRequest request, String name, String filename,
|
||||||
String contentType, String contentTransferEncoding, Charset charset,
|
String contentType, String contentTransferEncoding, Charset charset,
|
||||||
long size) throws NullPointerException, IllegalArgumentException;
|
long size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the given InterfaceHttpData from clean list (will not delete the file, except if the file
|
* Remove the given InterfaceHttpData from clean list (will not delete the file, except if the file
|
@ -49,7 +49,7 @@ public class HttpHeaders {
|
|||||||
/**
|
/**
|
||||||
* {@code "Accept-Encoding"}
|
* {@code "Accept-Encoding"}
|
||||||
*/
|
*/
|
||||||
public static final String ACCEPT_ENCODING= "Accept-Encoding";
|
public static final String ACCEPT_ENCODING = "Accept-Encoding";
|
||||||
/**
|
/**
|
||||||
* {@code "Accept-Language"}
|
* {@code "Accept-Language"}
|
||||||
*/
|
*/
|
||||||
@ -57,11 +57,11 @@ public class HttpHeaders {
|
|||||||
/**
|
/**
|
||||||
* {@code "Accept-Ranges"}
|
* {@code "Accept-Ranges"}
|
||||||
*/
|
*/
|
||||||
public static final String ACCEPT_RANGES= "Accept-Ranges";
|
public static final String ACCEPT_RANGES = "Accept-Ranges";
|
||||||
/**
|
/**
|
||||||
* {@code "Accept-Patch"}
|
* {@code "Accept-Patch"}
|
||||||
*/
|
*/
|
||||||
public static final String ACCEPT_PATCH= "Accept-Patch";
|
public static final String ACCEPT_PATCH = "Accept-Patch";
|
||||||
/**
|
/**
|
||||||
* {@code "Age"}
|
* {@code "Age"}
|
||||||
*/
|
*/
|
||||||
@ -93,7 +93,7 @@ public class HttpHeaders {
|
|||||||
/**
|
/**
|
||||||
* {@code "Content-Language"}
|
* {@code "Content-Language"}
|
||||||
*/
|
*/
|
||||||
public static final String CONTENT_LANGUAGE= "Content-Language";
|
public static final String CONTENT_LANGUAGE = "Content-Language";
|
||||||
/**
|
/**
|
||||||
* {@code "Content-Length"}
|
* {@code "Content-Length"}
|
||||||
*/
|
*/
|
||||||
@ -117,7 +117,7 @@ public class HttpHeaders {
|
|||||||
/**
|
/**
|
||||||
* {@code "Content-Type"}
|
* {@code "Content-Type"}
|
||||||
*/
|
*/
|
||||||
public static final String CONTENT_TYPE= "Content-Type";
|
public static final String CONTENT_TYPE = "Content-Type";
|
||||||
/**
|
/**
|
||||||
* {@code "Cookie"}
|
* {@code "Cookie"}
|
||||||
*/
|
*/
|
||||||
@ -161,7 +161,7 @@ public class HttpHeaders {
|
|||||||
/**
|
/**
|
||||||
* {@code "If-Range"}
|
* {@code "If-Range"}
|
||||||
*/
|
*/
|
||||||
public static final String IF_RANGE= "If-Range";
|
public static final String IF_RANGE = "If-Range";
|
||||||
/**
|
/**
|
||||||
* {@code "If-Unmodified-Since"}
|
* {@code "If-Unmodified-Since"}
|
||||||
*/
|
*/
|
@ -568,11 +568,9 @@ public abstract class HttpMessageDecoder extends ReplayingDecoder<HttpMessageDec
|
|||||||
if (nextByte == HttpCodecUtil.LF) {
|
if (nextByte == HttpCodecUtil.LF) {
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
}
|
} else if (nextByte == HttpCodecUtil.LF) {
|
||||||
else if (nextByte == HttpCodecUtil.LF) {
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (lineLength >= maxLineLength) {
|
if (lineLength >= maxLineLength) {
|
||||||
// TODO: Respond with Bad Request and discard the traffic
|
// TODO: Respond with Bad Request and discard the traffic
|
||||||
// or close the connection.
|
// or close the connection.
|
@ -25,6 +25,8 @@ import io.netty.buffer.ChannelBuffer;
|
|||||||
import io.netty.buffer.ChannelBuffers;
|
import io.netty.buffer.ChannelBuffers;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.handler.codec.http.HttpHeaders.Names;
|
||||||
|
import io.netty.handler.codec.http.HttpHeaders.Values;
|
||||||
import io.netty.handler.codec.oneone.OneToOneEncoder;
|
import io.netty.handler.codec.oneone.OneToOneEncoder;
|
||||||
import io.netty.util.CharsetUtil;
|
import io.netty.util.CharsetUtil;
|
||||||
|
|
||||||
@ -59,7 +61,17 @@ public abstract class HttpMessageEncoder extends OneToOneEncoder {
|
|||||||
protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception {
|
protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception {
|
||||||
if (msg instanceof HttpMessage) {
|
if (msg instanceof HttpMessage) {
|
||||||
HttpMessage m = (HttpMessage) msg;
|
HttpMessage m = (HttpMessage) msg;
|
||||||
boolean chunked = this.chunked = HttpCodecUtil.isTransferEncodingChunked(m);
|
boolean chunked;
|
||||||
|
if (m.isChunked()) {
|
||||||
|
// check if the Transfer-Encoding is set to chunked already.
|
||||||
|
// if not add the header to the message
|
||||||
|
if (!HttpCodecUtil.isTransferEncodingChunked(m)) {
|
||||||
|
m.addHeader(Names.TRANSFER_ENCODING, Values.CHUNKED);
|
||||||
|
}
|
||||||
|
chunked = this.chunked = true;
|
||||||
|
} else {
|
||||||
|
chunked = this.chunked = HttpCodecUtil.isTransferEncodingChunked(m);
|
||||||
|
}
|
||||||
ChannelBuffer header = ChannelBuffers.dynamicBuffer(
|
ChannelBuffer header = ChannelBuffers.dynamicBuffer(
|
||||||
channel.getConfig().getBufferFactory());
|
channel.getConfig().getBufferFactory());
|
||||||
encodeInitialLine(header, m);
|
encodeInitialLine(header, m);
|
@ -23,7 +23,8 @@ import io.netty.util.CharsetUtil;
|
|||||||
/**
|
/**
|
||||||
* Shared Static object between HttpMessageDecoder, HttpPostRequestDecoder and HttpPostRequestEncoder
|
* Shared Static object between HttpMessageDecoder, HttpPostRequestDecoder and HttpPostRequestEncoder
|
||||||
*/
|
*/
|
||||||
public class HttpPostBodyUtil {
|
final class HttpPostBodyUtil {
|
||||||
|
|
||||||
public static int chunkSize = 8096;
|
public static int chunkSize = 8096;
|
||||||
/**
|
/**
|
||||||
* HTTP content disposition header name.
|
* HTTP content disposition header name.
|
@ -50,12 +50,12 @@ public class HttpPostRequestDecoder {
|
|||||||
/**
|
/**
|
||||||
* Does request have a body to decode
|
* Does request have a body to decode
|
||||||
*/
|
*/
|
||||||
private boolean bodyToDecode = false;
|
private boolean bodyToDecode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does the last chunk already received
|
* Does the last chunk already received
|
||||||
*/
|
*/
|
||||||
private boolean isLastChunk = false;
|
private boolean isLastChunk;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HttpDatas from Body
|
* HttpDatas from Body
|
||||||
@ -71,28 +71,28 @@ public class HttpPostRequestDecoder {
|
|||||||
/**
|
/**
|
||||||
* The current channelBuffer
|
* The current channelBuffer
|
||||||
*/
|
*/
|
||||||
private ChannelBuffer undecodedChunk = null;
|
private ChannelBuffer undecodedChunk;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does this request is a Multipart request
|
* Does this request is a Multipart request
|
||||||
*/
|
*/
|
||||||
private boolean isMultipart = false;
|
private boolean isMultipart;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Body HttpDatas current position
|
* Body HttpDatas current position
|
||||||
*/
|
*/
|
||||||
private int bodyListHttpDataRank = 0;
|
private int bodyListHttpDataRank;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If multipart, this is the boundary for the flobal multipart
|
* If multipart, this is the boundary for the flobal multipart
|
||||||
*/
|
*/
|
||||||
private String multipartDataBoundary = null;
|
private String multipartDataBoundary;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If multipart, there could be internal multiparts (mixed) to the global multipart.
|
* If multipart, there could be internal multiparts (mixed) to the global multipart.
|
||||||
* Only one level is allowed.
|
* Only one level is allowed.
|
||||||
*/
|
*/
|
||||||
private String multipartMixedBoundary = null;
|
private String multipartMixedBoundary;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Current status
|
* Current status
|
||||||
@ -102,17 +102,17 @@ public class HttpPostRequestDecoder {
|
|||||||
/**
|
/**
|
||||||
* Used in Multipart
|
* Used in Multipart
|
||||||
*/
|
*/
|
||||||
private Map<String, Attribute> currentFieldAttributes = null;
|
private Map<String, Attribute> currentFieldAttributes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current FileUpload that is currently in decode process
|
* The current FileUpload that is currently in decode process
|
||||||
*/
|
*/
|
||||||
private FileUpload currentFileUpload = null;
|
private FileUpload currentFileUpload;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current Attribute that is currently in decode process
|
* The current Attribute that is currently in decode process
|
||||||
*/
|
*/
|
||||||
private Attribute currentAttribute = null;
|
private Attribute currentAttribute;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -122,8 +122,7 @@ public class HttpPostRequestDecoder {
|
|||||||
* @throws ErrorDataDecoderException if the default charset was wrong when decoding or other errors
|
* @throws ErrorDataDecoderException if the default charset was wrong when decoding or other errors
|
||||||
*/
|
*/
|
||||||
public HttpPostRequestDecoder(HttpRequest request)
|
public HttpPostRequestDecoder(HttpRequest request)
|
||||||
throws ErrorDataDecoderException, IncompatibleDataDecoderException,
|
throws ErrorDataDecoderException, IncompatibleDataDecoderException {
|
||||||
NullPointerException {
|
|
||||||
this(new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE),
|
this(new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE),
|
||||||
request, HttpCodecUtil.DEFAULT_CHARSET);
|
request, HttpCodecUtil.DEFAULT_CHARSET);
|
||||||
}
|
}
|
||||||
@ -137,8 +136,7 @@ public class HttpPostRequestDecoder {
|
|||||||
* @throws ErrorDataDecoderException if the default charset was wrong when decoding or other errors
|
* @throws ErrorDataDecoderException if the default charset was wrong when decoding or other errors
|
||||||
*/
|
*/
|
||||||
public HttpPostRequestDecoder(HttpDataFactory factory, HttpRequest request)
|
public HttpPostRequestDecoder(HttpDataFactory factory, HttpRequest request)
|
||||||
throws ErrorDataDecoderException, IncompatibleDataDecoderException,
|
throws ErrorDataDecoderException, IncompatibleDataDecoderException {
|
||||||
NullPointerException {
|
|
||||||
this(factory, request, HttpCodecUtil.DEFAULT_CHARSET);
|
this(factory, request, HttpCodecUtil.DEFAULT_CHARSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,7 +151,7 @@ public class HttpPostRequestDecoder {
|
|||||||
*/
|
*/
|
||||||
public HttpPostRequestDecoder(HttpDataFactory factory, HttpRequest request,
|
public HttpPostRequestDecoder(HttpDataFactory factory, HttpRequest request,
|
||||||
Charset charset) throws ErrorDataDecoderException,
|
Charset charset) throws ErrorDataDecoderException,
|
||||||
IncompatibleDataDecoderException, NullPointerException {
|
IncompatibleDataDecoderException {
|
||||||
if (factory == null) {
|
if (factory == null) {
|
||||||
throw new NullPointerException("factory");
|
throw new NullPointerException("factory");
|
||||||
}
|
}
|
||||||
@ -446,19 +444,29 @@ public class HttpPostRequestDecoder {
|
|||||||
case DISPOSITION:// search '='
|
case DISPOSITION:// search '='
|
||||||
if (read == '=') {
|
if (read == '=') {
|
||||||
currentStatus = MultiPartStatus.FIELD;
|
currentStatus = MultiPartStatus.FIELD;
|
||||||
equalpos = currentpos-1;
|
equalpos = currentpos - 1;
|
||||||
String key = decodeAttribute(
|
String key = decodeAttribute(
|
||||||
undecodedChunk.toString(firstpos, equalpos-firstpos, charset),
|
undecodedChunk.toString(firstpos, equalpos - firstpos, charset),
|
||||||
charset);
|
charset);
|
||||||
currentAttribute = factory.createAttribute(request, key);
|
currentAttribute = factory.createAttribute(request, key);
|
||||||
firstpos = currentpos;
|
firstpos = currentpos;
|
||||||
|
} else if (read == '&') { // special empty FIELD
|
||||||
|
currentStatus = MultiPartStatus.DISPOSITION;
|
||||||
|
ampersandpos = currentpos - 1;
|
||||||
|
String key = decodeAttribute(undecodedChunk.toString(firstpos, ampersandpos - firstpos, charset), charset);
|
||||||
|
currentAttribute = factory.createAttribute(request, key);
|
||||||
|
currentAttribute.setValue(""); // empty
|
||||||
|
addHttpData(currentAttribute);
|
||||||
|
currentAttribute = null;
|
||||||
|
firstpos = currentpos;
|
||||||
|
contRead = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FIELD:// search '&' or end of line
|
case FIELD:// search '&' or end of line
|
||||||
if (read == '&') {
|
if (read == '&') {
|
||||||
currentStatus = MultiPartStatus.DISPOSITION;
|
currentStatus = MultiPartStatus.DISPOSITION;
|
||||||
ampersandpos = currentpos-1;
|
ampersandpos = currentpos - 1;
|
||||||
setFinalBuffer(undecodedChunk.slice(firstpos, ampersandpos-firstpos));
|
setFinalBuffer(undecodedChunk.slice(firstpos, ampersandpos - firstpos));
|
||||||
firstpos = currentpos;
|
firstpos = currentpos;
|
||||||
contRead = true;
|
contRead = true;
|
||||||
} else if (read == HttpCodecUtil.CR) {
|
} else if (read == HttpCodecUtil.CR) {
|
||||||
@ -467,9 +475,9 @@ public class HttpPostRequestDecoder {
|
|||||||
currentpos++;
|
currentpos++;
|
||||||
if (read == HttpCodecUtil.LF) {
|
if (read == HttpCodecUtil.LF) {
|
||||||
currentStatus = MultiPartStatus.PREEPILOGUE;
|
currentStatus = MultiPartStatus.PREEPILOGUE;
|
||||||
ampersandpos = currentpos-2;
|
ampersandpos = currentpos - 2;
|
||||||
setFinalBuffer(
|
setFinalBuffer(
|
||||||
undecodedChunk.slice(firstpos, ampersandpos-firstpos));
|
undecodedChunk.slice(firstpos, ampersandpos - firstpos));
|
||||||
firstpos = currentpos;
|
firstpos = currentpos;
|
||||||
contRead = false;
|
contRead = false;
|
||||||
} else {
|
} else {
|
||||||
@ -482,9 +490,9 @@ public class HttpPostRequestDecoder {
|
|||||||
}
|
}
|
||||||
} else if (read == HttpCodecUtil.LF) {
|
} else if (read == HttpCodecUtil.LF) {
|
||||||
currentStatus = MultiPartStatus.PREEPILOGUE;
|
currentStatus = MultiPartStatus.PREEPILOGUE;
|
||||||
ampersandpos = currentpos-1;
|
ampersandpos = currentpos - 1;
|
||||||
setFinalBuffer(
|
setFinalBuffer(
|
||||||
undecodedChunk.slice(firstpos, ampersandpos-firstpos));
|
undecodedChunk.slice(firstpos, ampersandpos - firstpos));
|
||||||
firstpos = currentpos;
|
firstpos = currentpos;
|
||||||
contRead = false;
|
contRead = false;
|
||||||
}
|
}
|
||||||
@ -499,7 +507,7 @@ public class HttpPostRequestDecoder {
|
|||||||
ampersandpos = currentpos;
|
ampersandpos = currentpos;
|
||||||
if (ampersandpos > firstpos) {
|
if (ampersandpos > firstpos) {
|
||||||
setFinalBuffer(
|
setFinalBuffer(
|
||||||
undecodedChunk.slice(firstpos, ampersandpos-firstpos));
|
undecodedChunk.slice(firstpos, ampersandpos - firstpos));
|
||||||
} else if (! currentAttribute.isCompleted()) {
|
} else if (! currentAttribute.isCompleted()) {
|
||||||
setFinalBuffer(ChannelBuffers.EMPTY_BUFFER);
|
setFinalBuffer(ChannelBuffers.EMPTY_BUFFER);
|
||||||
}
|
}
|
||||||
@ -511,7 +519,7 @@ public class HttpPostRequestDecoder {
|
|||||||
// reset index except if to continue in case of FIELD status
|
// reset index except if to continue in case of FIELD status
|
||||||
if (currentStatus == MultiPartStatus.FIELD) {
|
if (currentStatus == MultiPartStatus.FIELD) {
|
||||||
currentAttribute.addContent(
|
currentAttribute.addContent(
|
||||||
undecodedChunk.slice(firstpos, currentpos-firstpos),
|
undecodedChunk.slice(firstpos, currentpos - firstpos),
|
||||||
false);
|
false);
|
||||||
firstpos = currentpos;
|
firstpos = currentpos;
|
||||||
}
|
}
|
||||||
@ -1221,7 +1229,7 @@ public class HttpPostRequestDecoder {
|
|||||||
// so go back of delimiter size
|
// so go back of delimiter size
|
||||||
try {
|
try {
|
||||||
currentAttribute.addContent(
|
currentAttribute.addContent(
|
||||||
undecodedChunk.slice(readerIndex, lastPosition-readerIndex),
|
undecodedChunk.slice(readerIndex, lastPosition - readerIndex),
|
||||||
true);
|
true);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new ErrorDataDecoderException(e);
|
throw new ErrorDataDecoderException(e);
|
||||||
@ -1230,7 +1238,7 @@ public class HttpPostRequestDecoder {
|
|||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
currentAttribute.addContent(
|
currentAttribute.addContent(
|
||||||
undecodedChunk.slice(readerIndex, lastPosition-readerIndex),
|
undecodedChunk.slice(readerIndex, lastPosition - readerIndex),
|
||||||
false);
|
false);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new ErrorDataDecoderException(e);
|
throw new ErrorDataDecoderException(e);
|
@ -51,16 +51,16 @@ public class HttpPostRequestEncoder implements ChunkedInput {
|
|||||||
/**
|
/**
|
||||||
* Chunked false by default
|
* Chunked false by default
|
||||||
*/
|
*/
|
||||||
private boolean isChunked = false;
|
private boolean isChunked;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* InterfaceHttpData for Body (without encoding)
|
* InterfaceHttpData for Body (without encoding)
|
||||||
*/
|
*/
|
||||||
private List<InterfaceHttpData> bodyListDatas = null;
|
private List<InterfaceHttpData> bodyListDatas;
|
||||||
/**
|
/**
|
||||||
* The final Multipart List of InterfaceHttpData including encoding
|
* The final Multipart List of InterfaceHttpData including encoding
|
||||||
*/
|
*/
|
||||||
private List<InterfaceHttpData> multipartHttpDatas = null;
|
private List<InterfaceHttpData> multipartHttpDatas;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does this request is a Multipart request
|
* Does this request is a Multipart request
|
||||||
@ -70,17 +70,17 @@ public class HttpPostRequestEncoder implements ChunkedInput {
|
|||||||
/**
|
/**
|
||||||
* If multipart, this is the boundary for the flobal multipart
|
* If multipart, this is the boundary for the flobal multipart
|
||||||
*/
|
*/
|
||||||
private String multipartDataBoundary = null;
|
private String multipartDataBoundary;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If multipart, there could be internal multiparts (mixed) to the global multipart.
|
* If multipart, there could be internal multiparts (mixed) to the global multipart.
|
||||||
* Only one level is allowed.
|
* Only one level is allowed.
|
||||||
*/
|
*/
|
||||||
private String multipartMixedBoundary = null;
|
private String multipartMixedBoundary;
|
||||||
/**
|
/**
|
||||||
* To check if the header has been finalized
|
* To check if the header has been finalized
|
||||||
*/
|
*/
|
||||||
private boolean headerFinalized = false;
|
private boolean headerFinalized;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -90,7 +90,7 @@ public class HttpPostRequestEncoder implements ChunkedInput {
|
|||||||
* @throws ErrorDataEncoderException if the request is not a POST
|
* @throws ErrorDataEncoderException if the request is not a POST
|
||||||
*/
|
*/
|
||||||
public HttpPostRequestEncoder(HttpRequest request, boolean multipart)
|
public HttpPostRequestEncoder(HttpRequest request, boolean multipart)
|
||||||
throws ErrorDataEncoderException, NullPointerException {
|
throws ErrorDataEncoderException {
|
||||||
this(new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE),
|
this(new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE),
|
||||||
request, multipart, HttpCodecUtil.DEFAULT_CHARSET);
|
request, multipart, HttpCodecUtil.DEFAULT_CHARSET);
|
||||||
}
|
}
|
||||||
@ -104,7 +104,7 @@ public class HttpPostRequestEncoder implements ChunkedInput {
|
|||||||
* @throws ErrorDataEncoderException if the request is not a POST
|
* @throws ErrorDataEncoderException if the request is not a POST
|
||||||
*/
|
*/
|
||||||
public HttpPostRequestEncoder(HttpDataFactory factory, HttpRequest request, boolean multipart)
|
public HttpPostRequestEncoder(HttpDataFactory factory, HttpRequest request, boolean multipart)
|
||||||
throws ErrorDataEncoderException, NullPointerException {
|
throws ErrorDataEncoderException {
|
||||||
this(factory, request, multipart, HttpCodecUtil.DEFAULT_CHARSET);
|
this(factory, request, multipart, HttpCodecUtil.DEFAULT_CHARSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,8 +118,7 @@ public class HttpPostRequestEncoder implements ChunkedInput {
|
|||||||
* @throws ErrorDataEncoderException if the request is not a POST
|
* @throws ErrorDataEncoderException if the request is not a POST
|
||||||
*/
|
*/
|
||||||
public HttpPostRequestEncoder(HttpDataFactory factory, HttpRequest request,
|
public HttpPostRequestEncoder(HttpDataFactory factory, HttpRequest request,
|
||||||
boolean multipart, Charset charset) throws ErrorDataEncoderException,
|
boolean multipart, Charset charset) throws ErrorDataEncoderException {
|
||||||
NullPointerException {
|
|
||||||
if (factory == null) {
|
if (factory == null) {
|
||||||
throw new NullPointerException("factory");
|
throw new NullPointerException("factory");
|
||||||
}
|
}
|
||||||
@ -157,24 +156,24 @@ public class HttpPostRequestEncoder implements ChunkedInput {
|
|||||||
/**
|
/**
|
||||||
* Does the last non empty chunk already encoded so that next chunk will be empty (last chunk)
|
* Does the last non empty chunk already encoded so that next chunk will be empty (last chunk)
|
||||||
*/
|
*/
|
||||||
private boolean isLastChunk = false;
|
private boolean isLastChunk;
|
||||||
/**
|
/**
|
||||||
* Last chunk already sent
|
* Last chunk already sent
|
||||||
*/
|
*/
|
||||||
private boolean isLastChunkSent = false;
|
private boolean isLastChunkSent;
|
||||||
/**
|
/**
|
||||||
* The current FileUpload that is currently in encode process
|
* The current FileUpload that is currently in encode process
|
||||||
*/
|
*/
|
||||||
private FileUpload currentFileUpload = null;
|
private FileUpload currentFileUpload;
|
||||||
/**
|
/**
|
||||||
* While adding a FileUpload, is the multipart currently in Mixed Mode
|
* While adding a FileUpload, is the multipart currently in Mixed Mode
|
||||||
*/
|
*/
|
||||||
private boolean duringMixedMode = false;
|
private boolean duringMixedMode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Global Body size
|
* Global Body size
|
||||||
*/
|
*/
|
||||||
private long globalBodySize = 0;
|
private long globalBodySize;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if this request is a Multipart request
|
* True if this request is a Multipart request
|
||||||
@ -224,7 +223,7 @@ public class HttpPostRequestEncoder implements ChunkedInput {
|
|||||||
* @throws ErrorDataEncoderException if the encoding is in error or if the finalize were already done
|
* @throws ErrorDataEncoderException if the encoding is in error or if the finalize were already done
|
||||||
*/
|
*/
|
||||||
public void setBodyHttpDatas(List<InterfaceHttpData> datas)
|
public void setBodyHttpDatas(List<InterfaceHttpData> datas)
|
||||||
throws NullPointerException, ErrorDataEncoderException {
|
throws ErrorDataEncoderException {
|
||||||
if (datas == null) {
|
if (datas == null) {
|
||||||
throw new NullPointerException("datas");
|
throw new NullPointerException("datas");
|
||||||
}
|
}
|
||||||
@ -246,7 +245,7 @@ public class HttpPostRequestEncoder implements ChunkedInput {
|
|||||||
* @throws ErrorDataEncoderException if the encoding is in error or if the finalize were already done
|
* @throws ErrorDataEncoderException if the encoding is in error or if the finalize were already done
|
||||||
*/
|
*/
|
||||||
public void addBodyAttribute(String name, String value)
|
public void addBodyAttribute(String name, String value)
|
||||||
throws NullPointerException, ErrorDataEncoderException {
|
throws ErrorDataEncoderException {
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
throw new NullPointerException("name");
|
throw new NullPointerException("name");
|
||||||
}
|
}
|
||||||
@ -268,7 +267,7 @@ public class HttpPostRequestEncoder implements ChunkedInput {
|
|||||||
* @throws ErrorDataEncoderException if the encoding is in error or if the finalize were already done
|
* @throws ErrorDataEncoderException if the encoding is in error or if the finalize were already done
|
||||||
*/
|
*/
|
||||||
public void addBodyFileUpload(String name, File file, String contentType, boolean isText)
|
public void addBodyFileUpload(String name, File file, String contentType, boolean isText)
|
||||||
throws NullPointerException, ErrorDataEncoderException {
|
throws ErrorDataEncoderException {
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
throw new NullPointerException("name");
|
throw new NullPointerException("name");
|
||||||
}
|
}
|
||||||
@ -307,7 +306,7 @@ public class HttpPostRequestEncoder implements ChunkedInput {
|
|||||||
* @throws ErrorDataEncoderException if the encoding is in error or if the finalize were already done
|
* @throws ErrorDataEncoderException if the encoding is in error or if the finalize were already done
|
||||||
*/
|
*/
|
||||||
public void addBodyFileUploads(String name, File[] file, String[] contentType, boolean[] isText)
|
public void addBodyFileUploads(String name, File[] file, String[] contentType, boolean[] isText)
|
||||||
throws NullPointerException, ErrorDataEncoderException {
|
throws ErrorDataEncoderException {
|
||||||
if (file.length != contentType.length && file.length != isText.length) {
|
if (file.length != contentType.length && file.length != isText.length) {
|
||||||
throw new NullPointerException("Different array length");
|
throw new NullPointerException("Different array length");
|
||||||
}
|
}
|
||||||
@ -323,7 +322,7 @@ public class HttpPostRequestEncoder implements ChunkedInput {
|
|||||||
* @throws ErrorDataEncoderException if the encoding is in error or if the finalize were already done
|
* @throws ErrorDataEncoderException if the encoding is in error or if the finalize were already done
|
||||||
*/
|
*/
|
||||||
public void addBodyHttpData(InterfaceHttpData data)
|
public void addBodyHttpData(InterfaceHttpData data)
|
||||||
throws NullPointerException, ErrorDataEncoderException {
|
throws ErrorDataEncoderException {
|
||||||
if (headerFinalized) {
|
if (headerFinalized) {
|
||||||
throw new ErrorDataEncoderException("Cannot add value once finalized");
|
throw new ErrorDataEncoderException("Cannot add value once finalized");
|
||||||
}
|
}
|
||||||
@ -340,12 +339,12 @@ public class HttpPostRequestEncoder implements ChunkedInput {
|
|||||||
String value = encodeAttribute(attribute.getValue(), charset);
|
String value = encodeAttribute(attribute.getValue(), charset);
|
||||||
Attribute newattribute = factory.createAttribute(request, key, value);
|
Attribute newattribute = factory.createAttribute(request, key, value);
|
||||||
multipartHttpDatas.add(newattribute);
|
multipartHttpDatas.add(newattribute);
|
||||||
globalBodySize += newattribute.getName().length()+1+
|
globalBodySize += newattribute.getName().length() + 1 +
|
||||||
newattribute.length()+1;
|
newattribute.length() + 1;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new ErrorDataEncoderException(e);
|
throw new ErrorDataEncoderException(e);
|
||||||
}
|
}
|
||||||
} else if (data instanceof FileUpload){
|
} else if (data instanceof FileUpload) {
|
||||||
// since not Multipart, only name=filename => Attribute
|
// since not Multipart, only name=filename => Attribute
|
||||||
FileUpload fileUpload = (FileUpload) data;
|
FileUpload fileUpload = (FileUpload) data;
|
||||||
// name=filename& with encoded name and filename
|
// name=filename& with encoded name and filename
|
||||||
@ -353,8 +352,8 @@ public class HttpPostRequestEncoder implements ChunkedInput {
|
|||||||
String value = encodeAttribute(fileUpload.getFilename(), charset);
|
String value = encodeAttribute(fileUpload.getFilename(), charset);
|
||||||
Attribute newattribute = factory.createAttribute(request, key, value);
|
Attribute newattribute = factory.createAttribute(request, key, value);
|
||||||
multipartHttpDatas.add(newattribute);
|
multipartHttpDatas.add(newattribute);
|
||||||
globalBodySize += newattribute.getName().length()+1+
|
globalBodySize += newattribute.getName().length() + 1 +
|
||||||
newattribute.length()+1;
|
newattribute.length() + 1;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -393,7 +392,7 @@ public class HttpPostRequestEncoder implements ChunkedInput {
|
|||||||
if (data instanceof Attribute) {
|
if (data instanceof Attribute) {
|
||||||
if (duringMixedMode) {
|
if (duringMixedMode) {
|
||||||
InternalAttribute internal = new InternalAttribute();
|
InternalAttribute internal = new InternalAttribute();
|
||||||
internal.addValue("\r\n--"+multipartMixedBoundary+"--");
|
internal.addValue("\r\n--" + multipartMixedBoundary + "--");
|
||||||
multipartHttpDatas.add(internal);
|
multipartHttpDatas.add(internal);
|
||||||
multipartMixedBoundary = null;
|
multipartMixedBoundary = null;
|
||||||
currentFileUpload = null;
|
currentFileUpload = null;
|
||||||
@ -404,24 +403,24 @@ public class HttpPostRequestEncoder implements ChunkedInput {
|
|||||||
// previously a data field so CRLF
|
// previously a data field so CRLF
|
||||||
internal.addValue("\r\n");
|
internal.addValue("\r\n");
|
||||||
}
|
}
|
||||||
internal.addValue("--"+multipartDataBoundary+"\r\n");
|
internal.addValue("--" + multipartDataBoundary + "\r\n");
|
||||||
// content-disposition: form-data; name="field1"
|
// content-disposition: form-data; name="field1"
|
||||||
Attribute attribute = (Attribute) data;
|
Attribute attribute = (Attribute) data;
|
||||||
internal.addValue(HttpPostBodyUtil.CONTENT_DISPOSITION+": "+
|
internal.addValue(HttpPostBodyUtil.CONTENT_DISPOSITION + ": " +
|
||||||
HttpPostBodyUtil.FORM_DATA+"; "+
|
HttpPostBodyUtil.FORM_DATA + "; " +
|
||||||
HttpPostBodyUtil.NAME+"=\""+
|
HttpPostBodyUtil.NAME + "=\"" +
|
||||||
encodeAttribute(attribute.getName(), charset)+"\"\r\n");
|
encodeAttribute(attribute.getName(), charset) + "\"\r\n");
|
||||||
Charset localcharset = attribute.getCharset();
|
Charset localcharset = attribute.getCharset();
|
||||||
if (localcharset != null) {
|
if (localcharset != null) {
|
||||||
// Content-Type: charset=charset
|
// Content-Type: charset=charset
|
||||||
internal.addValue(HttpHeaders.Names.CONTENT_TYPE+": "+
|
internal.addValue(HttpHeaders.Names.CONTENT_TYPE + ": " +
|
||||||
HttpHeaders.Values.CHARSET+"="+localcharset+"\r\n");
|
HttpHeaders.Values.CHARSET + "=" + localcharset + "\r\n");
|
||||||
}
|
}
|
||||||
// CRLF between body header and data
|
// CRLF between body header and data
|
||||||
internal.addValue("\r\n");
|
internal.addValue("\r\n");
|
||||||
multipartHttpDatas.add(internal);
|
multipartHttpDatas.add(internal);
|
||||||
multipartHttpDatas.add(data);
|
multipartHttpDatas.add(data);
|
||||||
globalBodySize += attribute.length()+internal.size();
|
globalBodySize += attribute.length() + internal.size();
|
||||||
} else if (data instanceof FileUpload) {
|
} else if (data instanceof FileUpload) {
|
||||||
FileUpload fileUpload = (FileUpload) data;
|
FileUpload fileUpload = (FileUpload) data;
|
||||||
InternalAttribute internal = new InternalAttribute();
|
InternalAttribute internal = new InternalAttribute();
|
||||||
@ -441,7 +440,7 @@ public class HttpPostRequestEncoder implements ChunkedInput {
|
|||||||
|
|
||||||
// add endmixedmultipart delimiter, multipart body header and
|
// add endmixedmultipart delimiter, multipart body header and
|
||||||
// Data to multipart list
|
// Data to multipart list
|
||||||
internal.addValue("--"+multipartMixedBoundary+"--");
|
internal.addValue("--" + multipartMixedBoundary + "--");
|
||||||
multipartHttpDatas.add(internal);
|
multipartHttpDatas.add(internal);
|
||||||
multipartMixedBoundary = null;
|
multipartMixedBoundary = null;
|
||||||
// start a new one (could be replaced if mixed start again from here
|
// start a new one (could be replaced if mixed start again from here
|
||||||
@ -475,19 +474,19 @@ public class HttpPostRequestEncoder implements ChunkedInput {
|
|||||||
// Content-Type: text/plain
|
// Content-Type: text/plain
|
||||||
initMixedMultipart();
|
initMixedMultipart();
|
||||||
InternalAttribute pastAttribute =
|
InternalAttribute pastAttribute =
|
||||||
(InternalAttribute) multipartHttpDatas.get(multipartHttpDatas.size()-2);
|
(InternalAttribute) multipartHttpDatas.get(multipartHttpDatas.size() - 2);
|
||||||
// remove past size
|
// remove past size
|
||||||
globalBodySize -= pastAttribute.size();
|
globalBodySize -= pastAttribute.size();
|
||||||
String replacement = HttpPostBodyUtil.CONTENT_DISPOSITION+": "+
|
String replacement = HttpPostBodyUtil.CONTENT_DISPOSITION + ": " +
|
||||||
HttpPostBodyUtil.FORM_DATA+"; "+HttpPostBodyUtil.NAME+"=\""+
|
HttpPostBodyUtil.FORM_DATA + "; " + HttpPostBodyUtil.NAME + "=\"" +
|
||||||
encodeAttribute(fileUpload.getName(), charset)+"\"\r\n";
|
encodeAttribute(fileUpload.getName(), charset) + "\"\r\n";
|
||||||
replacement += HttpHeaders.Names.CONTENT_TYPE+": "+
|
replacement += HttpHeaders.Names.CONTENT_TYPE + ": " +
|
||||||
HttpPostBodyUtil.MULTIPART_MIXED+"; "+HttpHeaders.Values.BOUNDARY+
|
HttpPostBodyUtil.MULTIPART_MIXED + "; " + HttpHeaders.Values.BOUNDARY +
|
||||||
"="+multipartMixedBoundary+"\r\n\r\n";
|
"=" + multipartMixedBoundary + "\r\n\r\n";
|
||||||
replacement += "--"+multipartMixedBoundary+"\r\n";
|
replacement += "--" + multipartMixedBoundary + "\r\n";
|
||||||
replacement += HttpPostBodyUtil.CONTENT_DISPOSITION+": "+
|
replacement += HttpPostBodyUtil.CONTENT_DISPOSITION + ": " +
|
||||||
HttpPostBodyUtil.FILE+"; "+HttpPostBodyUtil.FILENAME+"=\""+
|
HttpPostBodyUtil.FILE + "; " + HttpPostBodyUtil.FILENAME + "=\"" +
|
||||||
encodeAttribute(fileUpload.getFilename(), charset)+
|
encodeAttribute(fileUpload.getFilename(), charset) +
|
||||||
"\"\r\n";
|
"\"\r\n";
|
||||||
pastAttribute.setValue(replacement, 1);
|
pastAttribute.setValue(replacement, 1);
|
||||||
// update past size
|
// update past size
|
||||||
@ -510,51 +509,51 @@ public class HttpPostRequestEncoder implements ChunkedInput {
|
|||||||
if (localMixed) {
|
if (localMixed) {
|
||||||
// add mixedmultipart delimiter, mixedmultipart body header and
|
// add mixedmultipart delimiter, mixedmultipart body header and
|
||||||
// Data to multipart list
|
// Data to multipart list
|
||||||
internal.addValue("--"+multipartMixedBoundary+"\r\n");
|
internal.addValue("--" + multipartMixedBoundary + "\r\n");
|
||||||
// Content-Disposition: file; filename="file1.txt"
|
// Content-Disposition: file; filename="file1.txt"
|
||||||
internal.addValue(HttpPostBodyUtil.CONTENT_DISPOSITION+": "+
|
internal.addValue(HttpPostBodyUtil.CONTENT_DISPOSITION + ": " +
|
||||||
HttpPostBodyUtil.FILE+"; "+HttpPostBodyUtil.FILENAME+"=\""+
|
HttpPostBodyUtil.FILE + "; " + HttpPostBodyUtil.FILENAME + "=\"" +
|
||||||
encodeAttribute(fileUpload.getFilename(), charset)+
|
encodeAttribute(fileUpload.getFilename(), charset) +
|
||||||
"\"\r\n");
|
"\"\r\n");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
internal.addValue("--"+multipartDataBoundary+"\r\n");
|
internal.addValue("--" + multipartDataBoundary + "\r\n");
|
||||||
// Content-Disposition: form-data; name="files"; filename="file1.txt"
|
// Content-Disposition: form-data; name="files"; filename="file1.txt"
|
||||||
internal.addValue(HttpPostBodyUtil.CONTENT_DISPOSITION+": "+
|
internal.addValue(HttpPostBodyUtil.CONTENT_DISPOSITION + ": " +
|
||||||
HttpPostBodyUtil.FORM_DATA+"; "+HttpPostBodyUtil.NAME+"=\""+
|
HttpPostBodyUtil.FORM_DATA + "; " + HttpPostBodyUtil.NAME + "=\"" +
|
||||||
encodeAttribute(fileUpload.getName(), charset)+"\"; "+
|
encodeAttribute(fileUpload.getName(), charset) + "\"; " +
|
||||||
HttpPostBodyUtil.FILENAME+"=\""+
|
HttpPostBodyUtil.FILENAME + "=\"" +
|
||||||
encodeAttribute(fileUpload.getFilename(), charset)+
|
encodeAttribute(fileUpload.getFilename(), charset) +
|
||||||
"\"\r\n");
|
"\"\r\n");
|
||||||
}
|
}
|
||||||
// Content-Type: image/gif
|
// Content-Type: image/gif
|
||||||
// Content-Type: text/plain; charset=ISO-8859-1
|
// Content-Type: text/plain; charset=ISO-8859-1
|
||||||
// Content-Transfer-Encoding: binary
|
// Content-Transfer-Encoding: binary
|
||||||
internal.addValue(HttpHeaders.Names.CONTENT_TYPE+": "+
|
internal.addValue(HttpHeaders.Names.CONTENT_TYPE + ": " +
|
||||||
fileUpload.getContentType());
|
fileUpload.getContentType());
|
||||||
String contentTransferEncoding = fileUpload.getContentTransferEncoding();
|
String contentTransferEncoding = fileUpload.getContentTransferEncoding();
|
||||||
if (contentTransferEncoding != null &&
|
if (contentTransferEncoding != null &&
|
||||||
contentTransferEncoding.equals(
|
contentTransferEncoding.equals(
|
||||||
HttpPostBodyUtil.TransferEncodingMechanism.BINARY.value)) {
|
HttpPostBodyUtil.TransferEncodingMechanism.BINARY.value)) {
|
||||||
internal.addValue("\r\n"+HttpHeaders.Names.CONTENT_TRANSFER_ENCODING+
|
internal.addValue("\r\n" + HttpHeaders.Names.CONTENT_TRANSFER_ENCODING +
|
||||||
": "+HttpPostBodyUtil.TransferEncodingMechanism.BINARY.value+
|
": " + HttpPostBodyUtil.TransferEncodingMechanism.BINARY.value +
|
||||||
"\r\n\r\n");
|
"\r\n\r\n");
|
||||||
} else if (fileUpload.getCharset() != null) {
|
} else if (fileUpload.getCharset() != null) {
|
||||||
internal.addValue("; "+HttpHeaders.Values.CHARSET+"="+
|
internal.addValue("; " + HttpHeaders.Values.CHARSET + "=" +
|
||||||
fileUpload.getCharset()+"\r\n\r\n");
|
fileUpload.getCharset() + "\r\n\r\n");
|
||||||
} else {
|
} else {
|
||||||
internal.addValue("\r\n\r\n");
|
internal.addValue("\r\n\r\n");
|
||||||
}
|
}
|
||||||
multipartHttpDatas.add(internal);
|
multipartHttpDatas.add(internal);
|
||||||
multipartHttpDatas.add(data);
|
multipartHttpDatas.add(data);
|
||||||
globalBodySize += fileUpload.length()+internal.size();
|
globalBodySize += fileUpload.length() + internal.size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Iterator to be used when encoding will be called chunk after chunk
|
* Iterator to be used when encoding will be called chunk after chunk
|
||||||
*/
|
*/
|
||||||
private ListIterator<InterfaceHttpData> iterator = null;
|
private ListIterator<InterfaceHttpData> iterator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finalize the request by preparing the Header in the request and
|
* Finalize the request by preparing the Header in the request and
|
||||||
@ -573,9 +572,9 @@ public class HttpPostRequestEncoder implements ChunkedInput {
|
|||||||
if (isMultipart) {
|
if (isMultipart) {
|
||||||
InternalAttribute internal = new InternalAttribute();
|
InternalAttribute internal = new InternalAttribute();
|
||||||
if (duringMixedMode) {
|
if (duringMixedMode) {
|
||||||
internal.addValue("\r\n--"+multipartMixedBoundary+"--");
|
internal.addValue("\r\n--" + multipartMixedBoundary + "--");
|
||||||
}
|
}
|
||||||
internal.addValue("\r\n--"+multipartDataBoundary+"--\r\n");
|
internal.addValue("\r\n--" + multipartDataBoundary + "--\r\n");
|
||||||
multipartHttpDatas.add(internal);
|
multipartHttpDatas.add(internal);
|
||||||
multipartMixedBoundary = null;
|
multipartMixedBoundary = null;
|
||||||
currentFileUpload = null;
|
currentFileUpload = null;
|
||||||
@ -597,7 +596,7 @@ public class HttpPostRequestEncoder implements ChunkedInput {
|
|||||||
HttpHeaders.Values.MULTIPART_FORM_DATA)) {
|
HttpHeaders.Values.MULTIPART_FORM_DATA)) {
|
||||||
// ignore
|
// ignore
|
||||||
} else if (contentType.toLowerCase().startsWith(
|
} else if (contentType.toLowerCase().startsWith(
|
||||||
HttpHeaders.Values.APPLICATION_X_WWW_FORM_URLENCODED)){
|
HttpHeaders.Values.APPLICATION_X_WWW_FORM_URLENCODED)) {
|
||||||
// ignore
|
// ignore
|
||||||
} else {
|
} else {
|
||||||
request.addHeader(HttpHeaders.Names.CONTENT_TYPE, contentType);
|
request.addHeader(HttpHeaders.Names.CONTENT_TYPE, contentType);
|
||||||
@ -675,11 +674,11 @@ public class HttpPostRequestEncoder implements ChunkedInput {
|
|||||||
/**
|
/**
|
||||||
* The ChannelBuffer currently used by the encoder
|
* The ChannelBuffer currently used by the encoder
|
||||||
*/
|
*/
|
||||||
private ChannelBuffer currentBuffer = null;
|
private ChannelBuffer currentBuffer;
|
||||||
/**
|
/**
|
||||||
* The current InterfaceHttpData to encode (used if more chunks are available)
|
* The current InterfaceHttpData to encode (used if more chunks are available)
|
||||||
*/
|
*/
|
||||||
private InterfaceHttpData currentData = null;
|
private InterfaceHttpData currentData;
|
||||||
/**
|
/**
|
||||||
* If not multipart, does the currentBuffer stands for the Key or for the Value
|
* If not multipart, does the currentBuffer stands for the Key or for the Value
|
||||||
*/
|
*/
|
||||||
@ -787,12 +786,12 @@ public class HttpPostRequestEncoder implements ChunkedInput {
|
|||||||
currentBuffer = ChannelBuffers.wrappedBuffer(
|
currentBuffer = ChannelBuffers.wrappedBuffer(
|
||||||
buffer, ChannelBuffers.wrappedBuffer("=".getBytes()));
|
buffer, ChannelBuffers.wrappedBuffer("=".getBytes()));
|
||||||
//continue
|
//continue
|
||||||
size -= buffer.readableBytes()+1;
|
size -= buffer.readableBytes() + 1;
|
||||||
} else {
|
} else {
|
||||||
currentBuffer = ChannelBuffers.wrappedBuffer(currentBuffer,
|
currentBuffer = ChannelBuffers.wrappedBuffer(currentBuffer,
|
||||||
buffer, ChannelBuffers.wrappedBuffer("=".getBytes()));
|
buffer, ChannelBuffers.wrappedBuffer("=".getBytes()));
|
||||||
//continue
|
//continue
|
||||||
size -= buffer.readableBytes()+1;
|
size -= buffer.readableBytes() + 1;
|
||||||
}
|
}
|
||||||
if (currentBuffer.readableBytes() >= HttpPostBodyUtil.chunkSize) {
|
if (currentBuffer.readableBytes() >= HttpPostBodyUtil.chunkSize) {
|
||||||
buffer = fillChannelBuffer();
|
buffer = fillChannelBuffer();
|
@ -71,7 +71,7 @@ public class HttpRequestDecoder extends HttpMessageDecoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected HttpMessage createMessage(String[] initialLine) throws Exception{
|
protected HttpMessage createMessage(String[] initialLine) throws Exception {
|
||||||
return new DefaultHttpRequest(
|
return new DefaultHttpRequest(
|
||||||
HttpVersion.valueOf(initialLine[2]), HttpMethod.valueOf(initialLine[0]), initialLine[1]);
|
HttpVersion.valueOf(initialLine[2]), HttpMethod.valueOf(initialLine[0]), initialLine[1]);
|
||||||
}
|
}
|
@ -36,8 +36,7 @@ public class MemoryAttribute extends AbstractMemoryHttpData implements Attribute
|
|||||||
* @throws IllegalArgumentException
|
* @throws IllegalArgumentException
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public MemoryAttribute(String name, String value)
|
public MemoryAttribute(String name, String value) throws IOException {
|
||||||
throws NullPointerException, IllegalArgumentException, IOException {
|
|
||||||
super(name, HttpCodecUtil.DEFAULT_CHARSET, 0); // Attribute have no default size
|
super(name, HttpCodecUtil.DEFAULT_CHARSET, 0); // Attribute have no default size
|
||||||
setValue(value);
|
setValue(value);
|
||||||
}
|
}
|
@ -24,15 +24,14 @@ import java.nio.charset.Charset;
|
|||||||
*/
|
*/
|
||||||
public class MemoryFileUpload extends AbstractMemoryHttpData implements FileUpload {
|
public class MemoryFileUpload extends AbstractMemoryHttpData implements FileUpload {
|
||||||
|
|
||||||
private String filename = null;
|
private String filename;
|
||||||
|
|
||||||
private String contentType = null;
|
private String contentType;
|
||||||
|
|
||||||
private String contentTransferEncoding = null;
|
private String contentTransferEncoding;
|
||||||
|
|
||||||
public MemoryFileUpload(String name, String filename, String contentType,
|
public MemoryFileUpload(String name, String filename, String contentType,
|
||||||
String contentTransferEncoding, Charset charset, long size)
|
String contentTransferEncoding, Charset charset, long size) {
|
||||||
throws NullPointerException, IllegalArgumentException {
|
|
||||||
super(name, charset, size);
|
super(name, charset, size);
|
||||||
setFilename(filename);
|
setFilename(filename);
|
||||||
setContentType(contentType);
|
setContentType(contentType);
|
||||||
@ -115,12 +114,12 @@ public class MemoryFileUpload extends AbstractMemoryHttpData implements FileUplo
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return HttpPostBodyUtil.CONTENT_DISPOSITION+": "+
|
return HttpPostBodyUtil.CONTENT_DISPOSITION + ": " +
|
||||||
HttpPostBodyUtil.FORM_DATA+"; "+HttpPostBodyUtil.NAME+"=\"" + getName() +
|
HttpPostBodyUtil.FORM_DATA + "; " + HttpPostBodyUtil.NAME + "=\"" + getName() +
|
||||||
"\"; "+HttpPostBodyUtil.FILENAME+"=\"" + filename + "\"\r\n" +
|
"\"; " + HttpPostBodyUtil.FILENAME + "=\"" + filename + "\"\r\n" +
|
||||||
HttpHeaders.Names.CONTENT_TYPE+": " + contentType +
|
HttpHeaders.Names.CONTENT_TYPE + ": " + contentType +
|
||||||
(charset != null? "; "+HttpHeaders.Values.CHARSET+"=" + charset + "\r\n" : "\r\n") +
|
(charset != null? "; " + HttpHeaders.Values.CHARSET + "=" + charset + "\r\n" : "\r\n") +
|
||||||
HttpHeaders.Names.CONTENT_LENGTH+": " + length() + "\r\n" +
|
HttpHeaders.Names.CONTENT_LENGTH + ": " + length() + "\r\n" +
|
||||||
"Completed: " + isCompleted() +
|
"Completed: " + isCompleted() +
|
||||||
"\r\nIsInMemory: " + isInMemory();
|
"\r\nIsInMemory: " + isInMemory();
|
||||||
}
|
}
|
@ -26,20 +26,16 @@ import io.netty.buffer.ChannelBuffer;
|
|||||||
* Mixed implementation using both in Memory and in File with a limit of size
|
* Mixed implementation using both in Memory and in File with a limit of size
|
||||||
*/
|
*/
|
||||||
public class MixedAttribute implements Attribute {
|
public class MixedAttribute implements Attribute {
|
||||||
private Attribute attribute = null;
|
private Attribute attribute;
|
||||||
|
|
||||||
private long limitSize = 0;
|
private long limitSize;
|
||||||
|
|
||||||
public MixedAttribute(String name,
|
public MixedAttribute(String name, long limitSize) {
|
||||||
long limitSize) throws NullPointerException,
|
|
||||||
IllegalArgumentException {
|
|
||||||
this.limitSize = limitSize;
|
this.limitSize = limitSize;
|
||||||
attribute = new MemoryAttribute(name);
|
attribute = new MemoryAttribute(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MixedAttribute(String name, String value,
|
public MixedAttribute(String name, String value, long limitSize) {
|
||||||
long limitSize) throws NullPointerException,
|
|
||||||
IllegalArgumentException {
|
|
||||||
this.limitSize = limitSize;
|
this.limitSize = limitSize;
|
||||||
if (value.length() > this.limitSize) {
|
if (value.length() > this.limitSize) {
|
||||||
try {
|
try {
|
||||||
@ -62,8 +58,7 @@ public class MixedAttribute implements Attribute {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addContent(ChannelBuffer buffer, boolean last)
|
public void addContent(ChannelBuffer buffer, boolean last) throws IOException {
|
||||||
throws IOException {
|
|
||||||
if (attribute instanceof MemoryAttribute) {
|
if (attribute instanceof MemoryAttribute) {
|
||||||
if (attribute.length() + buffer.readableBytes() > limitSize) {
|
if (attribute.length() + buffer.readableBytes() > limitSize) {
|
||||||
DiskAttribute diskAttribute = new DiskAttribute(attribute
|
DiskAttribute diskAttribute = new DiskAttribute(attribute
|
@ -26,16 +26,15 @@ import io.netty.buffer.ChannelBuffer;
|
|||||||
* Mixed implementation using both in Memory and in File with a limit of size
|
* Mixed implementation using both in Memory and in File with a limit of size
|
||||||
*/
|
*/
|
||||||
public class MixedFileUpload implements FileUpload {
|
public class MixedFileUpload implements FileUpload {
|
||||||
private FileUpload fileUpload = null;
|
private FileUpload fileUpload;
|
||||||
|
|
||||||
private long limitSize = 0;
|
private long limitSize;
|
||||||
|
|
||||||
private long definedSize = 0;
|
private long definedSize;
|
||||||
|
|
||||||
public MixedFileUpload(String name, String filename, String contentType,
|
public MixedFileUpload(String name, String filename, String contentType,
|
||||||
String contentTransferEncoding, Charset charset, long size,
|
String contentTransferEncoding, Charset charset, long size,
|
||||||
long limitSize) throws NullPointerException,
|
long limitSize) {
|
||||||
IllegalArgumentException {
|
|
||||||
this.limitSize = limitSize;
|
this.limitSize = limitSize;
|
||||||
if (size > this.limitSize) {
|
if (size > this.limitSize) {
|
||||||
fileUpload = new DiskFileUpload(name, filename, contentType,
|
fileUpload = new DiskFileUpload(name, filename, contentType,
|
||||||
@ -57,7 +56,7 @@ public class MixedFileUpload implements FileUpload {
|
|||||||
.getContentType(), fileUpload
|
.getContentType(), fileUpload
|
||||||
.getContentTransferEncoding(), fileUpload.getCharset(),
|
.getContentTransferEncoding(), fileUpload.getCharset(),
|
||||||
definedSize);
|
definedSize);
|
||||||
if (((MemoryFileUpload) fileUpload).getChannelBuffer() != null){
|
if (((MemoryFileUpload) fileUpload).getChannelBuffer() != null) {
|
||||||
diskFileUpload.addContent(((MemoryFileUpload) fileUpload)
|
diskFileUpload.addContent(((MemoryFileUpload) fileUpload)
|
||||||
.getChannelBuffer(), last);
|
.getChannelBuffer(), last);
|
||||||
}
|
}
|
@ -32,10 +32,25 @@ import io.netty.util.CharsetUtil;
|
|||||||
* <pre>
|
* <pre>
|
||||||
* {@link QueryStringDecoder} decoder = new {@link QueryStringDecoder}("/hello?recipient=world&x=1;y=2");
|
* {@link QueryStringDecoder} decoder = new {@link QueryStringDecoder}("/hello?recipient=world&x=1;y=2");
|
||||||
* assert decoder.getPath().equals("/hello");
|
* assert decoder.getPath().equals("/hello");
|
||||||
* assert decoder.getParameters().get("recipient").equals("world");
|
* assert decoder.getParameters().get("recipient").get(0).equals("world");
|
||||||
* assert decoder.getParameters().get("x").equals("1");
|
* assert decoder.getParameters().get("x").get(0).equals("1");
|
||||||
* assert decoder.getParameters().get("y").equals("2");
|
* assert decoder.getParameters().get("y").get(0).equals("2");
|
||||||
* </pre>
|
* </pre>
|
||||||
|
*
|
||||||
|
* This decoder can also decode the content of an HTTP POST request whose
|
||||||
|
* content type is <tt>application/x-www-form-urlencoded</tt>:
|
||||||
|
* <pre>
|
||||||
|
* {@link QueryStringDecoder} decoder = new {@link QueryStringDecoder}("recipient=world&x=1;y=2", false);
|
||||||
|
* ...
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* <h3>HashDOS vulnerability fix</h3>
|
||||||
|
*
|
||||||
|
* As a workaround to the <a href="http://events.ccc.de/congress/2011/Fahrplan/attachments/2007_28C3_Effective_DoS_on_web_application_platforms.pdf">HashDOS</a>
|
||||||
|
* vulnerability, the decoder limits the maximum number of decoded key-value
|
||||||
|
* parameter pairs, up to {@literal 1024} by default, and you can configure it
|
||||||
|
* when you construct the decoder by passing an additional integer parameter.
|
||||||
|
*
|
||||||
* @see QueryStringEncoder
|
* @see QueryStringEncoder
|
||||||
*
|
*
|
||||||
* @apiviz.stereotype utility
|
* @apiviz.stereotype utility
|
||||||
@ -43,10 +58,15 @@ import io.netty.util.CharsetUtil;
|
|||||||
*/
|
*/
|
||||||
public class QueryStringDecoder {
|
public class QueryStringDecoder {
|
||||||
|
|
||||||
|
private static final int DEFAULT_MAX_PARAMS = 1024;
|
||||||
|
|
||||||
private final Charset charset;
|
private final Charset charset;
|
||||||
private final String uri;
|
private final String uri;
|
||||||
|
private final boolean hasPath;
|
||||||
|
private final int maxParams;
|
||||||
private String path;
|
private String path;
|
||||||
private Map<String, List<String>> params;
|
private Map<String, List<String>> params;
|
||||||
|
private int nParams;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new decoder that decodes the specified URI. The decoder will
|
* Creates a new decoder that decodes the specified URI. The decoder will
|
||||||
@ -56,21 +76,51 @@ public class QueryStringDecoder {
|
|||||||
this(uri, HttpCodecUtil.DEFAULT_CHARSET);
|
this(uri, HttpCodecUtil.DEFAULT_CHARSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new decoder that decodes the specified URI encoded in the
|
||||||
|
* specified charset.
|
||||||
|
*/
|
||||||
|
public QueryStringDecoder(String uri, boolean hasPath) {
|
||||||
|
this(uri, HttpCodecUtil.DEFAULT_CHARSET, hasPath);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new decoder that decodes the specified URI encoded in the
|
* Creates a new decoder that decodes the specified URI encoded in the
|
||||||
* specified charset.
|
* specified charset.
|
||||||
*/
|
*/
|
||||||
public QueryStringDecoder(String uri, Charset charset) {
|
public QueryStringDecoder(String uri, Charset charset) {
|
||||||
|
this(uri, charset, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new decoder that decodes the specified URI encoded in the
|
||||||
|
* specified charset.
|
||||||
|
*/
|
||||||
|
public QueryStringDecoder(String uri, Charset charset, boolean hasPath) {
|
||||||
|
this(uri, charset, hasPath, DEFAULT_MAX_PARAMS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new decoder that decodes the specified URI encoded in the
|
||||||
|
* specified charset.
|
||||||
|
*/
|
||||||
|
public QueryStringDecoder(String uri, Charset charset, boolean hasPath, int maxParams) {
|
||||||
if (uri == null) {
|
if (uri == null) {
|
||||||
throw new NullPointerException("uri");
|
throw new NullPointerException("uri");
|
||||||
}
|
}
|
||||||
if (charset == null) {
|
if (charset == null) {
|
||||||
throw new NullPointerException("charset");
|
throw new NullPointerException("charset");
|
||||||
}
|
}
|
||||||
|
if (maxParams <= 0) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"maxParams: " + maxParams + " (expected: a positive integer)");
|
||||||
|
}
|
||||||
|
|
||||||
// http://en.wikipedia.org/wiki/Query_string
|
// http://en.wikipedia.org/wiki/Query_string
|
||||||
this.uri = uri.replace(';', '&');
|
this.uri = uri.replace(';', '&');
|
||||||
this.charset = charset;
|
this.charset = charset;
|
||||||
|
this.maxParams = maxParams;
|
||||||
|
this.hasPath = hasPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -85,17 +135,31 @@ public class QueryStringDecoder {
|
|||||||
* Creates a new decoder that decodes the specified URI encoded in the
|
* Creates a new decoder that decodes the specified URI encoded in the
|
||||||
* specified charset.
|
* specified charset.
|
||||||
*/
|
*/
|
||||||
public QueryStringDecoder(URI uri, Charset charset){
|
public QueryStringDecoder(URI uri, Charset charset) {
|
||||||
|
this(uri, charset, DEFAULT_MAX_PARAMS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new decoder that decodes the specified URI encoded in the
|
||||||
|
* specified charset.
|
||||||
|
*/
|
||||||
|
public QueryStringDecoder(URI uri, Charset charset, int maxParams) {
|
||||||
if (uri == null) {
|
if (uri == null) {
|
||||||
throw new NullPointerException("uri");
|
throw new NullPointerException("uri");
|
||||||
}
|
}
|
||||||
if (charset == null) {
|
if (charset == null) {
|
||||||
throw new NullPointerException("charset");
|
throw new NullPointerException("charset");
|
||||||
}
|
}
|
||||||
|
if (maxParams <= 0) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"maxParams: " + maxParams + " (expected: a positive integer)");
|
||||||
|
}
|
||||||
|
|
||||||
// http://en.wikipedia.org/wiki/Query_string
|
// http://en.wikipedia.org/wiki/Query_string
|
||||||
this.uri = uri.toASCIIString().replace(';', '&');
|
this.uri = uri.toASCIIString().replace(';', '&');
|
||||||
this.charset = charset;
|
this.charset = charset;
|
||||||
|
this.maxParams = maxParams;
|
||||||
|
hasPath = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -103,11 +167,14 @@ public class QueryStringDecoder {
|
|||||||
*/
|
*/
|
||||||
public String getPath() {
|
public String getPath() {
|
||||||
if (path == null) {
|
if (path == null) {
|
||||||
|
if (!hasPath) {
|
||||||
|
return path = "";
|
||||||
|
}
|
||||||
|
|
||||||
int pathEndPos = uri.indexOf('?');
|
int pathEndPos = uri.indexOf('?');
|
||||||
if (pathEndPos < 0) {
|
if (pathEndPos < 0) {
|
||||||
path = uri;
|
path = uri;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return path = uri.substring(0, pathEndPos);
|
return path = uri.substring(0, pathEndPos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,17 +186,25 @@ public class QueryStringDecoder {
|
|||||||
*/
|
*/
|
||||||
public Map<String, List<String>> getParameters() {
|
public Map<String, List<String>> getParameters() {
|
||||||
if (params == null) {
|
if (params == null) {
|
||||||
|
if (hasPath) {
|
||||||
int pathLength = getPath().length();
|
int pathLength = getPath().length();
|
||||||
if (uri.length() == pathLength) {
|
if (uri.length() == pathLength) {
|
||||||
return Collections.emptyMap();
|
return Collections.emptyMap();
|
||||||
}
|
}
|
||||||
params = decodeParams(uri.substring(pathLength + 1));
|
decodeParams(uri.substring(pathLength + 1));
|
||||||
|
} else {
|
||||||
|
if (uri.isEmpty()) {
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
decodeParams(uri);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, List<String>> decodeParams(String s) {
|
private void decodeParams(String s) {
|
||||||
Map<String, List<String>> params = new LinkedHashMap<String, List<String>>();
|
Map<String, List<String>> params = this.params = new LinkedHashMap<String, List<String>>();
|
||||||
|
nParams = 0;
|
||||||
String name = null;
|
String name = null;
|
||||||
int pos = 0; // Beginning of the unprocessed region
|
int pos = 0; // Beginning of the unprocessed region
|
||||||
int i; // End of the unprocessed region
|
int i; // End of the unprocessed region
|
||||||
@ -146,9 +221,13 @@ public class QueryStringDecoder {
|
|||||||
// We haven't seen an `=' so far but moved forward.
|
// We haven't seen an `=' so far but moved forward.
|
||||||
// Must be a param of the form '&a&' so add it with
|
// Must be a param of the form '&a&' so add it with
|
||||||
// an empty value.
|
// an empty value.
|
||||||
addParam(params, decodeComponent(s.substring(pos, i), charset), "");
|
if (!addParam(params, decodeComponent(s.substring(pos, i), charset), "")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
} else if (name != null) {
|
} else if (name != null) {
|
||||||
addParam(params, name, decodeComponent(s.substring(pos, i), charset));
|
if (!addParam(params, name, decodeComponent(s.substring(pos, i), charset))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
name = null;
|
name = null;
|
||||||
}
|
}
|
||||||
pos = i + 1;
|
pos = i + 1;
|
||||||
@ -157,15 +236,34 @@ public class QueryStringDecoder {
|
|||||||
|
|
||||||
if (pos != i) { // Are there characters we haven't dealt with?
|
if (pos != i) { // Are there characters we haven't dealt with?
|
||||||
if (name == null) { // Yes and we haven't seen any `='.
|
if (name == null) { // Yes and we haven't seen any `='.
|
||||||
addParam(params, decodeComponent(s.substring(pos, i), charset), "");
|
if (!addParam(params, decodeComponent(s.substring(pos, i), charset), "")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
} else { // Yes and this must be the last value.
|
} else { // Yes and this must be the last value.
|
||||||
addParam(params, name, decodeComponent(s.substring(pos, i), charset));
|
if (!addParam(params, name, decodeComponent(s.substring(pos, i), charset))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (name != null) { // Have we seen a name without value?
|
} else if (name != null) { // Have we seen a name without value?
|
||||||
addParam(params, name, "");
|
if (!addParam(params, name, "")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return params;
|
private boolean addParam(Map<String, List<String>> params, String name, String value) {
|
||||||
|
if (nParams >= maxParams) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> values = params.get(name);
|
||||||
|
if (values == null) {
|
||||||
|
values = new ArrayList<String>(1); // Often there's only 1 value.
|
||||||
|
params.put(name, values);
|
||||||
|
}
|
||||||
|
values.add(value);
|
||||||
|
nParams ++;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -284,13 +382,4 @@ public class QueryStringDecoder {
|
|||||||
return Character.MAX_VALUE;
|
return Character.MAX_VALUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void addParam(Map<String, List<String>> params, String name, String value) {
|
|
||||||
List<String> values = params.get(name);
|
|
||||||
if (values == null) {
|
|
||||||
values = new ArrayList<String>(1); // Often there's only 1 value.
|
|
||||||
params.put(name, values);
|
|
||||||
}
|
|
||||||
values.add(value);
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -29,7 +29,7 @@ import java.util.List;
|
|||||||
* This encoder is for one time use only. Create a new instance for each URI.
|
* This encoder is for one time use only. Create a new instance for each URI.
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* {@link QueryStringEncoder} encoder = new {@link QueryStringDecoder}("/hello");
|
* {@link QueryStringEncoder} encoder = new {@link QueryStringEncoder}("/hello");
|
||||||
* encoder.addParam("recipient", "world");
|
* encoder.addParam("recipient", "world");
|
||||||
* assert encoder.toString().equals("/hello?recipient=world");
|
* assert encoder.toString().equals("/hello?recipient=world");
|
||||||
* </pre>
|
* </pre>
|
||||||
@ -106,7 +106,7 @@ public class QueryStringEncoder {
|
|||||||
sb.append(encodeComponent(param.name, charset));
|
sb.append(encodeComponent(param.name, charset));
|
||||||
sb.append("=");
|
sb.append("=");
|
||||||
sb.append(encodeComponent(param.value, charset));
|
sb.append(encodeComponent(param.value, charset));
|
||||||
if(i != params.size() - 1) {
|
if (i != params.size() - 1) {
|
||||||
sb.append("&");
|
sb.append("&");
|
||||||
}
|
}
|
||||||
}
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user