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

📄 http_request.cpp

📁 ace开发环境 用来开发网络程序 其运用了设计模式、多平台、C++等多种知识
💻 CPP
字号:
// $Id: HTTP_Request.cpp 61404 2004-10-27 21:30:47Z olli $#include "ace/Message_Block.h"#include "HTTP_Request.h"#include "HTTP_Helpers.h"#include "HTTP_Config.h"#include "ace/OS_NS_string.h"#include "ace/OS_NS_pwd.h"#include "ace/Log_Msg.h"ACE_RCSID(server, HTTP_Request, "$Id: HTTP_Request.cpp 61404 2004-10-27 21:30:47Z olli $")const char *constHTTP_Request::static_header_strings_[HTTP_Request::NUM_HEADER_STRINGS] ={  "Date",  "Pragma",  "Authorization",  "From",  "If-Modified-Since",  "Referrer",  "User-Agent",  "Allow",  "Content-Encoding",  "Content-Length",  "Content-Type",  "Expires",  "Last-Modified"};const char *constHTTP_Request::static_method_strings_[HTTP_Request::NUM_METHOD_STRINGS] ={  "GET",  "HEAD",  "POST",  "PUT"};// For reasons of efficiency, this class expects buffer to be// null-terminated, and buflen does NOT include the \0.HTTP_Request::HTTP_Request (void)  : got_request_line_ (0),    method_ (0),    uri_ (0),    version_ (0),    path_ (0),    cgi_ (0),    cgi_env_ (0),    cgi_args_ (0),    query_string_ (0),    path_info_ (0),    header_strings_ (HTTP_Request::static_header_strings_),    method_strings_ (HTTP_Request::static_method_strings_){  for (size_t i = 0;       i < HTTP_Request::NUM_HEADER_STRINGS;       i++)    this->headers_.recognize (this->header_strings_[i]);}HTTP_Request::~HTTP_Request (void){  ACE_OS::free (this->method_);  ACE_OS::free (this->uri_);  ACE_OS::free (this->version_);  ACE_OS::free (this->path_);  ACE_OS::free (this->query_string_);  ACE_OS::free (this->path_info_);  delete [] this->cgi_env_;}intHTTP_Request::parse_request (ACE_Message_Block &mb){  mb.wr_ptr ()[0] = '\0';  // Note that RFC 822 does not mention the maximum length of a header  // line.  So in theory, there is no maximum length.  // In Apache, they assume that each header line should not exceed  // 8K.  int result = this->headers_.complete_header_line (mb.rd_ptr ());  if (result != 0)    {      if (!this->got_request_line ())        {          this->parse_request_line (mb.rd_ptr ());          while (this->headers_.complete_header_line (mb.rd_ptr ()) > 0)            this->headers_.parse_header_line (mb.rd_ptr ());        }      else if (result > 0)        do          this->headers_.parse_header_line (mb.rd_ptr ());        while (this->headers_.complete_header_line (mb.rd_ptr ()) > 0);    }  mb.wr_ptr (ACE_OS::strlen(mb.rd_ptr ()) - mb.length ());  if (this->headers_.end_of_headers ()      || (this->got_request_line () && this->version () == 0))    return this->init (mb.rd_ptr (), mb.length ());  else    return 0;}voidHTTP_Request::parse_request_line (char *const request_line){  char *ptr = request_line;  char *buf = request_line;  int offset = 1;  this->status_ = HTTP_Status_Code::STATUS_OK;  ptr = ACE_OS::strchr (request_line, '\n');  if (ptr > request_line && ptr[-1] == '\r')    ptr--, offset++;  if (ptr == request_line)    {      this->status_ = HTTP_Status_Code::STATUS_BAD_REQUEST;      return;    }  *ptr = '\0';  ptr += offset;  char *lasts = 0; // for strtok_r  // Get the request type.  this->got_request_line_ = 1;  if (this->method (ACE_OS::strtok_r (buf, " \t", &lasts))      && this->uri (ACE_OS::strtok_r (0, " \t", &lasts)))    {      this->type (this->method ());      if (this->version (ACE_OS::strtok_r (0, " \t", &lasts)) == 0          && this->type () != HTTP_Request::GET)        this->status_ = HTTP_Status_Code::STATUS_NOT_IMPLEMENTED;      if (this->path (this->uri ()) == 0)        this->status_ = HTTP_Status_Code::STATUS_NOT_FOUND;    }  ACE_DEBUG ((LM_DEBUG, " (%t) request %s %s %s parsed\n",              (this->method () ? this->method () : "-"),              (this->uri () ? this->uri () : "="),              (this->version () ? this->version () : "HTTP/0.9")));  ACE_OS::memmove (buf, ptr, ACE_OS::strlen (ptr)+1);}intHTTP_Request::init (char *const buffer,                    int buflen){  // Initialize these every time.  content_length_ = -1;  // Extract the data pointer.  data_ = buffer;  datalen_ = 0;  // Set the datalen  if (data_ != 0)    datalen_ = buflen;  else    datalen_ = 0;  ACE_DEBUG ((LM_DEBUG, " (%t) init has initialized\n"));  return 1;}const char *HTTP_Request::method (void) const{  return this->method_;}const char *HTTP_Request::uri (void) const{  return this->uri_;}const char *HTTP_Request::version (void) const{  return this->version_;}const char *HTTP_Request::path (void) const{  return this->path_;}intHTTP_Request::cgi (void) const{  return this->cgi_;}const char **HTTP_Request::cgi_env (void) const{  return (const char **)this->cgi_env_;}const char *HTTP_Request::cgi_args (void) const{  return this->cgi_args_;}const char *HTTP_Request::query_string (void) const{  return this->query_string_;}const char *HTTP_Request::path_info (void) const{  return this->path_info_;}intHTTP_Request::got_request_line (void) const{  return this->got_request_line_;}intHTTP_Request::type (void) const{  return type_;}const Headers &HTTP_Request::headers (void) const{  return this->headers_;}const char *HTTP_Request::header_strings (int index) const{  const char *hs = 0;  if (0 <= index && index < NUM_HEADER_STRINGS)    hs = this->header_strings_[index];  return hs;}const char *HTTP_Request::header_values (int index) const{  const char *hs = 0;  const char *hv = 0;  if (0 <= index && index < NUM_HEADER_STRINGS)    {      hs = this->header_strings_[index];      hv = this->headers_[hs].value ();    }  return hv;}char *HTTP_Request::data (void){  return data_;}intHTTP_Request::data_length (void){  return datalen_;}intHTTP_Request::content_length (void){  if (this->content_length_ == -1)    {      const char * clv = this->headers_["Content-length"].value ();      this->content_length_ = (clv ? ACE_OS::atoi (clv) : 0);    }  return this->content_length_;}intHTTP_Request::status (void){  return this->status_;}const char *HTTP_Request::status_string (void){  return HTTP_Status_Code::instance ()[this->status_];}voidHTTP_Request::dump (void){  ACE_DEBUG ((LM_DEBUG, "%s command.\n"              "filename is %s,"              " length of the file is %d,"              " data string is %s,"              " datalen is %d,"              " status is %d, which is %s\n\n",              this->method () ? this->method () : "EMPTY",              this->uri () ? this->uri () : "EMPTY",              this->content_length (),              this->data () ? this->data () : "EMPTY",              this->data_length (),              this->status (),              this->status_string ()));}const char *HTTP_Request::method (const char *method_string){  if (this->method_)    ACE_OS::free (this->method_);  if (method_string == 0)    {      this->status_ = HTTP_Status_Code::STATUS_BAD_REQUEST;      this->method_ = 0;    }  else    this->method_ = ACE_OS::strdup (method_string);  return this->method_;}const char *HTTP_Request::uri (char *uri_string){  if (this->uri_)    ACE_OS::free (this->uri_);  if (uri_string == 0)    {      this->status_ = HTTP_Status_Code::STATUS_BAD_REQUEST;      this->uri_ = 0;    }  else    {      this->uri_ =  ACE_OS::strdup (uri_string);      this->cgi (this->uri_);      HTTP_Helper::HTTP_decode_string (this->uri_);    }  return this->uri_;}const char *HTTP_Request::version (const char *version_string){  if (this->version_)    ACE_OS::free (this->version_);  if (version_string)    this->version_ = ACE_OS::strdup (version_string);  else    this->version_ = 0;  return this->version_;}intHTTP_Request::type (const char *type_string){  this->type_ = HTTP_Request::NO_TYPE;  if (type_string == 0)    return this->type_;  for (size_t i = 0;       i < HTTP_Request::NUM_METHOD_STRINGS;       i++)    if (ACE_OS::strcmp (type_string, this->method_strings_[i]) == 0)      {        this->type_ = i;        break;      }  if (this->type_ == HTTP_Request::NO_TYPE)    this->status_ = HTTP_Status_Code::STATUS_NOT_IMPLEMENTED;  return this->type_;}intHTTP_Request::cgi (char *uri_string){  this->cgi_ = 0;  this->cgi_env_ = 0;  this->cgi_args_ = 0;  ACE_DEBUG ((LM_DEBUG, " (%t) HTTP_Request::cgi (%s)\n", uri_string));  if (uri_string == 0 || ACE_OS::strlen (uri_string) == 0)    return 0;  // There are 2 cases where a file could be a CGI script  //  // (1) the file has a CGI extension.  // (2) the file resides in a CGI bin directory.  char *extra_path_info = 0;  if (this->cgi_in_path (uri_string, extra_path_info)      || this->cgi_in_extension (uri_string, extra_path_info))    {      cgi_args_and_env (extra_path_info);      if (extra_path_info)        {          this->path_info_ = ACE_OS::strdup (extra_path_info);          HTTP_Helper::HTTP_decode_string (this->path_info_);          *extra_path_info = '\0';        }    }  return this->cgi_;}intHTTP_Request::cgi_in_path (char *uri_string, char *&extra_path_info){  char *cgi_path;  ACE_DEBUG ((LM_DEBUG, " (%t) HTTP_Request::cgi_in_path (%s)\n",              uri_string));  if (HTTP_Config::instance ()->cgi_path ())    cgi_path = ACE_OS::strdup (HTTP_Config::instance ()->cgi_path ());  else    cgi_path = ACE_OS::strdup ("");  // error checking considered helpful!  if (cgi_path == 0)    return 0;  char *lasts = 0;  char *cgi_path_next = ACE_OS::strtok_r (cgi_path, ":", &lasts);  if (cgi_path_next)    do      {        int len = ACE_OS::strlen (cgi_path_next);        // match path to cgi path        int in_cgi_path = 0;        if (*cgi_path_next == '/')          {            // cgi path next points to an ``absolute'' path            extra_path_info = uri_string;            in_cgi_path =              (ACE_OS::strncmp (extra_path_info, cgi_path_next, len) == 0);          }        else          {            // cgi path next points to a ``relative'' path            extra_path_info = ACE_OS::strstr (uri_string, cgi_path_next);            in_cgi_path = (extra_path_info != 0);          }        if (in_cgi_path)          {            if (extra_path_info[len] == '/')              {                this->cgi_ = 1;                extra_path_info += len;                // move past the executable name                do                  extra_path_info++;                while (*extra_path_info != '/'                       && *extra_path_info != '?'                       && *extra_path_info != '\0');                if (*extra_path_info == '\0')                  extra_path_info = 0;                break;              }          }        extra_path_info = 0;        cgi_path_next = ACE_OS::strtok_r (0, ":", &lasts);      }    while (cgi_path_next);  ACE_OS::free (cgi_path);  return this->cgi_;}intHTTP_Request::cgi_in_extension (char *uri_string, char *&extra_path_info){  extra_path_info = ACE_OS::strstr (uri_string, ".cgi");  ACE_DEBUG ((LM_DEBUG, " (%t) HTTP_Request::cgi_in_extension (%s)\n",              uri_string));  while (extra_path_info != 0)    {      extra_path_info += 4;      // skip past ``.cgi''      switch (*extra_path_info)        {        case '\0':          extra_path_info = 0;          break;        case '/':        case '?':          break;        default:          extra_path_info = ACE_OS::strstr (extra_path_info, ".cgi");          continue;        }      this->cgi_ = 1;      break;    }  return this->cgi_;}voidHTTP_Request::cgi_args_and_env (char *&extra_path_info){  char *cgi_question = 0;  if (extra_path_info)    cgi_question = ACE_OS::strchr (extra_path_info, '?');  if (extra_path_info == cgi_question)    extra_path_info = 0;  if (cgi_question)    {      *cgi_question++ = '\0';      if (*cgi_question != '\0')        {          // We need the ``original'' QUERY_STRING for the          // environment.  We will substitute '+'s for spaces in the          // other copy.          this->query_string_ = ACE_OS::strdup (cgi_question);          char *ptr = cgi_question;          int count = 0;          do            if (*ptr == '+')              *ptr = ' ';            else if (*ptr == '&' || *ptr == '=')              count++;          while (*++ptr);          count++;          if (ACE_OS::strchr (cgi_question, '='))            {              ACE_NEW (this->cgi_env_, char *[count+1]);              int i = 0;              ptr = cgi_question;              do                {                  this->cgi_env_ [i++] = ptr;                  while (*ptr++)                      if (*ptr == '&' || *ptr == '=')                        *ptr = '\0';                  HTTP_Helper::HTTP_decode_string (this->cgi_env_[i-1]);                }              while (i < count);              this->cgi_env_[count] = 0;            }          else            {              this->cgi_args_ = cgi_question;              HTTP_Helper::HTTP_decode_string (cgi_question);            }        }    }}const char *HTTP_Request::path (const char *uri_string){  char const *file_name = uri_string;  char buf[MAXPATHLEN + 1];  buf[0] = '\0';  if (file_name == 0) return 0;  if (*file_name == '/')    {      file_name++;      if (*file_name == '~')        {          char *ptr = buf;          while (*++file_name && *file_name != '/')            *ptr++ = *file_name;          *ptr = '\0';          if (ptr == buf)            ACE_OS::strcpy (buf, ACE_OS::getenv ("HOME"));          else            {#if !defined (ACE_WIN32) && !defined (VXWORKS)              char pw_buf[BUFSIZ];              struct passwd pw_struct;              if (ACE_OS::getpwnam_r (buf, &pw_struct, pw_buf, sizeof (pw_buf))                  == 0)                return 0;              ACE_OS::strcpy (buf, pw_struct.pw_dir);#endif /* NOT ACE_WIN32 AND NOT VXWORKS */            }          ACE_OS::strcat (buf, "/");          ACE_OS::strcat (buf, HTTP_Config::instance ()->user_dir ());          ACE_OS::strcat (buf, file_name);        }      else        {          // With a starting '/' but no '~'          ACE_OS::strcat (buf, HTTP_Config::instance ()->document_root ());          ACE_OS::strcat (buf, file_name - 1);        }    }  if (*buf != '\0')    this->path_ = ACE_OS::strdup (buf);  return this->path_;}

⌨️ 快捷键说明

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