diff options
Diffstat (limited to 'ACE/apps/JAWS2/HTTPU')
24 files changed, 2161 insertions, 0 deletions
diff --git a/ACE/apps/JAWS2/HTTPU/http_base.cpp b/ACE/apps/JAWS2/HTTPU/http_base.cpp new file mode 100644 index 00000000000..3a653e5feef --- /dev/null +++ b/ACE/apps/JAWS2/HTTPU/http_base.cpp @@ -0,0 +1,323 @@ +// $Id$ + +#include "JAWS/Parse_Headers.h" +#include "HTTPU/http_base.h" +#include "HTTPU/http_headers.h" + +int +HTTP_Base::receive (ACE_Message_Block &mb) +{ + if (this->line () == 0) + { + if (this->extract_line (mb) == 0) + return 0; + if (this->status () != STATUS_OK) + return 1; + + // Call into the receive hook. + this->parse_line (); + if (this->status_ == STATUS_INTERNAL_SERVER_ERROR || this->no_headers_) + return 1; + } + + // Parse headers + JAWS_Parse_Headers *parser = JAWS_Parse_Headers_Singleton::instance (); + int ret = parser->parse_headers (&(this->info_), mb); + + switch (this->info_.status ()) + { + case JAWS_Header_Info::OK: + break; + + case JAWS_Header_Info::NO_MEMORY: + case JAWS_Header_Info::TOO_LONG: + default: + this->status_ = STATUS_INTERNAL_SERVER_ERROR; + break; + } + + return ret; +} + +int +HTTP_Base::deliver (ACE_Message_Block &mb) +{ + JAWS_Header_Data *data = 0; + + // Deliver this outgoing request. + // We do this by building the request up and writing it into the + // message block. + if (this->mb_ == 0) + { + // Make our Message Block big enough to hold a header name and + // header value + this->mb_ = new ACE_Message_Block (16384); // MAGIC! 2 x 8192 + if (this->mb_ == 0) + { + this->status_ = STATUS_INTERNAL_SERVER_ERROR; + return -1; + } + + // Call into the deliver hook + int r = this->espouse_line (); + if (r == -1) + return -1; + + if (r == 1) + this->deliver_state_ = 2; + + this->iter_.first (); + } + + while (this->deliver_state_ < 3) + { + // Deliver whatever is currently held in this->mb_. + size_t sz = (mb.space () < this->mb_->length () + ? mb.space () + : this->mb_->length ()); + + if (sz > 0) + { + mb.copy (this->mb_->rd_ptr (), sz); + this->mb_->rd_ptr (sz); + } + + if (mb.space () == 0) + return 0; + + // Arriving here means this->mb_ has been emptied. + this->mb_->crunch (); + + switch (this->deliver_state_) + { + case 0: // Obtain the next header data // Deliver a header name + this->deliver_state_ = this->deliver_header_name (data); + break; + + case 1: // Deliver a header value + this->deliver_state_ = this->deliver_header_value (data); + break; + + case 2: // Finished! + delete this->mb_; + this->mb_ = 0; + this->deliver_state_ = 3; + } + } + + return 1; +} + +int +HTTP_Base::receive_payload (ACE_Message_Block &mb) +{ + int result = 0; + + if (this->payload_.space () < mb.length ()) + result = this->payload_.size (this->payload_.size () + + mb.length () - this->payload_.space ()); + + if (result == 0) + { + this->payload_.copy (mb.rd_ptr (), mb.length ()); + mb.rd_ptr (mb.wr_ptr ()); + mb.crunch (); + } + else + this->status_ = STATUS_INTERNAL_SERVER_ERROR; + + return result; +} + +int +HTTP_Base::receive_payload (ACE_Message_Block &mb, long length) +{ + int result = 0; + + if (length == -1) + return this->receive_payload (mb); + + if (this->payload_.size () < (unsigned long) length) + result = this->payload_.size (length); + + if (result == -1) + { + this->status_ = STATUS_INTERNAL_SERVER_ERROR; + return -1; + } + + if (this->payload_.space () >= mb.length ()) + { + this->payload_.copy (mb.rd_ptr (), mb.length ()); + mb.rd_ptr (mb.wr_ptr ()); + mb.crunch (); + } + else + { + size_t space = this->payload_.space (); + this->payload_.copy (mb.rd_ptr (), space); + mb.rd_ptr (space); + } + + return this->payload_.length () == (unsigned long) length; +} + +const char * +HTTP_Base::payload (void) +{ + return this->payload_.rd_ptr (); +} + +unsigned long +HTTP_Base::payload_size (void) +{ + return this->payload_.length (); +} + +int +HTTP_Base::build_headers (JAWS_Headers *new_headers) +{ + JAWS_Header_Data *data = 0; + JAWS_Header_Data *data2 = 0; + JAWS_Header_Table_Iterator iter (*new_headers); + + iter.first (); + while (! iter.done ()) + { + data = iter.next (); + if (data == 0) + { + iter.advance (); + continue; + } + + if (data->header_type () == HTTP_HCodes::REPLACE_HEADER) + this->headers ()->remove_all (data->header_name ()); + else if (data->header_type () == HTTP_HCodes::INSERT_HEADER + || data->header_type () == HTTP_HCodes::APPENDTO_HEADER) + { + data2 = this->headers ()->find (data->header_name ()); + if (data2 != 0) + { + if (data->header_type () == HTTP_HCodes::APPENDTO_HEADER) + { + // Append to existing header + size_t len + = ACE_OS::strlen (data->header_value ()) + + ACE_OS::strlen (data2->header_value ()) + + 3; /* for comma, space, and nul */ + char *buf = new char [len]; + if (buf == 0) + { + this->status_ = STATUS_INTERNAL_SERVER_ERROR; + return -1; + } + ACE_OS::sprintf (buf, "%s, %s", + data2->header_value (), + data->header_value ()); + data2->header_value (buf); + delete [] buf; + } + + // Only insert if it isn't already present + iter.advance (); + continue; + } + } + + data2 = new JAWS_Header_Data (data->header_name (), + data->header_value ()); + if (data2 == 0 || data2->header_name () == 0 + || data2->header_value () == 0) + { + this->status_ = STATUS_INTERNAL_SERVER_ERROR; + return -1; + } + this->headers ()->insert (data2); + + iter.advance (); + } + + return 0; +} + +int +HTTP_Base::deliver_header_name (JAWS_Header_Data *&data) +{ + data = 0; + + for (;;) + { + if ((data = this->iter_.next ()) == 0) + { + // No more headers, deliver final "\r\n" + this->mb_->copy ("\r\n", 2); + return 2; + } + + if (data->header_name ()) + break; + + this->iter_.advance (); + } + + // Assume the following lines will always succeed. + this->mb_->copy (data->header_name ()); + this->mb_->wr_ptr (this->mb_->wr_ptr () - 1); + this->mb_->copy (": ", 2); + + return 1; +} + +int +HTTP_Base::deliver_header_value (JAWS_Header_Data *&data) +{ + // Assume the following line will always succeed. + if (data->header_value ()) + { + this->mb_->copy (data->header_value ()); + this->mb_->wr_ptr (this->mb_->wr_ptr () - 1); + } + this->mb_->copy ("\r\n", 2); + + this->iter_.advance (); + return 0; +} + + +int +HTTP_Base::extract_line (ACE_Message_Block &mb) +{ + JAWS_Parse_Headers *parser = JAWS_Parse_Headers_Singleton::instance (); + char *p = parser->skipset ("\n", mb.rd_ptr (), mb.wr_ptr ()); + if (p == mb.wr_ptr ()) + return 0; + + this->status_ = STATUS_OK; + + *p = '\0'; + if (p[-1] == '\r') + p[-1] = '\0'; + + this->line_ = ACE_OS::strdup (mb.rd_ptr ()); + if (this->line_ == 0) + this->status_ = STATUS_INTERNAL_SERVER_ERROR; + + mb.rd_ptr (p+1); + this->info_.end_of_line (1); + return 1; +} + +void +HTTP_Base::dump (void) +{ + ACE_DEBUG ((LM_DEBUG, "%s\n", this->line ())); + this->info_.dump (); + ACE_DEBUG ((LM_DEBUG, "STATUS IS %d %s\n", + this->status (), + (*HTTP_SCode::instance ())[this->status ()])); +} + +#if !defined (ACE_HAS_INLINED_OSCALLS) +# include "HTTPU/http_base.i" +# endif /* ACE_HAS_INLINED_OSCALLS */ diff --git a/ACE/apps/JAWS2/HTTPU/http_base.h b/ACE/apps/JAWS2/HTTPU/http_base.h new file mode 100644 index 00000000000..5f5486f888d --- /dev/null +++ b/ACE/apps/JAWS2/HTTPU/http_base.h @@ -0,0 +1,87 @@ +// $Id$ + +#ifndef HTTPU_HTTP_BASE_H +#define HTTPU_HTTP_BASE_H + +#include "ace/Message_Block.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "JAWS/Parse_Headers.h" +#include "HTTPU/http_export.h" +#include "HTTPU/http_status.h" +#include "HTTPU/http_headers.h" + +class HTTPU_Export HTTP_Base : public HTTP_SCode_Base +{ +public: + + HTTP_Base (void); + virtual ~HTTP_Base (void); + + virtual int receive (ACE_Message_Block &mb); + virtual int deliver (ACE_Message_Block &mb); + + virtual int receive_payload (ACE_Message_Block &mb); + virtual int receive_payload (ACE_Message_Block &mb, long length); + + const char * payload (void); + unsigned long payload_size (void); + + int status (void) const; + const char *line (void) const; + HTTP_Headers *http_headers (void); + JAWS_Headers *headers (void); + + int build_headers (JAWS_Headers *new_headers); + // takes a set of new headers that will replace existing headers or + // be added to the header list if there is no corresponding one to replace. + + void dump (void); + +protected: + + virtual void parse_line (void) = 0; + // Hook into the receive function to do specialized parsing of initial line. + // Sets the status_ variable. + + virtual int espouse_line (void) = 0; + // Hook into the deliver function to do specialized initial line creation. + // Returns 0 for success and -1 for failure. + + int deliver_header_name (JAWS_Header_Data *&data); + // Returns the next deliver state + + int deliver_header_value (JAWS_Header_Data *&data); + // Returns the next deliver state + + virtual int extract_line (ACE_Message_Block &mb); + // The first line of a request or a response. + // Return 0 if more data needed. + // Return 1 if line successfully parsed. + +protected: + + int status_; + char *line_; + int deliver_state_; + int no_headers_; + HTTP_Headers info_; + JAWS_Header_Table_Iterator iter_; + ACE_Message_Block *mb_; + ACE_Message_Block payload_; + +}; + + +#if defined (ACE_HAS_INLINED_OSCALLS) +# if defined (ACE_INLINE) +# undef ACE_INLINE +# endif /* ACE_INLINE */ +# define ACE_INLINE inline +# include "HTTPU/http_base.i" +# endif /* ACE_HAS_INLINED_OSCALLS */ + +#endif /* !defined (HTTPU_HTTP_BASE_H) */ diff --git a/ACE/apps/JAWS2/HTTPU/http_base.i b/ACE/apps/JAWS2/HTTPU/http_base.i new file mode 100644 index 00000000000..3c862c5b5fb --- /dev/null +++ b/ACE/apps/JAWS2/HTTPU/http_base.i @@ -0,0 +1,53 @@ +// -*- c++ -*- +// $Id$ + +#if !defined (ACE_HAS_INLINED_OSCALLS) +# undef ACE_INLINE +# define ACE_INLINE +#endif /* ACE_HAS_INLINED_OSCALLS */ + +ACE_INLINE +HTTP_Base::HTTP_Base (void) + : status_ (200), + line_ (0), + deliver_state_ (0), + no_headers_ (0), + iter_ (*(this->info_.table ())), + mb_ (0) +{ +} + +ACE_INLINE +HTTP_Base::~HTTP_Base (void) +{ + if (this->line_) + ACE_OS::free (this->line_); + if (this->mb_) + delete this->mb_; + this->line_ = 0; + this->mb_ = 0; +} + +ACE_INLINE int +HTTP_Base::status (void) const +{ + return this->status_; +} + +ACE_INLINE const char * +HTTP_Base::line (void) const +{ + return this->line_; +} + +ACE_INLINE HTTP_Headers * +HTTP_Base::http_headers (void) +{ + return &(this->info_); +} + +ACE_INLINE JAWS_Headers * +HTTP_Base::headers (void) +{ + return this->info_.table (); +} diff --git a/ACE/apps/JAWS2/HTTPU/http_export.h b/ACE/apps/JAWS2/HTTPU/http_export.h new file mode 100644 index 00000000000..b0f6848cba2 --- /dev/null +++ b/ACE/apps/JAWS2/HTTPU/http_export.h @@ -0,0 +1,38 @@ +// $Id$ + +// Definition for Win32 Export directives. +// This file is generated automatically by +// ${TAO_ROOT}/TAO_IDL/GenExportH.BAT +// ------------------------------ +#ifndef HTTPU_EXPORT_H +#define HTTPU_EXPORT_H + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (HTTPU_HAS_DLL) +# if (HTTPU_HAS_DLL == 1) +# if defined (HTTPU_BUILD_DLL) +# define HTTPU_Export ACE_Proper_Export_Flag +# define HTTPU_SINGLETON_DECLARATION(T) \ + ACE_EXPORT_SINGLETON_DECLARATION (T) +# else +# define HTTPU_Export ACE_Proper_Import_Flag +# define HTTPU_SINGLETON_DECLARATION(T) \ + ACE_IMPORT_SINGLETON_DECLARATION (T) +# endif /* HTTPU_BUILD_DLL */ +# else +# define HTTPU_Export +# define HTTPU_SINGLETON_DECLARATION(T) +# endif /* ! HTTPU_HAS_DLL == 1 */ +#else +# define HTTPU_Export +# define HTTPU_SINGLETON_DECLARATION(T) +#endif /* HTTPU_HAS_DLL */ + +#endif /* HTTPU_EXPORT_H */ + // End of auto generated file. + diff --git a/ACE/apps/JAWS2/HTTPU/http_headers.cpp b/ACE/apps/JAWS2/HTTPU/http_headers.cpp new file mode 100644 index 00000000000..370835ff294 --- /dev/null +++ b/ACE/apps/JAWS2/HTTPU/http_headers.cpp @@ -0,0 +1,145 @@ +// $Id$ + +#include "ace/RB_Tree.h" +#include "HTTPU/http_headers.h" + +HTTP_Hdr_Node + + HTTP_HCodes::HTTP ("HTTP", "HTTP%s %s"), + HTTP_HCodes::ACCEPT ("Accept", "Accept: %s\r\n"), + HTTP_HCodes::ACCEPTCHARSET ("Accept-Charset", "Accept-Charset: %s\r\n"), + HTTP_HCodes::ACCEPTENCODING ("Accept-Encoding", "Accept-Encoding: %s\r\n"), + HTTP_HCodes::ACCEPTLANGUAGE ("Accept-Language", "Accept-Language: %s\r\n"), + HTTP_HCodes::ACCEPTRANGES ("Accept-Ranges", "Accept-Ranges: %s\r\n"), + HTTP_HCodes::AGE ("Age", "Age: %s\r\n"), + HTTP_HCodes::ALLOW ("Allow", "Allow: %s\r\n"), + HTTP_HCodes::AUTHORIZATION ("Authorization", "Authorization: %s\r\n"), + HTTP_HCodes::CACHECONTROL ("Cache-Control", "Cache-Control: %s\r\n"), + HTTP_HCodes::CONNECTION ("Connection", "Connection: %s\r\n"), + HTTP_HCodes::CONTENTENCODING ("Content-Encoding", + "Content-Encoding: %d\r\n"), + HTTP_HCodes::CONTENTLENGTH ("Content-Length", "Content-Length: %d\r\n"), + HTTP_HCodes::CONTENTLOCATION ("Content-Location", "Content-Location: %s\r\n"), + HTTP_HCodes::CONTENTMD5 ("Content-MD5", "Content-MD5: %s\r\n"), + HTTP_HCodes::CONTENTRANGE ("Content-Range", "Content-Range: %s\r\n"), + HTTP_HCodes::CONTENTTYPE ("Content-Type", "Content-Type: %s\r\n"), + HTTP_HCodes::DATE ("Date", "Date: %s\r\n"), + HTTP_HCodes::ETAG ("ETag", "ETag: %s\r\n"), + HTTP_HCodes::EXPECT ("Expect", "Expect: %s\r\n"), + HTTP_HCodes::EXPIRES ("Expires", "Expires: %s\r\n"), + HTTP_HCodes::FROM ("From", "From: %s\r\n"), + HTTP_HCodes::HOST ("Host", "Host: %s\r\n"), + HTTP_HCodes::IFMATCH ("If-Match", "If-Match: %s\r\n"), + HTTP_HCodes::IFMODIFIEDSINCE ("If-Modified-Since", + "If-Modified-Since: %s\r\n"), + HTTP_HCodes::IFNONEMATCH ("If-None-Match", "If-None-Match: %s\r\n"), + HTTP_HCodes::IFRANGE ("If-Range", "If-Range: %s\r\n"), + HTTP_HCodes::IFUNMODIFIEDSINCE ("If-Unmodified-Since", + "If-Unmodified-Since: %s\r\n"), + HTTP_HCodes::LASTMODIFIED ("Last-Modified", "Last-Modified: %s\r\n"), + HTTP_HCodes::LOCATION ("Location", "Location: %s\r\n"), + HTTP_HCodes::MAXFORWARDS ("Max-Forwards", "Max-Forwards: %s\r\n"), + HTTP_HCodes::PRAGMA ("Pragma", "Pragma: %s\r\n"), + HTTP_HCodes::PROXYAUTHENTICATE ("Proxy-Authenticate", + "Proxy-Authenticate: %s\r\n"), + HTTP_HCodes::PROXYAUTHORIZATION ("Proxy-Authorization", + "Proxy-Authorization: %s\r\n"), + HTTP_HCodes::RANGE ("Range", "Range: %s\r\n"), + HTTP_HCodes::REFERER ("Referer", "Referer: %s\r\n"), + HTTP_HCodes::SERVER ("Server", "Server: %s\r\n"), + HTTP_HCodes::TE ("TE", "TE: %s\r\n"), + HTTP_HCodes::TRAILER ("Trailer", "Trailer: %s\r\n"), + HTTP_HCodes::TRANSFERENCODING ("Transfer-Encoding", + "Transfer-Encoding: %s\r\n"), + HTTP_HCodes::UPGRADE ("Ugrade", "Ugrade: %s\r\n"), + HTTP_HCodes::USERAGENT ("User-Agent", "User-Agent: %s\r\n"), + HTTP_HCodes::VARY ("Vary", "Vary: %s\r\n"), + HTTP_HCodes::VIA ("Via", "Via: %s\r\n"), + HTTP_HCodes::WARNING ("Warning", "Warning: %s\r\n"), + HTTP_HCodes::WWWAUTHENTICATE ("WWW-Authenticate", + "WWW-Authenticate: %s\r\n"), + HTTP_HCodes::GET ("GET", "GET %s HTTP/%s\r\n"), + HTTP_HCodes::HEAD ("HEAD", "HEAD %s HTTP/%s\r\n"), + HTTP_HCodes::POST ("POST", "POST %s HTTP/%s\r\n"), + HTTP_HCodes::PUT ("PUT", "PUT %s HTTP/%s\r\n"), + HTTP_HCodes::QUIT ("QUIT", "QUIT %s HTTP/%s\r\n"), + HTTP_HCodes::DUNNO ("", ""), + HTTP_HCodes::META ("<META", "<META %s>"), + HTTP_HCodes::A ("<A", "<A %s>"), + HTTP_HCodes::SCRIPT ("<SCRIPT", "<SCRIPT %s>"), + HTTP_HCodes::APPLET ("<APPLET", "<APPLET %s>") + + ////////////// + ; + + +const int &HTTP_HCodes::NUM_HEADER_STRINGS + = HTTP_Header_Nodes_Singleton::instance ()->num_header_strings_; + +HTTP_Header_Nodes::HTTP_Header_Nodes (void) + : num_header_strings_ (0) +{ +} + +HTTP_Hdr_Node::HTTP_Hdr_Node (const char *token, const char *format) + : token_ (token), + format_ (format) +{ + HTTP_Header_Nodes *header_nodes + = HTTP_Header_Nodes_Singleton::instance (); + + this->index_ = header_nodes->num_header_strings_; + header_nodes->insert (this->index_, this); + header_nodes->num_header_strings_++; +} + +HTTP_HCodes::HTTP_HCodes (void) + : header_nodes_ (HTTP_Header_Nodes_Singleton::instance ()) +{ +} + +HTTP_Headers::HTTP_Headers (void) +{ +} + +const char * +HTTP_Headers::header (int name) const +{ + return this->header_token (name); +} + +const char * +HTTP_Headers::value (int index) +{ + this->value_reset (); + return this->value_next (index); +} + +const char * +HTTP_Headers::value_next (int index) +{ + const char *hs = 0; + const char *hv = 0; + JAWS_Header_Data *data; + + if (0 <= index && index < NUM_HEADER_STRINGS) + { + hs = this->header (index); + data = this->table ()->find_next (hs); + if (data != 0) + hv = data->header_value (); + } + + return hv; +} + +void +HTTP_Headers::value_reset (void) +{ + this->table ()->iter ().first (); +} + +#if !defined (ACE_HAS_INLINED_OSCALLS) +# include "HTTPU/http_headers.i" +# endif /* ACE_HAS_INLINED_OSCALLS */ + diff --git a/ACE/apps/JAWS2/HTTPU/http_headers.h b/ACE/apps/JAWS2/HTTPU/http_headers.h new file mode 100644 index 00000000000..2bfe04c8437 --- /dev/null +++ b/ACE/apps/JAWS2/HTTPU/http_headers.h @@ -0,0 +1,166 @@ +// $Id$ + +// by James Hu +// Borrowed from HTTP_Headers.*, which appears to be irrelevent now anyway. + +#ifndef HTTPU_HTTP_HEADERS_H +#define HTTPU_HTTP_HEADERS_H + +#include "ace/RB_Tree.h" +#include "ace/Null_Mutex.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Singleton.h" + +#include "JAWS/Parse_Headers.h" +#include "HTTPU/http_export.h" + +class HTTP_Headers; + +class HTTPU_Export HTTP_Hdr_Node +{ + // Constructor should be passed literal strings. + friend class HTTP_HCodes; + +public: + operator const int (void) const; + operator const char * (void) const; + const char * format (void) const; + +private: + HTTP_Hdr_Node (const char *token, const char *format); + +private: + int index_; + const char *token_; + const char *format_; +}; + + +class HTTP_HCodes; + +class HTTPU_Export HTTP_Header_Nodes : public ACE_RB_Tree<int, const HTTP_Hdr_Node *, ACE_Less_Than<int>, ACE_Null_Mutex> +{ + friend class HTTP_HCodes; + friend class HTTP_Hdr_Node; + +public: + HTTP_Header_Nodes (void); + +private: + int num_header_strings_; +}; + +typedef ACE_Singleton<HTTP_Header_Nodes, ACE_SYNCH_MUTEX> + HTTP_Header_Nodes_Singleton; + +class HTTPU_Export HTTP_HCodes +{ +public: + HTTP_HCodes (void); + + enum { + REPLACE_HEADER = 1, // Remove any existing header that matches first + APPEND_HEADER = 2, // Unconditionally append the header + INSERT_HEADER = 4, // Insert header if one does not already exist + APPENDTO_HEADER = 8 // Concatenate data to existing header value + }; + + static HTTP_Hdr_Node HTTP; + static HTTP_Hdr_Node ACCEPT; + static HTTP_Hdr_Node ACCEPTCHARSET; + static HTTP_Hdr_Node ACCEPTENCODING; + static HTTP_Hdr_Node ACCEPTLANGUAGE; + static HTTP_Hdr_Node ACCEPTRANGES; + static HTTP_Hdr_Node AGE; + static HTTP_Hdr_Node ALLOW; + static HTTP_Hdr_Node AUTHORIZATION; + static HTTP_Hdr_Node CACHECONTROL; + static HTTP_Hdr_Node CONNECTION; + static HTTP_Hdr_Node CONTENTENCODING; + static HTTP_Hdr_Node CONTENTLENGTH; + static HTTP_Hdr_Node CONTENTLOCATION; + static HTTP_Hdr_Node CONTENTMD5; + static HTTP_Hdr_Node CONTENTRANGE; + static HTTP_Hdr_Node CONTENTTYPE; + static HTTP_Hdr_Node DATE; + static HTTP_Hdr_Node ETAG; + static HTTP_Hdr_Node EXPECT; + static HTTP_Hdr_Node EXPIRES; + static HTTP_Hdr_Node FROM; + static HTTP_Hdr_Node HOST; + static HTTP_Hdr_Node IFMATCH; + static HTTP_Hdr_Node IFMODIFIEDSINCE; + static HTTP_Hdr_Node IFNONEMATCH; + static HTTP_Hdr_Node IFRANGE; + static HTTP_Hdr_Node IFUNMODIFIEDSINCE; + static HTTP_Hdr_Node LASTMODIFIED; + static HTTP_Hdr_Node LOCATION; + static HTTP_Hdr_Node MAXFORWARDS; + static HTTP_Hdr_Node PRAGMA; + static HTTP_Hdr_Node PROXYAUTHENTICATE; + static HTTP_Hdr_Node PROXYAUTHORIZATION; + static HTTP_Hdr_Node RANGE; + static HTTP_Hdr_Node REFERER; + static HTTP_Hdr_Node RETRYAFTER; + static HTTP_Hdr_Node SERVER; + static HTTP_Hdr_Node TE; + static HTTP_Hdr_Node TRAILER; + static HTTP_Hdr_Node TRANSFERENCODING; + static HTTP_Hdr_Node UPGRADE; + static HTTP_Hdr_Node USERAGENT; + static HTTP_Hdr_Node VARY; + static HTTP_Hdr_Node VIA; + static HTTP_Hdr_Node WARNING; + static HTTP_Hdr_Node WWWAUTHENTICATE; + static HTTP_Hdr_Node GET; + static HTTP_Hdr_Node HEAD; + static HTTP_Hdr_Node POST; + static HTTP_Hdr_Node PUT; + static HTTP_Hdr_Node QUIT; + static HTTP_Hdr_Node DUNNO; + static HTTP_Hdr_Node META; + static HTTP_Hdr_Node A; + static HTTP_Hdr_Node SCRIPT; + static HTTP_Hdr_Node APPLET; + + static const int &NUM_HEADER_STRINGS; + +protected: + + const HTTP_Hdr_Node &hcode (int type) const; + +protected: + + HTTP_Header_Nodes *header_nodes_; +}; + +class HTTPU_Export HTTP_Headers : public JAWS_Header_Info, public HTTP_HCodes +{ +public: + const char *header( int name ) const; + const char *value( int name ); + const char *value_next( int name ); + void value_reset ( void ); + +public: + HTTP_Headers (void); + + const char *header_token (int name) const; + const char *header_strings (int name) const; + +}; + + +#if defined (ACE_HAS_INLINED_OSCALLS) +# if defined (ACE_INLINE) +# undef ACE_INLINE +# endif /* ACE_INLINE */ +# define ACE_INLINE inline +# include "HTTPU/http_headers.i" +# endif /* ACE_HAS_INLINED_OSCALLS */ + +#endif /* !defined (HTTPU_HTTP_HEADERS_HPP) */ diff --git a/ACE/apps/JAWS2/HTTPU/http_headers.i b/ACE/apps/JAWS2/HTTPU/http_headers.i new file mode 100644 index 00000000000..73ea46e57b6 --- /dev/null +++ b/ACE/apps/JAWS2/HTTPU/http_headers.i @@ -0,0 +1,48 @@ +// -*- c++ -*- +// $Id$ + +#if !defined (ACE_HAS_INLINED_OSCALLS) +# undef ACE_INLINE +# define ACE_INLINE +#endif /* ACE_HAS_INLINED_OSCALLS */ + +ACE_INLINE +HTTP_Hdr_Node::operator const int (void) const +{ + return this->index_; +} + +ACE_INLINE +HTTP_Hdr_Node::operator const char * (void) const +{ + return this->token_; +} + +ACE_INLINE const char * +HTTP_Hdr_Node::format (void) const +{ + return this->format_; +} + +ACE_INLINE const HTTP_Hdr_Node & +HTTP_HCodes::hcode (int type) const +{ + const HTTP_Hdr_Node **hn = this->header_nodes_->find (type); + + // No error checking! + return **hn; +} + +ACE_INLINE const char * +HTTP_Headers::header_token (int name) const +{ + const HTTP_Hdr_Node **hn = this->header_nodes_->find (name); + return ((hn && *hn) ? (const char *)**hn : 0); +} + +ACE_INLINE const char * +HTTP_Headers::header_strings (int name) const +{ + const HTTP_Hdr_Node **hn = this->header_nodes_->find (name); + return ((hn && *hn) ? (*hn)->format () : 0); +} diff --git a/ACE/apps/JAWS2/HTTPU/http_request.cpp b/ACE/apps/JAWS2/HTTPU/http_request.cpp new file mode 100644 index 00000000000..ac1c08028e0 --- /dev/null +++ b/ACE/apps/JAWS2/HTTPU/http_request.cpp @@ -0,0 +1,86 @@ +// $Id$ + +#include "HTTPU/http_request.h" +#include "HTTPU/parse_http_request.h" + +void +HTTP_Request::parse_line (void) +{ + this->status_ = STATUS_OK; + + this->request_.init (this->line ()); + if (this->request_.error () != Parse_HTTP_Request::HTTPU_OK) + { + this->status_ = STATUS_INTERNAL_SERVER_ERROR; + return; + } + if (this->request_.major_version () == 0) + { + this->no_headers_ = 1; + return; + } + + this->url_.init (this->request_.url ()); + if (this->url_.error () != 0) + this->status_ = STATUS_INTERNAL_SERVER_ERROR; +} + +int +HTTP_Request::espouse_line (void) +{ + int count; + + if (this->request_.major_version () == 0) + { + count = ACE_OS::sprintf (this->mb_->wr_ptr (), "%s /%s\r\n\r\n", + this->request_.method_str (), + this->url_.url_path ()); + + if (count < 0) + return -1; + + this->mb_->wr_ptr (count); + + return 1; + } + + count = ACE_OS::sprintf (this->mb_->wr_ptr (), "%s /%s %s\r\n", + this->request_.method_str (), + this->url_.url_path (), + this->request_.version ()); + + if (count < 0) + return -1; + + this->mb_->wr_ptr (count); + + if (this->url_.host () != 0) + { + JAWS_Header_Data *hd = this->headers ()->find ("Host"); + if (hd == 0) + { + count = ACE_OS::sprintf (this->mb_->wr_ptr (), "Host: %s\r\n", + this->url_.host ()); + + if (count < 0) + return -1; + + this->mb_->wr_ptr (count); + } + } + + return 0; +} + +void +HTTP_Request::dump (void) +{ + ACE_DEBUG ((LM_DEBUG, "===== BEGIN entera_HTTP_Request::dump =====\n")); + HTTP_Base::dump (); + this->request_.dump (); + ACE_DEBUG ((LM_DEBUG, "===== END entera_HTTP_Request::dump =====\n")); +} + +#if !defined (ACE_HAS_INLINED_OSCALLS) +# include "HTTPU/http_request.i" +# endif /* ACE_HAS_INLINED_OSCALLS */ diff --git a/ACE/apps/JAWS2/HTTPU/http_request.h b/ACE/apps/JAWS2/HTTPU/http_request.h new file mode 100644 index 00000000000..c04d08dabf6 --- /dev/null +++ b/ACE/apps/JAWS2/HTTPU/http_request.h @@ -0,0 +1,59 @@ +// $Id$ + +// There are two kinds of HTTP Requests in a proxy. +// One is the kind you have to read in from the HTTP client. +// The other is the kind you issue to the server. + +#ifndef HTTPU_HTTP_REQUEST_HPP +#define HTTPU_HTTP_REQUEST_HPP + +#include "ace/Message_Block.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "JAWS/Parse_Headers.h" +#include "HTTPU/http_export.h" +#include "HTTPU/http_base.h" +#include "HTTPU/parse_http_request.h" +#include "HTTPU/parse_url.h" + +class HTTPU_Export HTTP_Request : public HTTP_Base +{ +public: + HTTP_Request (void); + virtual ~HTTP_Request (void); + + Parse_HTTP_Request *request_line (void); + // Returns the parsed request line. + + const Parse_HTTP_Request *request_line (void) const; + // Returns the parsed request line. + + HTTP_Parse_URL *url (void); + // Returns the parsed url. + + void dump (void); + +protected: + + virtual void parse_line (void); + virtual int espouse_line (void); + virtual void set_status (int); + +private: + Parse_HTTP_Request request_; + HTTP_Parse_URL url_; +}; + +#if defined (ACE_HAS_INLINED_OSCALLS) +# if defined (ACE_INLINE) +# undef ACE_INLINE +# endif /* ACE_INLINE */ +# define ACE_INLINE inline +# include "HTTPU/http_request.i" +# endif /* ACE_HAS_INLINED_OSCALLS */ + + +#endif /* !defined (HTTPU_HTTP_REQUEST_HPP) */ diff --git a/ACE/apps/JAWS2/HTTPU/http_request.i b/ACE/apps/JAWS2/HTTPU/http_request.i new file mode 100644 index 00000000000..a6adeb98e92 --- /dev/null +++ b/ACE/apps/JAWS2/HTTPU/http_request.i @@ -0,0 +1,41 @@ +// -*- c++ -*- +// $Id$ + +#if !defined (ACE_HAS_INLINED_OSCALLS) +# undef ACE_INLINE +# define ACE_INLINE +#endif /* ACE_HAS_INLINED_OSCALLS */ + +ACE_INLINE +HTTP_Request::HTTP_Request (void) +{ +} + +ACE_INLINE +HTTP_Request::~HTTP_Request (void) +{ +} + +ACE_INLINE Parse_HTTP_Request * +HTTP_Request::request_line (void) +{ + return &(this->request_); +} + +ACE_INLINE const Parse_HTTP_Request * +HTTP_Request::request_line (void) const +{ + return &(this->request_); +} + +ACE_INLINE HTTP_Parse_URL * +HTTP_Request::url (void) +{ + return &(this->url_); +} + +ACE_INLINE void +HTTP_Request::set_status (int s) +{ + this->status_ = s; +} diff --git a/ACE/apps/JAWS2/HTTPU/http_response.cpp b/ACE/apps/JAWS2/HTTPU/http_response.cpp new file mode 100644 index 00000000000..380d0155b0f --- /dev/null +++ b/ACE/apps/JAWS2/HTTPU/http_response.cpp @@ -0,0 +1,49 @@ +// $Id$ + +#include "HTTPU/http_response.h" + +void +HTTP_Response::parse_line (void) +{ + this->response_.init (this->line ()); + if (this->response_.error () != Parse_HTTP_Response::HTTPU_OK) + this->status_ = STATUS_INTERNAL_SERVER_ERROR; +} + +int +HTTP_Response::espouse_line (void) +{ + int count; + int status; + + if (this->status_ != (int)STATUS_OK) + status = this->status_; + else + status = this->response_line ()->code (); + + count = ACE_OS::sprintf (this->mb_->wr_ptr (), "%s %d %s\r\n", + "HTTP/1.1", + status, + (char *)(*HTTP_SCode::instance ())[status]); + // Last arg is hard coded since we are suppose to report the + // level of server we are, and not act like the level of the + // client. This information should be obtained from the config. + + if (count < 0) + return -1; + + this->mb_->wr_ptr (count); + return 0; +} + +void +HTTP_Response::dump (void) +{ + ACE_DEBUG ((LM_DEBUG, "===== BEGIN entera_HTTP_Response::dump =====\n")); + HTTP_Base::dump (); + ACE_DEBUG ((LM_DEBUG, "===== END entera_HTTP_Response::dump =====\n")); +} + +#if !defined (ACE_HAS_INLINED_OSCALLS) +# include "HTTPU/http_response.i" +# endif /* ACE_HAS_INLINED_OSCALLS */ diff --git a/ACE/apps/JAWS2/HTTPU/http_response.h b/ACE/apps/JAWS2/HTTPU/http_response.h new file mode 100644 index 00000000000..71b6cae2fae --- /dev/null +++ b/ACE/apps/JAWS2/HTTPU/http_response.h @@ -0,0 +1,51 @@ +// $Id$ + +// There are two kinds of HTTP Responses in a proxy. +// One is the kind you have to read in from the HTTP server. +// The other is the kind you issue to the HTTP client. + +#ifndef HTTPU_HTTP_RESPONSE_HPP +#define HTTPU_HTTP_RESPONSE_HPP + +#include "ace/Message_Block.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "JAWS/Parse_Headers.h" + +#include "HTTPU/http_export.h" +#include "HTTPU/http_base.h" +#include "HTTPU/parse_http_response.h" + +class HTTPU_Export HTTP_Response : public HTTP_Base +{ +public: + HTTP_Response (void); + ~HTTP_Response (void); + + Parse_HTTP_Response *response_line (void); + // Returns the parsed response line. + + void dump (void); + +protected: + + virtual void parse_line (void); + virtual int espouse_line (void); + +private: + Parse_HTTP_Response response_; +}; + +#if defined (ACE_HAS_INLINED_OSCALLS) +# if defined (ACE_INLINE) +# undef ACE_INLINE +# endif /* ACE_INLINE */ +# define ACE_INLINE inline +# include "HTTPU/http_response.i" +# endif /* ACE_HAS_INLINED_OSCALLS */ + + +#endif /* !defined (HTTPU_HTTP_RESPONSE_HPP) */ diff --git a/ACE/apps/JAWS2/HTTPU/http_response.i b/ACE/apps/JAWS2/HTTPU/http_response.i new file mode 100644 index 00000000000..9f4eb0d244f --- /dev/null +++ b/ACE/apps/JAWS2/HTTPU/http_response.i @@ -0,0 +1,23 @@ +// -*- c++ -*- +// $Id$ + +#if !defined (ACE_HAS_INLINED_OSCALLS) +# undef ACE_INLINE +# define ACE_INLINE +#endif /* ACE_HAS_INLINED_OSCALLS */ + +ACE_INLINE +HTTP_Response::HTTP_Response (void) +{ +} + +ACE_INLINE +HTTP_Response::~HTTP_Response (void) +{ +} + +ACE_INLINE Parse_HTTP_Response * +HTTP_Response::response_line (void) +{ + return &(this->response_); +} diff --git a/ACE/apps/JAWS2/HTTPU/http_status.cpp b/ACE/apps/JAWS2/HTTPU/http_status.cpp new file mode 100644 index 00000000000..5abc2313fec --- /dev/null +++ b/ACE/apps/JAWS2/HTTPU/http_status.cpp @@ -0,0 +1,81 @@ +// $Id$ + +#include "HTTPU/http_status.h" + +const char * +HTTP_SCode::table_ [HTTP_SCode::SC_TABLE_SIZE]; + +HTTP_SCode_Node + + HTTP_SCode_Base::STATUS_OK (200, "OK"), + HTTP_SCode_Base::STATUS_CREATED (201, "Created"), + HTTP_SCode_Base::STATUS_ACCEPTED (202, "Accepted"), + HTTP_SCode_Base::STATUS_NO_CONTENT (204, "No Content"), + HTTP_SCode_Base::STATUS_MULTIPLE_CHOICES (300, "Multiple Choices"), + HTTP_SCode_Base::STATUS_MOVED_PERMANENTLY (301, "Moved Permanently"), + HTTP_SCode_Base::STATUS_MOVED_TEMPORARILY (302, "Moved Temporarily"), + HTTP_SCode_Base::STATUS_NOT_MODIFIED (304, "Not Modified"), + HTTP_SCode_Base::STATUS_INSUFFICIENT_DATA (399, "Insufficient Data"), + HTTP_SCode_Base::STATUS_BAD_REQUEST (400, "Bad Request"), + HTTP_SCode_Base::STATUS_UNAUTHORIZED (401, "Unauthorized"), + HTTP_SCode_Base::STATUS_FORBIDDEN (403, "Forbidden"), + HTTP_SCode_Base::STATUS_NOT_FOUND (404, "Not Found"), + HTTP_SCode_Base::STATUS_INTERNAL_SERVER_ERROR (500, "Internal Server Error"), + HTTP_SCode_Base::STATUS_NOT_IMPLEMENTED (501, "Not Implemented"), + HTTP_SCode_Base::STATUS_BAD_GATEWAY (502, "Bad Gateway"), + HTTP_SCode_Base::STATUS_SERVICE_UNAVAILABLE (503, "Service Unavailable"), + HTTP_SCode_Base::STATUS_QUIT (599, "Quit"), + + HTTP_SCode_Base::DUMMY (0, 0); + +HTTP_SCode_Node::HTTP_SCode_Node (int code, const char *code_str) + : code_ (code), + code_str_ (code_str) +{ + if ((HTTP_SCode::MIN_STATUS_CODE <= code) + && (code <= HTTP_SCode::MAX_STATUS_CODE)) + HTTP_SCode::table_[code - HTTP_SCode::MIN_STATUS_CODE] = code_str; +} + +const char * +HTTP_SCode::operator[] (int i) const +{ + const char *s = "Unknown"; + + if (MIN_STATUS_CODE <= i && i <= MAX_STATUS_CODE) + s = this->table_[i - MIN_STATUS_CODE]; + + return s; +} + +HTTP_SCode * +HTTP_SCode::instance (void) +{ + return HTTP_SCode_Singleton::instance (); +} + +void +HTTP_SCode::dump (void) +{ + for (int i = 0; i < SC_TABLE_SIZE; i++) + ACE_DEBUG ((LM_DEBUG, "%s\n", this->table_[i])); +} + +HTTP_SCode::HTTP_SCode (void) +{ + int i; + for (i = 0; i < SC_TABLE_SIZE; i++) + { + if (this->table_[i] == 0) + this->table_[i] = this->table_[(i/100) * 100]; + } +} + +HTTP_SCode::~HTTP_SCode (void) +{ +} + +#if !defined (ACE_HAS_INLINED_OSCALLS) +# include "HTTPU/http_status.i" +# endif /* ACE_HAS_INLINED_OSCALLS */ + diff --git a/ACE/apps/JAWS2/HTTPU/http_status.h b/ACE/apps/JAWS2/HTTPU/http_status.h new file mode 100644 index 00000000000..3a4567c0a1c --- /dev/null +++ b/ACE/apps/JAWS2/HTTPU/http_status.h @@ -0,0 +1,110 @@ +// $Id$ + +#ifndef HTTPU_HTTP_STATUS_HPP +#define HTTPU_HTTP_STATUS_HPP + +#include "ace/Singleton.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "HTTPU/http_export.h" +#include "ace/Synch_Traits.h" + +class HTTP_SCode_Base; + +class HTTPU_Export HTTP_SCode_Node +// Constructor should be passed a string literal. +{ + friend class HTTP_SCode_Base; + +public: + operator int (void) const; + operator const char * (void) const; + +private: + HTTP_SCode_Node (int code, const char *code_str); + +private: + int code_; + const char *code_str_; +}; + +class HTTPU_Export HTTP_SCode_Base +{ +public: + static HTTP_SCode_Node STATUS_OK; + static HTTP_SCode_Node STATUS_CREATED; + static HTTP_SCode_Node STATUS_ACCEPTED; + static HTTP_SCode_Node STATUS_NO_CONTENT; + static HTTP_SCode_Node STATUS_MULTIPLE_CHOICES; + static HTTP_SCode_Node STATUS_MOVED_PERMANENTLY; + static HTTP_SCode_Node STATUS_MOVED_TEMPORARILY; + static HTTP_SCode_Node STATUS_NOT_MODIFIED; + static HTTP_SCode_Node STATUS_INSUFFICIENT_DATA; + static HTTP_SCode_Node STATUS_BAD_REQUEST; + static HTTP_SCode_Node STATUS_UNAUTHORIZED; + static HTTP_SCode_Node STATUS_FORBIDDEN; + static HTTP_SCode_Node STATUS_NOT_FOUND; + static HTTP_SCode_Node STATUS_INTERNAL_SERVER_ERROR; + static HTTP_SCode_Node STATUS_NOT_IMPLEMENTED; + static HTTP_SCode_Node STATUS_BAD_GATEWAY; + static HTTP_SCode_Node STATUS_SERVICE_UNAVAILABLE; + static HTTP_SCode_Node STATUS_QUIT; + + enum + { + MIN_STATUS_CODE = 200, + MAX_STATUS_CODE = 599 + }; + +private: + static HTTP_SCode_Node DUMMY; +}; + +class HTTPU_Export HTTP_SCode : public HTTP_SCode_Base +{ + // = TITLE + // Go from numeric status codes to descriptive strings. + // + friend class HTTP_SCode_Node; + friend class ACE_Singleton<HTTP_SCode, ACE_SYNCH_MUTEX>; + +protected: + + HTTP_SCode (void); + ~HTTP_SCode (void); + +public: + + const char * operator[] (int) const; + // Return the reason string corresponding to a status code number. + + static HTTP_SCode *instance (void); + // Return reference to the singleton. + + enum + { + SC_TABLE_SIZE = MAX_STATUS_CODE - MIN_STATUS_CODE + 1 + }; + + void dump (void); + +private: + static const char *table_[SC_TABLE_SIZE]; +}; + + +typedef ACE_Singleton<HTTP_SCode, ACE_SYNCH_MUTEX> + HTTP_SCode_Singleton; + +#if defined (ACE_HAS_INLINED_OSCALLS) +# if defined (ACE_INLINE) +# undef ACE_INLINE +# endif /* ACE_INLINE */ +# define ACE_INLINE inline +# include "HTTPU/http_status.i" +# endif /* ACE_HAS_INLINED_OSCALLS */ + +#endif /* HTTPU_HTTP_STATUS_HPP */ diff --git a/ACE/apps/JAWS2/HTTPU/http_status.i b/ACE/apps/JAWS2/HTTPU/http_status.i new file mode 100644 index 00000000000..0247ddeb738 --- /dev/null +++ b/ACE/apps/JAWS2/HTTPU/http_status.i @@ -0,0 +1,19 @@ +// -*- c++ -*- +// $Id$ + +#if !defined (ACE_HAS_INLINED_OSCALLS) +# undef ACE_INLINE +# define ACE_INLINE +#endif /* ACE_HAS_INLINED_OSCALLS */ + +ACE_INLINE +HTTP_SCode_Node::operator int (void) const +{ + return this->code_; +} + +ACE_INLINE +HTTP_SCode_Node::operator const char * (void) const +{ + return this->code_str_; +} diff --git a/ACE/apps/JAWS2/HTTPU/parse_http_request.cpp b/ACE/apps/JAWS2/HTTPU/parse_http_request.cpp new file mode 100644 index 00000000000..07146a095ac --- /dev/null +++ b/ACE/apps/JAWS2/HTTPU/parse_http_request.cpp @@ -0,0 +1,116 @@ +// $Id$ + +#include "HTTPU/parse_http_request.h" + +Parse_HTTP_Request::Parse_HTTP_Request (const char *request) + : method_ (0), + major_version_ (-1), + minor_version_ (-1), + version_ (0), + url_ (0), + request_ (0), + error_ (0) +{ + if (request != 0) + this->init (request); +} + +Parse_HTTP_Request::~Parse_HTTP_Request (void) +{ + if (this->request_) + ACE_OS::free (this->request_); + this->request_ = 0; + this->version_ = 0; + this->url_ = 0; +} + +void +Parse_HTTP_Request::dump (void) +{ + ACE_DEBUG ((LM_DEBUG, "%s %s %s\n", + this->method_str (), this->url (), this->version ())); +} + +void +Parse_HTTP_Request::init (const char *request) +{ + char *method; + + this->request_ = ACE_OS::strdup (request); + if (this->request_ == 0) + { + this->error_ = NO_MEMORY; + return; + } + + char buf[BUFSIZ]; + int n = ::sscanf (this->request_, "%s %*s HTTP/%d.%d", + buf, + &(this->major_version_), + &(this->minor_version_)); + + if (n == 1 || n == 3) + { + char *p = this->request_; + + while (*p == ' ' || *p == '\t') + p++; + + method = p++; + + while (*p != ' ' && *p != '\t') + p++; + + *p++ = '\0'; + + while (*p == ' ' || *p == '\t') + p++; + + this->url_ = p; + + while (*p && !ACE_OS::strchr (" \t\r\n", *p)) + p++; + + *p++ = '\0'; + + if (n == 1) + { + this->major_version_ = 0; + this->minor_version_ = 9; + } + else + { + while (*p == ' ' || *p == '\t') + p++; + + this->version_ = p; + + while (*p && !ACE_OS::strchr (" \t\r\n", *p)) + p++; + + *p++ = '\0'; + } + + if (ACE_OS::strcmp (method, "GET") == 0) + this->method_ = &GET; + else if (ACE_OS::strcmp (method, "HEAD") == 0) + this->method_ = &HEAD; + else if (ACE_OS::strcmp (method, "POST") == 0) + this->method_ = &POST; + else if (ACE_OS::strcmp (method, "PUT") == 0) + this->method_ = &PUT; + else if (ACE_OS::strcmp (method, "QUIT") == 0) + this->method_ = &QUIT; + else + { + this->method_ = &DUNNO; + this->error_ = NOT_IMPLEMENTED; + } + } + else + this->error_ = BAD_REQUEST; +} + +#if !defined (ACE_HAS_INLINED_OSCALLS) +# include "HTTPU/parse_http_request.i" +#endif /* ACE_HAS_INLINED_OSCALLS */ diff --git a/ACE/apps/JAWS2/HTTPU/parse_http_request.h b/ACE/apps/JAWS2/HTTPU/parse_http_request.h new file mode 100644 index 00000000000..43c2f954790 --- /dev/null +++ b/ACE/apps/JAWS2/HTTPU/parse_http_request.h @@ -0,0 +1,59 @@ +// $Id$ + +#ifndef HTTPU_PARSE_HTTP_REQUEST_H +#define HTTPU_PARSE_HTTP_REQUEST_H + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "HTTPU/http_headers.h" + +class HTTPU_Export Parse_HTTP_Request : public HTTP_HCodes +{ +public: + Parse_HTTP_Request (const char *request = 0); + ~Parse_HTTP_Request (void); + + void init (const char *request); + + int method (void) const; + const char *method_str (void) const; + + int major_version (void) const; + int minor_version (void) const; + + const char *version (void) const; + + const char *url (void) const; + + enum { HTTPU_OK, NO_MEMORY, BAD_REQUEST, NOT_IMPLEMENTED }; + + int error (void) const; + // 0 -> ok + + void dump (void); + +private: + + HTTP_Hdr_Node *method_; + int major_version_; + int minor_version_; + char *version_; + char *url_; + char *request_; + int error_; + +}; + +#if defined (ACE_HAS_INLINED_OSCALLS) +# if defined (ACE_INLINE) +# undef ACE_INLINE +# endif /* ACE_INLINE */ +# define ACE_INLINE inline +# include "HTTPU/parse_http_request.i" +# endif /* ACE_HAS_INLINED_OSCALLS */ + +#endif /* !defined (HTTPU_PARSE_HTTP_REQUEST_H) */ diff --git a/ACE/apps/JAWS2/HTTPU/parse_http_request.i b/ACE/apps/JAWS2/HTTPU/parse_http_request.i new file mode 100644 index 00000000000..3ef87d48479 --- /dev/null +++ b/ACE/apps/JAWS2/HTTPU/parse_http_request.i @@ -0,0 +1,49 @@ +// -*- c++ -*- +// $Id$ + +#if !defined (ACE_HAS_INLINED_OSCALLS) +# undef ACE_INLINE +# define ACE_INLINE +#endif /* ACE_HAS_INLINED_OSCALLS */ + +ACE_INLINE int +Parse_HTTP_Request::method (void) const +{ + return (int) *this->method_; +} + +ACE_INLINE const char * +Parse_HTTP_Request::method_str (void) const +{ + return (const char *) *this->method_; +} + +ACE_INLINE int +Parse_HTTP_Request::major_version (void) const +{ + return this->major_version_; +} + +ACE_INLINE int +Parse_HTTP_Request::minor_version (void) const +{ + return this->minor_version_; +} + +ACE_INLINE const char * +Parse_HTTP_Request::version (void) const +{ + return this->version_ ? this->version_ : "HTTP/0.9"; +} + +ACE_INLINE const char * +Parse_HTTP_Request::url (void) const +{ + return this->url_; +} + +ACE_INLINE int +Parse_HTTP_Request::error (void) const +{ + return this->error_; +} diff --git a/ACE/apps/JAWS2/HTTPU/parse_http_response.cpp b/ACE/apps/JAWS2/HTTPU/parse_http_response.cpp new file mode 100644 index 00000000000..ce7530bf694 --- /dev/null +++ b/ACE/apps/JAWS2/HTTPU/parse_http_response.cpp @@ -0,0 +1,74 @@ +// $Id$ + +#include "HTTPU/parse_http_response.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_stdlib.h" + +Parse_HTTP_Response::Parse_HTTP_Response (const char *response) + : code_ (200), + code_str_ (0), + major_version_ (0), + minor_version_ (9), + version_ (0), + response_ (0), + error_ (0) +{ + if (response != 0) + this->init (response); +} + +Parse_HTTP_Response::~Parse_HTTP_Response (void) +{ + if (this->response_) + ACE_OS::free (this->response_); + this->response_ = 0; + this->code_str_ = 0; + this->version_ = 0; +} + +void +Parse_HTTP_Response::init (const char *response) +{ + this->response_ = ACE_OS::strdup (response); + if (this->response_ == 0) + { + this->error_ = NO_MEMORY; + return; + } + + int n = ::sscanf (this->response_, "HTTP/%d.%d %d %*s", + &(this->major_version_), + &(this->minor_version_), + &(this->code_)); + + if (n == 3) + { + char *p = this->response_; + + while (*p == ' ' || *p == '\t') + p++; + + this->version_ = p++; + + while (*p != ' ' && *p != '\t') + p++; + + *p++ = '\0'; + + while (*p == ' ' || *p == '\t') + p++; + + this->code_str_ = p; + + while (*p && !ACE_OS::strchr (" \t\r\n", *p)) + p++; + + *p++ = '\0'; + } + else + this->error_ = BAD_RESPONSE; +} + +#if !defined (ACE_HAS_INLINED_OSCALLS) +# include "HTTPU/parse_http_response.i" +#endif /* ACE_HAS_INLINED_OSCALLS */ diff --git a/ACE/apps/JAWS2/HTTPU/parse_http_response.h b/ACE/apps/JAWS2/HTTPU/parse_http_response.h new file mode 100644 index 00000000000..58f126f654a --- /dev/null +++ b/ACE/apps/JAWS2/HTTPU/parse_http_response.h @@ -0,0 +1,56 @@ +// $Id$ + +#ifndef HTTPU_PARSE_HTTP_RESPONSE_H +#define HTTPU_PARSE_HTTP_RESPONSE_H + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "HTTPU/http_export.h" + +class HTTPU_Export Parse_HTTP_Response +{ +public: + Parse_HTTP_Response (const char *response = 0); + ~Parse_HTTP_Response (void); + + void init (const char *response); + + int code (void) const; + const char *code_str (void) const; + + int major_version (void) const; + int minor_version (void) const; + + const char *version (void) const; + + enum { HTTPU_OK, NO_MEMORY, BAD_RESPONSE }; + + int error (void) const; + // 0 -> ok + +private: + + int code_; + char *code_str_; + int major_version_; + int minor_version_; + char *version_; + char *response_; + int error_; + +}; + +#if defined (ACE_HAS_INLINED_OSCALLS) +# if defined (ACE_INLINE) +# undef ACE_INLINE +# endif /* ACE_INLINE */ +# define ACE_INLINE inline +# include "HTTPU/parse_http_response.i" +# endif /* ACE_HAS_INLINED_OSCALLS */ + + +#endif /* !defined (HTTPU_PARSE_HTTP_RESPONSE_H) */ diff --git a/ACE/apps/JAWS2/HTTPU/parse_http_response.i b/ACE/apps/JAWS2/HTTPU/parse_http_response.i new file mode 100644 index 00000000000..57a694377e5 --- /dev/null +++ b/ACE/apps/JAWS2/HTTPU/parse_http_response.i @@ -0,0 +1,43 @@ +// -*- c++ -*- +// $Id$ + +#if !defined (ACE_HAS_INLINED_OSCALLS) +# undef ACE_INLINE +# define ACE_INLINE +#endif /* ACE_HAS_INLINED_OSCALLS */ + +ACE_INLINE int +Parse_HTTP_Response::code (void) const +{ + return this->code_; +} + +ACE_INLINE const char * +Parse_HTTP_Response::code_str (void) const +{ + return this->code_str_ ? this->code_str_ : "200"; +} + +ACE_INLINE int +Parse_HTTP_Response::major_version (void) const +{ + return this->major_version_; +} + +ACE_INLINE int +Parse_HTTP_Response::minor_version (void) const +{ + return this->minor_version_; +} + +ACE_INLINE const char * +Parse_HTTP_Response::version (void) const +{ + return this->version_ ? this->version_ : "HTTP/0.9"; +} + +ACE_INLINE int +Parse_HTTP_Response::error (void) const +{ + return this->error_; +} diff --git a/ACE/apps/JAWS2/HTTPU/parse_url.cpp b/ACE/apps/JAWS2/HTTPU/parse_url.cpp new file mode 100644 index 00000000000..c1c753d0784 --- /dev/null +++ b/ACE/apps/JAWS2/HTTPU/parse_url.cpp @@ -0,0 +1,322 @@ +// $Id$ + +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_stdlib.h" +#include "ace/Log_Msg.h" +#include "HTTPU/parse_url.h" + +HTTP_Parse_URL::HTTP_Parse_URL (const char *url) + : url_ (0), + scheme_ (0), + user_ (0), + passwd_ (0), + host_ (0), + port_ (-1), + url_path_ (0), + error_ (NONE), + is_cgi_ (0) +{ + this->init (url); +} + +HTTP_Parse_URL::~HTTP_Parse_URL (void) +{ + if (this->url_) + ACE_OS::free (this->url_); + this->url_ = 0; + this->scheme_ = 0; + this->user_ = 0; + this->passwd_ = 0; + this->host_ = 0; + this->port_ = -1; + this->url_path_ = 0; +} + + +void +HTTP_Parse_URL::init( const char *url ) +{ + // Should really reset completely and cleanly here before + // doing anything else! + if ( url == 0 ) + return; + + if ( url_ ) + ACE_OS::free( url_ ); + + url_ = ACE_OS::strdup( url ); + if ( url_ == 0 ) + { + error_ = STRDUP; + return; + } + + if (ACE_OS::strlen (this->url_) > 3 && ACE_OS::strstr ("://", this->url_)) + { + // Parse it out completely. Figure out what it is later. + parse_url(); + } + else + { + this->url_path_ = this->url_; + this->is_cgi (this->url_path_); + } +} + + +void +HTTP_Parse_URL::parse_url (void) +{ + char *p = this->url_; + + char *q; + if ((q = ACE_OS::strchr (this->url_, '\r')) + || (q = ACE_OS::strchr (this->url_, '\n'))) + *q = '\0'; + + this->parse_scheme (p); + if (*p == '\0') + { + this->error_ = SCHEME; + return; + } + + // Parse past "//" + if (*p != '/' || *(p+1) != '/') + { + this->error_ = SLASHSLASH; + return; + } + p += 2; + + this->parse_host (p); + + while (*p == '/') + p++; + + if (*p == '\0') + return; + + this->url_path_ = p; + this->is_cgi (this->url_path_); +} + +void +HTTP_Parse_URL::parse_scheme (char *&p) +{ + // Parse the scheme. The scheme is delimited by a ':'. + if (*p != '\0') + { + this->scheme_ = p++; + for (;;) + { + switch (*p) + { + case '\0': + break; + case ':': + *p++ = '\0'; + break; + default: + p++; + continue; + } + break; + } + } +} + +void +HTTP_Parse_URL::parse_host (char *&p) +{ + // Parse user, password, host, port + if (*p == '/' || *p == '\0') + { + this->set_port_from_scheme (); + return; + } + + char *at = 0; + char *colon1 = 0; + char *colon2 = 0; + char *q = p; + while (*q != '\0') + { + if (*q == '/') + { + *q = '\0'; + q++; + break; + } + if (*q == ':') + { + if (colon1 == 0) + { + if (at != 0 && colon2 == 0) + colon2 = q; + else + colon1 = q; + } + else + { + if (at != 0 && colon2 == 0) + colon2 = q; + } + } + if (*q == '@') + { + if (at == 0) + at = q; + } + q++; + } + + // no user, no port + if (at == 0 && colon1 == 0) + { + if (*p != '\0' && *p != '/') + this->host_ = p; + } + + // no user, port + else if (at == 0 && colon1 != 0) + { + if (p != colon1) + this->host_ = p; + *colon1++ = '\0'; + this->port_ = ACE_OS::atoi (colon1); + } + + // user, no passwd, no port + else if (at != 0 && colon1 == 0 && colon2 == 0) + { + this->user_ = p; + *at++ = '\0'; + if (*at != '\0' && *at != '/') + this->host_ = at; + } + + // user, no passwd, port + else if (at != 0 && colon1 == 0 && colon2 != 0) + { + this->user_ = p; + *at++ = '\0'; + if (at != colon2) + this->host_ = at; + *colon2++ = '\0'; + this->port_ = ACE_OS::atoi (colon2); + } + + // user, passwd, no port + else if (at != 0 && colon1 != 0 && colon2 == 0) + { + this->user_ = p; + *colon1++ = '\0'; + this->passwd_ = colon1; + *at++ = '\0'; + if (*at != '\0') + this->host_ = at; + } + + // user, passwd, and port + else if (at != 0 && colon1 != 0 && colon2 != 0) + { + this->user_ = p; + *colon1++ = '\0'; + this->passwd_ = colon1; + *at++ = '\0'; + if (at != colon2) + this->host_ = at; + *colon2++ = '\0'; + this->port_ = ACE_OS::atoi (colon2); + } + + // impossible! + else + { + ACE_ERROR ((LM_ERROR, "uh oh!\n")); + p = q; + return; + } + + this->set_port_from_scheme (); + p = q; +} + +void +HTTP_Parse_URL::set_port_from_scheme (void) +{ + if (ACE_OS::strcmp (this->scheme_, "ftp") == 0) + { + if (this->port_ == -1) + this->port_ = 21; + if (this->user_ == 0) + { + this->user_ = "anonymous"; + + // *** need something better here + this->passwd_ = "a@b.c"; + } + } + else if (ACE_OS::strcmp (this->scheme_, "http") == 0) + { + if (this->port_ == -1) + this->port_ = 80; + } +} + +const char * +HTTP_Parse_URL::scheme (void) const +{ + return this->scheme_; +} + +const char * +HTTP_Parse_URL::user (void) const +{ + return this->user_; +} + +const char * +HTTP_Parse_URL::passwd (void) const +{ + return this->passwd_; +} + +const char * +HTTP_Parse_URL::host (void) const +{ + return this->host_; +} + +int +HTTP_Parse_URL::port (void) const +{ + return this->port_; +} + +const char * +HTTP_Parse_URL::url_path (void) const +{ + return this->url_path_ ? this->url_path_ : ""; +} + +void +HTTP_Parse_URL::is_cgi (const char *path) +{ + int yes; + + yes = (ACE_OS::strchr (path, '?') != 0); + if (!yes && (ACE_OS::strlen (path) >= 3)) + yes = (ACE_OS::strstr (path, "cgi") != 0); + if (!yes) + yes = (ACE_OS::strstr (path, "asp") != 0); + + this->is_cgi_ = yes; +} + +int +HTTP_Parse_URL::is_cgi (void) const +{ + return this->is_cgi_; +} diff --git a/ACE/apps/JAWS2/HTTPU/parse_url.h b/ACE/apps/JAWS2/HTTPU/parse_url.h new file mode 100644 index 00000000000..64260edd2a8 --- /dev/null +++ b/ACE/apps/JAWS2/HTTPU/parse_url.h @@ -0,0 +1,63 @@ +/* -*- c++ -*- */ +// $Id$ + +#ifndef HTTPU_HTTP_PARSE_H +#define HTTPU_HTTP_PARSE_H + +#include "HTTPU/http_export.h" + +class HTTPU_Export HTTP_Parse_URL +{ + // CAVEAT: + + // The user of the class is responsible for testing the difference + // between a missing username versus an empty one. Same goes for + // password The RFC (1738) makes the differentiation for username + // and password. If the hostname is missing (or empty), this class + // always returns a null value for the host. + +public: + HTTP_Parse_URL (const char *url = 0); + ~HTTP_Parse_URL (void); + + void init (const char *url); + + enum URL_SCHEME { HTTP, FTP }; + + const char *scheme (void) const; + const char *user (void) const; + const char *passwd (void) const; + const char *host (void) const; + int port (void) const; + const char *url_path (void) const; + + enum URL_ERROR { NONE, STRDUP, SCHEME, SLASHSLASH }; + + int error (void) const { return( error_ ); } + + int is_cgi (void) const; + +private: + void parse_url (void); + void parse_scheme (char *&p); + void parse_host (char *&p); + void parse_url_path (char *&p); + void is_cgi (const char *path); + + void set_port_from_scheme (void); + +private: + char *url_; + + char *scheme_; + char *user_; + char *passwd_; + char *host_; + int port_; + char *url_path_; + + int error_; + int is_cgi_; +}; + +#endif /* !defined (HTTPU_HTTP_PARSE_H) */ |