diff options
Diffstat (limited to 'src/Duet/Webserver.h')
-rw-r--r-- | src/Duet/Webserver.h | 382 |
1 files changed, 0 insertions, 382 deletions
diff --git a/src/Duet/Webserver.h b/src/Duet/Webserver.h deleted file mode 100644 index d2bab356..00000000 --- a/src/Duet/Webserver.h +++ /dev/null @@ -1,382 +0,0 @@ -/**************************************************************************************************** - -RepRapFirmware - Webserver - -This class serves a single-page web applications to the attached network. This page forms the user's -interface with the RepRap machine. This software interprests returned values from the page and uses it -to Generate G Codes, which it sends to the RepRap. It also collects values from the RepRap like -temperature and uses those to construct the web page. - -The page itself - reprap.htm - uses Knockout.js and Jquery.js. See: - -http://knockoutjs.com/ - -http://jquery.com/ - ------------------------------------------------------------------------------------------------------ - -Version 0.2 - -10 May 2013 - -Adrian Bowyer -RepRap Professional Ltd -http://reprappro.com - -Licence: GPL - -****************************************************************************************************/ - -#ifndef WEBSERVER_H -#define WEBSERVER_H - -#include "lwipopts.h" - -/* Generic values */ - -const size_t gcodeBufferLength = 512; // size of our gcode ring buffer, preferably a power of 2 - -/* HTTP */ - -#define KO_START "rr_" -#define KO_FIRST 3 - -const uint16_t webMessageLength = TCP_MSS; // maximum length of the web message we accept after decoding -const size_t minHttpResponseSize = 768; // minimum number of bytes required for an HTTP response - -const size_t maxCommandWords = 4; // max number of space-separated words in the command -const size_t maxQualKeys = 5; // max number of key/value pairs in the qualifier -const size_t maxHeaders = 16; // max number of key/value pairs in the headers - -const size_t maxHttpSessions = 8; // maximum number of simultaneous HTTP sessions -const uint32_t httpSessionTimeout = 8000; // HTTP session timeout in milliseconds - -/* FTP */ - -const uint16_t ftpMessageLength = 128; // maximum line length for incoming FTP commands -const uint32_t ftpPasvPortTimeout = 10000; // maximum time to wait for an FTP data connection in milliseconds - -/* Telnet */ - -const uint32_t telnetSetupDuration = 4000; // ignore the first Telnet request within this duration (in ms) - - -class Webserver; - -// List of protocols that can execute G-Codes -enum class WebSource -{ - HTTP, - Telnet -}; - -// This is the abstract class for all supported protocols -// Any inherited class should implement a state machine to increase performance and reduce memory usage. -class ProtocolInterpreter -{ - public: - - ProtocolInterpreter(Platform *p, Webserver *ws, Network *n); - virtual ~ProtocolInterpreter() { } // to keep Eclipse happy - virtual void Diagnostics(MessageType mtype) = 0; - virtual void Spin(); - - virtual void ConnectionEstablished(); - virtual void ConnectionLost(const ConnectionState *cs) { } - virtual bool CanParseData(); - virtual bool CharFromClient(const char c) = 0; - virtual void NoMoreDataAvailable(); - - virtual bool DoingFastUpload() const; - virtual void DoFastUpload(); - void CancelUpload(); // may be called from ISR! - - protected: - - Platform *platform; - Webserver *webserver; - Network *network; - - // Information for file uploading - enum UploadState - { - notUploading, // no upload in progress - uploadOK, // upload in progress, no error so far - uploadError // upload in progress but had error - }; - - UploadState uploadState; - FileData fileBeingUploaded; - char filenameBeingUploaded[FILENAME_LENGTH]; - - bool StartUpload(FileStore *file, const char *fileName); - bool IsUploading() const; - bool FinishUpload(uint32_t fileLength); -}; - -class Webserver -{ - public: - - friend class Platform; - friend class ProtocolInterpreter; - - Webserver(Platform* p, Network *n); - void Init(); - void Spin(); - void Exit(); - void Diagnostics(MessageType mtype); - - bool GCodeAvailable(const WebSource source) const; - char ReadGCode(const WebSource source); - void HandleGCodeReply(const WebSource source, OutputBuffer *reply); - void HandleGCodeReply(const WebSource source, const char *reply); - uint32_t GetReplySeq() const; - - // Returns the available G-Code buffer space of the HTTP interpreter (may be dropped in a future version) - uint16_t GetGCodeBufferSpace(const WebSource source) const; - - void ConnectionLost(const ConnectionState *cs); - void ConnectionError(); - - protected: - - class HttpInterpreter : public ProtocolInterpreter - { - public: - - HttpInterpreter(Platform *p, Webserver *ws, Network *n); - void Spin(); - void Diagnostics(MessageType mtype) override; - void ConnectionLost(const ConnectionState *cs); - bool CanParseData() override; - bool CharFromClient(const char c) override; - void NoMoreDataAvailable() override; - void ResetState(); - void ResetSessions(); - - bool DoingFastUpload() const override; - void DoFastUpload(); - - bool GCodeAvailable() const; - char ReadGCode(); - void HandleGCodeReply(OutputBuffer *reply); - void HandleGCodeReply(const char *reply); - uint16_t GetGCodeBufferSpace() const; - uint32_t GetReplySeq() const; - - private: - - // HTTP server state enumeration. The order is important, in particular xxxEsc1 must follow xxx, and xxxEsc2 must follow xxxEsc1. - // We assume that qualifier keys do not contain escapes, because none of ours needs to be encoded. If we are sent escapes in the key, - // it won't do any harm, but the key won't be recognised even if it would be valid were it decoded. - enum HttpState - { - doingCommandWord, // receiving a word in the first line of the HTTP request - doingFilename, // receiving the filename (second word in the command line) - doingFilenameEsc1, // received '%' in the filename (e.g. we are being asked for a filename with spaces in it) - doingFilenameEsc2, // received '%' and one hex digit in the filename - doingQualifierKey, // receiving a key name in the HTTP request - doingQualifierValue, // receiving a key value in the HTTP request - doingQualifierValueEsc1, // received '%' in the qualifier - doingQualifierValueEsc2, // received '%' and one hex digit in the qualifier - doingHeaderKey, // receiving a header key - expectingHeaderValue, // expecting a header value - doingHeaderValue, // receiving a header value - doingHeaderContinuation // received a newline after a header value - }; - HttpState state; - - struct KeyValueIndices - { - const char* key; - const char* value; - }; - - void SendFile(const char* nameOfFileToSend, bool isWebFile); - void SendGCodeReply(); - void SendJsonResponse(const char* command); - void GetJsonResponse(const char* request, OutputBuffer *&response, const char* key, const char* value, size_t valueLength, bool& keepOpen); - bool ProcessMessage(); - bool RejectMessage(const char* s, unsigned int code = 500); - - // Buffers for processing HTTP input - char clientMessage[webMessageLength + 3]; // holds the command, qualifier, and headers - size_t clientPointer; // current index into clientMessage - char decodeChar; - - const char* commandWords[maxCommandWords]; - KeyValueIndices qualifiers[maxQualKeys + 1]; // offsets into clientQualifier of the key/value pairs, the +1 is needed so that values can contain nulls - KeyValueIndices headers[maxHeaders]; // offsets into clientHeader of the key/value pairs - size_t numCommandWords; - size_t numQualKeys; // number of qualifier keys we have found, <= maxQualKeys - size_t numHeaderKeys; // number of keys we have found, <= maxHeaders - - // HTTP sessions - struct HttpSession - { - uint32_t ip; - uint32_t lastQueryTime; - bool isPostUploading; - uint16_t postPort; - }; - - HttpSession sessions[maxHttpSessions]; - uint8_t numSessions; - uint8_t clientsServed; - - bool Authenticate(); - bool IsAuthenticated() const; - void UpdateAuthentication(); - bool RemoveAuthentication(); - - // Deal with incoming G-Codes - - char gcodeBuffer[gcodeBufferLength]; - uint16_t gcodeReadIndex, gcodeWriteIndex; // head and tail indices into gcodeBuffer - - void LoadGcodeBuffer(const char* gc); - void ProcessGcode(const char* gc); - void StoreGcodeData(const char* data, uint16_t len); - - // Responses from GCodes class - - uint32_t seq; // Sequence number for G-Code replies - OutputStack *gcodeReply; - - // File uploads - uint32_t postFileLength, uploadedBytes; // How many POST bytes do we expect and how many have already been written? - time_t fileLastModified; - - // Deferred requests (rr_fileinfo) - ConnectionState * volatile deferredRequestConnection; // Which connection expects a response for a deferred request? - char filenameBeingProcessed[FILENAME_LENGTH]; // The filename being processed (for rr_fileinfo) - - void ProcessDeferredRequest(); - }; - HttpInterpreter *httpInterpreter; - - class FtpInterpreter : public ProtocolInterpreter - { - public: - - FtpInterpreter(Platform *p, Webserver *ws, Network *n); - void Diagnostics(MessageType mtype) override; - - void ConnectionEstablished() override; - void ConnectionLost(const ConnectionState *cs) override; - bool CharFromClient(const char c) override; - void ResetState(); - - bool DoingFastUpload() const override; - - private: - - enum FtpState - { - idle, // no client connected - authenticating, // not logged in - authenticated, // logged in - waitingForPasvPort, // waiting for connection to be established on PASV port - pasvPortConnected, // client connected to PASV port, ready to send data - doingPasvIO // client is connected and data is being transferred - }; - FtpState state; - uint8_t connectedClients; - - char clientMessage[ftpMessageLength]; - size_t clientPointer; - - char filename[FILENAME_LENGTH]; - char currentDir[FILENAME_LENGTH]; - - uint32_t portOpenTime; - - void ProcessLine(); - void SendReply(int code, const char *message, bool keepConnection = true); - void SendFeatures(); - - void ReadFilename(uint16_t start); - void ChangeDirectory(const char *newDirectory); - }; - FtpInterpreter *ftpInterpreter; - - class TelnetInterpreter : public ProtocolInterpreter - { - public: - - TelnetInterpreter(Platform *p, Webserver *ws, Network *n); - void Diagnostics(MessageType mtype) override; - - void ConnectionEstablished() override; - void ConnectionLost(const ConnectionState *cs) override; - bool CanParseData() override; - bool CharFromClient(const char c) override; - void ResetState(); - - bool GCodeAvailable() const; - char ReadGCode(); - void HandleGCodeReply(OutputBuffer *reply); - void HandleGCodeReply(const char *reply); - uint16_t GetGCodeBufferSpace() const; - - void SendGCodeReply(); - - private: - - enum TelnetState - { - idle, // not connected - justConnected, // not logged in, but the client has just connected - authenticating, // not logged in - authenticated // logged in - }; - TelnetState state; - uint8_t connectedClients; - uint32_t connectTime; - - bool processNextLine; - char clientMessage[GCODE_LENGTH]; - size_t clientPointer; - - bool ProcessLine(); - - // Deal with incoming G-Codes - - char gcodeBuffer[gcodeBufferLength]; - uint16_t gcodeReadIndex, gcodeWriteIndex; // head and tail indices into gcodeBuffer - - void ProcessGcode(const char* gc); - void StoreGcodeData(const char* data, uint16_t len); - - // Converted response from GCodes class (NL -> CRNL) - - OutputBuffer * volatile gcodeReply; - }; - TelnetInterpreter *telnetInterpreter; - - private: - - Platform* platform; - Network* network; - bool webserverActive; - NetworkTransaction *currentTransaction; - ConnectionState * volatile readingConnection; - - float longWait; -}; - -inline bool ProtocolInterpreter::CanParseData() { return true; } -inline bool ProtocolInterpreter::DoingFastUpload() const { return false; } -inline bool ProtocolInterpreter::IsUploading() const { return uploadState != notUploading; } - -inline uint32_t Webserver::GetReplySeq() const { return httpInterpreter->GetReplySeq(); } - -inline uint16_t Webserver::HttpInterpreter::GetGCodeBufferSpace() const { return (gcodeReadIndex - gcodeWriteIndex - 1u) % gcodeBufferLength; } -inline bool Webserver::HttpInterpreter::GCodeAvailable() const { return gcodeReadIndex != gcodeWriteIndex; } -inline uint32_t Webserver::HttpInterpreter::GetReplySeq() const { return seq; } - -inline uint16_t Webserver::TelnetInterpreter::GetGCodeBufferSpace() const { return (gcodeReadIndex - gcodeWriteIndex - 1u) % gcodeBufferLength; } -inline bool Webserver::TelnetInterpreter::GCodeAvailable() const { return gcodeReadIndex != gcodeWriteIndex; } - -#endif |