pythonpython-3.xhttpserverbasehttprequesthandler

How to visualize the body part of a BaseHTTPRequestHandler


I'm writing a server in Python and I want to send some data in the body part of a GET request. Currently when I run my code it just freezes.

I tried to put it in a try/except and read details about the instance variable rfile but I didn't find anything helpful

Client-side :

import http.client
import sys  
import os

#get http server ip  
http_server = sys.argv[1]  
#create a connection  
conn = http.client.HTTPConnection(http_server)  

while 1:  
  cmd = input('input command (ex. GET index.html): ')  
  cmd = cmd.split()  

  f = open('data.txt')

  if cmd[0] == 'exit': #tipe exit to end it  
    break  

  #request command to server  
  conn.request(cmd[0],'',f.read())  

  #get response from server  
  rsp = conn.getresponse()  

  #print server response and data  
  print(rsp.status, rsp.reason)  
  data_received = rsp.read()  
  print(data_received)  

Server-side :

from http.server import BaseHTTPRequestHandler,HTTPServer
import os

class TestHTTPRequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        a = ''
        fichier = open("data2.txt", "w")
        try:
            fichier.write(self.rfile.read())
        except:

        self.send_response(200)
        self.send_header('Content-type','text-html')
        self.end_headers()
        return


def run():
    print('http server is starting...')
    server_address = ('127.0.0.1',80)
    httpd = HTTPServer(server_address, PancakeHTTPRequestHandler)
    print('htttp server is running...')
    httpd.serve_forever()

if __name__ == '__main__':
    run()  

I expect being able to write my data from my GET request in my data2.txt file.

Thank you for your help


Solution

  • It freezes because of the self.rfile.read() in your server.py. The read method expect either EOF or a byte length to read. See https://docs.python.org/3/library/io.html#io.BufferedIOBase.read You're trying to log the client requests made to the server, a quick work around would be to pass the content length of the request to the read method with int(self.headers.get('Content-Length'))

    In the end it gives us:

    client.py

    import http.client
    import sys  
    import os
    
    #get http server ip  
    http_server = sys.argv[1]  
    #create a connection  
    conn = http.client.HTTPConnection(http_server)  
    
    while 1:  
      cmd = input('input command (ex. GET index.html): ')  
      cmd = cmd.split()
    
      f = open('data.txt')
    
      if cmd[0] == 'exit': #tipe exit to end it  
        break  
    
      #request command to server  
      conn.request(cmd[0], '', f.read())  
    
      #get response from server  
      rsp = conn.getresponse()  
    
      #print server response and data  
      print(rsp.status, rsp.reason)  
      data_received = rsp.read()  
      print(data_received)  
    

    server.py

    from http.server import BaseHTTPRequestHandler,HTTPServer
    import os
    
    class TestHTTPRequestHandler(BaseHTTPRequestHandler):
        def do_GET(self):
            a = ''
            fichier = open("data2.txt", "a")
            try:
                content_length = int(self.headers.get('Content-Length'))
                response_str = self.rfile.read(content_length)
                fichier.write(response_str.decode('utf-8'))
                self.send_response(200)
                self.send_header("Content-type", "text/html")
                self.end_headers()
            except:
                self.send_response(200)
                self.send_header('Content-type','text-html')
                self.end_headers()
            fichier.close()
            return
    
    
    def run():
        print('http server is starting...')
        server_address = ('127.0.0.1',80)
        httpd = HTTPServer(server_address, TestHTTPRequestHandler)
        print('htttp server is running...')
        httpd.serve_forever()
    
    if __name__ == '__main__':
        run()  
    

    ps. I don't know what PancakeHTTPRequestHandler was so I replaced it with TestHTTPRequestHandler. And I also added a response in try except on the server side so that the the client gets a response otherwise it will crash.