예제 #1
0
void TWorker::work(int socket)
{
    std::string request;
    std::string fileName;
   // setNonBlock(socket);

    if( readRequest(socket, request) ) {
        #if defined(DEBUG)
            std::cout << "\n\nReqest:\n" << request;
        #endif
        std::string answer;
        if( parseRequest(request, fileName) ) {
            std::string context;
            if( getContext(fileName, context) ) {
                answer = createHeader(200, context.size() ) + context;
            }
            else {
                answer = createHeader(404);
            }
        }
        else {
            answer = createHeader(500);
        }
        #if defined(DEBUG)
            std::cout << "\n\nAnswer:\n" << answer;
        #endif
        sendAnswer(socket, answer);
    }
    disconnect(socket);
}
예제 #2
0
void ExtCommandsHandler::run()
{
    while (1) {
        QStringList args;
        if (!readRequest(&args)) {
            qWarning ("failed to read request from shell extension: %s",
                      formatErrorMessage().c_str());
            break;
        }

        QString cmd = args.takeAt(0);
        QString resp;
        if (cmd == "list-repos") {
            resp = handleListRepos(args);
        } else if (cmd == "get-share-link") {
            handleGenShareLink(args);
        } else if (cmd == "get-file-status") {
            resp = handleGetFileStatus(args);
        } else {
            qWarning ("[ext] unknown request command: %s", cmd.toUtf8().data());
        }

        if (!sendResponse(resp)) {
            qWarning ("failed to write response to shell extension: %s",
                      formatErrorMessage().c_str());
            break;
        }
    }

    qWarning ("An extension client is disconnected: GLE=%lu\n",
              GetLastError());
    DisconnectNamedPipe(pipe_);
    CloseHandle(pipe_);
}
예제 #3
0
void work(int sock) {
	if (readRequest(sock) > 0) writeResponse(sock);
	snooze(0,1000000);						// sleep for 1 milisecond
	if (--timeout <= 0) done = 1;
	if (timeout%1000 == 0) debug("Socket %d has %ds before disconnect",sock,timeout/1000);
	if (done) closeSocket(sock);
}
예제 #4
0
void ClientConnection::loop() {
	if (state == FREE_STATE) {
		return;
	}

	if (client.connected()) {
		switch(state) {
		case READ_HEADER_STATE:
		case READ_REQUEST_STATE:
			readRequest();
			break;

		case WRITE_HEADER_STATE:
		case WRITE_RESPONSE_STATE:
			writeResponse();
			break;
		}

		if (millis() - lastUse > INACTIVITY_TIMEOUT_MS) {
			Serial.printlnf("%d: inactivity timeout", clientId);
			client.stop();
			clear();
		}
	}
	else {
		Serial.printlnf("%d: client disconnected", clientId);
		client.stop();
		clear();
	}
}
예제 #5
0
QT_USE_NAMESPACE

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
    , transactionCount(0)
    , serialPortLabel(new QLabel(tr("Serial port:")))
    , serialPortComboBox(new QComboBox())
    , waitRequestLabel(new QLabel(tr("Wait request, msec:")))
    , waitRequestSpinBox(new QSpinBox())
    , responseLabel(new QLabel(tr("Response:")))
    , responseLineEdit(new QLineEdit(tr("Hello, I'm Slave.")))
    , trafficLabel(new QLabel(tr("No traffic.")))
    , statusLabel(new QLabel(tr("Status: Not running.")))
    , runButton(new QPushButton(tr("Start")))
{
    waitRequestSpinBox->setRange(0, 10000);
    waitRequestSpinBox->setValue(20);

    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
        serialPortComboBox->addItem(info.portName());

    QGridLayout *mainLayout = new QGridLayout;
    mainLayout->addWidget(serialPortLabel, 0, 0);
    mainLayout->addWidget(serialPortComboBox, 0, 1);
    mainLayout->addWidget(waitRequestLabel, 1, 0);
    mainLayout->addWidget(waitRequestSpinBox, 1, 1);
    mainLayout->addWidget(runButton, 0, 2, 2, 1);
    mainLayout->addWidget(responseLabel, 2, 0);
    mainLayout->addWidget(responseLineEdit, 2, 1, 1, 3);
    mainLayout->addWidget(trafficLabel, 3, 0, 1, 4);
    mainLayout->addWidget(statusLabel, 4, 0, 1, 5);
    setLayout(mainLayout);

    setWindowTitle(tr("Slave"));
    serialPortComboBox->setFocus();

    timer.setSingleShot(true);

    connect(runButton, SIGNAL(clicked()),
            this, SLOT(startSlave()));
    connect(&serial, SIGNAL(readyRead()),
            this, SLOT(readRequest()));
    connect(&timer, SIGNAL(timeout()),
            this, SLOT(processTimeout()));

    connect(serialPortComboBox, SIGNAL(currentIndexChanged(QString)),
            this, SLOT(activateRunButton()));
    connect(waitRequestSpinBox, SIGNAL(valueChanged(int)),
            this, SLOT(activateRunButton()));
    connect(responseLineEdit, SIGNAL(textChanged(QString)),
            this, SLOT(activateRunButton()));
}
예제 #6
0
파일: server.c 프로젝트: Bipsy/Linux
void service(int server_fd) {
    for(;;) {
        Message msg = readRequest(server_fd);
        if (strncmp(msg.type, PIPE, 4) == 0) {
            char client_pipe[BUF_LEN];
            strncpy(client_pipe, msg.msg_buf, BUF_LEN);
            int client_fd = open(client_pipe, O_WRONLY);
            writeResponse(client_fd, OK, 2);
        } else {
            printf("Couldn't decipher message\n");
        }
    }
}
예제 #7
0
HTTPConnection::HTTPConnection(QTcpSocket* socket, HTTPManager* parentManager) :
    QObject(parentManager),
    _parentManager(parentManager),
    _socket(socket),
    _address(socket->peerAddress())
{
    // take over ownership of the socket
    _socket->setParent(this);

    // connect initial slots
    connect(socket, SIGNAL(readyRead()), SLOT(readRequest()));
    connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(deleteLater()));
    connect(socket, SIGNAL(disconnected()), SLOT(deleteLater()));
}
예제 #8
0
void Manager::registerSocket()
{
    ++clientsConnected;
    QTcpSocket *clientConnection = tcpServer->nextPendingConnection();
    reportStatus();
    Q_EMIT message(tr("Client %1(%2) connected.")
                   .arg(clientConnection->peerAddress().toString())
                   .arg(clientConnection->peerPort()));
    connect(clientConnection, SIGNAL(disconnected()),
            this, SLOT(clearSocket()));
    connect(clientConnection, SIGNAL(readyRead()), this, SLOT(readRequest()));
    connect(clientConnection, SIGNAL(error(QAbstractSocket::SocketError)),
            this, SLOT(displayError(QAbstractSocket::SocketError)));
}
예제 #9
0
THttpSocket::THttpSocket(QObject *parent)
    : QTcpSocket(parent), lengthToRead(-1)
{
    T_TRACEFUNC("");

    do {
        sid = point.fetch_add(1);
    } while (!socketManager[sid].compareExchange(nullptr, this)); // store a socket
    tSystemDebug("THttpSocket  sid:%d", sid);

    connect(this, SIGNAL(readyRead()), this, SLOT(readRequest()));
    connect(this, SIGNAL(requestWrite(const QByteArray&)), this, SLOT(writeRawData(const QByteArray&)), Qt::QueuedConnection);

    idleElapsed = std::time(nullptr);
}
TInt CCTSYIntegrationTestSuiteStepBase::DoPauseL(const TDesC& aText, TTimeDuration aTimeout /* = ETimeMedium */)
/**
 Performs a pause, usually to allow user to intervene in Manual tests
 
 @param		aText - text for prompt
 @param		aTimeout - 
 @return	KErrNone if user pressed a key
 */
	{
	TInt ret = KErrNone;
		
	CConsoleBase* con = NULL;
	TRAPD(err, con = Console::NewL(_L("Interactive Test"), TSize(KConsFullScreen, KConsFullScreen)));

	INFO_PRINTF2(_L("Console status = %d"), err);
	TEST(err == KErrNone);
	CleanupStack::PushL(con);
	
	TConsoleReadRequestStatus readRequest(*con);
	//add to cleanup stack
	CleanupStack::PushL(readRequest);
	con->Printf(_L("%S (timeout %d secs) ..."), &aText, aTimeout / KOneSecond);
	con->Read(readRequest);
	
	ret = WaitForRequestWithTimeOut(readRequest, aTimeout);	
		
	if (ret == KErrTimedOut)
		{
		WARN_PRINTF1(_L("[doPause] No keypress detected, timeout! Manual action may not have occurred."));
		}

	if (readRequest.Int() == KRequestPending)	
		{
		readRequest.Cancel();
		}
	
	CleanupStack::PopAndDestroy(); // readRequest
	CleanupStack::PopAndDestroy(); // con
	
	return ret;
	}
예제 #11
0
void HTTPConnection::readRequest() {
    if (!_socket->canReadLine()) {
        return;
    }
    if (!_requestUrl.isEmpty()) {
        qDebug() << "Request URL was already set";
        return;
    }
    // parse out the method and resource
    QByteArray line = _socket->readLine().trimmed();
    if (line.startsWith("HEAD")) {
        _requestOperation = QNetworkAccessManager::HeadOperation;

    } else if (line.startsWith("GET")) {
        _requestOperation = QNetworkAccessManager::GetOperation;

    } else if (line.startsWith("PUT")) {
        _requestOperation = QNetworkAccessManager::PutOperation;

    } else if (line.startsWith("POST")) {
        _requestOperation = QNetworkAccessManager::PostOperation;

    } else if (line.startsWith("DELETE")) {
        _requestOperation = QNetworkAccessManager::DeleteOperation;

    } else {
        qWarning() << "Unrecognized HTTP operation." << _address << line;
        respond("400 Bad Request", "Unrecognized operation.");
        return;
    }
    int idx = line.indexOf(' ') + 1;
    _requestUrl.setUrl(line.mid(idx, line.lastIndexOf(' ') - idx));

    // switch to reading the header
    _socket->disconnect(this, SLOT(readRequest()));
    connect(_socket, SIGNAL(readyRead()), SLOT(readHeaders()));

    // read any headers immediately available
    readHeaders();
}
예제 #12
0
void TActionThread::run()
{
    QList<THttpRequest> reqs;
    QEventLoop eventLoop;
    httpSocket = new THttpSocket;

    if (!httpSocket->setSocketDescriptor(TActionContext::socketDesc)) {
        emitError(httpSocket->error());
        goto socket_error;
    }
    TActionContext::socketDesc = 0;

    for (;;) {
        reqs = readRequest(httpSocket);
        tSystemDebug("HTTP request count: %d", reqs.count());

        if (reqs.isEmpty())
            break;

        for (QMutableListIterator<THttpRequest> it(reqs); it.hasNext(); ) {
            THttpRequest &req = it.next();
            TActionContext::execute(req);

            httpSocket->flush();  // Flush socket
            TActionContext::release();
        }

        if (!httpSocket->waitForReadyRead(5000))
            break;
    }

    closeHttpSocket();  // disconnect

    // For cleanup
    while (eventLoop.processEvents()) {}

socket_error:
    delete httpSocket;
    httpSocket = 0;
}
예제 #13
0
/**
	Function which handles the server process management.
	The function polls the requests directory for new requests generated
	by the client processes.
	The server process management function requires max_restarts as a limitation
	for graceful degradation.
*/
int server(int max_restarts) {

	/**Directory pointer used to point to the directory location requests.*/
	DIR *dirp;
	/**Storage variable for return variable for usleep function call.*/
	int ret_val_usleep;

	/**Directory entry pointer.*/
	struct dirent *dp;

	printf("Server Process has begun processing the requests...\n");
	/**Check for Failure in generation of backup process.*/
	if(backup(max_restarts)==EXIT_SUCCESS) {
		printf("successfully executed...\n");		
	}
	/**If backup process cannot be created. The parent process takes control.(Graceful Degradation)*/
	else {		
		fprintf(stderr, "Error:Backup cannot be created.\nParent server process PID:%d taking control.\n",getpid());
	}

	while(1) {
		/**Open the requests directory.*/
		dirp = opendir("./requests");
		/**Condition to check if the opendir function has failed or not.*/
		if(dirp==NULL) {
			fprintf(stderr, "Error:Open Directory function failed.\n");
			/**Process returns and terminates with error.*/
			return EXIT_FAILURE;	
		}

		while(dirp) {
			/**Storage variable to generate the absolute path for the request file name.*/
			char request_name[100]="requests/";
			/**
				Condition to check if the readdir function has reached end of the directory
				or not. It is a condition to detect even failures for the readdir function calls.
				readdir() returns the directory entry pointer to the next directory file inside the
				given directory location.
			*/	    
    		if ((dp = readdir(dirp)) != NULL) {
        		/**
        			Check if the request file name contains req_ as the substring in the file name.
        			And if the type of the file is Regular file or not.
        		*/        		
        		if ((strstr(dp->d_name,"req_")!=NULL)&&(dp->d_type == DT_REG))
        		{
        			/**Generating the absolute path of the request file name.*/
        			if(strcat(request_name,dp->d_name)==NULL) {
        				fprintf(stderr, "Error:String Concatenation function failed.\n");
        				return EXIT_FAILURE;	
        			}
        			/**
        				Performing readRequest Call with requesting file name and failure chance.
        				Condition checks if the readRequest call failed or not.
        			*/	
        			if(readRequest(request_name)==EXIT_FAILURE) {
        				fprintf(stderr, "Error:readRequest function failed.\n");
        				return EXIT_FAILURE;
        			}
        			/**
        				Performing removeRequest Call with requesting file name.
        				Condition checks if the removeRequest call failed or not.
        			*/	
        			if(removeRequest(request_name)==EXIT_FAILURE) {
						fprintf(stderr, "Error:removeRequest function failed.\n");
        				return EXIT_FAILURE;
        			}
        			/**Sleeping the process for 500ms.*/
					ret_val_usleep = usleep(500000);
					/**Failure in usleep call*/
					if(ret_val_usleep<0) {
						
						fprintf(stderr, "Error:Usleep function failed.\n");
						/**Process returns and terminates with error*/
						return EXIT_FAILURE;
					}
        		}
    		}
    		else {
    			/**Directory end reached.*/
    			break;
    		}        
		}
		/**Close the requests directory. Check if the close operation was successful or not.*/
		if(closedir(dirp)<0) {
			fprintf(stderr, "Error:Usleep function failed.\n");
			/**Process returns and terminates with error*/
			return EXIT_FAILURE;
		}
	}
	/**Process returns and terminates with success.*/
	return EXIT_SUCCESS;
}
예제 #14
0
void TActionContext::execute()
{
    T_TRACEFUNC("");
    THttpResponseHeader responseHeader;
    accessLogger.open();

    try {
        if (!readRequest()) {
            return;
        }
        const THttpRequestHeader &hdr = httpReq->header();

        // Access log
        accessLogger.setTimestamp(QDateTime::currentDateTime());
        QByteArray firstLine = hdr.method() + ' ' + hdr.path();
        firstLine += QString(" HTTP/%1.%2").arg(hdr.majorVersion()).arg(hdr.minorVersion()).toLatin1();
        accessLogger.setRequest(firstLine);
        accessLogger.setRemoteHost( (Tf::app()->appSettings().value(LISTEN_PORT).toUInt() > 0) ? clientAddress().toString().toLatin1() : QByteArray("(unix)") );

        tSystemDebug("method : %s", hdr.method().data());
        tSystemDebug("path : %s", hdr.path().data());

        Tf::HttpMethod method = httpReq->method();
        QString path = THttpUtility::fromUrlEncoding(hdr.path().mid(0, hdr.path().indexOf('?')));

        // Routing info exists?
        TRouting rt = TUrlRoute::instance().findRouting(method, path);
        tSystemDebug("Routing: controller:%s  action:%s", rt.controller.data(),
                     rt.action.data());

        if (rt.isEmpty()) {
            // Default URL routing
            rt.params = path.split('/');
            if (path.startsWith(QLatin1Char('/')) && !rt.params.isEmpty()) {
                rt.params.removeFirst();  // unuse first item
            }
            if (path.endsWith(QLatin1Char('/')) && !rt.params.isEmpty()) {
                rt.params.removeLast();  // unuse last item
            }

            // Direct view render mode?
            if (Tf::app()->appSettings().value(DIRECT_VIEW_RENDER_MODE).toBool()) {
                // Direct view setting
                rt.controller = "directcontroller";
                rt.action = "show";
            } else {
                if (!rt.params.value(0).isEmpty()) {
                    rt.controller = rt.params.takeFirst().toLower().toLatin1() + "controller";

                    if (rt.controller == "applicationcontroller") {
                        rt.controller.clear();  // Can not call 'ApplicationController'
                    }

                    // Default action: index
                    rt.action = rt.params.value(0, QLatin1String("index")).toLatin1();
                    if (!rt.params.isEmpty()) {
                        rt.params.takeFirst();
                    }
                }
                tSystemDebug("Active Controller : %s", rt.controller.data());
            }
        }

        // Call controller method
        TDispatcher<TActionController> ctlrDispatcher(rt.controller);
        currController = ctlrDispatcher.object();
        if (currController) {
            currController->setActionName(rt.action);

            // Session
            if (currController->sessionEnabled()) {
                TSession session;
                QByteArray sessionId = httpReq->cookie(TSession::sessionName());
                if (!sessionId.isEmpty()) {
                    // Finds a session
                    session = TSessionManager::instance().findSession(sessionId);
                }
                currController->setSession(session);

                // Exports flash-variant
                currController->exportAllFlashVariants();
            }

            // Verify authenticity token
            if (Tf::app()->appSettings().value(ENABLE_CSRF_PROTECTION_MODULE, true).toBool()
                && currController->csrfProtectionEnabled() && !currController->exceptionActionsOfCsrfProtection().contains(rt.action)) {

                if (method == Tf::Post || method == Tf::Put || method == Tf::Delete) {
                    if (!currController->verifyRequest(*httpReq)) {
                        throw SecurityException("Invalid authenticity token", __FILE__, __LINE__);
                    }
                }
            }

            if (currController->sessionEnabled()) {
                if (currController->session().id().isEmpty() || Tf::app()->appSettings().value(AUTO_ID_REGENERATION).toBool()) {
                    TSessionManager::instance().remove(currController->session().sessionId); // Removes the old session
                    // Re-generate session ID
                    currController->session().sessionId = TSessionManager::instance().generateId();
                    tSystemDebug("Re-generate session ID: %s", currController->session().sessionId.data());
                }
                // Sets CSRF protection informaion
                TActionController::setCsrfProtectionInto(currController->session());
            }

            // Database Transaction
            transactions.setEnabled(currController->transactionEnabled());

            // Do filters
            if (currController->preFilter()) {

                // Dispathes
                bool dispatched = ctlrDispatcher.invoke(rt.action, rt.params);
                if (dispatched) {
                    autoRemoveFiles << currController->autoRemoveFiles;  // Adds auto-remove files

                    // Post fileter
                    currController->postFilter();

                    if (currController->rollbackRequested()) {
                        rollbackTransactions();
                    } else {
                        // Commits a transaction to the database
                        commitTransactions();
                    }

                    // Session store
                    if (currController->sessionEnabled()) {
                        bool stored = TSessionManager::instance().store(currController->session());
                        if (stored) {
                            QDateTime expire;
                            if (TSessionManager::sessionLifeTime() > 0) {
                                expire = QDateTime::currentDateTime().addSecs(TSessionManager::sessionLifeTime());
                            }

                            // Sets the path in the session cookie
                            QString cookiePath = Tf::app()->appSettings().value(SESSION_COOKIE_PATH).toString();
                            currController->addCookie(TSession::sessionName(), currController->session().id(), expire, cookiePath);
                        }
                    }
                }
            }

            // Sets charset to the content-type
            QByteArray ctype = currController->response.header().contentType().toLower();
            if (ctype.startsWith("text") && !ctype.contains("charset")) {
                ctype += "; charset=";
                ctype += Tf::app()->codecForHttpOutput()->name();
                currController->response.header().setContentType(ctype);
            }

            // Sets the default status code of HTTP response
            accessLogger.setStatusCode( (!currController->response.isBodyNull()) ? currController->statusCode() : Tf::InternalServerError );
            currController->response.header().setStatusLine(accessLogger.statusCode(), THttpUtility::getResponseReasonPhrase(accessLogger.statusCode()));

            // Writes a response and access log
            int bytes = writeResponse(currController->response.header(), currController->response.bodyIODevice(),
                                      currController->response.bodyLength());
            accessLogger.setResponseBytes(bytes);

            // Session GC
            TSessionManager::instance().collectGarbage();

        } else {
            accessLogger.setStatusCode( Tf::BadRequest );

            if (method == Tf::Get) {  // GET Method
                path.remove(0, 1);
                QFile reqPath(Tf::app()->publicPath() + path);
                QFileInfo fi(reqPath);

                if (fi.isFile() && fi.isReadable()) {
                    // Check "If-Modified-Since" header for caching
                    bool sendfile = true;
                    QByteArray ifModifiedSince = hdr.rawHeader("If-Modified-Since");

                    if (!ifModifiedSince.isEmpty()) {
                        QDateTime dt = THttpUtility::fromHttpDateTimeString(ifModifiedSince);
                        sendfile = (!dt.isValid() || dt != fi.lastModified());
                    }

                    if (sendfile) {
                        // Sends a request file
                        responseHeader.setRawHeader("Last-Modified", THttpUtility::toHttpDateTimeString(fi.lastModified()));
                        QByteArray type = Tf::app()->internetMediaType(fi.suffix());
                        int bytes = writeResponse(Tf::OK, responseHeader, type, &reqPath, reqPath.size());
                        accessLogger.setResponseBytes( bytes );
                    } else {
                        // Not send the data
                        int bytes = writeResponse(Tf::NotModified, responseHeader);
                        accessLogger.setResponseBytes( bytes );
                    }
                } else {
                    int bytes = writeResponse(Tf::NotFound, responseHeader);
                    accessLogger.setResponseBytes( bytes );
                }
                accessLogger.setStatusCode( responseHeader.statusCode() );

            } else if (method == Tf::Post) {
                // file upload?
            } else {
                // HEAD, DELETE, ...
            }
        }

    } catch (ClientErrorException &e) {
        tWarn("Caught ClientErrorException: status code:%d", e.statusCode());
        int bytes = writeResponse(e.statusCode(), responseHeader);
        accessLogger.setResponseBytes( bytes );
        accessLogger.setStatusCode( e.statusCode() );
    } catch (SqlException &e) {
        tError("Caught SqlException: %s  [%s:%d]", qPrintable(e.message()), qPrintable(e.fileName()), e.lineNumber());
        tSystemError("Caught SqlException: %s  [%s:%d]", qPrintable(e.message()), qPrintable(e.fileName()), e.lineNumber());
        closeHttpSocket();
    } catch (KvsException &e) {
        tError("Caught KvsException: %s  [%s:%d]", qPrintable(e.message()), qPrintable(e.fileName()), e.lineNumber());
        tSystemError("Caught KvsException: %s  [%s:%d]", qPrintable(e.message()), qPrintable(e.fileName()), e.lineNumber());
        closeHttpSocket();
    } catch (SecurityException &e) {
        tError("Caught SecurityException: %s  [%s:%d]", qPrintable(e.message()), qPrintable(e.fileName()), e.lineNumber());
        tSystemError("Caught SecurityException: %s  [%s:%d]", qPrintable(e.message()), qPrintable(e.fileName()), e.lineNumber());
        closeHttpSocket();
    } catch (RuntimeException &e) {
        tError("Caught RuntimeException: %s  [%s:%d]", qPrintable(e.message()), qPrintable(e.fileName()), e.lineNumber());
        tSystemError("Caught RuntimeException: %s  [%s:%d]", qPrintable(e.message()), qPrintable(e.fileName()), e.lineNumber());
        closeHttpSocket();
    } catch (...) {
        tError("Caught Exception");
        tSystemError("Caught Exception");
        closeHttpSocket();
    }

    // Push to the pool
    TActionContext::releaseSqlDatabases();
    TActionContext::releaseKvsDatabases();

    TActionContext::accessLogger.write();  // Writes access log
    releaseHttpSocket();
}
예제 #15
0
int main(int argc, char* argv[]) {
  Config config;
  int socket;
  int returnStatus = 0;
  struct sockaddr_in tcpServer;

  /* server is running */
  server_running = 1;
  server_pid = getpid();

  /* no requests yet! */
  total_requests = 0;

  /* make sure we've got a config file */
  if(argc < 2) {
    fprintf(stderr, "Usage: %s <config_file>\n", argv[0]);
    exit(1);
  }

  /* load the config file, abort on error */
  if(load_config(&config, argv[1]) < 0) {
    fprintf(stderr, "Error parsing config file %s\n", argv[1]);
    exit(1);
  }

  /* create a UDP socket or die */
  if((socket = e_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
    exit(1);
  }

  /* allow re-use of socket addresses to avoid 'already bound' problems */
  int v = 1;
  returnStatus = setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &v, sizeof(v));
  if(returnStatus < 0) {
    perror("Setting socket option failed");
    exit(1);
  }
  
  /* set up the TCP server */
  tcpServer.sin_family = AF_INET;
  tcpServer.sin_port = htons(config.port);
  tcpServer.sin_addr.s_addr = INADDR_ANY;

  /* bind socket to the server */
  returnStatus = bind(socket, (struct sockaddr*)&tcpServer, sizeof(tcpServer));
  if(returnStatus < 0) {
    perror("Bind Failed");
    if(close(socket) < 0) {
      perror("Error closing socket");
    }
    exit(1);
  }
  
  /* allow a given signal to terminate server */
  struct sigaction act;
  memset(&act, 0, sizeof(act));
  act.sa_handler = sigshutdown_handler;
  sigaction(config.shutdown_signal, &act, 0);

  /* open log file if enabled */
  if(config.logging) {
    logfile = fopen_or_die(config.logfile, "w");
  }
  
  /* run indefinitely */
  int connect_fd;
  if(config.logging) {
    slog(logfile, "Server started\n");
    slog(logfile, "Listening on port %d\n", config.port); 
  }

  /* listen for connections */
  returnStatus = listen(socket, BACK_LOG);
  if(returnStatus < 0) {
    perror("Error listening for connection");
  }

  while(server_running) {
    /* accept an incoming connection from queue */
    if((connect_fd = accept(socket, NULL, NULL)) < 0) {
      /* may have been interrupted, safe to try again */
      if(errno == EINTR || errno == EAGAIN) {
        continue;
      } else {
        perror("Unable to accept connection");
        exit(EXIT_FAILURE);
      }
    } else {
      /* read in an entire HTTP request */
      FILE* record_file = NULL;
      if(config.recording) {
        record_file = fopen_or_die(config.recordfile, "w");
      }
      char* request = readRequest(connect_fd, record_file);
      /* ensure is a valid request i.e is a GET and hostname matches */
      char* file_path = malloc_or_die(BUFFER_LEN);
      if(parseRequest(connect_fd, request, file_path, &config)) {
        ReplyParams r;
        r.connect_fd = connect_fd;
        strncpy(r.file_path, file_path, BUFFER_LEN);
        r.c = &config;
        r.logfile = logfile;
        sendHttpReply(&r);
      }

      /* successfully handled a request, count it */
      total_requests++;

      /* shutdown & close client connection */
      close(connect_fd);
    }
  }

  if(close(socket) < 0) {
    perror("Error closing socket");
  }
  /* cleanup & exit */
  if(config.logging) {
    slog(logfile, "Terminating server\n");
    fclose(logfile);
  }
  return 0;
}
예제 #16
0
void CNearbySession::doSession(SOCKET sessionSocket, SOCKET cancelSocket) {

    this->sessionSocket = sessionSocket;

    std::cout << "CNearby::startup - accepted connection!" << std::endl;

    uint32_t sequence = 1;

    fd_set readFds;

    struct timeval tv;
    tv.tv_sec = 5;
    tv.tv_usec = 0;

    std::string remoteDevice, remoteEndpoint;

    SOCKET selectSocket = std::max<SOCKET>(sessionSocket, std::max<SOCKET>(queueReadySocket, cancelSocket)) + 1;

    std::vector<uint8_t> buffer;
    buffer.reserve(chunkSize*2);

    bool sessionLoop = true;

    while(sessionLoop) {

        FD_ZERO(&readFds);

        FD_SET(sessionSocket, &readFds);
        FD_SET(queueReadySocket, &readFds);
        if (cancelSocket != SOCKET_ERROR) {
            FD_SET(cancelSocket, &readFds);
        }

        tv.tv_sec = 5;
        tv.tv_usec = 0;

        if(int activity = select(selectSocket, &readFds, nullptr, nullptr, &tv)) {

            //check for read
            if (FD_ISSET(cancelSocket, &readFds)) {
                //data on cancelSocket means we should quit
                std::cerr << "CNearby::doSession - sessionSocket error set!" << std::endl;
                break;
            }

            if (FD_ISSET(queueReadySocket, &readFds)) {
                //data on messageQueue means we should send it
                std::cerr << "CNearby::doSession - messageQueue notification set!" << std::endl;
                NotificationSocket::Clear(queueReadySocket);
                doWriteQueue(sessionSocket, sequence);
            }

            if (FD_ISSET(sessionSocket, &readFds)) {
                sessionLoop = readRequest(sessionSocket, buffer, sequence, remoteDevice, remoteEndpoint);
            }
        }
        else
        {
            std::cerr << "CNearby::doSession - send Ping!" << std::endl;

            CNearbyMessage message;
            sendAnswer(sessionSocket, message.buildPing(sequence));
        }
    }

    closesocket(sessionSocket);
    this->sessionSocket = SOCKET_ERROR;

    std::cout << "CNearby::doSession - complete!" << std::endl;
}
예제 #17
0
/**
*INICIO DO PROGRAMA PRINCIPAL
*/
int main (int argc, char **argv) {
   /* Os sockets. Um que será o socket que vai escutar pelas conexões
    * e o outro que vai ser o socket específico de cada conexão */
	int listenfd, connfd;
   /* Informações sobre o socket (endereço e porta) ficam nesta struct */
	struct sockaddr_in servaddr;
   /* Retorno da função fork para saber quem é o processo filho e quem
    * é o processo pai */
   pid_t childpid;
   /* Armazena linhas recebidas do cliente */
	char	recvline[MAXLINE + 1];
   /* Armazena o tamanho da string lida do cliente */
   ssize_t  n;

	if (argc != 2) {
      fprintf(stderr,"Uso: %s <Porta>\n",argv[0]);
      fprintf(stderr,"Vai rodar um servidor HTTP <Porta> TCP\n");
		exit(1);
	}

   /* Criação de um socket. Eh como se fosse um descritor de arquivo. Eh
    * possivel fazer operacoes como read, write e close. Neste
    * caso o socket criado eh um socket IPv4 (por causa do AF_INET),
    * que vai usar TCP (por causa do SOCK_STREAM), já que o HTTP
    * funciona sobre TCP, e será usado para uma aplicação convencional sobre
    * a Internet (por causa do número 0) */
	if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
		perror("socket :(\n");
		exit(2);
	}

   /* Agora é necessário informar os endereços associados a este
    * socket. É necessário informar o endereço / interface e a porta,
    * pois mais adiante o socket ficará esperando conexões nesta porta
    * e neste(s) endereços. Para isso é necessário preencher a struct
    * servaddr. É necessário colocar lá o tipo de socket (No nosso
    * caso AF_INET porque é IPv4), em qual endereço / interface serão
    * esperadas conexões (Neste caso em qualquer uma -- INADDR_ANY) e
    * qual a porta. Neste caso será a porta que foi passada como
    * argumento no shell (atoi(argv[1]))
    */
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family      = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port        = htons(atoi(argv[1]));
	if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {
		perror("bind :(\n");
		exit(3);
	}

   /* Como este código é o código de um servidor, o socket será um
    * socket passivo. Para isto é necessário chamar a função listen
    * que define que este é um socket de servidor que ficará esperando
    * por conexões nos endereços definidos na função bind. */
	if (listen(listenfd, LISTENQ) == -1) {
		perror("listen :(\n");
		exit(4);
	}
   system("clear");
   printf("[Servidor no ar. Aguardando conexoes na porta %s]\n",argv[1]);
   printf("[Para finalizar, pressione CTRL+c ou rode um kill ou killall]\n");

   /* O servidor no final das contas é um loop infinito de espera por
    * conexões e processamento de cada uma individualmente */
	for (;;) {
      /* O socket inicial que foi criado é o socket que vai aguardar
       * pela conexão na porta especificada. Mas pode ser que existam
       * diversos clientes conectando no servidor. Por isso deve-se
       * utilizar a função accept. Esta função vai retirar uma conexão
       * da fila de conexões que foram aceitas no socket listenfd e
       * vai criar um socket específico para esta conexão. O descritor
       * deste novo socket é o retorno da função accept. */
		if ((connfd = accept(listenfd, (struct sockaddr *) NULL, NULL)) == -1 ) {
			perror("accept :(\n");
			exit(5);
		}

      /* Agora o servidor precisa tratar este cliente de forma
       * separada. Para isto é criado um processo filho usando a
       * função fork. O processo vai ser uma cópia deste. Depois da
       * função fork, os dois processos (pai e filho) estarão no mesmo
       * ponto do código, mas cada um terá um PID diferente. Assim é
       * possível diferenciar o que cada processo terá que fazer. O
       * filho tem que processar a requisição do cliente. O pai tem
       * que voltar no loop para continuar aceitando novas conexões */
      /* Se o retorno da função fork for zero, é porque está no
       * processo filho. */
      if ( (childpid = fork()) == 0) {
         /**** PROCESSO FILHO ****/
         printf("[Uma conexao aberta]\n");
         /* Já que está no processo filho, não precisa mais do socket
          * listenfd. Só o processo pai precisa deste socket. */
         close(listenfd);

         /* Agora pode ler do socket e escrever no socket. Isto tem
          * que ser feito em sincronia com o cliente. Não faz sentido
          * ler sem ter o que ler. Ou seja, neste caso está sendo
          * considerado que o cliente vai enviar algo para o servidor.
          * O servidor vai processar o que tiver sido enviado e vai
          * enviar uma resposta para o cliente (Que precisará estar
          * esperando por esta resposta)
          */

         /* ========================================================= */
         /* ========================================================= */
         /*                         EP1 INÍCIO                        */
         /* ========================================================= */
         /* ========================================================= */
         /* TODO: É esta parte do código que terá que ser modificada
          * para que este servidor consiga interpretar comandos HTTP */

         /* Definindo o cliente */
         Host cliente;
         cliente.destino = servaddr;
         cliente.socket = connfd;

         /* Ler a requisição do cliente*/
         Request client_request = readRequest(cliente);

         /* Mostrar na tela as requisições dos clientes */
         printf("*********************************************************************");
         printf("\n [Metodo requisitado]:   %s \n", client_request.metodo);
         printf("\n [Recurso solicitado]:   %s \n", client_request.recurso);
         printf("\n [Protocolo]:            %s \n", client_request.protocolo);

         /* checar a Request do client */
         CR_returns returns =  checkRequest(cliente, client_request);

         /* enviar resposta da requisição para o cliente */
         if (strcmp(client_request.metodo,"GET")==0) {
            sendGETRequest(cliente, returns);
         }
         else if (strcmp(client_request.metodo,"POST")==0) {
            sendPOSTRequest(cliente, returns,client_request);

         }

         /* ========================================================= */
         /* ========================================================= */
         /*                         EP1 FIM                           */
         /* ========================================================= */
         /* ========================================================= */

         /* Após ter feito toda a troca de informação com o cliente,
          * pode finalizar o processo filho */
         printf("[Uma conexao fechada]\n");
         exit(0);
      }
      /**** PROCESSO PAI ****/
      /* Se for o pai, a única coisa a ser feita é fechar o socket
       * connfd (ele é o socket do cliente específico que será tratado
       * pelo processo filho) */
		close(connfd);
	}
	exit(0);
}
예제 #18
0
THttpSocket::THttpSocket(QObject *parent)
    : QTcpSocket(parent), lengthToRead(-1), lastProcessed(QDateTime::currentDateTime())
{
    T_TRACEFUNC("");
    connect(this, SIGNAL(readyRead()), this, SLOT(readRequest()));
}