New python webserver script for upload
This commit is contained in:
parent
abaea3bc35
commit
daada7a1db
787
droopy
787
droopy
|
@ -1,787 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Droopy (http://stackp.online.fr/droopy)
|
||||
# Copyright 2008 (C) Pierre Duquesne <stackp@online.fr>
|
||||
# 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 = '''<style type="text/css">
|
||||
<!--
|
||||
body {margin: 0; border: 0; padding: 0px; background-color: #fafafa;
|
||||
text-align: center; font-size: 0.9em; font-family: sans-serif;
|
||||
padding-top: 20px;}
|
||||
#wrap {width: 500px; padding: 0px; margin: auto;
|
||||
border: 1px dashed #ccc; background-color: white;}
|
||||
#wrapform {height: 75px; padding: 50px 20px 0px 20px; text-align: center;
|
||||
margin: 0; border: 0; border-bottom: 1px dashed #ccc;}
|
||||
#form {}
|
||||
#sending {display: none;}
|
||||
#progress {display: inline; border-collapse: separate; empty-cells: show;
|
||||
border-spacing: 6px 0; padding: 0; vertical-align: bottom;}
|
||||
#progress td {height: 15px; width: 13px; background-color: #eee;
|
||||
border: 1px solid #666; padding: 0px;}
|
||||
#userinfo {border-collapse: collapse; padding:0px}
|
||||
#userinfo td {border-collapse: collapse; cell-spacing: 0px; vertical-align:top}
|
||||
#picture {margin: 0; padding: 20px; border: 0;}
|
||||
#message {margin: 0; padding: 20px; font-family: monospace; font-size: 1.2em;
|
||||
width: 100%%;}
|
||||
#linkurl {font-size: 0.8em; text-align: center; padding: 5px; float: right;
|
||||
background-color: orange; margin-top: 13px; width: 100%%;}
|
||||
#linkurl a {color: white; font-weight: bold; text-decoration: none;}
|
||||
#linkurl a:hover {text-decoration: underline;}
|
||||
--></style>'''
|
||||
|
||||
userinfo = '''
|
||||
<table id="userinfo"><tr>
|
||||
<td>%(htmlpicture)s</td>
|
||||
<td id="message"> %(message)s </td>
|
||||
</tr></table>
|
||||
'''
|
||||
|
||||
maintmpl = '''<html><head><title>%(maintitle)s</title>
|
||||
''' + style + '''
|
||||
<script language="JavaScript">
|
||||
function swap() {
|
||||
document.getElementById("form").style.display = "none";
|
||||
document.getElementById("sending").style.display = "block";
|
||||
update();
|
||||
}
|
||||
ncell = 4;
|
||||
curcell = 0;
|
||||
function update() {
|
||||
setTimeout(update, 300);
|
||||
e = document.getElementById("cell"+curcell);
|
||||
e.style.backgroundColor = "#eee";
|
||||
curcell = (curcell+1) %% ncell
|
||||
e = document.getElementById("cell"+curcell);
|
||||
e.style.backgroundColor = "#aaa";
|
||||
}
|
||||
function onunload() {
|
||||
document.getElementById("form").style.display = "block";
|
||||
document.getElementById("sending").style.display = "none";
|
||||
}
|
||||
</script></head><body>
|
||||
%(linkurl)s
|
||||
<div id="wrap">
|
||||
<div id="wrapform">
|
||||
<div id="form">
|
||||
<form method="post" enctype="multipart/form-data" action="">
|
||||
<input name="upfile" type="file">
|
||||
<input value="%(submit)s" onclick="swap()" type="submit">
|
||||
</form>
|
||||
</div>
|
||||
<div id="sending"> %(sending)s
|
||||
<table id="progress"><tr>
|
||||
<td id="cell0"/><td id="cell1"/><td id="cell2"/><td id="cell3"/>
|
||||
</tr></table>
|
||||
</div>
|
||||
</div>
|
||||
''' + userinfo + '''
|
||||
</div></body></html>
|
||||
'''
|
||||
|
||||
successtmpl = '''
|
||||
<html>
|
||||
<head><title> %(successtitle)s </title>
|
||||
''' + style + '''
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrap">
|
||||
<div id="wrapform">
|
||||
%(received)s
|
||||
<a href="/"> %(another)s </a>
|
||||
</div>
|
||||
''' + userinfo + '''
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
'''
|
||||
|
||||
errortmpl = '''
|
||||
<html>
|
||||
<head><title> %(errortitle)s </title>
|
||||
''' + style + '''
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrap">
|
||||
<div id="wrapform">
|
||||
%(problem)s
|
||||
<a href="/"> %(retry)s </a>
|
||||
</div>
|
||||
''' + userinfo + '''
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
'''
|
||||
|
||||
linkurltmpl = '''<div id="linkurl">
|
||||
<a href="http://stackp.online.fr/droopy-ip.php?port=%(port)d"> %(discover)s
|
||||
</a></div>'''
|
||||
|
||||
|
||||
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"] = '<div id="picture"><img src="/%s"/></div>' %\
|
||||
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
|
||||
|
|
@ -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'<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">')
|
||||
f.write(b"<html>\n<title>Upload Result Page</title>\n")
|
||||
f.write(b"<body>\n<h2>Upload Result Page</h2>\n")
|
||||
f.write(b"<hr>\n")
|
||||
if r:
|
||||
f.write(b"<strong>Success:</strong>")
|
||||
else:
|
||||
f.write(b"<strong>Failed:</strong>")
|
||||
f.write(info.encode())
|
||||
f.write(("<br><a href=\"%s\">back</a>" % self.headers['referer']).encode())
|
||||
f.write(b"</body>\n</html>\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'<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">')
|
||||
f.write(("<html>\n<title>Directory listing for %s</title>\n" % displaypath).encode())
|
||||
f.write(("<body>\n<h2>Directory listing for %s</h2>\n" % displaypath).encode())
|
||||
f.write(b"<hr>\n")
|
||||
f.write(b"<form ENCTYPE=\"multipart/form-data\" method=\"post\">")
|
||||
f.write(b"<input name=\"file\" type=\"file\"/>")
|
||||
f.write(b"<input type=\"submit\" value=\"upload\"/></form>\n")
|
||||
f.write(b"<hr>\n<ul>\n")
|
||||
for name in list:
|
||||
fullname = os.path.join(path, name)
|
||||
displayname = linkname = name
|
||||
# Append / for directories or @ for symbolic links
|
||||
if os.path.isdir(fullname):
|
||||
displayname = name + "/"
|
||||
linkname = name + "/"
|
||||
if os.path.islink(fullname):
|
||||
displayname = name + "@"
|
||||
# Note: a link to a directory displays with @ and links with /
|
||||
f.write(('<li><a href="%s">%s</a>\n'
|
||||
% (urllib.parse.quote(linkname), html.escape(displayname))).encode())
|
||||
f.write(b"</ul>\n<hr>\n</body>\n</html>\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 <file>
|
||||
|
||||
|
Loading…
Reference in New Issue