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

Introduced properties

fun body: nullable String

curl :: CurlHTTPRequest :: body

Raw body string
fun body=(body: nullable String)

curl :: CurlHTTPRequest :: body=

Raw body string
fun data: nullable HeaderMap

curl :: CurlHTTPRequest :: data

Data for the body of a POST request
fun data=(data: nullable HeaderMap)

curl :: CurlHTTPRequest :: data=

Data for the body of a POST request
init defaultinit(url: String, data: nullable HeaderMap, body: nullable String, headers: nullable HeaderMap, delegate: nullable CurlCallbacks, user_agent: nullable String, unix_socket_path: nullable String, method: nullable String)

curl :: CurlHTTPRequest :: defaultinit

fun delegate: nullable CurlCallbacks

curl :: CurlHTTPRequest :: delegate

Delegates to customize the behavior when running execute
fun delegate=(delegate: nullable CurlCallbacks)

curl :: CurlHTTPRequest :: delegate=

Delegates to customize the behavior when running execute
fun download_to_file(output_file_name: nullable String): CurlResponse

curl :: CurlHTTPRequest :: download_to_file

Download to file given resource
fun execute: CurlResponse

curl :: CurlHTTPRequest :: execute

Execute HTTP request
fun headers: nullable HeaderMap

curl :: CurlHTTPRequest :: headers

Header content of the request
fun headers=(headers: nullable HeaderMap)

curl :: CurlHTTPRequest :: headers=

Header content of the request
fun method: String

curl :: CurlHTTPRequest :: method

The HTTP method, GET by default
fun method=(method: nullable String)

curl :: CurlHTTPRequest :: method=

The HTTP method, GET by default
fun unix_socket_path: nullable String

curl :: CurlHTTPRequest :: unix_socket_path

Set the Unix domain socket path to use
fun unix_socket_path=(unix_socket_path: nullable String)

curl :: CurlHTTPRequest :: unix_socket_path=

Set the Unix domain socket path to use
fun url: String

curl :: CurlHTTPRequest :: url

Address of the remote resource to request
protected fun url=(url: String)

curl :: CurlHTTPRequest :: url=

Address of the remote resource to request
fun user_agent: nullable String

curl :: CurlHTTPRequest :: user_agent

Set the user agent for all following HTTP requests
fun user_agent=(user_agent: nullable String)

curl :: CurlHTTPRequest :: user_agent=

Set the user agent for all following HTTP requests

Redefined properties

redef type SELF: CurlHTTPRequest

curl $ CurlHTTPRequest :: SELF

Type of this instance, automatically specialized in every class

All properties

fun !=(other: nullable Object): Bool

core :: Object :: !=

Have self and other different values?
fun ==(other: nullable Object): Bool

core :: Object :: ==

Have self and other the same value?
type CLASS: Class[SELF]

core :: Object :: CLASS

The type of the class of self.
type SELF: Object

core :: Object :: SELF

Type of this instance, automatically specialized in every class
fun body: nullable String

curl :: CurlHTTPRequest :: body

Raw body string
fun body=(body: nullable String)

curl :: CurlHTTPRequest :: body=

Raw body string
protected fun class_factory(name: String): CLASS

core :: Object :: class_factory

Implementation used by get_class to create the specific class.
fun class_name: String

core :: Object :: class_name

The class name of the object.
fun close

curl :: CurlRequest :: close

Close low-level resources associated to this request
fun data: nullable HeaderMap

curl :: CurlHTTPRequest :: data

Data for the body of a POST request
fun data=(data: nullable HeaderMap)

curl :: CurlHTTPRequest :: data=

Data for the body of a POST request
init defaultinit(url: String, data: nullable HeaderMap, body: nullable String, headers: nullable HeaderMap, delegate: nullable CurlCallbacks, user_agent: nullable String, unix_socket_path: nullable String, method: nullable String)

curl :: CurlHTTPRequest :: defaultinit

fun delegate: nullable CurlCallbacks

curl :: CurlHTTPRequest :: delegate

Delegates to customize the behavior when running execute
fun delegate=(delegate: nullable CurlCallbacks)

curl :: CurlHTTPRequest :: delegate=

Delegates to customize the behavior when running execute
fun download_to_file(output_file_name: nullable String): CurlResponse

curl :: CurlHTTPRequest :: download_to_file

Download to file given resource
fun execute: CurlResponse

curl :: CurlHTTPRequest :: execute

Execute HTTP request
fun get_class: CLASS

core :: Object :: get_class

The meta-object representing the dynamic type of self.
fun hash: Int

core :: Object :: hash

The hash code of the object.
fun headers: nullable HeaderMap

curl :: CurlHTTPRequest :: headers

Header content of the request
fun headers=(headers: nullable HeaderMap)

curl :: CurlHTTPRequest :: headers=

Header content of the request
init init

core :: Object :: init

fun inspect: String

core :: Object :: inspect

Developer readable representation of self.
protected fun inspect_head: String

core :: Object :: inspect_head

Return "CLASSNAME:#OBJECTID".
intern fun is_same_instance(other: nullable Object): Bool

core :: Object :: is_same_instance

Return true if self and other are the same instance (i.e. same identity).
fun is_same_serialized(other: nullable Object): Bool

core :: Object :: is_same_serialized

Is self the same as other in a serialization context?
intern fun is_same_type(other: Object): Bool

core :: Object :: is_same_type

Return true if self and other have the same dynamic type.
fun method: String

curl :: CurlHTTPRequest :: method

The HTTP method, GET by default
fun method=(method: nullable String)

curl :: CurlHTTPRequest :: method=

The HTTP method, GET by default
intern fun object_id: Int

core :: Object :: object_id

An internal hash code for the object based on its identity.
fun output

core :: Object :: output

Display self on stdout (debug only).
intern fun output_class_name

core :: Object :: output_class_name

Display class name on stdout (debug only).
fun serialization_hash: Int

core :: Object :: serialization_hash

Hash value use for serialization
intern fun sys: Sys

core :: Object :: sys

Return the global sys object, the only instance of the Sys class.
abstract fun to_jvalue(env: JniEnv): JValue

core :: Object :: to_jvalue

fun to_s: String

core :: Object :: to_s

User readable representation of self.
fun unix_socket_path: nullable String

curl :: CurlHTTPRequest :: unix_socket_path

Set the Unix domain socket path to use
fun unix_socket_path=(unix_socket_path: nullable String)

curl :: CurlHTTPRequest :: unix_socket_path=

Set the Unix domain socket path to use
fun url: String

curl :: CurlHTTPRequest :: url

Address of the remote resource to request
protected fun url=(url: String)

curl :: CurlHTTPRequest :: url=

Address of the remote resource to request
fun user_agent: nullable String

curl :: CurlHTTPRequest :: user_agent

Set the user agent for all following HTTP requests
fun user_agent=(user_agent: nullable String)

curl :: CurlHTTPRequest :: user_agent=

Set the user agent for all following HTTP requests
fun verbose: Bool

curl :: CurlRequest :: verbose

Shall this request be verbose?
fun verbose=(verbose: Bool)

curl :: CurlRequest :: verbose=

Shall this request be verbose?
package_diagram curl::CurlHTTPRequest CurlHTTPRequest curl::CurlRequest CurlRequest curl::CurlHTTPRequest->curl::CurlRequest curl::NativeCurlCallbacks NativeCurlCallbacks curl::CurlHTTPRequest->curl::NativeCurlCallbacks core::Object Object curl::CurlRequest->core::Object curl::NativeCurlCallbacks->core::Object ...core::Object ... ...core::Object->core::Object neo4j::JsonCurlRequest JsonCurlRequest neo4j::JsonCurlRequest->curl::CurlHTTPRequest neo4j::JsonGET JsonGET neo4j::JsonGET->neo4j::JsonCurlRequest neo4j::JsonPOST JsonPOST neo4j::JsonPOST->neo4j::JsonCurlRequest neo4j::JsonDELETE JsonDELETE neo4j::JsonDELETE->neo4j::JsonCurlRequest neo4j::JsonPUT JsonPUT neo4j::JsonPUT->neo4j::JsonCurlRequest neo4j::JsonGET... ... neo4j::JsonGET...->neo4j::JsonGET neo4j::JsonPOST... ... neo4j::JsonPOST...->neo4j::JsonPOST neo4j::JsonDELETE... ... neo4j::JsonDELETE...->neo4j::JsonDELETE neo4j::JsonPUT... ... neo4j::JsonPUT...->neo4j::JsonPUT

Ancestors

interface Object

core :: Object

The root of the class hierarchy.

Parents

class CurlRequest

curl :: CurlRequest

CURL Request
interface NativeCurlCallbacks

curl :: NativeCurlCallbacks

Interface for internal information callbacks methods

Children

abstract class JsonCurlRequest

neo4j :: JsonCurlRequest

An abstract request that defines most of the standard options for Neo4j REST API

Descendants

class JsonDELETE

neo4j :: JsonDELETE

HTTP DELETE command
class JsonGET

neo4j :: JsonGET

HTTP GET command
class JsonPOST

neo4j :: JsonPOST

HTTP POST command that sends JSON data
class JsonPUT

neo4j :: JsonPUT

HTTP PUT command that sends JSON data

Class definitions

curl $ CurlHTTPRequest
# 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