A Brief Introduce to WSGI
- 2. Contents Retrospect 1: Web server Retrospect 2: APIs What is WSGI? WSGI Family The WSGI Model Middleware Further Readings References
- 3. Retrospect 1: Web server A web server is a computer program that delivers (serves) content, such as web pages , using the Hypertext Transfer Protocol (HTTP), over the World Wide Web . Two programming models to implements a web server Thread model: Classic Java servlet container Event model: Node.js A long history of the debates between the two models. [1][2]
- 4. Retrospect 2: APIs CGI: process based [3] FastCGI: eliminate the processes burden [4] Java Servlet API: OO style, application logic is encapsulated in a servlet class [5]
- 5. What is WSGI A question: What is a good abstraction for the logic between web server and application? WSGI is a specification [6] for connecting HTTP servers with web applications and frameworks. WSGI App Framework Web Server
- 6. WSGI Family 2003, The original python version [6] 2007, Rack, Ruby version [7] 2008, Lua WSAPI, Lua version [8] 2009, JSGI, Javascript version [9] 2009, PSGI, Perl version [10] 2010, Hack, Haskell version [11]
- 7. The WSGI Model Server side: We do not discuss this topic for now Application side: Application (a function) Environment -> (status, headers, body) Environment (a data structure) Hold request and other environment data Middleware (a function) Application -> Application
- 8. Examples 1 Hello World! [12] def application(environ, start_response): start_response("200 OK", [("Content-type", "text/plain")]) return ["Hello World!",] Sending a large file [12] def application(environ, start_response): size = os.path.getsize(file_path) headers = [ ("Content-type", mimetype), ("Content-length", str(size)), ] start_response("200 OK", headers) return send_file(file_path, size) def send_file(file_path, size): with open(file_path) as f: block = f.read(BLOCK_SIZE) while block: yield block block = f.read(BLOCK_SIZE)
- 9. Middleware Url routes Rack::URLMap Logging Rack::CommonLogger Exception handling Rack::ShowException Static files Rack::File ETag Rack::ETag Auth Rack::Auth And others Rack::JSONP Rack::LighttpdScriptNameFix Rack::Locale Rack::MailExceptions Rack::NestedParams Rack::PostBodyContentTypeParser Rack::ProcTitle Rack::Profiler Rack::Sendfile Rack::Signals Rack::StaticCache Rack::TimeZone Rack::Evil Rack::Callbacks Rack::Config Rack::NotFound Rack::CSSHTTPRequest Rack::Deflect Rack::ResponseCache Rack::RelativeRedirect Rack::Backstage Rack::AcceptFormat Rack::HostMeta Rack::Cookies Rack::Access Rack::ResponseHeaders Rack::SimpleEndpoint
- 10. Examples 2 module Rack class Upcase def initialize app @app = app end def call env puts 'upcase' p @app puts status, headers, body = @app.call env [status, headers, [body.first.upcase]] end end end module Rack class Reverse def initialize app @app = app end def call env puts 'reverse' p @app puts status, headers, body = @app.call env [status, headers, [body.first.reverse]] end end end use Rack::Upcase use Rack::Reverse use Rack::ContentLength app = lambda { |env| [200, { 'Content-Type' => 'text/html' }, 'Hello World'] } run app
- 12. Some Thoughts Simplicity OO is not silver bullet function as first class member in a programming language sometimes OO style is too burden Open culture The Cathedral and the Bazaar
- 13. References [1] Why Thread Are A Bad Idea, John Ousterhout , 1996 USENIX Technical Conference, 1996 [2] Why Event Are A Bad Idea, Rob von Behren, et al. , Proceedings of HotOS IX, 2003 [3] RFC3875: The Common Gateway Interface (CGI) Version 1.1 [4] FastCGI specification [5] Java™ Servlet API [6] PEP 333 Python Web Server Gateway Interface v1.0 [7] Rack Specification [8] WSAPI Specification [9] JSGI Specification [10] PSGI Specification [11] Hack Packages [12] WSGI Tutorial [13] Ruby Rack Middleware Tutorial