A simple HTTP static file server written in nodejs and Python

  • 2020-03-30 03:34:18
  • OfStack

It's easy to implement this feature. The key points are as follows:

1. Open an HTTP service locally and listen to port 80;
2. Modify the system hosts file, add "127.0.0.1 a.mycdn.com", and bind the CDN domain name to the local server address;
3. Configure the local HTTP service. After receiving a GET request, check whether the corresponding file exists on the local hard disk.

As you can see, the key part is to set up a local HTTP service. There are many tutorials on this, such as installing server software such as Apache or Ngnix locally and configuring forwarding rules accordingly. However, I think this kind of method is still a bit complicated, this article will introduce, is another method that does not need to install server software.

Since we were developing and debugging locally, and the requirements for performance and concurrency were not high, we didn't really need a professional HTTP software like Apache/Ngnix, we just needed a script that could provide HTTP services. Such as using nodejs to implement.


/**
 * author: oldj
 *
 **/ var http = require("http"),
 url = require("url"),
 path = require("path"),
 fs = require("fs"),
 local_folders,
 base_url; local_folders = [ //Local path, the agent will look for files in the directory in this list, if not found then go to the online address
 "D:/work/assets"
];
base_url = "http://10.232.133.214"; //Line path, if you can't find the file, then go to this address
function loadFile(pathname, response) {
 var i, l = local_folders.length,
  fn;  console.log("try to load " + pathname);  for (i = 0; i < l; i++) {   fn = local_folders[i] + pathname;
  if (path.existsSync(fn) && fs.statSync(fn).isFile()) {
   fs.readFile(fn, function (err, data) {
    response.writeHead(200);
    response.write(data);
    response.end();
   });    return;
  }  }  response.writeHead(302, {
  "Location":base_url + pathname
 });
 response.end();
} http.createServer(
 function (request, response) {   var req_url = request.url,
   pathname;   //Handle similar to HTTP: s/s. Tbcdn.cn /? The & # 63; P/global / 1.0 / global - min. CSS, TBSP/TBSP. CSS & # 63; T =20110920172000. CSS request
  pathname = req_url.indexOf("??") == -1 ? url.parse(request.url).pathname : req_url;
  console.log("Request for '" + pathname + "' received.");
  loadFile(pathname, response);  }).listen(80);


Note that the above two variables local_folders and base_url are changed to the values you need. Save this file, such as local-cdn-proxy.js, then execute "node local-cdn-proxy.js" on the command line, and the local server is up and running. Of course, don't forget to bind the hosts.

When a path is accessed through HTTP, the above script will first search in the local corresponding directory, and then return the contents of the corresponding file if found. If not, it will jump directly from 302 to the corresponding address online. In the case of missing, another option is for the local server to download the corresponding content from the line and return, but for this requirement, 302 is sufficient.

In addition to the nodejs version, I also wrote a Python version:


# -*- coding: utf-8 -*-
#
# author: oldj
# import os
import BaseHTTPServer LOCAL_FOLDERS = [
    "D:/work/assets"
]
BASE_URL = "http://10.232.133.214" class WebRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):     def do_GET(self):
        print "Request for '%s' received." % self.path
        for folder in LOCAL_FOLDERS:
            fn = os.path.join(folder, self.path.replace("/", os.sep)[1:])
            if os.path.isfile(fn):
                self.send_response(200)
                self.wfile.write(open(fn, "rb").read())
                break         else:
            self.send_response(302)
            self.send_header("Location", "%s%s" % (BASE_URL, self.path)) server = BaseHTTPServer.HTTPServer(("0.0.0.0", 80), WebRequestHandler)
server.serve_forever()


As you can see, the Python version is much more streamlined than the nodejs version.

The above two pieces of code are relatively simple in terms of functionality, such as header information such as mime-type and content-length with no output Content, and no special handling of possible blocking operations such as read file timeout. They are already working versions for the local development environment, and you can continue to extend both scripts to meet more requirements.


Related articles: