HTTP/1.1 400 Bad Request. Bad number of command parts
<p>Im trying to execute the following code from Chapter 12 of the book "Python for Informatics". </p>

<pre><code>import socket
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysock.connect(('www.py4inf.com', 80))
mysock.send('GET http://www.py4inf.com/code/romeo.txt HTTP/1.0\n\n')
while True:
    data = mysock.recv(512)
    if ( len(data) &lt; 1 ) :
        break
    print data
mysock.close()
</code></pre>

<p>According to the book, the script should print the following:</p>

<blockquote>
  <p>HTTP/1.1 200 OK
  Date: Sun, 14 Mar 2010 23:52:41 GMT
  Server: Apache
  Last-Modified: Tue, 29 Dec 2009 01:31:22 GMT
  ETag: "143c1b33-a7-4b395bea"
  Accept-Ranges: bytes
  Content-Length: 167
  Connection: close
  Content-Type: text/plain
  But soft what light through yonder window breaks
  It is the east and Juliet is the sun
  Arise fair sun and kill the envious moon
  Who is already sick and pale with grief</p>
</blockquote>

<p>Unfortunately the variable data is filled with the following string: </p>

<blockquote>
  <p>'HTTP/1.1 400 Bad Request. Bad number of command parts ['GET', '<a href="http://www.py4inf.com/code/romeo.txt" rel="nofollow">http://www.py4inf.com/code/romeo.txt</a>', 'HTTP/1.0', 'X-WS-Ver:', '1.0']'</p>
</blockquote>

<p>I cannot find any good explanation for this error. I hope someone can help!</p>

<p>On your Python installation, machine, or your network, something is rewriting requests and injecting its own code. Prime suspects are</p>

<ul>
<li>Anything marketed as "Anti-Virus"</li>
<li>Anything marketed as "Network Security Solution"</li>
<li>Malware on your computer or router</li>
<li>A network-wide (transparent) proxy</li>
<li>A library in your Python program or installation</li>
<li>Your ISP or network administrator</li>
</ul>

<p>This service wants, in your case, to inject a totally useless header <code>X-WS-Ver</code>. However, this service's interpretation of HTTP is more strict than yours and that of the py4inf.com server; HTTP lines are supposed to end with <code>\r\n</code>, but you use <code>\n</code> only. This service modifies the data you sent to</p>

<pre><code>GET http://www.py4inf.com/code/romeo.txt HTTP/1.0\n\nX-WS-Ver: 1.0\r\n\r\n
</code></pre>

<p>or something similar. This is of course a very buggy behavior by this service. Since the new request is not valid HTTP anymore, py4inf.com will return an error message, correctly indicating that the request it received is malformed (<code>400 Bad request</code>).</p>

<p>To make your program work, you can take any of these options:</p>

<ul>
<li>If something on your local machine is the problem, disable the offending service (if it uselessly and incorrectly modifies connections, it's not likely to provide much, if any, security anyways), or use another machine</li>
<li>Get unrestricted network access, maybe with the help of a VPN provider</li>
<li>Send proper HTTP, i.e.</li>
</ul>



<pre><code>mysock.send('GET http://www.py4inf.com/code/romeo.txt HTTP/1.0\r\n\r\n')
#                                                             ^^  ^^
</code></pre>

<ul>
<li>Use an encrypted connection (with Python's <a href="https://docs.python.org/dev/library/ssl.html#ssl.wrap_socket" rel="nofollow">ssl</a> module), i.e. URLs under the <code>https://</code> scheme.</li>
</ul>

python sockets http web bad-request