Issues (15)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/Agent.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace CurlX;
4
5
/**
6
 * Class Agent
7
 * @package CurlX
8
 *
9
 * @property int $max_concurrent The maximum number of simultaneous connections allowed
10
 * @property int $maxConcurrent The maximum number of simultaneous connections allowed
11
 * @property string $url default url for requests
12
 * @property array $post_data array of default post data for requests
13
 * @property float $time running time of the agent
14
 * @property int $timeout default timeout (in msec) for requests
15
 * @property array $options default cUrl options for requests
16
 * @property array $headers default headers for requests
17
 * @property resource $handle cUrl Multi Handle
18
 * @property callable[] $listeners array of registered listeners which will be registered to newly created requests
19
 * @property array $response responses of the individual requests
20
 */
21
class Agent
22
{
23
    /**
24
     * @var array results
25
     */
26
    protected $result;
27
28
    /**
29
     * @var array responses
30
     */
31
    protected $response;
32
33
    /**
34
     * @var int The maximum number of simultaneous connections allowed
35
     */
36
    protected $maxConcurrent = 0;
37
38
    /**
39
     * @var RequestInterface[] array of Requests
40
     */
41
    protected $requests;
42
43
    /**
44
     * @var Request default request
45
     */
46
    protected $defaultRequest;
47
48
    /**
49
     * @var resource cUrl Multi Handle
50
     */
51
    protected $mh;
52
53
    protected $requestCounter = 0;
54
55
    /**
56
     * Agent constructor.
57
     * @param int $maxConcurrent max current requests
58
     */
59
    public function __construct($maxConcurrent = 10)
60
    {
61
        $this->setMaxConcurrent($maxConcurrent);
62
        $this->defaultRequest = new Request();
63
        $this->mh = curl_multi_init();
64
    }
65
66
    /**
67
     * Destructor
68
     */
69
    public function __destruct()
70
    {
71
        curl_multi_close($this->mh);
72
    }
73
74
    /**
75
     * Magic setter function
76
     * @param string $name attribute to set
77
     * @param mixed $value the new value
78
     * @return void
79
     */
80
    public function __set($name, $value)
81
    {
82
        $c = Request::camelize($name);
83
        $m = "set$c";
84
        if (method_exists($this, $m)) {
85
            $this->$m($value);
86
        } else {
87
            $this->defaultRequest->__set($name, $value);
88
        }
89
    }
90
91
    /**
92
     * Magic getter function
93
     * @param string $name of the attribute to get
94
     * @return mixed the attribute's value
95
     */
96
    public function __get($name)
97
    {
98
        $c = Request::camelize($name);
99
        $m = "get$c";
100
        if (method_exists($this, $m)) {
101
            return $this->$m();
102
        } else {
103
            return $this->defaultRequest->__get($name);
104
        }
105
    }
106
107
    /**
108
     * Add a default listener to be added to all new Requests
109
     * @param callable $listener the listener
110
     * @return void
111
     */
112
    public function addListener(callable $listener)
113
    {
114
        $this->defaultRequest->addListener($listener);
115
    }
116
117
    /**
118
     * Set the maximum number of concurrent requests
119
     * @param int $maxConcurrent maximum concurrent requests
120
     * @return void
121
     */
122
    public function setMaxConcurrent($maxConcurrent)
123
    {
124
        if ($maxConcurrent > 0) {
125
            $this->maxConcurrent = $maxConcurrent;
126
        }
127
    }
128
129
    /**
130
     * Get the currently set value of maxConcurrent
131
     * @return int maximum number of concurrent requests
132
     */
133
    public function getMaxConcurrent()
134
    {
135
        return $this->maxConcurrent;
136
    }
137
138
    /**
139
     * Adds a new request to the queue and returns it
140
     * this request will have its default options set to global options
141
     * @param null $url URL to send the request to
142
     * @return RequestInterface the newly added request object
143
     */
144
    public function newRequest($url = null)
145
    {
146
        $request = clone $this->defaultRequest;
147
        $request->url = $url;
148
        return $this->addRequest($request);
149
    }
150
151
    /**
152
     * Add a request to the request queue
153
     * @param RequestInterface $request the request to add
154
     * @return RequestInterface
155
     */
156
    public function addRequest(RequestInterface $request)
157
    {
158
        $this->requests[] = $request;
159
        return $request;
160
    }
161
162
    /**
163
     * Returns the Request object for a give cUrl handle
164
     * @param resource $handle cUrl handle
165
     * @return RequestInterface Request with handle
166
     */
167
    protected function getRequestByHandle($handle)
168
    {
169
        foreach ($this->requests as $request) {
170
            if ($request->handle === $handle) {
171
                return $request;
172
            }
173
        }
174
    }
175
176
    /**
177
     * Execute the request queue
178
     * @return void
179
     */
180
    public function execute()
181
    {
182
        // start the first batch of requests
183
        $numOfRequests = count($this->requests);
184
        while ($this->requestCounter < $this->maxConcurrent && $this->requestCounter < $numOfRequests) {
185
            curl_multi_add_handle($this->mh, $this->requests[$this->requestCounter]->handle);
186
            $this->requestCounter++;
187
        }
188
189
        do {
190
            while (($mrc = curl_multi_exec($this->mh, $running)) == CURLM_CALL_MULTI_PERFORM) {
0 ignored issues
show
This while loop is empty and can be removed.

This check looks for while loops that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

Consider removing the loop.

Loading history...
191
192
            }
193
            if ($mrc != CURLM_OK) {
194
                break;
195
            }
196
197
            // a request was just completed -- find out which one
198
            while ($done = curl_multi_info_read($this->mh)) {
199
                // Callback
200
                $this->getRequestByHandle($done['handle'])->callBack($done);
201
202
                // start a new request
203
                if ($this->requestCounter < $numOfRequests) {
204
                    curl_multi_add_handle($this->mh, $this->requests[$this->requestCounter]->handle);
205
                    $this->requestCounter++;
206
207
                    // remove the curl handle that just completed
208
                    curl_multi_remove_handle($this->mh, $done['handle']);
209
                }
210
            }
211
        } while ($running);
212
    }
213
}
214