FileSystem
FileSystem Pharo Moose
Free Software
Moose
Pharo
Pike
REST
RosettaCode
VR
Zinc-REST
angular.js
beijinglug
code-in
collaboration
community-calendar
email
ember.js
fish
interview
life-after-death
n-reduce
open hardware
open-party
shell
smalltalk
vim

basic http file server
Pike

I needed to quickly serve some files, and i didn't want to install a full webserver, knowing that this was only temporary. So instead here is a simple http file-server in Pike. I call it a file-server because it serves static files, and nothing else.

Based on this example for a simple web-server, it just takes a few additions to turn this into a file-server:

#!/usr/local/bin/pike

constant default_port = 8080;
constant my_version = "0.0";

Protocols.HTTP.Server.Port port;

string basedir = "/srv/www";

int main(int argc, array(string) argv)
{
  int my_port = default_port;
  if(argc>1) my_port=(int)argv[1];

  write("SocServe starting on port %d\n", my_port);

  port = Protocols.HTTP.Server.Port(handle_request, my_port);
  return -1;
}

void handle_request(Protocols.HTTP.Server.Request request)
{
  write(sprintf("got request: %O\n", request));

  mapping response = ([]);

  response->server="SocServe " + my_version;

  string target = Stdio.append_path(basedir, request->not_query);
  mixed tstat = file_stat(target);
  write("target: %O\n", tstat);

  if (tstat && tstat->isdir)
  {
    response->type = "text/html";
    response->error = 200;
    response->data = dirlist(target);
  } 
  else if (tstat && tstat->isreg)
  {
    response->type = MIME.ext_to_media_type((target/".")[-1]) || "octet/stream";
    response->error = 200;
    response->file = Stdio.File(target);
  }
  else
  {
    response->type = "text/html";
    response->error = 200;
    response->request = sprintf("%O", mkmapping(indices(request), values(request)));
    response->data = "<h1>SocServe " + my_version + "</h1>n<pre>"
    + response->request + "</pre>n";
  }

  request->response_and_finish(response);
}

string dirlist(string path)
{ 
  array dir = get_dir(path);
  return sprintf("%{<a href=\"%s\">%s</a><br>\n%}", ({ dir[*], dir[*] })); 
}

These are the changes: first combine the request path with our basedir which will reduce any embedded /../ to not go beyond that base. Then we check if it's a directory or a file. For a directory we make a simple listing, and for a file we find the mime-type and then just open the file and pass it to the request. This will cause the file to be served with non-blocking I/O, allowing you to handle multiple requests in parallel without blocking the server while a file is being downloaded.

That's all there is to it. Start it up, and it's ready to serve files.

Author : mbaehr   |   size : 2640Bytes   |   Publish Date : Jul/7/13/17:46   |   to Top