def transform_request(self) -> None: loop = self.server.loop # FIXME: should we shutdown() read or write depending on what # we do here ? (i.e. SHUT_RD for GETs, SHUT_WD for sources) self.server.logger.info( "%s:%s %s %s %s, request headers: %s", self.address[0], self.address[1], self.request_parser.request_method, self.request_parser.request_path, self.request_parser.http_version, self.request_parser.headers, ) # Squash any consecutive / into one self.request_parser.request_path = re.sub( b"//+", b"/", self.request_parser.request_path) self.server.request_in(self.request_parser, self.sock) # Authorization for auth_handler in self.server.auth_handlers: auth_result = auth_handler.authorize(self.address, self.request_parser) if auth_result is None: continue elif not isinstance(auth_result, HTTPResponse): # Wrong response from auth handler raise RuntimeError( "Wrong response from authorization handler %s" % auth_handler) elif auth_result.status == 200: # Request authorized break else: # Access denied loop.register( helpers.HTTPEventHandler(self.server, self.sock, self.address, self.request_parser, auth_result), looping.POLLOUT, ) return path = self.request_parser.request_path.decode("ascii") response = None if self.request_parser.request_method in [b"PUT", b"SOURCE", b"POST"]: self.server.register_source( sources.find_source(self.server, self.sock, self.address, self.request_parser, path)) elif self.request_parser.request_method in [b"GET", b"HEAD"]: # New client # Is our client asking for status ? if path in self.server.status_handlers: # FIXME: should we handle HEAD requests ? if self.request_parser.request_method not in [b"GET"]: response = HTTPResponse(405, b"Method Not Allowed") else: loop.register( self.server.status_handlers[path].get_status( self.sock, self.address, self.request_parser), looping.POLLOUT, ) else: # New client for one of our sources if path in self.server.sources: # Used by some clients to know the stream type # before attempting playout if self.request_parser.request_method in [b"HEAD"]: source = list(self.server.sources[path].keys())[0] response = HTTPResponse( 200, b"OK", { b"Content-Type": bytes(source.content_type, "ascii"), b"Content-Length": None, b"Connection": b"close", }, ) # Check for server clients limit elif self.server.clients_limit is not None and ( self.server.clients_limit == self.server.clients_connected): response = HTTPResponse( 503, b"Cannot handle response." b" Too many clients.") else: # FIXME: proper source selection source = random.choice( list(self.server.sources[path].keys())) new_client = clients.find_client( self.server, source, self.sock, self.address, self.request_parser) # FIXME: this call may actually need to instatiate # the client itself (e.g. if the source needs some # dedicated code in its clients) source.new_client(new_client) # FIXME: see above wrt to proper source selection self.server.sources[path][source]["clients"][ new_client.fileno()] = new_client self.server.clients_connected += 1 loop.register(new_client, looping.POLLOUT) else: # Stream does not exist response = HTTPResponse(404, b"Stream Not Found") else: # Unknown HTTP request method response = HTTPResponse(405, b"Method Not Allowed") if response is not None: loop.register( helpers.HTTPEventHandler(self.server, self.sock, self.address, self.request_parser, response), looping.POLLOUT, )
def transform_request(self): # FIXME: should we shutdown() read or write depending on what # we do here ? (i.e. SHUT_RD for GETs, SHUT_WD for sources) self.server.logger.debug('%s %s %s %s, request headers: %s', self.address, self.request_parser.request_method, self.request_parser.request_path, self.request_parser.http_version, self.request_parser.headers) # Squash any consecutive / into one self.request_parser.request_path = re.sub('//+', '/', self.request_parser.request_path) self.server.request_in(self.request_parser, self.sock) # Authorization for auth_handler in self.server.auth_handlers: auth_result = auth_handler.authorize(self.address, self.request_parser) if auth_result is None: continue elif not isinstance(auth_result, HTTPResponse): # Wrong response from auth handler raise RuntimeError('Wrong response from authorization handler %s' % auth_handler) elif auth_result.status == 200: # Request authorized break else: # Access denied response_handler = helpers.HTTPEventHandler( self.server, self.sock, self.address, self.request_parser, auth_result) response_handler.start() self.follow_up() return path = self.request_parser.request_path response = None if self.request_parser.request_method in [b'PUT', b'SOURCE', b'POST']: self.server.register_source(sources.find_source( self.server, self.sock, self.address, self.request_parser, path)) elif self.request_parser.request_method in [b'GET']: # New client # Is our client asking for status ? if path in self.server.status_handlers: response_handler = self.server.status_handlers[path].get_status( self.sock, self.address, self.request_parser) response_handler.start() self.follow_up() else: # New client for one of our sources if self.server.sources.get(path, []): # Check for server clients limit if self.server.clients_limit is not None and ( self.server.clients_limit == self.server.clients_connected): response = HTTPResponse(503, b'Cannot handle response.' b' Too many clients.') else: # FIXME: proper source selection source = random.choice(self.server.sources[path].keys()) new_client = clients.find_client(self.server, source, self.sock, self.address, self.request_parser) # FIXME: this call may actually need to instatiate # the client itself (e.g. if the source needs some # dedicated code in its clients) source.new_client(new_client) # FIXME refactor following lines in source.new_client new_client.start() self.follow_up() # FIXME: see above wrt to proper source selection self.server.sources[path][source]['clients'][new_client.fileno()] = new_client self.server.clients_connected += 1 else: # Stream does not exist response = HTTPResponse(404, b'Stream Not Found') else: # Unknown HTTP request method response = HTTPResponse(405, b'Method Not Allowed') if response is not None: response_handler = helpers.HTTPEventHandler( self.server, self.sock, self.address, self.request_parser, response) response_handler.start() self.follow_up()