Skip to content

Commit 011a0b2

Browse files
author
Stephane Bortzmeyer
committed
A simple example of a HTTP client. Addresses pyca#872
1 parent 26f1a92 commit 011a0b2

File tree

1 file changed

+67
-0
lines changed

1 file changed

+67
-0
lines changed

examples/simple-http-example.py

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#!/usr/bin/env python3
2+
3+
"""A simple Python program to show the use of the pyOpenSSL
4+
library. We connect to a HTTPS server and retrieve its home page. (Of
5+
course, for this specific task, pyCurl would be a better solution but
6+
the goal is to demonstrate pyOpenSSL.)"""
7+
8+
PORT = 443 # Hardwired
9+
PATH = "/" # Hardwired
10+
11+
# https://www.pyopenssl.org/
12+
# https://pyopenssl.readthedocs.io/
13+
import OpenSSL
14+
15+
import socket
16+
import sys
17+
18+
if len(sys.argv) != 2:
19+
raise Exception("Usage: %s hostname" % sys.argv[0])
20+
host = sys.argv[1]
21+
22+
addrinfo = socket.getaddrinfo(host, PORT, 0)
23+
24+
# We should loop over the IP addresses instead of taking only the first one…
25+
sock = socket.socket(addrinfo[0][0], socket.SOCK_STREAM)
26+
addr = addrinfo[0][4]
27+
print("Connecting to %s ..." % str(addr))
28+
29+
context = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_2_METHOD)
30+
31+
# Use the OS' default CAs
32+
context.set_default_verify_paths()
33+
34+
# Ask for a certificate check. Warning, this does not check the host
35+
# name, just the path from the CA, the expiration, may be the CRLs…
36+
context.set_verify(OpenSSL.SSL.VERIFY_PEER | OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT | \
37+
OpenSSL.SSL.VERIFY_CLIENT_ONCE,
38+
lambda conn, cert, errno, depth, preverify_ok: preverify_ok)
39+
40+
session = OpenSSL.SSL.Connection(context, sock)
41+
session.set_tlsext_host_name(host.encode()) # Server Name Indication (SNI)
42+
43+
# TCP
44+
session.connect((addr))
45+
46+
# TLS
47+
session.do_handshake()
48+
cert = session.get_peer_certificate()
49+
print("Connected, its certificate is for \"%s\", delivered by \"%s\"" % \
50+
(cert.get_subject().commonName,
51+
cert.get_issuer().commonName))
52+
53+
# HTTP
54+
request = """GET %s HTTP/1.1
55+
Host: %s
56+
Connection: close
57+
58+
""" % (PATH, host)
59+
session.write(request.replace("\n","\r\n"))
60+
61+
# A real program must loop to read all the data
62+
data = session.read(4096)
63+
print("Got %i bytes, the first ones are: \"%s...\"" % (len(data),
64+
data[:256].decode()))
65+
66+
session.close()
67+
sock.close()

0 commit comments

Comments
 (0)