From 4cfbdda0ef2dd23debbb22d7ee74ceba81a0040a Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 26 Jun 2022 11:12:34 +0200 Subject: ups: switch from curl to urllib Avoid curl dependency, fixes files with spaces in their name. --- bin/ups | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/bin/ups b/bin/ups index 2de9dfb..d38a076 100755 --- a/bin/ups +++ b/bin/ups @@ -2,10 +2,13 @@ # ups.khirnov.net uploader import argparse +from http import HTTPStatus import os.path import shutil +import ssl import subprocess import sys +from urllib import request, error as urlerror try: import magic @@ -23,33 +26,37 @@ parser.add_argument('path', nargs = '?', default = '-') args = parser.parse_args() if args.path == '-' and not args.name: - src_name = '-' - dst_name = args.name or 'stdin' + dst_name = 'stdin' # try to guess the extension when name is not provided - if not args.name and have_magic: + if have_magic: m = magic.Magic(extension = True) e = m.from_buffer(sys.stdin.buffer.peek(2048)) if e != '???': dst_name += '.' + e.split('/')[0] else: - src_name = args.path - dst_name = args.name or os.path.basename(src_name) + dst_name = args.name or os.path.basename(args.path) -stdin = subprocess.PIPE if src_name == '-' else subprocess.DEVNULL +ssl_ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) +ssl_ctx.verify_mode = ssl.CERT_REQUIRED +ssl_ctx.load_cert_chain(cert_path) +ssl_ctx.load_default_certs() -curl_cmdline = ['curl', '--silent', '--show-error', '--cert', cert_path, - '--data-binary', '@' + src_name, server + dst_name] +src = sys.stdin.buffer if args.path == '-' else open(args.path, 'rb') -child = subprocess.Popen(curl_cmdline, stdin = stdin) -if stdin != subprocess.DEVNULL: - # stream our stdin to the child process - # cannot pass stdin to the child directly because we peeked at it above - shutil.copyfileobj(sys.stdin.buffer, child.stdin) - child.stdin.close() - -ret = child.wait() -if ret != 0: - sys.stderr.write('curl returned an error code: %d\n' % ret) +req = request.Request(server + dst_name, data = src, method = 'POST') +try: + resp = request.urlopen(req, context = ssl_ctx) +except KeyboardInterrupt: + sys.stderr.write('Interrupted\n') + sys.exit(1) +except urlerror.URLError as e: + sys.stderr.write('Error submitting the file: %s\n' % str(e.reason)) + sys.exit(1) + +if resp.status in (HTTPStatus.OK, HTTPStatus.CREATED): + sys.stdout.write(resp.read().decode('ascii') + '\n') else: - sys.stdout.write('\n') + sys.stderr.write('The server returned unexpected code: %d %s\n' % + (resp.status, resp.reason)) + sys.exit(1) -- cgit v1.2.3