public function testRequestCanSetAndRetrieveUri() { $request = new Request(); $request->setUri('/foo'); $this->assertEquals('/foo', $request->getUri()); $this->assertInstanceOf('Zend\\Uri\\Uri', $request->uri()); $this->assertEquals('/foo', $request->uri()->toString()); $this->assertEquals('/foo', $request->getUri()); }
/** * Parse Digest Authorization header * * @param string $header Client's Authorization: HTTP header * @return array|false Data elements from header, or false if any part of * the header is invalid */ protected function _parseDigestAuth($header) { $temp = null; $data = array(); // See ZF-1052. Detect invalid usernames instead of just returning a // 400 code. $ret = preg_match('/username="******"]+)"/', $header, $temp); if (!$ret || empty($temp[1]) || !ctype_print($temp[1]) || strpos($temp[1], ':') !== false) { $data['username'] = '******'; } else { $data['username'] = $temp[1]; } $temp = null; $ret = preg_match('/realm="([^"]+)"/', $header, $temp); if (!$ret || empty($temp[1])) { return false; } if (!ctype_print($temp[1]) || strpos($temp[1], ':') !== false) { return false; } else { $data['realm'] = $temp[1]; } $temp = null; $ret = preg_match('/nonce="([^"]+)"/', $header, $temp); if (!$ret || empty($temp[1])) { return false; } if (!ctype_xdigit($temp[1])) { return false; } else { $data['nonce'] = $temp[1]; } $temp = null; $ret = preg_match('/uri="([^"]+)"/', $header, $temp); if (!$ret || empty($temp[1])) { return false; } // Section 3.2.2.5 in RFC 2617 says the authenticating server must // verify that the URI field in the Authorization header is for the // same resource requested in the Request Line. $rUri = $this->_request->uri(); $cUri = UriFactory::factory($temp[1]); // Make sure the path portion of both URIs is the same if ($rUri->getPath() != $cUri->getPath()) { return false; } // Section 3.2.2.5 seems to suggest that the value of the URI // Authorization field should be made into an absolute URI if the // Request URI is absolute, but it's vague, and that's a bunch of // code I don't want to write right now. $data['uri'] = $temp[1]; $temp = null; $ret = preg_match('/response="([^"]+)"/', $header, $temp); if (!$ret || empty($temp[1])) { return false; } if (32 != strlen($temp[1]) || !ctype_xdigit($temp[1])) { return false; } else { $data['response'] = $temp[1]; } $temp = null; // The spec says this should default to MD5 if omitted. OK, so how does // that square with the algo we send out in the WWW-Authenticate header, // if it can easily be overridden by the client? $ret = preg_match('/algorithm="?(' . $this->_algo . ')"?/', $header, $temp); if ($ret && !empty($temp[1]) && in_array($temp[1], $this->_supportedAlgos)) { $data['algorithm'] = $temp[1]; } else { $data['algorithm'] = 'MD5'; // = $this->_algo; ? } $temp = null; // Not optional in this implementation $ret = preg_match('/cnonce="([^"]+)"/', $header, $temp); if (!$ret || empty($temp[1])) { return false; } if (!ctype_print($temp[1])) { return false; } else { $data['cnonce'] = $temp[1]; } $temp = null; // If the server sent an opaque value, the client must send it back if ($this->_useOpaque) { $ret = preg_match('/opaque="([^"]+)"/', $header, $temp); if (!$ret || empty($temp[1])) { // Big surprise: IE isn't RFC 2617-compliant. $headers = $this->_request->headers(); if (!$headers->has('User-Agent')) { return false; } $userAgent = $headers->get('User-Agent')->getFieldValue(); if (false === strpos($userAgent, 'MSIE')) { return false; } $temp[1] = ''; $this->_ieNoOpaque = true; } // This implementation only sends MD5 hex strings in the opaque value if (!$this->_ieNoOpaque && (32 != strlen($temp[1]) || !ctype_xdigit($temp[1]))) { return false; } else { $data['opaque'] = $temp[1]; } $temp = null; } // Not optional in this implementation, but must be one of the supported // qop types $ret = preg_match('/qop="?(' . implode('|', $this->_supportedQops) . ')"?/', $header, $temp); if (!$ret || empty($temp[1])) { return false; } if (!in_array($temp[1], $this->_supportedQops)) { return false; } else { $data['qop'] = $temp[1]; } $temp = null; // Not optional in this implementation. The spec says this value // shouldn't be a quoted string, but apparently some implementations // quote it anyway. See ZF-1544. $ret = preg_match('/nc="?([0-9A-Fa-f]{8})"?/', $header, $temp); if (!$ret || empty($temp[1])) { return false; } if (8 != strlen($temp[1]) || !ctype_xdigit($temp[1])) { return false; } else { $data['nc'] = $temp[1]; } $temp = null; return $data; }
/** * match(): defined by Route interface. * * @see Route::match() * @param Request $request * @return RouteMatch */ public function match(Request $request, $pathOffset = null) { $uri = $request->uri(); $path = $uri->getPath(); if ($pathOffset !== null) { if (strpos($path, $this->route) === $pathOffset) { return new RouteMatch($this->defaults, $this); } } else { if ($path === $this->route) { return new RouteMatch($this->defaults, $this); } } return null; }
/** * match(): defined by Route interface. * * @see Route::match() * @param Request $request * @return RouteMatch */ public function match(Request $request, $pathOffset = null) { $uri = $request->uri(); $path = $uri->getPath(); if ($pathOffset !== null) { $result = preg_match('#\G' . $this->regex . '#i', $path, $match, null, $pathOffset); } else { $result = preg_match('#^' . $this->regex . '$#i', $path, $match); } if (!$result) { return null; } foreach ($match as $key => $value) { if (is_numeric($key) || is_int($key)) { unset($match[$key]); } } $matches = array_merge($this->defaults, $match); $this->matches = $matches; return new RouteMatch($matches, $this); }