mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-30 12:30:20 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			251 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			251 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /**
 | |
|   @file
 | |
|   @author Stefan Frings
 | |
| */
 | |
| 
 | |
| #ifndef HTTPREQUEST_H
 | |
| #define HTTPREQUEST_H
 | |
| 
 | |
| #include <QByteArray>
 | |
| #include <QHostAddress>
 | |
| #include <QTcpSocket>
 | |
| #include <QMap>
 | |
| #include <QMultiMap>
 | |
| #include <QSettings>
 | |
| #include <QTemporaryFile>
 | |
| #include <QUuid>
 | |
| #include "httpglobal.h"
 | |
| #include "httplistenersettings.h"
 | |
| 
 | |
| #include "export.h"
 | |
| 
 | |
| namespace qtwebapp {
 | |
| 
 | |
| /**
 | |
|   This object represents a single HTTP request. It reads the request
 | |
|   from a TCP socket and provides getters for the individual parts
 | |
|   of the request.
 | |
|   <p>
 | |
|   The following config settings are required:
 | |
|   <code><pre>
 | |
|   maxRequestSize=16000
 | |
|   maxMultiPartSize=1000000
 | |
|   </pre></code>
 | |
|   <p>
 | |
|   MaxRequestSize is the maximum size of a HTTP request. In case of
 | |
|   multipart/form-data requests (also known as file-upload), the maximum
 | |
|   size of the body must not exceed maxMultiPartSize.
 | |
|   The body is always a little larger than the file itself.
 | |
| */
 | |
| 
 | |
| class HTTPSERVER_API HttpRequest {
 | |
|     Q_DISABLE_COPY(HttpRequest)
 | |
|     friend class HttpSessionStore;
 | |
| 
 | |
| public:
 | |
| 
 | |
|     /** Values for getStatus() */
 | |
|     enum RequestStatus {waitForRequest, waitForHeader, waitForBody, complete, abort};
 | |
| 
 | |
|     /**
 | |
|       Constructor.
 | |
|       @param settings Configuration settings
 | |
|     */
 | |
|     HttpRequest(QSettings* settings);
 | |
| 
 | |
|     /**
 | |
|       Constructor.
 | |
|       @param settings Configuration settings as a structure
 | |
|     */
 | |
|     HttpRequest(const HttpListenerSettings* settings);
 | |
| 
 | |
|     /**
 | |
|       Destructor.
 | |
|     */
 | |
|     virtual ~HttpRequest();
 | |
| 
 | |
|     /**
 | |
|       Read the HTTP request from a socket.
 | |
|       This method is called by the connection handler repeatedly
 | |
|       until the status is RequestStatus::complete or RequestStatus::abort.
 | |
|       @param socket Source of the data
 | |
|     */
 | |
|     void readFromSocket(QTcpSocket* socket);
 | |
| 
 | |
|     /**
 | |
|       Get the status of this request.
 | |
|       @see RequestStatus
 | |
|     */
 | |
|     RequestStatus getStatus() const;
 | |
| 
 | |
|     /** Get the method of the HTTP request  (e.g. "GET") */
 | |
|     QByteArray getMethod() const;
 | |
| 
 | |
|     /** Get the decoded path of the HTPP request (e.g. "/index.html") */
 | |
|     QByteArray getPath() const;
 | |
| 
 | |
|     /** Get the raw path of the HTTP request (e.g. "/file%20with%20spaces.html") */
 | |
|     const QByteArray& getRawPath() const;
 | |
| 
 | |
|     /** Get the version of the HTPP request (e.g. "HTTP/1.1") */
 | |
|     QByteArray getVersion() const;
 | |
| 
 | |
|     /**
 | |
|       Get the value of a HTTP request header.
 | |
|       @param name Name of the header, not case-senitive.
 | |
|       @return If the header occurs multiple times, only the last
 | |
|       one is returned.
 | |
|     */
 | |
|     QByteArray getHeader(const QByteArray& name) const;
 | |
| 
 | |
|     /**
 | |
|       Get the values of a HTTP request header.
 | |
|       @param name Name of the header, not case-senitive.
 | |
|     */
 | |
|     QList<QByteArray> getHeaders(const QByteArray& name) const;
 | |
| 
 | |
|     /**
 | |
|      * Get all HTTP request headers. Note that the header names
 | |
|      * are returned in lower-case.
 | |
|      */
 | |
|     QMultiMap<QByteArray,QByteArray> getHeaderMap() const;
 | |
| 
 | |
|     /**
 | |
|       Get the value of a HTTP request parameter.
 | |
|       @param name Name of the parameter, case-sensitive.
 | |
|       @return If the parameter occurs multiple times, only the last
 | |
|       one is returned.
 | |
|     */
 | |
|     QByteArray getParameter(const QByteArray& name) const;
 | |
| 
 | |
|     /**
 | |
|       Get the values of a HTTP request parameter.
 | |
|       @param name Name of the parameter, case-sensitive.
 | |
|     */
 | |
|     QList<QByteArray> getParameters(const QByteArray& name) const;
 | |
| 
 | |
|     /** Get all HTTP request parameters. */
 | |
|     QMultiMap<QByteArray,QByteArray> getParameterMap() const;
 | |
| 
 | |
|     /** Get the HTTP request body.  */
 | |
|     QByteArray getBody() const;
 | |
| 
 | |
|     /**
 | |
|       Decode an URL parameter.
 | |
|       E.g. replace "%23" by '#' and replace '+' by ' '.
 | |
|       @param source The url encoded strings
 | |
|       @see QUrl::toPercentEncoding for the reverse direction
 | |
|     */
 | |
|     static QByteArray urlDecode(const QByteArray source);
 | |
| 
 | |
|     /**
 | |
|       Get an uploaded file. The file is already open. It will
 | |
|       be closed and deleted by the destructor of this HttpRequest
 | |
|       object (after processing the request).
 | |
|       <p>
 | |
|       For uploaded files, the method getParameters() returns
 | |
|       the original fileName as provided by the calling web browser.
 | |
|     */
 | |
|     QTemporaryFile* getUploadedFile(const QByteArray fieldName) const;
 | |
| 
 | |
|     /**
 | |
|       Get the value of a cookie.
 | |
|       @param name Name of the cookie
 | |
|     */
 | |
|     QByteArray getCookie(const QByteArray& name) const;
 | |
| 
 | |
|     /** Get all cookies. */
 | |
|     QMap<QByteArray,QByteArray>& getCookieMap();
 | |
| 
 | |
|     /**
 | |
|       Get the address of the connected client.
 | |
|       Note that multiple clients may have the same IP address, if they
 | |
|       share an internet connection (which is very common).
 | |
|      */
 | |
|     QHostAddress getPeerAddress() const;
 | |
| 
 | |
| private:
 | |
| 
 | |
|     /** Request headers */
 | |
|     QMultiMap<QByteArray,QByteArray> headers;
 | |
| 
 | |
|     /** Parameters of the request */
 | |
|     QMultiMap<QByteArray,QByteArray> parameters;
 | |
| 
 | |
|     /** Uploaded files of the request, key is the field name. */
 | |
|     QMap<QByteArray,QTemporaryFile*> uploadedFiles;
 | |
| 
 | |
|     /** Received cookies */
 | |
|     QMap<QByteArray,QByteArray> cookies;
 | |
| 
 | |
|     /** Storage for raw body data */
 | |
|     QByteArray bodyData;
 | |
| 
 | |
|     /** Request method */
 | |
|     QByteArray method;
 | |
| 
 | |
|     /** Request path (in raw encoded format) */
 | |
|     QByteArray path;
 | |
| 
 | |
|     /** Request protocol version */
 | |
|     QByteArray version;
 | |
| 
 | |
|     /**
 | |
|       Status of this request. For the state engine.
 | |
|       @see RequestStatus
 | |
|     */
 | |
|     RequestStatus status;
 | |
| 
 | |
|     /** Address of the connected peer. */
 | |
|     QHostAddress peerAddress;
 | |
| 
 | |
|     /** Maximum size of requests in bytes. */
 | |
|     int maxSize;
 | |
| 
 | |
|     /** Maximum allowed size of multipart forms in bytes. */
 | |
|     int maxMultiPartSize;
 | |
| 
 | |
|     /** Current size */
 | |
|     int currentSize;
 | |
| 
 | |
|     /** Expected size of body */
 | |
|     int expectedBodySize;
 | |
| 
 | |
|     /** Name of the current header, or empty if no header is being processed */
 | |
|     QByteArray currentHeader;
 | |
| 
 | |
|     /** Boundary of multipart/form-data body. Empty if there is no such header */
 | |
|     QByteArray boundary;
 | |
| 
 | |
|     /** Temp file, that is used to store the multipart/form-data body */
 | |
|     QTemporaryFile* tempFile;
 | |
| 
 | |
|     /** Parse the multipart body, that has been stored in the temp file. */
 | |
|     void parseMultiPartFile();
 | |
| 
 | |
|     /** Sub-procedure of readFromSocket(), read the first line of a request. */
 | |
|     void readRequest(QTcpSocket* socket);
 | |
| 
 | |
|     /** Sub-procedure of readFromSocket(), read header lines. */
 | |
|     void readHeader(QTcpSocket* socket);
 | |
| 
 | |
|     /** Sub-procedure of readFromSocket(), read the request body. */
 | |
|     void readBody(QTcpSocket* socket);
 | |
| 
 | |
|     /** Sub-procedure of readFromSocket(), extract and decode request parameters. */
 | |
|     void decodeRequestParams();
 | |
| 
 | |
|     /** Sub-procedure of readFromSocket(), extract cookies from headers */
 | |
|     void extractCookies();
 | |
| 
 | |
|     /** Buffer for collecting characters of request and header lines */
 | |
|     QByteArray lineBuffer;
 | |
| 
 | |
|     /** Settings flag */
 | |
|     bool useQtSettings;
 | |
| };
 | |
| 
 | |
| } // end of namespace
 | |
| 
 | |
| #endif // HTTPREQUEST_H
 |