title: Shopware REST Api - Invalid or missing auth
body: <p>I'm trying to access the REST api of Shopware. I'm using version 5.1.3 of Shopware. I'm using the code of the <a href="https://developers.shopware.com/developers-guide/rest-api/" rel="nofollow">documentation</a>. </p>
  
  <p>I always get a http code 400 (Invalid or missing auth) back.</p>
  
  <p>When I try to access the API via Google Chrome it works after login with http authentication, so the credentials should be OK.</p>
  
  <p>I guess the Authentication header Chrome sends differs from the one I send with PHP curl.</p>
  
  <p>With Chrome:</p>
  
  <pre><code>Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
  Accept-Encoding:gzip, deflate, sdch
  Accept-Language:nl-NL,nl;q=0.8,en-US;q=0.6,en;q=0.4
  Authorization:Digest username="demo", realm="Shopware REST-API", nonce="7aa6aa7e8089c60e5930cb45ead39197", uri="/api/articles", algorithm=MD5, response="cee77e425508605dfbcf2deda8f83938", opaque="d75db7b160fe72d1346d2bd1f67bfd10", qop=auth, nc=0000001e, cnonce="8b5121e862c4fce1"
  Cache-Control:max-age=0
  Connection:keep-alive
  Cookie:session-1=2d0cb2941684d2767e76ffeb48c7337706cba39c
  Host:shopware.example.com
  Upgrade-Insecure-Requests:1
  User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36
  </code></pre>
  
  <p>With PHP Curl </p>
  
  <pre><code>GET /api/articles? HTTP/1.1\r\n
  Host: shopware.example.com\r\n
  Authorization: Digest username="demo",realm="",nonce="806c9770a53bf2f82b87734a9d8eb98c",uri="/api/articles?",cnonce="60e6c8db046db8f4e63fece37e38f92e",nc=00000001,algorithm=MD5,response="299069d4659af386a4ec7058796267c2",qop="auth",opaque="d75db7b160fe72d1346d2bd1f67bfd10"\r\n
  User-Agent: Shopware shopwareApiClient\r\n
  Accept: */*\r\n
  Content-Type: application/json; charset=utf-8\r\n
  Content-Length: 2\r\n
  </code></pre>
  
  <p>Extra PHP curl directives to get header information:</p>
  
  <pre><code>curl_setopt($this-&gt;cURL, CURLINFO_HEADER_OUT, true);
  print_r(curl_getinfo($this-&gt;cURL, CURLINFO_HEADER_OUT ));
  </code></pre>
  
  <p>The code I use:</p>
  
  <pre><code>&lt;?php
  
  namespace App;
  
  class shopwareApiClient
  {
  
      const METHOD_GET = 'GET';
      const METHOD_PUT = 'PUT';
      const METHOD_POST = 'POST';
      const METHOD_DELETE = 'DELETE';
  
      protected $validMethods = array(
          self::METHOD_GET,
          self::METHOD_PUT,
          self::METHOD_POST,
          self::METHOD_DELETE
      );
      protected $apiUrl;
      protected $cURL;
  
      public function __construct($apiUrl, $username, $apiKey)
      {
          $this-&gt;apiUrl = rtrim($apiUrl, '/') . '/';
          //Initializes the cURL instance
          $this-&gt;cURL = curl_init();
          curl_setopt($this-&gt;cURL, CURLOPT_RETURNTRANSFER, true);
          curl_setopt($this-&gt;cURL, CURLOPT_FOLLOWLOCATION, false);
          curl_setopt($this-&gt;cURL, CURLOPT_USERAGENT, 'Shopware shopwareApiClient');
          curl_setopt($this-&gt;cURL, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
          curl_setopt($this-&gt;cURL, CURLOPT_USERPWD, $username . ':' . $apiKey);
          curl_setopt($this-&gt;cURL, CURLOPT_HTTPHEADER, array(
              'Content-Type: application/json; charset=utf-8',
          ));
          curl_setopt($this-&gt;cURL, CURLINFO_HEADER_OUT, true);
      }
  
      public function call($url, $method = self::METHOD_GET, $data = array(), $params = array())
      {
          if (!in_array($method, $this-&gt;validMethods))
          {
              throw new Exception('Invalid HTTP-Methode: ' . $method);
          }
          $queryString = '';
          if (!empty($params))
          {
              $queryString = http_build_query($params);
          }
          $url = rtrim($url, '?') . '?';
          $url = $this-&gt;apiUrl . $url . $queryString;
          $dataString = json_encode($data);
          curl_setopt($this-&gt;cURL, CURLOPT_URL, $url);
          curl_setopt($this-&gt;cURL, CURLOPT_CUSTOMREQUEST, $method);
          curl_setopt($this-&gt;cURL, CURLOPT_POSTFIELDS, $dataString);
          $result = curl_exec($this-&gt;cURL);
          dd(curl_getinfo($this-&gt;cURL, CURLINFO_HEADER_OUT ));
          $httpCode = curl_getinfo($this-&gt;cURL, CURLINFO_HTTP_CODE);
          return $this-&gt;prepareResponse($result, $httpCode);
      }
  
      public function get($url, $params = array())
      {
          return $this-&gt;call($url, self::METHOD_GET, array(), $params);
      }
  
      public function post($url, $data = array(), $params = array())
      {
          return $this-&gt;call($url, self::METHOD_POST, $data, $params);
      }
  
      public function put($url, $data = array(), $params = array())
      {
          return $this-&gt;call($url, self::METHOD_PUT, $data, $params);
      }
  
      public function delete($url, $params = array())
      {
          return $this-&gt;call($url, self::METHOD_DELETE, array(), $params);
      }
  
      protected function prepareResponse($result, $httpCode)
      {
          echo "&lt;h2&gt;HTTP: $httpCode&lt;/h2&gt;";
          if (null === $decodedResult = json_decode($result, true))
          {
              $jsonErrors = array(
                  JSON_ERROR_NONE =&gt; 'No error occurred',
                  JSON_ERROR_DEPTH =&gt; 'The maximum stack depth has been reached',
                  JSON_ERROR_CTRL_CHAR =&gt; 'Control character issue, maybe wrong encoded',
                  JSON_ERROR_SYNTAX =&gt; 'Syntaxerror',
              );
              echo "&lt;h2&gt;Could not decode json&lt;/h2&gt;";
              echo "json_last_error: " . $jsonErrors[json_last_error()];
              echo "&lt;br&gt;Raw:&lt;br&gt;";
              echo "&lt;pre&gt;" . print_r($result, true) . "&lt;/pre&gt;";
              return;
          }
          if (!isset($decodedResult['success']))
          {
              echo "Invalid Response";
              return;
          }
          if (!$decodedResult['success'])
          {
              echo "&lt;h2&gt;No Success&lt;/h2&gt;";
              echo "&lt;p&gt;" . $decodedResult['message'] . "&lt;/p&gt;";
              return;
          }
          echo "&lt;h2&gt;Success&lt;/h2&gt;";
          if (isset($decodedResult['data']))
          {
              echo "&lt;pre&gt;" . print_r($decodedResult['data'], true) . "&lt;/pre&gt;";
          }
          return $decodedResult;
      }
  }
  </code></pre>
  
  <p>Edit: Found a <a href="https://bugs.php.net/bug.php?id=70101" rel="nofollow">php bug report</a> which states there is a bug in PHP with Windows on version 5.6 and above. I'm using XAMP on Windows. I'm going to try it on linux to see if it does work.</p>