Add request and response functionality for network requests and the corresponding responses
(Taken from Concept 3 below)
To faciliate network request handling, a Request class shall be added. The MNENetProtocolHandler interface shall be removed and Request class instances shall interact directly with the NetworkHandler (former MNENetworkHandler). The latter shall be refactorised.
- Implement a Request class
- Add a ResponseHandler interface and make the Request class an implementation of it.
Implement Request::send: Pass the (raw) data to the network handler.See #13
- Add Semaphores to the Request class for "response header ready" and "response data available".
- Add the "aborted" flag to the request class to indicate an aborted request.
- Add a mutex to the Request class for the raw data buffer.
Implement thread support in NetworkHandler to start a new thread for each request before sending it. Check for the "aborted" flag of the Request before sending data to it. End a thread when the request has been aborted or no more data can be read.See #15
- Move code from MNENetprotocolHandler to Request specialisations or the base Request class.
- Refactorise MNENetworkHandler class and rename it to MNE::Network::NetworkHandler.
Outdated original text:
To faciliate network request handling, a request class and response handling interfaces shall be added. The MNENetProtocolHandler interface shall be refactorised/extended to use these classes/interfaces when the getResource method is called. The MNENetProtocolHeader class can be refactorised.
- Implement a request class
- Implement a response header handler interface
- Implement a response handler interface
- Rename MNENetProtocolHeader class to MNE::Network::ProtocolHeader and refactorise it.
- The Request class contains just the "metadata" like host, path, protocol method and other header fields.
- The MNENetProtocolhandler (MNENPH) gets a Request object to produce a Connection identifier out of it.
- Additional data (the request body) is sent to the MNENPH together with the connection-ID as vector.
- The MNENPH calls a closure in case the full respone header has been read. The closure gets a ResponseHeader object.
- The MNENPH calls a closure in case a specified amount of data is read from the response. The data is passed as vector<uint8_t>.
- The Request class contains just t he "metadata" like host, path, protocol method and other header fields. It also contains an ID field that is unique for all requests made during program execution.
- The MNENetProtocolHandler (MNENPH) gets a Request object, together with two other objects, where one of those implements ResponseHeaderHandler and the other one ResposeDataHandler.
- The MNENPH can receive additional data (request bodies) that must specify a Request-ID in addition to the body data.
- When the MNENPH has read the complete header, it calls a method on the ResponseHeaderHandler object that processes the header.
- When the MNENPH has read a specified (or sufficient) amount of data, it calls a method on the ResponseDataHandler object that processes the data.
- In both cases where the MNENPH calls the handlers, it also passes the Request-ID so that the handlers can distinguish the responses for different requests.
- MNENetProtocolHandler will be removed.
- A new Request class will be created as base class for protocol-specific specialisations. The base class will allow clients to send "raw" requests (no header etc.).
- Request class instances will be linked directly to a NetworkHandler instance, so that there is no additional layer when sending/receiving data.
- When calling Request::send() for a Request object, it creates the request header and passes the "raw" data (header + body) to the NetworkHandler.
- The Request class will have a mutex and two semaphores: The first represents the "response header ready" status, the second represents the "response data available" status. Both get locked when the request is made. The first semaphore becomes unlocked once the response header is completely read. The second one becomes unlocked when a data block is available. If that data is passed on, it becomes locked again until the end of the response is read. The mutex makes sure that either a data block is read or written and prevents that both happens at the same time.
- The NetworkHandler starts a new thread for each request before actually sending it. This way, multiple requests can be started at the same time.
- The NetworkHandler thread for a Request object passes data to the Request object in case it hasn't set the "aborted" flag that specifies that the request has been aborted and no more recceived data will be processed.
- In case of an aborted request, the NetworkHandler will end the thread that receives data.
Addendum to concept 3:
Add a ResponseHandler interface and make the Request class an implementation of it. Otherwise, there would be a circular include: Request requires NetworkHandler, NetworkHandler requires Request.
Deleting a branch is permanent. It CANNOT be undone. Continue?