void ErrorRequestProcessor::process(HttpRequest& req, DataBuffer<uint8_t>& buffer) { DataBuffer<char> content; HttpStatus status; if (code_ == EACCES) { status = FORBIDDEN; const std::string path = std::string("../html/403.html"); FilePro::File file(path, path); file.content(content); } else if (code_ == ENOENT) { status = NOT_FOUND; const std::string path = std::string("../html/404.html"); FilePro::File file(path, path); file.content(content); } else { status = INTERNAL_ERROR; const std::string path = std::string("../html/500.html"); FilePro::File file(path, path); file.content(content); } makeHttpResponse(req, content.data(), content.size(), buffer, status); (void)req; }
void http_server_start(http_server_t *http_server) { WSADATA wsa; if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) { printf("WSA startup failed: %d\n", WSAGetLastError()); exit(1); } SOCKET listenSocket; if ((listenSocket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { printf("Create listen socket failed: %d\n", WSAGetLastError()); WSACleanup(); exit(1); } struct sockaddr_in serverSockAddr; memset(&serverSockAddr, 0, sizeof(struct sockaddr_in)); serverSockAddr.sin_family = AF_INET; serverSockAddr.sin_addr.s_addr = INADDR_ANY; serverSockAddr.sin_port = htons(8888); if (bind(listenSocket, (struct sockaddr *)&serverSockAddr, sizeof(struct sockaddr_in)) == SOCKET_ERROR) { printf("Bind socket error: %d\n", WSAGetLastError()); WSACleanup(); exit(1); } if (listen(listenSocket, SOMAXCONN) == SOCKET_ERROR) { printf("Listen socket error: %d\n", WSAGetLastError()); closesocket(listenSocket); WSACleanup(); exit(1); } while (1) { SOCKET clientSocket = accept(listenSocket, NULL, NULL); if (clientSocket == INVALID_SOCKET) { printf("Client socket accept error: %d\n", WSAGetLastError()); closesocket(listenSocket); WSACleanup(); exit(1); } char recvBuffer[BUFFER_LENGTH]; char sendBuffer[BUFFER_LENGTH]; size_t recvTotalSize = 0; while (1) { int recvSize = recv(clientSocket, recvBuffer + recvTotalSize, BUFFER_LENGTH - recvTotalSize, 0); if (recvSize > 0) { recvTotalSize += recvSize; if (checkHttpRequestCompleteness(recvBuffer, recvTotalSize)) break; } else if (recvSize == 0) { break; } else { printf("recv error: %d\n", WSAGetLastError()); closesocket(clientSocket); closesocket(listenSocket); WSACleanup(); exit(1); } } recvBuffer[recvTotalSize] = '\0'; http_method_t http_method; char url[MAX_URL_LENGTH]; char urlParamStr[MAX_URL_LENGTH]; char request[BUFFER_LENGTH]; char response[BUFFER_LENGTH]; parseHttpRequest(recvBuffer, &http_method, url, urlParamStr, request); http_server_callback_t http_server_callback = middleware_callback(); if (!http_server_callback(http_server->middleware, http_method, url, urlParamStr, request, response)) strcpy(sendBuffer, MESSAGE_404); else makeHttpResponse(response, sendBuffer); size_t sendTotalSize = 0; while (1) { int sendSize = send(clientSocket, sendBuffer + sendTotalSize, strlen(sendBuffer) - sendTotalSize, 0); if (sendSize == SOCKET_ERROR) { printf("send error: %d\n", WSAGetLastError()); closesocket(clientSocket); closesocket(listenSocket); WSACleanup(); exit(1); } sendTotalSize += sendSize; if (sendTotalSize == strlen(sendBuffer)) break; } if (shutdown(clientSocket, SD_SEND) == SOCKET_ERROR) { printf("shutdown client socket error: %d\n", WSAGetLastError()); closesocket(clientSocket); closesocket(listenSocket); WSACleanup(); exit(1); } closesocket(clientSocket); } closesocket(listenSocket); WSACleanup(); }
void http_server_start(http_server_t *http_server) { WSADATA wsa; if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) { printf("Failed. Error Code : %d", WSAGetLastError()); exit(1); } SOCKET s; if ((s = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { printf("Could not create socket : %d" , WSAGetLastError()); exit(1); } struct sockaddr_in server; server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = htons(8888); if (bind(s, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR) { printf("Bind failed with error code : %d" , WSAGetLastError()); exit(EXIT_FAILURE); } listen(s, 3); int c = sizeof(struct sockaddr_in); SOCKET newSocket; struct sockaddr_in client; while ((newSocket = accept(s, (struct sockaddr *)&client, &c)) != INVALID_SOCKET) { char message[500000]; char request[500000]; int recvSize = recv(newSocket, request, sizeof(request), 0); request[recvSize] = '\0'; http_server_request_method_t http_server_request_method; char url[128]; char requestMessage[500000]; parseHttpRequest(request, &http_server_request_method, url, requestMessage); printf("%s\n", url); if (strcmp(url, "/directors") == 0) { cJSON *json = cJSON_CreateArray(); for (size_t i = 0; i < directors_size(http_server->directors); ++i) { director_t *director = directors_get(http_server->directors, i); cJSON *jsonDir = cJSON_CreateObject(); cJSON_AddStringToObject(jsonDir, "name", director->name); cJSON_AddStringToObject(jsonDir, "surname", director->surname); char birthdateStr[128]; sprintf(birthdateStr, "%i-%i-%i", director->birth_date.tm_year, director->birth_date.tm_mday, director->birth_date.tm_mon); cJSON_AddStringToObject(jsonDir, "birthdate", birthdateStr); cJSON *jsonStartup = cJSON_CreateObject(); cJSON_AddStringToObject(jsonStartup, "name", director->startup.name); cJSON_AddStringToObject(jsonStartup, "country", director->startup.country); cJSON_AddItemToObject(jsonDir, "startup", jsonStartup); cJSON_AddNumberToObject(jsonDir, "salary", director->salary); cJSON_AddNumberToObject(jsonDir, "rating", director->rating); cJSON_AddItemToArray(json, jsonDir); } char *jsonStr = cJSON_Print(json); makeHttpResponse(jsonStr, message); cJSON_Delete(json); send(newSocket, message, strlen(message), 0); } else if (strncmp(url, "/directors/", strlen("/directors/")) == 0) { size_t directorIndex = atoi(strstr(url + 1, "/") + 1); director_t *director = directors_get(http_server->directors, directorIndex); if (http_server_request_method == http_server_request_method_delete) { directors_remove(http_server->directors, directorIndex); makeHttpResponse("", message); send(newSocket, message, strlen(message), 0); } else if (http_server_request_method == http_server_request_method_post) { cJSON *json = cJSON_Parse(requestMessage); cJSON *subItem = json->child; while (subItem) { if ((subItem->type == cJSON_String) && (strcmp(subItem->string, "name") == 0)) director_update(director, subItem->valuestring, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if ((subItem->type == cJSON_String) && (strcmp(subItem->string, "surname") == 0)) director_update(director, NULL, subItem->valuestring, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if ((subItem->type == cJSON_String) && (strcmp(subItem->string, "birthdate") == 0)) { int year; int day; int month; sscanf(subItem->valuestring, "%i-%i-%i", &year, &day, &month); director_update(director, NULL, NULL, &year, &day, &month, NULL, NULL, NULL, NULL); } if ((subItem->type == cJSON_Object) && (strcmp(subItem->string, "startup") == 0)) { cJSON *subJtem = subItem->child; while (subJtem) { if ((subJtem->type == cJSON_String) && (strcmp(subJtem->string, "name") == 0)) director_update(director, NULL, NULL, NULL, NULL, NULL, subJtem->valuestring, NULL, NULL, NULL); if ((subJtem->type == cJSON_String) && (strcmp(subJtem->string, "country") == 0)) director_update(director, NULL, NULL, NULL, NULL, NULL, NULL, subJtem->valuestring, NULL, NULL); subJtem = subJtem->next; } } if ((subItem->type == cJSON_Number) && (strcmp(subItem->string, "salary") == 0)) { director_update(director, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &subItem->valueint, NULL); } if ((subItem->type == cJSON_Number) && (strcmp(subItem->string, "rating") == 0)) { director_update(director, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &subItem->valuedouble); } subItem = subItem->next; } makeHttpResponse("", message); send(newSocket, message, strlen(message), 0); } else { cJSON *json = cJSON_CreateObject(); cJSON_AddStringToObject(json, "name", director->name); cJSON_AddStringToObject(json, "surname", director->surname); char birthdateStr[128]; sprintf(birthdateStr, "%i-%i-%i", director->birth_date.tm_year, director->birth_date.tm_mday, director->birth_date.tm_mon); cJSON_AddStringToObject(json, "birthdate", birthdateStr); cJSON *jsonStartup = cJSON_CreateObject(); cJSON_AddStringToObject(jsonStartup, "name", director->startup.name); cJSON_AddStringToObject(jsonStartup, "country", director->startup.country); cJSON_AddItemToObject(json, "startup", jsonStartup); cJSON_AddNumberToObject(json, "salary", director->salary); cJSON_AddNumberToObject(json, "rating", director->rating); char *jsonStr = cJSON_Print(json); makeHttpResponse(jsonStr, message); cJSON_Delete(json); send(newSocket, message, strlen(message), 0); } } else { const char *message = "HTTP/1.1 404\r\nContent-length: 0\r\n\r\n"; send(newSocket, message, strlen(message), 0); } closesocket(newSocket); } if (newSocket == INVALID_SOCKET) { printf("accept failed with error code : %d" , WSAGetLastError()); exit(1); } closesocket(s); WSACleanup(); }
void HttpServerThread::run() { m_server = new BlockingHttpServer(m_features & Ssl); m_server->listen(); QMutexLocker lock(&m_mutex); m_port = m_server->serverPort(); lock.unlock(); m_ready.release(); const bool doDebug = qgetenv("KDSOAP_DEBUG").toInt(); if (doDebug) qDebug() << "HttpServerThread listening on port" << m_port; // Wait for first connection (we'll wait for further ones inside the loop) QTcpSocket *clientSocket = m_server->waitForNextConnectionSocket(); Q_ASSERT(clientSocket); Q_FOREVER { // get the "request" packet if (doDebug) { qDebug() << "HttpServerThread: waiting for read"; } if (clientSocket->state() == QAbstractSocket::UnconnectedState || !clientSocket->waitForReadyRead(2000)) { if (clientSocket->state() == QAbstractSocket::UnconnectedState) { delete clientSocket; if (doDebug) { qDebug() << "Waiting for next connection..."; } clientSocket = m_server->waitForNextConnectionSocket(); Q_ASSERT(clientSocket); continue; // go to "waitForReadyRead" } else { qDebug() << "HttpServerThread:" << clientSocket->error() << "waiting for \"request\" packet"; break; } } const QByteArray request = m_partialRequest + clientSocket->readAll(); if (doDebug) { qDebug() << "HttpServerThread: request:" << request; } // Split headers and request xml lock.relock(); const bool splitOK = splitHeadersAndData(request, m_receivedHeaders, m_receivedData); if (!splitOK) { //if (doDebug) // qDebug() << "Storing partial request" << request; m_partialRequest = request; continue; } m_headers = parseHeaders(m_receivedHeaders); if (m_headers.value("Content-Length").toInt() > m_receivedData.size()) { //if (doDebug) // qDebug() << "Storing partial request" << request; m_partialRequest = request; continue; } m_partialRequest.clear(); if (m_headers.value("_path").endsWith("terminateThread")) // we're asked to exit break; // normal exit // TODO compared with expected SoapAction QList<QByteArray> contentTypes = m_headers.value("Content-Type").split(';'); if (contentTypes[0] == "text/xml" && m_headers.value("SoapAction").isEmpty()) { qDebug() << "ERROR: no SoapAction set for Soap 1.1"; break; }else if( contentTypes[0] == "application/soap+xml" && !contentTypes[2].startsWith("action")){ qDebug() << "ERROR: no SoapAction set for Soap 1.2"; break; } lock.unlock(); //qDebug() << "headers received:" << m_receivedHeaders; //qDebug() << headers; //qDebug() << "data received:" << m_receivedData; if (m_features & BasicAuth) { QByteArray authValue = m_headers.value("Authorization"); if (authValue.isEmpty()) authValue = m_headers.value("authorization"); // as sent by Qt-4.5 bool authOk = false; if (!authValue.isEmpty()) { //qDebug() << "got authValue=" << authValue; // looks like "Basic <base64 of user:pass>" Method method; QString headerVal; parseAuthLine(QString::fromLatin1(authValue.data(),authValue.size()), &method, &headerVal); //qDebug() << "method=" << method << "headerVal=" << headerVal; switch (method) { case None: // we want auth, so reject "None" break; case Basic: { const QByteArray userPass = QByteArray::fromBase64(headerVal.toLatin1()); //qDebug() << userPass; // TODO if (validateAuth(userPass)) { if (userPass == ("kdab:testpass")) { authOk = true; } break; } default: qWarning("Unsupported authentication mechanism %s", authValue.constData()); } } if (!authOk) { // send auth request (Qt supports basic, ntlm and digest) const QByteArray unauthorized = "HTTP/1.1 401 Authorization Required\r\nWWW-Authenticate: Basic realm=\"example\"\r\nContent-Length: 0\r\n\r\n"; clientSocket->write( unauthorized ); if (!clientSocket->waitForBytesWritten(2000)) { qDebug() << "HttpServerThread:" << clientSocket->error() << "writing auth request"; break; } continue; } } // send response QByteArray response = makeHttpResponse(m_dataToSend); if (doDebug) { qDebug() << "HttpServerThread: writing" << response; } clientSocket->write(response); clientSocket->flush(); } // all done... delete clientSocket; delete m_server; if (doDebug) { qDebug() << "HttpServerThread terminated"; } }