File indexing completed on 2025-01-26 04:24:52

0001 /*
0002  * Copyright 2011 Nikhil Marathe <nsm.nikhil@gmail.com>
0003  * 
0004  * Permission is hereby granted, free of charge, to any person obtaining a copy
0005  * of this software and associated documentation files (the "Software"), to
0006  * deal in the Software without restriction, including without limitation the
0007  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
0008  * sell copies of the Software, and to permit persons to whom the Software is
0009  * furnished to do so, subject to the following conditions:
0010  * 
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  * 
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
0017  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0018  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
0019  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
0020  * IN THE SOFTWARE. 
0021  */
0022 
0023 #include "qhttpserver.h"
0024 
0025 #include <QTcpServer>
0026 #include <QTcpSocket>
0027 #include <QVariant>
0028 #include <QDebug>
0029 
0030 #include "qhttpconnection.h"
0031 
0032 QHash<int, QString> STATUS_CODES;
0033 
0034 QHttpServer::QHttpServer(QObject *parent)
0035     : QObject(parent)
0036     , m_tcpServer(0)
0037 {
0038 #define STATUS_CODE(num, reason) STATUS_CODES.insert(num, reason);
0039 // {{{
0040   STATUS_CODE(100, "Continue")
0041   STATUS_CODE(101, "Switching Protocols")
0042   STATUS_CODE(102, "Processing")                 // RFC 2518) obsoleted by RFC 4918
0043   STATUS_CODE(200, "OK")
0044   STATUS_CODE(201, "Created")
0045   STATUS_CODE(202, "Accepted")
0046   STATUS_CODE(203, "Non-Authoritative Information")
0047   STATUS_CODE(204, "No Content")
0048   STATUS_CODE(205, "Reset Content")
0049   STATUS_CODE(206, "Partial Content")
0050   STATUS_CODE(207, "Multi-Status")               // RFC 4918
0051   STATUS_CODE(300, "Multiple Choices")
0052   STATUS_CODE(301, "Moved Permanently")
0053   STATUS_CODE(302, "Moved Temporarily")
0054   STATUS_CODE(303, "See Other")
0055   STATUS_CODE(304, "Not Modified")
0056   STATUS_CODE(305, "Use Proxy")
0057   STATUS_CODE(307, "Temporary Redirect")
0058   STATUS_CODE(400, "Bad Request")
0059   STATUS_CODE(401, "Unauthorized")
0060   STATUS_CODE(402, "Payment Required")
0061   STATUS_CODE(403, "Forbidden")
0062   STATUS_CODE(404, "Not Found")
0063   STATUS_CODE(405, "Method Not Allowed")
0064   STATUS_CODE(406, "Not Acceptable")
0065   STATUS_CODE(407, "Proxy Authentication Required")
0066   STATUS_CODE(408, "Request Time-out")
0067   STATUS_CODE(409, "Conflict")
0068   STATUS_CODE(410, "Gone")
0069   STATUS_CODE(411, "Length Required")
0070   STATUS_CODE(412, "Precondition Failed")
0071   STATUS_CODE(413, "Request Entity Too Large")
0072   STATUS_CODE(414, "Request-URI Too Large")
0073   STATUS_CODE(415, "Unsupported Media Type")
0074   STATUS_CODE(416, "Requested Range Not Satisfiable")
0075   STATUS_CODE(417, "Expectation Failed")
0076   STATUS_CODE(418, "I\"m a teapot")              // RFC 2324
0077   STATUS_CODE(422, "Unprocessable Entity")       // RFC 4918
0078   STATUS_CODE(423, "Locked")                     // RFC 4918
0079   STATUS_CODE(424, "Failed Dependency")          // RFC 4918
0080   STATUS_CODE(425, "Unordered Collection")       // RFC 4918
0081   STATUS_CODE(426, "Upgrade Required")           // RFC 2817
0082   STATUS_CODE(500, "Internal Server Error")
0083   STATUS_CODE(501, "Not Implemented")
0084   STATUS_CODE(502, "Bad Gateway")
0085   STATUS_CODE(503, "Service Unavailable")
0086   STATUS_CODE(504, "Gateway Time-out")
0087   STATUS_CODE(505, "HTTP Version not supported")
0088   STATUS_CODE(506, "Variant Also Negotiates")    // RFC 2295
0089   STATUS_CODE(507, "Insufficient Storage")       // RFC 4918
0090   STATUS_CODE(509, "Bandwidth Limit Exceeded")
0091   STATUS_CODE(510, "Not Extended")                // RFC 2774
0092 // }}}
0093 }
0094 
0095 QHttpServer::~QHttpServer()
0096 {
0097 }
0098 
0099 void QHttpServer::newConnection()
0100 {
0101     Q_ASSERT(m_tcpServer);
0102     while(m_tcpServer->hasPendingConnections()) {
0103         QHttpConnection *connection = new QHttpConnection(m_tcpServer->nextPendingConnection(), this);
0104         connect(connection, SIGNAL(newRequest(QHttpRequest*, QHttpResponse*)),
0105                 this, SIGNAL(newRequest(QHttpRequest*, QHttpResponse*)));
0106     }
0107 }
0108 
0109 bool QHttpServer::listen(const QHostAddress &address, quint16 port)
0110 {
0111     m_tcpServer = new QTcpServer;
0112 
0113     connect(m_tcpServer, SIGNAL(newConnection()), this, SLOT(newConnection()));
0114     return m_tcpServer->listen(address, port);
0115 }
0116 
0117 bool QHttpServer::listen(const QString &address, quint16 port)
0118 {
0119     return listen(QHostAddress(address), port);
0120 }
0121 
0122 bool QHttpServer::listen(quint16 port)
0123 {
0124     return listen(QHostAddress::Any, port);
0125 }
0126 
0127 void QHttpServer::close()
0128 {
0129   m_tcpServer->close();
0130 }