Is there any way to initial the HTTP request by given request formatted text?

Viewed 72

I have a text as GET request format:


GET /40x.jpg HTTP/1.1\r\n\
Host: ns.pb.cachecn.net\r\n\
Connection: keep-alive\r\n\
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n\
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1636.2 Safari/537.36\r\n\
Accept-Encoding: gzip,deflate,sdch\r\n\
Accept-Language: zh-CN,zh;q=0.8\r\n\
\r\n"

we know in Python there have three module ways to create HTTP request:

urllib2/urllib
httplib/urllib
Requests

but if is it possible to create a HTTP request by import the given text? I mean use a string = the GET request text, and use this one variable string to create the HTTP request. not by using many steps, because it is complicated to differentiate the request header, request body.

3 Answers

The libs (urllib2/urllib, httplib/urllib, Requests) are encapsulated for high-level conveniently usage.

if you want to send the formatted HTTP request text, you should consider the Python socket lib.

there is an socket example:

import socket

get_str = 'GET %s HTTP/1.1\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.125 Safari/537.36\r\nAccept: */*\r\n\r\n'%("/", "www.example.com")

def get(hostname, port):
    sock = socket.socket()
    sock.connect((hostname, port))

    b_str = get_str.encode("utf-8")
    sock.send(b_str)

    response = b''
    temp = sock.recv(4096)
    while temp:
        temp = sock.recv(4096)
        response += temp

    return response.decode(encoding="utf-8")

res = get(hostname="www.example.com", port=80)
print(res)

You can write that string into the socket object connected to the HTTP server port but that is rather hard way to make requests. I would suggest the requests package instead. It is really simple and handy.

If you really, really want to, you can trick http.client.HTTPSConnection (or http.client.HTTPConnection for a plain HTTP connection) into doing what you want. This is Python 3 code; it should be possible in Python 2 with different imports and with regular strings instead of bytes.

import http.client

# Requesting https://api.ipify.org as a test
client = http.client.HTTPSConnection('api.ipify.org')
# Send raw HTTP. Note that the docs specifically tell you not to do this
# before the headers are sent.
client.send(b'GET / HTTP/1.1\r\nHost: api.ipify.org\r\n\r\n')
# Trick the connection into thinking a request has been sent. We are
# manipulating the name-mangled __state attribute of the connection,
# which is very, very ugly.
client._HTTPConnection__state = 'Request-sent'
response = client.getresponse()
# should print the response body as bytes, in this case e.g. b'123.10.10.123'
print(response.read())

Note that I don't recommend you do this; it's a very nasty hack. Although you explicitly say you don't want to parse your raw request string, it's definitely the right thing to do.

Related