The request itself is sent by either execute
or download_to_file
.
The attributes of this class must be set before calling either of these two methods.
var request = new CurlHTTPRequest("http://example.org/")
var response = request.execute
if response isa CurlResponseSuccess then
print "Response status code: {response.status_code}"
print response.body_str
else if response isa CurlResponseFailed then
print_error response.error_msg
end
curl :: CurlHTTPRequest :: data=
Data for the body of a POST requestcurl :: CurlHTTPRequest :: defaultinit
curl :: CurlHTTPRequest :: delegate
Delegates to customize the behavior when runningexecute
curl :: CurlHTTPRequest :: delegate=
Delegates to customize the behavior when runningexecute
curl :: CurlHTTPRequest :: download_to_file
Download to file given resourcecurl :: CurlHTTPRequest :: headers=
Header content of the requestcurl :: CurlHTTPRequest :: method=
The HTTP method, GET by defaultcurl :: CurlHTTPRequest :: unix_socket_path
Set the Unix domain socket path to usecurl :: CurlHTTPRequest :: unix_socket_path=
Set the Unix domain socket path to usecurl :: CurlHTTPRequest :: url=
Address of the remote resource to requestcurl :: CurlHTTPRequest :: user_agent
Set the user agent for all following HTTP requestscurl :: CurlHTTPRequest :: user_agent=
Set the user agent for all following HTTP requestscurl $ CurlHTTPRequest :: SELF
Type of this instance, automatically specialized in every classcore :: Object :: class_factory
Implementation used byget_class
to create the specific class.
curl :: CurlHTTPRequest :: data=
Data for the body of a POST requestcurl :: CurlHTTPRequest :: defaultinit
core :: Object :: defaultinit
curl :: CurlRequest :: defaultinit
curl :: CurlHTTPRequest :: delegate
Delegates to customize the behavior when runningexecute
curl :: CurlHTTPRequest :: delegate=
Delegates to customize the behavior when runningexecute
curl :: CurlHTTPRequest :: download_to_file
Download to file given resourcecurl :: CurlHTTPRequest :: headers=
Header content of the requestcore :: Object :: is_same_instance
Return true ifself
and other
are the same instance (i.e. same identity).
core :: Object :: is_same_serialized
Isself
the same as other
in a serialization context?
core :: Object :: is_same_type
Return true ifself
and other
have the same dynamic type.
curl :: CurlHTTPRequest :: method=
The HTTP method, GET by defaultcore :: Object :: output_class_name
Display class name on stdout (debug only).curl :: CurlHTTPRequest :: unix_socket_path
Set the Unix domain socket path to usecurl :: CurlHTTPRequest :: unix_socket_path=
Set the Unix domain socket path to usecurl :: CurlHTTPRequest :: url=
Address of the remote resource to requestcurl :: CurlHTTPRequest :: user_agent
Set the user agent for all following HTTP requestscurl :: CurlHTTPRequest :: user_agent=
Set the user agent for all following HTTP requests
# HTTP request builder
#
# The request itself is sent by either `execute` or `download_to_file`.
# The attributes of this class must be set before calling either of these two methods.
#
# ## Minimal usage example
#
# ~~~
# var request = new CurlHTTPRequest("http://example.org/")
# var response = request.execute
# if response isa CurlResponseSuccess then
# print "Response status code: {response.status_code}"
# print response.body_str
# else if response isa CurlResponseFailed then
# print_error response.error_msg
# end
# ~~~
class CurlHTTPRequest
super CurlRequest
super NativeCurlCallbacks
# Address of the remote resource to request
var url: String
# Data for the body of a POST request
var data: nullable HeaderMap is writable
# Raw body string
#
# Set this value to send raw data instead of the POST formatted `data`.
#
# If `data` is set, the body will not be sent.
var body: nullable String is writable
# Header content of the request
var headers: nullable HeaderMap is writable
# Delegates to customize the behavior when running `execute`
var delegate: nullable CurlCallbacks is writable
# Set the user agent for all following HTTP requests
var user_agent: nullable String is writable
# Set the Unix domain socket path to use
#
# When not null, enables using a Unix domain socket
# instead of a TCP connection and DNS hostname resolution.
var unix_socket_path: nullable String is writable
# The HTTP method, GET by default
#
# Must be a capitalized string with request name complying with RFC7231
var method: String = "GET" is optional, writable
# Execute HTTP request
#
# By default, the response body is returned in an instance of `CurlResponse`.
# This behavior can be customized by setting a custom `delegate`.
fun execute: CurlResponse
do
# Reset libcurl parameters as the lib is shared and options
# might affect requests from one another.
if not self.curl.is_ok then return answer_failure(0, "Curl instance is not correctly initialized")
var success_response = new CurlResponseSuccess
var callback_receiver: CurlCallbacks = success_response
var err : CURLCode
# Prepare request
err = prepare_request(callback_receiver)
if not err.is_ok then return answer_failure(err.to_i, err.to_s)
# Perform request
var err_resp = perform
if err_resp != null then return err_resp
var st_code = self.curl.native.easy_getinfo_long(new CURLInfoLong.response_code)
if not st_code == null then success_response.status_code = st_code
return success_response
end
# Internal function that sets cURL options and request' parameters
private fun prepare_request(callback_receiver: CurlCallbacks) : CURLCode
do
var err
# cURL options and delegates
err = set_curl_options
if not err.is_ok then return err
# Callbacks
err = set_curl_callback(callback_receiver)
if not err.is_ok then return err
# HTTP Header
err = set_curl_http_header
if not err.is_ok then return err
# Set HTTP method and body
err = set_method
if not err.is_ok then return err
err = set_body
return err
end
# Set cURL parameters according to assigned HTTP method set in method
# attribute and body if the method allows it according to RFC7231
private fun set_method : CURLCode
do
var err : CURLCode
if self.method=="GET" then
err=self.curl.native.easy_setopt(new CURLOption.get, 1)
else if self.method=="POST" then
err=self.curl.native.easy_setopt(new CURLOption.post, 1)
else if self.method=="HEAD" then
err=self.curl.native.easy_setopt(new CURLOption.no_body,1)
else
err=self.curl.native.easy_setopt(new CURLOption.custom_request,self.method)
end
return err
end
# Set request's body
private fun set_body : CURLCode
do
var err
var data = self.data
var body = self.body
if data != null then
var postdatas = data.to_url_encoded(self.curl)
err = self.curl.native.easy_setopt(new CURLOption.postfields, postdatas)
if not err.is_ok then return err
else if body != null then
err = self.curl.native.easy_setopt(new CURLOption.postfields, body)
if not err.is_ok then return err
end
return new CURLCode.ok
end
# Set cURL options
# such as delegate, follow location, URL, user agent and address family
private fun set_curl_options : CURLCode
do
var err
err = self.curl.native.easy_setopt(new CURLOption.follow_location, 1)
if not err.is_ok then return err
err = self.curl.native.easy_setopt(new CURLOption.url, url)
if not err.is_ok then return err
var user_agent = user_agent
if user_agent != null then
err = curl.native.easy_setopt(new CURLOption.user_agent, user_agent)
if not err.is_ok then return err
end
var unix_socket_path = unix_socket_path
if unix_socket_path != null then
err = self.curl.native.easy_setopt(new CURLOption.unix_socket_path, unix_socket_path)
if not err.is_ok then return err
end
return err
end
# Set cURL callback
private fun set_curl_callback(callback_receiver : CurlCallbacks) : CURLCode
do
var err
if self.delegate != null then callback_receiver = self.delegate.as(not null)
err = self.curl.native.register_callback_header(callback_receiver)
if not err.is_ok then return err
err = self.curl.native.register_callback_body(callback_receiver)
if not err.is_ok then return err
return err
end
# Set cURL request header according to attribute headers
private fun set_curl_http_header : CURLCode
do
var headers = self.headers
if headers != null then
var headers_joined = headers.join_pairs(": ")
var err = self.curl.native.easy_setopt(new CURLOption.httpheader, headers_joined.to_curlslist)
if not err.is_ok then return err
end
return new CURLCode.ok
end
# Download to file given resource
fun download_to_file(output_file_name: nullable String): CurlResponse
do
if not self.curl.is_ok then return answer_failure(0, "Curl instance is not correctly initialized")
var success_response = new CurlFileResponseSuccess
var callback_receiver: CurlCallbacks = success_response
if self.delegate != null then callback_receiver = self.delegate.as(not null)
var err
err = self.curl.native.easy_setopt(new CURLOption.follow_location, 1)
if not err.is_ok then return answer_failure(err.to_i, err.to_s)
err = self.curl.native.easy_setopt(new CURLOption.url, url)
if not err.is_ok then return answer_failure(err.to_i, err.to_s)
err = self.curl.native.register_callback_header(callback_receiver)
if not err.is_ok then return answer_failure(err.to_i, err.to_s)
err = self.curl.native.register_callback_stream(callback_receiver)
if not err.is_ok then return answer_failure(err.to_i, err.to_s)
var opt_name
if not output_file_name == null then
opt_name = output_file_name
else if not self.url.substring(self.url.length-1, self.url.length) == "/" then
opt_name = self.url.basename
else
return answer_failure(0, "Unable to extract file name, please specify one")
end
success_response.file = new FileWriter.open(opt_name)
if not success_response.file.is_writable then
return answer_failure(0, "Unable to create associated file")
end
var err_resp = perform
if err_resp != null then return err_resp
var st_code = self.curl.native.easy_getinfo_long(new CURLInfoLong.response_code)
if not st_code == null then success_response.status_code = st_code
var speed = self.curl.native.easy_getinfo_double(new CURLInfoDouble.speed_download)
if not speed == null then success_response.speed_download = speed
var size = self.curl.native.easy_getinfo_double(new CURLInfoDouble.size_download)
if not size == null then success_response.size_download = size
var time = self.curl.native.easy_getinfo_double(new CURLInfoDouble.total_time)
if not time == null then success_response.total_time = time
success_response.file.close
return success_response
end
end
lib/curl/curl.nit:77,1--334,3