QHttpEngine  1.0.0
Simple and secure HTTP server for Qt applications
Public Types | Signals | Public Member Functions | Protected Member Functions | Friends | List of all members
QHttpEngine::Socket Class Reference

Implementation of the HTTP protocol. More...

#include <qhttpengine/socket.h>

Inheritance diagram for QHttpEngine::Socket:

Public Types

enum  {
  OK = 200,
  Created = 201,
  Accepted = 202,
  PartialContent = 206,
  MovedPermanently = 301,
  Found = 302,
  BadRequest = 400,
  Unauthorized = 401,
  Forbidden = 403,
  NotFound = 404,
  MethodNotAllowed = 405,
  Conflict = 409,
  InternalServerError = 500,
  BadGateway = 502,
  ServiceUnavailable = 503,
  HttpVersionNotSupported = 505
}
 
typedef QMultiMap< IByteArray, QByteArray > HeaderMap
 Map consisting of HTTP headers. More...
 
enum  Method {
  OPTIONS = 1,
  GET = 1 << 1,
  HEAD = 1 << 2,
  POST = 1 << 3,
  PUT = 1 << 4,
  DELETE = 1 << 5,
  TRACE = 1 << 6,
  CONNECT = 1 << 7
}
 
typedef QMultiMap< QString, QString > QueryStringMap
 Map consisting of query string values.
 

Signals

void disconnected ()
 Indicate that the client has disconnected.
 
void headersParsed ()
 Indicate that request headers have been parsed. More...
 

Public Member Functions

 Socket (QTcpSocket *socket, QObject *parent=0)
 Create a new socket from a QTcpSocket. More...
 
virtual qint64 bytesAvailable () const
 Retrieve the number of bytes available for reading. More...
 
virtual void close ()
 Close the device and underlying socket. More...
 
qint64 contentLength () const
 Retrieve the length of the content. More...
 
HeaderMap headers () const
 Retrieve a map of request headers. More...
 
bool isHeadersParsed () const
 Determine if the request headers have been parsed yet.
 
virtual bool isSequential () const
 Determine if the device is sequential. More...
 
Method method () const
 Retrieve the request method. More...
 
QString path () const
 Retrieve the decoded path with the query string removed. More...
 
QHostAddress peerAddress () const
 Retrive the address of the remote peer.
 
QueryStringMap queryString () const
 Retrieve the query string. More...
 
QByteArray rawPath () const
 Retrieve the raw request path. More...
 
bool readJson (QJsonDocument &document)
 Parse the request body as a JSON document. More...
 
void setHeader (const QByteArray &name, const QByteArray &value, bool replace=true)
 Set a response header to a specific value. More...
 
void setHeaders (const HeaderMap &headers)
 Set the response headers. More...
 
void setStatusCode (int statusCode, const QByteArray &statusReason=QByteArray())
 Set the response code. More...
 
void writeError (int statusCode, const QByteArray &statusReason=QByteArray())
 Write an HTTP error to the socket and close it.
 
void writeHeaders ()
 Write response headers to the socket. More...
 
void writeJson (const QJsonDocument &document, int statusCode=OK)
 Write the specified JSON document to the socket and close it.
 
void writeRedirect (const QByteArray &path, bool permanent=false)
 Write an HTTP 3xx redirect to the socket and close it.
 

Protected Member Functions

virtual qint64 readData (char *data, qint64 maxlen)
 Implementation of QIODevice::readData()
 
virtual qint64 writeData (const char *data, qint64 len)
 Implementation of QIODevice::writeData()
 

Friends

class SocketPrivate
 

Detailed Description

This class provides a class derived from QIODevice that can be used to read data from and write data to an HTTP client through a QTcpSocket provided in the constructor. The socket will assume ownership of the QTcpSocket and ensure it is properly deleted. Consequently, the QTcpSocket must have been allocated on the heap:

QTcpSocket *tcpSock = new QTcpSocket;
tcpSock->connectToHost(...);
tcpSock->waitForConnected();
QHttpEngine::Socket *httpSock = new QHttpEngine::Socket(tcpSock);

Once the headersParsed() signal is emitted, information about the request can be retrieved using the appropriate methods. As data is received, the readyRead() signal is emitted and any available data can be read using QIODevice::read():

QByteArray data;
connect(httpSock, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
void MyClass::onReadyRead()
{
data.append(httpSock->readAll());
}

If the client sets the Content-Length header, the readChannelFinished() signal will be emitted when the specified amount of data is read from the client. Otherwise the readChannelFinished() signal will be emitted immediately after the headers are read.

The status code and headers may be set as long as no data has been written to the device and the writeHeaders() method has not been called. The headers are written either when the writeHeaders() method is called or when data is first written to the device:

httpSock->setStatusCode(QHttpSocket::OK);
httpSock->setHeader("Content-Length", 13);
httpSock->write("Hello, world!");

This class also provides methods that simplify writing a redirect or an HTTP error to the socket. To write a redirect, simply pass a path to the writeRedirect() method. To write an error, simply pass the desired HTTP status code to the writeError() method. Both methods will close the socket once the response is written.

Member Typedef Documentation

◆ HeaderMap

typedef QMultiMap<IByteArray, QByteArray> QHttpEngine::Socket::HeaderMap

The key used for the map is the IByteArray class, which allows for case-insensitive comparison.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum

Predefined constants for HTTP status codes

Enumerator
OK 

Request was successful.

Created 

Request was successful and a resource was created.

Accepted 

Request was accepted for processing, not completed yet.

PartialContent 

Range request was successful

MovedPermanently 

Resource has moved permanently.

Found 

Resource is available at an alternate URI.

BadRequest 

Bad client request.

Unauthorized 

Client is unauthorized to access the resource.

Forbidden 

Access to the resource is forbidden.

NotFound 

Resource was not found.

MethodNotAllowed 

Method is not valid for the resource.

Conflict 

The request could not be completed due to a conflict with the current state of the resource.

InternalServerError 

An internal server error occurred.

BadGateway 

Invalid response from server while acting as a gateway.

ServiceUnavailable 

Server unable to handle request due to overload

HttpVersionNotSupported 

Server does not supports the HTTP version in the request

◆ Method

HTTP methods

An integer constant is provided for each of the methods described in RFC 2616 (HTTP/1.1).

Enumerator
OPTIONS 

Request for communications options.

GET 

Request resource.

HEAD 

Request resource without body.

POST 

Store subordinate resource.

PUT 

Store resource.

DELETE 

Delete resource.

TRACE 

Diagnostic trace.

CONNECT 

Proxy connection.

Constructor & Destructor Documentation

◆ Socket()

QHttpEngine::Socket::Socket ( QTcpSocket *  socket,
QObject *  parent = 0 
)

This instance will assume ownership of the QTcpSocket. That is, it will make itself the parent of the socket.

Member Function Documentation

◆ bytesAvailable()

virtual qint64 QHttpEngine::Socket::bytesAvailable ( ) const
virtual

This method indicates the number of bytes that could immediately be read by a call to QIODevice::readAll().

◆ close()

virtual void QHttpEngine::Socket::close ( )
virtual

Invoking this method signifies that no more data will be written to the device. It will also close the underlying QTcpSocket and destroy this object.

◆ contentLength()

qint64 QHttpEngine::Socket::contentLength ( ) const

This value is provided by the Content-Length HTTP header (if present) and returns -1 if the value is not available.

◆ headers()

HeaderMap QHttpEngine::Socket::headers ( ) const

This method may only be called after the request headers have been parsed. The original case of the headers is preserved but comparisons are performed in a case-insensitive manner.

◆ headersParsed

void QHttpEngine::Socket::headersParsed ( )
signal

This signal is emitted when the request headers have been received from the client and parsing is complete. It is then safe to begin reading request data. The readyRead() signal will be emitted as request data is received.

◆ isSequential()

virtual bool QHttpEngine::Socket::isSequential ( ) const
virtual

This method will always return true.

◆ method()

Method QHttpEngine::Socket::method ( ) const

This method may only be called after the request headers have been parsed.

◆ path()

QString QHttpEngine::Socket::path ( ) const

This method may only be called after the request headers have been parsed.

◆ queryString()

QueryStringMap QHttpEngine::Socket::queryString ( ) const

This method may only be called after the request headers have been parsed.

◆ rawPath()

QByteArray QHttpEngine::Socket::rawPath ( ) const

This method may only be called after the request headers have been parsed.

◆ readJson()

bool QHttpEngine::Socket::readJson ( QJsonDocument &  document)

This method may only be called after the request headers and the request body have been received. The most effective way to confirm that this is the case is by using:

socket->bytesAvailable() >= socket->contentLength()

If the JSON received is invalid, an error will be immediately written to the socket. The return value indicates whether the JSON was valid.

◆ setHeader()

void QHttpEngine::Socket::setHeader ( const QByteArray &  name,
const QByteArray &  value,
bool  replace = true 
)

This method may only be called before the response headers are written. Duplicate values will be either appended to the header or used to replace the original value, depending on the third parameter.

◆ setHeaders()

void QHttpEngine::Socket::setHeaders ( const HeaderMap headers)

This method may only be called before the response headers are written. All existing headers will be overwritten.

◆ setStatusCode()

void QHttpEngine::Socket::setStatusCode ( int  statusCode,
const QByteArray &  statusReason = QByteArray() 
)

This method may only be called before the response headers are written.

The statusReason parameter may be omitted if one of the predefined status code constants is used. If no response status code is explicitly set, it will assume a default value of "200 OK".

◆ writeHeaders()

void QHttpEngine::Socket::writeHeaders ( )

This method should not be invoked after the response headers have been written.


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