482855 - Content-Length omitted for POST requests with empty body

An ineligant fix. Will improve in 9.3.x/9.4.x without HTTP 0.9 support.
This commit is contained in:
Greg Wilkins 2015-11-25 14:15:14 +11:00
parent cd152f515e
commit aa85d85510
2 changed files with 54 additions and 9 deletions

View File

@ -23,6 +23,8 @@ import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.jetty.http.HttpTokens.EndOfContent;
import org.eclipse.jetty.util.BufferUtil;
@ -70,8 +72,8 @@ public class HttpGenerator
private final int _send;
private final static int SEND_SERVER = 0x01;
private final static int SEND_XPOWEREDBY = 0x02;
private final static Set<String> __assumedContentMethods = new HashSet<>(Arrays.asList(new String[]{HttpMethod.POST.asString(),HttpMethod.PUT.asString()}));
/* ------------------------------------------------------------------------------- */
public static void setJettyVersion(String serverVersion)
{
@ -745,12 +747,17 @@ public class HttpGenerator
long content_length = _contentPrepared+BufferUtil.length(content);
// Do we need to tell the headers about it
if ((response!=null || content_length>0 || content_type ) && !_noContent)
if (content_length>0)
{
header.put(HttpHeader.CONTENT_LENGTH.getBytesColonSpace());
BufferUtil.putDecLong(header, content_length);
header.put(HttpTokens.CRLF);
}
else if (!_noContent)
{
if (content_type || response!=null || (request!=null && __assumedContentMethods.contains(request.getMethod())))
header.put(CONTENT_LENGTH_0);
}
}
else
{
@ -767,19 +774,21 @@ public class HttpGenerator
case CONTENT_LENGTH:
long content_length = _info.getContentLength();
if ((response!=null || content_length>0 || content_type ) && !_noContent)
if (content_length>0)
{
// known length but not actually set.
header.put(HttpHeader.CONTENT_LENGTH.getBytesColonSpace());
BufferUtil.putDecLong(header, content_length);
header.put(HttpTokens.CRLF);
}
else if (!_noContent)
{
if (content_type || response!=null || (request!=null && __assumedContentMethods.contains(request.getMethod())))
header.put(CONTENT_LENGTH_0);
}
break;
case NO_CONTENT:
if (response!=null && status >= 200 && status != 204 && status != 304)
header.put(CONTENT_LENGTH_0);
break;
throw new IllegalStateException();
case EOF_CONTENT:
_persistent = request!=null;

View File

@ -43,7 +43,7 @@ public class HttpGeneratorClientTest
}
@Test
public void testRequestNoContent() throws Exception
public void testGETRequestNoContent() throws Exception
{
ByteBuffer header=BufferUtil.allocate(2048);
HttpGenerator gen = new HttpGenerator();
@ -77,7 +77,43 @@ public class HttpGeneratorClientTest
Assert.assertEquals(0, gen.getContentPrepared());
Assert.assertThat(out, Matchers.containsString("GET /index.html HTTP/1.1"));
Assert.assertThat(out, Matchers.not(Matchers.containsString("Content-Length")));
}
@Test
public void testPOSTRequestNoContent() throws Exception
{
ByteBuffer header=BufferUtil.allocate(2048);
HttpGenerator gen = new HttpGenerator();
HttpGenerator.Result
result=gen.generateRequest(null,null,null,null, true);
Assert.assertEquals(HttpGenerator.Result.NEED_INFO, result);
Assert.assertEquals(HttpGenerator.State.START, gen.getState());
Info info = new Info("POST","/index.html");
info.getHttpFields().add("Host","something");
info.getHttpFields().add("User-Agent","test");
Assert.assertTrue(!gen.isChunking());
result=gen.generateRequest(info,null,null,null, true);
Assert.assertEquals(HttpGenerator.Result.NEED_HEADER, result);
Assert.assertEquals(HttpGenerator.State.START, gen.getState());
result=gen.generateRequest(info,header,null,null, true);
Assert.assertEquals(HttpGenerator.Result.FLUSH, result);
Assert.assertEquals(HttpGenerator.State.COMPLETING, gen.getState());
Assert.assertTrue(!gen.isChunking());
String out = BufferUtil.toString(header);
BufferUtil.clear(header);
result=gen.generateResponse(null,null,null,null, false);
Assert.assertEquals(HttpGenerator.Result.DONE, result);
Assert.assertEquals(HttpGenerator.State.END, gen.getState());
Assert.assertTrue(!gen.isChunking());
Assert.assertEquals(0, gen.getContentPrepared());
Assert.assertThat(out, Matchers.containsString("POST /index.html HTTP/1.1"));
Assert.assertThat(out, Matchers.containsString("Content-Length: 0"));
}
@Test