@@ -529,6 +529,13 @@ def _get_socket(
529529 self ._socket_free [sock ] = False
530530 return sock
531531
532+ @staticmethod
533+ def _header_suppplied (header , supplied_headers ):
534+ for supplied_header in supplied_headers :
535+ if supplied_header .lower () == header .lower ():
536+ return True
537+ return False
538+
532539 @staticmethod
533540 def _send (socket : SocketType , data : bytes ):
534541 total_sent = 0
@@ -551,6 +558,16 @@ def _send(socket: SocketType, data: bytes):
551558 raise OSError (errno .EIO )
552559 total_sent += sent
553560
561+ def _send_as_bytes (self , socket : SocketType , data : str ):
562+ return self ._send (socket , bytes (data , "utf-8" ))
563+
564+ def _send_header (self , socket , header , value ):
565+ self ._send_as_bytes (socket , header )
566+ self ._send_as_bytes (socket , ": " )
567+ self ._send_as_bytes (socket , value )
568+ self ._send_as_bytes (socket , "\r \n " )
569+
570+ # pylint: disable=too-many-arguments
554571 def _send_request (
555572 self ,
556573 socket : SocketType ,
@@ -561,40 +578,48 @@ def _send_request(
561578 data : Any ,
562579 json : Any ,
563580 ):
564- # pylint: disable=too-many-arguments
565- self ._send (socket , bytes (method , "utf-8" ))
566- self ._send (socket , b" /" )
567- self ._send (socket , bytes (path , "utf-8" ))
568- self ._send (socket , b" HTTP/1.1\r \n " )
569- if "Host" not in headers :
570- self ._send (socket , b"Host: " )
571- self ._send (socket , bytes (host , "utf-8" ))
572- self ._send (socket , b"\r \n " )
573- if "User-Agent" not in headers :
574- self ._send (socket , b"User-Agent: Adafruit CircuitPython\r \n " )
575- # Iterate over keys to avoid tuple alloc
576- for k in headers :
577- self ._send (socket , k .encode ())
578- self ._send (socket , b": " )
579- self ._send (socket , headers [k ].encode ())
580- self ._send (socket , b"\r \n " )
581+ # Convert data
582+ content_type_header = None
583+
584+ # If json is sent, set content type header and convert to string
581585 if json is not None :
582586 assert data is None
587+ content_type_header = "application/json"
583588 data = json_module .dumps (json )
584- self ._send (socket , b"Content-Type: application/json\r \n " )
585- if data :
586- if isinstance (data , dict ):
587- self ._send (
588- socket , b"Content-Type: application/x-www-form-urlencoded\r \n "
589- )
590- _post_data = ""
591- for k in data :
592- _post_data = "{}&{}={}" .format (_post_data , k , data [k ])
593- data = _post_data [1 :]
594- if isinstance (data , str ):
595- data = bytes (data , "utf-8" )
596- self ._send (socket , b"Content-Length: %d\r \n " % len (data ))
589+
590+ # If data is sent and it's a dict, set content type header and convert to string
591+ if data and isinstance (data , dict ):
592+ content_type_header = "application/x-www-form-urlencoded"
593+ _post_data = ""
594+ for k in data :
595+ _post_data = "{}&{}={}" .format (_post_data , k , data [k ])
596+ # remove first "&" from concatenation
597+ data = _post_data [1 :]
598+
599+ # Convert str data to bytes
600+ if data and isinstance (data , str ):
601+ data = bytes (data , "utf-8" )
602+
603+ self ._send_as_bytes (socket , method )
604+ self ._send_as_bytes (socket , " /" )
605+ self ._send_as_bytes (socket , path )
606+ self ._send_as_bytes (socket , " HTTP/1.1\r \n " )
607+
608+ # Send headers
609+ if not self ._header_suppplied ("Host" , headers ):
610+ self ._send_header (socket , "Host" , host )
611+ if not self ._header_suppplied ("User-Agent" , headers ):
612+ self ._send_header (socket , "User-Agent" , "Adafruit CircuitPython" )
613+ if content_type_header and not self ._header_suppplied ("Content-Type" , headers ):
614+ self ._send_header (socket , "Content-Type" , content_type_header )
615+ if data and not self ._header_suppplied ("Content-Length" , headers ):
616+ self ._send_header (socket , "Content-Length" , str (len (data )))
617+ # Iterate over keys to avoid tuple alloc
618+ for header in headers :
619+ self ._send_header (socket , header , headers [header ])
597620 self ._send (socket , b"\r \n " )
621+
622+ # Send data
598623 if data :
599624 self ._send (socket , bytes (data ))
600625
0 commit comments