async def send_stream_to_ngas(request: aiohttp.web.Request, session, hostname, port, filename_ngas, logger): """If an incoming POST request has the content-length, send a stream direct to NGAS""" try: # Create parameters for the upload params = {"filename": filename_ngas, "file_id" : filename_ngas, "mime_type": "application/octet-stream"} # The URL to contact the NGAS server url="http://"+str(hostname)+":"+str(port)+"/ARCHIVE" # Test for content-length if 'content-length' not in request.headers: raise aiohttp.ServerConnectionError("No content-length in header") content_length=int(request.headers['Content-Length']) if content_length==0: raise ValueError # Create a ControlledReader from the content reader=ControlledReader(request.content, content_length) # Test for proper implementation if 'transfer-encoding' in request.headers: if request.headers['transfer-encoding']=="chunked": raise aiohttp.ServerConnectionError("Error, content length defined but transfer-encoding is chunked") # Connect to the NGAS server and upload resp = await session.post(url, params=params, data=reader, headers={"content-length" : str(content_length)}) # Handle the response in a specific way, as requested if resp.status==200: # Dig into the XML response for output, we are looking for SUCCESS feedback = await resp.text() xmltree = ElementTree.fromstring(feedback) # Create a dictionary of all XML elements in the response elements = {t.tag: t for t in xmltree.iter()} # Status of the NGAS transaction status=elements["Status"].get("Status") if status=="SUCCESS": return(content_length) else: raise aiohttp.ServerConnectionError("Error received in connecting to NGAS server") return(None) else: raise aiohttp.ServerConnectionError("Error received in connecting to NGAS server") return(None) except Exception as e: # Do we do anything here? raise e
async def send_stream_to_ngas(request: aiohttp.web.Request, session, hostname, port, filename_ngas, logger): """If an incoming POST request has the content-length, send a stream direct to NGAS""" try: # Create parameters for the upload params = { "filename": filename_ngas, "mime_type": "application/octet-stream" } # The URL to contact the NGAS server url = "http://" + str(hostname) + ":" + str(port) + "/ARCHIVE" # Test for content-length if 'content-length' not in request.headers: raise aiohttp.ServerConnectionError("No content-length in header") content_length = int(request.headers['Content-Length']) if content_length == 0: raise ValueError # Create a ControlledReader from the content reader = ControlledReader(request.content, content_length) # Test for proper implementation if 'transfer-encoding' in request.headers: if request.headers['transfer-encoding'] == "chunked": raise aiohttp.ServerConnectionError( "Error, content length defined but transfer-encoding is chunked" ) # Connect to the NGAS server and upload resp = await session.post( url, params=params, data=reader, headers={"content-length": str(content_length)}) if resp.status != 200: raise aiohttp.ServerConnectionError( "Error received in connecting to NGAS server") return (content_length) except Exception as e: # Do we do anything here? raise e
async def send_file_to_ngas(session, hostname, port, filename_ngas, filename_local, logger): """Send a single file to an NGAS server""" try: # Create parameters for the upload params = { "filename": filename_ngas, "mime_type": "application/octet-stream" } # The URL to contact the NGAS server url = "http://" + str(hostname) + ":" + str(port) + "/ARCHIVE" # Make sure a the file exists if filename_local is None or not os.path.isfile(filename_local): raise FileNotFoundError # Get the size of the file for content-length file_size = (await stat(filename_local)).st_size if file_size == 0: raise ValueError(f"file {filename_local} has 0 size") async with aiofiles.open(filename_local, 'rb') as fd: # Connect to the NGAS server and upload the file resp = await session.post( url, params=params, data=fd, headers={"content-length": str(file_size)}) if resp.status != 200: raise aiohttp.ServerConnectionError( "Error received in connecting to NGAS server") return (file_size) except Exception as e: # Do we do anything here? raise e
async def upload(hostname, port, filename_ngas, filename_local): # Upload a simple file to an NGAS server params = { "filename": filename_ngas, "file_id": filename_ngas, "mime_type": "application/octet-stream" } encoded_parms = urllib.parse.urlencode(params) ngas_string = "ngas_client" # Get the number of bytes in a file nbytes = os.stat(filename_local).st_size # Open a HTTP connection to the NGAS server # Multiline f string for header raw_header= f"POST /ARCHIVE?{encoded_parms} HTTP/1.1\r\n" \ f"Host: {hostname}:{port}\r\n" \ f"Accept: */*\r\n" \ f"User-Agent: {ngas_string}\r\n" \ f"Content-Type: application/octet-stream\r\n" \ f"Content-Length: {nbytes}\r\n" \ f"Expect: 100-continue\r\n" \ f"\r\n" raw_header = raw_header.encode("utf-8") print(raw_header) (reader, writer) = await asyncio.open_connection(host=hostname, port=port) async with aiofiles.open(filename_local, "rb") as fd: writer.write(raw_header) while True: buffer = await fd.read(65536) if buffer: #print(buffer) writer.write(buffer) await writer.drain() else: break writer.write_eof() await writer.drain() # Write some headers to the connection # Read any response print("\nMoving to response:\n") # Look for ok Message in the first column firstline = (await reader.readline()).decode().split(" ") if '200' not in firstline: # Do we let the client know? raise aiohttp.ServerConnectionError( "Error received in connecting to NGAS server") else: # Do we do something here? pass writer.close()