Skip to content

Latest commit

 

History

History
256 lines (191 loc) · 8.79 KB

http.rst

File metadata and controls

256 lines (191 loc) · 8.79 KB

HTTP Service

The HTTP service is a basic servlet container, dispatching HTTP requests to the handler registered for the given path. A servlet can be a simple class or a component, registered programmatically to the HTTP service, or a service registered in the Pelix framework and automatically registered by the HTTP service.

Note

Even if it borrows the concept of servlets from Java, the Pelix HTTP service doesn't follow the OSGi specification. The latter inherits a lot from the existing Java APIs, while this is an uncommon way to work in Python.

The basic implementation of the HTTP service is defined in pelix.http.basic. It is based on the HTTP server available in the standard Python library (see http.server). Future implementations might appear in the future Pelix implementations, based on more robust requests handlers.

Configuration properties

All implementations of the HTTP service must support the following property:

Property Default Description
pelix.http.address 0.0.0.0 The address the HTTP server is bound to
pelix.http.port 8080 The port the HTTP server is bound to

Instantiation

The HTTP bundle defines a component factory which name is implementation-dependent. The HTTP service factory provided by Pelix/iPOPO is pelix.http.service.basic.factory.

Here is a snippet that starts a HTTP server component, named http-server, which only accepts local clients on port 9000:

from pelix.framework import FrameworkFactory
from pelix.ipopo.constants import use_ipopo

# Start the framework
framework = FrameworkFactory.get_framework()
framework.start()
context = framework.get_bundle_context()

# Install & start iPOPO
context.install_bundle('pelix.ipopo.core').start()

# Install & start the basic HTTP service
context.install_bundle('pelix.http.basic').start()

# Instantiate a HTTP service component
with use_ipopo(context) as ipopo:
   ipopo.instantiate(
       'pelix.http.service.basic.factory', 'http-server',
       {'pelix.http.address': 'localhost',
        'pelix.http.port': 9000})

This code starts an HTTP server which will be listening on port 9000 and the HTTP service will be ready to handle requests. As no servlet service has been registered, the server will only return 404 errors.

API

HTTP service

The HTTP service provides the following interface:

HttpService

The service also provides two utility methods to ease the display of error pages:

HttpService

Servlet service

To use the whiteboard pattern, a servlet can be registered as a service providing the pelix.http.servlet specification. It must also have a valid pelix.http.path property, or it will be ignored.

The binding methods described below have a parameters argument, which represents a set of properties of the server, given as a dictionary. Some parameters can also be given when using the ~HttpService.register_servlet method, with the parameters argument.

In any case, the following entries must be set by all implementations of the HTTP service and can't be overridden when register a servlet. Note that their content and liability is implementation-dependent:

  • http.address: the binding address (str) of the HTTP server;
  • http.port: the real listening port (int) of the HTTP server;
  • http.https: a boolean flag indicating if the server is listening to HTTP (False) or HTTPS (True) requests;
  • http.name: the name (str) of the server. If the server is an iPOPO component, it should be the instance name;
  • http.extra: an implementation dependent set of properties.

A servlet for the Pelix HTTP service has the following methods:

HTTP request

Each request method has a request helper argument, which implements the ~pelix.http.AbstractHTTPServletRequest abstract class.

pelix.http.AbstractHTTPServletRequest

HTTP response

Each request method also has a response helper argument, which implements the ~pelix.http.AbstractHTTPServletResponse abstract class.

pelix.http.AbstractHTTPServletResponse

Write a servlet

This snippet shows how to write a component providing the servlet service:

from pelix.ipopo.decorators import ComponentFactory, Property, Provides, \
    Requires, Validate, Invalidate, Unbind, Bind, Instantiate

@ComponentFactory(name='simple-servlet-factory')
@Instantiate('simple-servlet')
@Provides(specifications='pelix.http.servlet')
@Property('_path', 'pelix.http.path', "/servlet")
class SimpleServletFactory(object):
  """
  Simple servlet factory
  """
  def __init__(self):
      self._path = None

  def bound_to(self, path, params):
      """
      Servlet bound to a path
      """
      print('Bound to ' + path)
      return True

  def unbound_from(self, path, params):
      """
      Servlet unbound from a path
      """
      print('Unbound from ' + path)
      return None

  def do_GET(self, request, response):
      """
      Handle a GET
      """
      content = """<html>
<head>
<title>Test SimpleServlet</title>
</head>
<body>
<ul>
<li>Client address: {clt_addr[0]}</li>
<li>Client port: {clt_addr[1]}</li>
<li>Host: {host}</li>
<li>Keys: {keys}</li>
</ul>
</body>
</html>""".format(clt_addr=request.get_client_address(),
                host=request.get_header('host', 0),
                keys=request.get_headers().keys())

      response.send_content(200, content)

To test this snippet, install and start this bundle and the HTTP service bundle in a framework, then open a browser to the servlet URL. If you used the HTTP service instantiation sample, this URL should be http://localhost:9000/servlet.