Welcome to mirror list, hosted at ThFree Co, Russian Federation.

HttpResponder.h « Networking « src - github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: d19decba41016981118019bbc44b0b9a3f1686e3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/*
 * HttpResponder.h
 *
 *  Created on: 14 Apr 2017
 *      Author: David
 */

#ifndef SRC_NETWORKING_HTTPRESPONDER_H_
#define SRC_NETWORKING_HTTPRESPONDER_H_

#include "NetworkResponder.h"

class HttpResponder : public NetworkResponder
{
public:
	HttpResponder(NetworkResponder *n);
	bool Spin() override;								// do some work, returning true if we did anything significant
	bool Accept(Socket *s, NetworkProtocol protocol) override;	// ask the responder to accept this connection, returns true if it did
	void Terminate(NetworkProtocol protocol) override;			// terminate the responder if it is serving the specified protocol
	void Diagnostics(MessageType mtype) const override;

	static void InitStatic();
	static void HandleGCodeReply(const char *reply);
	static void HandleGCodeReply(OutputBuffer *reply);
	static uint32_t GetReplySeq() { return seq; }
	static void CheckSessions();
	static void CommonDiagnostics(MessageType mtype);

protected:
	void CancelUpload() override;
	void SendData() override;

private:
	static const size_t MaxHttpSessions = 8;			// maximum number of simultaneous HTTP sessions
	static const uint16_t WebMessageLength = 1460;		// maximum length of the web message we accept after decoding
	static const size_t MaxCommandWords = 4;			// max number of space-separated words in the command
	static const size_t MaxQualKeys = 5;				// max number of key/value pairs in the qualifier
	static const size_t MaxHeaders = 30;				// max number of key/value pairs in the headers
	static const uint32_t HttpSessionTimeout = 8000;	// HTTP session timeout in milliseconds
	static const uint32_t MaxFileInfoGetTime = 1800;	// maximum length of time we spend getting file info, to avoid the client timing out (actual time will be a little longer than this)

	enum class HttpParseState
	{
		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
	};

	struct KeyValueIndices
	{
		const char* key;
		const char* value;
	};

	// HTTP sessions
	struct HttpSession
	{
		uint32_t ip;
		uint32_t lastQueryTime;
		bool isPostUploading;
		uint16_t postPort;
	};

	bool Authenticate();
	bool CheckAuthenticated();
	bool RemoveAuthentication();

	bool CharFromClient(char c);
	void SendFile(const char* nameOfFileToSend, bool isWebFile);
	void SendGCodeReply();
	void SendJsonResponse(const char* command);
	bool GetJsonResponse(const char* request, OutputBuffer *&response, bool& keepOpen);
	void ProcessMessage();
	void ProcessRequest();
	void RejectMessage(const char* s, unsigned int code = 500);
	bool SendFileInfo(bool quitEarly);

	void DoUpload();

	const char* GetKeyValue(const char *key) const;	// return the value of the specified key, or nullptr if not present

	HttpParseState parseState;

	// Buffers for processing HTTP input
	char clientMessage[WebMessageLength + 3];		// holds the command, qualifier, and headers
	size_t clientPointer;							// current index into clientMessage
	char decodeChar;								// the character we are decoding in a URL-encoded argument

	// Parser state
	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

	// rr_fileinfo requests
	uint32_t startedProcessingRequestAt;			// when we started processing the current HTTP request
	char filenameBeingProcessed[MaxFilenameLength];	// The filename being processed (for rr_fileinfo)

	// Keeping track of HTTP sessions
	static HttpSession sessions[MaxHttpSessions];
	static unsigned int numSessions;
	static unsigned int clientsServed;

	// Responses from GCodes class
	static volatile uint32_t seq;					// Sequence number for G-Code replies
	static volatile OutputStack gcodeReply;
	static Mutex gcodeReplyMutex;
};

#endif /* SRC_NETWORKING_HTTPRESPONDER_H_ */