Ruby uses eventmachine to add file download capabilities to the HTTP server

Time:2021-10-22

Idea:
Use ruby eventmachine and EM HTTP server gem to complete a simple httpserver that provides file download function;
EM FileStreamer is used to send files asynchronously. When sending files, header is first assembled and FileStreamer is called.

code:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
require 'rubygems'
require 'eventmachine'
require 'em-http-server'
 
class HTTPHandler < EM::HttpServer::Server
 attr_accessor :filename, :filesize, :path
 
 def process_http_request
  #send file async
  if @http_request_method.to_s =~ /GET/ && @http_request_uri.to_s.end_with?(filename)
   send_data "HTTP/1.1 200 OK\n"
   send_data "Server: XiaoMi\n"
   send_data "Connection: Keep-Alive\n"
   send_data "Keep-Alive: timeout=15\n"
   send_data "Content-Type: application/octet-stream\n"
   send_data "Content-Disposition: filename='#{filename}'\n"
   send_data "Content-Length: #{filesize}\n"
   send_data "\n"
 
   streamer = EventMachine::FileStreamer.new(self, path)
   streamer.callback {
    # file was sent successfully
    close_connection_after_writing
   }
  else
   response = EM::DelegatedHttpResponse.new(self)
   response.status = 200
   response.content_type 'text/html'
   response.content = "Package HttpServer<br>usage: wget http://host:port/#{filename}"
   response.send_response
  end
 end
 
end
 
EM::run do
 path = '/tmp/aaa.tar.gz'
 EM::start_server("0.0.0.0", 8080, HTTPHandler) do |conn|
  conn.filename = File.basename(path)
  conn.filesize = File.size(path)
  conn.path = path
 end
end

PS: about the installation error of eventmachine
Installing eventmachine on windows always reports an error:
 

?
1
2
3
Building native extensions. This could take a while...
ERROR: Error installing eventmachine:
    ERROR: Failed to build gem native extension.

Or another:

?
1
2
3
4
5
6
ERROR: Error installing ruby-debug:
      The 'linecache' native gem requires installed build tools.
   
  Please update your PATH to include build tools or download the DevKit
  from 'http://rubyinstaller.org/downloads' and follow the instructions
  at 'http://github.com/oneclick/rubyinstaller/wiki/Development-Kit'

Later, after a long Google search, two solutions were found:

1. Use a lower version of eventmachine
 
This prompt continues all the time. There is another difficult error below, which is the compilation error of C. later, I found two methods on the Internet
(1)

?
1
gem install eventmachine-win32

This seems to have a lower version installed
(2)gem install

?
1
eventmachine --pre

This seems to be installed in beta 1.0.0.

 
2. Upgrade devkit
 
After a look, there is no specific solution mentioned above, but two possible causes of the problem are given:
(1) No C compilation environment
(2) There are spaces in the path
Look at the error log above and find that it may be a problem with the compilation environment. So I looked for it.
My ruby is installed with one click installer. The version is 1.8.6-p398.
On the addon page of ruby installer, devkit is found.
Read devkit’s Description:

//Sometimes you just want RubyGems to build that cool native,
//C-based extension without squawking.
//Who’s your buddy? DevKit!
It seems that this is what I need.
 
The reason for the error is that build tools is required when installing eventmachine, but it is not available in the system. The error message also gives the solution:
(1) To http://rubyinstaller.org/downloads/ Download dev kit – devkit-tdm-32-4.5.1-20101214-1400-sfx.exe
(2) According to http://github.com/oneclick/rubyinstaller/wiki/Development-Kit/ Install dev Kit
The main installation steps are as follows:
If the old version of dev kit is already installed in the original system, delete it
Download the dev kit mentioned above
Unzip the downloaded file to the specified directory, such as C: / devkit. (Note: the directory cannot have spaces)
Run ruby dk.rb, and then run ruby dk.rb init and ruby dk.rb install respectively as prompted to enhance ruby
Can run

?
1
gem install rdiscount –platform=ruby

To test for success.
Follow the installation steps to complete the installation of devkit, which is very simple.

Then, install eventmachine again:

?
1
gem install eventmachine