Perl not playing video with vlc plugin - apache

I am trying to play the video file with help of vlc-plugin.
Here is my code:-
#!/usr/bin/perl
use strict;
use warnings;
use File::Basename;
my $file ='/home/abhishek/Videos/lua.mp4';
my $size = -s "$file";
my $begin=0;
my $end=$size;
(my $name, my $dir, my $ext) = fileparse($file, qr/\.[^.]*/);
open (my $fh, '<', $file)or die "can't open $file: $!";
binmode $fh;
print "Content-Type: application/x-vlc-plugin \n";
print "Cache-Control: public, must-revalidate, max-age=0";
print "Pragma: no-cache" ;
print "Accept-Ranges: bytes";
print "Content-Length: $end - $begin\n\n";
print "Content-Range: bytes $begin'-'$end'/'$size";
print "Content-Disposition: inline; filename=\"$name$ext\"\n";
print "Content-Transfer-Encoding: binary";
print "Connection: close";
my $cur=$begin;
seek($fh,$begin,0);
while(!eof($fh) && $cur < $end)
{
my $buf=1024*16;
read $fh, $buf, $end-$cur;
$cur+=1024*16;
}
close $fh;
And here is my access log is writing
127.0.0.1 - - [29/Dec/2015:11:39:31 +0530] "GET /cgi-bin/download.cgi HTTP/1.1" 200 484 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:43.0) Gecko/20100101 Firefox/43.0"
127.0.0.1 - - [29/Dec/2015:11:39:32 +0530] "GET /cgi-bin/download.cgi HTTP/1.1" 200 447 "-" "(null)"
As I checked what does this mean from apache site,here is what i got
If no content was returned to the client, this value will be "-". To log "0" for no content, use %B instead.
No content is returning to the client.It is returning null.
I am not able to figure out what is going wrong. Any help what will be grateful.
And please suggest me what should i do to play the video and I am not sure is this the correct way to do?
Thanks in advance

I see numerous major problems with the headers you are printing:
print "Content-Type: application/x-vlc-plugin \n";
This MIME type is primarily used in an <embed> tag to invoke VLC. The correct MIME type for this file type is probably video/mp4.
print "Cache-Control: public, must-revalidate, max-age=0";
print "Pragma: no-cache" ;
These headers, and a number of the other ones following, are missing terminal newlines (\n). This will cause them to run together, causing unexpected results.
print "Accept-Ranges: bytes";
Along with not having a newline, this header is telling the browser that this resource supports range requests. Your script doesn't actually implement this, though, which will cause browsers to get very confused.
print "Content-Length: $end - $begin\n\n";
Content-Length must be a single number representing the total length of the resource (e.g, Content-Length: $size). Also, you've got two newlines here, which will cause all the following headers to be treated as part of the content.
print "Content-Range: bytes $begin'-'$end'/'$size";
This header would normally be used with range requests, but you haven't fully implemented this feature, so this header will just confuse matters.
print "Content-Transfer-Encoding: binary";
This header is meaningless here — it's primarily used in email. Leave it out.
print "Connection: close";
This header will be set as needed by the web server. CGI scripts shouldn't generate it.
You're also missing the double newline that needs to follow the last header.

I am too lazy to get it fully working, Here is a few suggestions
which does not fit into comments
Definitely will move you forward.
# format is in the detail
my $content_length = $end - $begin;
print "Content-Type: text/html\r\n";
print "Content-Type: application/x-vlc-plugin\r\n";
print "Cache-Control: public, must-revalidate, max-age=0\r\n";
print "Pragma: no-cache\r\n" ;
print "Accept-Ranges: bytes\r\n";
print "Content-Length: $content_length", "\r\n";
print "Content-Range: bytes ${begin}-${end}/${size}\r\n";
print "Content-Disposition: inline; filename=\"$name$ext\"\r\n";
print "Content-Transfer-Encoding: binary\r\n";
print "Connection: close\r\n";
print "\r\n";
################################
#
# flush is needed
#
# ##############################
use IO::Handle;
STDOUT->autoflush;
my $cur=$begin;
seek($fh,$begin,0);
while(!eof($fh) && $cur < $end)
{
my $buf=1024*16;
read $fh, $buf, $end-$cur;
$cur+=1024*16;
##############################
# I suspect you will need this
#
###############################
print $buf;
}
close $fh;

Related

How do I implement sendgrid.env file?

I am trying to implement the sendgrid email API.
I have followed all the instructions I can find to try and set up the sendgrid email API but I all I get is this:
Response status: 401 Response Headers - HTTP/1.1 401 Unauthorized
- Server: nginx - Date: Wed, 02 Mar 2022 21:56:45 GMT
- Content-Type: application/json
- Content-Length: 88
- Connection: keep-alive
- Access-Control-Allow-Origin: https://sendgrid.api-docs.io
- Access-Control-Allow-Methods: POST
- Access-Control-Allow-Headers: Authorization, Content-Type, On-behalf-of, x-sg-elas-acl
- Access-Control-Max-Age: 600
- X-No-CORS-Reason: https://sendgrid.com/docs/Classroom/Basics/API/cors.html
- Strict-Transport-Security: max-age=600; includeSubDomains
I installed the SendGrid helper library, ran the Composer command which created a composer.json file in the root of my project, installed the SendGrid helper library for PHP, along with its dependencies in a new directory named vendor.
I then used the following to create sendgrid.env:
echo "export SENDGRID_API_KEY='SG.XXX....XXXX'" > sendgrid.env
echo "sendgrid.env" >> .gitignore
source ./sendgrid.env
The API key works fine when I tested it using curl --request POST and email comes through ok.
But I have tried every combination I can think of to integrate the sendgrid.env e.g. changing the location, removing the single quotes etc. but I just get the same error message every time.
Here is my php script to send the email:
declare(strict_types=1);
require 'vendor/autoload.php';
use \SendGrid\Mail\Mail;
$email = new Mail();
// Replace the email address and name with your verified sender
$email->setFrom(
'paul#xxx.com',
'Paul xxx'
);
$email->setSubject('Sending with Twilio SendGrid is Fun');
// Replace the email address and name with your recipient
$email->addTo(
'paul#yyy.com',
'Paul yyy'
);
$email->addContent(
'text/html',
'<strong>and fast with the PHP helper library.</strong>'
);
$sendgrid = new \SendGrid(getenv('SENDGRID_API_KEY'));
try {
$response = $sendgrid->send($email);
printf("Response status: %d\n\n", $response->statusCode());
$headers = array_filter($response->headers());
echo "Response Headers\n\n";
foreach ($headers as $header) {
echo '- ' . $header . "\n";
}
} catch (Exception $e) {
echo 'Caught exception: '. $e->getMessage() ."\n";
}
This is the structure of the files:
My domain and email have been verified on Sendgrid.
I have a feeling that there's another step involved to get the API from the sendgrid.env file?
Thanks in advance.

Fortify API Start Scan with Default - How to send package

I am trying to use the API from https://api.emea.fortify.com/swagger/ui/index#/
called Start Scan with Default.
I cannot find any documentation to suggest how to set the post up.
This is what I have so far, but I get an error and of course I am not sending the files to scan either, so I know it is not right.
I have tried a Get request, which works so I know it is authenticated etc.
I just need to know are the parameters correctly formatted and how do I upload the actual files to scan.
POST /api/v3/releases/43579/static-scans/start-scan-with-defaults?releaseId=43579& fragNo=22& offset=22& isRemediationScan=false& notes=hello HTTP/1.1
Host: api.emea.fortify.com
Content-Type: application/json
Authorization: Bearer [TOKEN HERE]
User-Agent: PostmanRuntime/7.13.0
Accept: */*
Cache-Control: no-cache
Postman-Token: 57e40c1d-c99c-40a4-a79b-06ef9a678a07,8ef4ad1e-327f-4eee-b6bb-bddb21b18d50
Host: api.emea.fortify.com
accept-encoding: gzip, deflate
content-length:
Connection: keep-alive
cache-control: no-cache
Response:
{
"errors": [
{
"errorCode": null,
"message": "Unexpected error processing request"
}
]
}
UPDATE
I have found this repo on Git written in Java, which I have tried to recreate in PowerShell with no success.
https://github.com/fod-dev/fod-uploader-java
My PowerShell:
[System.Net.WebRequest]::DefaultWebProxy = [System.Net.WebRequest]::GetSystemWebProxy()
[System.Net.WebRequest]::DefaultWebProxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
$zipDetails = Get-Content C:\Users\patemanc\Desktop\types.zip -Encoding Byte
Write-Host $zipDetails.Length
$releaseId = "43576"
$url = "https://api.emea.fortify.com/api/v3/releases/$releaseId/static-scans/start-scan-with-defaults?"
$url += "releaseId=$releaseId"
$url += "&fragNo=-1"
$url += "&offset=0"
$url += "&isRemediationScan=false"
$url += "&notes=PowrShell Test"
$long_lived_access_token = "ENTER TOKEN HERE"
$headers = #{Authorization = "bearer:$long_lived_access_token"}
$response = Invoke-WebRequest -ContentType "application/octet-stream" -Uri $url -Method POST -Body $zipDetails -Headers $headers -UseBasicParsing
Write-Host "Here is the end"
Write-Host $response
Error Response:
79212
Invoke-WebRequest : The underlying connection was closed: An unexpected error occurred on a send.
At line:22 char:13
+ $response = Invoke-WebRequest -ContentType "application/json" -Uri $ ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
Why postman? If you use some plugin to run it, from Jenkins for example, it works fine. I don't know how the plugins call it from the API.

Forming a JSON post request with Boost asio

I don't usually get this low level, so I think I'm just missing something obvious with the header.
Here's the code:
request_stream << "POST / HTTP/1.1\r\n"
"Host: localhost:5000 \r\n"
"Accept: */*\r\n"
"Content-Type: application/json\r\n";
request_stream << "Content-Length: " << json.length() << "\r\n\r\n";
request_stream << json;
The resulting string is
POST / HTTP/1.1
Host: localhost:5000
Accept: */*
Content-Type: application/json
Content-Length: 34
{'key1':'value1', 'key2':'value2'}
I then send the request_stream string to the server. I can connect to the server, but it says "bad request". I'm guessing there's something wrong with the above string. Any ideas?
Thanks.
Turns out that the request was fine. The issue was the simple Flask server I set up. I was calling
print(request.get_json())
when I should've have been calling
print(request.form.get('data'))

Loop CSV and post data through REST API

I have simple CSV file like:
device,template
dlinkrouter,DLink DGS Switch
cisco, DLink DGS Switch
And simple script like below:
$csv = Import-Csv "C:\Users\m.zurek\Desktop\devices.csv"
$csv.device | ForEach-Object {
Write-Host $_
$action = "http://localhost:8090/api/json/ncmsettings/addDevice"
$hash = #{}
$hash.Add("apiKey", "cb464d185c0cdf785295a6a0a1d227a2")
$hash.Add("IPADDRESS", $($_))
$hash.Add("DEVICE_BEHAVIOUR", "DLink DGS Switch")
$adddev = Invoke-WebRequest -Uri $action -UseBasicParsing -Body $hash -Method Post
return $adddev
}
Problem is that the script adds only the first device from the CSV file. On the rest I have response from API about error. Not sure if it's a problem with API or with my script.
StatusCode : 200
StatusDescription :
Content : {"Message":"Error in adding device. Zip the logs folder and send it to support.","isSuccess":false,"statusMsg":"Failure","bulkResourceIds":[]}
RawContent : HTTP/1.1 200
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET,POST
Access-Control-Max-Age: 5000
Transfer-Encoding: chunked
Vary: Accept-Encoding
Content-Type: application/json;c...
Forms :
Headers : {[Access-Control-Allow-Origin, *], [Access-Control-Allow-Methods, GET,POST], [Access-Control-Max-Age, 5000], [Transfer-Encoding, chunked]...}
Images : {}
InputFields : {}
Links : {}
ParsedHtml :
RawContentLength : 144
Write-Host works fine and write name of all devices from CSV.

PayPal IPN Updates to Accommodate HTTP1.1 - Connection reset by peer

We have been working to update our PayPal IPN scripts in accord with seom recent changes. Here is the instruction in part by PayPal ...
Your Action Required before February 1, 2013 You will need to update
your IPN and/or PDT scripts to use HTTP 1.1, and include the "Host:
www.paypal.com" and "Connection: close" HTTP headers in the IPN and
PDT scripts.
We did that and the IPNs failed. PayPal Merchant Technical Service asked that we move to a SLL connection. Previously our connection to PayPal had been based upon ...
fsockopen ('www.paypal.com', 80, $errno, $errstr, 30)
Now it is ...
fsockopen ('ssl://ipnpb.paypal.com', 443, $errno, $errstr, 30)
We had to overcome an SSL problem with our host config to get this working, but it now makes the connection. However IPN requires us to post back to PayPal in order to receive a "VERIFIED" notification, at which point the script can do it's local processing based upon a confirmed payment.
This is where it fails.
The lines of the sample PayPal script are:
if (!$fp) {
// HTTP ERROR
} else {
fputs ($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
if (strcmp (trim($res), "VERIFIED") == 0) { ... rest of script
But the response comes back blank. I have inserted a diagnostic to email me the value of $res at each stage. If I do this with the old script it comes back with a "VERIFIED" value just fine. The old scripts on several sites have been stable for years. I have now tried these new updates on two distinct sites on two different servers and the result is the same.
When looking at the Apache logs I see this error:
PHP Warning: fgets() [function.fgets]: SSL: Connection reset by peer in /home/[sitename]/public_html/[IPN scriptname].php on line 145
So it appears that PayPal shuts down the connection without sending a Verified response. However PayPal support deny that this is a problem at this end since the connection is opening in the first place.
I have spent several days trying to fix this. I still have the deadline of Feb 1st after which PayPal say my old scripts may not work, but neither do the new ones.
Anyone else have any experience with this?
If anyone else has the same issue, CURL seems to be the recommend choice for IPN by PayPal.
Check out there code sample on Github at: https://github.com/paypal/ipn-code-samples/blob/master/paypal_ipn.php
After struggle this issue a few hours. I got it right.
first, the header should be correct.
$header = "POST /cgi-bin/webscr HTTP/1.1\r\n";
$header .= "Host: www.sanbox.paypal.com\r\n";
$header .= "Accept: */*\r\n";
$header .= "Connection: Close\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "\r\n";
second, the buffer should be big enough to receive whole msg from Paypal. the original sample code use 1024, but the result got truncated.
$res = stream_get_contents($fp, 2048);
After the two, the result return good.
Finaly found an answer! Paypal IPN Script, issue with feof and fgets
remove while(!feof($fp) ... and change it to $res = stream_get_contents($fp, 1024); also add $header .= "Conection: Close" to make sure that paypal closes the connection.
UPDATE: Jan 7th 2016
I noticed that the below works very well for tls://www.sandbox.paypal.com but when you go live to tls://www.paypal.com connection is refused! (It doesn't work) I found the problem is in the headers, sandbox and production level live paypal needs different headers! This is a bug but for you to get it work both in production level and sandbox, please use these headers respectively:
Production Level (Live PayPal Headers):
$header = "POST /cgi-bin/webscr HTTP/1.1\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
Sandbox PayPal Headers:
$header = "POST /cgi-bin/webscr HTTP/1.1\r\n";
$header .= "Host: www.paypal.com\r\n";
$header .= "Accept: */*\r\n";
$header .= "Connection: Close\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "\r\n";
* The code below is the same and it works fine, just replace the headers respectively.*
Here is the rest of the code (and answer):
I checked all of the answers here and there to make it work in Jan 5th 2016.
All of them had good points, but didn't work for the whole picture.
So first, here is the complete code that actually works and then I'll go through it:
<?php
// =========================================================================
// PayPal Official PHP Codes and Tutorial:
// https://developer.paypal.com/webapps/developer/docs/classic/ipn/gs_IPN/
// =========================================================================
// Send an empty HTTP 200 OK response to acknowledge receipt of the notification
header('HTTP/1.1 200 OK');
// Assign payment notification values to local variables
$item_name = $_POST['item_name'];
$item_number = $_POST['item_number'];
$payment_status = $_POST['payment_status'];
$payment_amount = $_POST['mc_gross'];
$payment_currency = $_POST['mc_currency'];
$txn_id = $_POST['txn_id'];
$receiver_email = $_POST['receiver_email'];
$payer_email = $_POST['payer_email'];
// Build the required acknowledgement message out of the notification just received
$req = 'cmd=_notify-validate'; // Add 'cmd=_notify-validate' to beginning of the acknowledgement
foreach ($_POST as $key => $value) {
// Loop through the notification NV pairs
$value = urlencode(stripslashes($value)); // Encode these values
$req .= "&$key=$value"; // Add the NV pairs to the acknowledgement
}
// Set up the acknowledgement request headers
// HTTP POST request
$header = "POST /cgi-bin/webscr HTTP/1.1\r\n";
$header .= "Host: www.sanbox.paypal.com\r\n";
$header .= "Accept: */*\r\n";
$header .= "Connection: Close\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "\r\n";
// Open a socket for the acknowledgement request
$fp = fsockopen('tls://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
// Send the HTTP POST request back to PayPal for validation
fputs($fp, $header . $req);
// Log the transaction:
file_put_contents("paypal_post.txt", date('Y-m-d H:i:s')."\n".file_get_contents("php://input")."\n\n", FILE_APPEND);
// While not EOF
while (!feof($fp)) {
// Get the acknowledgement response
// $res = fgets($fp, 1024);
$res = stream_get_contents($fp, 1024);
$responses = explode("\r\n", $res);
foreach ($responses as $response) {
if (strcmp ($response, "VERIFIED") == 0) {
// Response contains VERIFIED - process notification
// Authentication protocol is complete - OK to process notification contents
// Possible processing steps for a payment include the following:
// Check that the payment_status is Completed
// Check that txn_id has not been previously processed
// Check that receiver_email is your Primary PayPal email
// Check that payment_amount/payment_currency are correct
// Process payment
} else if (strcmp ($response, "INVALID") == 0) {
// Response contains INVALID - reject notification
// Authentication protocol is complete - begin error handling
}
}
}
// Close the file
fclose($fp);
?>
OK, now you have the code that works to listen for a PayPal IPN, re-compile and send it back to PayPal for verification, receive the headers back, process the headers line by line to find the VERIFIED validation.
Which should be provided by PayPal all-in-one package in a working condition but their tutorial lacked very critical parts and it didn't work for me and many here on this thread.
So now what are the critical parts that makes it work:
First, the headers provided by paypal didn't work, I found #jp_eagle 's headers work perfectly.
And paypal was wrong for $res = fgets($fp, 1024); as well...
However you dont need $res = stream_get_contents($fp, 2048); as #jp_eagle suggested, $res = stream_get_contents($fp, 1024); is just fine.
while (!feof($fp)) {} loop should stay there to make it work! Yes, even with the switch from fgets() to stream_get_contents() it should stay there!
#richbai90 was wrong for the suggestion to remove it.
Try the other way and it won't work...
And the most critical part to get the VALIDATION is this loop:
$res = stream_get_contents($fp, 1024);
$responses = explode("\r\n", $res);
foreach ($responses as $response) {}
Now you can look for the VALIDATION in each line here:
if (strcmp ($response, "VERIFIED") == 0) {}
Also logged the initial complete incoming POST request form paypal before anything else:
// Log the transaction:
file_put_contents("paypal_post.txt", date('Y-m-d H:i:s')."\n".file_get_contents("php://input")."\n\n", FILE_APPEND);
That's it.
Now go here and login with your paypal to see if it works:
https://developer.paypal.com/developer/ipnSimulator/
Give your url select "cart checkout" for example and send a test IPN.
If it works all good, go ahead and remove the .sandbox from the above paypal URL from www.sandbox.paypal.com to www.paypal.com and you are live.
Fill in the VERIFIED and INVALID sections in the if-else statements with your database actions and it is done.