Bredbandskollen CLI  1.2
Asynchronous network task engine
httprequestengine.h
1 // Copyright (c) 2018 IIS (The Internet Foundation in Sweden)
2 // Written by Göran Andersson <initgoran@gmail.com>
3 
4 #pragma once
5 
6 #include <queue>
7 #include <vector>
8 #include <map>
9 #include <set>
10 #include <functional>
11 
12 #include "httpclienttask.h"
13 
15  const std::string &url;
16  unsigned int http_status;
17  const std::string &response;
18 };
19 
21 public:
22  HttpRequestEngine(const std::string &name, const HttpHost &host,
23  unsigned int min_conn = 0, unsigned int max_conn = 10,
24  double tick_duration = 0.5) :
25  HttpClientTask(name, host),
26  min_connections(std::min(min_conn, max_conn)),
27  max_connections(max_conn),
28  no_connections(min_connections),
29  active_connections(0),
30  tick(tick_duration > 0.0 ? tick_duration : 0.5) {
31  }
32 
33  // Will call task's handleExecution when done, if task has told me to
34  // observe it. I.e. task must have done engine->startObserving(this);
35  // Also, if event_name is an empty string, handleExecution won't be called.
36  void getJob(Task *task, const std::string &event_name,
37  const std::string &url) {
38  postJob(task, event_name, url, "");
39  }
40 
41  void postJob(Task *task, const std::string &event_name,
42  const std::string &url, const std::string &data);
43 
44  // Return HTTP status of last completed request, 0 for failure.
45  // Should only be called in the handleExecution callback.
46  unsigned int httpStatus() const {
47  return last_completed ? last_completed->httpStatus() : 0;
48  }
49 
50  // Return MIME type of last completed request, empty on failure.
51  // Should only be called in the handleExecution callback.
52  std::string contentType() const {
53  return last_completed ? last_completed->contentType() : "";
54  }
55 
56  // Return the payload of the last completed request, empty on failure.
57  // Should only be called in the handleExecution callback.
58  const std::string contents() const {
59  return last_completed ? last_completed->contents() : "";
60  }
61 
62  // Return the URL of the last completed request, empty on failure.
63  // Should only be called in the handleExecution callback.
64  const std::string &currentUrl() const {
65  static std::string dummy;
66  return current_job ? current_job->url : dummy;
67  }
68 
69  // Perform the same request again.
70  // Should only be called in the handleExecution callback.
71  void redoJob() {
72  redo_job = current_job;
73  }
74 
75 
76  // Perform another GET request, but with updated url.
77  void redoJob(const std::string &url) {
78  if (current_job) {
79  current_job->url = url;
80  current_job->data.clear();
81  }
82  }
83 
84  // Perform another POST request, but with updated url/data.
85  void redoJob(const std::string &url, const std::string &data) {
86  if (current_job) {
87  current_job->url = url;
88  current_job->data = data;
89  }
90  }
91 
92  // If a task terminates, release ongoing jobs
93  void taskFinished(Task *t) override;
94 
95  // Will be called if all connections have failed.
96  // Default is to try again after next tick.
97  virtual void connectionLost() {
98  dbg_log() << "connectionLost() not implemented";
99  }
100 private:
101  struct HREJob {
102  Task *task;
103  HttpClientConnection *connection;
104  std::string event_name, url, data;
105  };
106 
107  double start() final;
108 
109  double timerEvent() final;
110 
111  // Cancel all request owned by task. Handlers won't be executed.
112  void cancelRequestsByTask(Task *task);
113 
114  void newRequest(HttpClientConnection *conn) final;
115  bool requestComplete(HttpClientConnection *conn) final;
116  void connAdded(SocketConnection *) final;
117  void connRemoved(SocketConnection *) final;
118  void checkConnectionCount();
119  void checkQueue();
120 
121  unsigned int min_connections, max_connections;
122  unsigned int no_connections, active_connections;
123  double tick;
124 
125  HttpClientConnection *last_completed = nullptr;
126  HREJob *current_job;
127 
128  HREJob *redo_job;
129 
130  //size_t max_response_size = 10000000;
131 
132  // Jobs waiting to be started
133  std::deque<HREJob *> incoming_jobs;
134 
135  std::set<SocketConnection *> idle_connections;
136  std::map<HttpClientConnection *, HREJob *> active_jobs;
137 };
HTTP/1.1 client protocol.
Definition: httpclientconnection.h:39
unsigned int httpStatus() const
Definition: httpclientconnection.h:64
std::string contentType() const
Return value of first Content-Type header, empty string on failure.
Definition: httpclientconnection.h:69
API for HTTP clients.
Definition: httpclienttask.h:11
The host name and port number of a HTTP host.
Definition: httphost.h:17
Definition: httprequestengine.h:20
void taskFinished(Task *t) override
Definition: httprequestengine.cpp:128
std::ostream & dbg_log() const
Write a line of debug log.
Definition: logger.h:345
This class implements low-level socket connection operations. Inherit from it to implement protocols ...
Definition: socketconnection.h:47
The purpose of a task is to manage socket connections, and/or to execute timers.
Definition: task.h:39
Definition: httprequestengine.h:14