summaryrefslogtreecommitdiffstats
path: root/source/HTTPServer
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--source/HTTPServer/HTTPConnection.cpp18
-rw-r--r--source/HTTPServer/HTTPConnection.h3
-rw-r--r--source/HTTPServer/HTTPMessage.cpp17
-rw-r--r--source/HTTPServer/HTTPMessage.h18
-rw-r--r--source/HTTPServer/HTTPServer.cpp10
5 files changed, 65 insertions, 1 deletions
diff --git a/source/HTTPServer/HTTPConnection.cpp b/source/HTTPServer/HTTPConnection.cpp
index 61f4b3a31..e3a6be494 100644
--- a/source/HTTPServer/HTTPConnection.cpp
+++ b/source/HTTPServer/HTTPConnection.cpp
@@ -26,6 +26,18 @@ void cHTTPConnection::SendStatusAndReason(int a_StatusCode, const AString & a_Re
{
AppendPrintf(m_OutgoingData, "%d %s\r\n\r\n", a_StatusCode, a_Response.c_str());
m_HTTPServer.NotifyConnectionWrite(*this);
+ m_State = wcsRecvHeaders;
+}
+
+
+
+
+
+void cHTTPConnection::SendNeedAuth(const AString & a_Realm)
+{
+ AppendPrintf(m_OutgoingData, "HTTP/1.1 401 Unauthorized\r\nWWW-Authenticate: Basic realm=\"%s\"\r\n\r\n", a_Realm.c_str());
+ m_HTTPServer.NotifyConnectionWrite(*this);
+ m_State = wcsRecvHeaders;
}
@@ -73,6 +85,12 @@ void cHTTPConnection::AwaitNextRequest(void)
{
switch (m_State)
{
+ case wcsRecvHeaders:
+ {
+ // Nothing has been received yet, or a special response was given (SendStatusAndReason() or SendNeedAuth() )
+ break;
+ }
+
case wcsRecvIdle:
{
// The client is waiting for a response, send an "Internal server error":
diff --git a/source/HTTPServer/HTTPConnection.h b/source/HTTPServer/HTTPConnection.h
index 9e05d342b..941a29000 100644
--- a/source/HTTPServer/HTTPConnection.h
+++ b/source/HTTPServer/HTTPConnection.h
@@ -43,6 +43,9 @@ public:
/// Sends HTTP status code together with a_Reason (used for HTTP errors)
void SendStatusAndReason(int a_StatusCode, const AString & a_Reason);
+ /// Sends the "401 unauthorized" reply together with instructions on authorizing, using the specified realm
+ void SendNeedAuth(const AString & a_Realm);
+
/// Sends the headers contained in a_Response
void Send(const cHTTPResponse & a_Response);
diff --git a/source/HTTPServer/HTTPMessage.cpp b/source/HTTPServer/HTTPMessage.cpp
index ed5c87e84..6cf9464a3 100644
--- a/source/HTTPServer/HTTPMessage.cpp
+++ b/source/HTTPServer/HTTPMessage.cpp
@@ -71,7 +71,8 @@ cHTTPRequest::cHTTPRequest(void) :
super(mkRequest),
m_EnvelopeParser(*this),
m_IsValid(true),
- m_UserData(NULL)
+ m_UserData(NULL),
+ m_HasAuth(false)
{
}
@@ -204,6 +205,20 @@ int cHTTPRequest::ParseRequestLine(const char * a_Data, int a_Size)
void cHTTPRequest::OnHeaderLine(const AString & a_Key, const AString & a_Value)
{
+ if (
+ (NoCaseCompare(a_Key, "Authorization") == 0) &&
+ (strncmp(a_Value.c_str(), "Basic ", 6) == 0)
+ )
+ {
+ AString UserPass = Base64Decode(a_Value.substr(6));
+ size_t idxCol = UserPass.find(':');
+ if (idxCol != AString::npos)
+ {
+ m_AuthUsername = UserPass.substr(0, idxCol);
+ m_AuthPassword = UserPass.substr(idxCol + 1);
+ m_HasAuth = true;
+ }
+ }
AddHeader(a_Key, a_Value);
}
diff --git a/source/HTTPServer/HTTPMessage.h b/source/HTTPServer/HTTPMessage.h
index ef8e12ca4..151eb468f 100644
--- a/source/HTTPServer/HTTPMessage.h
+++ b/source/HTTPServer/HTTPMessage.h
@@ -91,6 +91,15 @@ public:
/// Returns true if more data is expected for the request headers
bool IsInHeaders(void) const { return m_EnvelopeParser.IsInHeaders(); }
+ /// Returns true if the request did present auth data that was understood by the parser
+ bool HasAuth(void) const { return m_HasAuth; }
+
+ /// Returns the username that the request presented. Only valid if HasAuth() is true
+ const AString & GetAuthUsername(void) const { return m_AuthUsername; }
+
+ /// Returns the password that the request presented. Only valid if HasAuth() is true
+ const AString & GetAuthPassword(void) const { return m_AuthPassword; }
+
protected:
/// Parser for the envelope data
cEnvelopeParser m_EnvelopeParser;
@@ -110,6 +119,15 @@ protected:
/// Data that the HTTPServer callbacks are allowed to store.
void * m_UserData;
+ /// Set to true if the request contains auth data that was understood by the parser
+ bool m_HasAuth;
+
+ /// The username used for auth
+ AString m_AuthUsername;
+
+ /// The password used for auth
+ AString m_AuthPassword;
+
/** Parses the incoming data for the first line (RequestLine)
Returns the number of bytes consumed, or -1 for an error
diff --git a/source/HTTPServer/HTTPServer.cpp b/source/HTTPServer/HTTPServer.cpp
index 4102d1047..43bb751c4 100644
--- a/source/HTTPServer/HTTPServer.cpp
+++ b/source/HTTPServer/HTTPServer.cpp
@@ -73,6 +73,16 @@ class cDebugCallbacks :
return;
}
+ // Test the auth failure and success:
+ if (a_Request.GetURL() == "/auth")
+ {
+ if (!a_Request.HasAuth() || (a_Request.GetAuthUsername() != "a") || (a_Request.GetAuthPassword() != "b"))
+ {
+ a_Connection.SendNeedAuth("MCServer WebAdmin");
+ return;
+ }
+ }
+
cHTTPResponse Resp;
Resp.SetContentType("text/plain");
a_Connection.Send(Resp);