/** callback to be invoked when new connection(s) have been assigned to this worker. */ void HttpWorker::onNewConnection(ev::async& /*w*/, int /*revents*/) { std::pair<Socket*, ServerSocket*> client; while (queue_.dequeue(&client)) { spawnConnection(client.first, client.second); } }
// retrieves the data from the server - control path void d_retr(char **params, short *abor, int fd, struct state *cstate, struct config *configuration) { int accepted, retcode, file, r, subn = 0; char filepath[PATH_LENGTH], buf[2 * BUFSIZE]; // accepts / connects to the client if (spawnConnection(cstate, &accepted)) { retcode = 5; write(fd, &retcode, sizeof (int)); return; } // loads filepath of the given file readUntil(filepath, fd, 0, PATH_LENGTH); // check the file status if (isFileOk(filepath) == -1) { retcode = 5; write(fd, &retcode, sizeof (int)); close(accepted); return; } // opens the file if ((file = open(filepath, O_RDONLY)) == -1) { retcode = 5; write(fd, &retcode, sizeof (int)); close(accepted); return; } // read blocks of data from the file // and sends it through the data connection while ((r = read(file, buf, BUFSIZE)) > 0) { // ASCII type transfer if (cstate->transfer_type == ASCII) { char tmp[2 * BUFSIZE]; // converts \n to \r\n sequence, // return how much is the result longer if ((subn = im2as(tmp, buf, BUFSIZE)) == -1) { retcode = 5; write(fd, &retcode, sizeof (int)); close(accepted); break; } r += subn; memcpy(buf, tmp, BUFSIZE * 2); } if (write(accepted, buf, r) == -1) { retcode = 5; write(fd, &retcode, sizeof (int)); close(accepted); break; } } // closes the connection close(file); close(accepted); // reads and reports the result retcode = 2; write(fd, &retcode, sizeof (int)); }
// strores the received file on the server - data part void d_stor(char **params, short *abor, int fd, struct state *cstate, struct config *configuration) { int accepted, retcode, file, r, subn = 0; char filepath[PATH_LENGTH], buf[BUFSIZE]; accepted = 0; // accepts/ connects to the client if (spawnConnection(cstate, &accepted)) { retcode = 5; write(fd, &retcode, sizeof (int)); return; } // reads the filepath from the ctrl thread readUntil(filepath, fd, 0, PATH_LENGTH); // if (isFileOk(filepath) == -1){ // retcode = 5; // write(fd, &retcode, sizeof (int)); // return; // } // creates the file if ((file = open(filepath, O_WRONLY | O_CREAT | O_TRUNC, 0700)) == -1) { retcode = 5; write(fd, &retcode, sizeof (int)); close(accepted); return; } // reads the data and saves it to the file while ((r = read(accepted, buf, BUFSIZE)) > 0) { // ASCII data transfer if (cstate->transfer_type == 6) { char tmp[BUFSIZE]; // converts \r\n sequence to \n, // return how much is the result shorter if ((subn = as2im(tmp, buf, BUFSIZE)) == -1) { retcode = 5; write(fd, &retcode, sizeof (int)); close(accepted); break; } r -= subn; memcpy(buf, tmp, BUFSIZE); } if (write(file, buf, r) == -1) { retcode = 5; write(fd, &retcode, sizeof (int)); close(accepted); break; } } // closes the file close(file); // reports result and closes the connection retcode = 2; close(accepted); write(fd, &retcode, sizeof (int)); }
/** callback to be invoked when new connection(s) have been assigned to this worker. */ void HttpWorker::onNewConnection(ev::async& /*w*/, int /*revents*/) { pthread_spin_lock(&queueLock_); while (!queue_.empty()) { std::pair<Socket*, ServerSocket*> client(queue_.front()); queue_.pop_front(); pthread_spin_unlock(&queueLock_); spawnConnection(client.first, client.second); pthread_spin_lock(&queueLock_); } pthread_spin_unlock(&queueLock_); }
// sends the listing of the directory - data part void d_list(char **params, short *abor, int fd, struct state *cstate, struct config *configuration) { int accepted, retcode, subn, r; char buf[BUFSIZE], dir[32], path[128], tmp[2 * BUFSIZE]; // accept connection / connect to the client if (spawnConnection(cstate, &accepted)) { retcode = 5; write(fd, &retcode, sizeof (int)); return; } // read path to dir from the control thread readUntil(dir, fd, 0, 32); // join the path if (getFullPath(path, cstate, configuration, dir) == -1) { retcode = 5; write(fd, &retcode, sizeof (int)); close(accepted); return; } // loads the listing of the directory // determined by path to string pointed to by buf listDir(path, buf); // sends the list in ASCII mode r = strlen(buf); // converts \n to \r\n sequence, // return how much is the result longer if ((subn = im2as(tmp, buf, BUFSIZE)) == -1) { retcode = 5; write(fd, &retcode, sizeof (int)); close(accepted); return; } r += subn; memcpy(buf, tmp, BUFSIZE * 2); if (write(accepted, buf, r) == -1) { retcode = 5; write(fd, &retcode, sizeof (int)); close(accepted); return; } close(accepted); // report the result retcode = 2; write(fd, &retcode, sizeof (int)); }