I am trying to get a simple http server going, using the directory in my code below as the root. This is using Python 3.5.1 Shell:
>>> import os
>>> import http.server
>>> import socketserver
>>> os.chdir('c:/users/owner/desktop/tom/tomsEnyo2.5-May27')
>>> python -m http.server 8000
SyntaxError: invalid syntax
>>> python -m SimpleHTTPServer 8000
SyntaxError: invalid syntax
>>>
I have looked at a similar topic: How to set up simple HTTP server in Python 3.5 on Windows 10? , but even when I try doing what the answer suggests, I still have the same problem ('invalid syntax').
You're confusing Python commands and shells command.
import os etc are Python statements (interpreted by Python), python -m http.server 8000 is a shell statement, interpreted by bash, sh or whatever Microsoft use for Windows. You may try something like this to run it in the Python REPL:
import os
from http.server import SimpleHTTPRequestHandler, HTTPServer
os.chdir('c:/users/owner/desktop/tom/tomsEnyo2.5-May27')
server_address = ('', 8000)
httpd = HTTPServer(server_address, SimpleHTTPRequestHandler)
httpd.serve_forever()
But the easiest way to do is probably to just run python -m http.server 8000 while being in the right directory in your terminal emulator. Note, on recent versions of Python, the http.server module also accept a --directory or -d option to specify the directory to serve.
The problem is that the python -m command is not a python command itself but should be used in the shell ;)
You can use instead:
import http.server
def start_server(port=8000, bind="", cgi=False):
if cgi==True:
http.server.test(HandlerClass=http.server.CGIHTTPRequestHandler, port=port, bind=bind)
else:
http.server.test(HandlerClass=http.server.SimpleHTTPRequestHandler,port=port,bind=bind)
start_server() #If you want cgi, set cgi to True e.g. start_server(cgi=True)
Or, you can also do:
import http.server
import socketserver
PORT = 8000
Handler = http.server.SimpleHTTPRequestHandler
httpd = socketserver.TCPServer(("", PORT), Handler)
print("serving at port", PORT)
httpd.serve_forever()
The idea itself of running a Web server into the Python shell is wrong as a server is a system-level process supposed to run forever. You can try to run it using the subprocess library maybe?
Furthermore, you cannot run python executable into the shell. Once you run the shell, you need to type code line by line, not OS executables.
If you wanto to start a server, you need instead to run the python executable from a directory in your OS command-line, using SimpleServer class; that directory will be served through the Web server.
import socket
import sys
try:
HOST = 'Your_ip'
PORT = 80
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1)
s.bind((HOST, PORT))
s.listen(10)
print '[*]Running HTTP on port %s..'%PORT
while 1:
conn, addr = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
data = ""
while 1:
request = conn.recv(8000)
data += request
if len(data) == 24:
print data
req_list = data.split(' ')
method = req_list[0]
req_file = req_list[1]
print 'The Requested file from client: ', req_file
fileid = req_file.split('?')[0]
fileid = fileid.lstrip('/')
print fileid
if(fileid == 'index.html'): #verifies index.html
file = open(fileid,'rb')
response = file.read()
file.close()
header ='HTTP/1.1 200 OK\n'
mimetype = 'text/html'
header += 'Content-Type: '+str(mimetype)+'\n\n'
else:
header = 'HTTP/1.1 404 Not Found\n\n'
response = '<html><body><h3>Error 404: File not found</h3></body></html>'
final_response = header.encode('utf-8')
final_response += response
conn.send(final_response)
else:
continue
conn.close()
except KeyboardInterrupt as msg:
sys.exit(0)
An HTTP server(equivalent implementation in Linux) listens on port 80, and can be customized to listen on all different ports. This server parses the GET request and send successful response if index.html file is present, and its unsuccessful if client tries to access other .html file. Alternative to one liner bash web server
Related
Creating a python syslog server for my network devices I am using the below code that comes from here https://gist.githubusercontent.com/marcelom/4218010/raw/53b643bd056d03ffc21abcfe2e1b9f6a7de005f0/pysyslog.py
This will meet my needs but I cannot seem to get any python version of sysloghandler to run. I see this is old code about 5 years or so.
I am running ubuntu 16.04 system. Everything seems to hang on the try: for initiating the server.
#!/usr/bin/env python
## Tiny Syslog Server in Python.
##
## This is a tiny syslog server that is able to receive UDP based syslog
## entries on a specified port and save them to a file.
## That's it... it does nothing else...
## There are a few configuration parameters.
LOG_FILE = 'youlogfile.log'
HOST, PORT = "0.0.0.0", 514
#
# NO USER SERVICEABLE PARTS BELOW HERE...
#
import logging
import SocketServer
logging.basicConfig(level=logging.INFO, format='%(message)s', datefmt='', filename=LOG_FILE, filemode='a')
class SyslogUDPHandler(SocketServer.BaseRequestHandler):
def handle(self):
data = bytes.decode(self.request[0].strip())
socket = self.request[1]
print( "%s : " % self.client_address[0], str(data))
logging.info(str(data))
if __name__ == "__main__":
try:
server = SocketServer.UDPServer((HOST,PORT), SyslogUDPHandler)
server.serve_forever(poll_interval=0.5)
except (IOError, SystemExit):
raise
except KeyboardInterrupt:
print ("Crtl+C Pressed. Shutting down.")
Your code works for me. If I start the server like this:
sudo python server.py
And then send a message like this:
echo this is a test | nc -u localhost 514
I see output on stdout:
('127.0.0.1 : ', 'this is a test')
And the file youlogfile.log contains:
this is a test
I suspect your problems stem from trying to use a TCP tool to connect to a UDP server.
For educational purposes, I set up a server that allows remote command execution on Windows - or rather, I tried to. For some reason, the command line refuses to recognize some of the commands I send, but others work fine. For instance, sending the command echo "Hello World!!!" causes, as it should, a cmd window to pop up reading "Hello World!!!". Fine. But when I send the command shutdown /s /t 30 it gives me the improper syntax / help screen for the shutdown command. When I send the command msg * "Hello World" it tells me that 'msg' is not a recognized internal or external command, operable program, or batch file. Here is my server code:
import socket
import sys
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_address = ('', 4242)
sock.bind(server_address)
sock.listen(1)
connection, client_address = sock.accept()
print("Connection established with %s " % str(client_address))
while True:
command = input("Enter a command: ")
connection.send(bytes(command, 'UTF-8'))
confirm = connection.recv(128)
if confirm == "yes":
print("[+] Command executed successfully.")
else:
print("[-] Command failed to execute!!!")
And here is my client code:
import socket
import sys
import os
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_address = ('', 42042)
sock.bind(server_address)
sock.connect(('192.168.1.5', 4242))
while True:
command = str(sock.recv(1024))
try:
os.system(command[2:]) # an odd thing, the commands somehow came out prefaced with "b'". Ideas?
sock.send(bytes("yes", 'UTF-8'))
except:
sock.send(bytes("no", 'UTF-8'))
So yeah, that's that. The fact that only SOME commands are getting screwed up is really confusing me. Anybody have any ideas? Also, what's up with that "b'"?
str(sock.recv(1024)) is not the way to convert a bytes object into a string, you should be using the sock.recv(1024).decode('UTF-8') method
You can look at the documentation for bytes.decode https://docs.python.org/3.4/library/stdtypes.html#bytes.decode
Or this related question Best way to convert string to bytes in Python 3?
I am attempting to create an easy solution to file sharing across computers in my local network. I used to execute python -m SimpleHTTPServer in bash whenever I wanted to share a directory, but I wanted a way to share only one specific file. Can anyone point me in the right direction for how I might create a web server, and then have it download a file for each GET request. For example, someone on my network could go to my IP and have the file download.
P.S. What would be even cooler is if there was a way to password protect a file! Also, I have Python 2.7.2, if that matters. Anyway, As you have probably noticed, I know almost nothing about Python, but I learn by example so I am hoping this will help me some as well.
Thanks a bunch in advance!
Try following:
try:
import http.server as BaseHTTPServer # Python 3.x
except ImportError:
import BaseHTTPServer # Python 2.x
import os
import shutil
import sys
FILEPATH = sys.argv[1] if sys.argv[1:] else __file__
class SimpleHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_GET(self):
with open(FILEPATH, 'rb') as f:
self.send_response(200)
self.send_header("Content-Type", 'application/octet-stream')
self.send_header("Content-Disposition", 'attachment; filename="{}"'.format(os.path.basename(FILEPATH)))
fs = os.fstat(f.fileno())
self.send_header("Content-Length", str(fs.st_size))
self.end_headers()
shutil.copyfileobj(f, self.wfile)
def test(HandlerClass=SimpleHTTPRequestHandler,
ServerClass=BaseHTTPServer.HTTPServer,
protocol="HTTP/1.0"):
if sys.argv[2:]:
port = int(sys.argv[2])
else:
port = 8000
server_address = ('', port)
HandlerClass.protocol_version = protocol
httpd = BaseHTTPServer.HTTPServer(server_address, HandlerClass)
sa = httpd.socket.getsockname()
print("Serving HTTP on {0[0]} port {0[1]} ... {1}".format(sa, FILEPATH))
httpd.serve_forever()
if __name__ == '__main__':
test()
Usage: python script_path [filepath_to_serve [port]]
UPDATE code works for Python 2.x / 3.x
I just encountered a weird issue about bottle on windows.
When I tested the my bottle codes, I found that it could run multiple same programs on WINDOWS using same address and port. But when you try to start multiple same program on the Linux or Mac using same address and port, it will report the below error:
socket.error: [Errno 48] Address already in use
my bottle codes are:
from bottle import route, run, template
#route('/hello/:name')
def index(name='World'):
return template('<b>Hello {{name}} </b>', name=name)
run(host='localhost', port=9999)
Then I traced the code, from bottle to wsgiref, and finnaly found that the problem might be in the Python27\Lib\BaseHTTPServer.py.
I mean when I use the the below simple codes:
import BaseHTTPServer
def run(server_class=BaseHTTPServer.HTTPServer,
handler_class=BaseHTTPServer.BaseHTTPRequestHandler):
server_address = ('localhost', 9999)
print "start server on localhost 9999"
httpd = server_class(server_address, handler_class)
httpd.serve_forever()
run()
The same issue would happen on windows.
But if I directly used the socketserver, like the below codes:
import SocketServer
class MyTCPHandler(SocketServer.BaseRequestHandler):
def handle(self):
# self.request is the TCP socket connected to the client
self.data = self.request.recv(1024).strip()
print "{} wrote:".format(self.client_address[0])
print self.data
# just send back the same data, but upper-cased
self.request.sendall(self.data.upper())
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
print "Start a server on localhost:9999"
# Create the server, binding to localhost on port 9999
server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
# Activate the server; this will keep running until you
# interrupt the program with Ctrl-C
server.serve_forever()
The same issue will not happen, I mean even on window the above socketserver codes will report the error, when you try to start another programe.
socket.error: [Errno 48] Address already in use
All my tests used the Python 2.7, Windows 7 and Centos 5.
So my questions are why the HTTPServer will have this issue on windows?
And how can I let my bottle programe will report the same error on windows, just like on windows?
Sorry to bother all.
I've found the resolution, just so simple.
Simply change the BaseHTTPServer.HTTPServer's attribute allow_reuse_address to 0.
The codes should be:
from bottle import route, run, template
import BaseHTTPServer
#route('/hello/:name')
def index(name='World'):
return template('<b>Hello {{name}} </b>', name=name)
setattr(BaseHTTPServer.HTTPServer,'allow_reuse_address',0)
run(host='localhost', port=9999)
I want to know is there a way to send a multiline command to maya through python socket and the Maya's own "commandPort" command?
I'm using below code for sending the code to maya("message" value is the command):
import socket
#HOST = '192.168.1.122' # The remote host
HOST = '127.0.0.1' # the local host
PORT = 54321 # The same port as used by the server
ADDR=(HOST,PORT)
def SendCommand():
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(ADDR)
command = 'import maya.cmds as mc mc.polyCube()' # the commang from external editor to maya
MyMessage = command
client.send(MyMessage)
data = client.recv(1024) #receive the result info
client.close()
print 'The Result is %s'%data
if __name__=='__main__':
SendCommand()
When I send a single command like 'polyCube()' it works but for example sending a python
Command such as:
import maya.cmds as mc
mc.polyCube()
Raises an "invalid syntax error"!
Try:
command = 'import maya.cmds as mc\n mc.polyCube()'
For sending small commands to Maya, #pajton's method works, or you can use ; as a separator:
command = "import maya.cmds as mc; mc.polyCube()"
If possible, the easiest way to send many lines at once is to create a separate .py file that Maya has access to.
command = "import sys; sys.append(r'c:\path to my_script');"
command += "import my_script; my_script.run()"