• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

src/web/HttpRequestBody.cpp

00001 /*
00002  *   This file is part of the Standard Portable Library (SPL).
00003  *
00004  *   SPL is free software: you can redistribute it and/or modify
00005  *   it under the terms of the GNU General Public License as published by
00006  *   the Free Software Foundation, either version 3 of the License, or
00007  *   (at your option) any later version.
00008  *
00009  *   SPL is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details.
00013  *
00014  *   You should have received a copy of the GNU General Public License
00015  *   along with SPL.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 #include <spl/web/HttpRequestBody.h>
00018 #include <spl/web/HttpUtility.h>
00019 #include <spl/io/Stream.h>
00020 #include <spl/io/MemoryStream.h>
00021 
00022 
00023 IHttpRequestBody::~IHttpRequestBody()
00024 {
00025 }
00026 
00027 HttpRequestBodyGeneric::HttpRequestBodyGeneric()
00028 : m_buf()
00029 {
00030 }
00031 
00032 HttpRequestBodyGeneric::HttpRequestBodyGeneric(const HttpRequestBodyGeneric& b)
00033 : m_buf( b.m_buf )
00034 {
00035 }
00036 
00037 HttpRequestBodyGeneric::~HttpRequestBodyGeneric()
00038 {
00039 }
00040 
00041 int HttpRequestBodyGeneric::ByteCount() const
00042 {
00043         return m_buf.Length();
00044 }
00045 
00046 IHttpRequestBody *HttpRequestBodyGeneric::Clone() const
00047 {
00048         return new HttpRequestBodyGeneric(*this);
00049 }
00050 
00051 void HttpRequestBodyGeneric::Parse( const Array<byte>& cp, int pos, int len, int contentLen )
00052 {
00053         m_buf.Append( &((const char *)cp.Data())[pos], len );
00054 }
00055 
00056 void HttpRequestBodyGeneric::Write( TextWriter& strm ) const
00057 {
00058         strm.Write( m_buf.GetChars() );
00059 }
00060 
00061 StringPtr HttpRequestBodyGeneric::ToString() const
00062 {
00063         return m_buf.ToString();
00064 }
00065 
00066 #ifdef DEBUG
00067 void HttpRequestBodyGeneric::ValidateMem() const
00068 {
00069         m_buf.ValidateMem();
00070 }
00071 
00072 void HttpRequestBodyGeneric::CheckMem() const
00073 {
00074         m_buf.CheckMem();
00075 }
00076 #endif
00077 
00078 HttpRequestBodyFormData::HttpRequestBodyFormData()
00079 : m_data(), m_byteCount(0), m_state(HTTPBODY_STATE_NAME), m_accum()
00080 {
00081 }
00082 
00083 HttpRequestBodyFormData::HttpRequestBodyFormData(const HttpRequestBodyFormData& body)
00084 : m_data(body.m_data), m_byteCount(body.m_byteCount), m_state(body.m_state), m_accum(body.m_accum)
00085 {
00086 }
00087 
00088 HttpRequestBodyFormData::~HttpRequestBodyFormData()
00089 {
00090 }
00091 
00092 HttpRequestBodyFormData& HttpRequestBodyFormData::operator =(const HttpRequestBodyFormData& body)
00093 {
00094         m_data = body.m_data;
00095         m_byteCount = body.m_byteCount;
00096         m_state = body.m_state;
00097         m_accum = body.m_accum;
00098 
00099         return *this;
00100 }
00101 
00102 IHttpRequestBody *HttpRequestBodyFormData::Clone() const
00103 {
00104         return new HttpRequestBodyFormData(*this);
00105 }
00106 
00107 void HttpRequestBodyFormData::Parse( const Array<byte>& cp, int pos, int len, int contentLen )
00108 {
00109         m_byteCount += len;
00110 
00111         for ( int x = 0; x < len; x++ )
00112         {
00113                 char ch = cp[x+pos];
00114 
00115                 switch ( m_state )
00116                 {
00117                 case HTTPBODY_STATE_NAME:
00118                         if ( ch == '&' || ch == '\0' )
00119                         {
00120                                 StringPtr key = m_accum.ToString();
00121                                 m_data.Add( Association<String, String>(*key, String("")) );
00122                                 m_accum.SetLength(0);
00123                                 m_state = HTTPBODY_STATE_VAL;
00124                                 break;
00125                         }
00126 
00127                         m_accum.Append( ch );
00128                         break;
00129 
00130                 case HTTPBODY_STATE_VAL:
00131                         if ( ch == '&' || ch == '\0' )
00132                         {
00133                                 m_data.ElementAtRef( m_data.Count() - 1 ).ValueRef() = *m_accum.ToString();
00134                                 m_accum.SetLength(0);
00135                                 m_state = HTTPBODY_STATE_NAME;
00136                                 break;
00137                         }
00138 
00139                         m_accum.Append( ch );
00140                         break;
00141 
00142                 default:
00143                         throw new Exception("HttpRequestBody::Parse: state corrupted");
00144                 }
00145         }
00146 
00147         if ( m_byteCount >= contentLen && 0 >= contentLen )
00148         {
00149                 if ( m_state == HTTPBODY_STATE_VAL )
00150                 {
00151                         m_data.ElementAtRef( m_data.Count() - 1 ).ValueRef() = *m_accum.ToString();
00152                         m_accum.SetLength(0);
00153                         m_state = HTTPBODY_STATE_NAME;
00154                 }
00155         }
00156 }
00157 
00158 int HttpRequestBodyFormData::ByteCount() const 
00159 { 
00160         return m_byteCount; 
00161 }
00162 
00163 void HttpRequestBodyFormData::Write( TextWriter& strm ) const
00164 {
00165         int count = m_data.Count();
00166         for ( int x = 0; x < count; x++ )
00167         {
00168                 String& key = m_data.ElementAtRef(x).KeyRef();
00169                 String& val = m_data.ElementAtRef(x).ValueRef();
00170 
00171                 if ( x > 0 )
00172                 {
00173                         strm.Write("&");
00174                 }
00175 
00176                 if ( HttpUtility::UrlEncodeRequired(key) )
00177                 {
00178                         strm.Write( *HttpUtility::UrlEncode(key) );
00179                 }
00180                 else
00181                 {
00182                         strm.Write( key );
00183                 }
00184                 strm.Write("=");
00185                 if ( HttpUtility::UrlEncodeRequired(val) )
00186                 {
00187                         strm.Write( *HttpUtility::UrlEncode(val) );
00188                 }
00189                 else
00190                 {
00191                         strm.Write( val );
00192                 }
00193         }
00194 }
00195 
00196 StringPtr HttpRequestBodyFormData::ToString() const
00197 {
00198         MemoryStreamPtr ms(new MemoryStream());
00199         TextWriter tw(ms);
00200         Write( tw );
00201         return ms->ToString();
00202 }
00203 
00204 #ifdef DEBUG
00205 void HttpRequestBodyFormData::ValidateMem() const
00206 {
00207         m_data.ValidateMem();
00208 }
00209 
00210 void HttpRequestBodyFormData::CheckMem() const
00211 {
00212         m_data.CheckMem();
00213 }
00214 #endif