SiouX: New Framework to Build HTTP Servers
There will be a few types of HTTP server solutions available in 7.10:
- Supported solution
- SiouX-Net-Http server based on Net framework.
- SiouX-Net-Https server based on Net framework.
- Preview
- SiouX-Http server based on Xtreams.
- SiouX-Https server based on Xtreams
The 7.10 builds have already included new parcels:
- SiouX-Net-Http in www directory.
- SiouX-Net-Https in www directory.
- SiouX-Http in preview/www directory
- SiouX-Https in preview/www directory.
The new framework allows creating a secure, efficient and extensible server that provides HTTP services that are in sync with the current HTTP standards. The current features include:
- streaming responses
- focus on efficient and scalable implementation
- server can be configured to listen on multiple ports (multiple listeners)
- chunked responses
- gzipping
- SSL and TLS support
- – flexible and easy to maintain configuration
- – running different Web applications from the same address
- – announcements based on the server event notification
The new framework replaces the old Opentalk framework as a solution for building Web servers. Opentalk was designed to support CORBA-style remote objects/messages. Building HTTP servers required a deep understanding of the Opentalk architecture and didn’t provide a scalable, robust solution. Opentalk still remains the solution for remote, objects-style distributed computing (STST, CORBA, etc.) but for Web servers, we suggest using the SiouX framework.
In 7.10, Seaside and Web Services servers will be released based on the SiouX framework. To run existing Opentalk-based WebServices applications in 7.10, customers will need to install obsolete Opentalk-SOAP and Opentalk-WS-Support parcels. The WebServices applications won’t require any changes in 7.10.
SiouX framework
There are just a few core classes in SiouX framework. A Server has one or more listeners listening for incoming connections. An established connection waits for incoming requests of corresponding type, which are then passed back to the server for execution. A server is configured with one or more responders. For each request, the server asks the responders to execute it, one by one in their registered order. A responder can reject a request by returning a nil. This iteration ends with the first responder that returns a response. This response is then passed back to the corresponding connection for delivery back to the client.
Creating SiouX-HTTP server
SiouX-HTTP implementation using Xtreams was designed with an emphasis on efficiency and scalability. It focuses solely on the server side. Consequently, requests are only read and responses are only written, causing their implementation and behavior to be quite different. To use this implementation, configure the server with a listener for the HttpConnection class. Responders registered with such a server have to be able to handle SiouX.HttpRequest and SiouX.HttpResponse.
Here is an example of creating and running SiouX HTTP server based on Xtreams:
Create a responder class as a subclass from SiouX.Responder:
Smalltalk.SiouX defineClass: #Hellosuperclass: #{SiouX.Responder}
The Hello class has to handle the HTTP request and return the response. Let’s return “Hello World!” page in the response:
Hello>>dispatchRequest: anHttpRequest connection:aConnection response: anHttpResponseanHttpRequest url tail = 'hello' ifTrue: [anHttpResponsecontentType:'text/html';contents: '<HTML><BODY><H1>HelloWorld!</H1></BODY></HTML>'.^anHttpResponse].^nil
Create and start the server:
server := SiouX.Server newaddResponder: SiouX.Hello new;yourself.server listenOn: 4242 for: SiouX.HttpConnection.server start
Once started, the server is ready to respond to client requests.
'http://localhost:4242/hello' asURI get.server stop.
Creating SiouX-Net-HTTP server
The SiouX-Net-HTTP server implementation uses Net framework to parse messages. It focuses solely on the server side. To use this implementation, configure the Server with a listener for the NetHttpConnection class. Responders registered with such server have to be able to handle Net.HttpRequest and Net.HttpResponse.
Here is an example of creating and running SiouX-Net-HTTP server based on Net request and the response:
server := SiouX.Server newaddResponder: SiouX.Hello new;yourself.server listenOn: 8000 for: SiouX.NetHttpConnection.server start.
Once started, the server is ready to respond to client requests.
'http://localhost:8000/hello' asURI get.server stop.
Creating SiouX HTTP Secure server
The SiouX-HTTPS implementation is based on Xtreams. To use this implementation, add a listener for HttpsConnection with the desired address. The listener must be configured with the proper TLSContext. At the very least, the context must be configured with a valid server certificate and private key.
Here is an example of creating and running SiouX HTTP Secure server based on Xtreams:
server := Server newaddResponder: Hello new;yourself.listener := server listenOn: 8001 for:HttpsConnection.certificates := TLSCertificateStore newWithDefaultsknown:anX509Certificate;certificate:(Array with:anX509Certificate) key: aRSAPrivateKey;yourself.serverContext := TLSContext newServerWithDefaultscertificates: certificates;yourself.listener tlsContext: serverContext.clientContext := TLSContext newClientWithDefaultscertificates: certificates;yourself.client := HttpClient new.client tlsContext: clientContext.server start.[ client get: 'https://localhost:8001/hello'.] ensure: [server ifNotNil: [ server release ].client ifNotNil: [ client close ].certificates release.clientContext release.
Creating SiouX-Net-HTTPS server
The SiouX-Net-HTTPS implementation uses Net HTTP framework. To use this implementation, add a listener for NetHttpsConnection with the desired address.
This example of creating and running SiouX Net HTTP Secure server is the almost same as for the SiouX HTTP Secure server based on Xtreams. The only difference is the connection type:
server := Server new addResponder:Hello new; yourself.listener := server listenOn:8001 for: NetHttpsConnection.
Creating SiouX HTTP server to run Seaside and Web Services from the same port
As an example, we can consider creating a Seaside server that runs Web services from the same port.
Assume that we have a WSDL schema with #TimeNow service that returns time now.
Load WSDL schema and create WsdlBinding:
config := (WsdlConfigurationDescriptor defaultReadFrom:wsdlSchema readStream) buildComponents.wsdlBinding := config bindings asArray first.
Create SOAPResponder that is going to process #TimeNow requests.
soapResponder := SOAPResponder fromBinding: wsdlBinding.
Now we can create a server that can process Seaside requests and #TimeNow Web service.
server := SiouX.Server new.
Configure the server with responders that execute incoming requests.
serveraddResponder: soapResponder;addResponder: SeasideResponder new.
The order in which the responders are registered reflects their assigned priority. A responder will only get a chance to handle a request if all of the previous responders rejected it first. The SOAPResponder knows the exact URL that it can consume, and it should be the first one in the responder collection. The SeasideResponder is going to process the rest of the requests.
Define the server access address and listener on this address:
address := IPSocketAddress hostAddress: #[0 0 0 0] port: 7777.listener := server listenOn: address for: SiouX.NetHttpConnection.
Now we can test the server:
server start.
Open a Web browser on the Seaside server:
ExternalWebBrowser open: 'http://localhost:7777'.Execute #TimeNow service:client := WsdlClient newconfig: config;yourself.(client executeSelector: #TimeNow args: #()) inspect.server stop.