开发者

Error with HTTP Connection: close header

开发者 https://www.devze.com 2023-01-31 15:02 出处:网络
I am having a weird problem with a small restlet service that I am building as an exercise. The application is supposed to respond with some XML (specifically TwiML, as it is meant for Twilio) on an H

I am having a weird problem with a small restlet service that I am building as an exercise. The application is supposed to respond with some XML (specifically TwiML, as it is meant for Twilio) on an HTTP POST, and it worked well for standalone requests. However, when requested by Twilio, the response never completes and it times out. After comparing the traffic coming from Twilio with the one that is working (using a fake HTML form), I isolated the issue to the "Connection: close" header and can reproduce it using nothing but curl command-line. Here is the request that works:

curl -i -H 'Connection: keep-alive' -X POST -d "name=value" http://localhost:8020/hello

and here is the one that just hangs:

curl -i -H 'Connection: close' -X POST -d "name=value" http://localhost:8020/hello

If I kill the server then curl says "(52) Empty reply from server". Here is the code that I am using in the ServerResource:

@Post
public Representation hello(Representation repr)
{
    Representation result = new StringRepresentation(("<Response>\n"+
            "   <Say>Hello. This is a test.</Say>\n"+
            "</Response>"), MediaType.APPLICATION_XML);
    return result;
}

Is something obviously wrong with what I am doing here? I am using restlet-2.0, but also tried with 2.1m1 with the same result. I would really appreciate a quick response as I am on a d开发者_开发知识库eadline to finish the exercise.


not sure if you found a solution for your error, but I came across the same problem in Restlet V 2.0.4.

When running the restlet using the default server. Here the server does assume that the response stream is not writable and thus will not respond with an entity.

As a quick fix I located

  org.restlet.engine.http.connector.Connection

and changed the the canWrite() method to

public boolean canWrite() { 
    return (
             (getState() == ConnectionState.OPEN) 
                     || (getState() == ConnectionState.CLOSING)) 
            && !isOutboundBusy() 
            && (getOutboundMessages().size() > 0); 
} 

from the original

public boolean canWrite() { 
    return (getState() == ConnectionState.OPEN) && !isOutboundBusy() 
            && (getOutboundMessages().size() > 0); 
}

Not sure if that is a good fix, but after recompiling the restlet module it now seems to work fine. It seems to be the issue that when specifying the HTTP Header 'Connection: close' the stream is by default in closing state.

Hope that helps

Joey

See here for the problem on the restlet forum

http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2698048


Not sure this is it, but here's something to consider:

Restlet very carefully and accurately implements the REST architectural style. One of the key REST principles it implements is the uniform interface. In an HTTP-based web service, the uniform interface leverages the HTTP GET, PUT, POST, DELETE (and other) operations the way they were originally intended to. So to create a resource on the server when you assign its resource name, you use PUT. To update that resource, you again use PUT. To read it, you use GET. To delete it, use DELETE. POST is reserved for creating a resource when the server assigns the resource name.

So this may somehow be due to a mismatch in expectations. A POST generally has a representation you're sending to the server, but this POST does not. Are you reading in the full request and closing the connection properly on the server-side?

0

精彩评论

暂无评论...
验证码 换一张
取 消