Spinning Topp Logo BlackTopp Studios
inc
httprequest.cpp
1 // © Copyright 2010 - 2016 BlackTopp Studios Inc.
2 /* This file is part of The Mezzanine Engine.
3 
4  The Mezzanine Engine is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  The Mezzanine Engine is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with The Mezzanine Engine. If not, see <http://www.gnu.org/licenses/>.
16 */
17 /* The original authors have included a copy of the license specified above in the
18  'Docs' folder. See 'gpl.txt'
19 */
20 /* We welcome the use of the Mezzanine engine to anyone, including companies who wish to
21  Build professional software and charge for their product.
22 
23  However there are some practical restrictions, so if your project involves
24  any of the following you should contact us and we will try to work something
25  out:
26  - DRM or Copy Protection of any kind(except Copyrights)
27  - Software Patents You Do Not Wish to Freely License
28  - Any Kind of Linking to Non-GPL licensed Works
29  - Are Currently In Violation of Another Copyright Holder's GPL License
30  - If You want to change our code and not add a few hundred MB of stuff to
31  your distribution
32 
33  These and other limitations could cause serious legal problems if you ignore
34  them, so it is best to simply contact us or the Free Software Foundation, if
35  you have any questions.
36 
37  Joseph Toppi - toppij@gmail.com
38  John Blackwood - makoenergy02@gmail.com
39 */
40 
41 #ifndef _networkhttprequest_cpp
42 #define _networkhttprequest_cpp
43 
44 #include "Network/httprequest.h"
45 
46 #include "stringtool.h"
47 
48 namespace Mezzanine
49 {
50  namespace Network
51  {
53  RequestMethod(Network::HRM_GET)
54  { }
55 
56  HTTPRequest::HTTPRequest(const String& ToDecompose)
57  { this->Decompose(ToDecompose); }
58 
60  RequestMethod(Method),
61  RequestURI(URI)
62  { this->MessageBody = Body; }
63 
65  { }
66 
68  {
69  // A request header has 3 components: A method, a URI, and a version.
70  Boole EoL = false;
71  String HeaderTemp;
72  // Method
73  EoL = this->GetMessageComponent(CurrIt,EndIt,HeaderTemp);
74  this->RequestMethod = this->ConvertRequestMethod(HeaderTemp);
75  if( EoL ) {
76  return false;
77  }
78  // URI
79  HeaderTemp.clear();
80  EoL = this->GetMessageComponent(CurrIt,EndIt,HeaderTemp);
81  this->RequestURI.ParseFromString(HeaderTemp);
82  if( EoL ) {
83  return false;
84  }
85  // Version
86  HeaderTemp.clear();
87  this->GetMessageComponent(CurrIt,EndIt,HeaderTemp);
88  this->ParseHTTPVersion(HeaderTemp);
89  return true;
90  }
91 
92  ///////////////////////////////////////////////////////////////////////////////
93  // Utility
94 
96  {
97  switch( Method )
98  {
99  case HRM_GET: return "GET";
100  case HRM_HEAD: return "HEAD";
101  case HRM_POST: return "POST";
102  case HRM_OPTIONS: return "OPTIONS";
103  case HRM_PUT: return "PUT";
104  case HRM_DELETE: return "DELETE";
105  case HRM_TRACE: return "TRACE";
106  case HRM_CONNECT: return "CONNECT";
107  case HRM_PATCH: return "PATCH";
108  case HRM_PROPFIND: return "PROPFIND";
109  case HRM_PROPPATCH: return "PROPPATCH";
110  case HRM_MKCOL: return "MKCOL";
111  case HRM_COPY: return "COPY";
112  case HRM_MOVE: return "MOVE";
113  case HRM_LOCK: return "LOCK";
114  case HRM_UNLOCK: return "UNLOCK";
115  default:
116  case HRM_Invalid: return "";
117  }
118  return "";
119  }
120 
122  {
123  // 3 characters is the shortest length for any Request Method
124  if( Method.size() >= 3 ) {
125  switch( Method[0] )
126  {
127  case 'C':
128  {
129  switch( Method[2] )
130  {
131  case 'N': return Network::HRM_CONNECT; break;
132  case 'P': return Network::HRM_COPY; break;
133  }
134  }
135  case 'D': return Network::HRM_DELETE; break;
136  case 'G': return Network::HRM_GET; break;
137  case 'H': return Network::HRM_HEAD; break;
138  case 'L': return Network::HRM_LOCK; break;
139  case 'M':
140  {
141  switch( Method[1] )
142  {
143  case 'K': return Network::HRM_MKCOL; break;
144  case 'O': return Network::HRM_MOVE; break;
145  }
146  }
147  case 'O': return Network::HRM_OPTIONS; break;
148  case 'P':
149  {
150  switch( Method[1] )
151  {
152  case 'A': return Network::HRM_PATCH; break;
153  case 'O': return Network::HRM_POST; break;
154  case 'R':
155  {
156  if( Method.size() >= 5 ) {
157  switch( Method[4] )
158  {
159  case 'F': return Network::HRM_PROPFIND; break;
160  case 'P': return Network::HRM_PROPPATCH; break;
161  }
162  }
163  }
164  case 'U': return Network::HRM_PUT; break;
165  }
166  }
167  case 'T': return Network::HRM_TRACE; break;
168  case 'U': return Network::HRM_UNLOCK; break;
169  }
170  }
171  return Network::HRM_Invalid;
172  }
173 
175  {
176  StringStream RequestStream;
177  // Header
178  RequestStream << HTTPRequest::ConvertRequestMethod( this->RequestMethod ) << " " << this->RequestURI.ConvertToString() << " ";
179  RequestStream << "HTTP/" << this->MessageVersion.Major << "." << this->MessageVersion.Minor << "\r\n";
180  // Fields
181  for( HeaderFieldContainer::const_iterator FieldIt = this->MessageFields.begin() ; FieldIt != this->MessageFields.end() ; ++FieldIt )
182  {
183  RequestStream << (*FieldIt).HeaderName << ": " << (*FieldIt).HeaderValue << "\r\n";
184  }
185  RequestStream << "\r\n";
186  // Body
187  RequestStream << this->MessageBody;
188  return RequestStream.str();
189  }
190 
192  {
193  StringIterator CurrIt = Message.begin();
194  return this->Decompose(CurrIt,Message.end());
195  }
196 
198  {
199  if( CurrIt != EndIt ) {
200  // Start decomposing
201  if( !this->ParseHTTPHeader(CurrIt,EndIt) ) {
202  return false;
203  }
204  if( !this->ParseHTTPFields(CurrIt,EndIt) ) {
205  return false;
206  }
207  this->MessageBody.clear();
208  String Length = this->GetContentLengthHeader();
209  if( !Length.empty() ) {
210  this->MessageBody.reserve(StringTools::ConvertToWhole(Length));
211  }
212  this->MessageBody.assign(CurrIt,EndIt);
213 
214  return true;
215  }
216  return false;
217  }
218 
220  { this->RequestURI = URI; }
221 
222  const URI& HTTPRequest::GetURI() const
223  { return this->RequestURI; }
224 
226  { this->RequestMethod = Method; }
227 
229  { return this->RequestMethod; }
230 
231  ///////////////////////////////////////////////////////////////////////////////
232  // Recommended Header Field Convenience Methods
233 
235  { this->SetField("Expect",Expect); }
236 
238  { return this->GetField("Expect"); }
239 
241  { this->SetField("From",From); }
242 
244  { return this->GetField("From"); }
245 
247  { this->SetField("Host",Host); }
248 
250  { return this->GetField("Host"); }
251 
253  { this->SetField("User-Agent",UserAgent); }
254 
256  { return this->GetField("User-Agent"); }
257  }//Network
258 }//Mezzanine
259 
260 #endif
HTTPRequest()
Blank constructor.
Definition: httprequest.cpp:52
String::const_iterator StringIterator
Convenience typedef for String iterators.
Definition: httpmessage.h:77
Retrieves a list of the supported HTTP methods on the server.
Boole ParseHTTPFields(StringIterator &CurrIt, const StringIterator EndIt)
Parses the HTTP fields from a provided string.
void SetURI(const URI &URI)
Sets the URI of the resource being requested.
bool Boole
Generally acts a single bit, true or false.
Definition: datatypes.h:173
String ConvertToString() const
Combines the set components of this URI into a usable String for transmission.
Definition: uri.cpp:747
~HTTPRequest()
Class destructor.
Definition: httprequest.cpp:64
Moves a resource from one URI to another.
const String & GetFromHeader() const
Gets the From Header.
Requests the server accept enclosed data as a new subordinate of the specified resource/URI. Such as a blog or forum post.
void SetMethod(const Network::HTTPRequestMethod Method)
Sets the method to be used for the request.
const String & GetExpectHeader() const
Gets the Expect Header.
void SetFromHeader(const String &From)
Sets the From Header.
const URI & GetURI() const
Gets the URI of the resource being requested.
HTTPRequestMethod RequestMethod
The HTTP method to use for the request.
Definition: httprequest.h:66
UInt16 Major
The Major component of the version to be expressed.
Definition: version.h:68
Requests a representation of the specified resource.
const String & GetField(const String &FieldName) const
Gets a Name-Value pair for a header field in the message.
std::stringstream StringStream
A Datatype used for streaming operations with strings.
Definition: datatypes.h:176
SimpleVersion MessageVersion
The version component for this response.
Definition: httpmessage.h:90
Unlocks a resource, freeing it for other purposes.
UInt16 Minor
The Minor component of the version to be expressed.
Definition: version.h:70
static String ConvertRequestMethod(const Network::HTTPRequestMethod Method)
Converts a HTTPRequestMethod enum value to it's text representation.
Definition: httprequest.cpp:95
Copies a resource from one URI to another.
Places or replaces a supplied resource at the specified URI.
Retrieves a property, stored as XML, from a resource. Can alternatively be overloaded to retrieve the...
Boole GetMessageComponent(StringIterator &CurrIt, const StringIterator EndIt, String &Component)
Extracts all characters from CurrIt until the first space encountered or EndIt, whichever comes first...
void SetExpectHeader(const String &Expect)
Sets the Expect Header.
Similar to GET, but only requests the header without the body.
void SetHostHeader(const String &Host)
Sets the Host Header.
const String & GetContentLengthHeader() const
Gets the Content-Length Header.
URI & ParseFromString(const String &ToParse)
Parses the contents of a String into this URI.
Definition: uri.cpp:707
const String & GetHostHeader() const
Gets the Host Header.
void SetField(const String &FieldName, const String &FieldValue)
Sets a Name-Value pair for a header field in the message.
Requests a list of changes or additions done by other sessions.
Deletes the specified resource.
Applies partial modifications to a resource.
void SetUserAgentHeader(const String &UserAgent)
Sets the User-Agent Header.
Boole Decompose(const String &Message)
Populates the members of this class with data from a text HTTP Message.
Boole ParseHTTPHeader(StringIterator &CurrIt, const StringIterator EndIt)
Parses the information contained in the Message Header.
Definition: httprequest.cpp:67
Whole ConvertToWhole(const String &ToConvert)
Converts a string into an Whole.
Definition: stringtool.cpp:408
URI RequestURI
The URI of the resource to request.
Definition: httprequest.h:69
A helper class for the reading and using of Uniform Resource Identifiers.
Definition: uri.h:59
Boole ParseHTTPVersion(const String &ToParse)
Parses the HTTP version from a provided string.
The bulk of the engine components go in this namspace.
Definition: actor.cpp:56
HeaderFieldContainer MessageFields
A container of fields to populate the message header with.
Definition: httpmessage.h:96
String MessageBody
The body of the message.
Definition: httpmessage.h:93
const String & GetUserAgentHeader() const
Gets the User-Agent Header.
Converts the request connection to a tunnel, useful for sending traffic through a proxy...
Can change and/or delete multiple properties of a resource in a single atomic act.
HTTPRequestMethod
This enum is a listing of commonly supported HTTP request methods.
Can be used to create a new directory. "COL" is short for Collection, which is the term commonly used...
Locks a resource to prevent alterations being made to it by another session. This is similar in funct...
std::string String
A datatype used to a series of characters.
Definition: datatypes.h:159
Network::HTTPRequestMethod GetMethod() const
Gets the method to be used for the request.
Use for error conditions, not an actual request method.
String Compose() const
Creates a completed Message that can be sent across an HTTP connection.