2023-08-27 01:35:51 +02:00
// What is this module called?
module curlEngine ;
// What does this module require to function?
import std.net.curl ;
import etc.c.curl : CurlOption ;
import std.datetime ;
// What other modules that we have created do we need to import?
import log ;
class CurlEngine {
HTTP http ;
this ( ) {
http = HTTP ( ) ;
}
void initialise ( long dnsTimeout , long connectTimeout , long dataTimeout , long operationTimeout , int maxRedirects , bool httpsDebug , string userAgent , bool httpProtocol , long userRateLimit , long protocolVersion ) {
// Curl Timeout Handling
// libcurl dns_cache_timeout timeout
http . dnsTimeout = ( dur ! "seconds" ( dnsTimeout ) ) ;
// Timeout for HTTPS connections
http . connectTimeout = ( dur ! "seconds" ( connectTimeout ) ) ;
// Data Timeout for HTTPS connections
http . dataTimeout = ( dur ! "seconds" ( dataTimeout ) ) ;
// maximum time any operation is allowed to take
// This includes dns resolution, connecting, data transfer, etc.
http . operationTimeout = ( dur ! "seconds" ( operationTimeout ) ) ;
// Specify how many redirects should be allowed
http . maxRedirects ( maxRedirects ) ;
// Debug HTTPS
http . verbose = httpsDebug ;
// Use the configured 'user_agent' value
http . setUserAgent = userAgent ;
// What IP protocol version should be used when using Curl - IPv4 & IPv6, IPv4 or IPv6
http . handle . set ( CurlOption . ipresolve , protocolVersion ) ; // 0 = IPv4 + IPv6, 1 = IPv4 Only, 2 = IPv6 Only
// What version of HTTP protocol do we use?
// Curl >= 7.62.0 defaults to http2 for a significant number of operations
if ( httpProtocol ) {
// Downgrade to HTTP 1.1 - yes version = 2 is HTTP 1.1
http . handle . set ( CurlOption . http_version , 2 ) ;
}
// Configure upload / download rate limits if configured
// 131072 = 128 KB/s - minimum for basic application operations to prevent timeouts
// A 0 value means rate is unlimited, and is the curl default
if ( userRateLimit > 0 ) {
// set rate limit
http . handle . set ( CurlOption . max_send_speed_large , userRateLimit ) ;
http . handle . set ( CurlOption . max_recv_speed_large , userRateLimit ) ;
}
// Explicitly set these libcurl options
// https://curl.se/libcurl/c/CURLOPT_NOSIGNAL.html
// Ensure that nosignal is set to 0 - Setting CURLOPT_NOSIGNAL to 0 makes libcurl ask the system to ignore SIGPIPE signals
http . handle . set ( CurlOption . nosignal , 0 ) ;
// https://curl.se/libcurl/c/CURLOPT_TCP_NODELAY.html
// Ensure that TCP_NODELAY is set to 0 to ensure that TCP NAGLE is enabled
http . handle . set ( CurlOption . tcp_nodelay , 0 ) ;
2023-09-08 22:34:52 +02:00
2023-08-27 01:35:51 +02:00
// https://curl.se/libcurl/c/CURLOPT_FORBID_REUSE.html
2023-08-30 22:29:24 +02:00
// CURLOPT_FORBID_REUSE - make connection get closed at once after use
2023-09-08 22:34:52 +02:00
// Ensure that we ARE NOT reusing TCP sockets connections - setting to 0 ensures that we ARE reusing connections (we did this in v2.4.xx) to ensure connections remained open and usable
// Setting this to 1 ensures that when we close the curl instance, any open sockets are closed - which we need to do when running
// multiple threads and API instances at the same time otherwise we run out of local files | sockets pretty quickly
2023-09-08 23:36:24 +02:00
// The libcurl default is 1 - ensure we are configuring not to reuse connections and leave unused sockets open
2023-09-08 22:34:52 +02:00
http . handle . set ( CurlOption . forbid_reuse , 1 ) ;
2023-08-27 01:35:51 +02:00
if ( httpsDebug ) {
// Output what options we are using so that in the debug log this can be tracked
log . vdebug ( "http.dnsTimeout = " , dnsTimeout ) ;
log . vdebug ( "http.connectTimeout = " , connectTimeout ) ;
log . vdebug ( "http.dataTimeout = " , dataTimeout ) ;
log . vdebug ( "http.operationTimeout = " , operationTimeout ) ;
log . vdebug ( "http.maxRedirects = " , maxRedirects ) ;
2023-09-08 22:34:52 +02:00
log . vdebug ( "http.CurlOption.ipresolve = " , protocolVersion ) ;
2023-08-27 01:35:51 +02:00
}
}
2023-08-30 22:29:24 +02:00
void setMethodPost ( ) {
2023-08-27 01:35:51 +02:00
http . method = HTTP . Method . post ;
}
2023-08-30 22:29:24 +02:00
void setMethodPatch ( ) {
2023-08-27 01:35:51 +02:00
http . method = HTTP . Method . patch ;
}
2023-08-30 22:29:24 +02:00
void setDisableSSLVerifyPeer ( ) {
log . vdebug ( "Switching off CurlOption.ssl_verifypeer" ) ;
http . handle . set ( CurlOption . ssl_verifypeer , 0 ) ;
}
2023-08-27 01:35:51 +02:00
}