Как получить данные из http запроса в Java

Сервис по этому URL

http://www.free-kassa.ru/api.php?merchant_id=136624&s=a44405c624c12047dd9d4e7dc5d08a24&action=get_balance 

Возвращает такой XML

<?xml version="1.0" encoding="UTF-8" ?> <root>     <answer>info</answer>     <desc>Merchant balance</desc>     <balance>0.00</balance> </root> 

Мне нужно из него вытащить значение 0. Подскажите, пожалуйста, как это сделать с помощью http запроса в Java?

String url = "http://www.free-kassa.ru/api.php";  URL obj = new URL(url); HttpURLConnection connection = (HttpURLConnection) obj.openConnection();  connection.setRequestMethod("GET");  BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); String inputLine; StringBuffer response = new StringBuffer();  while ((inputLine = in.readLine()) != null) {             response.append(inputLine); } in.close(); 

Мучаюсь уже пару часов, не могу найти ответ.

Apache2 Vhost HTTP to HTTPS Redirect not working in a strange way

I set up HTTPS for my website for the first time today. I started with the following code:

<VirtualHost *:443>     ServerName website.tld     DocumentRoot /var/www/website.tld      SSLEngine on     SSLCertificateFile /etc/apache2/ssl/website.tld.crt     SSLCertificateKeyFile /etc/apache2/ssl/website.tld.key      ErrorLog $  {APACHE_LOG_DIR}/error.log     CustomLog $  {APACHE_LOG_DIR}/access.log combined      <Directory /var/www/website.tld/>             Options Indexes FollowSymLinks MultiViews             AllowOverride All             Order allow,deny             allow from all         </Directory> </VirtualHost> 

which totally worked fine. Now I wanted the website to redirect http to https and added the following at the top:

<VirtualHost *:80>     ServerName website.tld     ServerAlias www.website.tld     Redirect 301 / https://website.tld </VirtualHost>  <VirtualHost *:443>      ServerName www.website.tld      Redirect 301 / https://website.tld </VirtualHost> 

Now if I access the website from http it redirects to https, BUT once I’m on the https site I get an error from Chrome saying “ERR_SSL_PROTOCOL_ERROR”. Can somebody help?

Putting a Queue Between HTTP Request/Response

We currently have two legacy systems: the Consumer and the Worker. These systems are massively complex in ways that are not important to this review, but it is enough to say that a large-scale re-development of these systems is not currently possible.

The Consumer communicates with the Worker via http request/response. The request/response nature of this setup is critical and non-negotiable; this is really the whole purpose of this review. There is no opportunity to use (for example) notifications or events to solve this problem. The Worker’s task of processing the request may be long (or longish) running, and returns a response when complete.

So the current state could not be simpler:

1. Consumer sends a request to the Worker via POST 2. Worker receives the request and does the necessary work 3. Worker returns a response to the Consumer 

Now, the problem: the actual work that the Worker does has resource constraints, and allowing an unlimited number of “jobs” to be processed concurrently is problematic. What we need to do is introduce a way to queue up requests and feed them to the Worker in a measured, predictable way.

Our solution is to introduce a “Queue Service” in between the Consumer and the Worker. This will be a physical, singular service that acts as a pass-through, with its only other responsibility being to manage the Worker’s load.

The actual implementation of the queuing mechanism is not important for this question, but a few important requirements:

1. The Queue Service will consist of custom code to queue, prioritize and feed the work to the Worker (out-of-box solutions like Gateways are not viable options). 2. The Queue Service will be asynchronous to avoid thread starvation when there are many http requests in flight. 

So the desired state would be:

1. Consumer sends a request to the Queue Service via POST 2. Queue Service receives the request 3. Queue Service sends a request to the Worker via POST (immediately or delayed depending on the state of the queue)  4. Worker receives the request and does the necessary work 5. Worker returns a response to the Queue Service 6. Queue Service returns a response to the Consumer 

To be clear, the idea is that the request remains active even if the work gets put into queue and has to wait.

In the code below, I am trying to prove that this is possible by signaling using the TaskCompletionSource construct. There are all kinds of shortcuts/simplifications in this code–the main question is whether this technique is viable to keep the request alive until a separate process signals its completion (and provides a result).

[TestFixture] public class ValidateAsyncContinuation {     [Test]     public async Task RunAsync()     {         //start this as a background task (fire and forget)         PretendQueueReader.StartProcessing();          var sw = Stopwatch.StartNew();          const int feedDelayInMs = 1;         const int numToProcess = 1000;          var tasks = new List<Task>();          //this simulates x number of requests sent via http and waiting for a response, spaced out by a 1ms delay         for (var x = 0; x < numToProcess; x++)         {             var x1 = x; //to avoid "access to modified closure" warning             var task = Task.Run(async () =>             {                 await PretendController.Post(new Request($  "request {x1}"), x1);                 Debug.WriteLine($  "Completed {x1}.");             });             tasks.Add(task);             Thread.Sleep(feedDelayInMs);         }          await Task.WhenAll(tasks);         Debug.WriteLine($  "took {sw.ElapsedMilliseconds}ms");         PretendQueueReader.Stop();     } }  //background process that periodically tells the PretendQueue to check to see if there is work to be done public static class PretendQueueReader {     private static bool _stop;      public static async Task StartProcessing()     {         while (!_stop)         {             await PretendQueue.ProcessQueue();             await Task.Delay(1); //run every 1ms.  Not having any delay spikes the CPU.         }     }      public static void Stop()     {         _stop = true;     } }  public static class PretendController {     //the controller passes the request along to the queue and waits for a response     public static async Task<Response> Post(Request request, int index)     {         return await PretendQueue.QueueRequest(request, index);     } }  public static class PretendQueue {     private static readonly Queue<RequestCompletion> Queue = new Queue<RequestCompletion>();     private static int _inProcess;     private const int MaxConcurrent = 100;     private static readonly SemaphoreSlim SemaphoreSlim = new SemaphoreSlim(1,1);      public static async Task<Response> QueueRequest(Request request, int index)     {         var responseSignal = new TaskCompletionSource<Response>();          //lock the queue when accessing and release when complete.         await SemaphoreSlim.WaitAsync();         try         {             Queue.Enqueue(new RequestCompletion(request, responseSignal));             Debug.WriteLine($  "Queuing Request #{index}:  {_inProcess} requests are in process and {Queue.Count} requests are in queue.");         }         finally         {             SemaphoreSlim.Release();         }          return await responseSignal.Task;     }      public static async Task ProcessQueue()     {         RequestCompletion requestCompletion;         //lock the queue when accessing and release when complete.         await SemaphoreSlim.WaitAsync();         try         {             if (Queue.Count == 0 || _inProcess >= MaxConcurrent) return;             Debug.WriteLine($  "DE-Queuing a Request:  {_inProcess} requests are in process and {Queue.Count} requests are in queue.");             requestCompletion = Queue.Dequeue();         }         finally         {             SemaphoreSlim.Release();         }          //fire and forget         Run(requestCompletion.Request, requestCompletion.ResponseCompletionSource);     }      private static async Task<Response> Run(Request request, TaskCompletionSource<Response> responseSignal)     {         await SemaphoreSlim.WaitAsync();         _inProcess++;         SemaphoreSlim.Release();          //Fire and forget.         PretendWorker.ProcessAndSignal(request, responseSignal);          var response = await responseSignal.Task;          await SemaphoreSlim.WaitAsync();         _inProcess--;         SemaphoreSlim.Release();          return response;     } }  public static class PretendWorker {     public static async Task ProcessAndSignal(Request request, TaskCompletionSource<Response> responseCompletionSource)     {         var start = DateTime.Now;          //this simulates the call to the worker (taking 2 seconds)         await Task.Delay(TimeSpan.FromSeconds(2));          responseCompletionSource.SetResult(new Response(start, DateTime.Now));     } }  public class RequestCompletion {     public RequestCompletion(Request request, TaskCompletionSource<Response> responseCompletionSource)     {         Request = request;         ResponseCompletionSource = responseCompletionSource;     }      public Request Request { get; }     public TaskCompletionSource<Response> ResponseCompletionSource { get; } }  public class Request {     public Request(string name)     {         Name = name;     }      public string Name { get; } }  public class Response {     public Response(DateTime startedTime, DateTime completedTime)     {         StartedTime = startedTime;         CompletedTime = completedTime;     }      public DateTime StartedTime { get; }     public DateTime CompletedTime { get; } } 

HTTP doesn’t work in OpenVPN, other protocols does

I’ve set up iptables rules on OpenVPN network server, to forward client traffic to internet. According to traceroute output, ICMP traffic goes through VPN server, and then to the desired website (e.g. google.com). TCP and UDP connections work, but HTTP doesn’t. When I try to download HTML document with wget command, it connects to the HTTP server, but waits infinite and doesn’t receive any response. Here are iptables rules on server:

    Chain INPUT (policy ACCEPT)     target     prot opt source               destination               Chain FORWARD (policy DROP)     target     prot opt source               destination              ACCEPT     all  --  10.8.0.0/24          anywhere                 ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED      Chain OUTPUT (policy ACCEPT)     target     prot opt source               destination  --- NAT rules ----- Chain PREROUTING (policy ACCEPT) target     prot opt source               destination           Chain INPUT (policy ACCEPT) target     prot opt source               destination           Chain OUTPUT (policy ACCEPT) target     prot opt source               destination           Chain POSTROUTING (policy ACCEPT) target     prot opt source               destination          MASQUERADE  all  --  anywhere             anywhere  

Wget output:

    --2019-04-23 10:54:27--  https://google.com/     Resolving google.com (google.com)... 172.217.20.174, 2a00:1450:401b:802::200e     Connecting to google.com (google.com)|172.217.20.174|:443... connected. (Waits infinite) 

Client’s iptables rules are default. I’ve found out that the only website I can connect to is example.com (however it isn’t because of HTTP instead of HTTPS, I can’t connect to both HTTP and HTTPS servers). What are the possible causes of this situation?

HTTP doesn’t work in OpenVPN, other protocols does

I’ve set up iptables rules on OpenVPN network server, to forward client traffic to internet. According to traceroute output, ICMP traffic goes through VPN server, and then to the desired website (e.g. google.com). TCP and UDP connections work, but HTTP doesn’t. When I try to download HTML document with wget command, it connects to the HTTP server, but waits infinite and doesn’t receive any response. Here are iptables rules on server:

    Chain INPUT (policy ACCEPT)     target     prot opt source               destination               Chain FORWARD (policy DROP)     target     prot opt source               destination              ACCEPT     all  --  10.8.0.0/24          anywhere                 ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED      Chain OUTPUT (policy ACCEPT)     target     prot opt source               destination  --- NAT rules ----- Chain PREROUTING (policy ACCEPT) target     prot opt source               destination           Chain INPUT (policy ACCEPT) target     prot opt source               destination           Chain OUTPUT (policy ACCEPT) target     prot opt source               destination           Chain POSTROUTING (policy ACCEPT) target     prot opt source               destination          MASQUERADE  all  --  anywhere             anywhere  

Wget output:

    --2019-04-23 10:54:27--  https://google.com/     Resolving google.com (google.com)... 172.217.20.174, 2a00:1450:401b:802::200e     Connecting to google.com (google.com)|172.217.20.174|:443... connected. (Waits infinite) 

Client’s iptables rules are default. I’ve found out that the only website I can connect to is example.com (however it isn’t because of HTTP instead of HTTPS, I can’t connect to both HTTP and HTTPS servers). What are the possible causes of this situation?

HTTP 500, el codigo PHP no es capaz de ser ejecutado

Estoy creando un codigo de formulario con un POST con animo de aprender, el formulario esta funcionando correctamente pero una vez los datos se han pasado al POST el codigo PHP no llega a ejecutarse dando un error 500. He hecho un par de pruebas mediante echos y el codigo funciona bien hasta la insercion en el mysql.

<?php        session_start();       $  con=mysqli_connect("localhost","root","pass","tabla");       if (isset($  _POST['empresa']) && isset($  _POST['per_contacto']) && isset($  _POST['tel_contacto']) && isset($  _POST['email']) && isset($  _POST['hor_disp_inicio']) && isset($  _POST['hor_disp_final'])          && isset($  _POST['numero_serie']) && isset($  _POST['modelo_maquina']) && isset($  _POST['ip_maquina']) && isset($  _POST['comentario'])){          $  empresa = $  _POST['empresa'];         $  per_contacto = $  _POST['per_contacto'];         $  tel_contacto = $  _POST['tel_contacto'];         $  email = $  _POST['email'];         $  hor_disp_inicio = $  _POST['hor_disp_inicio'];         $  hor_disp_final = $  _POST['hor_disp_final'];         $  lunes = $  _POST['lunes'];         $  martes = $  _POST['martes'];         $  miercoles = $  _POST['miercoles'];         $  jueves = $  _POST['jueves'];         $  viernes = $  _POST['viernes'];         $  numero_serie = $  _POST['numero_serie'];         $  modelo_maquina = $  _POST['modelo_maquina'];         $  ip_maquina = $  _POST['ip_maquina'];         $  comentario = $  _POST['comentario'];          $  sql = "INSERT INTO tabla(empresa, per_contacto, tel_contacto, email, hor_disp_inicio, hor_disp_final, numero_serie, modelo_maquina, ip_maquina,comentario) values ('$  empresa', '$  per_contacto', '$  tel_contacto', '$  email', '$  hor_disp_inicio', '$  hor_disp_final, '$  lunes', '$  martes', '$  miercoles',  '$  jueves, '$  viernes', '$  numero_serie', '$  modelo_maquina', '$  numero_serie', '$  ip_maquina', '$  comentario')";             $  query = $  bdd->prepare( $  sql );         if ($  query == false) {          print_r($  bdd->errorInfo());          die ('Erreur prepare');         }         $  sth = $  query->execute();         if ($  sth == false) {          print_r($  query->errorInfo());          die ('Erreur execute');       } else {        echo "Not found";        }     }      ?> 

Does HTTP:// to HTTPS:// redirection means strict HTTPS from server

when I try to connect to some websites using http:// (notice the absence of s) , my client end up with https://.

I use python requests for this purpose, which simulate a client behavior. It performs the redirection and show me the final URL after redirection, if any.

Example: when I input http://facebook.com the get requets end up at https://facebook.com.

Does this mean the website DOES NOT accept http:// requests?

How set person field in Flow: Send HTTP Request to SharePoint

I’ve been playing with Flow: Send HTTP Request to SharePoint to create items in a list. Everything works great until I include the Person field: Assigned To.

error 400: A ‘PrimitiveValue’ node with non-null value was found when trying to read the value of a navigation property

Tried claims, display name, email…

enter image description here

Looking at the list item XML I see Assigned_x0020_ToId, so I guess I need to pass the numeric ID of the person. Do I need a step prior to resolve the user or look up their id?

Once I figure out this issue I would like to move on to something more advanced, like creating a list item for each person in a multiple person column…

enter image description here

FYI, I would have just used the available Create Item but Flow seems to ignore site column lookups.

Simple Http Server

I’m working on a project (studying) and I have a lot of time for proof of concepts and write something from scratch.

Basically I’m creating a Http Server (simple, but not too simple) in C++ using sockets and multi-threading.

There are two topics that I’m concerned about: the design pattern of my code structure and the efficiency of my thread implementation. Obs: a little worried about C++ best practices, since I’m diving too fast into C++ (Am I abusing of std items?, since this require a low-level implementation).

Server is the main file, that calls Routes, Request and Response. Request and Response contains Struct (that contains Status Code). And Routes contains Request and Response.

IMPORTANT: I’m using nlohmann/json (https://github.com/nlohmann/json) and j-ulrich status-codes (https://github.com/j-ulrich/http-status-codes-cpp).

Server (Accepting Sockets and Multi-threading):


#pragma once  #include <unistd.h> #include <stdio.h> #include <sys/socket.h> #include <stdlib.h> #include <netinet/in.h> #include <string.h> #include <iostream> #include <unordered_map> #include <thread> #include <mutex> #include <condition_variable>  #include "Server/Request.h" #include "Server/Response.h" #include "Server/Struct.h" #include "Server/Routes.h" #include "Tools/Logger.h"  class Server {     public:         Server(unsigned int port, unsigned int max_connections = 64, unsigned int thread_count = 5);         ~Server();          bool setRoute(std::string path, Struct::Methods method, void (*callback)(Request*, Response*));         bool doListen();         bool doStop();      private:         unsigned int _port;         unsigned int _max_connections;         unsigned int _thread_count;          std::mutex _mutex;         std::condition_variable _condition;          bool _signal;          std::vector<unsigned int> _queue;          std::thread* _thread_consume;         std::thread* _thread_process;          Routes* _routes;          int _socket;         struct sockaddr_in _address;         bool _listen;          bool _doStop();         bool _doCreateSocket(int& socket_in);         bool _doBindSocket(int file_descriptor);         void _doConsumeSocket();         void _doProcessSocket(int id);         bool _doProcessRequest(Request* request, Response* response); }; 

#include "Server/Server.h"  Server::Server(unsigned int port, unsigned int max_connections, unsigned int thread_count) {     if (port > 65535) {         Logger::doSendMessage(Logger::TYPES::ERROR, "[Port must be something between 0 and 65535 on Server::Constructor.");     }      if (max_connections < 1) {         Logger::doSendMessage(Logger::TYPES::ERROR, "Max connections can't be lower than 1 on Server::Constructor.");     }      _port = port;     _max_connections = max_connections;     _thread_count = thread_count;      _routes = new Routes();      int status = _doCreateSocket(_socket);     if (!status) {         Logger::doSendMessage(Logger::TYPES::ERROR, "Failed to create socket on Server::Constructor.");     }      if (!_doBindSocket(_socket)) {         Logger::doSendMessage(Logger::TYPES::ERROR, "Failed to bind socket on Server::Constructor.");     };      _signal = false;     _listen = false; }  Server::~Server() {     _doStop();      shutdown(_socket, SHUT_RD);     close(_socket);      try {         _thread_consume->join();         for (size_t i = 0; i < _thread_count; i++) {             _thread_process[i].join();         }     } catch (...) {}      delete _thread_consume;     delete[] _thread_process;     delete _routes; }  bool Server::setRoute(std::string path, Struct::Methods method, void (*callback)(Request*, Response*)) {     return _routes->setRoute(path, method, callback); }  bool Server::doListen() {     if (_listen) return false;      int status;      status = listen(_socket, _max_connections);     if (status < 0) return false;      Logger::doSendMessage(Logger::TYPES::INFO, "Server running with success at port " + std::to_string(_port) + ".");      _listen = true;      _thread_consume = new std::thread(&Server::_doConsumeSocket, this);     _thread_process = new std::thread[_thread_count];     for (size_t i = 0; i < _thread_count; i++) {         _thread_process[i] = std::thread(&Server::_doProcessSocket, this, i);     }      return true; }  bool Server::doStop() {     return _doStop(); }  bool Server::_doStop() {     if (!_listen) return false;     {         std::lock_guard<std::mutex> lock(_mutex);         _listen = false;     }     _condition.notify_one();     return true; }  bool Server::_doCreateSocket(int& socket_in) {     int file_descriptor = socket(AF_INET, SOCK_STREAM, 0);     if (file_descriptor == 0) return false;      int error;     int opt = 1;      error = setsockopt(file_descriptor, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt));     if (error) return false;      socket_in = file_descriptor;     return true; }  bool Server::_doBindSocket(int file_descriptor) {     if (!file_descriptor) return false;      _address.sin_family = AF_INET;     _address.sin_addr.s_addr = INADDR_ANY;     _address.sin_port = htons(_port);      int status;      status = bind(file_descriptor, (struct sockaddr*) &_address, sizeof(_address));     if (status < 0) return false;      return true; }  void Server::_doConsumeSocket() {     int socket_in;     int address_size = sizeof(_address);      while (_listen) {         socket_in = accept(_socket, (struct sockaddr*) &_address, (socklen_t*) &address_size);         if (socket_in < 0) continue;          {             std::lock_guard<std::mutex> lock(_mutex);             _queue.push_back(socket_in);             _signal = true;         }          _condition.notify_one();     } }  void Server::_doProcessSocket(int id) {     while (_listen) {         int queue_size = 0;          {             std::unique_lock<std::mutex> lock(_mutex);             _condition.wait(lock,                 [this] {                     if (this->_signal) return true;                     if (!this->_listen && !this->_queue.size()) return true;                     return false;                 }             );             queue_size = _queue.size();         }          if (!queue_size) {             {                 std::lock_guard<std::mutex> lock(_mutex);                 _signal = false;             }              _condition.notify_one();             continue;         }          int socket_in = 0;         {             std::lock_guard<std::mutex> lock(_mutex);             socket_in = _queue[0];             _queue.erase(_queue.begin());         }          Request* request = new Request(socket_in);         Response* response = new Response(socket_in);          int status = _doProcessRequest(request, response);          delete request;         delete response;         close(socket_in);     } }  bool Server::_doProcessRequest(Request* request, Response* response) {     if (!request->isValid()) {         response->doSendError(HttpStatus::Code::BadRequest, "Invalid request.");         return false;     }      std::string path = request->getPath();     Struct::Methods method = request->getMethod();      Routes::Route route;     if (!(_routes->getRoute(path, method, route) && route.isValid())) {         response->doSendError(HttpStatus::Code::Forbidden, "Path invalid/not found.");         return false;     }      if (route.method != method) {         response->doSendError(HttpStatus::Code::MethodNotAllowed, "Method invalid/not found.");         return false;     }      void (*callback)(Request*, Response*) = route.callback;     callback(request, response);      if (!response->isSent()) {         response->doSendError(HttpStatus::Code::ServiceUnavailable, "Resource was not found or can't respond now.");     }      return true; } 

Request (parsing) and Response (sending)


Request

#pragma once  #include <unistd.h> #include <string.h> #include <iostream> #include <string> #include <vector> #include <unordered_map> #include <regex> #include <json.hpp>  #include "Server/Struct.h"  using json = nlohmann::json;  class Request {     public:         Request(int socket, unsigned int buffer_size = 1024);         ~Request();          bool isValid();         std::string getPath() {return _attributes.path;}         Struct::Methods getMethod() {return _attributes.method;}         std::unordered_map<std::string, std::string> getHeaders() {return _attributes.headers;}         std::string getHeader(std::string header) {return _attributes.headers[header];}         json getBody() {return _attributes.body;}      private:         int _socket;         unsigned int _buffer_size;         std::string _data;         Struct::Attributes _attributes;         bool _status;          std::string _doReceiveData(int sock_in);         bool _doParseData(std::string data, Struct::Attributes& attributes);         std::vector<std::string> _doSplitText(std::string text, std::string delimiter);         std::vector<std::string> _doSplitText(std::string text, std::string delimiter, int lock); }; 

Request::Request(int socket, unsigned int buffer_size) {     _socket = socket;     _buffer_size = buffer_size;     _status = false;      _data = _doReceiveData(_socket);     if (!_data.length()) return;      bool result;     result = _doParseData(_data, _attributes);      if (!result) return;     if (!_attributes.isValidRequest()) return;      _status = true; }  Request::~Request() {  }  bool Request::isValid() {     return _status; }  std::string Request::_doReceiveData(int sock_in) {     char* buffer = new char[_buffer_size];     memset(buffer, '', _buffer_size);     read(sock_in, buffer, _buffer_size);      std::string data;     data.assign(buffer);     delete[] buffer;     return data; }  bool Request::_doParseData(std::string data, Struct::Attributes& attributes) {     std::string delimiter = "\r\n";     std::vector<std::string> rows = _doSplitText(data, delimiter);     if (!rows.size()) return false;      std::string header = rows[0];     rows.erase(rows.begin());      if (!header.length()) return false;      std::vector<std::string> parsed_header = _doSplitText(header, std::string(" "));     if (parsed_header.size() < 2) return false;      Struct::Methods method = Struct::doParseHttpMethod(parsed_header[0]);     if (method == Struct::Methods::NONE) return false;      std::string path = parsed_header[1];      std::unordered_map<std::string, std::string> headers;     for (size_t i = 0; i < rows.size(); i++) {         std::string row = rows[i];         delimiter = ":";          std::vector<std::string> splited = _doSplitText(row, delimiter, true);         if (splited.size() != 2) continue;          headers[splited[0]] = splited[1];     }      _attributes.method = method;     _attributes.path = path;     _attributes.headers = headers;      std::string content_length = headers["Content-Length"];     int content_size = 0;      if (content_size = atoi(content_length.c_str())) {         std::string body = data.substr(data.length() - content_size, data.length());         json parsed_body = json::parse(body, nullptr, false);         if (parsed_body != NULL && !parsed_body.is_discarded()) _attributes.body = parsed_body;     }      return true; }  std::vector<std::string> Request::_doSplitText(std::string text, std::string delimiter) {     std::vector<std::string> result;     int delimiter_length = delimiter.length();      std::string block;     std::string region;     int index = 0;      for (size_t i = 0; i < text.length(); i++) {         block = text.substr(i, delimiter_length);         if (block.length() != delimiter_length) continue;          if (block == delimiter) {             region = text.substr(index, i - index);             result.push_back(region);             index = i + delimiter_length;         }     }      return result; }  std::vector<std::string> Request::_doSplitText(std::string text, std::string delimiter, int lock) {     ... } 

Response

#pragma once  #include <unistd.h> #include <iostream> #include <string> #include <unordered_map>  #include "Server/Struct.h"  class Response {     public:         Response(int socket_in);         ~Response();          bool isSent() {return _sent;}         void setCode(HttpStatus::Code code) {_attributes.code = code;}         void setHeader(std::string key, std::string value) {_attributes.headers[key] = value;}         void setBody(json body) {_attributes.body = body;}         void doClearHeaders() {_attributes.headers.clear();}         void doClearBody() {_attributes.body = json::value_t::object;}          bool doSendSuccess();         bool doSendError(HttpStatus::Code code, const std::string& message);      private:         int _socket;         bool _sent;          Struct::Attributes _attributes;          bool _doSendPayload();         bool _doCreatePayload(std::string& payload); }; 

#include "Response.h"  Response::Response(int socket_in) {     _socket = socket_in;     _sent = false; }  Response::~Response() {  }  bool Response::doSendSuccess() {     setCode(HttpStatus::Code::OK);     setHeader("Connection", "Closed");     return _doSendPayload(); }  bool Response::doSendError(HttpStatus::Code code, const std::string& message) {     setCode(code);     doClearHeaders();     doClearBody();      setHeader("Connection", "Closed");      json body;     body["error"] = {};     body["error"]["code"] = code;     body["error"]["message"] = message;      setBody(body);     return _doSendPayload(); }  bool Response::_doSendPayload() {     if (_sent) return false;      int status;      setHeader("Server", "Dark");     setHeader("Content-Type", "application/json");      std::string payload;     status = _doCreatePayload(payload);     if (!status) return false;      status = write(_socket, payload.c_str(), payload.size());     if (status < 1) return false;      _sent = true;     return true; }  bool Response::_doCreatePayload(std::string& payload) {     std::string current_payload;     std::string data = _attributes.body.dump(4);      int data_length = data.size();      if (data_length) {         _attributes.headers["Content-Length"] = std::to_string(data_length);     }      current_payload += _attributes.version + " " + std::to_string((int) _attributes.code) + " " + HttpStatus::getReasonPhrase(_attributes.code) + "\r\n";      std::unordered_map<std::string, std::string>::iterator iterator;     for (iterator = _attributes.headers.begin(); iterator != _attributes.headers.end(); iterator++){         std::string key = iterator->first;         std::string value = iterator->second;          current_payload += key + ": " + value + "\r\n";     }      if (data_length) current_payload += "\r\n" + data + "\r\n\r\n";      payload = current_payload;     return true; } 

Routes


#pragma once  #include <iostream> #include <string> #include <vector>  #include "Server/Request.h" #include "Server/Response.h"  class Routes {     public:         Routes();         ~Routes();          struct Route {             std::string path;             Struct::Methods method;             void (*callback)(Request*, Response*);              bool isValid() {                 if (!path.length()) return false;                 if (method < Struct::Methods::FIRST || method > Struct::Methods::LAST) return false;                 if (callback == nullptr) return false;                 return true;             }         };          bool setRoute(std::string path, Struct::Methods method, void (*callback)(Request*, Response*));         bool getRoute(std::string path, Struct::Methods method, Route& route);      private:         std::vector<Route> _routes;          int _getRouteIndex(std::string path, Struct::Methods method); }; 

#include "Routes.h"  Routes::Routes() {  }  Routes::~Routes() {  }  bool Routes::setRoute(std::string path, Struct::Methods method, void (*callback)(Request*, Response*)) {     if (path.length() < 1) return false;     if (_getRouteIndex(path, method) >= 0) return false;     if (method < Struct::Methods::FIRST || method > Struct::Methods::LAST) return false;     if (callback == nullptr) return false;      Routes::Route route = {path, method, callback};     _routes.push_back(route);     return true; }  bool Routes::getRoute(std::string path, Struct::Methods method, Routes::Route& route) {     int index = _getRouteIndex(path, method);     if (index < 0) return false;     route = _routes[index];     return true; }  int Routes::_getRouteIndex(std::string path, Struct::Methods method) {     for (size_t i = 0; i < _routes.size(); i++) {         Route* route = &_routes[i];         if (route->path == path && route->method == method) {             return i;         }     }     return -1; } 

Struct and StatusCode


StatusCode

https://github.com/j-ulrich/http-status-codes-cpp

Struct

#pragma once  #include <json.hpp>  #include "Server/StatusCode.h"  using json = nlohmann::json;  class Struct {     public:         enum class Methods {             NONE = 0, GET = 1, POST = 2, FIRST = GET, LAST = POST         };          struct Attributes {             const std::string version = "HTTP/1.1";              std::string path;             Methods method;             HttpStatus::Code code;             std::unordered_map<std::string, std::string> headers;             json body;              Attributes() {                 code = HttpStatus::Code::InternalServerError;                 body = json::value_t::object;             }              bool isValidRequest() {                 if (!path.length()) return false;                 if (method < Methods::FIRST || method > Methods::LAST) return false;                 if (!headers.size()) return false;                 return true;             }              bool isValidResponse() {                 if (!headers.size()) return false;                 return true;                 }         };          static Methods doParseHttpMethod(std::string value) {             Methods target = Methods::NONE;              if (value == "GET") target = Methods::GET;             if (value == "POST") target = Methods::POST;              return target;         }      private: }; 

Main (usage):


#include "Server/Server.h"  void exec(Request* request, Response* response) {     json body;      body["foo"] = 123;     body["bar"] = true;      response->setBody(body);     response->doSendSuccess(); }  int main(int argc, char* argv[]) {     Server* server = new Server(5000);     server->setRoute("/getStatus", Struct::Methods::GET, exec);     server->setRoute("/postStatus", Struct::Methods::POST, exec);     server->doListen();      // let threads live for some time before they eternaly be gone     /*        actually I'm stuck with this sleep, I don't know how to hold         this until caller call doStop() without using while and        consuming process power     */     sleep(30);      delete server;     return 1; } 

Basically I’m mirroring NodeJS express API Usage: server.setRoute(path, route, callback);

So, what can be done to improve my code in terms of optimization and efficiency?

Thanks in advance.