I am trying to send yahoo calendars(caldav) a request to get "current-user-principal" But In response I am getting "401 Unauthorized" error. Before this request I am making another request to get "OPTIONS" which is giving "200 OK" response.
Request call is
PROPFIND / HTTP/1.1
Authorization: Basic XXXXXXXXXXXXXXXX=
Host: calendar.yahoo.com:443
Depth: 0
Prefer: return-minimal
Content-type: application/xml; charset=utf-8
Content-Length: 85
User-Agent: DAViCalClient
Connection: close
Request Response is:
string(613) "HTTP/1.1 401 Unauthorized
WSHost: tardis012.cal.bf1.yahoo.com
Set-Cookie: rememberMe=deleteMe; Path=/; Max-Age=0; Expires=Thu, 18-Feb-2021 03:44:03 GMT
WWW-Authenticate: Basic realm="YahooCalendar"
WWW-Authenticate: OAuth realm="YahooCalendar"
Content-Length: 0
Date: Fri, 19 Feb 2021 03:44:03 GMT
Age: 1
Server: ATS
Referrer-Policy: no-referrer-when-downgrade
Connection: close
Strict-Transport-Security: max-age=15552000
Expect-CT: max-age=31536000, report-uri="http://csp.yahoo.com/beacon/csp?src=yahoocom-expect-ct-report-only"
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
I am using a client library which has a function to make server request
function DoRequest( $relative_url = "" ) {
if(!defined("_FSOCK_TIMEOUT")){ define("_FSOCK_TIMEOUT", 10); }
$headers = array();
$headers[] = $this->requestMethod." ". $this->base_url . $relative_url . " HTTP/1.1";
$headers[] = "Authorization: Basic ".base64_encode($this->user .":". $this->pass );
$headers[] = "Host: ".$this->server .":".$this->port;
foreach( $this->headers as $ii => $head ) {
$headers[] = $head;
}
$headers[] = "Content-Length: " . strlen($this->body);
$headers[] = "User-Agent: " . $this->user_agent;
$headers[] = 'Connection: close';
$this->httpRequest = join("\r\n",$headers);
$this->xmlRequest = $this->body;
$fip = fsockopen( $this->protocol . '://' . $this->server, $this->port, $errno, $errstr, _FSOCK_TIMEOUT); //error handling?
if ( !(get_resource_type($fip) == 'stream') ) return false;
if ( !fwrite($fip, $this->httpRequest."\r\n\r\n".$this->body) ) { fclose($fip); return false; }
$rsp = "";
while( !feof($fip) ) { $rsp .= fgets($fip,8192); }
fclose($fip);
$this->headers = array(); // reset the headers array for our next request
$this->ParseResponse($rsp);
return $rsp;
}
Here is class init.
$cal = new CalDAVClient("https://calendar.yahoo.com/", "piyush138", "XXXXXXXXXXX", "calendar" );
Link to library
The following request gives "200 ok" response which runs before above request:
Request to server
OPTIONS / HTTP/1.1
Authorization: Basic cGl5dXNoMTM4OkQxZzF0YWxoZWw=
Host: calendar.yahoo.com:443
Content-Length: 0
User-Agent: DAViCalClient
Connection: close
Response from server
string(668) "HTTP/1.1 200 OK
WSHost: tardis030.cal.bf1.yahoo.com
Set-Cookie: rememberMe=deleteMe; Path=/; Max-Age=0; Expires=Thu, 18-Feb-2021 03:44:01 GMT
DAV: 1, 3, calendar-access
MS-Author-Via: DAV
Allow: HEAD, MKCOL, POST, PROPFIND, ACL, COPY, REPORT, OPTIONS, PUT, DELETE, MKCALENDAR, MOVE, GET, PROPPATCH
Content-Length: 0
Date: Fri, 19 Feb 2021 03:44:02 GMT
Age: 3
Server: ATS
Referrer-Policy: no-referrer-when-downgrade
Connection: close
Strict-Transport-Security: max-age=15552000
Expect-CT: max-age=31536000, report-uri="http://csp.yahoo.com/beacon/csp?src=yahoocom-expect-ct-report-only"
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
I also tried simplifying my password but that didn't work either
I have found the Solution.
I was using the conventional password in server call but in actual I had to use "APP Password" which you can create from
your yahoo account Under "Account security" tab.
Related
I get the request headers from the browser like this.
<?php
$DataFromBrowser='';
$DataToBrowser='';
$headers = getallheaders();
foreach($headers as $key=>$val){
$DataFromBrowser = $DataFromBrowser . $key . ': ' . $val . "\n";
}
//echo get_raw_http_request();
echo "Data from browser";
echo '<textarea rows="12" style="width:100%;">' . $DataFromBrowser . '</textarea>';
?>
And the output will look like this.
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:101.0) Gecko/20100101 Firefox/101.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,/;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Cookie: foo=bar
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Now I want to do exactly the same but for the response headers from the server. I'm aware I can do the following but it will create another connection I need the response headers of the current served page.
<?php
$URL = 'https://www.google.com';
$headers = get_headers($URL);
foreach($headers as $value) {
echo $value;
echo "<br>";
}
?>
If I change the above to http://127.0.0.1 It get's it self in a deadlock and will loop until it bombs out.
The response headers should look like this.
HTTP/1.1 200 OK
Date: Wed, 08 Jun 2022 16:53:45 GMT
Server: Apache/2.4.46 (Win64) OpenSSL/1.1.1j PHP/8.0.3
X-Powered-By: PHP/8.0.3
Content-Length: 589
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8
I'm trying to extract the Soap response's HTTP status code.
So for instance i have :
$client = new SoapClient($wsdl);
$client->__setSoapHeaders(
new SoapHeader(
$nameSpace,
'Security',
$secHeaderValue,
true
)
);
// The actual call
$response = $client->Complete($paramswebservice)
So now i'm getting the response headers, this way :
$responseHeaders = $client->__getLastResponseHeaders();
var_dump($responseHeaders);
This is the result of the vardump : a string formatted this way (web browser - page source code)
What i am doing right now to extract the http status code '200' :
/**
* Returns the HTTP Status code of $response
* #param string $response
* #return string
*/
function extract_response_http_code($response) {
$tmp = explode('\n', $response);
$array = explode(' ', $tmp[0]);
return $array[1];
}
I really don't like this solution. I would like a more robust / consistent one. Any suggestions ?
EDIT 1
As asked in the comments :
HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Content-Length: 1315
Content-Type: text/xml; charset=utf-8
Server: Microsoft-IIS/8.5
X-Powered-By: ASP.NET
Date: Thu, 30 Mar 2017 08:52:15 GMT
PHP code demo
<?php
$result="HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Content-Length: 1315
Content-Type: text/xml; charset=utf-8
Server: Microsoft-IIS/8.5
X-Powered-By: ASP.NET
Date: Thu, 30 Mar 2017 08:52:15 GMT";
preg_match("/HTTP\/\d\.\d\s*\K[\d]+/", $result,$matches);
print_r($matches);
Output:
Array
(
[0] => 200
)
I need your help guys i have some php code running on my server:
<?php
if ($_GET['id'])
$id = $_GET['id'];
$json = file_get_contents('http://www.youtubeinmp3.com/fetch/?format=JSON&video=http://www.youtube.com/watch?v=' . $id);
$data = json_decode($json, true);
$stream = $data['link'];
$url = $stream;
$output = shell_exec ('curl -I -L ' . $url);
echo "<pre>$output</pre>";
?>
and it outputs this when i go to:http://146.185.137.252/new.php?id=HgzGwKwLmgM
it outputs this:
HTTP/1.1 302 Moved Temporarily
Date: Sat, 11 Feb 2017 01:25:56 GMT
Content-Type: text/html
Connection: keep-alive
Set-Cookie: __cfduid=db002cf41b2472eb20de42ec65b16029a1486776356; expires=Sun, 11-Feb-18 01:25:56 GMT; path=/; domain=.youtubeinmp3.com; HttpOnly
X-Powered-By: PHP/5.5.38
Location: //w23.youtubeinmp3.com/download/get/?id=HgzGwKwLmgM&r=kT7YFcbHgX3m25ULP3GeWulVx9OmT2qd&t=Queen+-+Don%27t+Stop+Me+Now+%28Official+Video%29
Server: cloudflare-nginx
CF-RAY: 32f40283e57d148b-AMS
HTTP/1.1 200 OK
Server: nginx
Date: Sat, 11 Feb 2017 01:25:56 GMT
Content-Type: audio/mpeg
Content-Length: 3499136
Last-Modified: Fri, 18 Nov 2016 18:09:22 GMT
Connection: keep-alive
Content-Disposition: attachment; filename="Queen - Don't Stop Me Now (Official Video).mp3"
Accept-Ranges: bytes
Expires: 0
ETag: "582f43d2-356480"
Accept-Ranges: bytes
but i don't need al that stuff i only need to two things:
the (Location:) and the (Content-Disposition: attachment; filename=)
in two different variables so in this case i need:
//w23.youtubeinmp3.com/download/get/?id=HgzGwKwLmgM&r=kT7YFcbHgX3m25ULP3GeWulVx9OmT2qd&t=Queen+-+Don%27t+Stop+Me+Now+%28Official+Video%29
and
Queen - Don't Stop Me Now (Official Video) (i dont want the .mp3 btw)
i've searched the web everywhere but to be honest i'm a total noob at this
so if anyone can help me out that would be amazing
This code is tested. Response was copied from my Browser.
I just used curl to do the curl request and used curl_getinfo($ch,CURLINFO_REDIRECT_URL) to get the redirect link.
I also added getting the header which you do not need unless there are issues and you'd like to see the response header.
PHP
<?php
header('content-type: text/plain');
$id='HgzGwKwLmgM';
$json = file_get_contents('http://www.youtubeinmp3.com/fetch/?format=JSON&video=http://www.youtube.com/watch?v=' . $id);
$json = json_decode($json, true);
$url = $json['link'];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
$header = curl_exec($ch);
$link = curl_getinfo($ch,CURLINFO_REDIRECT_URL);
echo "\nLINK: $link\n\nHEADER: $header";
?>
RESPONSE:
LINK: http://w23.youtubeinmp3.com/download/get/?id=HgzGwKwLmgM&r=aRDQ1MGdfkY3Mm6EFxQqEVqgd9FHf81q&t=Queen+-+Don%27t+Stop+Me+Now+%28Official+Video%29
HEADER: HTTP/1.1 302 Moved Temporarily
Date: Sun, 12 Feb 2017 16:23:39 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: __cfduid=d27df4bad722b0449b88b37d4b9d9b7341486916619; expires=Mon, 12-Feb-18 16:23:39 GMT; path=/; domain=.youtubeinmp3.com; HttpOnly
X-Powered-By: PHP/5.5.38
Location: //w23.youtubeinmp3.com/download/get/?id=HgzGwKwLmgM&r=aRDQ1MGdfkY3Mm6EFxQqEVqgd9FHf81q&t=Queen+-+Don%27t+Stop+Me+Now+%28Official+Video%29
Server: cloudflare-nginx
CF-RAY: 330162e8b07e115f-DFW
If you only want the filename and the the title as you wrote on your question.
you can simply use them like this
$link = $data['link'];
$title = $data['title'];
once you have that, you can print it or make a link with it like this
echo "<a href=$link>$title</a>";
Unless you want to save the file, you don't need the curl (and the shell_Exec) part
it would look something like this:
<?php
if (isset($_GET['id'])) {
$id = $_GET['id'];
$json = file_get_contents('http://www.youtubeinmp3.com/fetch/?format=JSON&video=http://www.youtube.com/watch?v=' . $id);
$data = json_decode($json, true);
$link = $data['link'];
$title = $data['title'];
echo "<a href=$link>$title</a>";
}
?>
I am trying to communicate to an API using cURL. One of the methods require that I pass the value of the ININ-ICWS-CSRF-Token header (ie. WAhtYWxoYXlla1dBY2NvUkRJWCQxZmUxZWFhZS0xZTE0LTQyNGYtYjdhZS0zNmZjN2MxYWJmODBYCjEwLjAuNC4xNjA=) and the Set-Cookie (ie. icws_904586002=bf7c7783-6766-4c4f-862b-48f25a9a3741) so I need to extract them so I can pass them later in my code.
Here is what I did to extract the header and the body from the cURL/API respond:
$respond = curl_exec($ch);
//throw cURL exception
if($respond === false){
$errorNo = curl_errno($ch);
$errorMessage = curl_error($ch);
throw new ApiException($errorMessage, $errorNo);
}
list($header, $body) = explode("\r\n\r\n", $respond, 2);
echo '<pre>';
print_r($header);
echo '</pre>';
This is the content of the $header value:
HTTP/1.1 201 Created
ININ-ICWS-CSRF-Token: WAhtYWxoYXlla1dBY2NvUkRJWCQxZmUxZWFhZS0xZTE0LTQyNGYtYjdhZS0zNmZjN2MxYWJmODBYCjEwLjAuNC4xNjA=
ININ-ICWS-Session-ID: 904586002
Set-Cookie: icws_904586002=bf7c7783-6766-4c4f-862b-48f25a9a3741; Path=/icws/904586002
Location: /icws/904586002/connection
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Content-Type: application/vnd.inin.icws+JSON; charset=utf-8
Date: Wed, 06 May 2015 17:13:44 GMT
Server: HttpPluginHost
Content-Length: 237
I would like to get in return results like this
the value of "ININ-ICWS-CSRF-Token" is "WAhtYWxoYXlla1dBY2NvUkRJWCQxZmUxZWFhZS0xZTE0LTQyNGYtYjdhZS0zNmZjN2MxYWJmODBYCjEwLjAuNC4xNjA="
the value of the "cookie" is "ININ-ICWS-CSRF-Token: WAhtYWxoYXlla1dBY2NvUkRJWCQxZmUxZWFhZS0xZTE0LTQyNGYtYjdhZS0zNmZjN2MxYWJmODBYCjEwLjAuNC4xNjA="
You can use the http_parse_headers function to parse the headers.
$hdr_array = http_parse_headers($header);
foreach ($hdr_array as $name => $value) {
echo "The value of '$name' is '$value'<br>";
}
If you don't have http_parse_headers, you can use the code in Pedro Lobito's answer.
<?php
$myHeader = <<< LOL
HTTP/1.1 201 Created
ININ-ICWS-CSRF-Token: WAhtYWxoYXlla1dBY2NvUkRJWCQxZmUxZWFhZS0xZTE0LTQyNGYtYjdhZS0zNmZjN2MxYWJmODBYCjEwLjAuNC4xNjA=
ININ-ICWS-Session-ID: 904586002
Set-Cookie: icws_904586002=bf7c7783-6766-4c4f-862b-48f25a9a3741; Path=/icws/904586002
Location: /icws/904586002/connection
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Content-Type: application/vnd.inin.icws+JSON; charset=utf-8
Date: Wed, 06 May 2015 17:13:44 GMT
Server: HttpPluginHost
Content-Length: 237
LOL;
preg_match_all('/(.*?Token): (.*?)\s+/', $myHeader, $matches, PREG_PATTERN_ORDER);
$tokenName = $matches[1][0];
$token = $matches[2][0];
echo <<< LOL
the value of "$tokenName" is "$token"
the value of the "cookie" is "$tokenName: $token"
LOL;
?>
I am making a request through Guzzle 3.8.1 for a Jasper report (via the Jasper Server API) that is over 2MB and I'm getting a response with the correct Content-Length header but no response body.
Guzzle request:
GET /jasperserver/rest_v2/reports/projects/i3app_suite/Resource/BulkShiftExport.csv?ACCOUNT_ID=2&START_DATETIME=2015-01-01&END_DATETIME=2015-01-31 HTTP/1.1
Host: jasper.i3app:8080
User-Agent: Guzzle/3.8.1 curl/7.19.7 PHP/5.5.8
Authorization: Basic ***=
Response:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Cache-Control: private
Expires: Wed, 31 Dec 1969 17:00:00 MST
P3P: CP="ALL"
Set-Cookie: JSESSIONID=F0B0F72B65A8145B45DA9DB2BACE53D8; Path=/jasperserver/; HttpOnly, userLocale=en_US;Expires=Fri, 13-Feb-2015 18:56:44 GMT;HttpOnly
Content-Disposition: attachment; filename="BulkShiftExport.csv"
output-final: true
Content-Type: application/vnd.ms-excel
Content-Length: 2173897
Date: Thu, 12 Feb 2015 18:57:02 GMT
If I make this request through curl on the command line (or request it in a browser) I get the report as expected
GET /jasperserver/rest_v2/reports/projects/i3app_suite/Resource/BulkShiftExport.csv?ACCOUNT_ID=2&START_DATETIME=2015-01-01&END_DATETIME=2015-01-30 HTTP/1.1
Authorization: Basic ***=
User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.15.3 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
Host: jasper.i3app:8080
Accept: */*
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Cache-Control: private
< Expires: Wed, 31 Dec 1969 17:00:00 MST
< P3P: CP="ALL"
< Set-Cookie: JSESSIONID=AF1BF885354AF3E352DD9E18FA044A4B; Path=/jasperserver/; HttpOnly
< Set-Cookie: userLocale=en_US;Expires=Fri, 13-Feb-2015 19:03:42 GMT;HttpOnly
< Content-Disposition: attachment; filename="BulkShiftExport.csv"
< output-final: true
< Content-Type: application/vnd.ms-excel
< Content-Length: 2113902
< Date: Thu, 12 Feb 2015 19:03:49 GMT
<
{ [data not shown]
The only difference I could see was Accept: */* in the curl request. I tried adding that header to the guzzle request and got the same result.
When making the request through the Guzzle client it appears to take the same amount of time (5-6 seconds) to receive the response, and it sets the Content-Length header, but the response body is empty. Why am I getting an empty response body though Guzzle which is using curl but not when using curl on the command line? Is there an option I need to set to make this work?
$request = $this->getGuzzleClient()->createRequest('GET');
$config = $this->getConfig();
$url = new Url(
$config['scheme'],
$config['host'],
$config['user'],
$config['pass'],
$config['port'],
$config['path'] . $reportPath . '.' . $format,
new QueryString($parameters)
);
$request->setUrl($url);
$response = $request->send();
...
public function getGuzzleClient()
{
if (!$this->restClient) {
$client = new GuzzleClient();
$this->setRestClient($client);
}
return $this->restClient;
}
In my case, I was using MockHandler mistakenly.