serve current directory from command line
Simplest way possible (thanks Aaron Patterson/n0kada):
ruby -run -e httpd . -p 9090
Alternate, more complex way:
ruby -r webrick -e "s = WEBrick::HTTPServer.new(:Port => 9090, :DocumentRoot => Dir.pwd); trap('INT') { s.shutdown }; s.start"
Even the first command is hard to remember, so I just have this in my .bashrc
:
function serve {
port="${1:-3000}"
ruby -run -e httpd . -p $port
}
It serves the current directory on port 3000 by default, but you can also specify the port:
~ $ cd tmp
~/tmp $ serve # ~/tmp served on port 3000
~/tmp $ cd ../www
~/www $ serve 5000 # ~/www served on port 5000
Set the current directory when running a SimpleHTTPServer
If you're using SimpleHTTPServer
directly from command line, you can simply use shell features:
pushd /path/you/want/to/serve; python -m SimpleHTTPServer; popd
In Python 3 you have to use:
pushd /path/you/want/to/serve; python -m http.server; popd
The SimpleHTTPServer module has been merged into http.server in Python 3.0
How to start a web server in the current folder on the command line using Node or ClojureScript?
From Big list of http static server one-liners
$ npm install -g http-server # install dependency
$ http-server -p 8000
or
$ npm install -g node-static # install dependency
$ static -p 8000
Start server in current directory (php/apache)
You can start PHP development server in versions 5.4 and above with:
php -S localhost:8008
I don't think Apache supports anything similar (being itself a web server), but PHP dev server is enough for testing scripts, including serving static contents.
Simple file server to serve current directory
python3 -m http.server
or if you don't want to use the default port 8000
python3 -m http.server 3333
or if you want to allow connections from localhost only
python3 -m http.server --bind 127.0.0.1
See the docs.
The equivalent Python 2 commands are
python -m SimpleHTTPServer
python -m SimpleHTTPServer 3333
There is no --bind
option.
See the Python 2 docs.
Serve directory in Python 3
The simple way
You want to extend the functionality of SimpleHTTPRequestHandler
, so you subclass it! Check for your special condition(s), if none of them apply, call super().do_GET()
and let it do the rest.
Example:
class MyHandler(http.server.SimpleHTTPRequestHandler):
def do_GET(self):
if self.path == '/up':
self.send_response(200)
self.end_headers()
self.wfile.write(b'up')
else:
super().do_GET()
The long way
To serve files, you basically just have to open them, read the contents and send it.
To serve directories (indexes), use os.listdir()
. (If you want, you can when receiving directories first check for an index.html and then, if that fails, serve an index listing).
Putting this into your code will give you:
class MyHandler(http.server.BaseHTTPRequestHandler):
def do_GET(self):
print(self.path)
if self.path == '/up':
self.send_response(200)
self.end_headers()
self.wfile.write(b'Going up')
elif os.path.isdir(self.path):
try:
self.send_response(200)
self.end_headers()
self.wfile.write(str(os.listdir(self.path)).encode())
except Exception:
self.send_response(500)
self.end_headers()
self.wfile.write(b'error')
else:
try:
with open(self.path, 'rb') as f:
data = f.read()
self.send_response(200)
self.end_headers()
self.wfile.write(data)
except FileNotFoundError:
self.send_response(404)
self.end_headers()
self.wfile.write(b'not found')
except PermissionError:
self.send_response(403)
self.end_headers()
self.wfile.write(b'no permission')
except Exception:
self.send_response(500)
self.end_headers()
self.wfile.write(b'error')
This example has a lot of error handling. You might want to move it somewhere else.
The problem is this serves from your root directory. To stop this, you'll have to (easy way) just add the serving directory to the beginning of self.path
. Also check if ..
cause you to land higher than you want. A way to do this is os.path.abspath(serve_from+self.path).startswith(serve_from)
Putting this inside (after the check for /up):
class MyHandler(http.server.BaseHTTPRequestHandler):
def do_GET(self):
print(self.path)
path = serve_from + self.path
if self.path == '/up':
self.send_response(200)
self.end_headers()
self.wfile.write(b'Going up')
elif not os.path.abspath(path).startswith(serve_from):
self.send_response(403)
self.end_headers()
self.wfile.write(b'Private!')
elif os.path.isdir(path):
try:
self.send_response(200)
self.end_headers()
self.wfile.write(str(os.listdir(path)).encode())
except Exception:
self.send_response(500)
self.end_headers()
self.wfile.write(b'error')
else:
try:
with open(path, 'rb') as f:
data = f.read()
self.send_response(200)
self.end_headers()
self.wfile.write(data)
# error handling skipped
except Exception:
self.send_response(500)
self.end_headers()
self.wfile.write(b'error')
Note you define path
and use it subsequently, otherwise you will still serve from /
How to run a http server which serves a specific path?
In Python 3.7 SimpleHTTPRequestHandler
can take a directory
argument:
import http.server
import socketserver
PORT = 8000
DIRECTORY = "web"
class Handler(http.server.SimpleHTTPRequestHandler):
def __init__(self, *args, **kwargs):
super().__init__(*args, directory=DIRECTORY, **kwargs)
with socketserver.TCPServer(("", PORT), Handler) as httpd:
print("serving at port", PORT)
httpd.serve_forever()
and from the command line:
python -m http.server --directory web
To get a little crazy... you could make handlers for arbitrary directories:
def handler_from(directory):
def _init(self, *args, **kwargs):
return http.server.SimpleHTTPRequestHandler.__init__(self, *args, directory=self.directory, **kwargs)
return type(f'HandlerFrom<{directory}>',
(http.server.SimpleHTTPRequestHandler,),
{'__init__': _init, 'directory': directory})
with socketserver.TCPServer(("", PORT), handler_from("web")) as httpd:
print("serving at port", PORT)
httpd.serve_forever()
Start an apache server in any directory from command line
http-server
is a much better simple http server than pache, it's what I use currently! :)
Use [pache][1]
Install with npm - which comes with node here: http://nodejs.org/
sudo npm install pache -g
Run on current dir, port 3000:
pache
Or specify directory and port:
pache site-directory 2000
[1]: https://github.com/devinrhode2/pache
how do I download a file in my current directory in ssh?
Firstly, forget URLs, and forget wget - this file isn't going to be accessible over the world wide web (if it is, your security is seriously broken).
However, if you can see it on SSH, you can probably (depending on security policies on the server) access it by using the same credentials over SCP.
On the command-line, using the PSCP program which comes with PuTTY that would look something like:
pscp user@server.example.com:/usr/local/lib/php.ini .
Or you could use a graphical client like WinSCP or FileZilla (which supports SFTP, which is another SSH-based protocol; use sftp://server.example.com
as the server to connect to), if you're on a Windows desktop.
Related Topics
Can Ruby Print Out Time Difference (Duration) Readily
Set Utf-8 as Default String Encoding in Heroku
What Does "≪≪-" Mean in Ruby
How to Access a Variable Defined in a Ruby File I Required in Irb
How to Run Untrusted Ruby Code Inside a Safe Sandbox
Why Doesn't Ruby Find Classes in a Higher Scope When Module Is Specified Using ::
How to Test a Function With Gets.Chomp in It
Returning All Maximum or Minimum Values That Can Be Multiple
Ruby on Rails Callback, What Is Difference Between :Before_Save and :Before_Create
Ruby: How to Write Multi-Line String With No Concatenation
Serve Current Directory from Command Line
Getting "Warning! Path Is Not Properly Set Up" When Doing Rvm Use 2.0.0 --Default
How to Create a Private Class Method
How to Get the Name of a Ruby Class