public class HttpRequestHandler extends TypedAtomicActor implements HttpService, ExceptionSubscriber
WebServer
, which discovers this actor and
delegates HTTP requests to a servlet that this actor creates.
It also requires that the model containing this actor provide
exactly one input to at least one of the input ports in response to
every output request,
and that such responses are delivered to its input in the very
next microstep, or at least before any other request is made
by the WebServer.
The path parameter specifies which HTTP requests will be delegated to this actor. If the base URL for the web server is "http://localhost:8080", say, then request of the form "http://localhost:8080/path" will be delegated to this actor. It is an error if two instances of this actor to have the same path in a model?
When this actor receives an HTTP request from the WebServer, it issues a request for the director to fire it at the greater of the current time of the director or the time elapsed since the last invocation of initialize() (in seconds). When the actor fires, it produces on its output ports the details of the request, time stamped by the elapsed time since the model started executing. It expects to be in a model that will send it data to input ports with the response to HTTP request. If that response does not arrive within timeout (default 30000) milliseconds, then this actor will a issue timeout response and will discard the response when it eventually arrives.
This actor is designed to be used in a DE model (with a DEDirector).
Since a model using this actor must deliver a response for
every request, the model must put this actor in a feedback
loop. The requests appear on the outputs of this actor,
and the responses appear on the inputs. Each such feedback
loop is required to include an instance of MicrostepDelay
in order to break the causality loop that the feedback loop would
otherwise incur.
The downstream model should be used to construct a response.
For example, to simply serve a web page, put a
FileReader
actor to read the response from a local
file and a MicrostepDelay
downstream in a feedback
loop connected back to the response input.
Some of the output ports (parameters
and headers
)
produce records and constrain their output type to be less than
or equal to an empty record. This does not, however, provide
enough information for type inference. If the downstream model
that receives these records requires particular fields
in the record, then putting a RecordDisassembler
actor downstream
to extract the field, and enabling backward type inference at the top
level of the model will result in a constraint on this port that the
record contain the specified field. A malformed URL that does
not contain the specified record fields will result in a response
400 Bad Request, meaning "the request could not be understood
by the server due to malformed syntax.
The client SHOULD NOT repeat the request without modifications."
If the downstream model does not require
any particular fields, but will rather examine any fields that
are provided, for example in a JavaScript
actor, then
you can declare the output ports of this actor to be of type "record",
or you can declare the input port of the downstream actor to be
of type "record" and enable backward type inference. In this case,
any fields that are provided will be passed downstream as a record.
WebServer
Modifier and Type | Class and Description |
---|---|
protected class |
HttpRequestHandler.ActorServlet
A servlet providing implementations of get and post.
|
protected static class |
HttpRequestHandler.HttpRequestItems
A data structure with all the relevant information about an
HTTP request.
|
protected static class |
HttpRequestHandler.HttpResponseItems
A data structure with all the relevant information about an
HTTP response.
|
Entity.ContainedObjectsIterator
Modifier and Type | Field and Description |
---|---|
TypedIOPort |
body
An output that sends the body of the request, or an empty string
if there isn't one.
|
TypedIOPort |
cookies
An output that sends the cookies specified by the
requestedCookies parameter, with values
provided by a get request. |
TypedIOPort |
headers
The header information of an HTTP request as a record.
|
TypedIOPort |
method
An output port that sends a string indicating the method of
the HTTP request, including at least the possibilities "GET"
and "POST".
|
TypedIOPort |
parameters
An output port that sends a record detailing any
parameters included in an HTTP request.
|
StringParameter |
path
The relative URL of HTTP requests that this actor handles.
|
Parameter |
requestedCookies
An array of names of cookies that this actor should retrieve from
an HTTP request and produce on the cookies output
port.
|
TypedIOPort |
requestor
Output port that produces the name or IP address of the
client or the last proxy that sent the request.
|
TypedIOPort |
responseBody
An input port on which to provide the
response body to issue to an HTTP request.
|
TypedIOPort |
responseCode
An input port on which to provide the
response code to issue to an HTTP request.
|
PortParameter |
responseContentType
The content type of the response.
|
PortParameter |
responseHeaders
The header data to include in the response.
|
TypedIOPort |
setCookies
An input on which to provide new cookies and/or new cookie values.
|
Parameter |
timeout
The time in milliseconds to wait after producing the details
of a request on the output ports for a response to appear at
the input ports.
|
TypedIOPort |
uri
An output port that sends the relative URI of a get request,
which must match the pattern given by the path parameter.
|
_typesValid
_actorFiringListeners, _initializables, _notifyingActorFiring, _stopRequested
_changeListeners, _changeLock, _changeRequests, _debugging, _debugListeners, _deferChangeRequests, _elementName, _isPersistent, _verbose, _workspace, ATTRIBUTES, CLASSNAME, COMPLETE, CONTENTS, DEEP, FULLNAME, LINKS
COMPLETED, NOT_READY, STOP_ITERATING
Constructor and Description |
---|
HttpRequestHandler(CompositeEntity container,
java.lang.String name)
Create an instance of the actor.
|
Modifier and Type | Method and Description |
---|---|
protected void |
_handleRequest(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response,
java.lang.String type)
Handle an HTTP request by recording the request data, requesting
a firing of this actor at the current time, waiting for a response
to be created, and then sending the response.
|
protected java.lang.String |
_readBody(javax.servlet.http.HttpServletRequest request)
Read the body information from the HttpServletRequest, which at this time
is constrained to be a string.
|
protected RecordToken |
_readCookies(javax.servlet.http.HttpServletRequest request)
Read the Cookies from the HttpServletRequest, construct
a record token with one field for each name in the requestedCookies
parameter and the value given by the request, or if there is no
value, with an empty string as a value.
|
protected RecordToken |
_readHeaders(javax.servlet.http.HttpServletRequest request)
Read the header information from the HttpServletRequest, construct
a record token with one field for each header name.
|
protected RecordToken |
_readParameters(javax.servlet.http.HttpServletRequest request)
Read the parameters from the HttpServletRequest, construct
a record token containing the parameters, and return that record.
|
protected void |
_writeCookies(RecordToken cookies,
javax.servlet.http.HttpServletResponse response)
Write the cookies in the specified RecordToken to the HttpResponse.
|
void |
attributeChanged(Attribute attribute)
React to a change in an attribute.
|
java.lang.Object |
clone(Workspace workspace)
Clone the actor.
|
boolean |
exceptionHandled(boolean succesful,
java.lang.String message)
Not used here.
|
boolean |
exceptionOccurred(java.lang.String policy,
java.lang.Throwable exception)
Generate an HTTP response for the client if an exception occurs in
the model and there is a
CatchExceptionAttribute in the model. |
void |
fire()
If there are input tokens on the
responseBody ,
setCookies , or responseCode ports and there is a pending
request, then send a response. |
java.net.URI |
getRelativePath()
Return the relative path that this HttpService is mapped to,
which is the value of the path parameter.
|
javax.servlet.http.HttpServlet |
getServlet()
Create and return an HttpServlet that is used to handle requests that
arrive at the path given by the path parameter.
|
void |
initialize()
Record the current model time and the current real time
so that output events can be time stamped with the elapsed
time since model start.
|
void |
setRelativePath(java.net.URI path)
Set the relative path that this HttpService is mapped to.
|
void |
setWebServer(WebServer server)
Specify the web server for this service.
|
_containedTypeConstraints, _customTypeConstraints, _defaultTypeConstraints, _fireAt, _fireAt, attributeTypeChanged, clone, isBackwardTypeInferenceEnabled, newPort, typeConstraintList, typeConstraints
_actorFiring, _actorFiring, _declareDelayDependency, addActorFiringListener, addInitializable, connectionsChanged, createReceivers, declareDelayDependency, getCausalityInterface, getDirector, getExecutiveDirector, getManager, inputPortList, isFireFunctional, isStrict, iterate, newReceiver, outputPortList, postfire, prefire, preinitialize, pruneDependencies, recordFiring, removeActorFiringListener, removeDependency, removeInitializable, setContainer, stop, stopFire, terminate, wrapup
_adjustDeferrals, _checkContainer, _getContainedObject, _propagateExistence, getContainer, instantiate, isAtomic, isOpaque, moveDown, moveToFirst, moveToIndex, moveToLast, moveUp, propagateExistence, setName
_addPort, _description, _exportMoMLContents, _removePort, _validateSettables, connectedPortList, connectedPorts, containedObjectsIterator, getAttribute, getPort, getPorts, linkedRelationList, linkedRelations, portList, removeAllPorts, setClassDefinition, uniqueName
_setParent, exportMoML, getChildren, getElementName, getParent, getPrototypeList, isClassDefinition, isWithinClassDefinition
_addAttribute, _adjustOverride, _attachText, _cloneFixAttributeFields, _containedDecorators, _copyChangeRequestList, _debug, _debug, _debug, _debug, _debug, _executeChangeRequests, _getIndentPrefix, _isMoMLSuppressed, _markContentsDerived, _notifyHierarchyListenersAfterChange, _notifyHierarchyListenersBeforeChange, _propagateValue, _removeAttribute, _splitName, _stripNumericSuffix, addChangeListener, addDebugListener, addHierarchyListener, attributeDeleted, attributeList, attributeList, decorators, deepContains, depthInHierarchy, description, description, event, executeChangeRequests, exportMoML, exportMoML, exportMoML, exportMoML, exportMoMLPlain, getAttribute, getAttributes, getChangeListeners, getClassName, getDecoratorAttribute, getDecoratorAttributes, getDerivedLevel, getDerivedList, getDisplayName, getFullName, getModelErrorHandler, getName, getName, getSource, handleModelError, isDeferringChangeRequests, isOverridden, isPersistent, lazyContainedObjectsIterator, message, notifyOfNameChange, propagateValue, propagateValues, removeAttribute, removeChangeListener, removeDebugListener, removeHierarchyListener, requestChange, setClassName, setDeferringChangeRequests, setDerivedLevel, setDisplayName, setModelErrorHandler, setPersistent, setSource, sortContainedObjects, toplevel, toString, validateSettables, workspace
equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
createReceivers, getCausalityInterface, getDirector, getExecutiveDirector, getManager, inputPortList, newReceiver, outputPortList
isFireFunctional, isStrict, iterate, postfire, prefire, stop, stopFire, terminate
addInitializable, preinitialize, removeInitializable, wrapup
description, getContainer, getDisplayName, getFullName, getName, getName, setName
getDerivedLevel, getDerivedList, propagateValue
public TypedIOPort body
public TypedIOPort cookies
requestedCookies
parameter, with values
provided by a get request. If the get request does
have cookies with names matching those in requestedCookies,
then those values will be empty strings.
The output will be a RecordToken with the field names given by
requestedCookies, and the field values being strings.public TypedIOPort headers
public TypedIOPort method
public TypedIOPort parameters
public StringParameter path
WebServer
.public Parameter requestedCookies
public TypedIOPort requestor
public TypedIOPort responseBody
public TypedIOPort responseCode
responseBody
input port, then the response code
will be 200 (OK). Standard response codes are described at
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html.
This port has type int.public PortParameter responseContentType
public PortParameter responseHeaders
responseContentType
.
Standard message header field names are given at
http://www.iana.org/assignments/message-headers/message-headers.xml#perm-headers
(see also http://en.wikipedia.org/wiki/List_of_HTTP_header_fields).public TypedIOPort setCookies
responseBody
input in the same firing, or if there is no token on the responseBody
input, will be treated as cookies accompanying an empty string response.
This has type record.public Parameter timeout
public TypedIOPort uri
public HttpRequestHandler(CompositeEntity container, java.lang.String name) throws IllegalActionException, NameDuplicationException
container
- The containername
- The name.IllegalActionException
- If the superclass throws it.NameDuplicationException
- If the superpublic void attributeChanged(Attribute attribute) throws IllegalActionException
attributeChanged
in class NamedObj
attribute
- The attribute that changed.IllegalActionException
- If the change is not acceptable
to this container (not thrown in this base class).public java.lang.Object clone(Workspace workspace) throws java.lang.CloneNotSupportedException
clone
in class TypedAtomicActor
workspace
- The workspace in which to place the cloned attribute.java.lang.CloneNotSupportedException
- Not thrown in this base class.Object.clone()
public boolean exceptionHandled(boolean succesful, java.lang.String message)
exceptionHandled
in interface ExceptionSubscriber
succesful
- True if the exception was successfully handled; false
otherwisemessage
- A status message from the exception handlerpublic boolean exceptionOccurred(java.lang.String policy, java.lang.Throwable exception)
CatchExceptionAttribute
in the model.
No response will be received on the input port in the event of such an
exception.exceptionOccurred
in interface ExceptionSubscriber
policy
- The exception handling policy of the exception handler;
see CatchExceptionAttribute
exception
- The exception that occurredpublic java.net.URI getRelativePath()
getRelativePath
in interface HttpService
setRelativePath(URI)
public javax.servlet.http.HttpServlet getServlet()
getServlet
in interface HttpService
public void fire() throws IllegalActionException
responseBody
,
setCookies
, or responseCode
ports and there is a pending
request, then send a response. Otherwise, if the servlet has received
an HTTP request, then also produce on the output ports
the details of the request.fire
in interface Executable
fire
in class AtomicActor<TypedIOPort>
IllegalActionException
- If sending the outputs fails.public void initialize() throws IllegalActionException
initialize
in interface Initializable
initialize
in class AtomicActor<TypedIOPort>
IllegalActionException
- If the superclass throws it.public void setRelativePath(java.net.URI path)
setRelativePath
in interface HttpService
path
- The relative path that this HttpService is mapped to.getRelativePath()
public void setWebServer(WebServer server)
WebServer
attribute of a model,
if there is one, and will enable this service to access
information about the web server (such as
the resourcePath, resourceLocation, or temporaryFileLocation).setWebServer
in interface HttpService
server
- The WebServer for this serviceprotected void _handleRequest(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, java.lang.String type) throws javax.servlet.ServletException, java.io.IOException
request
- The HTTP request.response
- The HTTP response to write to.type
- The type of request. 0 for get, 1 for post.javax.servlet.ServletException
- If there is a problem reading from the
servlet request or other servlet problemjava.io.IOException
- If there is a problem writing to the servlet
responseprotected java.lang.String _readBody(javax.servlet.http.HttpServletRequest request) throws IllegalActionException, java.io.IOException
request
- The HttpServletRequest to read header information from.IllegalActionException
- If construction of the record token fails.java.io.IOException
protected RecordToken _readCookies(javax.servlet.http.HttpServletRequest request) throws IllegalActionException
request
- The HttpServletRequest to read Cookies from. The
HttpServletRequest can be of any type - i.e. both GET and POST
requests are allowed to have Cookies.IllegalActionException
- If construction of the record token fails.protected RecordToken _readHeaders(javax.servlet.http.HttpServletRequest request) throws IllegalActionException
request
- The HttpServletRequest to read header information from.IllegalActionException
- If construction of the record token fails.protected RecordToken _readParameters(javax.servlet.http.HttpServletRequest request) throws IllegalActionException
request
- The HttpServletRequest to read parameters from. The
HttpServletRequest can be of any type - i.e. both GET and POST
requests are allowed to have parameters.IllegalActionException
- If construction of the record token fails.protected void _writeCookies(RecordToken cookies, javax.servlet.http.HttpServletResponse response)
cookies
- The cookies.response
- The HttpServletResponse to write the cookies to.