What is Delphi equivalent to "fsockopen" function in php? - php

What is Delphi equivalent to "fsockopen" function in php?
in PHP Manual:
resource fsockopen ( string $hostname [, int $port = -1 [, int &$errno [, string &$errstr [, float $timeout = ini_get("default_socket_timeout") ]]]] )
Initiates a socket connection to the resource specified by hostname.
My code is fully:
function accountcreate($username, $password, $connection, $bandwidth, $disabledate, $disabletime)
{
$adminpassword='';
$adminport=82;
$proxyaddress='127.1.1.1';
$fp = fsockopen($proxyaddress, $adminport, &$errno, &$errstr, 1000);
if(!$fp)
{
echo "$errstr ($errno)<br>\n";
}
else
{
$url_ = "/account";
$url = "add=1"."&";
.
.
$url = $url."userid=-1";
$len = "Content-Length: ".strlen($url);
$auth = "Authorization: Basic ".base64_encode("admin:".$adminpassword);
$msg = "POST ".$url_." HTTP/1.0\r\nHost: ".$proxyaddress."\r\n".$auth."\r\n".$len."\r\n"."\r\n".$url;
fputs($fp,$msg);
echo $msg;
fclose($fp);
}
that code make a new account in ccproxy.

Perhaps have a look at the Indy Components that ship with Delphi (assuming at least Delphi7). You would need :
TIdTCPConnection Documentation
which contains an IOHandler property (TIdIOHandler) where you specify the parameters used in fsockopen:
TIdTCPConnection.IOHandler Property
TIdIOHandler Documentation
As others have noted, however, you probably would be well served by looking at the bigger picture in your PHP code and perhaps implementing its functionality with a higher level tool like TIdHTTP :
TIdHTTP Documentation

Related

How do i send a byte stream to a socket with PHP?

In GO i can do the following:
conn, _ := net.Dial("tcp", CONNECT) // Client
request := []byte{01, 00} // The request start with 0100
request = append(request, []byte(`09302020073014323720200730007402`)...) // The request
conn.Write(request)
This does work, however, i'm unable to translate this to PHP.
What i have so far:
$fp = stream_socket_client("tcp://x:x", $errno, $errstr, 5);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$queryString = '010009302020073014323720200730007402';
fwrite($fp, $queryString);
echo fgets($fp, $responseSize);
fclose($fp);
}
I tried using the described solutions here with no success, the server does not recognise my input.
In your Go example, your request begins with the bytes 0x01, and 0x00. In PHP, you're writing the byte encoding of the string '0100'. These aren't exactly the same, and you can view how they differ here: https://play.golang.org/p/0gidDZe4lZF
What you really want to be writing is the single byte 0x0, and 0x1 at the beginning of your string instead of these characters.
Using PHP's builtin chr function we can create a string using the single bytes 0x0 and 0x1 like so:
$queryString = chr(0) . chr(1);
$queryString .= '09302020073014323720200730007402'
Barring any additional encoding issues on the PHP side of things, that should match your query in your Go example.

How to pass options to stream_open in google cloud PHP stream wrapper

I'm trying to serve large audio files from google cloud storage with seeking support.
I have difficulties understanding php fopen and google stream wrapper working together.
When fopen is called it immediately calls stream_open from google StreamWrapper class.
However im unable to pass options to it through fopen context. I would like to set bitwise option 0b10000 as its STREAM_MUST_SEEK option. $flags parameter is always 0.
https://www.php.net/manual/en/streamwrapper.stream-open
Documentation shows there are atleast two options you can set, but it doesnt tell where you can set them.
Without $flag set to 0b10000 im getting:
PHP Warning: stream_copy_to_stream(): Failed to seek to position 85721088 in the stream in /home/project/src/Classes/StreamResponse.php on line 296
If i set $flags to 0b10000 it works and supports seeking.
$opts = array(
'gs' => array('key' => 'value')
);
$context = stream_context_create($opts);
$out = fopen('php://output', 'wb');
$file = fopen($this->file->getPathname(), 'rb', false, $context);
stream_copy_to_stream($file, $out, $this->maxlen, $this->offset);
fclose($out);
fclose($file);
/**
* Callback handler for when a stream is opened. For reads, we need to
* download the file to see if it can be opened.
*
* #param string $path The path of the resource to open
* #param string $mode The fopen mode. Currently only supports ('r', 'rb', 'rt', 'w', 'wb', 'wt')
* #param int $flags Bitwise options STREAM_USE_PATH|STREAM_REPORT_ERRORS|STREAM_MUST_SEEK
* #param string $openedPath Will be set to the path on success if STREAM_USE_PATH option is set
* #return bool
*/
public function stream_open($path, $mode, $flags, &$openedPath)
{
$client = $this->openPath($path);
// strip off 'b' or 't' from the mode
$mode = rtrim($mode, 'bt');
$options = [];
if ($this->context) {
$contextOptions = stream_context_get_options($this->context);
if (array_key_exists($this->protocol, $contextOptions)) {
$options = $contextOptions[$this->protocol] ?: [];
}
}
if ($mode == 'w') {
$this->stream = new WriteStream(null, $options);
$this->stream->setUploader(
$this->bucket->getStreamableUploader(
$this->stream,
$options + ['name' => $this->file]
)
);
} elseif ($mode == 'r') {
try {
// Lazy read from the source
$options['restOptions']['stream'] = true;
$this->stream = new ReadStream(
$this->bucket->object($this->file)->downloadAsStream($options)
);
// Wrap the response in a caching stream to make it seekable
if (!$this->stream->isSeekable() && ($flags & STREAM_MUST_SEEK)) {
$this->stream = new CachingStream($this->stream);
}
} catch (ServiceException $ex) {
return $this->returnError($ex->getMessage(), $flags);
}
} else {
return $this->returnError('Unknown stream_open mode.', $flags);
}
if ($flags & STREAM_USE_PATH) {
$openedPath = $path;
}
return true;
}

clear cache on AWS s3 php amazon sdk

I add a new media image (using amazon-s3-and-cloudfront and amazon-web-services wordpress plugins) and I need to clear cache of this image.
I use smush PRO to compress image: it compress image only locally so I need to re-put images on S3.
This is my code
global $as3cf;
if ( ! $as3cf instanceof Amazon_S3_And_CloudFront ) return;
$results = new WP_Query( $query );
$attachments=(array)$results->get_posts();
if(!empty($attachments)){
foreach($attachments as $attachment){
$amazons3_info=get_post_meta($attachment->ID,'amazonS3_info');
#$as3cf->delete_attachment($attachment->ID);
$new_files = $as3cf->upload_attachment_to_s3($attachment->ID);
if(is_wp_error($new_files) && isset($amazons3_info) && !empty($amazons3_info)){
update_post_meta($attachment->ID,'amazonS3_info',$amazons3_info);
}
update_post_meta($attachment->ID,'my-smpro-smush',$new_files);
}
}
The variable $new_files contains something like that
a:3:{s:6:"bucket";s:21:"static.example.com";s:3:"key";s:63:"wp-content/uploads/2016/12/334ca0545d748d0fe135eb30212154db.jpg";s:6:"region";s:9:"eu-west-1";}
So now i need to clear image.
Someone can help me?
I also try https://github.com/subchild/CloudFront-PHP-Invalidator/blob/master/CloudFront.php but it doesn't work.
It seems that your question is not about S3, but about CloudFront.
You can use AWS SDK for PHP to invalidate any object or objects with createInvalidation: http://docs.aws.amazon.com/aws-sdk-php/v2/api/class-Aws.CloudFront.CloudFrontClient.html#_createInvalidation
If you don't want to use SDK for some reason, here is a good example of plain POST request to invalidate CloudFront cache:
<?php
/**
* Super-simple AWS CloudFront Invalidation Script
*
* Steps:
* 1. Set your AWS access_key
* 2. Set your AWS secret_key
* 3. Set your CloudFront Distribution ID
* 4. Define the batch of paths to invalidate
* 5. Run it on the command-line with: php cf-invalidate.php
*
* The author disclaims copyright to this source code.
*
* Details on what's happening here are in the CloudFront docs:
* http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/Invalidation.html
*
*/
$access_key = 'AWS_ACCESS_KEY';
$secret_key = 'AWS_SECRET_KEY';
$distribution = 'DISTRIBUTION_ID';
$epoch = date('U');
$xml = <<<EOD
<InvalidationBatch>
<Path>/index.html</Path>
<Path>/blog/index.html</Path>
<CallerReference>{$distribution}{$epoch}</CallerReference>
</InvalidationBatch>
EOD;
/**
* You probably don't need to change anything below here.
*/
$len = strlen($xml);
$date = gmdate('D, d M Y G:i:s T');
$sig = base64_encode(
hash_hmac('sha1', $date, $secret_key, true)
);
$msg = "POST /2010-11-01/distribution/{$distribution}/invalidation HTTP/1.0\r\n";
$msg .= "Host: cloudfront.amazonaws.com\r\n";
$msg .= "Date: {$date}\r\n";
$msg .= "Content-Type: text/xml; charset=UTF-8\r\n";
$msg .= "Authorization: AWS {$access_key}:{$sig}\r\n";
$msg .= "Content-Length: {$len}\r\n\r\n";
$msg .= $xml;
$fp = fsockopen('ssl://cloudfront.amazonaws.com', 443,
$errno, $errstr, 30
);
if (!$fp) {
die("Connection failed: {$errno} {$errstr}\n");
}
fwrite($fp, $msg);
$resp = '';
while(! feof($fp)) {
$resp .= fgets($fp, 1024);
}
fclose($fp);
echo $resp;
Source: https://gist.github.com/claylo/1009169

The request signature we calculated does not match AMAZON AWS PHP

I have looked at most samples of code based on this issue on stack overflow but I still cant get the request to work. I keep getting this error:
<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.
Here is my code:
$access_key = "ACCESS_KEY";
$associateTag = "AOSSOCIATE_TAG";
$secretkey = "SECRET_KEY";
$keywords = "harry%20potter";
$timestamp = gmdate("Y-m-d\TH:i:s\Z");
$operation = "AWSECommerceService";
function createSignature($operation,$timestamp,$secretkey){
$the_string=$operation.$timestamp;
return base64_encode(hash_hmac("sha256",$the_string,$secretkey,true));
}
$signature = createSignature ($operation,$timestamp,$secretkey);
$APIcall =
"http://ecs.amazonaws.com/onca/xml?".
"AWSAccessKeyId=$access_key&".
"AssociateTag=$associateTag&".
"BrowseNode=1000&".
"ItemPage=1&".
"Keywords=$keywords&".
"Operation=ItemSearch&".
"ResponseGroup=Medium&".
"SearchIndex=Books&".
"Service=AWSECommerceService&".
"Timestamp=$timestamp&".
"Version=2011-08-01&".
"Signature=$signature";
$response = simplexml_load_file($APIcall);
Can anyone help?
I had this issue long time and it worked for me with this code :
require_once 'Crypt/HMAC.php';
require_once 'HTTP/Request.php';
$keyId = "adasdasd";
$secretKey = "asdasdasdasdasd+";
function hex2b64($str) {
$raw = '';
for ($i=0; $i < strlen($str); $i+=2) {
$raw .= chr(hexdec(substr($str, $i, 2)));
}
return base64_encode($raw);
}
function constructSig($str) {
global $secretKey;
$str = utf8_encode($str);
$secretKey = utf8_encode($secretKey);
$hasher =& new Crypt_HMAC($secretKey, "sha1");
$signature = hex2b64($hasher->hash($str));
return ($signature);
}
$expire = time()+1000;
$resource = "/demo/files/clouds.jpg";
$date = gmdate("D, d M Y G:i:s T");
$mime = "image/jpeg";
$stringToSign = "PUT\n";
$stringToSign .= "\n";
$stringToSign .= "$mime\n";
$stringToSign .= "$date\n";
$stringToSign .= $resource;
$req =& new HTTP_Request("http://nameofmine.s3.amazonaws.com/files/clouds.jpg");
$req->setMethod("PUT");
$req->addHeader("Date",$date);
$req->addHeader("Authorization", "AWS " . $keyId . ":" . constructSig($stringToSign));
$req->addHeader("Content-Type",$mime);
$req->setBody(file_get_contents($file_path));
$req->sendRequest();
$responseCode = $req->getResponseCode();
$responseString = $req->getResponseBody();
echo $responseCode;
As you see you have to use Crypto, HTTP pear plugins
The function seems ok (it is the same as the one used in amazon AWS SDK) so make sure that there is no whitespace in front or after the copied key.
When I typed in my credentials by hand, I got the same error a couple of times.
Then I tried Console for Windows so I could copy/paste my credentials. This removed the error message. Either I sucked at typing, or sucked at reading.
Long story short: Don't type by hand, copy and past credentials to avoid typos.
EDIT:
My problem was when trying to add my credentials via EB CLIx3.

How to use fgets as stream_get_line alternative?

I am using stream_get_line to store some php output in a variable, while I'm running a telnet session via fsockopen.
However, my second server does not run PHP5, which is disabled the ability to use stream_get_line. Is there any alternative for PHP 4.3?
I heard that fgets is almost the same, but I don't seem to get it to work exactly like stream_get_line.
Code:
...
# opening connection
$fp = #fsockopen($ip, 23, $errno, $errstr, 8);
# loggin in
fputs($fp, "$user\r");
usleep(250000);
fputs($fp, "$password\r");
# getting information
fputs($fp, "show info\n");
usleep(250000);
fputs($fp, "show info 2\n");
usleep(250000);
fputs($fp, "show info 3\n");
usleep(250000);
fputs($fp, "show info 4\n");
usleep(250000);
fputs($fp, "?\n");
$content = stream_get_line($fp, 0, "?");
$contentvalues = array(
1 => substr($content, 130, 3),
2 => substr($content, 180, 3)
);
fclose($fp);
...
(I am storing specific parts of my output in the $contentvalues variable.)
From the docs:
This function is nearly identical to fgets() except in that it allows
end of line delimiters other than the standard \n, \r, and \r\n, and
does not return the delimiter itself.
From the comments:
when fgets reads some bytes from socket, where EOF is reached, it
returns bool(false) same as stream_get_line
BUT if remote client drops connection, and server script will try to
read some data with function fgets, function will return bool(false),
and stream_get_line will return string(0) ""
so you can detect remote client disconnection with stream_get_line,
and cannot with fgets
There's also some dithering about which function is faster, but it seems to be dependant on the version of PHP, the day of the week, and what the commenter had for dinner the previous night.
edit
Judging by your response to Steffen's answer you're hung up on the fact that fgets() does not take a third parameter as a delimiter. Applying a basic input loop and checking the string will get you there. Also, in Steffen's defense, you were never quite clear on in your question, stating only that it doesn't "work exactly like stream_get_line".
<?php
$delim = '?';
$buf = 4096;
$fp = #fsockopen($ip, 23, $errno, $errstr, 8);
// ... yadda yadda yadda ... //
$content = '';
while( $part = fgets($fp, $buf) ) {
$ind = strpos($part, $delim);
if( $ind !== false ) {
$content .= substr($part, 0, $ind);
break;
}
$content .= $part;
}
Also, even with stream_get_line() you should be using a loop to get the input as a length parameter or 0 does not mean "unlimited", but rather will use one of PHP's defaults which is 8192 bytes.
You can use fgets() (string fgets ( resource $handle [, int $length ] )) instead.
http://www.php.net/manual/de/function.fgets.php

Categories