java.lang.IllegalArgumentException: W nazwie metody znaleziono nieprawidłowy znak. Nazwy metod HTTP muszą być tokenami

161

Podczas wdrażania aplikacji w środowisku wieloserwerowym Apache Tomcat 8 pojawia się poniżej śladu stosu. Często otrzymuję ten błąd i wygląda na to, że blokuje wątek tomcat:

INFO [http-nio-80-exec-4461] org.apache.coyote.http11.AbstractHttp11Processor.process Error parsing HTTP request header
 Note: further occurrences of HTTP header parsing errors will be logged at DEBUG level.
 java.lang.IllegalArgumentException: Invalid character found in method name. HTTP method names must be tokens
 at org.apache.coyote.http11.AbstractNioInputBuffer.parseRequestLine(AbstractNioInputBuffer.java:233)
 at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1017)
 at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:684)
 at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1524)
 at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1480)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
 at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
 at java.lang.Thread.run(Unknown Source)

Czy ktoś może mi wskazać, jak rozwiązać problem lub zawęzić taki wyjątek? Nie otrzymuję żadnego odniesienia do żadnego z plików źródłowych mojej aplikacji. Próbowałem przeszukać go w Google, a wśród podanych linków próbujesz uzyskać dostęp do adresu URL http przez https, co wydaje się mało prawdopodobne. Nie pojawia się ten błąd, gdy aplikacja działa na jednej instancji Tomcat 8. Dostaję to tylko w środowisku wieloserwerowym.

Udostępniam również metatagi, które umieściłem na każdej stronie, jeśli pomoże to zidentyfikować przyczynę.

<%
    response.setHeader("Cache-Control", "no-cache");
    response.setHeader("Cache-Control", "no-store");
    response.setDateHeader("Expires", 0);
    response.setHeader("Pragma", "no-cache");
%>


<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0">
<meta name="viewport" content="width=device-width, initial-scale=1">

Na kilku stronach używam również tego, co w zasadzie jest takie samo jak powyżej:

<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Expires" content="-1" />
<meta http-equiv="Cache-Control" content="private" />
<meta http-equiv="Cache-Control" content="no-store" />
<meta http-equiv="Pragma" content="no-cache" />

Nawet jeśli ktoś pomoże mi wskazać kierunek mojej próby rozwiązania problemu, będzie to przydatne, ponieważ obecnie nie mam pojęcia, gdzie zajrzeć.

Z góry dziękuję.

user2016012
źródło

Odpowiedzi:

266

Ten wyjątek może wystąpić podczas próby wykonania żądania HTTPS od klienta w punkcie końcowym, który nie jest włączony w protokole HTTPS. Klient zaszyfruje dane żądania, gdy serwer oczekuje nieprzetworzonych danych.

Petar Tonev
źródło
1
Nie jestem pewien, czy rozumiem tę odpowiedź. Mam aplikację Spring Boot 1.5.1 i widziałem ten wyjątek w moim dzienniku. Moja aplikacja odpowiada tylko za SSL na porcie 8443 (przekierowanym z portu 443) i ma tylko jedno złącze dla SSL. Czy chcesz powiedzieć, że ktoś mógłby spróbować http: zamiast https: na porcie 443?
Jim Archer,
5
Takie wyjątki mają miejsce, gdy istnieje niezgodność między tym, czego oczekuje serwer, a tym, co otrzymuje. To, co powiedziałeś, jest jednym z możliwych scenariuszy. Może na twoim serwerze jest punkt końcowy, który nie działa na https, ale ktoś próbuje uzyskać do niego dostęp w ten sposób?
Petar Tonev,
1
Cześć Peter ... Problem polegał na tym, że ktoś utworzył regułę tabel adresów IP, aby przekierować port 80 na port 8443, więc każdy, kto trafił na witrynę przy użyciu protokołu http na porcie 80, powodował ten błąd. Dodaliśmy złącze Tomcat, aby przekierować port 8080 do 8443 i skonfigurowaliśmy regułę tabel IP, aby przekierować port 80 do portu 8080, a problem zniknął. Dziękuję za twoją odpowiedź!
Jim Archer
1
@PeterTonev: Masz jakiś pomysł, jak (przekierować https na http || wyłączyć https || przechwycić błąd, aby przynajmniej pokazać sensowny komunikat o błędzie)?
crusy
1
@crusy Coś, co może ci tutaj pomóc w obsłudze wyjątków, to link
Petar Tonev
56

Otrzymałem ten sam wyjątek, gdy przeprowadziłem lokalne testy. Problem polegał na schemacie adresu URL w mojej prośbie.

Zmiana https:// to http:// in your client url.

Prawdopodobnie to pomaga.

JustCode
źródło
2
Jasne, że działa, ale pamiętaj, że komunikacja przez HTTP nie jest bezpieczna.
Paramvir Singh Karwal,
23

Dzwonisz do lokalnego serwera z http : // localhost: 8080 / foo / bar. Wywołaj to za pomocą https : // localhost: 8080 / foo / bar. To rozwiązuje problem

Shivan Sawant
źródło
Prawdopodobnie nie będziesz mieć https: // na 8080. Zmień wywołanie na https: // localhost: 8443 / foo / bar - Oto przykładowy link - Rodrigo R. Coelho
Rodrigo R. Coelho
9

W przypadku, gdy ktoś używa swaggera:

Zmień Schemat na HTTPlub HTTPS, w zależności od potrzeb, przed wykonaniem polecenia.

Listonosz:

Zmień ścieżkę adresu URL na http://lub https://w adresie url

Cyber
źródło
8

Otrzymałem ten wyjątek niezwiązany z żadnymi problemami z TLS. W moim przypadku wartość nagłówka Content-Length nie odpowiadała długości treści.

mibollma
źródło
2
Nie mogę ci wystarczająco podziękować. Każde inne żądanie POST kończyło się niepowodzeniem z błędem 400 i byłem gotowy do wyrywania włosów. Okazało się, że niewysłanie content-lengthnagłówka rozwiązuje ten problem.
Alexander Woodblock
2
Dostawałem opóźnienie 30-90 sekund na żądania Postman do lokalnego programisty - okazuje się, że to był ten problem! Wyłączenie Content-Lengthnagłówka naprawiło opóźnienie.
Alok
1

Odpowiedź na to stare pytanie (dla innych, którzy mogą pomóc)

Prawidłowe skonfigurowanie httpd conf rozwiąże problem. Zainstaluj dowolny serwer httpd, jeśli go nie masz.

Wymieniam tutaj moją konfigurację.

[smilyface@box002 ~]$ cat /etc/httpd/conf/httpd.conf | grep shirts | grep -v "#"


        ProxyPass /shirts-service http://local.box002.com:16743/shirts-service
        ProxyPassReverse /shirts-service http://local.box002.com:16743/shirts-service
        ProxyPass /shirts http://local.box002.com:16443/shirts
        ProxyPassReverse /shirts http://local.box002.com:16443/shirts
        ...
        ...
        ...

edytuj plik jak powyżej, a następnie zrestartuj httpd jak poniżej

[smilyface@box002 ~]$ sudo service httpd restart


A następnie żądanie z httpsbędzie działać bez wyjątku.
Poproś również o httpprzekierowanie do https! Bez obaw.

uśmiechnięta twarz
źródło
1

Ten błąd został rozwiązany, wykonując 2 czynności w przeglądarce Chrome:

  1. Wciśnięty Ctrl + Shift + Delete i wyczyścił wszystkie dane przeglądania od początku.
  2. Przejdź do Chrome: Ustawienia -> Ustawienia zaawansowane -> Otwórz ustawienia proxy -> Właściwości internetowe, a następnie przejdź do okna Zawartość i kliknij przycisk Wyczyść stan SSL.

Ta strona zawiera również te informacje i inne opcje: https://www.thesslstore.com/blog/fix-err-ssl-protocol-error/

Ravi Shankar Kota
źródło
1

Wiem, że to stary wątek, ale jest szczególny przypadek, w którym może się to zdarzyć:

Jeśli używasz bramy AWS API połączonej z łączem VPC i jeśli Network Load Balancer ma włączony protokół proxy v2, wystąpi również 400 złych żądań.

Zajęło mi to całe popołudnie, żeby to rozgryźć, więc jeśli to może komuś pomóc, byłbym zadowolony :)

Daniel
źródło
0

Otrzymywałem ten sam wyjątek, gdy ładowała się strona,

NFO: Error parsing HTTP request header
 Note: further occurrences of HTTP header parsing errors will be logged at DEBUG level.
java.lang.IllegalArgumentException: Invalid character found in method name. HTTP method names must be tokens
    at org.apache.coyote.http11.InternalInputBuffer.parseRequestLine(InternalInputBuffer.java:139)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1028)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)

Odkryłem, że jeden z adresów URL mojej strony to https zamiast http, kiedy zmieniłem to samo, błąd zniknął.

Asif Iquebal Ajazi
źródło
0

Zwykle dzieje się tak, gdy używasz schematu identyfikatora URI, który nie jest obsługiwany przez serwer, na którym aplikacja jest wdrażana. Możesz więc albo chcieć sprawdzić, jakie schematy obsługują twój serwer i odpowiednio zmodyfikować żądanie URI, albo możesz chcieć dodać obsługę tego schematu na swoim serwerze. Zakres twojego wniosku powinien pomóc ci w podjęciu takiej decyzji.

Nowicjusz
źródło
0

Zdarzyło mi się to, gdy miałem ten sam port używany w tunelu ssh SOCKS do uruchamiania serwera proxy na porcie 8080, a mój serwer i mój serwer proxy przeglądarki Firefox były ustawione na ten port i wystąpił ten problem.

privatejava
źródło
0

W moim przypadku musiałem wyczyścić historię przeglądarki / pliki cookie, aby pozbyć się tego błędu.

rustylepord
źródło