0

I'm trying to reproduce the following in PHP:

curl -X GET "https://example.com/webservice" --user <Sender ID>:<password> -H  "accept: text/plain"

This is what I have so far:

$this->ch = curl_init();
curl_setopt_array( $this->ch, array(
CURLOPT_URL => 'https://example.com/webservice',
CURLOPT_HTTPHEADER => 'accept: text/plain',
CURLOPT_HTTPAUTH => CURLAUTH_ANY,
CURLOPT_USERPWD => $this->sender_id . ':' . $this->password,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT=>10,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT=>20 ) );
$result = curl_exec( $this->ch );

When I use curl_getinfo() I see a status code of 302 and REDIRECT_URL is https://example.com/webservice/ so it looks like the redirect is not being followed. I was expecting a status code of 200 and REDIRECT_URL to be empty. I tried accessing the web service by browser. It prompts for the password and then, after entering it, the browser successfully redirects. What am I missing?

VERBOSE output (with the URLs masked):

* Re-using existing connection! (#0) with host example.com
* Connected to example.com (216.81.87.19) port 443 (#0)
> GET /webservice HTTP/1.1
Host: example.com
Accept: */*

< HTTP/1.1 302 
< Date: Wed, 28 Aug 2019 17:25:33 GMT
< Server: Apache/2.4.39 (Unix) OpenSSL/1.0.2r
< Public-Key-Pins: pin-sha256="iWMi9jzvh3eEA6d6V1rooHD5721iut3mUupum14lLv4="; max-age=2592000; includeSubDomains
< Webfarm_Build_Host: WebFarm Build Ran on xxxxxxxxx.example.com
< Webfarm_Build_Date: Mon Jun 10 19:15:50 EDT 2019
< Webfarm_Version: Release-V12
< Webfarm_SSO_Agent: DMZWEBFARM
< Webfarm_SSO_Agent_Mode: simple
< Webgate_Product: Oracle_Access_Manager
< Webgate_Component: WebGate
< Webgate_Webserver: APACHE2.2/2.4
< Webgate_Webserver_OpenSSL_Version: OpenSSL 1.0.2r 26 Feb 2019
< Webgate_Platform: linux64
< Webgate_Language_Type: en-us
< Webgate_Version_Release: 11.1.2.3.0 
< Webgate_Version_Release_Date: 07/01/2016
< X-Frame-Options: SAMEORIGIN
< Location: https://example.com/webservice/
< X-XSS-Protection: 1; mode=block
< Content-Length: 0
< Strict-Transport-Security: max-age=31536000; includeSubDomains
< Proxy-Connection: Keep-Alive
< Connection: Keep-Alive
< Set-Cookie: EDME_EAPIS_PRD_apache-llb=!KgEF2eiXGNLd6aDBees2zCqa01Pqg/9GbgMNYbuHA7Jzql7b1eBMCnS5PyhwShD5S+nUZWKbTBYH9eY=; path=/; Httponly; Secure
< 
* Curl_http_done: called premature == 0
* Connection #0 to host example.com left intact
George
  • 934
  • 2
  • 10
  • 21
  • Possible duplicate of https://stackoverflow.com/a/28458522/2776343 ? – Manzolo Aug 28 '19 at 15:59
  • That one doesn't seem to apply. He forgot to use curl_exec. Also, I do set CURLOPT_FOLLOWLOCATION to true. I don't have open_basedir set and I'm not is safe mode. – George Aug 28 '19 at 16:14
  • But second reply @George ? $redirectURL = curl_getinfo($this->ch,CURLINFO_EFFECTIVE_URL ); – Manzolo Aug 28 '19 at 16:16
  • CURLINFO_EFFECTIVE_URL is the URL I specified, i.e., https: //example.com/webservice – George Aug 28 '19 at 16:58
  • show us the curl verbose log. ```$tmp=tmpfile();curl_setopt_array($ch,[CURLOPT_VERBOSE=>1,CURLOPT_STDERR=>$tmp]);curl_exec($ch);/*https://bugs.php.net/bug.php?id=76268*/rewind($tmp);var_dump(stream_get_contents($tmp));``` – hanshenrik Aug 28 '19 at 17:11
  • OK, I edited the question to add the verbose log – George Aug 28 '19 at 17:31

1 Answers1

0

If you are in safe_mode or you have open_basedir set, you'll need to do something like this (tweak to suit):

function curlWithFollow($ch)
{
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $content = curl_exec($ch);
    $httpStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    if (in_array($httpStatus, [301, 302]) {
        preg_match('/(Location:|URI:)(.*?)\n/', $data, $matches);

        if (isset($matches[2])) {
            $redirectUrl = trim($matches[2]);

            if ($redirectUrl !== '') {
                curl_setopt($ch, CURLOPT_URL, $redirectUrl);
                return curlWithFollow($ch);
            }
        }
    }

    return $content;
}

Call it something like this:

$ch = curl_init($url);
$content = curlWithFollow($ch);
curl_close($ch);
delboy1978uk
  • 12,118
  • 2
  • 21
  • 39