SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
Public Types | Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes | Friends | List of all members
qtwebapp::HttpRequest Class Reference

#include <httprequest.h>

Public Types

enum  RequestStatus {
  waitForRequest, waitForHeader, waitForBody, complete,
  abort
}
 

Public Member Functions

 HttpRequest (QSettings *settings)
 
 HttpRequest (const HttpListenerSettings *settings)
 
virtual ~HttpRequest ()
 
void readFromSocket (QTcpSocket *socket)
 
RequestStatus getStatus () const
 
QByteArray getMethod () const
 
QByteArray getPath () const
 
const QByteArray & getRawPath () const
 
QByteArray getVersion () const
 
QByteArray getHeader (const QByteArray &name) const
 
QList< QByteArray > getHeaders (const QByteArray &name) const
 
QMultiMap< QByteArray, QByteArray > getHeaderMap () const
 
QByteArray getParameter (const QByteArray &name) const
 
QList< QByteArray > getParameters (const QByteArray &name) const
 
QMultiMap< QByteArray, QByteArray > getParameterMap () const
 
QByteArray getBody () const
 
QTemporaryFile * getUploadedFile (const QByteArray fieldName) const
 
QByteArray getCookie (const QByteArray &name) const
 
QMap< QByteArray, QByteArray > & getCookieMap ()
 
QHostAddress getPeerAddress () const
 

Static Public Member Functions

static QByteArray urlDecode (const QByteArray source)
 

Private Member Functions

void parseMultiPartFile ()
 
void readRequest (QTcpSocket *socket)
 
void readHeader (QTcpSocket *socket)
 
void readBody (QTcpSocket *socket)
 
void decodeRequestParams ()
 
void extractCookies ()
 

Private Attributes

QMultiMap< QByteArray, QByteArray > headers
 
QMultiMap< QByteArray, QByteArray > parameters
 
QMap< QByteArray, QTemporaryFile * > uploadedFiles
 
QMap< QByteArray, QByteArray > cookies
 
QByteArray bodyData
 
QByteArray method
 
QByteArray path
 
QByteArray version
 
RequestStatus status
 
QHostAddress peerAddress
 
int maxSize
 
int maxMultiPartSize
 
int currentSize
 
int expectedBodySize
 
QByteArray currentHeader
 
QByteArray boundary
 
QTemporaryFile * tempFile
 
QByteArray lineBuffer
 
bool useQtSettings
 

Friends

class HttpSessionStore
 

Detailed Description

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.

The follwing config settings are required:

maxRequestSize=16000
maxMultiPartSize=1000000

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.

Definition at line 41 of file httprequest.h.

Member Enumeration Documentation

◆ RequestStatus

Constructor & Destructor Documentation

◆ HttpRequest() [1/2]

HttpRequest::HttpRequest ( QSettings *  settings)

Constructor.

Parameters
settingsConfiguration settings

Definition at line 15 of file httprequest.cpp.

References currentSize, expectedBodySize, maxMultiPartSize, maxSize, status, tempFile, and waitForRequest.

15  :
16  useQtSettings(true)
17 {
18  Q_ASSERT(settings != 0);
20  currentSize=0;
22  maxSize=settings->value("maxRequestSize","16000").toInt();
23  maxMultiPartSize=settings->value("maxMultiPartSize","1000000").toInt();
24  tempFile=0;
25 }
QTemporaryFile * tempFile
Definition: httprequest.h:221
RequestStatus status
Definition: httprequest.h:197

◆ HttpRequest() [2/2]

HttpRequest::HttpRequest ( const HttpListenerSettings settings)

◆ ~HttpRequest()

HttpRequest::~HttpRequest ( )
virtual

Destructor.

Definition at line 542 of file httprequest.cpp.

References tempFile, and uploadedFiles.

543 {
544  foreach(QByteArray key, uploadedFiles.keys())
545  {
546  QTemporaryFile* file=uploadedFiles.value(key);
547  if (file->isOpen())
548  {
549  file->close();
550  }
551  delete file;
552  }
553  if (tempFile != NULL)
554  {
555  if (tempFile->isOpen())
556  {
557  tempFile->close();
558  }
559  delete tempFile;
560  }
561 }
QTemporaryFile * tempFile
Definition: httprequest.h:221
QMap< QByteArray, QTemporaryFile * > uploadedFiles
Definition: httprequest.h:176

Member Function Documentation

◆ decodeRequestParams()

void HttpRequest::decodeRequestParams ( )
private

Sub-procedure of readFromSocket(), extract and decode request parameters.

Definition at line 228 of file httprequest.cpp.

References bodyData, headers, parameters, path, and urlDecode().

Referenced by readFromSocket().

229 {
230  #ifdef SUPERVERBOSE
231  qDebug("HttpRequest::decodeRequestParams: extract and decode request parameters");
232  #endif
233  // Get URL parameters
234  QByteArray rawParameters;
235  int questionMark=path.indexOf('?');
236  if (questionMark>=0)
237  {
238  rawParameters=path.mid(questionMark+1);
239  path=path.left(questionMark);
240  }
241  // Get request body parameters
242  QByteArray contentType=headers.value("content-type");
243  if (!bodyData.isEmpty() && (contentType.isEmpty() || contentType.startsWith("application/x-www-form-urlencoded")))
244  {
245  if (!rawParameters.isEmpty())
246  {
247  rawParameters.append('&');
248  rawParameters.append(bodyData);
249  }
250  else
251  {
252  rawParameters=bodyData;
253  }
254  }
255  // Split the parameters into pairs of value and name
256  QList<QByteArray> list=rawParameters.split('&');
257  foreach (QByteArray part, list)
258  {
259  int equalsChar=part.indexOf('=');
260  if (equalsChar>=0)
261  {
262  QByteArray name=part.left(equalsChar).trimmed();
263  QByteArray value=part.mid(equalsChar+1).trimmed();
264  parameters.insert(urlDecode(name),urlDecode(value));
265  }
266  else if (!part.isEmpty())
267  {
268  // Name without value
269  parameters.insert(urlDecode(part),"");
270  }
271  }
272 }
QMultiMap< QByteArray, QByteArray > parameters
Definition: httprequest.h:173
static QByteArray urlDecode(const QByteArray source)
QMultiMap< QByteArray, QByteArray > headers
Definition: httprequest.h:170
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ extractCookies()

void HttpRequest::extractCookies ( )
private

Sub-procedure of readFromSocket(), extract cookies from headers

Definition at line 274 of file httprequest.cpp.

References cookies, headers, and qtwebapp::HttpCookie::splitCSV().

Referenced by readFromSocket().

275 {
276  #ifdef SUPERVERBOSE
277  qDebug("HttpRequest::extractCookies");
278  #endif
279  foreach(QByteArray cookieStr, headers.values("cookie"))
280  {
281  QList<QByteArray> list=HttpCookie::splitCSV(cookieStr);
282  foreach(QByteArray part, list)
283  {
284  #ifdef SUPERVERBOSE
285  qDebug("HttpRequest::extractCookies: found cookie %s",part.data());
286  #endif // Split the part into name and value
287  QByteArray name;
288  QByteArray value;
289  int posi=part.indexOf('=');
290  if (posi)
291  {
292  name=part.left(posi).trimmed();
293  value=part.mid(posi+1).trimmed();
294  }
295  else
296  {
297  name=part.trimmed();
298  value="";
299  }
300  cookies.insert(name,value);
301  }
302  }
303  headers.remove("cookie");
304 }
QMultiMap< QByteArray, QByteArray > headers
Definition: httprequest.h:170
static QList< QByteArray > splitCSV(const QByteArray source)
Definition: httpcookie.cpp:219
QMap< QByteArray, QByteArray > cookies
Definition: httprequest.h:179
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getBody()

QByteArray HttpRequest::getBody ( ) const

◆ getCookie()

QByteArray HttpRequest::getCookie ( const QByteArray &  name) const

Get the value of a cookie.

Parameters
nameName of the cookie

Definition at line 568 of file httprequest.cpp.

References cookies.

Referenced by qtwebapp::HttpSessionStore::getSessionId().

569 {
570  return cookies.value(name);
571 }
QMap< QByteArray, QByteArray > cookies
Definition: httprequest.h:179
+ Here is the caller graph for this function:

◆ getCookieMap()

QMap< QByteArray, QByteArray > & HttpRequest::getCookieMap ( )

Get all cookies.

Get the map of cookies

Definition at line 574 of file httprequest.cpp.

References cookies.

575 {
576  return cookies;
577 }
QMap< QByteArray, QByteArray > cookies
Definition: httprequest.h:179

◆ getHeader()

QByteArray HttpRequest::getHeader ( const QByteArray &  name) const

Get the value of a HTTP request header.

Parameters
nameName of the header, not case-senitive.
Returns
If the header occurs multiple times, only the last one is returned.

Definition at line 366 of file httprequest.cpp.

References headers.

Referenced by qtwebapp::HttpConnectionHandler::read().

367 {
368  return headers.value(name.toLower());
369 }
QMultiMap< QByteArray, QByteArray > headers
Definition: httprequest.h:170
+ Here is the caller graph for this function:

◆ getHeaderMap()

QMultiMap< QByteArray, QByteArray > HttpRequest::getHeaderMap ( ) const

Get all HTTP request headers. Note that the header names are returned in lower-case.

Definition at line 376 of file httprequest.cpp.

References headers.

377 {
378  return headers;
379 }
QMultiMap< QByteArray, QByteArray > headers
Definition: httprequest.h:170

◆ getHeaders()

QList< QByteArray > HttpRequest::getHeaders ( const QByteArray &  name) const

Get the values of a HTTP request header.

Parameters
nameName of the header, not case-senitive.

Definition at line 371 of file httprequest.cpp.

References headers.

372 {
373  return headers.values(name.toLower());
374 }
QMultiMap< QByteArray, QByteArray > headers
Definition: httprequest.h:170

◆ getMethod()

QByteArray HttpRequest::getMethod ( ) const

Get the method of the HTTP request (e.g. "GET")

Definition at line 342 of file httprequest.cpp.

References method.

Referenced by WebAPIRequestMapper::devicesetChannelIndexService(), WebAPIRequestMapper::devicesetChannelReportService(), WebAPIRequestMapper::devicesetChannelService(), WebAPIRequestMapper::devicesetChannelSettingsService(), WebAPIRequestMapper::devicesetChannelsReportService(), WebAPIRequestMapper::devicesetDeviceReportService(), WebAPIRequestMapper::devicesetDeviceRunService(), WebAPIRequestMapper::devicesetDeviceService(), WebAPIRequestMapper::devicesetDeviceSettingsService(), WebAPIRequestMapper::devicesetFocusService(), WebAPIRequestMapper::devicesetService(), WebAPIRequestMapper::instanceAMBEDevicesService(), WebAPIRequestMapper::instanceAMBESerialService(), WebAPIRequestMapper::instanceAudioInputCleanupService(), WebAPIRequestMapper::instanceAudioInputParametersService(), WebAPIRequestMapper::instanceAudioOutputCleanupService(), WebAPIRequestMapper::instanceAudioOutputParametersService(), WebAPIRequestMapper::instanceAudioService(), WebAPIRequestMapper::instanceChannelsService(), WebAPIRequestMapper::instanceConfigService(), WebAPIRequestMapper::instanceDeviceSetService(), WebAPIRequestMapper::instanceDeviceSetsService(), WebAPIRequestMapper::instanceDevicesService(), WebAPIRequestMapper::instanceLocationService(), WebAPIRequestMapper::instanceLoggingService(), WebAPIRequestMapper::instancePresetFileService(), WebAPIRequestMapper::instancePresetService(), WebAPIRequestMapper::instancePresetsService(), WebAPIRequestMapper::instanceSummaryService(), qtwebapp::HttpConnectionHandler::read(), WebAPIRequestMapper::service(), and qtwebapp::HttpRequestHandler::service().

343 {
344  return method;
345 }
+ Here is the caller graph for this function:

◆ getParameter()

QByteArray HttpRequest::getParameter ( const QByteArray &  name) const

Get the value of a HTTP request parameter.

Parameters
nameName of the parameter, case-sensitive.
Returns
If the parameter occurs multiple times, only the last one is returned.

Definition at line 381 of file httprequest.cpp.

References parameters.

Referenced by WebAPIRequestMapper::instanceChannelsService(), WebAPIRequestMapper::instanceDeviceSetService(), and WebAPIRequestMapper::instanceDevicesService().

382 {
383  return parameters.value(name);
384 }
QMultiMap< QByteArray, QByteArray > parameters
Definition: httprequest.h:173
+ Here is the caller graph for this function:

◆ getParameterMap()

QMultiMap< QByteArray, QByteArray > HttpRequest::getParameterMap ( ) const

Get all HTTP request parameters.

Definition at line 391 of file httprequest.cpp.

References parameters.

392 {
393  return parameters;
394 }
QMultiMap< QByteArray, QByteArray > parameters
Definition: httprequest.h:173

◆ getParameters()

QList< QByteArray > HttpRequest::getParameters ( const QByteArray &  name) const

Get the values of a HTTP request parameter.

Parameters
nameName of the parameter, case-sensitive.

Definition at line 386 of file httprequest.cpp.

References parameters.

387 {
388  return parameters.values(name);
389 }
QMultiMap< QByteArray, QByteArray > parameters
Definition: httprequest.h:173

◆ getPath()

QByteArray HttpRequest::getPath ( ) const

Get the decoded path of the HTPP request (e.g. "/index.html")

Definition at line 348 of file httprequest.cpp.

References path, and urlDecode().

Referenced by qtwebapp::HttpConnectionHandler::read(), WebAPIRequestMapper::service(), qtwebapp::HttpRequestHandler::service(), and qtwebapp::StaticFileController::service().

349 {
350  return urlDecode(path);
351 }
static QByteArray urlDecode(const QByteArray source)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getPeerAddress()

QHostAddress HttpRequest::getPeerAddress ( ) const

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).

Definition at line 584 of file httprequest.cpp.

References peerAddress.

Referenced by qtwebapp::HttpConnectionHandler::read().

585 {
586  return peerAddress;
587 }
QHostAddress peerAddress
Definition: httprequest.h:200
+ Here is the caller graph for this function:

◆ getRawPath()

const QByteArray & HttpRequest::getRawPath ( ) const

Get the raw path of the HTTP request (e.g. "/file%20with%20spaces.html")

Definition at line 354 of file httprequest.cpp.

References path.

355 {
356  return path;
357 }

◆ getStatus()

HttpRequest::RequestStatus HttpRequest::getStatus ( ) const

Get the status of this reqeust.

See also
RequestStatus

Definition at line 336 of file httprequest.cpp.

References status.

Referenced by qtwebapp::HttpConnectionHandler::read().

337 {
338  return status;
339 }
RequestStatus status
Definition: httprequest.h:197
+ Here is the caller graph for this function:

◆ getUploadedFile()

QTemporaryFile * HttpRequest::getUploadedFile ( const QByteArray  fieldName) const

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).

For uploaded files, the method getParameters() returns the original fileName as provided by the calling web browser.

Definition at line 563 of file httprequest.cpp.

References uploadedFiles.

564 {
565  return uploadedFiles.value(fieldName);
566 }
QMap< QByteArray, QTemporaryFile * > uploadedFiles
Definition: httprequest.h:176

◆ getVersion()

QByteArray HttpRequest::getVersion ( ) const

Get the version of the HTPP request (e.g. "HTTP/1.1")

Definition at line 360 of file httprequest.cpp.

References version.

Referenced by qtwebapp::HttpConnectionHandler::read(), and qtwebapp::HttpRequestHandler::service().

361 {
362  return version;
363 }
+ Here is the caller graph for this function:

◆ parseMultiPartFile()

void HttpRequest::parseMultiPartFile ( )
private

Parse the multipart body, that has been stored in the temp file.

Definition at line 420 of file httprequest.cpp.

References boundary, currentSize, parameters, tempFile, and uploadedFiles.

Referenced by readBody().

421 {
422  qDebug("HttpRequest::parseMultiPartFile: parsing multipart temp file");
423  tempFile->seek(0);
424  bool finished=false;
425  while (!tempFile->atEnd() && !finished && !tempFile->error())
426  {
427  #ifdef SUPERVERBOSE
428  qDebug("HttpRequest::parseMultiPartFile: reading multpart headers");
429  #endif
430  QByteArray fieldName;
431  QByteArray fileName;
432  while (!tempFile->atEnd() && !finished && !tempFile->error())
433  {
434  QByteArray line=tempFile->readLine(65536).trimmed();
435  if (line.startsWith("Content-Disposition:"))
436  {
437  if (line.contains("form-data"))
438  {
439  int start=line.indexOf(" name=\"");
440  int end=line.indexOf("\"",start+7);
441  if (start>=0 && end>=start)
442  {
443  fieldName=line.mid(start+7,end-start-7);
444  }
445  start=line.indexOf(" filename=\"");
446  end=line.indexOf("\"",start+11);
447  if (start>=0 && end>=start)
448  {
449  fileName=line.mid(start+11,end-start-11);
450  }
451  #ifdef SUPERVERBOSE
452  qDebug("HttpRequest::parseMultiPartFile: multipart field=%s, filename=%s",fieldName.data(),fileName.data());
453  #endif
454  }
455  else
456  {
457  qDebug("HttpRequest::parseMultiPartFile: ignoring unsupported content part %s",line.data());
458  }
459  }
460  else if (line.isEmpty())
461  {
462  break;
463  }
464  }
465 
466  #ifdef SUPERVERBOSE
467  qDebug("HttpRequest::parseMultiPartFile: reading multpart data");
468  #endif
469  QTemporaryFile* uploadedFile=0;
470  QByteArray fieldValue;
471  while (!tempFile->atEnd() && !finished && !tempFile->error())
472  {
473  QByteArray line=tempFile->readLine(65536);
474  if (line.startsWith("--"+boundary))
475  {
476  // Boundary found. Until now we have collected 2 bytes too much,
477  // so remove them from the last result
478  if (fileName.isEmpty() && !fieldName.isEmpty())
479  {
480  // last field was a form field
481  fieldValue.remove(fieldValue.size()-2,2);
482  parameters.insert(fieldName,fieldValue);
483  qDebug("HttpRequest: set parameter %s=%s",fieldName.data(),fieldValue.data());
484  }
485  else if (!fileName.isEmpty() && !fieldName.isEmpty())
486  {
487  // last field was a file
488  #ifdef SUPERVERBOSE
489  qDebug("HttpRequest::parseMultiPartFile: finishing writing to uploaded file");
490  #endif
491  parameters.insert(fieldName,fileName);
492  if (uploadedFile)
493  {
494  uploadedFile->resize(uploadedFile->size()-2);
495  uploadedFile->flush();
496  uploadedFile->seek(0);
497  qDebug("HttpRequest::parseMultiPartFile: set parameter %s=%s",fieldName.data(),fileName.data());
498  uploadedFiles.insert(fieldName,uploadedFile);
499  qDebug("HttpRequest::parseMultiPartFile: uploaded file size is %i",(int) uploadedFile->size());
500  }
501  }
502  if (line.contains(boundary+"--"))
503  {
504  finished=true;
505  }
506  break;
507  }
508  else
509  {
510  if (fileName.isEmpty() && !fieldName.isEmpty())
511  {
512  // this is a form field.
513  currentSize+=line.size();
514  fieldValue.append(line);
515  }
516  else if (!fileName.isEmpty() && !fieldName.isEmpty())
517  {
518  // this is a file
519  if (!uploadedFile)
520  {
521  uploadedFile=new QTemporaryFile();
522  uploadedFile->open();
523  }
524  uploadedFile->write(line);
525  if (uploadedFile->error())
526  {
527  qCritical("HttpRequest::parseMultiPartFile: error writing temp file, %s",qPrintable(uploadedFile->errorString()));
528  }
529  }
530  }
531  }
532  }
533  if (tempFile->error())
534  {
535  qCritical("HttpRequest::parseMultiPartFile: cannot read temp file, %s",qPrintable(tempFile->errorString()));
536  }
537  #ifdef SUPERVERBOSE
538  qDebug("HttpRequest::parseMultiPartFile: finished parsing multipart temp file");
539  #endif
540 }
QTemporaryFile * tempFile
Definition: httprequest.h:221
QMultiMap< QByteArray, QByteArray > parameters
Definition: httprequest.h:173
QMap< QByteArray, QTemporaryFile * > uploadedFiles
Definition: httprequest.h:176
+ Here is the caller graph for this function:

◆ readBody()

void HttpRequest::readBody ( QTcpSocket *  socket)
private

Sub-procedure of readFromSocket(), read the request body.

Definition at line 165 of file httprequest.cpp.

References abort, bodyData, boundary, complete, currentSize, expectedBodySize, maxMultiPartSize, parseMultiPartFile(), status, and tempFile.

Referenced by readFromSocket().

166 {
167  Q_ASSERT(expectedBodySize!=0);
168  if (boundary.isEmpty())
169  {
170  // normal body, no multipart
171  #ifdef SUPERVERBOSE
172  qDebug("HttpRequest::readBody: receive body");
173  #endif
174  int toRead=expectedBodySize-bodyData.size();
175  QByteArray newData=socket->read(toRead);
176  currentSize+=newData.size();
177  bodyData.append(newData);
178  if (bodyData.size()>=expectedBodySize)
179  {
181  }
182  }
183  else
184  {
185  // multipart body, store into temp file
186  #ifdef SUPERVERBOSE
187  qDebug("HttpRequest::readBody: receiving multipart body");
188  #endif
189  // Create an object for the temporary file, if not already present
190  if (tempFile == NULL)
191  {
192  tempFile = new QTemporaryFile;
193  }
194  if (!tempFile->isOpen())
195  {
196  tempFile->open();
197  }
198  // Transfer data in 64kb blocks
199  int fileSize=tempFile->size();
200  int toRead=expectedBodySize-fileSize;
201  if (toRead>65536)
202  {
203  toRead=65536;
204  }
205  fileSize+=tempFile->write(socket->read(toRead));
206  if (fileSize>=maxMultiPartSize)
207  {
208  qWarning("HttpRequest::readBody: received too many multipart bytes");
209  status=abort;
210  }
211  else if (fileSize>=expectedBodySize)
212  {
213  #ifdef SUPERVERBOSE
214  qDebug("HttpRequest::readBody: received whole multipart body");
215  #endif
216  tempFile->flush();
217  if (tempFile->error())
218  {
219  qCritical("HttpRequest::readBody: Error writing temp file for multipart body");
220  }
222  tempFile->close();
224  }
225  }
226 }
QTemporaryFile * tempFile
Definition: httprequest.h:221
RequestStatus status
Definition: httprequest.h:197
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ readFromSocket()

void HttpRequest::readFromSocket ( QTcpSocket *  socket)

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.

Parameters
socketSource of the data

Definition at line 306 of file httprequest.cpp.

References abort, boundary, complete, currentSize, decodeRequestParams(), extractCookies(), maxMultiPartSize, maxSize, readBody(), readHeader(), readRequest(), status, waitForBody, waitForHeader, and waitForRequest.

Referenced by qtwebapp::HttpConnectionHandler::read().

307 {
308  Q_ASSERT(status!=complete);
309  if (status==waitForRequest)
310  {
311  readRequest(socket);
312  }
313  else if (status==waitForHeader)
314  {
315  readHeader(socket);
316  }
317  else if (status==waitForBody)
318  {
319  readBody(socket);
320  }
321  if ((boundary.isEmpty() && currentSize>maxSize) || (!boundary.isEmpty() && currentSize>maxMultiPartSize))
322  {
323  qWarning("HttpRequest::readFromSocket: received too many bytes");
324  status=abort;
325  }
326  if (status==complete)
327  {
328  // Extract and decode request parameters from url and body
330  // Extract cookies from headers
331  extractCookies();
332  }
333 }
void readHeader(QTcpSocket *socket)
Definition: httprequest.cpp:75
void readBody(QTcpSocket *socket)
RequestStatus status
Definition: httprequest.h:197
void readRequest(QTcpSocket *socket)
Definition: httprequest.cpp:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ readHeader()

void HttpRequest::readHeader ( QTcpSocket *  socket)
private

Sub-procedure of readFromSocket(), read header lines.

Definition at line 75 of file httprequest.cpp.

References abort, boundary, complete, currentHeader, currentSize, expectedBodySize, headers, lineBuffer, maxMultiPartSize, maxSize, status, and waitForBody.

Referenced by readFromSocket().

76 {
77  #ifdef SUPERVERBOSE
78  qDebug("HttpRequest::readHeader");
79  #endif
80  int toRead=maxSize-currentSize+1; // allow one byte more to be able to detect overflow
81  lineBuffer.append(socket->readLine(toRead));
82  currentSize+=lineBuffer.size();
83  if (!lineBuffer.contains('\r') && !lineBuffer.contains('\n'))
84  {
85  #ifdef SUPERVERBOSE
86  qDebug("HttpRequest::readHeader: collecting more parts until line break");
87  #endif
88  return;
89  }
90  QByteArray newData=lineBuffer.trimmed();
91  lineBuffer.clear();
92  int colon=newData.indexOf(':');
93  if (colon>0)
94  {
95  // Received a line with a colon - a header
96  currentHeader=newData.left(colon).toLower();
97  QByteArray value=newData.mid(colon+1).trimmed();
98  headers.insert(currentHeader,value);
99  #ifdef SUPERVERBOSE
100  qDebug("HttpRequest::readHeader: received header %s: %s",currentHeader.data(),value.data());
101  #endif
102  }
103  else if (!newData.isEmpty())
104  {
105  // received another line - belongs to the previous header
106  #ifdef SUPERVERBOSE
107  qDebug("HttpRequest::readHeader: read additional line of header");
108  #endif
109  // Received additional line of previous header
110  if (headers.contains(currentHeader)) {
111  headers.insert(currentHeader,headers.value(currentHeader)+" "+newData);
112  }
113  }
114  else
115  {
116  // received an empty line - end of headers reached
117  #ifdef SUPERVERBOSE
118  qDebug("HttpRequest::readHeader: headers completed");
119  #endif
120  // Empty line received, that means all headers have been received
121  // Check for multipart/form-data
122  QByteArray contentType=headers.value("content-type");
123  if (contentType.startsWith("multipart/form-data"))
124  {
125  int posi=contentType.indexOf("boundary=");
126  if (posi>=0) {
127  boundary=contentType.mid(posi+9);
128  if (boundary.startsWith('"') && boundary.endsWith('"'))
129  {
130  boundary = boundary.mid(1,boundary.length()-2);
131  }
132  }
133  }
134  QByteArray contentLength=headers.value("content-length");
135  if (!contentLength.isEmpty())
136  {
137  expectedBodySize=contentLength.toInt();
138  }
139  if (expectedBodySize==0)
140  {
141  #ifdef SUPERVERBOSE
142  qDebug("HttpRequest::readHeader: expect no body");
143  #endif
145  }
146  else if (boundary.isEmpty() && expectedBodySize+currentSize>maxSize)
147  {
148  qWarning("HttpRequest::readHeader: expected body is too large");
149  status=abort;
150  }
151  else if (!boundary.isEmpty() && expectedBodySize>maxMultiPartSize)
152  {
153  qWarning("HttpRequest::readHeader: expected multipart body is too large");
154  status=abort;
155  }
156  else {
157  #ifdef SUPERVERBOSE
158  qDebug("HttpRequest::readHeader: expect %i bytes body",expectedBodySize);
159  #endif
161  }
162  }
163 }
RequestStatus status
Definition: httprequest.h:197
QMultiMap< QByteArray, QByteArray > headers
Definition: httprequest.h:170
QByteArray currentHeader
Definition: httprequest.h:215
+ Here is the caller graph for this function:

◆ readRequest()

void HttpRequest::readRequest ( QTcpSocket *  socket)
private

Sub-procedure of readFromSocket(), read the first line of a request.

Definition at line 40 of file httprequest.cpp.

References abort, currentSize, lineBuffer, maxSize, method, path, peerAddress, status, version, and waitForHeader.

Referenced by readFromSocket().

41 {
42  #ifdef SUPERVERBOSE
43  qDebug("HttpRequest::readRequest: read request");
44  #endif
45  int toRead=maxSize-currentSize+1; // allow one byte more to be able to detect overflow
46  lineBuffer.append(socket->readLine(toRead));
47  currentSize+=lineBuffer.size();
48  if (!lineBuffer.contains('\r') && !lineBuffer.contains('\n'))
49  {
50  #ifdef SUPERVERBOSE
51  qDebug("HttpRequest::readRequest: collecting more parts until line break");
52  #endif
53  return;
54  }
55  QByteArray newData=lineBuffer.trimmed();
56  lineBuffer.clear();
57  if (!newData.isEmpty())
58  {
59  QList<QByteArray> list=newData.split(' ');
60  if (list.count()!=3 || !list.at(2).contains("HTTP"))
61  {
62  qWarning("HttpRequest::readRequest: received broken HTTP request, invalid first line");
63  status=abort;
64  }
65  else {
66  method=list.at(0).trimmed();
67  path=list.at(1);
68  version=list.at(2);
69  peerAddress = socket->peerAddress();
71  }
72  }
73 }
RequestStatus status
Definition: httprequest.h:197
QHostAddress peerAddress
Definition: httprequest.h:200
+ Here is the caller graph for this function:

◆ urlDecode()

QByteArray HttpRequest::urlDecode ( const QByteArray  source)
static

Decode an URL parameter. E.g. replace "%23" by '#' and replace '+' by ' '.

Parameters
sourceThe url encoded strings
See also
QUrl::toPercentEncoding for the reverse direction

Definition at line 401 of file httprequest.cpp.

Referenced by decodeRequestParams(), and getPath().

402 {
403  QByteArray buffer(source);
404  buffer.replace('+',' ');
405  int percentChar=buffer.indexOf('%');
406  while (percentChar>=0)
407  {
408  bool ok;
409  char byte=buffer.mid(percentChar+1,2).toInt(&ok,16);
410  if (ok)
411  {
412  buffer.replace(percentChar,3,(char*)&byte,1);
413  }
414  percentChar=buffer.indexOf('%',percentChar+1);
415  }
416  return buffer;
417 }
+ Here is the caller graph for this function:

Friends And Related Function Documentation

◆ HttpSessionStore

friend class HttpSessionStore
friend

Definition at line 43 of file httprequest.h.

Member Data Documentation

◆ bodyData

QByteArray qtwebapp::HttpRequest::bodyData
private

Storage for raw body data

Definition at line 182 of file httprequest.h.

Referenced by decodeRequestParams(), getBody(), and readBody().

◆ boundary

QByteArray qtwebapp::HttpRequest::boundary
private

Boundary of multipart/form-data body. Empty if there is no such header

Definition at line 218 of file httprequest.h.

Referenced by parseMultiPartFile(), readBody(), readFromSocket(), and readHeader().

◆ cookies

QMap<QByteArray,QByteArray> qtwebapp::HttpRequest::cookies
private

Received cookies

Definition at line 179 of file httprequest.h.

Referenced by extractCookies(), getCookie(), and getCookieMap().

◆ currentHeader

QByteArray qtwebapp::HttpRequest::currentHeader
private

Name of the current header, or empty if no header is being processed

Definition at line 215 of file httprequest.h.

Referenced by readHeader().

◆ currentSize

int qtwebapp::HttpRequest::currentSize
private

Current size

Definition at line 209 of file httprequest.h.

Referenced by HttpRequest(), parseMultiPartFile(), readBody(), readFromSocket(), readHeader(), and readRequest().

◆ expectedBodySize

int qtwebapp::HttpRequest::expectedBodySize
private

Expected size of body

Definition at line 212 of file httprequest.h.

Referenced by HttpRequest(), readBody(), and readHeader().

◆ headers

QMultiMap<QByteArray,QByteArray> qtwebapp::HttpRequest::headers
private

Request headers

Definition at line 170 of file httprequest.h.

Referenced by decodeRequestParams(), extractCookies(), getHeader(), getHeaderMap(), getHeaders(), and readHeader().

◆ lineBuffer

QByteArray qtwebapp::HttpRequest::lineBuffer
private

Buffer for collecting characters of request and header lines

Definition at line 242 of file httprequest.h.

Referenced by readHeader(), and readRequest().

◆ maxMultiPartSize

int qtwebapp::HttpRequest::maxMultiPartSize
private

Maximum allowed size of multipart forms in bytes.

Definition at line 206 of file httprequest.h.

Referenced by HttpRequest(), readBody(), readFromSocket(), and readHeader().

◆ maxSize

int qtwebapp::HttpRequest::maxSize
private

Maximum size of requests in bytes.

Definition at line 203 of file httprequest.h.

Referenced by HttpRequest(), readFromSocket(), readHeader(), and readRequest().

◆ method

QByteArray qtwebapp::HttpRequest::method
private

Request method

Definition at line 185 of file httprequest.h.

Referenced by getMethod(), and readRequest().

◆ parameters

QMultiMap<QByteArray,QByteArray> qtwebapp::HttpRequest::parameters
private

Parameters of the request

Definition at line 173 of file httprequest.h.

Referenced by decodeRequestParams(), getParameter(), getParameterMap(), getParameters(), and parseMultiPartFile().

◆ path

QByteArray qtwebapp::HttpRequest::path
private

Request path (in raw encoded format)

Definition at line 188 of file httprequest.h.

Referenced by decodeRequestParams(), getPath(), getRawPath(), and readRequest().

◆ peerAddress

QHostAddress qtwebapp::HttpRequest::peerAddress
private

Address of the connected peer.

Definition at line 200 of file httprequest.h.

Referenced by getPeerAddress(), and readRequest().

◆ status

RequestStatus qtwebapp::HttpRequest::status
private

Status of this request. For the state engine.

See also
RequestStatus

Definition at line 197 of file httprequest.h.

Referenced by getStatus(), HttpRequest(), readBody(), readFromSocket(), readHeader(), and readRequest().

◆ tempFile

QTemporaryFile* qtwebapp::HttpRequest::tempFile
private

Temp file, that is used to store the multipart/form-data body

Definition at line 221 of file httprequest.h.

Referenced by HttpRequest(), parseMultiPartFile(), readBody(), and ~HttpRequest().

◆ uploadedFiles

QMap<QByteArray,QTemporaryFile*> qtwebapp::HttpRequest::uploadedFiles
private

Uploaded files of the request, key is the field name.

Definition at line 176 of file httprequest.h.

Referenced by getUploadedFile(), parseMultiPartFile(), and ~HttpRequest().

◆ useQtSettings

bool qtwebapp::HttpRequest::useQtSettings
private

Settings flag

Definition at line 245 of file httprequest.h.

◆ version

QByteArray qtwebapp::HttpRequest::version
private

Request protocol version

Definition at line 191 of file httprequest.h.

Referenced by getVersion(), and readRequest().


The documentation for this class was generated from the following files: