6

I wrote a socket server using Python 2.7 and the socket module.

Everything works as expected when I issue an HTTP request: the server accepts it and answers correctly. But if instead of (let's say) http://a.com I browse for https://a.com I receive some kind of encrypted header and I don't know how to tell the client that HTTPS is not supported by the server.

I googled a bit but nothing good. I tried to reply in plain HTTP but the response is clearly ignored by the browser.

If anyone would be able to show me a way to tell the client there's no SSL it would really help me.

Thanks in advance.

Alex
  • 6,849
  • 6
  • 19
  • 36
  • In most cases there will be a webserver (nginx/apache/etc.) that can handle the SSL and proxy to your python app. Run a webserver and have python listen on a socket file or lock down requests to localhost only. – Chris Montanaro Aug 18 '15 at 03:34
  • also, http://stackoverflow.com/questions/26851034/opening-a-ssl-socket-connection-in-python and https://docs.python.org/2/library/ssl.html – Chris Montanaro Aug 18 '15 at 03:36
  • I'm not sure that there's a way to have your connection be both ssl and non. In all cases I can think of you need separate ports, generally 80 (http), 443 (https) – Chris Montanaro Aug 18 '15 at 03:40
  • Thanks Chris. But what if I _want_ to force the client to http? I know it's not secure and stuff, but just to know. – Alex Aug 18 '15 at 04:17
  • nginx can be configured to listen on both, and default to https, http://serverfault.com/questions/10854/nginx-https-serving-with-same-config-as-http – Chris Montanaro Aug 18 '15 at 04:19
  • Thanks Chris I really appreciate your help but I think we misunderstood. I'm not looking to establish an ssl connection, I would like to just say to the client "No boy, HTTPS here is not supported, use HTTP instead" – Alex Aug 19 '15 at 03:04
  • redirect port 443 traffic to port 80, http://stackoverflow.com/questions/3893839/how-do-i-redirect-https-requests-to-http-in-nginx – Chris Montanaro Aug 19 '15 at 15:39
  • iptables won't let me redirect port 443 traffic anywhere else than 443 – Alex Aug 24 '15 at 16:31
  • set "listen 443" and "ssl off" – Chris Montanaro Aug 24 '15 at 21:16
  • Are you talking about the Pyhton socket or iptables? (Thanks Chris, you're very patient) – Alex Aug 25 '15 at 17:37
  • I was talking about in nginx (or whatever webserver you use). You could also tunnel the port with iptables, http://www.cyberciti.biz/faq/linux-port-redirection-with-iptables/ or in python you would probably need to run multiple threads to listen on 2 ports – Chris Montanaro Aug 25 '15 at 21:01

2 Answers2

8

I had the same problem. You have to configure "ssl" context within your code as such:

import socket, ssl

HOST = "www.youtube.com"
PORT = 443

context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s_sock = context.wrap_socket(s, server_hostname=HOST)
s_sock.connect((HOST, 443))
s_sock.send(" GET / HTTP/1.1\r\nHost: www.youtube.com\r\n\r\n ".encode())

while True:
    data = s_sock.recv(2048)
    if ( len(data) < 1 ) :
        break
    print(data)

s_sock.close()
Ion
  • 81
  • 1
  • 2
  • The code above is for handling HTTPS from client side only. I believe server side HTTPS handling is done differently. – Ion Feb 24 '17 at 03:41
  • it produces error: OSError: [WinError 10038] An operation was attempted on something that is not a socket. Why is that so? – Kardi Teknomo May 17 '19 at 05:46
  • you create `context` but don't use it ? – rustyMagnet Dec 02 '20 at 11:18
  • 2
    Gives me this result: b'HTTP/1.0 400 Bad Request\r\nContent-Length: 54\r\nContent-Type: text/html; charset=UTF-8\r\nDate: Fri, 30 Apr 2021 08:28:45 GMT\r\n\r\nError 400 (Bad Request)!!1' – Sahin Apr 30 '21 at 08:29
  • I also got `HTTP/1.1 400 Bad Request`, and I found it was because there was a SPACE before `GET`. – Donghua Liu Jun 23 '22 at 08:16
-1

Try this. The module names have changed so that they are now part of the http.server module (part of a standard installation) - see the note at the top of the SimpleHTTPServer documentation for Python 2. The main problem, though, is that you need to get an SSL certificate to secure connections with (the easiest way I believe is OpenSSL).

Minion Jim
  • 1,239
  • 13
  • 30