Skip to content

Commit

Permalink
Adding the fetching from URI... still not fully defined...
Browse files Browse the repository at this point in the history
  • Loading branch information
silverdaz committed Jul 10, 2024
1 parent 4115714 commit 9d34dfd
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 9 deletions.
11 changes: 9 additions & 2 deletions crypt4gh/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
Utility for the cryptographic GA4GH standard, reading from stdin and outputting to stdout.
Usage:
{PROG} [-hv] [--log <file>] encrypt [--sk <path>] --recipient_pk <path> [--recipient_pk <path>]... [--range <start-end>] [--header <path>] [--expiration <date>]
{PROG} [-hv] [--log <file>] encrypt [--sk <path>] --recipient_pk <path> [--recipient_pk <path>]... [--range <start-end>] [--header <path>] [--expiration <date>] [--uri <path>]
{PROG} [-hv] [--log <file>] decrypt [--sk <path>] [--sender_pk <path>] [--range <start-end>]
{PROG} [-hv] [--log <file>] rearrange [--sk <path>] --range <start-end>
{PROG} [-hv] [--log <file>] reencrypt [--sk <path>] --recipient_pk <path> [--recipient_pk <path>]... [--trim] [--header-only]
Expand All @@ -45,6 +45,7 @@
--header <path> Where to write the header (default: stdout)
--header-only Whether the input data consists only of a header (default: false)
--expiration <date> Expiration date (in ISO format)
--uri <path> Fully Qualified URI Path to the payload location
Environment variables:
C4GH_LOG If defined, it will be used as the default logger
Expand Down Expand Up @@ -80,6 +81,9 @@ def parse_args(argv=sys.argv[1:]):
for s in ['--log', '--help', '--version']:#, 'help', 'version']:
del args[s]

if args['--range'] is not None and args['--uri'] is not None:
raise ValueError('Can not mix --range and --uri')

# print(args)
return args

Expand Down Expand Up @@ -157,6 +161,8 @@ def build_recipients():

header = args["--header"]
timestamp = args["--expiration"]
uri = args["--uri"]

if timestamp:
timestamp = make_timestamp(timestamp)
LOG.debug("timestamp: %s", timestamp)
Expand All @@ -170,7 +176,8 @@ def build_recipients():
headerfile = header,
offset = range_start,
span = range_span,
timestamp = timestamp)
timestamp = timestamp,
uri=uri)
finally:
if header:
header.close()
Expand Down
33 changes: 33 additions & 0 deletions crypt4gh/fetcher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

import logging
from urllib.request import urlopen, Request
from urllib.error import URLError, HTTPError

LOG = logging.getLogger(__name__)

class Fetcher():

__slots__ = ('response')

def __init__(self, link):
try:
LOG.info('Fetching URI: %s', link)
self.response = urlopen(link)
except HTTPError as e:
LOG.error('%r', e)
raise ValueError(f'HTTP Error {e.code}')
except URLError as e:
LOG.error('%r', e)
raise ValueError(e.reason)

def read(self, size=-1):
if size < 0:
return self.response.read()
return self.response.read(size)

def close(self):
return self.response.close()

def seek(self, offset, whence):
return self.response.seek(offset, whence=whence)

4 changes: 2 additions & 2 deletions crypt4gh/header.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,12 @@ def parse_timestamp_packet(packet):
def make_packet_link(link):
return (PACKET_TYPE_LINK
# + len(link).to_bytes(4,'little')
+ link)
+ link.encode())

def parse_link_packet(packet):
# size = int.from_bytes(packet[:4], byteorder='little')
# return packet[:size]
return packet
return packet.decode()

# -------------------------------------
# Header Encryption Methods Conventions
Expand Down
19 changes: 14 additions & 5 deletions crypt4gh/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from . import SEGMENT_SIZE
from .exceptions import close_on_broken_pipe
from . import header
from .fetcher import Fetcher, URLFetcher
from .fetcher import Fetcher

LOG = logging.getLogger(__name__)

Expand Down Expand Up @@ -49,7 +49,7 @@ def _encrypt_segment(data, process, key):


@close_on_broken_pipe
def encrypt(keys, infile, outfile, headerfile=None, offset=0, span=None, timestamp=None):
def encrypt(keys, infile, outfile, headerfile=None, offset=None, span=None, timestamp=None, uri=None):
'''Encrypt infile into outfile, using the list of keys.
Expand All @@ -60,7 +60,7 @@ def encrypt(keys, infile, outfile, headerfile=None, offset=0, span=None, timesta
'''

LOG.info('Encrypting the file')

headerfile = headerfile or outfile

# Forward to start position
Expand Down Expand Up @@ -97,11 +97,20 @@ def encrypt(keys, infile, outfile, headerfile=None, offset=0, span=None, timesta
header_packets = chain(header_packets,
header.encrypt(header.make_packet_timestamp(timestamp),
keys))
if uri:
header_packets = chain(header_packets,
header.encrypt(header.make_packet_link(uri),
keys))

header_bytes = header.serialize(header_packets)

LOG.debug('header length: %d', len(header_bytes))
headerfile.write(header_bytes)

if uri:
LOG.info('Encryption Successful via the URI: %s', uri)
return

# ...and cue music
LOG.debug("Streaming content")
# oh boy... I buffer a whole segment!
Expand Down Expand Up @@ -395,8 +404,8 @@ def decrypt(keys, infile, outfile, sender_pubkey=None, offset=0, span=None):
# Infile in now positioned at the beginning of the data portion
# or we fetch the data portion from the link.
if link:
# replacing the infile with a fetcher
outfile = URLFetcher(link)
# replacing the infile with a fetcher, might raise exception
infile = Fetcher(link)
# Note: the remainder of the infile might not be empty

# Generator to slice the output
Expand Down

0 comments on commit 9d34dfd

Please sign in to comment.