Ошибка с HTTP-соединением: закрыть заголовок - PullRequest
4 голосов
/ 20 декабря 2010

У меня странная проблема с небольшим сервисом рестлетов, который я строю в качестве упражнения.Предполагается, что приложение ответит некоторым HTTP (, в частности TwiML , как он предназначен для Twilio) по HTTP POST, и оно хорошо работает для автономных запросов.Однако по запросу Twilio ответ никогда не завершается и время ожидания истекает.После сравнения трафика, поступающего из Twilio, с тем, который работает (используя поддельную HTML-форму), я изолировал проблему с заголовком «Connection: close» и могу воспроизвести его, используя только командную строку curl.Вот запрос, который работает:

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

, а вот тот, который просто зависает:

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

Если я убью сервер, то curl говорит "(52) Пустой ответ от сервера».Вот код, который я использую в 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;
}

Что-то явно не так с тем, что я здесь делаю?Я использую restlet-2.0, но также пробовал с 2.1m1 с тем же результатом.Я был бы очень признателен за быстрый ответ, так как я в срок, чтобы закончить упражнение.

Ответы [ 2 ]

4 голосов
/ 14 января 2011

не уверен, что вы нашли решение для вашей ошибки, но я столкнулся с той же проблемой в Restlet V 2.0.4.

При запуске рестлета с использованием сервера по умолчанию.Здесь сервер предполагает, что поток ответов не доступен для записи и, следовательно, не будет отвечать сущностью.

В качестве быстрого исправления я обнаружил

  org.restlet.engine.http.connector.Connection

и изменил метод canWrite ()на

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

от оригинала

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

Не уверен, что это хорошее исправление, но после перекомпиляции модуля перезапуска теперь он, кажется, работает нормально.Похоже, проблема заключается в том, что при указании заголовка HTTP «Соединение: закрыть» поток по умолчанию находится в закрытом состоянии.

Надеюсь, это поможет

Джои

См. Здесьза проблему на форуме рестлета

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

0 голосов
/ 20 декабря 2010

Не уверен, что это так, но вот что нужно учитывать:

Рестлет очень аккуратно и аккуратно реализует архитектурный стиль REST. Один из ключевых принципов REST, который он реализует, - это унифицированный интерфейс. В веб-службе на основе HTTP универсальный интерфейс использует операции HTTP GET, PUT, POST, DELETE (и другие) так, как они изначально предназначались. Таким образом, чтобы создать ресурс на сервере, когда вы назначаете его имя ресурса, вы используете PUT. Чтобы обновить этот ресурс, вы снова используете PUT. Чтобы прочитать это, вы используете GET. Чтобы удалить его, используйте DELETE. POST зарезервирован для создания ресурса, когда сервер назначает имя ресурса.

Так что это может быть как-то из-за несоответствия в ожиданиях. У POST обычно есть представление, которое вы отправляете на сервер, но у этого POST нет. Вы читаете полный запрос и правильно закрываете соединение на стороне сервера?

...