When a new connection is accepted (or a new request is started on
an existing persistent connection), the #SoupServer will emit
signal@Server::request-started and then begin processing the request
as described below, but note that once the message is assigned a
status-code, then callbacks after that point will be
skipped. Note also that it is not defined when the callbacks happen
relative to various class@ServerMessage signals.
Once the headers have been read, #SoupServer will check if there is
a class@AuthDomain(qv) covering the Request-URI; if so, and if the
message does not contain suitable authorization, then the
class@AuthDomain will set a status of soup.types.Status.Unauthorized on
the message.
After checking for authorization, #SoupServer will look for "early"
handlers (added with soup.server.Server.addEarlyHandler) matching the
Request-URI. If one is found, it will be run; in particular, this
can be used to connect to signals to do a streaming read of the
request body.
(At this point, if the request headers contain `Expect:
100-continue`, and a status code has been set, then
#SoupServer will skip the remaining steps and return the response.
If the request headers contain `Expect:
100-continue` and no status code has been set,
#SoupServer will return a soup.types.Status.Continue status before
continuing.)
The server will then read in the response body (if present). At
this point, if there are no handlers at all defined for the
Request-URI, then the server will return soup.types.Status.NotFound to
the client.
Otherwise (assuming no previous step assigned a status to the
message) any "normal" handlers (added with
soup.server.Server.addHandler) for the message's Request-URI will be
run.
Then, if the path has a WebSocket handler registered (and has
not yet been assigned a status), #SoupServer will attempt to
validate the WebSocket handshake, filling in the response and
setting a status of soup.types.Status.SwitchingProtocols or
soup.types.Status.BadRequest accordingly.
Finally, the server will emit signal@Server::request-finished (or
signal@Server::request-aborted if an I/O error occurred before
handling was completed).
If you want to handle the special "*" URI (eg, "OPTIONS *"), you
must explicitly register a handler for "*"; the default handler
will not be used for that case.
If you want to process https connections in addition to (or instead
of) http connections, you can set the property@Server:tls-certificate
property.
Once the server is set up, make one or more calls to
soup.server.Server.listen, soup.server.Server.listenLocal, or
soup.server.Server.listenAll to tell it where to listen for
connections. (All ports on a #SoupServer use the same handlers; if
you need to handle some ports differently, such as returning
different data for http and https, you'll need to create multiple
soup.server.Servers, or else check the passed-in URI in the handler
function.).
#SoupServer will begin processing connections as soon as you return
to (or start) the main loop for the current thread-default
glib.main_context.MainContext.
A HTTP server.
#SoupServer implements a simple HTTP server.
To begin, create a server using soup.server.Server.new_. Add at least one handler by calling soup.server.Server.addHandler or soup.server.Server.addEarlyHandler; the handler will be called to process any requests underneath the path you pass. (If you want all requests to go to the same handler, just pass "/" (or null) for the path.)
When a new connection is accepted (or a new request is started on an existing persistent connection), the #SoupServer will emit signal@Server::request-started and then begin processing the request as described below, but note that once the message is assigned a status-code, then callbacks after that point will be skipped. Note also that it is not defined when the callbacks happen relative to various class@ServerMessage signals.
Once the headers have been read, #SoupServer will check if there is a class@AuthDomain (qv) covering the Request-URI; if so, and if the message does not contain suitable authorization, then the class@AuthDomain will set a status of soup.types.Status.Unauthorized on the message.
After checking for authorization, #SoupServer will look for "early" handlers (added with soup.server.Server.addEarlyHandler) matching the Request-URI. If one is found, it will be run; in particular, this can be used to connect to signals to do a streaming read of the request body.
(At this point, if the request headers contain `Expect: 100-continue`, and a status code has been set, then #SoupServer will skip the remaining steps and return the response. If the request headers contain `Expect: 100-continue` and no status code has been set, #SoupServer will return a soup.types.Status.Continue status before continuing.)
The server will then read in the response body (if present). At this point, if there are no handlers at all defined for the Request-URI, then the server will return soup.types.Status.NotFound to the client.
Otherwise (assuming no previous step assigned a status to the message) any "normal" handlers (added with soup.server.Server.addHandler) for the message's Request-URI will be run.
Then, if the path has a WebSocket handler registered (and has not yet been assigned a status), #SoupServer will attempt to validate the WebSocket handshake, filling in the response and setting a status of soup.types.Status.SwitchingProtocols or soup.types.Status.BadRequest accordingly.
If the message still has no status code at this point (and has not been paused with soup.server_message.ServerMessage.pause), then it will be given a status of soup.types.Status.InternalServerError (because at least one handler ran, but returned without assigning a status).
Finally, the server will emit signal@Server::request-finished (or signal@Server::request-aborted if an I/O error occurred before handling was completed).
If you want to handle the special "*" URI (eg, "OPTIONS *"), you must explicitly register a handler for "*"; the default handler will not be used for that case.
If you want to process https connections in addition to (or instead of) http connections, you can set the property@Server:tls-certificate property.
Once the server is set up, make one or more calls to soup.server.Server.listen, soup.server.Server.listenLocal, or soup.server.Server.listenAll to tell it where to listen for connections. (All ports on a #SoupServer use the same handlers; if you need to handle some ports differently, such as returning different data for http and https, you'll need to create multiple soup.server.Servers, or else check the passed-in URI in the handler function.).
#SoupServer will begin processing connections as soon as you return to (or start) the main loop for the current thread-default glib.main_context.MainContext.