⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 request.cpp

📁 伯克利做的SFTP安全文件传输协议
💻 CPP
字号:
// request.cc// code for request.h// copyright SafeTP Development Group, Inc., 2000  Terms of use are as specified in license.txt#include "request.h"      // this module#include "missing.h"      // stricmp#include <ctype.h>        // isspace#include "sockutil.h"     // socket calls#include "xassert.h"      // xassert#ifndef SAFETPC#include "lineread.h"     // StreamLineReader#endif// textual representations of the requests, in the// same order as the RequestCommand enumerationstatic char const * const requestMap[] = {  "(unknown)",  // 959 commands  "USER",  "PASS",  "ACCT",  "CWD",  "CDUP",  "SMNT",  "QUIT",  "REIN",  "PORT",  "PASV",  "TYPE",  "STRU",  "MODE",  "RETR",  "STOR",  "STOU",  "APPE",  "ALLO",  "REST",  "RNFR",  "RNTO",  "ABOR",  "DELE",  "RMD",  "MKD",  "PWD",  "LIST",  "NLST",  "SITE",  "SYST",  "STAT",  "HELP",  "NOOP",  // 2228 commands  "AUTH",  "ADAT",  "PROT",  "PBSZ",  "CCC",  "MIC",  "CONF",  "ENC",  // old commands  "XCUP",  "XCWD",  "XMKD",  "XPWD",  "XRMD",  "SIZE",  // nonstandard commands  "MDTM",  // new commands  "DIGT",};// if profiling reveals this is a bottleneck, it// can be replaced with a better algorithmRequestCommand textToRequestCommand(char const *cmd){  // NOTE: RFC959, section 5.3, states that commands  // are case insensitive.  Thus, stricmp is used.  loopi(TABLESIZE(requestMap)) {    if (0==missing_stricmp(cmd, requestMap[i])) {      return (RequestCommand)i;    }  }  return CMD_UNKNOWN;}char const *requestCommandToText(RequestCommand c){  xassert(validRequestCommand(c));  return requestMap[c];}bool validRequestCommand(RequestCommand c){  // get >= 0 test for free by using unsigned comparison  return (unsigned)c < NUM_COMMAND_REQUESTS;}Request::Request(Request const &obj)  : text(obj.text),    command(obj.text),    data(NULL),    // set below    c(obj.c){  data = text.pcharc() + (obj.data - obj.text.pcharc());}Request::Request(RequestCommand cmd, char const *dat)  : command(requestCommandToText(cmd)),    c(cmd){  xassert(validRequestCommand(cmd));  composeText(dat);}Request::Request(char const *cmd, char const *dat)  : command(cmd)                        // cmd as-is{  c = textToRequestCommand(command);    // integer code  composeText(dat);}void Request::composeText(char const *dat){  if (dat != NULL) {    text = stringb(command << " " << dat);        // command, space, data    data = text.pchar() + command.length() + 1;   // data starts one char after cmd ends  }  else {    text = command;                           // command only    data = text.pchar() + command.length();   // "", essentially  }}Request::Request(char const *src)  : text(src){  parse();}Request::Request(SOCKET s){  text = recvLine(s);  parse();}#ifndef SAFETPCRequest::Request(StreamLineReader &reader){  if (!reader.getNextLine(text)) {    // unexpected EOF    xassert(!"unexpected end of stream");  }  parse();}#endifvoid Request::send(SOCKET s) const{  #if 0    // original code    sendAllString(s, text);    sendEOL(s);  #else    // There are some firewalls, one of which in installed at ohio-state.edu, which    // believe that PORT requests must arrive, in their entirety, as a single IP    // datagram.  The above code, unfortunately, usually results in two IP datagrams,    // one for the request text and one for the CRLF pair.    //    // Therefore, as a fix, we will put all the data into a single buffer first.    //    // This is probably more efficient anyway, since new/strncpy/delete is probably    // less expensive than the additional system call.    int len = strlen(text);     // length *without* CRLF    char *buf = new char[len+2];    strncpy(buf, text, len);   	// main text    buf[len] = '\r';    buf[len+1] = '\n';	       	// CRLF    try {      sendAll(s, buf, len+2);    }    catch (...) {      delete[] buf;     // prevent leak      throw;    }    delete[] buf;  #endif}void Request::parse(){                        // grab a pointer to the internal char* of 'text'  char const *p = text.pcharc();  // ++ begin hack ++  // skip binary characters that may precede a command  // this is a temporary hack to fix an incompatibility with IE  // which sends a telnet IP & synch before ABOR  // we really need a more general solution to this problem  while (!isprint(*p) && *p!=0) {    p++;  }  // did we skip anything?  if (p != text.pcharc()) {    text = p;            // replace old text with trimmed text    p = text.pcharc();   // grab internal char* again  }  // -- end hack --  // find first non-ws character  while (isspace(*p)) {    p++;  }  char const *cmd_start = p;  // find next ws  while (*p!=0 && !isspace(*p)) {    p++;  }  char const *cmd_end = p;  // pull off command  command = string(cmd_start, cmd_end-cmd_start);  c = textToRequestCommand(command);  // find next non-ws; this is data (may be "")  while (isspace(*p)) {    p++;  }  data = p;}bool Request::isCommand(char const *cmd) const{  return 0==missing_stricmp(command, cmd);}string Request::getTextNoPassword() const{  if (getCmd() == CMD_PASS) {    return string("PASS ********");  }  else {    return getText();  }}// ---------------- test code -------------------#ifdef TEST_REQUEST#include <iostream.h>    // coutint main(){  {    char const *text = "AUTH frobozz-snazzy";    Request req(text);       // parse    xassert(req.getCmd() == CMD_AUTH);    cout << req.getText() << endl;    Request req2(req);       // copy ctor    xassert(req.getCmd() == CMD_AUTH);    cout << req.getText() << endl;  }  return 0;}#endif // TEST_REQUEST

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -