Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aiohttp.client_exceptions.ClientResponseError: 400, message='invalid character in header' #5443

Closed
Evanyifan opened this issue Jan 27, 2021 · 7 comments
Labels
invalid This doesn't seem right wontfix

Comments

@Evanyifan
Copy link

Evanyifan commented Jan 27, 2021

🐞 Describe the bug

When I want to use the put method to access a public network service, because the target operating system is windows, there is a problem of garbled code in the reason field of the response packet, which causes the above error. Stable reproduced in the aiohttp-3.7.3 version。

image
💡 To Reproduce

import aiohttp
import asyncio


async def fetch(session, url):
    async with session.put(url) as response:
        return await response.text()


async def main(url):
    async with aiohttp.ClientSession() as session:
        html = await fetch(session, url)
        print(html)


loop = asyncio.get_event_loop()

# 生成多个请求方法
url ="http://118.25.92.249:8161/fileserver/840f12/425ba"
tasks = [main(url)]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()

💡 Expected behavior

📋 Logs/tracebacks

📋 Your version of the Python

$ python --version
3.8
...

📋 Your version of the aiohttp/yarl/multidict distributions

$ python -m pip show aiohttp
3.7.3
...
$ python -m pip show multidict
...
$ python -m pip show yarl
...

📋 Additional context

@andrey-tikhov
Copy link

andrey-tikhov commented Feb 26, 2021

Same issue here.

aiohttp==3.7.3
Python 3.6.4

$ python -m pip show multidict
Name: multidict
Version: 5.0.2
Summary: multidict implementation
Home-page: https://github.com/aio-libs/multidict
Author: Andrew Svetlov
Author-email: [email protected]
License: Apache 2
Location: /Users/andrey/Documents/am_foundations_service_bot/env/lib/python3.6/site-packages
Requires: 
Required-by: yarl, aiohttp
$ python -m pip show yarl
Name: yarl
Version: 1.6.3
Summary: Yet another URL library
Home-page: https://github.com/aio-libs/yarl/
Author: Andrew Svetlov
Author-email: [email protected]
License: Apache 2
Location: /Users/andrey/Documents/am_foundations_service_bot/env/lib/python3.6/site-packages
Requires: multidict, idna, typing-extensions
Required-by: aiohttp

Using requests for the same web-address works successfully.

@webknjaz webknjaz removed the bug label Mar 6, 2021
@webknjaz
Copy link
Member

webknjaz commented Mar 6, 2021

@Evanyifan your server at 118.25.92.249:8161 produces a corrupted HTTP response. And since it's invalid, it's impossible to parse it as an HTTP message. That is why an appropriate exception is raised:

$ telnet 118.25.92.249 8161                 
Trying 118.25.92.249...
Connected to 118.25.92.249.
Escape character is '^]'.
PUT /fileserver/840f12/425ba HTTP/1.1
Host: 118.25.92.249:8161
User-Agent: curl/7.73.0
Accept: */*

0)TP/1.1 500 E:\apache-activemq-5.3.0\webapps\fileserver\840f12\425ba (~
Content-Type: text/html; charset=iso-8859-1
Content-Length: 3466
Server: Jetty(6.1.9)

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
<title>Error 500 E:\apache-activemq-5.3.0\webapps\fileserver\840f12\425ba (???????????)</title>
</head>
<body><h2>HTTP ERROR: 500</h2><pre>E:\apache-activemq-5.3.0\webapps\fileserver\840f12\425ba (???????????)</pre>
<p>RequestURI=/fileserver/840f12/425ba</p><h3>Caused by:</h3><pre>java.io.FileNotFoundException: E:\apache-activemq-5.3.0\webapps\fileserver\840f12\425ba (???????????)
	at java.io.FileOutputStream.open0(Native Method)
	at java.io.FileOutputStream.open(FileOutputStream.java:270)
	at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
	at java.io.FileOutputStream.<init>(FileOutputStream.java:162)
	at org.apache.activemq.util.RestFilter.doPut(RestFilter.java:176)
	at org.apache.activemq.util.RestFilter.doFilter(RestFilter.java:89)
	at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
	at org.apache.activemq.util.FilenameGuardFilter.doFilter(FilenameGuardFilter.java:46)
	at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
	at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)
	at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
	at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
	at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:726)
	at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
	at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
	at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
	at org.mortbay.jetty.Server.handle(Server.java:324)
	at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
	at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:828)
	at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:514)
	at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:205)
	at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
	at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
	at org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java:450)
</pre>
<p><i><small><a href="http://jetty.mortbay.org/">Powered by Jetty://</a></small></i></p><br/>                                                
<br/>                                                
<br/>                                                
<br/>                                                
<br/>                                                
<br/>                                                
<br/>                                                
<br/>                                                
<br/>                                                
<br/>                                                
<br/>                                                
<br/>                                                
<br/>                                                
<br/>                                                
<br/>                                                
<br/>                                                
<br/>                                                
<br/>                                                
<br/>                                                
<br/>                                                

</body>
</html>

Specifically,

0)TP/1.1 500 E:\apache-activemq-5.3.0\webapps\fileserver\840f12\425ba (~

looks like a leak from a corrupted in-memory object or something like that.

It's not a problem in aiohttp: the solution is to make your server return an actual valid HTTP response that does not have any garbage bytes in the status-line. If you need to just ignore such cases in your code, use try/except.

@webknjaz webknjaz closed this as completed Mar 6, 2021
@webknjaz webknjaz added invalid This doesn't seem right wontfix labels Mar 6, 2021
@andrey-tikhov
Copy link

andrey-tikhov commented Mar 7, 2021 via email

@webknjaz
Copy link
Member

webknjaz commented Mar 7, 2021

It's not a real response status but a synthetic one. The server is broken and the exception is a natural way of communicating this. It would be weird if the client pretended that everything is fine. It would give a false impression that the HTTP request is constructed incorrectly which is simply not true. The current design is the best way of communicating this situation unambiguously.
It sounds like requests does the wrong thing or maybe you misunderstood what it actually does. FWIW there's not enough info to make such a judgment because you didn't provide any proof.

@andrey-tikhov
Copy link

andrey-tikhov commented Mar 7, 2021 via email

@Dreamsorcerer
Copy link
Member

Because another framework will ignore and workaround the error doesn't mean that it should (or would) work in all other platforms.

For example, if I put invalid HTML on a web page, most browsers will be able to ignore and work around the error. But, different browsers may do different things and render completely different content, and other tools may error completely, because there is no defined behaviour for invalid HTML.

The same thing applies here, maybe other frameworks make a best guess at the correct behaviour when encountering this error, and it works well enough for you. But, aiohttp simply throws an exception as the response is not valid, rather than taking a best guess approach (which may or may not produce the desired outcome).

@devblack
Copy link

AIOHTTP_NO_EXTENSIONS=1 python3 my_script.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
invalid This doesn't seem right wontfix
Projects
None yet
Development

No branches or pull requests

5 participants