summaryrefslogtreecommitdiff
path: root/lib/httpserver/HTTPRequest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/httpserver/HTTPRequest.cpp')
-rw-r--r--lib/httpserver/HTTPRequest.cpp135
1 files changed, 112 insertions, 23 deletions
diff --git a/lib/httpserver/HTTPRequest.cpp b/lib/httpserver/HTTPRequest.cpp
index 8ba44903..aa064363 100644
--- a/lib/httpserver/HTTPRequest.cpp
+++ b/lib/httpserver/HTTPRequest.cpp
@@ -15,6 +15,7 @@
#include <stdio.h>
#include "HTTPRequest.h"
+#include "HTTPResponse.h"
#include "HTTPQueryDecoder.h"
#include "autogen_HTTPException.h"
#include "IOStream.h"
@@ -44,7 +45,9 @@ HTTPRequest::HTTPRequest()
mHTTPVersion(0),
mContentLength(-1),
mpCookies(0),
- mClientKeepAliveRequested(false)
+ mClientKeepAliveRequested(false),
+ mExpectContinue(false),
+ mpStreamToReadFrom(NULL)
{
}
@@ -61,11 +64,13 @@ HTTPRequest::HTTPRequest()
HTTPRequest::HTTPRequest(enum Method method, const std::string& rURI)
: mMethod(method),
mRequestURI(rURI),
- mHostPort(80), // default if not specified
+ mHostPort(80), // default if not specified
mHTTPVersion(HTTPVersion_1_1),
mContentLength(-1),
mpCookies(0),
- mClientKeepAliveRequested(false)
+ mClientKeepAliveRequested(false),
+ mExpectContinue(false),
+ mpStreamToReadFrom(NULL)
{
}
@@ -120,30 +125,36 @@ bool HTTPRequest::Receive(IOStreamGetLine &rGetLine, int Timeout)
// Check the method
unsigned int p = 0; // current position in string
- if(::strncmp(requestLine.c_str(), "GET ", 4) == 0)
- {
- p = 3;
- mMethod = Method_GET;
- }
- else if(::strncmp(requestLine.c_str(), "HEAD ", 5) == 0)
- {
- p = 4;
- mMethod = Method_HEAD;
- }
- else if(::strncmp(requestLine.c_str(), "POST ", 5) == 0)
+ p = requestLine.find(' '); // end of first word
+
+ if (p == std::string::npos)
{
- p = 4;
- mMethod = Method_POST;
+ // No terminating space, looks bad
+ p = requestLine.size();
}
else
{
- p = requestLine.find(' ');
- if(p == std::string::npos)
+ std::string method = requestLine.substr(0, p);
+ if (method == "GET")
{
- // No terminating space, looks bad
- p = requestLine.size();
+ mMethod = Method_GET;
+ }
+ else if (method == "HEAD")
+ {
+ mMethod = Method_HEAD;
+ }
+ else if (method == "POST")
+ {
+ mMethod = Method_POST;
+ }
+ else if (method == "PUT")
+ {
+ mMethod = Method_PUT;
+ }
+ else
+ {
+ mMethod = Method_UNKNOWN;
}
- mMethod = Method_UNKNOWN;
}
// Skip spaces to find URI
@@ -263,6 +274,15 @@ bool HTTPRequest::Receive(IOStreamGetLine &rGetLine, int Timeout)
// Now parse the headers
ParseHeaders(rGetLine, Timeout);
+ std::string expected;
+ if (GetHeader("Expect", &expected))
+ {
+ if (expected == "100-continue")
+ {
+ mExpectContinue = true;
+ }
+ }
+
// Parse form data?
if(mMethod == Method_POST && mContentLength >= 0)
{
@@ -305,10 +325,42 @@ bool HTTPRequest::Receive(IOStreamGetLine &rGetLine, int Timeout)
// Finish off
decoder.Finish();
}
+ else if (mContentLength > 0)
+ {
+ IOStream::pos_type bytesToCopy = rGetLine.GetSizeOfBufferedData();
+ if (bytesToCopy > mContentLength)
+ {
+ bytesToCopy = mContentLength;
+ }
+ Write(rGetLine.GetBufferedData(), bytesToCopy);
+ SetForReading();
+ mpStreamToReadFrom = &(rGetLine.GetUnderlyingStream());
+ }
return true;
}
+void HTTPRequest::ReadContent(IOStream& rStreamToWriteTo)
+{
+ Seek(0, SeekType_Absolute);
+
+ CopyStreamTo(rStreamToWriteTo);
+ IOStream::pos_type bytesCopied = GetSize();
+
+ while (bytesCopied < mContentLength)
+ {
+ char buffer[1024];
+ IOStream::pos_type bytesToCopy = sizeof(buffer);
+ if (bytesToCopy > mContentLength - bytesCopied)
+ {
+ bytesToCopy = mContentLength - bytesCopied;
+ }
+ bytesToCopy = mpStreamToReadFrom->Read(buffer, bytesToCopy);
+ rStreamToWriteTo.Write(buffer, bytesToCopy);
+ bytesCopied += bytesToCopy;
+ }
+}
+
// --------------------------------------------------------------------------
//
// Function
@@ -317,7 +369,7 @@ bool HTTPRequest::Receive(IOStreamGetLine &rGetLine, int Timeout)
// Created: 03/01/09
//
// --------------------------------------------------------------------------
-bool HTTPRequest::Send(IOStream &rStream, int Timeout)
+bool HTTPRequest::Send(IOStream &rStream, int Timeout, bool ExpectContinue)
{
switch (mMethod)
{
@@ -331,6 +383,8 @@ bool HTTPRequest::Send(IOStream &rStream, int Timeout)
rStream.Write("HEAD"); break;
case Method_POST:
rStream.Write("POST"); break;
+ case Method_PUT:
+ rStream.Write("PUT"); break;
}
rStream.Write(" ");
@@ -391,6 +445,11 @@ bool HTTPRequest::Send(IOStream &rStream, int Timeout)
{
oss << i->first << ": " << i->second << "\n";
}
+
+ if (ExpectContinue)
+ {
+ oss << "Expect: 100-continue\n";
+ }
rStream.Write(oss.str().c_str());
rStream.Write("\n");
@@ -398,6 +457,31 @@ bool HTTPRequest::Send(IOStream &rStream, int Timeout)
return true;
}
+void HTTPRequest::SendWithStream(IOStream &rStreamToSendTo, int Timeout,
+ IOStream* pStreamToSend, HTTPResponse& rResponse)
+{
+ IOStream::pos_type size = pStreamToSend->BytesLeftToRead();
+
+ if (size != IOStream::SizeOfStreamUnknown)
+ {
+ mContentLength = size;
+ }
+
+ Send(rStreamToSendTo, Timeout, true);
+
+ rResponse.Receive(rStreamToSendTo, Timeout);
+ if (rResponse.GetResponseCode() != 100)
+ {
+ // bad response, abort now
+ return;
+ }
+
+ pStreamToSend->CopyStreamTo(rStreamToSendTo, Timeout);
+
+ // receive the final response
+ rResponse.Receive(rStreamToSendTo, Timeout);
+}
+
// --------------------------------------------------------------------------
//
// Function
@@ -509,7 +593,12 @@ void HTTPRequest::ParseHeaders(IOStreamGetLine &rGetLine, int Timeout)
}
// else don't understand, just assume default for protocol version
}
- // else ignore it
+ else
+ {
+ std::string name = header.substr(0, p);
+ mExtraHeaders.push_back(Header(name,
+ h + dataStart));
+ }
// Unset have header flag, as it's now been processed
haveHeader = false;