def remove_request(self, identifier, is_global=False): """ Cancel a running request. NOT ALLOWED WHILE UPLOADING DATA. """ if self.is_uploading(): raise Exception("Can't remove while uploading. Sorry :-(") if not identifier in self.running_clients: print "FCPConnection.remove_request -- unknown identifier: ", \ identifier params = {'Identifier': identifier, 'Global': is_global} self.socket.write_bytes(make_request(REMOVE_REQUEST_DEF, params))
def remove_request(self, identifier, is_global = False): """ Cancel a running request. NOT ALLOWED WHILE UPLOADING DATA. """ if self.is_uploading(): raise Exception("Can't remove while uploading. Sorry :-(") if not identifier in self.running_clients: print "FCPConnection.remove_request -- unknown identifier: ", \ identifier params = {'Identifier': identifier, 'Global': is_global} self.socket.write_bytes(make_request(REMOVE_REQUEST_DEF, params))
def handled_redirect(self, msg, client): """ INTERNAL: Handle code 27 redirects. """ # BITCH: This is a design flaw in the FCP 2.0 protocol. # They should have used unique numbers for all error # codes so that client coders don't need to keep track # of the initiating request in order to interpret the # error code. if client.in_params.definition[0] == 'ClientGet' and is_code(msg, 27): #print "Checking for allowed redirect" if client.context.allowed_redirects: #print "Handling redirect" client.context.allowed_redirects -= 1 assert client.context.initiating_id assert client.context.initiating_id in self.running_clients assert client.context.running_id if client.context.running_id != client.context.initiating_id: # Remove the context for the intermediate redirect. #print "DELETED: ", client.context.running_id del self.running_clients[client.context.running_id] client.context.running_id = make_id() client.context.last_uri = msg[1]['RedirectURI'] # Copy, don't modify params. params = {} params.update(client.in_params.fcp_params) params['URI'] = client.context.last_uri params['Identifier'] = client.context.running_id # Send new request. self.socket.write_bytes( make_request(client.in_params.definition, params)) #print "MAPPED(1) [%s]->[%s]" % (client.context.running_id, # str(client)) self.running_clients[client.context.running_id] = client # REDFLAG: change callback to include identifier? # Hmmm...fixup identifier in msg? if client.message_callback: client.message_callback(client, msg) return True return False
def handled_redirect(self, msg, client): """ INTERNAL: Handle code 27 redirects. """ # BITCH: This is a design flaw in the FCP 2.0 protocol. # They should have used unique numbers for all error # codes so that client coders don't need to keep track # of the initiating request in order to interpret the # error code. if client.in_params.definition[0] == 'ClientGet' and is_code(msg, 27): #print "Checking for allowed redirect" if client.context.allowed_redirects: #print "Handling redirect" client.context.allowed_redirects -= 1 assert client.context.initiating_id assert client.context.initiating_id in self.running_clients assert client.context.running_id if client.context.running_id != client.context.initiating_id: # Remove the context for the intermediate redirect. #print "DELETED: ", client.context.running_id del self.running_clients[client.context.running_id] client.context.running_id = make_id() client.context.last_uri = msg[1]['RedirectURI'] # Copy, don't modify params. params = {} params.update(client.in_params.fcp_params) params['URI'] = client.context.last_uri params['Identifier'] = client.context.running_id # Send new request. self.socket.write_bytes(make_request(client.in_params. definition, params)) #print "MAPPED(1) [%s]->[%s]" % (client.context.running_id, # str(client)) self.running_clients[client.context.running_id] = client # REDFLAG: change callback to include identifier? # Hmmm...fixup identifier in msg? if client.message_callback: client.message_callback(client, msg) return True return False
def __init__(self, socket_, wait_for_connect=False, state_callback=None): """ Create an FCPConnection from an open IAsyncSocket instance. REQUIRES: socket_ ready for writing. """ self.running_clients = {} # Delegate handles parsing FCP protocol off the wire. self.parser = FCPParser() self.parser.msg_callback = self.msg_handler self.parser.context_callback = self.get_context self.socket = socket_ if state_callback: self.state_callback = state_callback else: self.state_callback = lambda x, y: None self.socket.recv_callback = self.parser.parse_bytes self.socket.closed_callback = self.closed_handler self.node_hello = None # Only used for uploads. self.data_source = None # Tell the client code that we are trying to connect. self.state_callback(self, CONNECTING) # Send a ClientHello params = { 'Name': 'FCPConnection[%s]' % make_id(), 'ExpectedVersion': FCP_VERSION } self.socket.write_bytes(make_request(HELLO_DEF, params)) if wait_for_connect: # Wait for the reply while not self.is_connected(): if not self.socket.poll(): raise IOError("Socket closed") time.sleep(POLL_TIME_SECS)
def __init__(self, socket_, wait_for_connect = False, state_callback = None): """ Create an FCPConnection from an open IAsyncSocket instance. REQUIRES: socket_ ready for writing. """ self.running_clients = {} # Delegate handles parsing FCP protocol off the wire. self.parser = FCPParser() self.parser.msg_callback = self.msg_handler self.parser.context_callback = self.get_context self.socket = socket_ if state_callback: self.state_callback = state_callback else: self.state_callback = lambda x, y: None self.socket.recv_callback = self.parser.parse_bytes self.socket.closed_callback = self.closed_handler self.node_hello = None # Only used for uploads. self.data_source = None # Tell the client code that we are trying to connect. self.state_callback(self, CONNECTING) # Send a ClientHello params = {'Name':'FCPConnection[%s]' % make_id(), 'ExpectedVersion': FCP_VERSION} self.socket.write_bytes(make_request(HELLO_DEF, params)) if wait_for_connect: # Wait for the reply while not self.is_connected(): if not self.socket.poll(): raise IOError("Socket closed") time.sleep(POLL_TIME_SECS)
def start_request(self, client, data_source=None, set_data_length=True): """ Start an FCP request. If in_params.async is True this returns immediately, otherwise it blocks until the request finishes. If client.in_params.send_data is set, trailing data is sent after the request message. If data_source is not None, then the data in it is sent. Otherwise if client.in_params.file is not None, the data in the file is sent. Finally if neither of the other sources are not None the contents of client.in_params.send_data are sent. If set_data_length is True the 'DataLength' field is set in the requests FCP message. If in_params.async it True, this method returns the identifier for the request, otherwise, returns the FCP message which terminated the request. """ assert not self.is_uploading() assert not client.context assert not client.response assert not 'Identifier' in client.in_params.fcp_params identifier = make_id() client.in_params.fcp_params['Identifier'] = identifier write_string = False if client.in_params.send_data: assert not self.data_source if data_source: data_source.initialize() if set_data_length: client.in_params.fcp_params['DataLength'] = ( data_source.data_length()) self.data_source = data_source self.socket.writable_callback = self.writable_handler elif client.in_params.file_name: self.data_source = FileDataSource(client.in_params.file_name) self.data_source.initialize() client.in_params.fcp_params['DataLength'] = ( self.data_source.data_length()) self.socket.writable_callback = self.writable_handler else: client.in_params.fcp_params['DataLength'] = len( client.in_params.send_data) write_string = True self.socket.write_bytes( make_request(client.in_params.definition, client.in_params.fcp_params, client.in_params.default_fcp_params)) if write_string: self.socket.write_bytes(client.in_params.send_data) assert not client.context client.context = RequestContext(client.in_params.allowed_redirects, identifier, client.in_params.fcp_params.get('URI')) if not client.in_params.send_data: client.context.file_name = client.in_params.file_name #print "MAPPED [%s]->[%s]" % (identifier, str(client)) self.running_clients[identifier] = client if self.data_source: self.state_callback(self, UPLOADING) if client.in_params. async: return identifier resp = self.wait_for_terminal(client) raise_on_error(resp) return client.response
def start_request(self, client, data_source = None, set_data_length = True): """ Start an FCP request. If in_params.async is True this returns immediately, otherwise it blocks until the request finishes. If client.in_params.send_data is set, trailing data is sent after the request message. If data_source is not None, then the data in it is sent. Otherwise if client.in_params.file is not None, the data in the file is sent. Finally if neither of the other sources are not None the contents of client.in_params.send_data are sent. If set_data_length is True the 'DataLength' field is set in the requests FCP message. If in_params.async it True, this method returns the identifier for the request, otherwise, returns the FCP message which terminated the request. """ assert not self.is_uploading() assert not client.context assert not client.response assert not 'Identifier' in client.in_params.fcp_params identifier = make_id() client.in_params.fcp_params['Identifier'] = identifier write_string = False if client.in_params.send_data: assert not self.data_source if data_source: data_source.initialize() if set_data_length: client.in_params.fcp_params['DataLength'] = (data_source. data_length()) self.data_source = data_source self.socket.writable_callback = self.writable_handler elif client.in_params.file_name: self.data_source = FileDataSource(client.in_params.file_name) self.data_source.initialize() client.in_params.fcp_params['DataLength'] = (self. data_source. data_length()) self.socket.writable_callback = self.writable_handler else: client.in_params.fcp_params['DataLength'] = len(client. in_params. send_data) write_string = True self.socket.write_bytes(make_request(client.in_params.definition, client.in_params.fcp_params, client.in_params. default_fcp_params)) if write_string: self.socket.write_bytes(client.in_params.send_data) assert not client.context client.context = RequestContext(client.in_params.allowed_redirects, identifier, client.in_params.fcp_params.get('URI')) if not client.in_params.send_data: client.context.file_name = client.in_params.file_name #print "MAPPED [%s]->[%s]" % (identifier, str(client)) self.running_clients[identifier] = client if self.data_source: self.state_callback(self, UPLOADING) if client.in_params.async: return identifier resp = self.wait_for_terminal(client) raise_on_error(resp) return client.response