Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(494)

Unified Diff: src/http/model/http-server.cc

Issue 4940041: HTTP Traffic Generator
Patch Set: update http controller Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/http/model/http-server.h ('k') | src/http/test/http-test-suite.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/http/model/http-server.cc
===================================================================
new file mode 100644
--- /dev/null
+++ b/src/http/model/http-server.cc
@@ -0,0 +1,316 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011 Yufei Cheng
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Yufei Cheng <yfcheng@ittc.ku.edu>
+ *
+ * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
+ * ResiliNets Research Group http://wiki.ittc.ku.edu/resilinets
+ * Information and Telecommunication Technology Center (ITTC)
+ * and Department of Electrical Engineering and Computer Science
+ * The University of Kansas Lawrence, KS USA.
+ *
+ * Work supported in part by NSF FIND (Future Internet Design) Program
+ * under grant CNS-0626918 (Postmodern Internet Architecture),
+ * NSF grant CNS-1050226 (Multilayer Network Resilience Analysis and Experimentation on GENI),
+ * US Department of Defense (DoD), and ITTC at The University of Kansas.
+ */
+
+#include <limits>
+#include <deque>
+
+#include "ns3/socket.h"
+#include "ns3/tcp-socket-factory.h"
+#include "ns3/uinteger.h"
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/packet.h"
+#include "ns3/tcp-socket.h"
+#include "ns3/pointer.h"
+#include "ns3/object.h"
+
+#include "http-server.h"
+#include "http-controller.h"
+
+#include "ns3/tcp-socket.h"
+
+NS_LOG_COMPONENT_DEFINE ("HttpServer");
+
+namespace ns3 {
+namespace http {
+
+NS_OBJECT_ENSURE_REGISTERED (HttpServer);
+
+TypeId
+HttpServer::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::http::HttpServer")
+ .SetParent<Application> ()
+ .AddConstructor<HttpServer> ()
+ .AddAttribute ("HttpController", "The controller",
+ PointerValue (0),
+ MakePointerAccessor (&HttpServer::SetController,
+ &HttpServer::GetController),
+ MakePointerChecker<HttpController> ())
+ .AddAttribute ("PageTimeout", "Time out value for each one web page",
+ UintegerValue (1),
+ MakeUintegerAccessor (&HttpServer::m_pageTimeout),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("Local", "The local address for server",
+ AddressValue (),
+ MakeAddressAccessor (&HttpServer::m_local),
+ MakeAddressChecker ())
+ .AddAttribute ("RunNo", "number of runs for simulation",
+ UintegerValue (0),
+ MakeUintegerAccessor (&HttpServer::m_run),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("TransportId", "The type of protocol to use.",
+ TypeIdValue (TcpSocketFactory::GetTypeId ()),
+ MakeTypeIdAccessor (&HttpServer::m_tid),
+ MakeTypeIdChecker ())
+ .AddAttribute ("Persistent", "Set if the connection is persistent connection or not.",
+ BooleanValue (true),
+ MakeBooleanAccessor (&HttpServer::m_persistent),
+ MakeBooleanChecker ())
+ ;
+ return tid;
+}
+
+HttpServer::HttpServer ()
+{
+ m_firstConnection = true;
+}
+
+HttpServer::~HttpServer ()
+{
+ m_firstConnection = false;
+}
+
+void
+HttpServer::SetController (Ptr<HttpController> controller)
+{
+ NS_LOG_FUNCTION (this);
+ m_controller = controller;
+}
+
+Ptr<HttpController>
+HttpServer::GetController () const
+{
+ NS_LOG_FUNCTION (this);
+ return m_controller;
+}
+
+void HttpServer::StartApplication ()
+{
+ NS_LOG_FUNCTION (this);
+ // Called at time specified by Start
+ // Create the socket if not already
+ if (!m_socket)
+ {
+ m_socket = Socket::CreateSocket (GetNode (), m_tid);
+ m_socket->Bind (m_local);
+ m_socket->Listen ();
+ }
+ NS_ASSERT (m_socket != 0);
+ m_socket->SetAcceptCallback (MakeCallback (&HttpServer::ConnectionRequested, this),
+ MakeCallback (&HttpServer::ConnectionAccepted, this));
+
+ /// By this time save the serve application information in the controller
+ SetServerApplication ();
+ NS_LOG_LOGIC (Simulator::Now () << " Server ready waiting for Client request");
+}
+
+void HttpServer::StopApplication ()
+{
+ NS_LOG_FUNCTION (this);
+ // Called at time specified by Stop
+ NS_LOG_DEBUG (Simulator::Now () << " Server: Stop Application");
+
+ if (m_socket)
+ {
+ m_socket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ());
+ }
+}
+
+void
+HttpServer::SetServerApplication ()
+{
+ NS_LOG_FUNCTION (this);
+ Ptr<Node> node = GetNode ();
+ for (uint32_t i = 0; i < node->GetNApplications (); ++i)
+ {
+ if (node->GetApplication (i) == this)
+ {
+ m_controller->SetServerApplication (node, i);
+ }
+ }
+}
+
+bool
+HttpServer::ConnectionRequested (Ptr<Socket> socket, const Address& address)
+{
+ NS_LOG_FUNCTION (this << socket << address);
+ NS_LOG_DEBUG (Simulator::Now () << " Socket = " << socket << " " << " Server: ConnectionRequested");
+ return true;
+}
+
+void
+HttpServer::ConnectionAccepted (Ptr<Socket> socket, const Address& address)
+{
+ NS_LOG_FUNCTION (this << socket << address);
+ /*
+ * We have a new socket and need to set the receive callback and respond with the response
+ * when the request arrives
+ */
+ NS_LOG_DEBUG (socket << " " << Simulator::Now () << " Server::Successful socket id : " << socket << " Connection Accepted");
+ m_socket = socket;
+
+ // Now we've blocked, so register the up-call for later
+ m_socket->SetRecvCallback (MakeCallback (&HttpServer::ServerReceive, this));
+
+ if (m_firstConnection)
+ {
+ m_firstConnection = false;
+ /// This is the first connection accepted, call the first web session
+ m_controller->StartFirstWebSession ();
+ }
+ else
+ {
+ NS_ASSERT (!m_persistent);
+ /// After the new connection is established, we start the next client send immediately
+ m_controller->CallClientSend ();
+ }
+}
+
+void
+HttpServer::ServerReceive (Ptr<Socket> socket)
+{
+ NS_LOG_FUNCTION (this << socket);
+ Ptr<Packet> packet = socket->Recv ();
+ /// We should not have a null packet
+ if (packet == NULL)
+ {
+ NS_LOG_WARN ("We should not receive this part");
+ return;
+ }
+
+ AduContainer serverContainer = m_controller->GetServerContainer ();
+ uint32_t bytesToRecv = packet->GetSize ();
+ while (bytesToRecv)
+ {
+ uint32_t requestSize = FindFirstRequestSize (serverContainer);
+ NS_LOG_DEBUG ("the request size " << requestSize);
+ if (!requestSize)
+ {
+ NS_FATAL_ERROR ("This should not happen");
+ return;
+ }
+
+ if (requestSize > bytesToRecv)
+ {
+ // Received less than a whole ADU. Reduce its size by the number of bytes received.
+ requestSize -= bytesToRecv;
+ UpdateFirstRequestSize (serverContainer, requestSize);
+ NS_LOG_LOGIC ("Received " << bytesToRecv << " bytes of an ADU. " << serverContainer.objects.front ().size << " bytes to go.");
+ break;
+ }
+ else
+ {
+ // Front ADU size <= bytesToRecv: remove the whole thing and continue receiving
+ bytesToRecv -= requestSize;
+ // Remove the next request adu
+ RemoveFirstRequestSize (serverContainer);
+ serverContainer.serverReceiveTime = Simulator::Now ().GetSeconds ();
+ m_controller->SetServerContainer (serverContainer);
+ if (serverContainer.objects.size ())
+ {
+ // After receiving the request we need to schedule the web response
+ m_controller->ScheduleNextServerSend (socket);
+ }
+ continue;
+ }
+ }
+}
+
+uint32_t
+HttpServer::FindFirstRequestSize (AduContainer & serverContainer)
+{
+ NS_LOG_FUNCTION (this);
+ for (deque<ADU>::iterator i = serverContainer.objects.begin (); i != serverContainer.objects.end (); ++i)
+ {
+ if (i->messageType == ADU::REQUEST)
+ {
+ return i->size;
+ }
+ }
+ return 0;
+}
+
+void
+HttpServer::UpdateFirstRequestSize (AduContainer & serverContainer, uint32_t requestSize)
+{
+ NS_LOG_FUNCTION (this << requestSize);
+ for (deque<ADU>::iterator i = serverContainer.objects.begin (); i != serverContainer.objects.end (); ++i)
+ {
+ if (i->messageType == ADU::REQUEST)
+ {
+ i->size = requestSize;
+ break;
+ }
+ }
+ m_controller->SetServerContainer (serverContainer);
+}
+
+void
+HttpServer::RemoveFirstRequestSize (AduContainer & serverContainer)
+{
+ NS_LOG_FUNCTION (this);
+ for (deque<ADU>::iterator i = serverContainer.objects.begin (); i != serverContainer.objects.end (); ++i)
+ {
+ if (i->messageType == ADU::REQUEST)
+ {
+ i = serverContainer.objects.erase (i);
+ break;
+ }
+ }
+ m_controller->SetServerContainer (serverContainer);
+}
+
+void
+HttpServer::PrintContainer (const AduContainer & container)
+{
+ NS_LOG_FUNCTION (this);
+ for (deque< deque <ADU> >::const_iterator i = container.pages.begin (); i != container.pages.end (); ++i)
+ {
+ deque<ADU> objects = *i;
+ for (deque<ADU>::const_iterator j = objects.begin (); j != objects.end (); ++j)
+ {
+ NS_LOG_DEBUG ("The adu size " << j->size);
+ if (j->messageType == ADU::REQUEST)
+ {
+ NS_LOG_DEBUG ("This is a request");
+ }
+ else
+ {
+ NS_LOG_DEBUG ("This is a response");
+ }
+ }
+ }
+}
+
+} // namespace http
+} // namespace ns3
« no previous file with comments | « src/http/model/http-server.h ('k') | src/http/test/http-test-suite.cc » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b