示例#1
0
/**
 * Check a GET to a url returns a certain code and data.
 */
static void _checkUrlText(
   TestRunner& tr, Url* url, int code, const char* expected, int length)
{
   // create client
   HttpClient client;

   // connect
   assertNoException(client.connect(url));

   if(tr.getVerbosityLevel() > 1)
   {
      printf("Connected to: %s\n", url->toString().c_str());
      InternetAddress address(url->getHost().c_str(), url->getPort());
      printf("%s\n", address.toString().c_str());
   }

   // do get
   HttpResponse* response = client.get(url);
   assert(response != NULL);

   if(tr.getVerbosityLevel() > 1)
   {
      printf("Response header:\n%s\n",
         response->getHeader()->toString().c_str());
   }

   if(response->getHeader()->getStatusCode() != code)
   {
      printf("Expecting response status code: %d, got %d\n",
         response->getHeader()->getStatusCode(), code);
   }
   assert(response->getHeader()->getStatusCode() == code);

   // receive content
   HttpTrailer trailer;
   ByteBuffer b;
   ByteArrayOutputStream baos(&b);
   assertNoException(client.receiveContent(&baos, &trailer));

   // put data in strings for strcmp since it may not be NULL terminated
   string strexpected;
   strexpected.assign(expected, length);

   string strdata;
   strdata.assign(b.data(), b.length());

   if(tr.getVerbosityLevel() > 1)
   {
      printf("Response content (%d bytes):\n%s\n", b.length(), strdata.c_str());
      printf("Response trailers:\n%s\n", trailer.toString().c_str());
   }

   // check content
   assertStrCmp(strdata.c_str(), strexpected.c_str());
   assert(b.length() == length);

   client.disconnect();

   assertNoExceptionSet();
}
示例#2
0
static void runHttpClientPostTest(TestRunner& tr)
{
   tr.test("Http Client POST");

   // create client
   HttpClient client;

   // connect
   Url url("http://www.bitmunk.com");
   if(client.connect(&url))
   {
      printf("Connected to: %s\n", url.toString().c_str());
      InternetAddress address(url.getHost().c_str(), url.getPort());
      printf("%s\n", address.toString().c_str());

      char someData[] = "Just some post data.";
      ByteArrayInputStream baos(someData, strlen(someData));

      // do post
      DynamicObject headers;
      headers["Content-Type"] = "text/plain";
      headers["Transfer-Encoding"] = "chunked";

      HttpTrailer trailer;
      HttpResponse* response = client.post(&url, &headers, &baos, &trailer);
      if(response != NULL)
      {
         printf("Response=\n%s\n",
            response->getHeader()->toString().c_str());
         if(response->getHeader()->getStatusCode() == 200)
         {
            // receive content
            trailer.clearFields();
            File file("/tmp/postresponse.txt");
            FileOutputStream fos(file);
            if(client.receiveContent(&fos, &trailer))
            {
               printf("Content downloaded to '%s'\n",
                  file->getAbsolutePath());

               printf("HTTP trailers=\n%s\n", trailer.toString().c_str());
            }
            assertNoExceptionSet();
         }
      }
      else
      {
         printf("There was no response!\n");
      }

      client.disconnect();
   }

   tr.passIfNoException();
}
示例#3
0
static void runHttpClientGetTest(TestRunner& tr)
{
   tr.test("Http Client GET");

   // create client
   HttpClient client;

   // connect
   Url url("http://www.bitmunk.com");
   if(client.connect(&url))
   {
      printf("Connected to: %s\n", url.toString().c_str());
      InternetAddress address(url.getHost().c_str(), url.getPort());
      printf("%s\n", address.toString().c_str());

      // do get
      DynamicObject headers;
      headers["Test-Header"] = "bacon";
      HttpResponse* response = client.get(&url, &headers);
      if(response != NULL)
      {
         printf("Response=\n%s\n", response->getHeader()->toString().c_str());
         if(response->getHeader()->getStatusCode() == 200)
         {
            // receive content
            HttpTrailer trailer;
            File file("/tmp/index.html");
            FileOutputStream fos(file);
            if(client.receiveContent(&fos, &trailer))
            {
               printf("Content downloaded to '%s'\n",
                  file->getAbsolutePath());

               printf("HTTP trailers=\n%s\n", trailer.toString().c_str());
            }
            assertNoExceptionSet();
         }
      }
      else
      {
         printf("There was no response!\n");
      }

      client.disconnect();
   }

   tr.passIfNoException();
}
void HttpProtocol::parseHttpResponse(const std::string& res,HttpResponse& http)
{
	string response(res);
	int pos;
	if( (pos = res.find("\n\r"))!= -1)
		response = response.replace(pos,2,"\n\n");
	HttpHeader header;
	http.getHeader(header);
	string str(response);
	string delim = "\n";
	vector<string> vec;
	split(str,delim,vec);
	parseResponseLine(vec[0],http);
	int i = 1;
	while(vec[i] != "")
	{
		parseHeader(vec[i],header);
		i++;
	}
	i++;
	for(;i<vec.size();i++)
	{
		string tmp(http.getContent());
		tmp = tmp+vec[i];
		if(i != vec.size()-1)
			tmp+="\n";
		http.setContent(tmp);
	}	
}
示例#5
0
static void runHttpClientRedirectLoopTest(TestRunner& tr)
{
   tr.test("Http Client Redirect Loop");

   // start a kernel
   Kernel k;
   k.getEngine()->start();

   // create server
   Server server;
   InternetAddress address("0.0.0.0", 19123);

   // create SSL/generic http connection servicer
   HttpConnectionServicer hcs;
   server.addConnectionService(&address, &hcs);

   // create redirect loop http request servicer
   RedirectLoopHttpRequestServicer loop("/loop");
   hcs.addRequestServicer(&loop, false);

   if(server.start(&k))
   {
      printf("\nServer started on %s\n",
         address.toString(false).c_str());

      // create client
      HttpClient client;

      printf("Connecting and expecting a redirect loop...\n");

      // do get
      Url url("http://localhost:19123/loop");
      HttpResponse* response = client.get(&url, NULL, 2);
      if(response != NULL)
      {
         printf("Response=\n%s\n", response->getHeader()->toString().c_str());
      }
      else
      {
         printf("Correctly detected an exception:\n");
         printf("'%s'\n", Exception::get()->getMessage());
      }
      client.disconnect();
   }
   else if(Exception::get() != NULL)
   {
      printf("\nServer start failed with errors=%s\n",
         Exception::get()->getMessage());
   }

   tr.passIfException();

   // stop server and kernel
   server.stop();
   k.getEngine()->stop();
   Exception::clear();
}
示例#6
0
bool HttpServer::sendResponse(
	SOCKET socket, HttpResponse &response){

	sendString( socket, response.getHeader() );
	sendString( socket, response.getDocument() );

	close( socket );

	return true;
}
void HttpProtocol::geneHttpResponse(const HttpResponse& http,string& response)
{
	HttpHeader header;
	http.getHeader(header);
	char t[10];
	sprintf(t, "%d", http.getStatusCode());
	string code = t;
	response = "" + http.getVersion() + " " + code + " " +  http.getReason() + "\n";
	geneHeader(response,header);
	response += http.getContent();
}
示例#8
0
bool Http11Handler::writeResponse(void* req, void* res, void* context) {
	HttpRequest* request = (HttpRequest*)req;
	HttpResponse* response = (HttpResponse*)res;

	if(isClosed()) {
		if(request!=NULL) {
			delete request;
		}
		delete response;
		return true;
	}

	if(!response->isDone()) {
		response->updateContent(request, chunkSize);
	}

	if(response->getHeader(HttpRequest::Connection)=="")
	{
		if(StringUtil::toLowerCopy(request->getHeader(HttpRequest::Connection))!="keep-alive"
				|| CastUtil::lexical_cast<int>(response->getStatusCode())>307 || request->getHttpVers()<1.1)
		{
			response->addHeaderValue(HttpResponse::Connection, "close");
		}
		else
		{
			response->addHeaderValue(HttpResponse::Connection, "keep-alive");
		}
	}

	std::string data = response->generateOnlyHeaderResponse(request);
	if(!write(data)) {
		bool isFirst = true;
		while(response->hasContent && (data = response->getRemainingContent(request->getUrl(), isFirst)) != "") {
			isFirst = false;
			if(write(data)) {
				break;
			}
		}
	}
	if(request!=NULL) {
		delete request;
	}
	delete response;
	return true;
}
void ProxyResourceHandler::operator()(BtpAction* action)
{
   // get request host
   HttpRequestHeader* hrh = action->getRequest()->getHeader();
   string host = hrh->getFieldValue("X-Forwarded-Host");
   if(host.length() == 0)
   {
      host = hrh->getFieldValue("Host");
   }

   // find a rule
   Rule* rule = findRule(action, host);
   if(rule == NULL)
   {
      // delegate to rest resource handler
      RestResourceHandler::operator()(action);
   }
   else
   {
      // get URL to proxy or redirect to
      UrlRef url = rule->url;

      // get url host
      string urlHost;
      HttpResponse* res = action->getResponse();
      bool secure = res->getConnection()->isSecure();

      // if URL has no host, reuse incoming host
      if(url->getHost().length() == 0)
      {
         urlHost = host;
      }
      // if URL has no port or uses a default port number, only use URL host
      else if(
         (url->getPort() == 0) ||
         (secure && url->getPort() == 443) ||
         (!secure && url->getPort() == 80))
      {
         urlHost = url->getHost();
      }
      // use URL host and port
      else
      {
         urlHost = url->getHostAndPort();
      }

      // handle 0.0.0.0 (any host) by replacing it with the request host
      if(strncmp(urlHost.c_str(), "0.0.0.0", 8) == 0)
      {
         // 0.0.0.0 is 8 chars long
         urlHost.replace(0, 8, host.substr(0, host.find(':')).c_str());
      }

      // rewrite the request path if it does not match URL path
      string path = hrh->getPath();
      if(strcmp(path.c_str(), url->getPath().c_str()) != 0)
      {
         // check for path wildcard
         if(strcmp(rule->path, "*") == 0)
         {
            // since a wildcard is used, prepend the URL path to the
            // resource (if the url path isn't '/')
            string urlPath = url->getPath();
            if(urlPath.length() > 1)
            {
               path.insert(0, url->getPath().c_str());
            }
         }
         else
         {
            // replace the part of the resource that matched the proxy
            // rule with the rewrite path from the proxy URL
            path.replace(0, strlen(rule->path), url->getPath().c_str());
         }
      }

      // do redirect if appropriate
      if(rule->type == Rule::Redirect)
      {
         // set response code
         HttpResponseHeader* header = res->getHeader();
         if(rule->permanent)
         {
            header->setStatus(301, "Moved Permanently");
         }
         else
         {
            header->setStatus(302, "Found");
         }

         // build new location url
         bool secure = res->getConnection()->isSecure();
         header->setField("Location", StringTools::format("%s://%s%s",
            secure ? "https" : "http", urlHost.c_str(), path.c_str()));
         action->sendResult();
      }
      // do proxy
      else if(rule->type == Rule::Proxy)
      {
         // get client-side request
         HttpRequest* req = action->getRequest();

         // do path rewrite
         hrh->setPath(path.c_str());

         // add X-Forwarded headers
         hrh->appendFieldValue("X-Forwarded-For",
            req->getConnection()->getRemoteAddress()->toString(true).c_str());
         hrh->appendFieldValue("X-Forwarded-Host",
            hrh->getFieldValue("Host").c_str());
         hrh->appendFieldValue("X-Forwarded-Server",
            SocketTools::getHostname().c_str());

         // rewrite host if rule specifies it
         if(rule->rewriteHost)
         {
            hrh->setField("Host", urlHost.c_str());
         }

         // do proxy:
         MO_CAT_INFO(BM_NODE_CAT,
            "ProxyResourceHandler proxying %s%s => %s%s",
            host.c_str(), hrh->getPath(), urlHost.c_str(), path.c_str());
         MO_CAT_DEBUG(BM_NODE_CAT,
            "ProxyResourceHandler request header for %s%s => %s%s:\n%s",
            host.c_str(), hrh->getPath(),
            urlHost.c_str(), path.c_str(),
            hrh->toString().c_str());

         // get a connection
         BtpClient* btpc = mNode->getMessenger()->getBtpClient();
         HttpConnection* conn = btpc->createConnection(false, &(*url));
         if(conn == NULL)
         {
            // send service unavailable
            HttpResponseHeader* header = action->getResponse()->getHeader();
            header->setStatus(503, "Service Unavailable");
            string content =
               "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n"
               "<html><head>\n"
               "<title>503 Service Unavailable</title>\n"
               "</head><body>\n"
               "<h1>Service Unavailable</h1>\n"
               "<p>The service was not available.</p>\n"
               "</body></html>";
            ByteBuffer b(content.length());
            b.put(content.c_str(), content.length(), false);
            ByteArrayInputStream bais(&b);
            action->sendResult(&bais);
         }
         else
         {
            // proxy the client's request and receive server's header (by
            // writing it into the client's response header)
            HttpResponse* res = action->getResponse();
            if(_proxyHttp(req->getHeader(), req->getConnection(), conn) &&
               conn->receiveHeader(res->getHeader()))
            {
               // proxy the server's response, consider result sent
               _proxyHttp(res->getHeader(), conn, req->getConnection());
               action->setResultSent(true);
            }

            // close connection
            conn->close();

            // clean up
            delete conn;
         }

         if(!action->isResultSent())
         {
            // send exception (client's fault if code < 500)
            ExceptionRef e = Exception::get();
            action->sendException(e, e->getCode() < 500);
         }
      }
   }
}
示例#10
0
static int mod_ffeadcpp_method_handler (request_rec *r)
{
	string port = CastUtil::lexical_cast<string>(r->server->port);

	//signal(SIGSEGV,signalSIGSEGV);
	string content;

	apr_bucket_brigade *bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
	for ( ; ; ) {
		apr_bucket* b ;
		bool done = false;
		ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES, APR_BLOCK_READ, HUGE_STRING_LEN);
		for ( b = APR_BRIGADE_FIRST(bb);b != APR_BRIGADE_SENTINEL(bb);b = APR_BUCKET_NEXT(b) )
		{
			size_t bytes ;
			const char* buf = "\0";
			if ( APR_BUCKET_IS_EOS(b) )
			{
				done = true;
			}
			else if (apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ)== APR_SUCCESS )
			{
				content += string(buf, 0, bytes);
			}
		}

		if (done)
		  break;
		else
		  apr_brigade_cleanup(bb) ;
	}
	apr_brigade_destroy(bb) ;

	HttpRequest* hreq= new HttpRequest();
	string cntpath = serverRootDirectory + "web/";
	string webpath = "URL" + cntpath;
	MyReq* req = new MyReq();
	req->r = r;
	req->htreq = hreq;

	apr_table_do(iterate_func, req, r->headers_in, NULL);

	ip_address = hreq->getHeader(HttpRequest::Host);
	string tipaddr = ip_address;
	if(port!="80")
		tipaddr += (":" + port);
	ConfigurationData::getInstance()->ip_address = tipaddr;

	string contret;
	if(content!="")
	{
		contret = hreq->buildRequest("Content",content.c_str());
		fprintf(stderr,contret.c_str());
		fflush(stderr);
	}
	hreq->buildRequest(webpath.c_str(),r->uri);
	hreq->buildRequest("Method",r->method);
	if(r->args != NULL && r->args[0] != '\0')
	{
		hreq->buildRequest("GetArguments",r->args);
	}
	hreq->buildRequest("HttpVersion", r->protocol);

	HttpResponse respo = service(hreq);
	string h1 = respo.generateResponse(hreq->getMethod(), hreq, false);

	for (int var = 0; var < (int)respo.getCookies().size(); var++)
	{
		apr_table_add(r->headers_out, "Set-cookie", respo.getCookies().at(var).c_str());
	}

	r->status_line = respo.getStatusLine().c_str();
	if(respo.getHeader(HttpResponse::ContentType)!="")
	{
		r->content_type = respo.getHeader(HttpResponse::ContentType).c_str();
	}
	r->clength = h1.length();

	fprintf(stderr,"\n\n\n\n--------------------------------------------\n");
	fprintf(stderr,hreq->getUrl().c_str());
	fprintf(stderr,"\n");
	string star =  hreq->toString();
	fprintf(stderr,star.c_str());
	fprintf(stderr,"\n--------------------------------------------\n");
	fprintf(stderr,contret.c_str());
	fflush(stderr);
	fprintf(stderr,"\n\n");
	fprintf(stderr,content.c_str());
	fprintf(stderr,"\n");
	fprintf(stderr,"ip_address = %s", tipaddr.c_str());
	fprintf(stderr,"\n");
	fprintf(stderr,"\n--------------------------------------------\n\n\n\n");
	fflush(stderr);
	fprintf(stderr, h1.c_str());
	fflush(stderr);
	delete hreq;
	delete req;

	if(h1!="")
	{
		ap_rwrite (h1.c_str(), h1.length(), r);
		return OK;
	}
	return OK;
}
示例#11
0
void HttpConnectionServicer::serviceConnection(Connection* c)
{
   // wrap connection, set default timeouts to 30 seconds
   HttpConnection hc(c, false);
   hc.setReadTimeout(30000);
   hc.setWriteTimeout(30000);

   // monitor connection
   if(!mConnectionMonitor.isNull())
   {
      mConnectionMonitor->beforeServicingConnection(&hc);
   }

   // create request
   HttpRequest* request = hc.createRequest();
   HttpRequestHeader* reqHeader = request->getHeader();

   // create response
   HttpResponse* response = request->createResponse();
   HttpResponseHeader* resHeader = response->getHeader();

   // handle keep-alive (HTTP/1.1 keep-alive is on by default)
   bool keepAlive = true;
   bool noerror = true;
   while(keepAlive && noerror)
   {
      // set defaults
      resHeader->setVersion("HTTP/1.1");
      resHeader->setDate();
      resHeader->setField("Server", mServerName);

      // monitor request waiting
      if(!mConnectionMonitor.isNull())
      {
         mConnectionMonitor->beforeRequest(&hc);
      }

      // receive request header
      if((noerror = request->receiveHeader()))
      {
         // begin new request state
         hc.getRequestState()->beginRequest();

         // monitor received request
         if(!mConnectionMonitor.isNull())
         {
            mConnectionMonitor->beforeServicingRequest(
               &hc, request, response);
         }

         // do request modification
         if(mRequestModifier != NULL)
         {
            mRequestModifier->modifyRequest(request);
         }

         // check http version
         bool version10 = (strcmp(reqHeader->getVersion(), "HTTP/1.0") == 0);
         bool version11 = (strcmp(reqHeader->getVersion(), "HTTP/1.1") == 0);

         // only version 1.0 and 1.1 supported
         if(version10 || version11)
         {
            // set response version according to request version
            resHeader->setVersion(reqHeader->getVersion());

            // use proxy'd host field if one was used
            // else use host field if one was used
            string host;
            if(reqHeader->getField("X-Forwarded-Host", host) ||
               reqHeader->getField("Host", host))
            {
               resHeader->setField("Host", host);
            }

            // get connection header
            string connHeader;
            if(reqHeader->getField("Connection", connHeader))
            {
               if(strcasecmp(connHeader.c_str(), "close") == 0)
               {
                  keepAlive = false;
               }
               else if(strcasecmp(connHeader.c_str(), "keep-alive") == 0)
               {
                  keepAlive = true;
               }
            }
            else if(version10)
            {
               // if HTTP/1.0 and no keep-alive header, keep-alive is off
               keepAlive = false;
            }

            // get request path and normalize it
            const char* inPath = reqHeader->getPath();
            char outPath[strlen(inPath) + 2];
            HttpRequestServicer::normalizePath(inPath, outPath);

            // find appropriate request servicer for path
            HttpRequestServicer* hrs = NULL;

            // find secure/non-secure servicer
            hrs = findRequestServicer(host, outPath, hc.isSecure());
            if(hrs != NULL)
            {
               // service request
               hrs->serviceRequest(request, response);

               // turn off keep-alive if response has close connection field
               if(keepAlive)
               {
                  if(resHeader->getField("Connection", connHeader) &&
                     strcasecmp(connHeader.c_str(), "close") == 0)
                  {
                     keepAlive = false;
                  }
               }

               // if servicer closed connection, turn off keep-alive
               if(keepAlive && c->isClosed())
               {
                  keepAlive = false;
               }
            }
            else
            {
               // no servicer, so send 404 Not Found
               const char* html =
                  "<html><body><h2>404 Not Found</h2></body></html>";
               resHeader->setStatus(404, "Not Found");
               resHeader->setField("Content-Type", "text/html");
               resHeader->setField("Content-Length", 48);
               resHeader->setField("Connection", "close");
               if((noerror = response->sendHeader()))
               {
                  ByteArrayInputStream is(html, 48);
                  noerror = response->sendBody(&is);
               }
            }
         }
         else
         {
            // send 505 HTTP Version Not Supported
            const char* html =
               "<html><body>"
               "<h2>505 HTTP Version Not Supported</h2>"
               "</body></html>";
            resHeader->setStatus(505, "HTTP Version Not Supported");
            resHeader->setField("Content-Type", "text/html");
            resHeader->setField("Content-Length", 65);
            resHeader->setField("Connection", "close");
            if((noerror = response->sendHeader()))
            {
               ByteArrayInputStream is(html, 65);
               noerror = response->sendBody(&is);
            }
         }

         // monitor serviced request
         if(!mConnectionMonitor.isNull())
         {
            mConnectionMonitor->afterServicingRequest(
               &hc, request, response);
         }
      }
      else
      {
         // begin new request state
         hc.getRequestState()->beginRequest();

         // monitor request error
         if(!mConnectionMonitor.isNull())
         {
            mConnectionMonitor->beforeRequestError(
               &hc, request, response);
         }

         // exception occurred while receiving header
         ExceptionRef e = Exception::get();
         // if no header then drop through and close connection
         if(e->isType("monarch.http.NoHeader"))
         {
            keepAlive = false;
         }
         // for bad header or request set 400
         else if(e->isType("monarch.http.BadHeader") ||
            e->isType("monarch.http.BadRequest"))
         {
            // send 400 Bad Request
            const char* html =
               "<html><body><h2>400 Bad Request</h2></body></html>";
            response->getHeader()->setStatus(400, "Bad Request");
            response->getHeader()->setField("Content-Type", "text/html");
            response->getHeader()->setField("Content-Length", 50);
            response->getHeader()->setField("Connection", "close");
            if(response->sendHeader())
            {
               ByteArrayInputStream is(html, 50);
               response->sendBody(&is);
            }
         }
         // if the exception was an interruption, then send a 503
         else if(e->isType("monarch.io.InterruptedException") ||
                 e->isType("monarch.rt.Interrupted"))
         {
            // send 503 Service Unavailable
            const char* html =
               "<html><body><h2>503 Service Unavailable</h2></body></html>";
            resHeader->setStatus(503, "Service Unavailable");
            resHeader->setField("Content-Type", "text/html");
            resHeader->setField("Content-Length", 58);
            resHeader->setField("Connection", "close");
            if((noerror = response->sendHeader()))
            {
               ByteArrayInputStream is(html, 58);
               noerror = response->sendBody(&is);
            }
         }
         // if the exception was not a socket error then send an internal
         // server error response
         else if(!e->isType("monarch.net.Socket", true))
         {
            // send 500 Internal Server Error
            const char* html =
               "<html><body><h2>500 Internal Server Error</h2></body></html>";
            resHeader->setStatus(500, "Internal Server Error");
            resHeader->setField("Content-Type", "text/html");
            resHeader->setField("Content-Length", 60);
            resHeader->setField("Connection", "close");
            if((noerror = response->sendHeader()))
            {
               ByteArrayInputStream is(html, 60);
               noerror = response->sendBody(&is);
            }
         }
         else
         {
            // log socket error
            if(e->getDetails()->hasMember("error"))
            {
               // build error string
               string error;
               DynamicObjectIterator i =
                  e->getDetails()["error"].getIterator();
               while(i->hasNext())
               {
                  error.append(i->next()->getString());
                  if(i->hasNext())
                  {
                     error.push_back(',');
                  }
               }
               MO_CAT_ERROR(MO_HTTP_CAT,
                  "Connection error: ['%s','%s','%s']",
                  e->getMessage(), e->getType(), error.c_str());
            }
            else
            {
               MO_CAT_ERROR(MO_HTTP_CAT,
                  "Connection error: ['%s','%s']",
                  e->getMessage(), e->getType());
            }
         }

         // monitor request error
         if(!mConnectionMonitor.isNull())
         {
            mConnectionMonitor->afterRequestError(
               &hc, request, response, e);
         }
      }

      // monitor request
      if(!mConnectionMonitor.isNull())
      {
         mConnectionMonitor->afterRequest(&hc);
      }

      if(keepAlive && noerror)
      {
         // set keep-alive timeout (defaults to 5 minutes)
         hc.setReadTimeout(1000 * 60 * 5);

         // clear request and response header fields
         reqHeader->clearFields();
         resHeader->clearFields();
         resHeader->clearStatus();
      }
   }

   // clean up request and response
   delete request;
   delete response;

   // monitor connection
   if(!mConnectionMonitor.isNull())
   {
      mConnectionMonitor->afterServicingConnection(&hc);
   }

   // close connection
   hc.close();
}
示例#12
0
int main()
{
	#ifdef OS_MINGW
		// startup WinSock in Windows
		WSADATA wsa_data;
		WSAStartup(MAKEWORD(1,1), &wsa_data);
	#endif
	
	PropFileReader propFileReader;
	propMap props = propFileReader.getProperties("testValues.prop");

	CsvFileReader csvFileReader;
	strVecVec testCases = csvFileReader.getRows("test.csv");

	Timer timer, timerc;
	std::string cookies, result;
	int total, skipped = 0, passed = 0, failed = 0, header = 0, counter = 0;

	total = (int)testCases.size();

	std::string ip = props["SERVER_IP_ADDRESS"];
	if(ip=="")
		ip = "localhost";
	int port = 8080;
	if(props["SERVER_PORT"]!="")
	{
		try{
			port = CastUtil::lexical_cast<int>(props["SERVER_PORT"]);
		} catch(...) {
		}

	}
	bool sslEnabled = false;
	if(props["SERVER_SSL_ENABLED"]!="")
	{
		try{
			sslEnabled = CastUtil::lexical_cast<bool>(props["SERVER_SSL_ENABLED"]);
		} catch(...) {
		}
	}

	std::string sslFile = props["SERVER_SSL_FILE"];

	bool isDebug = false;
	if(StringUtil::toLowerCopy(props["DEBUG"])=="true") {
		isDebug = true;
	}

	std::cout << "Server IP - " << ip <<std::endl;
	std::cout << "Server Port - " << port <<std::endl;
	std::cout << "Debug Mode - " << isDebug <<std::endl;
	std::cout << "Server SSL Enabled - " << CastUtil::lexical_cast<std::string>(sslEnabled) <<std::endl;
	if(sslEnabled)
	{
		std::cout << "Server SSL File - " << sslFile <<std::endl;
	}

	timerc.start();
	for (int var = 0; var < total; ++var)
	{
		ClientInterface* client;
		if(sslEnabled)
		{
			if(sslFile!="")
				client = new SSLClient(sslFile);
			else
				client = new SSLClient;
		}
		else
			client = new Client;
		if(testCases[var].size()>=4)
		{
			if(testCases[var][0]=="ENABLED")
			{
				header++;
				continue;
			}
			counter = var;
			std::string request = testCases[var][2];
			if(testCases[var][0]=="N" || testCases[var][0]=="n")
			{
				std::cout << "Request " << counter << " " << request << " was Skipped" << std::endl;
				skipped++;
				continue;
			}

			bool debugCont = false;
			std::string debugContStr = testCases[var][1];
			if(debugContStr=="Y" || debugContStr=="y")
				debugCont = true;

			std::string responseCode = testCases[var][3];
			std::string file;
			if(testCases[var].size()>4)
				file = testCases[var][4];
			std::string fileCntlen;
			if(testCases[var].size()>5)
				fileCntlen = testCases[var][5];
			std::string reqContTyp, content, headers, respCntType;
			if(testCases[var].size()>6)
			{
				reqContTyp = testCases[var][6];
			}
			if(testCases[var].size()>7)
			{
				content = testCases[var][7];
			}
			if(testCases[var].size()>8)
			{
				headers = testCases[var][8];
				if(headers!="" && headers.find("HEADERVALS_")!=std::string::npos)
				{
					headers = props[headers];
				}
				else
				{
					std::vector<std::string> headerVec;
					StringUtil::split(headerVec, headers, ";");
					headers = "";
					for (int var = 0; var < (int)headerVec.size(); ++var) {
						std::vector<std::string> param;
						StringUtil::split(param, headerVec.at(var), "=");
						if(param.size()==2)
						{
							headers += param.at(0) + ": " + param.at(1) + "\r\n";
						}
					}
				}
			}
			if(testCases[var].size()>9)
			{
				respCntType = testCases[var][9];
			}

			std::string data = request;
			data += " HTTP/1.1\r\nHost: "+ip+":"+CastUtil::lexical_cast<std::string>(port)+"\r\nUser-Agent: Program\r\n";

			if(content!="" && content.find("TSTVALUES_")!=std::string::npos)
				content = props[content];

			if(reqContTyp!="")
			{
				data += "Content-Type: " + reqContTyp + "\r\n";
			}
			if(content.length()>0)
			{
				data += "Content-Length: " + CastUtil::lexical_cast<std::string>((int)content.length()) + "\r\n";
			}
			if(cookies!="")
			{
				data += "Cookie: " + cookies + "\r\n";
			}
			if(headers!="")
			{
				data += headers;
			}
			data += "\r\n";

			if(content!="")
			{
				data += content;
			}

			timer.start();

			if(isDebug) {
				std::cout << "HTTP Request Is=>\n" << data << "\n\n" << std::endl;
			}

			client->connectionUnresolv(ip,port);
			int bytes = client->sendData(data);
			std::string tot = client->getTextData("\r\n","content-length");
			long long millis = timer.elapsedMilliSeconds();

			if(isDebug) {
				std::cout << "HTTP Response Is=>\n" << tot << "\n\n" << std::endl;
			}

			HttpResponse res;
			HttpResponseParser parser(tot, res);

			if(res.getHeader("Set-Cookie")!="")
			{
				cookies = res.getHeader("Set-Cookie");
				cookies = cookies.substr(0, cookies.find(";"));
			}

			std::string debugContentValue;
			if(debugCont)
			{
				debugContentValue = ", Content => " + parser.getContent();
			}

			std::string ss;
			bool passedFlag = false, done = false;
			if(res.getStatusCode()==responseCode)
			{
				if(respCntType!="")
				{
					if(res.getHeader("Content-Type")==respCntType)
					{
						ss.clear();
						ss = "Test " + CastUtil::lexical_cast<std::string>(counter) + " " + request + " was Successfull, Response Time = " + CastUtil::lexical_cast<std::string>(millis) + "ms" + debugContentValue;
						passedFlag = true;
					}
					else
					{
						ss.clear();
						ss = "Test " + CastUtil::lexical_cast<std::string>(counter) + " " + request + " Failed, Response Time = " + CastUtil::lexical_cast<std::string>(millis) + "ms"
								+ ", Expected ContentType = " + respCntType + ", Actual ContentType = "  + res.getHeader("Content-Type");
						passedFlag = false;
					}
					done = true;
				}
				if(!done)
				{
					std::string cntlen = res.getHeader("Content-Length");
					if(file!="")
					{
						std::ifstream myfile (&file[0], std::ios::binary | std::ios::ate);
						if (myfile.is_open() && cntlen!="" && myfile.tellg()==CastUtil::lexical_cast<int>(cntlen))
						{
							ss.clear();
							ss = "Test " + CastUtil::lexical_cast<std::string>(counter) + " " + request + " was Successfull, Response Time = " + CastUtil::lexical_cast<std::string>(millis) + "ms" + debugContentValue;
							passedFlag = true;
						}
						else
						{
							ss.clear();
							ss = "Test " + CastUtil::lexical_cast<std::string>(counter) + " " + request + ", Invalid Content Length, Response Time = " + CastUtil::lexical_cast<std::string>(millis) + "ms" + debugContentValue;
							passedFlag = false;
						}
					}
					else if((file=="" && fileCntlen=="") || (fileCntlen!="" && fileCntlen==cntlen))
					{
						ss.clear();
						ss = "Test " + CastUtil::lexical_cast<std::string>(counter) + " " + request + " was Successfull, Response Time = " + CastUtil::lexical_cast<std::string>(millis) + "ms" + debugContentValue;
						passedFlag = true;
					}
					else
					{
						ss.clear();
						ss = "Test " + CastUtil::lexical_cast<std::string>(counter) + " " + request + ", Invalid Content Length, Response Time = " + CastUtil::lexical_cast<std::string>(millis) + "ms" + debugContentValue;
						passedFlag = false;
					}
				}
			}
			else
			{
				ss.clear();
				ss = "Test " + CastUtil::lexical_cast<std::string>(counter) + " " + request + " Failed, Response Time = " + CastUtil::lexical_cast<std::string>(millis) + "ms" + ", Expected Status = " +
						responseCode + ", Actual Status = "  + res.getStatusCode();
				passedFlag = false;
			}
			std::cout << ss << std::endl;
			if(passedFlag)
				passed++;
			else
				failed++;
		}
		else
		{
			skipped++;
		}
		if(client!=NULL)
		{
			client->closeConnection();
			delete client;
		}
	}

	std::cout << "Total Tests = " << total-1 << ", Passed = " << passed << ", Failed = " << failed
			<< ", Skipped = " << skipped << ", Time taken = " << timerc.elapsedMilliSeconds() << "ms" << std::endl;
	
	#ifdef OS_MINGW
		WSACleanup();
	#endif

	return 0;
}
示例#13
0
/**
 * A helper function that sends a soap envelope and gets its result.
 *
 * @param device the service to connect to.
 * @param service the service to use.
 * @param msg the soap message to send.
 * @param result the result to populate.
 *
 * @return true if successful, false if an exception occurred.
 */
static bool doSoap(
   Service& service, SoapMessage& msg, ActionResult& result)
{
   bool rval = false;

   // create the soap envelope
   SoapEnvelope env;
   string envelope = env.create(msg);
   if(envelope.length() > 0)
   {
      // get the control url for the service
      Url url;
      url.format("%s%s",
         service["rootURL"]->getString(),
         service["controlURL"]->getString());

      MO_CAT_DEBUG(MO_UPNP_CAT,
         "Sending SOAP message to url '%s':\n%s",
         url.toString().c_str(), envelope.c_str());

      // do http connection
      HttpClient client;
      if((rval = client.connect(&url)))
      {
         // create special headers
         DynamicObject headers;
         headers["Connection"] = "close";
         headers["Content-Length"] = (uint32_t)envelope.length();
         headers["Content-Type"] = "text/xml; charset=\"utf-8\"";
         headers["Soapaction"] = StringTools::format("\"%s#%s\"",
            service["serviceType"]->getString(),
            msg["name"]->getString()).c_str();

         // do post
         Url path(url.getPath());
         ByteArrayInputStream bais(envelope.c_str(), envelope.length());
         HttpResponse* response = client.post(&path, &headers, &bais);
         if((rval = (response != NULL)))
         {
            MO_CAT_DEBUG(MO_UPNP_CAT,
               "Received response header:\n%s",
               response->getHeader()->toString().c_str());

            // receive response
            ByteBuffer bb(1024);
            ByteArrayOutputStream baos(&bb, true);
            if((rval = client.receiveContent(&baos)))
            {
               MO_CAT_DEBUG(MO_UPNP_CAT,
                  "Received SOAP message:\n%s",
                  string(bb.data(), bb.length()).c_str());

               // parse soap response
               ByteArrayInputStream bais2(&bb);
               SoapResult sr;
               rval = env.parse(&bais2, sr);
               if(!rval)
               {
                  // failure to parse response
                  ExceptionRef e = new Exception(
                     "Could not parse soap response.",
                     "monarch.upnp.InvalidSoapResponse");
                  Exception::push(e);
               }
               else if(sr["fault"]->getBoolean())
               {
                  // soap fault received
                  ExceptionRef e = new Exception(
                     "Could not perform SOAP transfer. SOAP fault received.",
                     "monarch.upnp.SoapFault");
                  e->getDetails()["fault"] = sr["message"];
                  Exception::set(e);
                  rval = false;
                  result = sr;
               }
               else
               {
                  // return result as soap result
                  result = sr;
               }
            }
         }

         // disconnect
         client.disconnect();
      }
   }

   if(!rval)
   {
      MO_CAT_ERROR(MO_UPNP_CAT,
         "Could not perform SOAP transfer: %s",
         JsonWriter::writeToString(
            Exception::getAsDynamicObject()).c_str());
   }

   return rval;
}
示例#14
0
bool ControlPoint::getDescription(Url* url, string& description)
{
   bool rval = false;

   MO_CAT_DEBUG(MO_UPNP_CAT,
      "Getting UPnP description from url '%s'...",
      url->toString().c_str());

   // do http connection
   HttpClient client;
   if((rval = client.connect(url)))
   {
      // create special headers
      DynamicObject headers;
      headers["Connection"] = "close";

      // do get
      Url path(url->getPath());
      HttpResponse* response = client.get(&path, &headers);
      if((rval = (response != NULL)))
      {
         MO_CAT_DEBUG(MO_UPNP_CAT,
            "Get UPnP description response header:\n%s",
            response->getHeader()->toString().c_str());

         // receive response
         ByteBuffer bb(2048);
         ByteArrayOutputStream baos(&bb, true);
         if((rval = client.receiveContent(&baos)))
         {
            MO_CAT_DEBUG(MO_UPNP_CAT,
               "Get UPnP description response body:\n%s",
               string(bb.data(), bb.length()).c_str());
            if(response->getHeader()->getStatusCode() < 400)
            {
               // get description
               description.erase();
               description.append(bb.data(), bb.length());
            }
            else
            {
               // error getting description
               ExceptionRef e = new Exception(
                  "HTTP transmission error.",
                  "monarch.upnp.HttpError");
               e->getDetails()["statusMessage"] =
                  response->getHeader()->getStatusMessage();
               e->getDetails()["statusCode"] =
                  response->getHeader()->getStatusCode();
            }
         }
      }

      // disconnect
      client.disconnect();
   }

   if(!rval)
   {
      MO_CAT_ERROR(MO_UPNP_CAT,
         "Failed to get UPnP description from url '%s': %s",
         url->toString().c_str(),
         JsonWriter::writeToString(
            Exception::getAsDynamicObject()).c_str());
   }

   return rval;
}