From daada7a1dbb7fdc28eeda113421ace81e1390470 Mon Sep 17 00:00:00 2001 From: Gardouille Date: Fri, 27 Jan 2023 13:58:07 +0100 Subject: [PATCH] New python webserver script for upload --- droopy | 787 ------------------------------------------ upload-http-server.py | 423 +++++++++++++++++++++++ 2 files changed, 423 insertions(+), 787 deletions(-) delete mode 100755 droopy create mode 100755 upload-http-server.py diff --git a/droopy b/droopy deleted file mode 100755 index 0f7e293..0000000 --- a/droopy +++ /dev/null @@ -1,787 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# Droopy (http://stackp.online.fr/droopy) -# Copyright 2008 (C) Pierre Duquesne -# Licensed under the Python Software Foundation License -# (http://www.python.org/psf/license/) - -# Changelog -# 20100523 * Simplified Chinese translation by Ye Wei. -# 20100521 * Hungarian translation by Csaba Szigetvári. -# * Russian translation by muromec. -# * Use %APPDATA% Windows environment variable -- fix by Maik. -# 20091229 * Brazilian Portuguese translation by -# Carlos Eduardo Moreira dos Santos and Toony Poony. -# * IE layout fix by Carlos Eduardo Moreira dos Santos. -# * Galician translation by Miguel Anxo Bouzada. -# 20090721 * Indonesian translation by Kemas. -# 20090205 * Japanese translation by Satoru Matsumoto. -# * Slovak translation by CyberBoBaK. -# 20090203 * Norwegian translation by Preben Olav Pedersen. -# 20090202 * Korean translation by xissy. -# * Fix for unicode filenames by xissy. -# * Relies on 127.0.0.1 instead of "localhost" hostname. -# 20090129 * Serbian translation by kotnik. -# 20090125 * Danish translation by jan. -# 20081210 * Greek translation by n2j3. -# 20081128 * Slovene translation by david. -# * Romanian translation by Licaon. -# 20081022 * Swedish translation by David Eurenius. -# 20081001 * Droopy gets pretty (css and html rework). -# * Finnish translation by ipppe. -# 20080926 * Configuration saving and loading. -# 20080906 * Extract the file base name (some browsers send the full path). -# 20080905 * File is uploaded directly into the specified directory. -# 20080904 * Arabic translation by Djalel Chefrour. -# * Italian translation by fabius and d1s4st3r. -# * Dutch translation by Tonio Voerman. -# * Portuguese translation by Pedro Palma. -# * Turkish translation by Heartsmagic. -# 20080727 * Spanish translation by Federico Kereki. -# 20080624 * Option -d or --directory to specify the upload directory. -# 20080622 * File numbering to avoid overwriting. -# 20080620 * Czech translation by Jiří. -# * German translation by Michael. -# 20080408 * First release. - -import BaseHTTPServer -import SocketServer -import cgi -import os -import posixpath -import macpath -import ntpath -import sys -import getopt -import mimetypes -import copy -import shutil -import tempfile -import socket -import locale - -USAGE='''\ -Usage: droopy [options] [PORT] - -Options: - -h, --help show this help message and exit - -m MESSAGE, --message MESSAGE set the message - -p PICTURE, --picture PICTURE set the picture - -d DIRECTORY, --directory DIRECTORY set the directory to upload files to - --save-config save options in a configuration file - --delete-config delete the configuration file and exit - -Example: - droopy -m "Hi, this is Bob. You can send me a file." -p avatar.png -''' - -picture = None -message = "" -port = 8000 -directory = os.curdir -must_save_options = False - -# -- HTML templates - -style = '''''' - -userinfo = ''' - - - -
%(htmlpicture)s %(message)s
- ''' - -maintmpl = '''%(maintitle)s -''' + style + ''' - -%(linkurl)s -
-
-
-
- - -
-
-
%(sending)s   - -
-
-
-
-''' + userinfo + ''' -
-''' - -successtmpl = ''' - - %(successtitle)s -''' + style + ''' - - -
-
- %(received)s - %(another)s -
-''' + userinfo + ''' -
- - -''' - -errortmpl = ''' - - %(errortitle)s -''' + style + ''' - - -
-
- %(problem)s - %(retry)s -
-''' + userinfo + ''' -
- - -''' - -linkurltmpl = '''''' - - -templates = {"main": maintmpl, "success": successtmpl, "error": errortmpl} - -# -- Translations - -ar = {"maintitle": u"إرسال ملف", - "submit": u"إرسال", - "sending": u"الملف قيد الإرسال", - "successtitle": u"تم استقبال الملف", - "received": u"تم استقبال الملف !", - "another": u"إرسال ملف آخر", - "errortitle": u"مشكلة", - "problem": u"حدثت مشكلة !", - "retry": u"إعادة المحاولة", - "discover": u"اكتشاف عنوان هذه الصفحة"} - -cs = {"maintitle": u"Poslat soubor", - "submit": u"Poslat", - "sending": u"Posílám", - "successtitle": u"Soubor doručen", - "received": u"Soubor doručen !", - "another": u"Poslat další soubor", - "errortitle": u"Chyba", - "problem": u"Stala se chyba !", - "retry": u"Zkusit znova.", - "discover": u"Zjistit adresu stránky"} - -da = {"maintitle": u"Send en fil", - "submit": u"Send", - "sending": u"Sender", - "successtitle": u"Fil modtaget", - "received": u"Fil modtaget!", - "another": u"Send en fil til.", - "errortitle": u"Problem", - "problem": u"Det er opstÃ¥et en fejl!", - "retry": u"Forsøg igen.", - "discover": u"Find adressen til denne side"} - -de = {"maintitle": "Datei senden", - "submit": "Senden", - "sending": "Sendet", - "successtitle": "Datei empfangen", - "received": "Datei empfangen!", - "another": "Weitere Datei senden", - "errortitle": "Fehler", - "problem": "Ein Fehler ist aufgetreten!", - "retry": "Wiederholen", - "discover": "Internet-Adresse dieser Seite feststellen"} - -el = {"maintitle": u"Στείλε ένα αρχείο", - "submit": u"Αποστολή", - "sending": u"Αποστέλλεται...", - "successtitle": u"Επιτυχής λήψη αρχείου ", - "received": u"Λήψη αρχείου ολοκληρώθηκε", - "another": u"Στείλε άλλο ένα αρχείο", - "errortitle": u"Σφάλμα", - "problem": u"Παρουσιάστηκε σφάλμα", - "retry": u"Επανάληψη", - "discover": u"Βρες την διεύθυνση της σελίδας"} - -en = {"maintitle": "Send a file", - "submit": "Send", - "sending": "Sending", - "successtitle": "File received", - "received": "File received !", - "another": "Send another file.", - "errortitle": "Problem", - "problem": "There has been a problem !", - "retry": "Retry.", - "discover": "Discover the address of this page"} - -es = {"maintitle": u"Enviar un archivo", - "submit": u"Enviar", - "sending": u"Enviando", - "successtitle": u"Archivo recibido", - "received": u"¡Archivo recibido!", - "another": u"Enviar otro archivo.", - "errortitle": u"Error", - "problem": u"¡Hubo un problema!", - "retry": u"Reintentar", - "discover": u"Descubrir la dirección de esta página"} - -fi = {"maintitle": u"Lähetä tiedosto", - "submit": u"Lähetä", - "sending": u"Lähettää", - "successtitle": u"Tiedosto vastaanotettu", - "received": u"Tiedosto vastaanotettu!", - "another": u"Lähetä toinen tiedosto.", - "errortitle": u"Virhe", - "problem": u"Virhe lahetettäessä tiedostoa!", - "retry": u"Uudelleen.", - "discover": u"Näytä tämän sivun osoite"} - -fr = {"maintitle": u"Envoyer un fichier", - "submit": u"Envoyer", - "sending": u"Envoi en cours", - "successtitle": u"Fichier reçu", - "received": u"Fichier reçu !", - "another": u"Envoyer un autre fichier.", - "errortitle": u"Problème", - "problem": u"Il y a eu un problème !", - "retry": u"Réessayer.", - "discover": u"Découvrir l'adresse de cette page"} - -gl = {"maintitle": u"Enviar un ficheiro", - "submit": u"Enviar", - "sending": u"Enviando", - "successtitle": u"Ficheiro recibido", - "received": u"Ficheiro recibido!", - "another": u"Enviar outro ficheiro.", - "errortitle": u"Erro", - "problem": u"Xurdíu un problema!", - "retry": u"Reintentar", - "discover": u"Descubrir o enderezo desta páxina"} - -hu = {"maintitle": u"Állomány küldése", - "submit": u"Küldés", - "sending": u"Küldés folyamatban", - "successtitle": u"Az állomány beérkezett", - "received": u"Az állomány beérkezett!", - "another": u"További állományok küldése", - "errortitle": u"Hiba", - "problem": u"Egy hiba lépett fel!", - "retry": u"Megismételni", - "discover": u"Az oldal Internet-címének megállapítása"} - -id = {"maintitle": "Kirim sebuah berkas", - "submit": "Kirim", - "sending": "Mengirim", - "successtitle": "Berkas diterima", - "received": "Berkas diterima!", - "another": "Kirim berkas yang lain.", - "errortitle": "Permasalahan", - "problem": "Telah ditemukan sebuah kesalahan!", - "retry": "Coba kembali.", - "discover": "Kenali alamat IP dari halaman ini"} - -it = {"maintitle": u"Invia un file", - "submit": u"Invia", - "sending": u"Invio in corso", - "successtitle": u"File ricevuto", - "received": u"File ricevuto!", - "another": u"Invia un altro file.", - "errortitle": u"Errore", - "problem": u"Si è verificato un errore!", - "retry": u"Riprova.", - "discover": u"Scopri l’indirizzo di questa pagina"} - -ja = {"maintitle": u"ファイル送信", - "submit": u"送信", - "sending": u"送信中", - "successtitle": u"受信完了", - "received": u"ファイルを受信しました!", - "another": u"他のファイルを送信する", - "errortitle": u"問題発生", - "problem": u"問題が発生しました!", - "retry": u"リトライ", - "discover": u"このページのアドレスを確認する"} - -ko = {"maintitle": u"파일 보내기", - "submit": u"보내기", - "sending": u"보내는 중", - "successtitle": u"파일이 받아졌습니다", - "received": u"파일이 받아졌습니다!", - "another": u"다른 파일 보내기", - "errortitle": u"ë¬¸ì œê°€ 발생했습니다", - "problem": u"ë¬¸ì œê°€ 발생했습니다!", - "retry": u"다시 시도", - "discover": u"이 페이지 주소 알아보기"} - -nl = {"maintitle": "Verstuur een bestand", - "submit": "Verstuur", - "sending": "Bezig met versturen", - "successtitle": "Bestand ontvangen", - "received": "Bestand ontvangen!", - "another": "Verstuur nog een bestand.", - "errortitle": "Fout", - "problem": "Er is een fout opgetreden!", - "retry": "Nog eens.", - "discover": "Vind het adres van deze pagina"} - -no = {"maintitle": u"Send en fil", - "submit": u"Send", - "sending": u"Sender", - "successtitle": u"Fil mottatt", - "received": u"Fil mottatt !", - "another": u"Send en ny fil.", - "errortitle": u"Feil", - "problem": u"Det har skjedd en feil !", - "retry": u"Send pÃ¥ nytt.", - "discover": u"Finn addressen til denne siden"} - -pt = {"maintitle": u"Enviar um ficheiro", - "submit": u"Enviar", - "sending": u"A enviar", - "successtitle": u"Ficheiro recebido", - "received": u"Ficheiro recebido !", - "another": u"Enviar outro ficheiro.", - "errortitle": u"Erro", - "problem": u"Ocorreu um erro !", - "retry": u"Tentar novamente.", - "discover": u"Descobrir o endereço desta página"} - -pt_br = { - "maintitle": u"Enviar um arquivo", - "submit": u"Enviar", - "sending": u"Enviando", - "successtitle": u"Arquivo recebido", - "received": u"Arquivo recebido!", - "another": u"Enviar outro arquivo.", - "errortitle": u"Erro", - "problem": u"Ocorreu um erro!", - "retry": u"Tentar novamente.", - "discover": u"Descobrir o endereço desta página"} - -ro = {"maintitle": u"Trimite un fiÅŸier", - "submit": u"Trimite", - "sending": u"Se trimite", - "successtitle": u"FiÅŸier recepÅ£ionat", - "received": u"FiÅŸier recepÅ£ionat !", - "another": u"Trimite un alt fiÅŸier.", - "errortitle": u"Problemă", - "problem": u"A intervenit o problemă !", - "retry": u"Reîncearcă.", - "discover": u"Descoperă adresa acestei pagini"} - -ru = {"maintitle": u"Отправить файл", - "submit": u"Отправить", - "sending": u"Отправляю", - "successtitle": u"Файл получен", - "received": u"Файл получен !", - "another": u"Отправить другой файл.", - "errortitle": u"Ошибка", - "problem": u"Произошла ошибка !", - "retry": u"Повторить.", - "discover": u"Посмотреть адрес этой страницы"} - -sk = {"maintitle": u"PoÅ¡li súbor", - "submit": u"PoÅ¡li", - "sending": u"Posielam", - "successtitle": u"Súbor prijatý", - "received": u"Súbor prijatý !", - "another": u"PoslaÅ¥ ďalší súbor.", - "errortitle": u"Chyba", - "problem": u"Vyskytla sa chyba!", - "retry": u"SkúsiÅ¥ znova.", - "discover": u"Zisti adresu tejto stránky"} - -sl = {"maintitle": u"PoÅ¡lji datoteko", - "submit": u"PoÅ¡lji", - "sending": u"PoÅ¡iljam", - "successtitle": u"Datoteka prejeta", - "received": u"Datoteka prejeta !", - "another": u"PoÅ¡lji novo datoteko.", - "errortitle": u"Napaka", - "problem": u"PriÅ¡lo je do napake !", - "retry": u"Poizkusi ponovno.", - "discover": u"Poišči naslov na tej strani"} - -sr = {"maintitle": u"PoÅ¡alji fajl", - "submit": u"PoÅ¡alji", - "sending": u"Å aljem", - "successtitle": u"Fajl primljen", - "received": u"Fajl primljen !", - "another": u"PoÅ¡alji joÅ¡ jedan fajl.", - "errortitle": u"Problem", - "problem": u"Desio se problem !", - "retry": u"PokuÅ¡aj ponovo.", - "discover": u"Otkrij adresu ove stranice"} - -sv = {"maintitle": u"Skicka en fil", - "submit": u"Skicka", - "sending": u"Skickar...", - "successtitle": u"Fil mottagen", - "received": u"Fil mottagen !", - "another": u"Skicka en fil till.", - "errortitle": u"Fel", - "problem": u"Det har uppstÃ¥tt ett fel !", - "retry": u"Försök igen.", - "discover": u"Ta reda pÃ¥ adressen till denna sida"} - -tr = {"maintitle": u"Dosya gönder", - "submit": u"Gönder", - "sending": u"Gönderiliyor...", - "successtitle": u"Gönderildi", - "received": u"Gönderildi", - "another": u"BaÅŸka bir dosya gönder.", - "errortitle": u"Problem.", - "problem": u"Bir problem oldu !", - "retry": u"Yeniden dene.", - "discover": u"Bu sayfanın adresini bul"} - -zh_cn = { - "maintitle": u"发送文件", - "submit": u"发送", - "sending": u"发送中", - "successtitle": u"文件已收到", - "received": u"文件已收到!", - "another": u"发送另一个文件。", - "errortitle": u"问题", - "problem": u"出现问题!", - "retry": u"重试。", - "discover": u"查看本页面的地址"} - -translations = {"ar": ar, "cs": cs, "da": da, "de": de, "el": el, "en": en, - "es": es, "fi": fi, "fr": fr, "gl": gl, "hu": hu, "id": id, - "it": it, "ja": ja, "ko": ko, "nl": nl, "no": no, "pt": pt, - "pt-br": pt_br, "ro": ro, "ru": ru, "sk": sk, "sl": sl, - "sr": sr, "sv": sv, "tr": tr, "zh-cn": zh_cn} - - -class DroopyFieldStorage(cgi.FieldStorage): - """The file is created in the destination directory and its name is - stored in the tmpfilename attribute. - """ - - def make_file(self, binary=None): - fd, name = tempfile.mkstemp(dir=directory) - self.tmpfile = os.fdopen(fd, 'w+b') - self.tmpfilename = name - return self.tmpfile - - -class HTTPUploadHandler(BaseHTTPServer.BaseHTTPRequestHandler): - - form_field = 'upfile' - - def html(self, page): - """ - page can be "main", "success", or "error" - returns an html page (in the appropriate language) as a string - """ - - # -- Parse accept-language header - if not self.headers.has_key("accept-language"): - a = [] - else: - a = self.headers["accept-language"] - a = a.split(',') - a = [e.split(';q=') for e in a] - a = [(lambda x: len(x)==1 and (1, x[0]) or - (float(x[1]), x[0])) (e) for e in a] - a.sort() - a.reverse() - a = [x[1] for x in a] - # now a is an ordered list of preferred languages - - # -- Choose the appropriate translation dictionary (default is english) - lang = "en" - for l in a: - if translations.has_key(l): - lang = l - break - dico = copy.copy(translations[lang]) - - # -- Set message and picture - dico["message"] = message - if picture != None: - dico["htmlpicture"] = '
' %\ - os.path.basename(picture) - else: - dico["htmlpicture"] = "" - - # -- Add a link to discover the url - if self.client_address[0] == "127.0.0.1": - dico["port"] = self.server.server_port - dico["linkurl"] = linkurltmpl % dico - else: - dico["linkurl"] = "" - - return templates[page] % dico - - - def do_GET(self): - if picture != None and self.path == '/' + os.path.basename(picture): - # send the picture - self.send_response(200) - self.send_header('Content-type', mimetypes.guess_type(picture)[0]) - self.end_headers() - self.wfile.write(open(picture, 'rb').read()) - else: - # send the upload form - self.send_response(200) - self.send_header('Content-type', 'text/html; charset=utf-8') - self.end_headers() - self.wfile.write(self.html("main").encode('utf-8')) - - - def do_POST(self): - # Do some browsers /really/ use multipart ? maybe Opera ? - try: - self.log_message("Started file transfer") - - # -- Set up environment for cgi.FieldStorage - env = {} - env['REQUEST_METHOD'] = self.command - if self.headers.typeheader is None: - env['CONTENT_TYPE'] = self.headers.type - else: - env['CONTENT_TYPE'] = self.headers.typeheader - - # -- Save file (numbered to avoid overwriting, ex: foo-3.png) - form = DroopyFieldStorage(fp = self.rfile, environ = env); - fileitem = form[self.form_field] - filename = self.basename(fileitem.filename).decode('utf-8') - if filename == "": - raise Exception("Empty filename") - localpath = os.path.join(directory, filename).encode('utf-8') - root, ext = os.path.splitext(localpath) - i = 1 - # race condition, but hey... - while (os.path.exists(localpath)): - localpath = "%s-%d%s" % (root, i, ext) - i = i+1 - if hasattr(fileitem, 'tmpfile'): - # DroopyFieldStorage.make_file() has been called - fileitem.tmpfile.close() - shutil.move(fileitem.tmpfilename, localpath) - else: - # no temporary file, self.file is a StringIO() - # see cgi.FieldStorage.read_lines() - fout = file(localpath, 'wb') - shutil.copyfileobj(fileitem.file, fout) - fout.close() - self.log_message("Received: %s", os.path.basename(localpath)) - - # -- Reply - self.send_response(200) - self.send_header('Content-type','text/html; charset=utf-8') - self.end_headers() - self.wfile.write(self.html("success").encode('utf-8')) - - except Exception, e: - self.log_message(repr(e)) - self.send_response(200) - self.send_header('Content-type','text/html; charset=utf-8') - self.end_headers() - self.wfile.write(self.html("error").encode('utf-8')) - - def basename(self, path): - """Extract the file base name (some browsers send the full file path). - """ - for mod in posixpath, macpath, ntpath: - path = mod.basename(path) - return path - - -class ThreadedHTTPServer(SocketServer.ThreadingMixIn, - BaseHTTPServer.HTTPServer): pass - -# -- Options - -def configfile(): - appname = 'droopy' - # os.name is 'posix', 'nt', 'os2', 'mac', 'ce' or 'riscos' - if os.name == 'posix': - filename = "%s/.%s" % (os.environ["HOME"], appname) - - elif os.name == 'mac': - filename = ("%s/Library/Application Support/%s" % - (os.environ["HOME"], appname)) - - elif os.name == 'nt': - filename = ("%s\%s" % (os.environ["APPDATA"], appname)) - - else: - filename = None - - return filename - - -def save_options(): - opt = [] - if message: - opt.append('--message=%s' % message.replace('\n', '\\n')) - if picture: - opt.append('--picture=%s' % picture) - if directory: - opt.append('--directory=%s' % directory) - if port: - opt.append('%d' % port) - f = open(configfile(), 'w') - f.write('\n'.join(opt).encode('utf8')) - f.close() - - -def load_options(): - try: - f = open(configfile()) - cmd = [line.strip().decode('utf8').replace('\\n', '\n') - for line in f.readlines()] - parse_args(cmd) - f.close() - return True - except IOError, e: - return False - - -def parse_args(cmd=None): - """Parse command-line arguments. - - Parse sys.argv[1:] if no argument is passed. - """ - global picture, message, port, directory, must_save_options - - if cmd == None: - cmd = sys.argv[1:] - lang, encoding = locale.getdefaultlocale() - if encoding != None: - cmd = [a.decode(encoding) for a in cmd] - - opts, args = None, None - try: - opts, args = getopt.gnu_getopt(cmd, "p:m:d:h", - ["picture=","message=", - "directory=", "help", - "save-config","delete-config"]) - except Exception, e: - print e - sys.exit(1) - - for o,a in opts: - if o in ["-p", "--picture"] : - picture = os.path.expanduser(a) - - elif o in ["-m", "--message"] : - message = a - - elif o in ['-d', '--directory']: - directory = a - - elif o in ['--save-config']: - must_save_options = True - - elif o in ['--delete-config']: - try: - filename = configfile() - os.remove(filename) - print 'Deleted ' + filename - except Exception, e: - print e - sys.exit(0) - - elif o in ['-h', '--help']: - print USAGE - sys.exit(0) - - # port number - try: - if args[0:]: - port = int(args[0]) - except ValueError: - print args[0], "is not a valid port number" - sys.exit(1) - - -# -- - -def run(): - """Run the webserver.""" - socket.setdefaulttimeout(3*60) - server_address = ('', port) - HTTPUploadHandler.protocol_version = "HTTP/1.0" - httpd = ThreadedHTTPServer(server_address, HTTPUploadHandler) - httpd.serve_forever() - - -if __name__ == '__main__': - config_found = load_options() - parse_args() - - if config_found: - print 'Configuration found in %s' % configfile() - else: - print "No configuration file found." - - if must_save_options: - save_options() - print "Options saved in %s" % configfile() - - print "Files will be uploaded to %s" % directory - try: - print "HTTP server running... Check it out at http://localhost:%d"%port - run() - except KeyboardInterrupt: - print '^C received, shutting down server' - # some threads may run until they terminate - diff --git a/upload-http-server.py b/upload-http-server.py new file mode 100755 index 0000000..3914a00 --- /dev/null +++ b/upload-http-server.py @@ -0,0 +1,423 @@ +#!/usr/bin/env python3 + +# From : https://gist.github.com/unkn0wnsyst3m/bd1d7a6f0b3588f118dff4ae1f43b4c1 + +"""Python Web Server with upload functionality and SSL. + +This module builds on BaseHTTPServer by implementing the standard GET +and HEAD requests in a fairly straightforward manner. + +For initial version, see: https://gist.github.com/UniIsland/3346170 + +Updated by midnightseer to include the ssl wrapper and command line options + +""" + + +__version__ = "1.0" +__all__ = ["PythonWebServer"] +__author__ = "bones7456,midnightseer" + +import os,sys +import posixpath +import http.server +import urllib.request, urllib.parse, urllib.error +import html +import shutil +import ssl +import mimetypes +import re +import argparse +from io import BytesIO + + + +#######key.pem goes here######## +key_pem = """-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDYe/JzvNhx/O4X +f2RHsSrUsJyTo83in7V9Vk8jhYccCPUeHQPr8n2aqtwkxA/tdTTqf61ynBAx7Ti2 +OdN5eTyzocM3Dh0zck2SwWXRTzn6x/Ui+6+utbCWA4c3ueiSS7U+GXYL4hFNWUn1 +wjeFCqH6i4WhfEn3tGvBrLextFhOc7N7SGC62WlXLXUD4Afv7LOsJ7lK9fmBv60a +d40Th5rsMDWGU+5QAlWhdcxNQ1fl6wYZ/McdoldLCYKZF0yqLfo2JPpBjgkqVhCt +lMSy67IB+pKiCi9v2syei5GKziZvvrMw/kJOSnL0dfzzVLenqOWZslXjO9JDWBZd +6ZG9iTxxAgMBAAECggEAEpZZ09wkDW11F+llN86badWcLAUFeW7TC2bstpURa7PN +L/+3xXt1k2EWM8XtxCqrF3NM9ik2LsM6elLuuGBTeOzrsP9yPGeVB4O5dUZDKSgg +ARfxFqQc/FRjOMKqmF0Nu74953lKmQSQmBxL3g1yqOtv1tSwGSeRlPh6cTSV3G5k +LRg/IhadwPsA2HwGiR6QU5TSCf9Gndw1GiAkjIzighR9DhTXgscP3grB08ex7K6e +KCebe9yJezBax8ibrrvIHACjcQ43dPGI92g/5oRRdWkOiHqcAtSPwv3TwKheG8pE +BrV+D2BGSUPntQS5t4b0EhNTlOOwLjGoDASIJjstjQKBgQD/J0DmiDjEUFMMxHuh +TVB3CUQ+P0IjCg+83uG6VexTHy4Ti7hzG7co8Do6JIj288qyfCFt16YhTf2o3vFZ +SHSS84KEJQNtIf0I2WUamHxZU48HIGhHg9kT4uDyAy/PTpS3+HFInfaTNp09pNTI +lmKkQpHytxEZoZ83GoNfpHy1rwKBgQDZM9hVjyFPvfs3i70R03ejfmUc7MwPAvSL +5rneuEOQRp3PbNmODnYXqz6UXSjx4CGP9Ajzetlv6n3oXsbYV5ptr1VfbGaN4Fus +Yvwmc5hWpXrJz2B2QWuPt4uPz9vn132cAEucEPGTJihpAZf3m+mZsLAfGi8hjGR3 +0pdG8f/X3wKBgQD7zxuH6AxOAg/UW9y/FfRBZg3JeNimh/l8JmKTaNTwO6dXdt60 +Czg52Ms+MmxRe8whVcwQAXFdEQEztcJuoMkbdeLq0zSMcaytHQ9grfial5JiMCN5 +4K9NpuzlKyv15dFztmbmia6dHpsUCSZOR8xV27T52p2vtAfTdAEPVOAW1QKBgQCD +wludq3H9ubXHgFF1mt6co3QbE9rF0Hkg1Roz7Xuu7eeViOaAsm0Y9pzDy6+m6tvx +Q4yahw+YQJuYdsYRPzNDDnWvqUadElkKPhHQEZd8GG5gNhjCI/Vn/WQAHYu9HI/q +LpOvXOfu59rjuD/DySTwQqrUc0HcDBp2RZ3XP75/6QKBgDY+G8Kg+hcpKScf2SKE +DwChKqTDBIUU6hKMbIomIHBI4tXZGuYWESe7MgypYvftOZJxlAnUzNV1Wd1baX6D +oj4850PjKhaO0TfoIVda0oLOtKQdIQX+pkFmVeJxmwTdcIqA6MvYk+WSOTbaERET +FuHTvZElIItUHjMP9TI6rC44 +-----END PRIVATE KEY-----""" + +#######crt.pem goes here######## +crt_pem = """-----BEGIN CERTIFICATE----- +MIIDazCCAlOgAwIBAgIUUoyr/cijbfsMFutoIiaBs5xS0T8wDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMDA3MTExNTExMTZaFw0zMDA3 +MDkxNTExMTZaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQDYe/JzvNhx/O4Xf2RHsSrUsJyTo83in7V9Vk8jhYcc +CPUeHQPr8n2aqtwkxA/tdTTqf61ynBAx7Ti2OdN5eTyzocM3Dh0zck2SwWXRTzn6 +x/Ui+6+utbCWA4c3ueiSS7U+GXYL4hFNWUn1wjeFCqH6i4WhfEn3tGvBrLextFhO +c7N7SGC62WlXLXUD4Afv7LOsJ7lK9fmBv60ad40Th5rsMDWGU+5QAlWhdcxNQ1fl +6wYZ/McdoldLCYKZF0yqLfo2JPpBjgkqVhCtlMSy67IB+pKiCi9v2syei5GKziZv +vrMw/kJOSnL0dfzzVLenqOWZslXjO9JDWBZd6ZG9iTxxAgMBAAGjUzBRMB0GA1Ud +DgQWBBQefIi+94KRWSiWDFnCUB3EAB3tiDAfBgNVHSMEGDAWgBQefIi+94KRWSiW +DFnCUB3EAB3tiDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCb +Hn0yRnveHwzFxxRm8Qgra0uAYxs3z6UsK7EXcrnf6pf26eKPM7KV/iI8siEaXFW4 +U1ulZ+pxKj6n6g0wFVZOamw5G5EPLkXXibixAdXCTWKOqBK5eNBPIZcsQe1ozDPk +KA1aoIOOFaec6BBaARiNxNEPebtPlFwIxAO4J3rAOYiE7hN3pBfjXlshxsTTYAnx +noTEKQfzLTGWZvRteIzuZGxfwjQvZOmRcTGwosXNzqRs4FWHKrOYhVAkZ9ijjtLR +hqETLhg4SEs82bXzqiSOTAd0R3zLZA54gPb9X0vwZQxnqR1XyQoHuzj8KsQnPeVK +fEOq7niByo0GsG8cvhHz +-----END CERTIFICATE-----""" + + +class SimpleHTTPRequestHandler(http.server.BaseHTTPRequestHandler): + + """Simple HTTP request handler with GET/HEAD/POST commands. + + This serves files from the current directory and any of its + subdirectories. The MIME type for files is determined by + calling the .guess_type() method. And can reveive file uploaded + by client. + + The GET/HEAD/POST requests are identical except that the HEAD + request omits the actual contents of the file. + + """ + + server_version = "SimpleHTTPWithUpload/" + __version__ + + def do_GET(self): + """Serve a GET request.""" + f = self.send_head() + if f: + self.copyfile(f, self.wfile) + f.close() + + def do_HEAD(self): + """Serve a HEAD request.""" + f = self.send_head() + if f: + f.close() + + def do_POST(self): + """Serve a POST request.""" + self.request.settimeout(10000) + r, info = self.deal_post_data() + print("[+] File Uploaded! {} --> {}".format(info, self.client_address)) + f = BytesIO() + f.write(b'') + f.write(b"\nUpload Result Page\n") + f.write(b"\n

Upload Result Page

\n") + f.write(b"
\n") + if r: + f.write(b"Success:") + else: + f.write(b"Failed:") + f.write(info.encode()) + f.write(("
back" % self.headers['referer']).encode()) + f.write(b"\n\n") + length = f.tell() + f.seek(0) + self.send_response(200) + self.send_header("Content-type", "text/html") + self.send_header("Content-Length", str(length)) + self.end_headers() + if f: + self.copyfile(f, self.wfile) + f.close() + + def deal_post_data(self): + content_type = self.headers['content-type'] + if not content_type: + return (False, "Content-Type header doesn't contain boundary") + boundary = content_type.split("=")[1].encode() + remainbytes = int(self.headers['content-length']) + line = self.rfile.readline() + remainbytes -= len(line) + if not boundary in line: + return (False, "Content NOT begin with boundary") + line = self.rfile.readline() + remainbytes -= len(line) + fn = re.findall(r'Content-Disposition.*name="fil.*"; filename="(.*)"', line.decode()) + if not fn: + return (False, "Unable to locate file for upload...") + path = self.translate_path(self.path) + fn = os.path.join(path, fn[0]) + line = self.rfile.readline() + remainbytes -= len(line) + line = self.rfile.readline() + remainbytes -= len(line) + try: + out = open(fn, 'wb') + except IOError: + return (False, "Can't create file to write, do you have permission to write?") + + preline = self.rfile.readline() + remainbytes -= len(preline) + while remainbytes > 0: + line = self.rfile.readline() + remainbytes -= len(line) + if boundary in line: + preline = preline[0:-1] + if preline.endswith(b'\r'): + preline = preline[0:-1] + out.write(preline) + out.close() + return (True, "File '%s' upload success!" % fn) + else: + out.write(preline) + preline = line + return (False, "Unexpect end of data.") + + def send_head(self): + """Common code for GET and HEAD commands. + + This sends the response code and MIME headers. + + Return value is either a file object (which has to be copied + to the outputfile by the caller unless the command was HEAD, + and must be closed by the caller under all circumstances), or + None, in which case the caller has nothing further to do. + + """ + path = self.translate_path(self.path) + f = None + if os.path.isdir(path): + if not self.path.endswith('/'): + # redirect browser - doing basically what apache does + self.send_response(301) + self.send_header("Location", self.path + "/") + self.end_headers() + return None + for index in "index.html", "index.htm": + index = os.path.join(path, index) + if os.path.exists(index): + path = index + break + else: + return self.list_directory(path) + ctype = self.guess_type(path) + try: + # Always read in binary mode. Opening files in text mode may cause + # newline translations, making the actual size of the content + # transmitted *less* than the content-length! + f = open(path, 'rb') + except IOError: + self.send_error(404, "File not found") + return None + self.send_response(200) + self.send_header("Content-type", ctype) + fs = os.fstat(f.fileno()) + self.send_header("Content-Length", str(fs[6])) + self.send_header("Last-Modified", self.date_time_string(fs.st_mtime)) + self.end_headers() + return f + + def list_directory(self, path): + """Helper to produce a directory listing (absent index.html). + + Return value is either a file object, or None (indicating an + error). In either case, the headers are sent, making the + interface the same as for send_head(). + + """ + try: + list = os.listdir(path) + except os.error: + self.send_error(404, "No permission to list directory") + return None + list.sort(key=lambda a: a.lower()) + f = BytesIO() + displaypath = html.escape(urllib.parse.unquote(self.path)) + f.write(b'') + f.write(("\nDirectory listing for %s\n" % displaypath).encode()) + f.write(("\n

Directory listing for %s

\n" % displaypath).encode()) + f.write(b"
\n") + f.write(b"
") + f.write(b"") + f.write(b"
\n") + f.write(b"
\n\n
\n\n\n") + length = f.tell() + f.seek(0) + self.send_response(200) + self.send_header("Content-type", "text/html") + self.send_header("Content-Length", str(length)) + self.end_headers() + return f + + def translate_path(self, path): + """Translate a /-separated PATH to the local filename syntax. + + Components that mean special things to the local file system + (e.g. drive or directory names) are ignored. (XXX They should + probably be diagnosed.) + + """ + # abandon query parameters + path = path.split('?',1)[0] + path = path.split('#',1)[0] + path = posixpath.normpath(urllib.parse.unquote(path)) + words = path.split('/') + words = [_f for _f in words if _f] + path = os.getcwd() + for word in words: + drive, word = os.path.splitdrive(word) + head, word = os.path.split(word) + if word in (os.curdir, os.pardir): continue + path = os.path.join(path, word) + return path + + def copyfile(self, source, outputfile): + """Copy all data between two file objects. + + The SOURCE argument is a file object open for reading + (or anything with a read() method) and the DESTINATION + argument is a file object open for writing (or + anything with a write() method). + + The only reason for overriding this would be to change + the block size or perhaps to replace newlines by CRLF + -- note however that this the default server uses this + to copy binary data as well. + + """ + shutil.copyfileobj(source, outputfile) + + def guess_type(self, path): + """Guess the type of a file. + + Argument is a PATH (a filename). + + Return value is a string of the form type/subtype, + usable for a MIME Content-type header. + + The default implementation looks the file's extension + up in the table self.extensions_map, using application/octet-stream + as a default; however it would be permissible (if + slow) to look inside the data to make a better guess. + + """ + + base, ext = posixpath.splitext(path) + if ext in self.extensions_map: + return self.extensions_map[ext] + ext = ext.lower() + if ext in self.extensions_map: + return self.extensions_map[ext] + else: + return self.extensions_map[''] + + if not mimetypes.inited: + mimetypes.init() # try to read system mime.types + extensions_map = mimetypes.types_map.copy() + extensions_map.update({ + '': 'application/octet-stream', # Default + '.py': 'text/plain', + '.c': 'text/plain', + '.h': 'text/plain', + }) + +def ssl_prep(): + + try: + with open("key.pem",'w') as file: + file.write(key_pem) + except: + print("Unable to create key.pem") + print(sys.exc_info()) + + try: + with open("crt.pem",'w') as file: + file.write(crt_pem) + except: + print("Unable to create crt.pem") + print(sys.exc_info()) + +def ssl_cleanup(): + try: + os.remove("key.pem") + except FileNotFoundError: + print("Unable to Delete key.pem") + try: + os.remove("crt.pem") + except FileNotFoundError: + print("Unable to Delete crt.pem") + +def test(PORT, HandlerClass = SimpleHTTPRequestHandler, ServerClass = http.server.HTTPServer): + + http.server.test(HandlerClass, ServerClass,port=PORT) + +if __name__ == '__main__': + p = argparse.ArgumentParser(description='A Better Python3 HTTP Server') + p.add_argument('-p', '--port', type=int, default=8000, dest="port", action="store", help="the port for the http service to listen on") + p.add_argument('-l', '--listen', type=str, default="0.0.0.0", dest="listen", action="store", help="the interface to bind to") + p.add_argument('-n', '--no-ssl', action="store_true", default=False, dest="nossl", help="do not serve https / ssl") + args = p.parse_args() + + try: + if args.nossl: + test(args.port, SimpleHTTPRequestHandler, http.server.HTTPServer) + else: + ssl_prep() + httpd = http.server.HTTPServer((args.listen, args.port), SimpleHTTPRequestHandler) + httpd.socket = ssl.wrap_socket (httpd.socket, keyfile='key.pem', certfile='crt.pem', server_side=True) + print("Serving HTTPS on {l} port {p} (https://{l}:{p}/) ...".format(l=args.listen, p=args.port)) + httpd.serve_forever() + + except KeyboardInterrupt: + print("^punch!") + finally: + try: + if args.nossl: + pass + else: + ssl_cleanup() + except: + pass + +####TO UPLOAD#### +# get(){ +# file=$1 +# ip="10.10.14.8" +# port="8080" +# #echo $file $ip $port +# output=$(curl -k -i -X POST -F filename=@"$file" -F name=file "http://$ip:$port") +# if [[ "$output" == *"success"* ]]; then + # echo "[+] Uploaded! --> $file" +# else + # echo "[-] Upload Failed! --> $file $ip:$port" +# fi +# } + +# get + +