ethon-impersonate 0.17.10-x86_64-darwin-24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +391 -0
- data/LICENSE +21 -0
- data/README.md +164 -0
- data/config/puma.rb +1 -0
- data/ethon-impersonate.gemspec +29 -0
- data/ext/libcurl-impersonate.4.dylib +0 -0
- data/lib/ethon-impersonate.rb +1 -0
- data/lib/ethon_impersonate/curl.rb +90 -0
- data/lib/ethon_impersonate/curls/classes.rb +65 -0
- data/lib/ethon_impersonate/curls/codes.rb +122 -0
- data/lib/ethon_impersonate/curls/constants.rb +81 -0
- data/lib/ethon_impersonate/curls/form_options.rb +37 -0
- data/lib/ethon_impersonate/curls/functions.rb +59 -0
- data/lib/ethon_impersonate/curls/infos.rb +151 -0
- data/lib/ethon_impersonate/curls/messages.rb +19 -0
- data/lib/ethon_impersonate/curls/options.rb +503 -0
- data/lib/ethon_impersonate/curls/settings.rb +13 -0
- data/lib/ethon_impersonate/easy/callbacks.rb +149 -0
- data/lib/ethon_impersonate/easy/debug_info.rb +49 -0
- data/lib/ethon_impersonate/easy/features.rb +31 -0
- data/lib/ethon_impersonate/easy/form.rb +107 -0
- data/lib/ethon_impersonate/easy/header.rb +65 -0
- data/lib/ethon_impersonate/easy/http/actionable.rb +157 -0
- data/lib/ethon_impersonate/easy/http/custom.rb +29 -0
- data/lib/ethon_impersonate/easy/http/delete.rb +25 -0
- data/lib/ethon_impersonate/easy/http/get.rb +24 -0
- data/lib/ethon_impersonate/easy/http/head.rb +24 -0
- data/lib/ethon_impersonate/easy/http/options.rb +24 -0
- data/lib/ethon_impersonate/easy/http/patch.rb +24 -0
- data/lib/ethon_impersonate/easy/http/post.rb +26 -0
- data/lib/ethon_impersonate/easy/http/postable.rb +32 -0
- data/lib/ethon_impersonate/easy/http/put.rb +27 -0
- data/lib/ethon_impersonate/easy/http/putable.rb +25 -0
- data/lib/ethon_impersonate/easy/http.rb +68 -0
- data/lib/ethon_impersonate/easy/informations.rb +118 -0
- data/lib/ethon_impersonate/easy/mirror.rb +38 -0
- data/lib/ethon_impersonate/easy/operations.rb +64 -0
- data/lib/ethon_impersonate/easy/options.rb +50 -0
- data/lib/ethon_impersonate/easy/params.rb +29 -0
- data/lib/ethon_impersonate/easy/queryable.rb +154 -0
- data/lib/ethon_impersonate/easy/response_callbacks.rb +136 -0
- data/lib/ethon_impersonate/easy/util.rb +28 -0
- data/lib/ethon_impersonate/easy.rb +332 -0
- data/lib/ethon_impersonate/errors/ethon_error.rb +9 -0
- data/lib/ethon_impersonate/errors/global_init.rb +13 -0
- data/lib/ethon_impersonate/errors/invalid_option.rb +13 -0
- data/lib/ethon_impersonate/errors/invalid_value.rb +13 -0
- data/lib/ethon_impersonate/errors/multi_add.rb +12 -0
- data/lib/ethon_impersonate/errors/multi_fdset.rb +12 -0
- data/lib/ethon_impersonate/errors/multi_remove.rb +12 -0
- data/lib/ethon_impersonate/errors/multi_timeout.rb +13 -0
- data/lib/ethon_impersonate/errors/select.rb +13 -0
- data/lib/ethon_impersonate/errors.rb +17 -0
- data/lib/ethon_impersonate/impersonate/fingerprints.rb +16 -0
- data/lib/ethon_impersonate/impersonate/settings.rb +86 -0
- data/lib/ethon_impersonate/impersonate/targets.rb +99 -0
- data/lib/ethon_impersonate/impersonate/tls.rb +189 -0
- data/lib/ethon_impersonate/impersonate.rb +10 -0
- data/lib/ethon_impersonate/libc.rb +21 -0
- data/lib/ethon_impersonate/loggable.rb +59 -0
- data/lib/ethon_impersonate/multi/operations.rb +228 -0
- data/lib/ethon_impersonate/multi/options.rb +117 -0
- data/lib/ethon_impersonate/multi/stack.rb +49 -0
- data/lib/ethon_impersonate/multi.rb +126 -0
- data/lib/ethon_impersonate/version.rb +6 -0
- data/lib/ethon_impersonate.rb +28 -0
- metadata +122 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require 'ethon_impersonate/curls/codes'
|
|
3
|
+
require 'ethon_impersonate/curls/options'
|
|
4
|
+
require 'ethon_impersonate/curls/infos'
|
|
5
|
+
require 'ethon_impersonate/curls/form_options'
|
|
6
|
+
require 'ethon_impersonate/curls/messages'
|
|
7
|
+
require 'ethon_impersonate/curls/functions'
|
|
8
|
+
|
|
9
|
+
module EthonImpersonate
|
|
10
|
+
|
|
11
|
+
# FFI Wrapper module for Curl. Holds constants and required initializers.
|
|
12
|
+
#
|
|
13
|
+
# @api private
|
|
14
|
+
module Curl
|
|
15
|
+
extend ::FFI::Library
|
|
16
|
+
extend EthonImpersonate::Curls::Codes
|
|
17
|
+
extend EthonImpersonate::Curls::Options
|
|
18
|
+
extend EthonImpersonate::Curls::Infos
|
|
19
|
+
extend EthonImpersonate::Curls::FormOptions
|
|
20
|
+
extend EthonImpersonate::Curls::Messages
|
|
21
|
+
|
|
22
|
+
# :nodoc:
|
|
23
|
+
def self.windows?
|
|
24
|
+
Libc.windows?
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
require 'ethon_impersonate/curls/constants'
|
|
28
|
+
require 'ethon_impersonate/curls/settings'
|
|
29
|
+
require 'ethon_impersonate/curls/classes'
|
|
30
|
+
extend EthonImpersonate::Curls::Functions
|
|
31
|
+
|
|
32
|
+
@blocking = true
|
|
33
|
+
|
|
34
|
+
@@initialized = false
|
|
35
|
+
@@curl_mutex = Mutex.new
|
|
36
|
+
|
|
37
|
+
class << self
|
|
38
|
+
# This function sets up the program environment that libcurl needs.
|
|
39
|
+
# Think of it as an extension of the library loader.
|
|
40
|
+
#
|
|
41
|
+
# This function must be called at least once within a program (a program is all the
|
|
42
|
+
# code that shares a memory space) before the program calls any other function in libcurl.
|
|
43
|
+
# The environment it sets up is constant for the life of the program and is the same for
|
|
44
|
+
# every program, so multiple calls have the same effect as one call.
|
|
45
|
+
#
|
|
46
|
+
# The flags option is a bit pattern that tells libcurl exactly what features to init,
|
|
47
|
+
# as described below. Set the desired bits by ORing the values together. In normal
|
|
48
|
+
# operation, you must specify CURL_GLOBAL_ALL. Don't use any other value unless
|
|
49
|
+
# you are familiar with it and mean to control internal operations of libcurl.
|
|
50
|
+
#
|
|
51
|
+
# This function is not thread safe. You must not call it when any other thread in
|
|
52
|
+
# the program (i.e. a thread sharing the same memory) is running. This doesn't just
|
|
53
|
+
# mean no other thread that is using libcurl. Because curl_global_init() calls
|
|
54
|
+
# functions of other libraries that are similarly thread unsafe, it could conflict with
|
|
55
|
+
# any other thread that uses these other libraries.
|
|
56
|
+
#
|
|
57
|
+
# @raise [ EthonImpersonate::Errors::GlobalInit ] If Curl.global_init fails.
|
|
58
|
+
def init
|
|
59
|
+
@@curl_mutex.synchronize {
|
|
60
|
+
if not @@initialized
|
|
61
|
+
raise Errors::GlobalInit.new if Curl.global_init(GLOBAL_ALL) != 0
|
|
62
|
+
@@initialized = true
|
|
63
|
+
EthonImpersonate.logger.debug("ETHON: Libcurl initialized") if EthonImpersonate.logger
|
|
64
|
+
end
|
|
65
|
+
}
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# This function releases resources acquired by curl_global_init.
|
|
69
|
+
# You should call curl_global_cleanup once for each call you make to
|
|
70
|
+
# curl_global_init, after you are done using libcurl.
|
|
71
|
+
# This function is not thread safe. You must not call it when any other thread in the
|
|
72
|
+
# program (i.e. a thread sharing the same memory) is running. This doesn't just
|
|
73
|
+
# mean no other thread that is using libcurl. Because curl_global_cleanup calls functions of other
|
|
74
|
+
# libraries that are similarly thread unsafe, it could conflict with
|
|
75
|
+
# any other thread that uses these other libraries.
|
|
76
|
+
# See the description in libcurl of global environment requirements
|
|
77
|
+
# for details of how to use this function.
|
|
78
|
+
def cleanup
|
|
79
|
+
@@curl_mutex.synchronize {
|
|
80
|
+
if @@initialized
|
|
81
|
+
Curl.global_cleanup()
|
|
82
|
+
@@initialized = false
|
|
83
|
+
EthonImpersonate.logger.debug("ETHON: Libcurl cleanup") if EthonImpersonate.logger
|
|
84
|
+
end
|
|
85
|
+
}
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module EthonImpersonate
|
|
3
|
+
module Curl
|
|
4
|
+
# :nodoc:
|
|
5
|
+
class MsgData < ::FFI::Union
|
|
6
|
+
layout :whatever, :pointer, :code, :easy_code
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# :nodoc:
|
|
10
|
+
class Msg < ::FFI::Struct
|
|
11
|
+
layout :code, :msg_code, :easy_handle, :pointer, :data, MsgData
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class VersionInfoData < ::FFI::Struct
|
|
15
|
+
layout :curl_version, :uint8,
|
|
16
|
+
:version, :string,
|
|
17
|
+
:version_num, :int,
|
|
18
|
+
:host, :string,
|
|
19
|
+
:features, :int,
|
|
20
|
+
:ssl_version, :string,
|
|
21
|
+
:ssl_version_num, :long,
|
|
22
|
+
:libz_version, :string,
|
|
23
|
+
:protocols, :pointer
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# :nodoc:
|
|
27
|
+
class FDSet < ::FFI::Struct
|
|
28
|
+
if Curl.windows?
|
|
29
|
+
layout :fd_count, :uint,
|
|
30
|
+
# TODO: Make it future proof by dynamically grabbing FD_SETSIZE.
|
|
31
|
+
:fd_array, [:uint, 2048]
|
|
32
|
+
|
|
33
|
+
def clear; self[:fd_count] = 0; end
|
|
34
|
+
else
|
|
35
|
+
# https://github.com/typhoeus/ethon/issues/182
|
|
36
|
+
FD_SETSIZE = begin
|
|
37
|
+
# Allow to override the (new) default cap
|
|
38
|
+
if ENV['ETHON_FD_SIZE']
|
|
39
|
+
ENV['ETHON_FD_SIZE']
|
|
40
|
+
|
|
41
|
+
# auto-detect ulimit, but cap at 2^16
|
|
42
|
+
else
|
|
43
|
+
[::EthonImpersonate::Libc.getdtablesize, 65_536].min
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
layout :fds_bits, [:long, FD_SETSIZE / ::FFI::Type::LONG.size]
|
|
48
|
+
|
|
49
|
+
# :nodoc:
|
|
50
|
+
def clear; super; end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# :nodoc:
|
|
55
|
+
class Timeval < ::FFI::Struct
|
|
56
|
+
if Curl.windows?
|
|
57
|
+
layout :sec, :long,
|
|
58
|
+
:usec, :long
|
|
59
|
+
else
|
|
60
|
+
layout :sec, :time_t,
|
|
61
|
+
:usec, :suseconds_t
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module EthonImpersonate
|
|
3
|
+
module Curls # :nodoc:
|
|
4
|
+
|
|
5
|
+
# This module contains all easy and
|
|
6
|
+
# multi return codes.
|
|
7
|
+
module Codes
|
|
8
|
+
|
|
9
|
+
# Libcurl error codes, refer
|
|
10
|
+
# https://github.com/bagder/curl/blob/master/include/curl/curl.h for details
|
|
11
|
+
def easy_codes
|
|
12
|
+
[
|
|
13
|
+
:ok,
|
|
14
|
+
:unsupported_protocol,
|
|
15
|
+
:failed_init,
|
|
16
|
+
:url_malformat,
|
|
17
|
+
:not_built_in,
|
|
18
|
+
:couldnt_resolve_proxy,
|
|
19
|
+
:couldnt_resolve_host,
|
|
20
|
+
:couldnt_connect,
|
|
21
|
+
:ftp_weird_server_reply,
|
|
22
|
+
:remote_access_denied,
|
|
23
|
+
:ftp_accept_failed,
|
|
24
|
+
:ftp_weird_pass_reply,
|
|
25
|
+
:ftp_accept_timeout,
|
|
26
|
+
:ftp_weird_pasv_reply,
|
|
27
|
+
:ftp_weird_227_format,
|
|
28
|
+
:ftp_cant_get_host,
|
|
29
|
+
:obsolete16,
|
|
30
|
+
:ftp_couldnt_set_type,
|
|
31
|
+
:partial_file,
|
|
32
|
+
:ftp_couldnt_retr_file,
|
|
33
|
+
:obsolete20,
|
|
34
|
+
:quote_error,
|
|
35
|
+
:http_returned_error,
|
|
36
|
+
:write_error,
|
|
37
|
+
:obsolete24,
|
|
38
|
+
:upload_failed,
|
|
39
|
+
:read_error,
|
|
40
|
+
:out_of_memory,
|
|
41
|
+
:operation_timedout,
|
|
42
|
+
:obsolete29,
|
|
43
|
+
:ftp_port_failed,
|
|
44
|
+
:ftp_couldnt_use_rest,
|
|
45
|
+
:obsolete32,
|
|
46
|
+
:range_error,
|
|
47
|
+
:http_post_error,
|
|
48
|
+
:ssl_connect_error,
|
|
49
|
+
:bad_download_resume,
|
|
50
|
+
:file_couldnt_read_file,
|
|
51
|
+
:ldap_cannot_bind,
|
|
52
|
+
:ldap_search_failed,
|
|
53
|
+
:obsolete40,
|
|
54
|
+
:function_not_found,
|
|
55
|
+
:aborted_by_callback,
|
|
56
|
+
:bad_function_argument,
|
|
57
|
+
:obsolete44,
|
|
58
|
+
:interface_failed,
|
|
59
|
+
:obsolete46,
|
|
60
|
+
:too_many_redirects ,
|
|
61
|
+
:unknown_option,
|
|
62
|
+
:telnet_option_syntax ,
|
|
63
|
+
:obsolete50,
|
|
64
|
+
:peer_failed_verification,
|
|
65
|
+
:got_nothing,
|
|
66
|
+
:ssl_engine_notfound,
|
|
67
|
+
:ssl_engine_setfailed,
|
|
68
|
+
:send_error,
|
|
69
|
+
:recv_error,
|
|
70
|
+
:obsolete57,
|
|
71
|
+
:ssl_certproblem,
|
|
72
|
+
:ssl_cipher,
|
|
73
|
+
:bad_content_encoding,
|
|
74
|
+
:ldap_invalid_url,
|
|
75
|
+
:filesize_exceeded,
|
|
76
|
+
:use_ssl_failed,
|
|
77
|
+
:send_fail_rewind,
|
|
78
|
+
:ssl_engine_initfailed,
|
|
79
|
+
:login_denied,
|
|
80
|
+
:tftp_notfound,
|
|
81
|
+
:tftp_perm,
|
|
82
|
+
:remote_disk_full,
|
|
83
|
+
:tftp_illegal,
|
|
84
|
+
:tftp_unknownid,
|
|
85
|
+
:remote_file_exists,
|
|
86
|
+
:tftp_nosuchuser,
|
|
87
|
+
:conv_failed,
|
|
88
|
+
:conv_reqd,
|
|
89
|
+
:ssl_cacert_badfile,
|
|
90
|
+
:remote_file_not_found,
|
|
91
|
+
:ssh,
|
|
92
|
+
:ssl_shutdown_failed,
|
|
93
|
+
:again,
|
|
94
|
+
:ssl_crl_badfile,
|
|
95
|
+
:ssl_issuer_error,
|
|
96
|
+
:ftp_pret_failed,
|
|
97
|
+
:rtsp_cseq_error,
|
|
98
|
+
:rtsp_session_error,
|
|
99
|
+
:ftp_bad_file_list,
|
|
100
|
+
:chunk_failed,
|
|
101
|
+
:last
|
|
102
|
+
]
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Curl-Multi socket error codes, refer
|
|
106
|
+
# https://github.com/bagder/curl/blob/master/include/curl/multi.h for details
|
|
107
|
+
def multi_codes
|
|
108
|
+
[
|
|
109
|
+
:call_multi_perform, -1,
|
|
110
|
+
:ok,
|
|
111
|
+
:bad_handle,
|
|
112
|
+
:bad_easy_handle,
|
|
113
|
+
:out_of_memory,
|
|
114
|
+
:internal_error,
|
|
115
|
+
:bad_socket,
|
|
116
|
+
:unknown_option,
|
|
117
|
+
:last
|
|
118
|
+
]
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module EthonImpersonate
|
|
3
|
+
module Curl
|
|
4
|
+
# :nodoc:
|
|
5
|
+
VERSION_NOW = 3
|
|
6
|
+
|
|
7
|
+
# Flag. Initialize SSL.
|
|
8
|
+
GLOBAL_SSL = 0x01
|
|
9
|
+
# Flag. Initialize win32 socket libraries.
|
|
10
|
+
GLOBAL_WIN32 = 0x02
|
|
11
|
+
# Flag. Initialize everything possible.
|
|
12
|
+
GLOBAL_ALL = (GLOBAL_SSL | GLOBAL_WIN32)
|
|
13
|
+
# Flag. Initialize everything by default.
|
|
14
|
+
GLOBAL_DEFAULT = GLOBAL_ALL
|
|
15
|
+
|
|
16
|
+
# :nodoc:
|
|
17
|
+
EasyCode = enum(:easy_code, easy_codes)
|
|
18
|
+
# :nodoc:
|
|
19
|
+
MultiCode = enum(:multi_code, multi_codes)
|
|
20
|
+
|
|
21
|
+
# :nodoc:
|
|
22
|
+
EasyOption = enum(:easy_option, easy_options(:enum).to_a.flatten)
|
|
23
|
+
# :nodoc:
|
|
24
|
+
MultiOption = enum(:multi_option, multi_options(:enum).to_a.flatten)
|
|
25
|
+
|
|
26
|
+
# Used by curl_debug_callback when setting CURLOPT_DEBUGFUNCTION
|
|
27
|
+
# https://github.com/bagder/curl/blob/master/include/curl/curl.h#L378 for details
|
|
28
|
+
DebugInfoType = enum(:debug_info_type, debug_info_types)
|
|
29
|
+
|
|
30
|
+
# :nodoc:
|
|
31
|
+
InfoType = enum(info_types.to_a.flatten)
|
|
32
|
+
|
|
33
|
+
# Info details, refer
|
|
34
|
+
# https://github.com/bagder/curl/blob/master/src/tool_writeout.c#L66 for details
|
|
35
|
+
Info = enum(:info, infos.to_a.flatten)
|
|
36
|
+
|
|
37
|
+
# Form options, used by FormAdd for temporary storage, refer
|
|
38
|
+
# https://github.com/bagder/curl/blob/master/lib/formdata.h#L51 for details
|
|
39
|
+
FormOption = enum(:form_option, form_options)
|
|
40
|
+
|
|
41
|
+
# :nodoc:
|
|
42
|
+
MsgCode = enum(:msg_code, msg_codes)
|
|
43
|
+
|
|
44
|
+
VERSION_IPV6 = (1<<0) # IPv6-enabled
|
|
45
|
+
VERSION_KERBEROS4 = (1<<1) # kerberos auth is supported
|
|
46
|
+
VERSION_SSL = (1<<2) # SSL options are present
|
|
47
|
+
VERSION_LIBZ = (1<<3) # libz features are present
|
|
48
|
+
VERSION_NTLM = (1<<4) # NTLM auth is supported
|
|
49
|
+
VERSION_GSSNEGOTIATE = (1<<5) # Negotiate auth supp
|
|
50
|
+
VERSION_DEBUG = (1<<6) # built with debug capabilities
|
|
51
|
+
VERSION_ASYNCHDNS = (1<<7) # asynchronous dns resolves
|
|
52
|
+
VERSION_SPNEGO = (1<<8) # SPNEGO auth is supported
|
|
53
|
+
VERSION_LARGEFILE = (1<<9) # supports files bigger than 2GB
|
|
54
|
+
VERSION_IDN = (1<<10) # International Domain Names support
|
|
55
|
+
VERSION_SSPI = (1<<11) # SSPI is supported
|
|
56
|
+
VERSION_CONV = (1<<12) # character conversions supported
|
|
57
|
+
VERSION_CURLDEBUG = (1<<13) # debug memory tracking supported
|
|
58
|
+
VERSION_TLSAUTH_SRP = (1<<14) # TLS-SRP auth is supported
|
|
59
|
+
VERSION_NTLM_WB = (1<<15) # NTLM delegating to winbind helper
|
|
60
|
+
VERSION_HTTP2 = (1<<16) # HTTP2 support built
|
|
61
|
+
VERSION_GSSAPI = (1<<17) # GSS-API is supported
|
|
62
|
+
VERSION_IMPERSONATE = (1<<18) # curl-impersonate support
|
|
63
|
+
|
|
64
|
+
SOCKET_BAD = -1
|
|
65
|
+
SOCKET_TIMEOUT = SOCKET_BAD
|
|
66
|
+
|
|
67
|
+
PollAction = enum(:poll_action, [
|
|
68
|
+
:none,
|
|
69
|
+
:in,
|
|
70
|
+
:out,
|
|
71
|
+
:inout,
|
|
72
|
+
:remove
|
|
73
|
+
])
|
|
74
|
+
|
|
75
|
+
SocketReadiness = bitmask(:socket_readiness, [
|
|
76
|
+
:in, # CURL_CSELECT_IN - 0x01 (bit 0)
|
|
77
|
+
:out, # CURL_CSELECT_OUT - 0x02 (bit 1)
|
|
78
|
+
:err, # CURL_CSELECT_ERR - 0x04 (bit 2)
|
|
79
|
+
])
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module EthonImpersonate
|
|
3
|
+
module Curls
|
|
4
|
+
|
|
5
|
+
# This module contains the available options for forms.
|
|
6
|
+
module FormOptions
|
|
7
|
+
|
|
8
|
+
# Form options, used by FormAdd for temporary storage, refer
|
|
9
|
+
# https://github.com/bagder/curl/blob/master/lib/formdata.h#L51 for details
|
|
10
|
+
def form_options
|
|
11
|
+
[
|
|
12
|
+
:none,
|
|
13
|
+
:copyname,
|
|
14
|
+
:ptrname,
|
|
15
|
+
:namelength,
|
|
16
|
+
:copycontents,
|
|
17
|
+
:ptrcontents,
|
|
18
|
+
:contentslength,
|
|
19
|
+
:filecontent,
|
|
20
|
+
:array,
|
|
21
|
+
:obsolete,
|
|
22
|
+
:file,
|
|
23
|
+
:buffer,
|
|
24
|
+
:bufferptr,
|
|
25
|
+
:bufferlength,
|
|
26
|
+
:contenttype,
|
|
27
|
+
:contentheader,
|
|
28
|
+
:filename,
|
|
29
|
+
:end,
|
|
30
|
+
:obsolete2,
|
|
31
|
+
:stream,
|
|
32
|
+
:last
|
|
33
|
+
]
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module EthonImpersonate
|
|
3
|
+
module Curls
|
|
4
|
+
|
|
5
|
+
# This module contains the functions to be attached in order to work with
|
|
6
|
+
# libcurl.
|
|
7
|
+
module Functions
|
|
8
|
+
|
|
9
|
+
# :nodoc:
|
|
10
|
+
def self.extended(base)
|
|
11
|
+
base.attach_function :global_init, :curl_global_init, [:long], :int
|
|
12
|
+
base.attach_function :global_cleanup, :curl_global_cleanup, [], :void
|
|
13
|
+
base.attach_function :free, :curl_free, [:pointer], :void
|
|
14
|
+
|
|
15
|
+
base.attach_function :easy_init, :curl_easy_init, [], :pointer
|
|
16
|
+
base.attach_function :easy_cleanup, :curl_easy_cleanup, [:pointer], :void
|
|
17
|
+
base.attach_function :easy_getinfo, :curl_easy_getinfo, [:pointer, :info, :varargs], :easy_code
|
|
18
|
+
base.attach_function :easy_setopt, :curl_easy_setopt, [:pointer, :easy_option, :varargs], :easy_code
|
|
19
|
+
base.instance_variable_set(:@blocking, true)
|
|
20
|
+
base.attach_function :easy_perform, :curl_easy_perform, [:pointer], :easy_code
|
|
21
|
+
base.attach_function :easy_strerror, :curl_easy_strerror, [:easy_code], :string
|
|
22
|
+
base.attach_function :easy_escape, :curl_easy_escape, [:pointer, :pointer, :int], :pointer
|
|
23
|
+
base.attach_function :easy_reset, :curl_easy_reset, [:pointer], :void
|
|
24
|
+
base.attach_function :easy_duphandle, :curl_easy_duphandle, [:pointer], :pointer
|
|
25
|
+
base.attach_function :easy_impersonate, :curl_easy_impersonate, [:pointer, :string, :int], :int
|
|
26
|
+
|
|
27
|
+
base.attach_function :formadd, :curl_formadd, [:pointer, :pointer, :varargs], :int
|
|
28
|
+
base.attach_function :formfree, :curl_formfree, [:pointer], :void
|
|
29
|
+
|
|
30
|
+
base.attach_function :multi_init, :curl_multi_init, [], :pointer
|
|
31
|
+
base.attach_function :multi_cleanup, :curl_multi_cleanup, [:pointer], :void
|
|
32
|
+
base.attach_function :multi_add_handle, :curl_multi_add_handle, [:pointer, :pointer], :multi_code
|
|
33
|
+
base.attach_function :multi_remove_handle, :curl_multi_remove_handle, [:pointer, :pointer], :multi_code
|
|
34
|
+
base.attach_function :multi_info_read, :curl_multi_info_read, [:pointer, :pointer], Curl::Msg.ptr
|
|
35
|
+
base.attach_function :multi_perform, :curl_multi_perform, [:pointer, :pointer], :multi_code
|
|
36
|
+
base.attach_function :multi_timeout, :curl_multi_timeout, [:pointer, :pointer], :multi_code
|
|
37
|
+
base.attach_function :multi_fdset, :curl_multi_fdset, [:pointer, Curl::FDSet.ptr, Curl::FDSet.ptr, Curl::FDSet.ptr, :pointer], :multi_code
|
|
38
|
+
base.attach_function :multi_strerror, :curl_multi_strerror, [:int], :string
|
|
39
|
+
base.attach_function :multi_setopt, :curl_multi_setopt, [:pointer, :multi_option, :varargs], :multi_code
|
|
40
|
+
base.attach_function :multi_socket_action, :curl_multi_socket_action, [:pointer, :int, :socket_readiness, :pointer], :multi_code
|
|
41
|
+
|
|
42
|
+
base.attach_function :version, :curl_version, [], :string
|
|
43
|
+
base.attach_function :version_info, :curl_version_info, [], Curl::VersionInfoData.ptr
|
|
44
|
+
|
|
45
|
+
base.attach_function :slist_append, :curl_slist_append, [:pointer, :string], :pointer
|
|
46
|
+
base.attach_function :slist_free_all, :curl_slist_free_all, [:pointer], :void
|
|
47
|
+
base.instance_variable_set(:@blocking, true)
|
|
48
|
+
|
|
49
|
+
if Curl.windows?
|
|
50
|
+
base.ffi_lib 'ws2_32'
|
|
51
|
+
else
|
|
52
|
+
base.ffi_lib ::FFI::Library::LIBC
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
base.attach_function :select, [:int, Curl::FDSet.ptr, Curl::FDSet.ptr, Curl::FDSet.ptr, Curl::Timeval.ptr], :int
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module EthonImpersonate
|
|
3
|
+
module Curls
|
|
4
|
+
|
|
5
|
+
# This module contains logic for the available informations
|
|
6
|
+
# on an easy, eg.: connect_time.
|
|
7
|
+
module Infos
|
|
8
|
+
|
|
9
|
+
# Return info types.
|
|
10
|
+
#
|
|
11
|
+
# @example Return info types.
|
|
12
|
+
# EthonImpersonate::Curl.info_types
|
|
13
|
+
#
|
|
14
|
+
# @return [ Hash ] The info types.
|
|
15
|
+
def info_types
|
|
16
|
+
{
|
|
17
|
+
string: 0x100000,
|
|
18
|
+
long: 0x200000,
|
|
19
|
+
double: 0x300000,
|
|
20
|
+
slist: 0x400000
|
|
21
|
+
}
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTDEBUGFUNCTION
|
|
25
|
+
# https://github.com/bagder/curl/blob/master/include/curl/curl.h#L378
|
|
26
|
+
#
|
|
27
|
+
# @example Return debug info types.
|
|
28
|
+
# EthonImpersonate::Curl.debug_info_types
|
|
29
|
+
#
|
|
30
|
+
# @return [ Hash ] The info types available to curl_debug_callback.
|
|
31
|
+
def debug_info_types
|
|
32
|
+
[
|
|
33
|
+
:text, 0,
|
|
34
|
+
:header_in,
|
|
35
|
+
:header_out,
|
|
36
|
+
:data_in,
|
|
37
|
+
:data_out,
|
|
38
|
+
:ssl_data_in,
|
|
39
|
+
:ssl_data_out
|
|
40
|
+
]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Return Info details, refer
|
|
44
|
+
# https://github.com/bagder/curl/blob/master/src/tool_writeout.c#L66 for details
|
|
45
|
+
#
|
|
46
|
+
# @example Return infos.
|
|
47
|
+
# EthonImpersonate::Curl.infos
|
|
48
|
+
#
|
|
49
|
+
# @return [ Hash ] The infos.
|
|
50
|
+
def infos
|
|
51
|
+
{
|
|
52
|
+
effective_url: info_types[:string] + 1,
|
|
53
|
+
response_code: info_types[:long] + 2,
|
|
54
|
+
total_time: info_types[:double] + 3,
|
|
55
|
+
namelookup_time: info_types[:double] + 4,
|
|
56
|
+
connect_time: info_types[:double] + 5,
|
|
57
|
+
pretransfer_time: info_types[:double] + 6,
|
|
58
|
+
size_upload: info_types[:double] + 7,
|
|
59
|
+
size_download: info_types[:double] + 8,
|
|
60
|
+
speed_download: info_types[:double] + 9,
|
|
61
|
+
speed_upload: info_types[:double] + 10,
|
|
62
|
+
header_size: info_types[:long] + 11,
|
|
63
|
+
request_size: info_types[:long] + 12,
|
|
64
|
+
ssl_verifyresult: info_types[:long] + 13,
|
|
65
|
+
filetime: info_types[:long] + 14,
|
|
66
|
+
content_length_download: info_types[:double] + 15,
|
|
67
|
+
content_length_upload: info_types[:double] + 16,
|
|
68
|
+
starttransfer_time: info_types[:double] + 17,
|
|
69
|
+
content_type: info_types[:string] + 18,
|
|
70
|
+
redirect_time: info_types[:double] + 19,
|
|
71
|
+
redirect_count: info_types[:long] + 20,
|
|
72
|
+
private: info_types[:string] + 21,
|
|
73
|
+
http_connectcode: info_types[:long] + 22,
|
|
74
|
+
httpauth_avail: info_types[:long] + 23,
|
|
75
|
+
proxyauth_avail: info_types[:long] + 24,
|
|
76
|
+
os_errno: info_types[:long] + 25,
|
|
77
|
+
num_connects: info_types[:long] + 26,
|
|
78
|
+
ssl_engines: info_types[:slist] + 27,
|
|
79
|
+
cookielist: info_types[:slist] + 28,
|
|
80
|
+
lastsocket: info_types[:long] + 29,
|
|
81
|
+
ftp_entry_path: info_types[:string] + 30,
|
|
82
|
+
redirect_url: info_types[:string] + 31,
|
|
83
|
+
primary_ip: info_types[:string] + 32,
|
|
84
|
+
appconnect_time: info_types[:double] + 33,
|
|
85
|
+
certinfo: info_types[:slist] + 34,
|
|
86
|
+
condition_unmet: info_types[:long] + 35,
|
|
87
|
+
rtsp_session_id: info_types[:string] + 36,
|
|
88
|
+
rtsp_client_cseq: info_types[:long] + 37,
|
|
89
|
+
rtsp_server_cseq: info_types[:long] + 38,
|
|
90
|
+
rtsp_cseq_recv: info_types[:long] + 39,
|
|
91
|
+
primary_port: info_types[:long] + 40,
|
|
92
|
+
local_ip: info_types[:string] + 41,
|
|
93
|
+
local_port: info_types[:long] + 42,
|
|
94
|
+
last: 42
|
|
95
|
+
}
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Return info as string.
|
|
99
|
+
#
|
|
100
|
+
# @example Return info.
|
|
101
|
+
# Curl.get_info_string(:primary_ip, easy)
|
|
102
|
+
#
|
|
103
|
+
# @param [ Symbol ] option The option name.
|
|
104
|
+
# @param [ ::FFI::Pointer ] handle The easy handle.
|
|
105
|
+
#
|
|
106
|
+
# @return [ String ] The info.
|
|
107
|
+
def get_info_string(option, handle)
|
|
108
|
+
string_ptr = ::FFI::MemoryPointer.new(:pointer)
|
|
109
|
+
|
|
110
|
+
if easy_getinfo(handle, option, :pointer, string_ptr) == :ok
|
|
111
|
+
ptr=string_ptr.read_pointer
|
|
112
|
+
ptr.null? ? nil : ptr.read_string
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Return info as integer.
|
|
117
|
+
#
|
|
118
|
+
# @example Return info.
|
|
119
|
+
# Curl.get_info_long(:response_code, easy)
|
|
120
|
+
#
|
|
121
|
+
# @param [ Symbol ] option The option name.
|
|
122
|
+
# @param [ ::FFI::Pointer ] handle The easy handle.
|
|
123
|
+
#
|
|
124
|
+
# @return [ Integer ] The info.
|
|
125
|
+
def get_info_long(option, handle)
|
|
126
|
+
long_ptr = ::FFI::MemoryPointer.new(:long)
|
|
127
|
+
|
|
128
|
+
if easy_getinfo(handle, option, :pointer, long_ptr) == :ok
|
|
129
|
+
long_ptr.read_long
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Return info as float
|
|
134
|
+
#
|
|
135
|
+
# @example Return info.
|
|
136
|
+
# Curl.get_info_double(:response_code, easy)
|
|
137
|
+
#
|
|
138
|
+
# @param [ Symbol ] option The option name.
|
|
139
|
+
# @param [ ::FFI::Pointer ] handle The easy handle.
|
|
140
|
+
#
|
|
141
|
+
# @return [ Float ] The info.
|
|
142
|
+
def get_info_double(option, handle)
|
|
143
|
+
double_ptr = ::FFI::MemoryPointer.new(:double)
|
|
144
|
+
|
|
145
|
+
if easy_getinfo(handle, option, :pointer, double_ptr) == :ok
|
|
146
|
+
double_ptr.read_double
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module EthonImpersonate
|
|
3
|
+
module Curls
|
|
4
|
+
|
|
5
|
+
# This module contains available message codes.
|
|
6
|
+
module Messages
|
|
7
|
+
|
|
8
|
+
# Return message codes.
|
|
9
|
+
#
|
|
10
|
+
# @example Return message codes.
|
|
11
|
+
# EthonImpersonate::Curl.msg_codes
|
|
12
|
+
#
|
|
13
|
+
# @return [ Array ] The messages codes.
|
|
14
|
+
def msg_codes
|
|
15
|
+
[:none, :done, :last]
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|