Hello
I'd like to send HTTP 412 (precondition faild) status to client. It
works when I test it from curl (even if repeated a hundred times).
When I test is from a junit test using the restlet client, the test fails:
-------
java.lang.AssertionError: expected:<Precondition Failed (412) - The
precondition given in one or more of the request header fields
evaluated to false when it was tested on the server> but
was:<Communication Error (1001) - Software caused connection abort:
socket write error>
at org.junit.Assert.fail(Assert.java:74)
at org.junit.Assert.failNotEquals(Assert.java:448)
at org.junit.Assert.assertEquals(Assert.java:102)
at org.junit.Assert.assertEquals(Assert.java:117)
at
hu.zakk.atom.server.TestResourceTest.testPut(TestResourceTest.java:30)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)
at
org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
at
org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
at
org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:88)
at
org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
at
org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
at
org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
at
org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
at
org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
-----
According to the server log, everything is ok, 412 status sent:
2008.08.19. 17:43:44 com.noelios.restlet.LogFilter afterHandle
INFO: 2008-08-19 17:43:44 127.0.0.1 - 127.0.0.1
8182 PUT /test/ - 412 391 - 0
http://localhost:8182 Noelios-Restlet-Engine/1.1.snapshot -
When I use smaller file to test, it seems to work, but occasionally it
fails. If I increase the of the file above 64k, it seems to fail every
time.
See the java classes below. I use the restlet snapshot from maven repo
with jetty.
Probably a client issue?
Thanks
Zsolt
--------------------------------
The resource class:
package hu.zakk.test;
import java.util.List;
import java.util.logging.Logger;
import org.restlet.Context;
import org.restlet.data.MediaType;
import org.restlet.data.Request;
import org.restlet.data.Response;
import org.restlet.data.Status;
import org.restlet.data.Tag;
import org.restlet.resource.Representation;
import org.restlet.resource.Resource;
import org.restlet.resource.ResourceException;
import org.restlet.resource.Variant;
public class TestResource extends Resource {
private Logger log;
public TestResource(Context context, Request request, Response response) {
super(context, request, response);
getVariants().add(new Variant(MediaType.ALL));
log = getLogger();
}
@Override
public void storeRepresentation(Representation entity)
throws ResourceException {
String tag = "fake";
List<Tag> match = getRequest().getConditions().getMatch();
Tag etag = match.isEmpty() ? null : match.get(0);
if (etag == null || !etag.toString().equals(tag)) {
log.info("precondition failed");
getResponse().setStatus(Status.CLIENT_ERROR_PRECONDITION_FAILED);
return;
}
log.info("NEVER HIT THIS");
}
@Override
public boolean allowPut() {
return true;
}
}
-----------------------
The test:
package hu.zakk.test;
import static org.junit.Assert.assertEquals;
import java.io.ByteArrayInputStream;
import org.junit.Test;
import org.restlet.Client;
import org.restlet.data.MediaType;
import org.restlet.data.Protocol;
import org.restlet.data.Response;
import org.restlet.data.Status;
import org.restlet.resource.InputRepresentation;
public class TestResourceTest {
@Test
public void testPut() {
// play with size
int size = (int) Math.pow(2, 15) + 1;
byte[] buf = new byte[size];
for (int i = 0; i < size; i++) {
buf[i] = 1;
}
ByteArrayInputStream bain = new ByteArrayInputStream(buf);
Client client = new Client(Protocol.HTTP);
Response putResponse = client.put("http://localhost:8182/test/",
new InputRepresentation(bain, MediaType.TEXT_PLAIN));
assertEquals(Status.CLIENT_ERROR_PRECONDITION_FAILED,
putResponse.getStatus());
}
}