Skip to content

glurp/femtows

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

41 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Femtows : femto sized web server

Presentation

The tiny web server ... 400 Lines of code.

Build to be embedded in any ruby application, test/debug/admin access...

Features :

  • methods GET POST (PUT, REMOVE, HEAD... are missing!)
  • index generate as simple explorer (if path correspond to existant directory or file)
  • multipart/data supported
  • upload file via multipart
  • multipart dynamic (can be active continiously, a timeout inter-part is setted to 10 minutes)
  • http redirection

Performances are not so bad : better than Sinatra/Thin, near Puma/Thin)

Install

gem install femtows

Usage

As file http server :

> ruby -rfemtows -e "cliweb()"
> ruby -rfemtows -e "cliweb('/tmp',8080)"
or
> femtows.bat
# femtows.sh

Embedded V1:

# server all file in current dir and .info request :

$ws=WebserverRoot.new(8080,"/tmp","femto ws",10,300, {})

$ws.serve("/info")    {|p|  
 [200,".html", "Femto demo<hr><a href='/'>site</a><hr>#{$ws.to_table(p)}" ] 
}

Embedded V2:

class App < Fem
  def get_app_html(p)
    "<html><body><h2><center>Hello</center></h2><hr>
      <p>#{content}</p><hr><center>[femtows]</center>
    </body></html>"
  end
  def content
    to_tableb(Dir.glob("*.rb")) {|f| [f,File.size(f),File.mtime(f)]}
  end
end
App.new(ARGV[0].to_i)

Upload file

class App < Fem
  def get_app_html(p)
	  form=<<EEND
<form action="mp" method="post" enctype="multipart/form-data">
  <p><input type="text" name="text" value="dddddddddddddddd">
  <p><input type="file" name="file1">
  <p><input type="file" name="file2">
  <p><button type="submit">Submit</button>
</form>
EEND
      "<html><body><h2><center>Hello</center></h2><hr><p>#{form}</p><hr><center>[femtows]</center></body>"
  end
  def get_mp_html(p)
	bilan={}
	stream_input { |name,type,value,headers|
		puts ["!!!!!!!!!! stream_input reactor ==> ",name,type,value,headers].join(" ")
		puts("           File size of %s  => %d" % [value,File.size(value)]) if type==:file
		size= (type==:file) ? File.size(value) : -1
		bilan[name]=[type,value,size]
	}
    "<html><body><h2><center>Stream input (multipart)</center></h2><hr><p>#{bilan.inspect.split(",").join("<br>")}</p><hr><center>[femtows]</center></body>"
  end
end

With v2 API, all methods which name match get_()_() will be associate with url $1 and his output will be sending with MIME code corresponding to file extension $2.

So def get_login_html() while match for path /login,method GET or POST, end returned value is sended as Content-type: text/html

API

WebserverRoot.new(
	port_http,  # server http  port (>1024 on posix, if not root)
	root-dir,	# only one file root. indexed by defalut
	ws_name,	# name in trace & index title 
	10,300, 	# watch too long connection: every  10 secondes, 
				    # kill session which have started from more than 300 seconds
	{}			  # options. only one, for logg events , see demo.rb
)

Servlet receive params hash which content :

  • all http header, with key upercase, prefixed with 'HEAD-'
  • http parameters (?a=b&...)

Exemple : http://localhost:9980/info?aa=bb&cc=dd, give with p.to_a.inspect:

["aa", "bb"]
["cc", "dd"]
["HEAD-HOST", "localhost:9980"]
["HEAD-USER-AGENT", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2"]
["HEAD-ACCEPT", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"]
["HEAD-ACCEPT-LANGUAGE", "fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3"]
["HEAD-ACCEPT-ENCODING", "gzip, deflate"]
["HEAD-CONNECTION", "keep-alive"]

License

LGPL

About

Tiny werb server : Femto-Apache ...

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages