27#include <QVarLengthArray>
29static const char s_forbidden[] =
"HTTP/1.1 403 Forbidden\r\nContent-Length: 0\r\n\r\n";
40 , m_serverObject(serverObject)
41 , m_delayedResponse(
false)
42 , m_socketEnabled(
true)
43 , m_receivedData(
false)
49 m_doDebug = qEnvironmentVariableIsSet(
"KDSOAP_DEBUG");
64 sourceBuffer.
setData(headerData);
68 if (firstLine.
count() < 3) {
69 qDebug() <<
"Malformed HTTP request:" << firstLine;
73 headersMap.
insert(
"_requestType", requestType);
80 const int queryPos = arg1.
indexOf(
'?');
81 const QByteArray path = queryPos >= 0 ? arg1.
left(queryPos) : arg1;
85 headersMap.
insert(
"_path", cleanedPath + query);
88 headersMap.
insert(
"_httpVersion", httpVersion);
90 while (!sourceBuffer.
atEnd()) {
92 const int pos = line.
indexOf(
':');
94 qDebug() <<
"Malformed HTTP header:" << line;
99 headersMap.
insert(header, value);
108 const int sep = request.
indexOf(
"\r\n\r\n");
112 header = request.
left(sep);
113 data = request.
mid(sep + 4);
132 httpResponse +=
"HTTP/1.1 500 Internal Server Error\r\n";
133 }
else if (responseDataSize == 0) {
134 httpResponse +=
"HTTP/1.1 204 No Content\r\n";
136 httpResponse +=
"HTTP/1.1 200 OK\r\n";
139 httpResponse +=
"Content-Type: ";
140 httpResponse += contentType;
141 httpResponse +=
"\r\nContent-Length: ";
143 httpResponse +=
"\r\n";
146 if (serverObjectInterface) {
149 httpResponse += headerItem.m_name;
150 httpResponse +=
": ";
151 httpResponse += headerItem.m_value;
152 httpResponse +=
"\r\n";
156 httpResponse +=
"\r\n";
160void KDSoapServerSocket::slotReadyRead()
162 if (!m_socketEnabled) {
168 if (!m_receivedData) {
169 m_receivedData =
true;
184 m_bytesReceived +=
nread;
211 qDebug() <<
"headers:" << m_httpHeaders;
212 qDebug() <<
"data received:" << m_requestBuffer;
215 if (m_httpHeaders.
value(
"transfer-encoding") !=
"chunked") {
218 m_requestBuffer.
clear();
229 handleRequest(m_httpHeaders, m_requestBuffer);
233 while (m_chunkStart >= 0) {
234 const int nextEOL = m_requestBuffer.
indexOf(
"\r\n", m_chunkStart);
248 m_requestBuffer = m_requestBuffer.
mid(
nextEOL);
259 m_decodedRequestBuffer +=
chunk;
264 if (!m_requestBuffer.
contains(
"\r\n\r\n")) {
270 handleRequest(m_httpHeaders, m_decodedRequestBuffer);
272 m_decodedRequestBuffer.
clear();
275 m_requestBuffer.
clear();
276 m_httpHeaders.
clear();
277 m_receivedData =
false;
297 "HTTP/1.1 401 Authorization Required\r\nWWW-Authenticate: Basic realm=\"example\"\r\nContent-Length: 0\r\n\r\n";
335 if (path == server->
wsdlPathInUrl() && handleWsdlDownload()) {
369 }
else if (
contentType.startsWith(
"application/soap+xml")) {
374 if (
part.trimmed().startsWith(
"action=")) {
388 setSocketEnabled(
false);
394bool KDSoapServerSocket::handleWsdlDownload()
426 qDebug() <<
"KDSoapServerSocket: file download response" << response;
432 char block[4096] = {0};
434 while (!device->
atEnd()) {
455void KDSoapServerSocket::writeXML(
const QByteArray &xmlResponse,
bool isFault)
474 const bool isFault =
replyMsg.isFault();
485 QString responseNamespace = m_messageNamespace;
493 msgWriter.setMessageNamespace(responseNamespace);
507 server->log(
"FAULT " + m_method.
toLatin1() +
" -- " +
replyMsg.faultAsString().toUtf8() +
'\n');
509 server->log(
"CALL " + m_method.
toLatin1() +
'\n');
518 m_delayedResponse =
false;
519 setSocketEnabled(
true);
524 m_delayedResponse =
true;
527void KDSoapServerSocket::handleError(
KDSoapMessage &replyMsg,
const char *errorCode,
const QString &error)
551 if (path != server->
path()) {
566void KDSoapServerSocket::setSocketEnabled(
bool enabled)
568 if (m_socketEnabled == enabled) {
572 m_socketEnabled = enabled;
578#include "moc_KDSoapServerSocket_p.cpp"
static const char s_forbidden[]
static QByteArray httpResponseHeaders(bool fault, const QByteArray &contentType, int responseDataSize, QObject *serverObject)
static HeadersMap parseHeaders(const QByteArray &headerData)
QMap< QByteArray, QByteArray > HeadersMap
static QByteArray stripQuotes(const QByteArray &bar)
static bool splitHeadersAndData(const QByteArray &request, QByteArray &header, QByteArray &data)
XmlError xmlToMessage(const QByteArray &data, KDSoapMessage *pParsedMessage, QString *pMessageNamespace, KDSoapHeaders *pRequestHeaders, KDSoap::SoapVersion soapVersion) const
@ PrematureEndOfDocumentError
virtual HttpResponseHeaderItems additionalHttpResponseHeaderItems() const
void sendDelayedReply(KDSoapServerObjectInterface *serverObjectInterface, const KDSoapMessage &replyMsg)
void socketDeleted(KDSoapServerSocket *)
KDSoapServerSocket(KDSoapSocketList *owner, QObject *serverObject)
void sendReply(KDSoapServerObjectInterface *serverObjectInterface, const KDSoapMessage &replyMsg)
void setResponseDelayed()
KDSoapMessage::Use use() const
QString wsdlPathInUrl() const
LogLevel logLevel() const
KDSoapServer * server() const
void increaseConnectionCount()
QAbstractSocket::SocketError error() const const
virtual bool atEnd() const const override
virtual bool open(QIODevice::OpenMode flags) override
void setData(const QByteArray &data)
bool contains(char ch) const const
bool endsWith(const QByteArray &ba) const const
int indexOf(char ch, int from) const const
QByteArray left(int len) const const
QByteArray mid(int pos, int len) const const
QByteArray number(int n, int base)
bool startsWith(const QByteArray &ba) const const
int toInt(bool *ok, int base) const const
QByteArray toLower() const const
QByteArray trimmed() const const
QString cleanPath(const QString &path)
virtual bool atEnd() const const
QString errorString() const const
virtual bool open(QIODevice::OpenMode mode)
qint64 read(char *data, qint64 maxSize)
qint64 readLine(char *data, qint64 maxSize)
virtual qint64 size() const const
qint64 write(const char *data, qint64 maxSize)
const T & at(int i) const const
int count(const T &value) const const
QMap::iterator insert(const Key &key, const T &value)
bool isEmpty() const const
const T value(const Key &key, const T &defaultValue) const const
T qobject_cast(QObject *object)
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
QString fromLatin1(const char *str, int size)
QString fromUtf8(const char *str, int size)
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
QByteArray toLatin1() const const
QByteArray toUtf8() const const