void serveClient(int cfd, struct sockaddr_in *clientaddr){ char client_msg[MAX_BUFFER]; int c1,c2,c3,c4,cookie,prev = 0; char magic[20], type[20], id[245], name[245], err[245]; char *claddr = inet_ntoa(clientaddr->sin_addr); int clport = clientaddr->sin_port; memset(client_msg,0,MAX_BUFFER); while(recv(cfd, client_msg, MAX_BUFFER, 0)){ if(strlen(client_msg) > MAX_STR_SIZE){ clientError(claddr,clport); break; } int t = 0, c = 0; memset(err, 0, 1); memset(name, 0, 1); memset(magic,0, 1); sscanf(client_msg,"%s%s%s%s%s",magic,type,id,name,err); if(!compare(magic,MAGIC_STRING)) t = 0; else if(prev == 0 && compare(err,"")) t = compare(type,"HELLO"); else if(prev == 1 && compare(name,"")){ c = atoi(id); if (cookie == c) t = compare(type,"CLIENT_BYE"); } int stat; stat = t; if(prev == 0 && stat){ prev = 1; sscanf(claddr,"%d.%d.%d.%d",&c1,&c2,&c3,&c4); cookie = ((c1+c2+c3+c4)*13)%1111; printf("%d %s %s from %s:%d\n",cookie,id,name,claddr,clport); fflush(stdout); memset(client_msg,0,MAX_BUFFER); /*reset buffer for writing*/ sprintf(client_msg,"%s STATUS %d %s:%d\n",MAGIC_STRING,cookie,claddr,clport); write(cfd, client_msg,strlen(client_msg)); memset(client_msg,0,MAX_BUFFER); /*reset buffer for client_bye*/ } else if(prev ==1 && stat){ memset(client_msg,0,MAX_BUFFER); /*reset buffer for writing*/ sprintf(client_msg,"%s SERVER_BYE\n",MAGIC_STRING); write(cfd, client_msg,strlen(client_msg)); break; } else{ clientError(claddr,clport); break; } } close(cfd); }
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), m_preferences(new Preferences), m_xmppClient(new QXmppClient(this)), m_loginWidget(new LoginWidget(this)) { ui->setupUi(this); initialize(); ui->treeWidget->setClient(m_xmppClient); // xmpp client connect(m_xmppClient, SIGNAL(connected()), this, SLOT(clientConnected())); connect(m_xmppClient, SIGNAL(disconnected()), this, SLOT(clientDisconnected()) ); connect(m_xmppClient, SIGNAL(error(QXmppClient::Error)), this, SLOT(clientError(QXmppClient::Error))); bool check = connect(m_xmppClient, SIGNAL(messageReceived(QXmppMessage)), this, SLOT(messageReceived(QXmppMessage))); Q_ASSERT(check); // qApp connect( qApp, SIGNAL(lastWindowClosed()), this, SLOT(quit()) ); // login connect(m_loginWidget, SIGNAL(login()), this, SLOT(login())); connect(m_loginWidget, SIGNAL(cancelLogin()), this, SLOT(cancelLogin())); }
void FileTransfertUpload::onSocketError(QAbstractSocket::SocketError) { sender()->deleteLater(); _errors++; emit clientError("Client reject file."); check_nbr(); }
JabberServerRegisterAccount::JabberServerRegisterAccount(const QString &server, const QString &username, const QString &password, bool legacySSLProbe, bool legacySSL, bool forceSSL, const QString &host, int port) : QObject(), Result(0), Server(server), Username(username), Password(password), Jid(QString::null) { Client = new MiniClient; connect(Client, SIGNAL(handshaken()), SLOT(clientHandshaken())); connect(Client, SIGNAL(error()), SLOT(clientError())); Client->connectToServer(XMPP::Jid(Server), legacySSLProbe, legacySSL, forceSSL, host, port); }
void MainWindow::doClientStateChanged( int status) { // qDebug() << "ClientStateChanged: state=" << status; if ((status == ArnClient::ConnectStat::Negotiating) && !_arnClient->isReContact()) { //// Initialy connected for negotiation and login // qDebug() << "ClientStateChanged Negotiating (!reContact):"; _wasContact = true; _arnClient->setAutoConnect( true, 2); disconnect( _arnClient, SIGNAL(tcpError(QString,QAbstractSocket::SocketError)), this, SLOT(clientError(QString))); _appSettings->setValue("connect/host", _ui->hostEdit->text()); _appSettings->setValue("connect/port", _ui->portEdit->value()); } else if ((status == ArnClient::ConnectStat::Connected) && !_arnClient->isReConnect()) { //// Fully connected also after any negotiation and login, but not reconnected // qDebug() << "ClientStateChanged Connected (!reConnect):"; _wasConnect = true; if (_ui->arnView->model()) { // model already set, just reset viewer _arnModel->clear(); // Needed after a canceled login (why?) _ui->arnView->reset(); } else // model has not been set, do it now _ui->arnView->setModel( _arnModel); _arnModel->setHideBidir( _ui->hideBidir->isChecked()); _ui->releaseButton->setEnabled( true); _ui->vcsButton->setEnabled( true); _ui->connectButton->setEnabled( true); _ui->manageButton->setEnabled( true); _delegate = qobject_cast<MultiDelegate*>( _ui->arnView->itemDelegate()); if (!_delegate) { _delegate = new MultiDelegate; connect( _delegate, SIGNAL(itemEditTrigged(QModelIndex)), this, SLOT(onItemEditTrigg(QModelIndex))); } _ui->arnView->setItemDelegate( _delegate); _ui->arnView->setEnabled( true); _ui->arnView->setColumnWidth(0, _pathWidth); _ui->arnView->setColumnWidth(1, 10); _chatServWin->reset(); setCurItemPath(); } else if ((status == ArnClient::ConnectStat::Disconnected) && !_isConnect) { //// Manual disconnection from user // qDebug() << "ClientStateChanged Manual Disconnect:"; setConnectOffGui(); } _ui->connectStat->setChecked( (status == ArnClient::ConnectStat::Connected) || ((status == ArnClient::ConnectStat::Negotiating) && _isLoginCancel)); _ui->connectStat->setVisible( _wasContact); _ui->chatButton->setVisible( _wasConnect); }
void Qtopia4Sync::abort() { TRACE(Qtopia4Sync) << "Qtopia4Sync::abort"; if ( d->transaction ) d->currentPlugin->abortTransaction(); clientError(); if ( d->currentPlugin ) cleanupPlugin(); initsyncVars(); }
void process_cgi(SWS_REQUEST* req_ptr){ struct stat st; char *question_mark; char absolute_path[PATH_MAX_SIZE]; char arg_str[PATH_MAX_SIZE]; if (req_ptr->method != METHOD_GET){ clientError(501, "Not Implemented", req_ptr); } memset(absolute_path, 0, PATH_MAX_SIZE); memset(arg_str, 0, PATH_MAX_SIZE); if ( (question_mark = strchr(req_ptr->path, '?')) != NULL ){ *question_mark = '\0'; snprintf(absolute_path,PATH_MAX_SIZE, "%s/%s", dir, req_ptr->path); snprintf(arg_str, PATH_MAX_SIZE, "%s", &question_mark[1]); }else{ snprintf(absolute_path,PATH_MAX_SIZE, "%s/%s", dir, req_ptr->path); } printf("cgi-file absolute_path : %s\n", absolute_path); printf("cgi-file argument list : %s\n", arg_str[0] == '\0'?"No Argument":arg_str); if (stat(absolute_path, &st) < 0){ perror("stat"); clientError(404, "Not Found", req_ptr); } switch(st.st_mode&S_IFMT){ case S_IFREG: if (st.st_mode&(S_IXUSR | S_IXGRP | S_IXOTH)){ exe_cgi(req_ptr, absolute_path, arg_str); }else{ clientError(500, "Internal Server Error", req_ptr); } break; default: clientError(500, "Internal Server Error", req_ptr); break; } }
cTcpClient::cTcpClient(QObject* parent): QObject(parent) { autoConnectGesetzt = false; aktMsg.len = 0; connectTimer = new QTimer(parent); connect( &client, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(clientError(QAbstractSocket::SocketError))); connect( &client, SIGNAL(readyRead()), this, SLOT(read())); connect( &client, SIGNAL(connected()), this, SLOT(clientConnected())); }
void process_request_path(SWS_REQUEST* req_ptr){ struct stat st; char absolute_path[PATH_MAX_SIZE]; if (!check_path_str(req_ptr)){ clientError(400, "Bad Request", req_ptr); } if (req_ptr->is_cgi){ process_cgi(req_ptr); return; } memset(absolute_path, 0, PATH_MAX_SIZE); //printf("dir : %s\n", dir); snprintf(absolute_path, strlen(dir) + strlen(req_ptr->path) + 1, "%s%s", dir, req_ptr->path); //printf("Server: absolute path is %s\n", absolute_path); if (stat(absolute_path, &st) < 0){ //perror("stat"); clientError(404, "Not Found", req_ptr); } switch(st.st_mode&S_IFMT){ case S_IFREG: if (st.st_mode&(S_IRUSR | S_IRGRP | S_IROTH)){ int file_fd; file_fd = open(absolute_path, O_RDONLY); if (file_fd < 0){ clientError(500, "Internal Server Error", req_ptr); return; }else{ //handle both simple and non-simple request fprintf(stderr, "%s\n", "it's a file"); send_file(file_fd, req_ptr, absolute_path); } }else{ clientError(403, "Forbidden", req_ptr); } break; case S_IFDIR: if (st.st_mode&(S_IRUSR | S_IRGRP | S_IROTH)){ //process the index here indexGenerate( req_ptr, absolute_path); }else{ clientError(403, "Forbidden", req_ptr); } break; default: clientError(404, "Not Found", req_ptr); break; } }
void FileTransfertUpload::receiveAcceptFile(NetworkClient *client, int port) { if (port == 0) { _errors++; emit clientError("Client reject file."); check_nbr(); } else { QTcpSocket *socket = new QTcpSocket(this); socket->connectToHost(client->getTcpSocket()->peerAddress(), port); connect(socket, SIGNAL(connected()), this, SLOT(onSocketConnected())); connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onSocketError(QAbstractSocket::SocketError))); connect(socket, SIGNAL(bytesWritten(qint64)), this, SLOT(onSocketWritten())); } }
void SocketHandler::newConnection() { QTcpSocket *socket = m_server->nextPendingConnection(); connect(socket, SIGNAL(disconnected()), this, SLOT(clientDisconnected())); qDebug() << "Got a connection"; if (m_client != 0) { qDebug() << "HELP! Already have a client but I have a new connection"; return; } m_client = socket; connect(m_client, SIGNAL(readyRead()), this, SLOT(clientReadyRead())); connect(m_client, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(clientError(QAbstractSocket::SocketError))); }
void init_sws_request(SWS_REQUEST* req_ptr){ req_ptr->method = METHOD_UNKNOWN; req_ptr->version = HTTP_UNKNOWN; //init the req_ptr->path to the current dir memset(dir, 0, PATH_MAX_SIZE); if (getcwd(dir, PATH_MAX_SIZE) == NULL){ clientError(500, "Internal Server Error", req_ptr); } memset(req_ptr->if_modified_since, 0, BUFF_SIZE); memset(req_ptr->request_line, 0, BUFF_SIZE); req_ptr->status = STATUS_UNKNOWN; req_ptr->is_simple = 0; req_ptr->is_cgi = 0; req_ptr->is_if_modified = 0; }
inline bool KMSmtpClient::waitAndCheckResponse( int captureCode, KMAbstractMailClient::MailClientError failedError) { //Wait for server response. if(!waitForResponse()) { //Server doesn't response. return false; } qDebug()<<"Response code is:"<<responseCode()<<"Capture code is:"<<captureCode; // The response code needs to be 250. if(responseCode() != captureCode) { //Server error. emit clientError(failedError); //Failed to connect. return false; } //Connect and response correct. return true; }
void MainWindow::connection( bool isConnect) { bool wasConnect = _wasConnect; setConnectionState( isConnect); _isLoginCancel = false; _ui->connectButton->setEnabled( false); if (isConnect) { connect( _arnClient, SIGNAL(tcpError(QString,QAbstractSocket::SocketError)), this, SLOT(clientError(QString))); //// Setup WhoIAm Arn::XStringMap wimXsm; wimXsm.add("Agent", "Arn Browser - " + ver); wimXsm.add("UserName", _settings->d.userName); wimXsm.add("Contact", _settings->d.contact); wimXsm.add("Location", _settings->d.location); _arnClient->setWhoIAm( wimXsm); _arnClient->connectToArn( _ui->hostEdit->text(), _ui->portEdit->value()); _connector->setCurHost( _ui->hostEdit->text()); _ui->discoverButton->setVisible( false); _ui->hostEdit->setEnabled( false); _ui->portEdit->setEnabled( false); } else if (wasConnect) { _arnModel->clear(); ArnClient::ConnectStat stat = _arnClient->connectStatus(); if ((stat != ArnClient::ConnectStat::Connected) // No contact with server && (stat != ArnClient::ConnectStat::Negotiating)) setConnectOffGui(); _arnClient->close(); } else { // Never got connected but got contact, model not dirty _arnClient->close(); setConnectOffGui(); } }
/** * Creation of a client into a thread * thread then started * @brief Controler::runClient */ void Controler::runClient() { qDebug()<<"launching client on port "+ QString::number(port_)+"..."; ipServer_ = window_->getIPAddress(); //set gui window_->setClientGuiFinal(port_); //create a client thread to avoid gui freeze client_ = new Client(this); clientThread_ = new QThread; client_->moveToThread(clientThread_); connect(client_,SIGNAL(error(QString)),this,SLOT(clientError(QString))); connect(clientThread_,SIGNAL(started()),client_,SLOT(run())); connect(client_,SIGNAL(finished()),clientThread_,SLOT(quit())); connect(client_,SIGNAL(finished()),clientThread_,SLOT(deleteLater())); connect(clientThread_,SIGNAL(finished()),clientThread_,SLOT(deleteLater())); clientThread_->start(); }
void TCPServer::connectClient() { emit info(classname, "adding new connection"); // Create socket and client while(server->hasPendingConnections()) { QTcpSocket *socket = server->nextPendingConnection(); QObject::connect(socket, SIGNAL(disconnected()), this, SLOT(disconnectClient())); socketMap[socket] = socket; TCPClient *client = new TCPClient(this); client->connect(socket); QObject::connect(client, SIGNAL(dataReceived(QByteArray)), this, SLOT(clientDataReceived(QByteArray))); QObject::connect(client, SIGNAL(info(QString,QString)), this, SLOT(clientInfo(QString,QString))); QObject::connect(client, SIGNAL(warning(QString,QString)), this, SLOT(clientWarning(QString,QString))); QObject::connect(client, SIGNAL(error(QString,QString)), this, SLOT(clientError(QString,QString))); clientMap[socket] = client; } emit connectionCount(socketMap.size()); }
void CTorrent::run() { m_bRunning = true; m_bStopping = false; try { if( !check() ) { m_nState = STATE_STOPPED; m_bStopping = m_bRunning = false; notify("Checking canceled"); return; } btContext* ctx = &m_Context; int dl = 0; m_pListener->notify("Starting server.."); ctx_startserver(ctx); m_pListener->notify("Registering..."); ctx_register(ctx, dl); m_nState = STATE_RUNNING; m_pListener->notify("Download started"); int ttv; int tv_slow = 1; /*ms*/ int tv_fast = 0; /*ms*/ btPeer *peer; int cs; struct sockaddr csin; int err; time_t choke_timer; time_t report_timer; time_t now; int i; time( &now ); choke_timer = report_timer = now; while( !m_bStopping ) { int readerr; int writeerr; int execerr; int pollerr; socklen_t sa_len; /* * Select a socket or time out */ if (ctx->xsock) { ttv = tv_fast; } else { ttv = tv_slow; } err = poll( ctx->status, ctx->nstatus, ttv); if (err < 0) { bts_perror(errno, "poll"); m_nState = STATE_ERROR; break; } time(&now); for (cs=0; cs < SOCKID_MAX; cs++) { /* loop through executable sockets */ if (ctx->x_set[ cs]) { btPeer *p = ctx->sockpeer[cs]; execerr = clientRun( cs, EXECUTE); if (execerr == 0) { if ( ctx->x_set[ cs]) { ctx->x_set[ cs] = 0; ctx->xsock--; } } if ( kStream_oqlen( &p->ios)) { /* data is waiting on the output buffer */ ctx_setevents( ctx, cs, POLLOUT); } if (execerr < 0) { clientError("execute", cs); } } } for (i=0; i<ctx->nstatus; i++) { /* for each poll event */ cs = ctx->status[i].fd; readerr=0; writeerr=0; execerr=0; pollerr=0; if (CTX_STATUS_REVENTS( ctx, i) & POLLIN) { bt_assert( ctx->status[i].events & POLLIN); /* readable */ if (cs == ctx->ss) { /* service socket */ sa_len = sizeof(csin); cs = accept( ctx->ss, &csin, &sa_len); if (cs < 0) { bts_perror( errno, "accept"); } else { peer_answer( ctx, cs); } } else if (cs == ctx->udpsock) { int err = udp_ready( ctx); if (err) { printf("Error %d processing UDP packet.\n", err); } } else { btPeer *p = ctx->sockpeer[ cs]; readerr = clientRun( cs, READABLE); if (readerr == 1) { /* more to read */ if (!ctx->x_set[cs]) { ctx->x_set[cs] = 1; ctx->xsock++; } } if ( kStream_oqlen( &p->ios)) { /* data is waiting on the output buffer */ ctx_setevents( ctx, cs, POLLOUT); } } } /* if */ if (CTX_STATUS_REVENTS( ctx, i) & POLLOUT) { writeerr = clientWrite( cs ); if (writeerr == 0) { /* output drained */ ctx_clrevents( ctx, cs, POLLOUT); if (!ctx->x_set[ cs]) { /* output buffer is empty, check for more work */ ctx->x_set[ cs] = 1; ctx->xsock++; } } } /* if */ if (CTX_STATUS_REVENTS( ctx, i) & (POLLERR | POLLHUP | POLLNVAL)) { int events = CTX_STATUS_REVENTS( ctx, i); if (events & POLLHUP) { ctx->sockpeer[cs]->ios.error = BTERR_POLLHUP; } else if (events & POLLERR) { ctx->sockpeer[cs]->ios.error = BTERR_POLLERR; } else if (events & POLLNVAL) { ctx->sockpeer[cs]->ios.error = BTERR_POLLNVAL; } pollerr = -1; } if (readerr < 0 || writeerr < 0 || execerr < 0 || pollerr < 0) { const char *act = NULL; if (readerr<0) act = "read"; if (writeerr<0) act = "write"; if (execerr<0) act = "execute"; if (pollerr<0) act = "poll"; clientError( act, cs); } peer = ctx->sockpeer[cs]; if ( peer && !peer->remote.choked && peer->local.interested && !peer->local.snubbed && now - peer->lastreceived > 120) { peer->local.snubbed = 1; } if (peer && peer->pex_supported > 0 && peer->pex_timer > 0 && now - peer->pex_timer >= 60) { sendPeerExchange(ctx->downloads[peer->download], peer); } } if (ctx->downloads[dl]->reregister_interval != 0 && now - ctx->downloads[dl]->reregister_timer > ctx->downloads[dl]->reregister_interval) { notify("Updating..."); ctx->downloads[dl]->reregister_timer = now; ctx_reregister( ctx, dl); } if (now - report_timer > 0) { int complt = bs_countBits( &ctx->downloads[dl]->fileset.completed); if ((complt == ctx->downloads[dl]->fileset.npieces) && !ctx->downloads[dl]->complete) { notify("Completing..."); ctx_complete (ctx, dl); m_nState = STATE_COMPLETE; break; } report_timer=now; updateStatus(); } if (now - choke_timer > 30) { /* recalculate favorite peers */ choke_timer=now; peer_favorites( ctx, &ctx->downloads[dl]->peerset); } } } catch(const char* ex) { m_pListener->error( ex ); m_nState = STATE_ERROR; } notify("Disconnecting..."); int dl = 0; ctx_writefastresume(m_Context.downloads[dl], (char*) m_szDownloadDir ); ctx_shutdown( &m_Context, dl ); cacheclose(); m_bRunning = false; if( m_bStopping ) { notify("Download stopped"); m_bStopping = false; m_nState = STATE_STOPPED; } else if( m_nState == STATE_COMPLETE ) { notify("Download complete"); } else if( m_nState == STATE_ERROR ) { notify("Download failed"); } else m_nState = STATE_STOPPED; }
bool KMSmtpClient::connectToHost() { //Check out the socket pointer. if(socket()==nullptr) { qCritical()<<"Socket pointer is NULL."; return false; } //Check out the connection type. switch (connectionType()) { case TlsConnection: case TcpConnection: qDebug()<<"Start normal link, host:"<<host()<<"port:"<<port(); //Simply call the connect to host function. socket()->connectToHost(host(), port()); break; case SslConnection: qDebug()<<"Start SSL link, host:"<<host()<<"port:"<<port(); //Recast socket as a QSslSocket. static_cast<QSslSocket *>(socket())->connectToHostEncrypted(host(), port()); break; } qDebug()<<"Start to connect."; //Tries to connect to server if(!socket()->waitForConnected(connectionTimeout())) { //Emit the error. emit clientError(ConnectionTimeoutError); //Failed to connect. return false; } // If the response code is not 220 (Service ready) // means that is something wrong with the server //The response code needs to be 220. if(!waitAndCheckResponse(220, ServerError)) { //Failed to login. return false; } qDebug()<<"Start EHLO"; // Send a EHLO/HELO message to the server // The client's first command must be EHLO/HELO sendMessage("EHLO " + userName()); //The response code needs to be 250. if(!waitAndCheckResponse(250, ServerError)) { //Failed to login. return false; } //If the connection type is TLS connection, we have to start TLS. if(connectionType() == TlsConnection) { //Send a request to start TLS handshake. sendMessage("STARTTLS"); //The response code needs to be 220. if(!waitAndCheckResponse(220, ServerError)) { //Failed to login. return false; } //Recast the socket into ssl socket. QSslSocket *sslSocket=static_cast<QSslSocket *>(socket()); //Start encryption. qDebug()<<"Start encryption."; sslSocket->startClientEncryption(); sslSocket->ignoreSslErrors(); //Check out result. if(!sslSocket->waitForEncrypted(connectionTimeout())) { //Print out the error information. qCritical()<<sslSocket->errorString(); //Emit the smtp error. emit clientError(ConnectionTimeoutError); //Failed to connect. return false; } qDebug()<<"Start EHLO again"; // Send ELHO one more time sendMessage("EHLO " + userName()); //The response code needs to be 250. if(!waitAndCheckResponse(250, ServerError)) { //Failed to login. return false; } } //Mission complete. return true; }
char *parse_request_path(char *req, SWS_REQUEST* req_ptr){ char *sp; char *c; char *path, *path_index; int hex1, hex2; int ret; /* * also has three situation * #1 request don't contain the HTTP version part like : method sp uri\r\n * #2 request contain the HTTP version part like : method sp uri sp HTTP\r\n * #3 path is empty like : method\r\n */ //for case #3 if ( strncmp(req, "\015\012", 2) == 0 || strncmp(req, "\012", 1) == 0){ //to the root strncpy(req_ptr->path, "/", 1); return req; } //for case #1/#2 if ((sp = strchr(req, ' ')) != NULL || (sp = strstr(req, "\015\012")) != NULL || (sp = strstr(req, "\012")) != NULL ){ if ((path = (char *)calloc(sp-req, sizeof(char))) == NULL) clientError(500, "Internal Server Error", req_ptr); path_index = path; //iterate throught the path and decode "% HEX HEX" URI encoding for (c = req; c != sp;){ if (*c == '%' && c+1 != sp && c+1 != NULL && isxdigit((int)c[1]) && c+2 != sp && c+2 != NULL && isxdigit((int)c[2])){ hex1 = *(c+1); hex2 = *(c+2); if (hex1 >= 'a'){ hex1 = hex1 - 87; }else if (hex1 >= 'a'){ hex1 = hex1 - 55; }else{ hex1 = hex1 - 48; } if (hex2 >= 'a'){ hex2 = hex2 - 87; }else if (hex2 >= 'a'){ hex2 = hex2 - 55; }else{ hex2 = hex2 - 48; } ret = hex1*16 + hex2; *path_index++ = ret; c += 3; }else{ *path_index++ = *c++; } } // memcopy (void)memmove((void *)(req_ptr->path), (void *)path, (path_index-path)); safe_free(path); } return sp; }
//check the path based on the string int check_path_str(SWS_REQUEST* req_ptr){ char *path = req_ptr->path; int len = strlen(path); //for ~ translation char *tilde; char *forward_slash; //check .. and . int forward = 0; int backward = 0; int prev; int cur; int i = 0; //printf("origin path: %s\n", path); //printf("origin len: %d\n", len); if (path[0] != '/'){ return 0; } prev = '/'; /* * check the ~ translation, like /~username/somefile * because username must exist and not '/', so the len is at least 3 */ if (len >= 3 && path[1] == '~' && path[2] != '/'){ tilde = path + 1; //check if the ending '/' exists if ( (forward_slash = strchr(tilde, '/')) != NULL ){ //if exists like /~username/ *forward_slash = '\0'; i = (forward_slash - path) + 1; }else{ //if not exists like /~username path[len++] = '/'; i = len; } //change the server dir root to user home // snprintf(dir, PATH_MAX_SIZE, "/home/%s/sws/", tilde+1); errno = 0; struct passwd *pwd; while( (pwd = getpwent()) != NULL ){ if(strncmp(pwd->pw_name, &tilde[1], strlen(pwd->pw_name)) == 0 ){ snprintf(dir, PATH_MAX_SIZE, "%s/sws", pwd->pw_dir); } errno = 0; } if(pwd == NULL && errno != 0){ clientError(404, "Not Found", req_ptr); } path[i - 1] = '/'; //truncate to the rest path string if(strcpy(req_ptr->path, req_ptr->path + i - 1) == NULL){ clientError(500, "Internal Server Error", req_ptr); } }else if ( len >= 9 && strncasecmp(path, "/cgi-bin/", 9) == 0 ){ req_ptr->is_cgi = 1; if(strncpy(dir, cgi_dir, PATH_MAX_SIZE) == NULL){ clientError(500, "Internal Server Error", req_ptr); } if(strncpy(req_ptr->path, req_ptr->path + 8, PATH_MAX_SIZE - 8) == NULL){ clientError(500, "Internal Server Error", req_ptr); } } //printf("new path : %s\n", req_ptr->path); i = 0; len = strlen(req_ptr->path); //check the rest of the path string, now '~' is only a normal char for (; i < len;){ cur = path[i]; if (prev != '/' && cur == '/'){ prev = '/'; forward++; continue; } if (prev == '/' && cur == '/'){ i++; continue; } //check `.` if (prev == '/' && path[i] == '.' && ((i+1 < len && path[i+1] == '/') | (i+1 == len))){ prev = '/'; i += 2; continue; } // check `..` if (prev == '/' && i+1 < len && path[i] == '.' && path[i+1] == '.' && (( i+2 < len && path[i+2] == '/')|(i+2 == len))){ prev = '/'; i += 3; backward++; //backward > forward means the path is jump out of the server dir root. if (backward > forward){ return 0; } continue; } prev = cur; i++; } return 1; }
void read_timeout_handler(int sig){ clientError(408, "Connection Time Out", req); }
void handle_request(SWS_REQUEST* req_ptr){ int fd = req_ptr->fd; int recv_size = 0; int req_index = 0; int is_request_line = TRUE; char read_buff[READ_BUFF_SIZE]; char req_buff[REQ_BUFF_SIZE]; char *rest; char *ifms_pos; char *ifms_end; //add read timeout struct sigaction sga; sga.sa_handler = read_timeout_handler; sigaction(SIGALRM, &sga, NULL); alarm(READ_TIMEOUT); memset(read_buff, 0, READ_BUFF_SIZE); memset(req_buff, 0, REQ_BUFF_SIZE); //read requesst for(;;){ if ((recv_size = recv(fd, read_buff, READ_BUFF_SIZE, 0)) > 0){ printf("read_buff : %s\n", read_buff); printf("req_buff : %s\n", req_buff); printf("recv_size : %d\n", recv_size); printf("req_index : %d\n", req_index); //add to request buff if (req_index + recv_size < REQ_BUFF_SIZE){ (void)memmove((void *)(req_buff+req_index), (void *)read_buff, recv_size); req_index += recv_size; }else{ //too long, bad request clientError(400, "Bad Request", req_ptr); } /* * parse request line first */ if (is_request_line && ( (rest = strstr(req_buff, "\015\012")) != NULL || (rest = strstr(req_buff, "\012")) != NULL)){ is_request_line = FALSE; // strncpy(req_ptr->request_line, req_buff, BUFF_SIZE); parse_request_line(req_buff, req_ptr); } if (req_ptr->is_simple){ break; } if ((strstr(req_buff, "\015\012\015\012") != NULL || strstr(req_buff, "\012\012") != NULL)){ break; } } /* peer shut down */ if ( recv_size == 0){ fprintf(stderr, "%s\n", "peer shut down"); break; } if ( recv_size < 0){ clientError(500, "Internal Server Error", req_ptr); break; } }//end of request parse //check the header /* Each header field consists of a name followed immediately by a colon (":"), a single space (SP) character, and the field value. Field names are case-insensitive. */ /* The If-Modified-Since request-header field is used with the `GET` method to make it conditional: if the requested resource has not been modified `since` the time specified in this field, a copy of the resource will not be returned from the server; instead, a 304 (not modified) response will be returned w, 3ithout any Entity-Body. */ if ( (ifms_pos = strstr(rest, "If-Modified-Since: ")) != NULL ){ ifms_pos += 19; if ( (ifms_end = strchr(rest, ' ')) != NULL || (ifms_end = strchr(rest, '\t')) != NULL ){ *ifms_end = '\0'; req_ptr->is_if_modified = 1; strncpy(req_ptr->if_modified_since, ifms_pos, 256); } } //check the method PrintRequest(req_ptr); if (req_ptr->method == METHOD_UNKNOWN){ clientError(400, "Bad Request", req_ptr); }else if (req_ptr->method == METHOD_UNIMPL){ clientError(501, "Not Implement", req_ptr); }else if (req_ptr->is_simple && req_ptr->method != METHOD_GET){ clientError(400, "Bad Request", req_ptr); } #ifndef DONT_CARE_VERSION //check http version if (req_ptr->version == HTTP_UNKNOWN){ clientError(505, "Version Not Supported", req_ptr); } #endif //check the request path process_request_path(req_ptr); close(req_ptr->fd); }