/** * Creates a default handler stack that can be used by clients. * * The returned handler will wrap the provided handler or use the most * appropriate default handler for you system. The returned HandlerStack has * support for cookies, redirects, HTTP error exceptions, and preparing a body * before sending. * * The returned handler stack can be passed to a client in the "handler" * option. * * @param callable $handler HTTP handler function to use with the stack. If no * handler is provided, the best handler for your * system will be utilized. * * @return HandlerStack */ public static function create(callable $handler = null) { $stack = new self($handler ?: choose_handler()); $stack->push(Middleware::httpErrors(), 'http_errors'); $stack->push(Middleware::redirect(), 'allow_redirects'); $stack->push(Middleware::cookies(), 'cookies'); $stack->push(Middleware::prepareBody(), 'prepare_body'); return $stack; }
/** * Construct a FamilySearch Client. * * @param array $options A keyed array of configuration options for the client. Available options: * * * `clientId` - Required for authentication. * * `redirectURI` - Required for authentication. * * `accessToken` - If the access token is set then the `clientId` and `redirectURI` are not needed. * * `environment` - `production`, `beta`, or `sandbox`; defaults to `sandbox`. * * `userAgent` - A string which will be prepended to the default user agent string. * * `pendingModifications` - An array of pending modifications that should be enabled. * * `logger` - A `Psr\Log\LoggerInterface`. A logger can also be registered via the `setLogger()` method but passing it in as an option during instantiation ensures that the logger will see all client events. * * `middleware` - An array of [Guzzle Middleware](http://docs.guzzlephp.org/en/latest/handlers-and-middleware.html#middleware). * * `httpExceptions` - When `true`, the client will throw a `Gedcomx\Rs\Client\Exception\GedcomxApplicationException` when a 400 or 500 level HTTP response is received. * * `throttling` - When `true`, the client will automatically handled throttled responses. */ public function __construct($options = array()) { if (isset($options['redirectURI'])) { $this->redirectURI = $options['redirectURI']; } if (isset($options['clientId'])) { $this->clientId = $options['clientId']; } // Set the proper homeURI based on the environment. // Default to sandbox. $environment = ''; $baseURI = ''; if (isset($options['environment'])) { $environment = $options['environment']; } switch ($environment) { case 'production': $baseURI = 'https://familysearch.org'; break; case 'beta': $baseURI = 'https://beta.familysearch.org'; break; default: $baseURI = 'https://sandbox.familysearch.org'; break; } $this->homeURI = $baseURI . '/platform/collection'; // Middleware $this->stack = new HandlerStack(); $this->stack->setHandler(new CurlHandler()); $this->stack->push(Middleware::httpErrors()); $this->stack->push(Middleware::redirect()); // Pending modifications if (isset($options['pendingModifications']) && is_array($options['pendingModifications']) && count($options['pendingModifications']) > 0) { $experiments = join(",", $options['pendingModifications']); $this->stack->push(Middleware::mapRequest(function (RequestInterface $request) use($experiments) { return $request->withHeader('X-FS-Feature-Tag', $experiments); })); } // Throttling if (isset($options['throttling']) && $options['throttling'] === true) { $this->stack->push(ThrottlingMiddleware::middleware()); } // Set user agent string $userAgent = 'gedcomx-php/1.1.1 ' . \GuzzleHttp\default_user_agent(); if (isset($options['userAgent'])) { $userAgent = $options['userAgent'] . ' ' . $userAgent; } // Custom middleware if (isset($options['middleware']) && is_array($options['middleware'])) { foreach ($options['middleware'] as $middleware) { $this->stack->push($middleware); } } // This goes last so that it sees the final request and response if (isset($options['logger'])) { $this->setLogger($options['logger']); } $clientOptions = ['handler' => $this->stack, 'base_uri' => $baseURI, 'headers' => ['User-Agent' => $userAgent]]; // Throw exceptions if (isset($options['httpExceptions']) && $options['httpExceptions'] === true) { $clientOptions['http_errors'] = true; } else { $clientOptions['http_errors'] = false; } // Create client $this->client = new Client($clientOptions); $this->stateFactory = new FamilyTreeStateFactory(); $this->createHomeState(); $this->createTreeState(); if (isset($options['accessToken'])) { $this->treeState->authenticateWithAccessToken($options['accessToken']); } }
public function testInvokesOnRedirectForRedirects() { $mock = new MockHandler([new Response(302, ['Location' => 'http://test.com']), new Response(200)]); $stack = new HandlerStack($mock); $stack->push(Middleware::redirect()); $handler = $stack->resolve(); $request = new Request('GET', 'http://example.com?a=b'); $call = false; $promise = $handler($request, ['allow_redirects' => ['max' => 2, 'on_redirect' => function ($request, $response, $uri) use(&$call) { $this->assertEquals(302, $response->getStatusCode()); $this->assertEquals('GET', $request->getMethod()); $this->assertEquals('http://test.com', (string) $uri); $call = true; }]]); $promise->wait(); $this->assertTrue($call); }