include: co/so/http.h.
#http::Client
http::Client
is a coroutine-based http client, which is implemented based on libcurl.
#Client::Client
explicit Client(const char* serv_url);
- Constructor, the parameter serv_url is the url address of the server, and its form is
protocol://host:port
, the following server urls are all ok:- “github.com”
- “https://github.com”
- “http://127.0.0.1:7788”
- “http://[::1]:8888”
- Like the tcp::Client, connection is not established in the constructor.
#Client::~Client
Client::~Client();
- Destructor, close the connection, and release libcurl related resources.
#Client::add_header
void add_header(const char* key, const char* val);
void add_header(const char* key, int val);
- Add a HTTP header.
- Users can use this method to add headers before performing HTTP requests, and the added headers will be present in all subsequent requests.
- In the second version, the parameter val is an integer, which is automatically converted into a string internally.
#Client::body
const char* body() const;
- Get the response body of the current HTTP request.
- It returns a pointer to the body data, and it is not null-terminated, the user needs to use the
body_size()
method to get its length.
#Client::body_size
size_t body_size() const;
- Returns length of the response body of the current HTTP request.
#Client::close
void close();
- Close the HTTP connection, must be called in the coroutine.
- Once this method is called, the http::Client object can no longer be used.
#Client::del
void del(const char* url, const char* s, size_t n);
void del(const char* url, const char* s);
void del(const char* url);
- HTTP **DELETE **request, must be called in the coroutine.
- The parameter url must be a string beginning with
'/'
. - The first two versions are suitable for DELETE requests with a body, and parameter s is a pointer to the body data.
- The third version is for DELETE requests without body.
#Client::easy_handle
void* easy_handle() const;
- Return the easy handle of libcurl.
#Client::get
void get(const char* url);
- HTTP **GET **request, must be called in the coroutine.
- The parameter url must be a string beginning with
'/'
.
#Client::head
void head(const char* url);
- HTTP **HEAD **request, must be called in the coroutine.
- The parameter url must be a string beginning with
'/'
.
#Client::header
const char* header(const char* key);
const char* header() const;
-
The first version gets value of a HTTP header. If the header does not exist, an empty string is returned.
-
The second version gets the entire HTTP header part.
-
Example
http::Client c("xx.com");
c.get("/");
auto s = c.header("Content-Length");
#Client::perform
void perform();
-
Perform a HTTP request, get, post and other methods are actually implemented based on this method.
-
Users generally don’t need to call this method. Only when the get, post and other methods provided by http::Client can’t meet their needs, should they consider using this method to customize HTTP requests.
-
Example
void Client::post(const char* url, const char* data, size_t size) {
curl_easy_setopt(_ctx->easy, CURLOPT_POST, 1L);
curl_easy_setopt(_ctx->easy, CURLOPT_URL, make_url(url));
curl_easy_setopt(_ctx->easy, CURLOPT_POSTFIELDS, data);
curl_easy_setopt(_ctx->easy, CURLOPT_POSTFIELDSIZE, (long)size);
this->perform();
}
#Client::post
void post(const char* url, const char* s, size_t n);
void post(const char* url, const char* s);
- HTTP **POST **request, must be called in the coroutine.
- The parameter url must be a string beginning with
'/'
.
#Client::put
void put(const char* url, const char* s, size_t n);
void put(const char* url, const char* s);
- HTTP **PUT **request, must be called in the coroutine.
- The parameter url must be a string beginning with
'/'
.
#Client::remove_header
void remove_header(const char* key);
- The headers added by add_header() method will apply to all subsequent HTTP requests. If the user does not want a header to appear in the subsequent request, this method can be used to delete this header.
#Client::response_code
int response_code() const;
- Get the response code of the current HTTP request.
- Normally, the return value is a value between 100 and 511.
- If the HTTP request is not sent due to network error or other reasons, or no response from the server was received within the timeout period, this method returns 0.
#Client::strerror
const char* strerror() const;
- Get the error information of the current HTTP request.
#Code example
void f() {
http::Client c("https://github.com");
int r;
c.get("/");
r = c.response_code();
LOG << "response code: "<< r;
LOG_IF(r == 0) << "error: "<< c.strerror();
LOG << "body size: "<< c.body_size();
LOG << c.header();
c.get("/idealvin/co");
LOG << "body size: "<< c.body_size();
LOG << "Content-Length: "<< c.header("Content-Length");
LOG << c.header();
c.close();
}
go(f);
#http::Req
http::Req
is an encapsulation of HTTP request, it is used in http::Server.
#Req::Req
Req() = default;
- Default constructor.
#Req::body
const char* body() const;
- Get the body data in the HTTP request.
- It returns a pointer, not null-terminated. The user needs to call the body_size() method to get its length.
#Req::body_size
size_t body_size() const;
- Returns the length of the HTTP request body.
#Req::clear
void clear();
- Clear the http::Req object, the user can continue to use it after it is cleared.
#Req::header
const char* header(const char* key) const;
- Get the value of the HTTP header. If the header does not exist, an empty string is returned.
#Req::is_method_xxx
bool is_method_get() const;
bool is_method_head() const;
bool is_method_post() const;
bool is_method_put() const;
bool is_method_delete() const;
bool is_method_options() const;
- Determine the method type of the HTTP request.
#Req::url
const fastring& url() const;
- Returns a reference to the url in the HTTP request. This value is part of the start line of the HTTP request.
#Req::version
Version version() const;
- Returns the HTTP version in the HTTP request. The return value is one of http::kHTTP10 or http::kHTTP11. Currently, HTTP/2.0 is not supported.
#http::Res
http::Res
class is the encapsulation of HTTP response, it is used in http::Server.
#Res::Res
Res();
- Default constructor.
#Res::add_header
void add_header(const char* key, const char* val);
- Add a HTTP header.
#Res::body_size
size_t body_size() const
- Returns the length of the HTTP response body.
#Res::clear
void clear();
- Clear the http::Res object, the user can continue to use it after it is cleared.
#Res::set_body
void set_body(const void* s, size_t n);
void set_body(const char* s);
- Set the body part of the HTTP response.
- The parameter s is the body data, and the parameter n is the length of s. In the second version, s ends with
'\0'
.
#Res::set_status
void set_status(int status);
- Set the HTTP response code, this value is generally between 100 and 511.
#Res::set_version
void set_version(Version v);
- Set the HTTP version in the HTTP response, HTTP/1.1 is used by default.
- Users generally do not need to call this method.
#Res::str
fastring str() const;
- Convert the HTTP response into a string, which can be sent to the Internet.
#http::Server
http::Server
is a coroutine-based HTTP server. It supports HTTPS. To use HTTPS, you need to install openssl first.
#Server::Server
Server();
- The default constructor, users don’t need to care.
#Server::on_req
void on_req(std::function<void(const Req&, Res&)>&& f);
template<typename T> void on_req(void (T::*f)(const Req&, Res&), T* o);
- Set a callback for processing a HTTP request.
- In the second version, the parameter f is a method in class T, and the parameter o is a pointer to type T.
- When the server receives an HTTP request, it will call the callback set by this method to process the request.
#Server::start
void start(const char* ip="0.0.0.0", int port=80);
void start(const char* ip, int port, const char* key, const char* ca);
- Start the HTTP server, this method will not block the current thread.
- The parameter ip is the server ip, which can be an IPv4 or IPv6 address, and the parameter port is the server port.
- The parameter key is path of a **PEM **file which stores the SSL private key, and the parameter ca is path of a PEM file which stores the SSL certificate. If key or ca is NULL or empty string, SSL will be disabled.
#Server::exit
void exit();
- Added since v2.0.2.
- Exit the HTTP server, close the listening socket, and no longer receive new connections.
- This method will not close the connections that has been established before.
#Code example
http::Server s
s.on_req(
[](const http::Req& req, http::Res& res) {
if (req.is_method_get()) {
if (req.url() == "/hello") {
res.set_status(200);
res.set_body("hello world");
} else {
res.set_status(404);
}
} else {
res.set_status(405);
}
}
);
// start as a http server
s.start("0.0.0.0", 7777);
// start as a https server
s.start("0.0.0.0", 7777, "privkey.pem", "certificate.pem");
There is a simple http::Server demo in co/test, the user can build and run it like this:
xmake -b http_serv
xmake r http_serv
After starting the http server, you can enter 127.0.0.1/hello
in the address bar of the browser to see the result.
#so::easy
void easy(const char* root_dir=".", const char* ip="0.0.0.0", int port=80);
void easy(const char* root_dir, const char* ip, int port, const char* key, const char* ca);
-
Start a static web server, the parameter root_dir is the root directory of the web server.
-
The parameter ip can be an IPv4 or IPv6 address.
-
The second version supports HTTPS, the parameter key is the SSL private key, the parameter ca is the SSL certificate, and both key and ca are files in pem format.
-
When key or ca is NULL or an empty string, HTTPS is not used.
-
This method will block the current thread.
-
Example
#include "co/flag.h"
#include "co/log.h"
#include "co/so.h"
DEF_string(d, ".", "root dir"); // root dir of web server
int main(int argc, char** argv) {
flag::init(argc, argv);
log::init();
so::easy(FLG_d.c_str()); // mum never have to worry again
return 0;
}
#Configuration items
#http_conn_timeout
DEF_uint32(http_conn_timeout, 3000, "#2 connect timeout in ms for http client");
- Connect timeout in milliseconds for http::Client.
#http_timeout
DEF_uint32(http_timeout, 3000, "#2 send or recv timeout in ms for http client");
- Receive and send timeout (libcurl does not distinguish between receive and send timeout) in milliseconds for http::Client.
#http_recv_timeout
DEF_uint32(http_recv_timeout, 3000, "#2 recv timeout in ms for http server");
- Recv timeout in milliseconds for http::Server.
#http_send_timeout
DEF_uint32(http_send_timeout, 3000, "#2 send timeout in ms for http server");
- Send timeout in milliseconds for http::Server.
#http_conn_idle_sec
DEF_uint32(http_conn_idle_sec, 180, "#2 http server may close the con...");
- Timeout in seconds for http::Server to keep an idle connection. If the server does not receive data from the client within this time, it may close the connection.
#http_log
DEF_bool(http_log, true, "#2 enable http server log if true");
- For http::Server, whether to print logs, the default is true.
- The log in http::Server will print the header part of HTTP request and response.
#http_max_idle_conn
DEF_uint32(http_max_idle_conn, 128, "#2 max idle connections for http server");
- For http::Server, maximum number of idle connections. When this number is exceeded, some idle connections will be closed.
#http_max_body_size
DEF_uint32(http_max_body_size, 8 << 20, "#2 max size of http body, default: 8M");
- The maximum body length supported by http::Server, the default is 8M.
#http_max_header_size
DEF_uint32(http_max_header_size, 4096, "#2 max size of http header");
- The maximum header (the entire HTTP header) length supported by http::Server, the default is 4k.