پیکربندی
چگونه یک کلاینت بسازید، همهٔ گزینهها، و آنچه پیش از فرستادن درخواست رد میکند.
گزینهها
use OpenEmail\OpenEmail; $client = new OpenEmail(); OpenEmail::init(timeout: 10);OpenEmail::getClient()->me->ping(); $billing = new OpenEmail(apiKey: (string) getenv('OPENEMAIL_BILLING_API_KEY')); echo $client->mode, ' ', $billing->mode, PHP_EOL;| نقطهٔ ورود | چه چیزی به شما میدهد |
|---|---|
| new OpenEmail(...) | کلاینتی که از آرگومانهای نامداری که میدهید ساخته میشود. هر چیزی که ندهید از محیط خوانده میشود: اگر هیچ اعتبارنامهای ندهید، کلید از OPENEMAIL_API_KEY یا توکن از OPENEMAIL_ACCESS_TOKEN، و اگر URL پایه ندهید، URL پایه از OPENEMAIL_BASE_URL. |
| OpenEmail::createClient(...) | همان کلاینتِ new OpenEmail(...)، برای کدی که ترجیح میدهد یک factory را فراخوانی کند. |
| OpenEmail::init(...) | یک کلاینت میسازد، آن را بهعنوان کلاینت مشترک نگه میدارد و برمیگرداند. همان آرگومانهای نامدار را میگیرد. |
| OpenEmail::getClient() | کلاینت مشترک، از هر جای فرایند. اگر پیش از init فراخوانی شود، در نخستین فراخوانی یکی از محیط میسازد. |
| OpenEmail::resetClient() | کلاینت مشترک را کنار میگذارد، پس getClient() بعدی یک کلاینت تازه میسازد، که همان چیزی است که یک آزمون میان موردها میخواهد. |
تبدیل getenv() به رشته عمدی است. متغیری که تنظیم نشده به یک کلید خالی تبدیل میشود، که کلاینت آن را با پیامی رد میکند که نام متغیر مورد نیازش را میآورد، در حالی که null بیصدا به OPENEMAIL_API_KEY برمیگشت.
use OpenEmail\Http\CurlHttpClient;use OpenEmail\OpenEmail; $client = new OpenEmail( apiKey: (string) getenv('OPENEMAIL_API_KEY'), baseUrl: 'https://api.openemail.uk', httpClient: new CurlHttpClient(), maxRetries: 2, timeout: 30, userAgent: 'billing-service/1.4', headers: ['X-Team' => 'billing'], disableUpdateNotice: true,);| گزینه | پیشفرض | توضیحات |
|---|---|---|
| apiKey: | OPENEMAIL_API_KEY | باید با oe_live_ یا oe_test_ شروع شود. فقط وقتی از محیط خوانده میشود که نه apiKey: بدهید و نه accessToken:. |
| accessToken: | OPENEMAIL_ACCESS_TOKEN | یک توکن دسترسی OAuth، یا یک callable که توکنی برگرداند. بخش «توکنهای دسترسی OAuth» در پایین را ببینید. یک کلید یا یک توکن بدهید، هرگز هر دو را. |
| baseUrl: | https://api.openemail.uk | یا OPENEMAIL_BASE_URL. اسلشهای پایانی حذف میشوند، و جلوی یک نام میزبان خالی https:// گذاشته میشود، یا جلوی میزبانی روی همین دستگاه http://: localhost، یک نشانی 127.x.x.x یا ::1. اعتبارنامه هرگز با http ساده به میزبان دیگری فرستاده نمیشود، و 0.0.0.0 یا [::] هنگام ساختن کلاینت رد میشود، چون اینها نشانیهاییاند که سرور روی آنها گوش میدهد، نه نشانیهایی برای فرستادن درخواست. |
| timeout: | 30 | ثانیه برای هر تلاش، نه برای هر فراخوانی، که برقراری اتصال و خواندن کل پاسخ را در بر میگیرد. 0 آن را خاموش میکند. files->upload دستکم 600 ثانیه صبر میکند، مگر آنکه روی همان فراخوانی timeout: بدهید. |
| maxRetries: | 2 | تلاشهای اضافی پس از تلاش نخست، روی فراخوانیهایی که تکرارشان بیخطر است. روی کلاینت تنظیم میشود، نه برای هر فراخوانی. 0 تلاشهای دوباره را خاموش میکند. |
| httpClient: | CurlHttpClient | لایهٔ HTTP: هر چیزی که OpenEmail\Http\HttpClient را پیادهسازی کند، مانند Psr18HttpClient روی Guzzle یا Symfony HttpClient، یا یک نمونهٔ ساختگی در آزمون. صفحهٔ «کلاینتهای HTTP» هر کدام را شرح میدهد. |
| headers: | [] | با هر درخواست فرستاده میشود. |
| userAgent: | openemail-php/<version> | با هر درخواست فرستاده میشود. |
| disableUpdateNotice: | false | بررسی یکبار در هر فرایند برای یافتن نسخهٔ تازهتر روی Packagist را رد میکند. این بررسی فقط در خط فرمان و وقتی اجرا میشود که خروجی استاندارد یک ترمینال باشد، و OPENEMAIL_DISABLE_UPDATE_NOTICE هم آن را خاموش میکند. |
متغیرهای محیطی
| متغیر | چه میکند |
|---|---|
| OPENEMAIL_API_KEY | کلیدی که یک کلاینت به کار میبرد، وقتی نه apiKey: بدهید و نه accessToken:. |
| OPENEMAIL_ACCESS_TOKEN | یک توکن دسترسی OAuth، که فقط وقتی خوانده میشود که هیچکدام از دو اعتبارنامه را ندهید و OPENEMAIL_API_KEY تنظیم نشده باشد، پس کلیدی که در محیط باشد مقدم است. |
| OPENEMAIL_BASE_URL | URL پایه، وقتی هیچ URLای ندهید. به میزبان خالی مانند localhost:2222 طرح نشانی (scheme) افزوده میشود. |
| OPENEMAIL_DISABLE_UPDATE_NOTICE | هر مقدار غیرخالی، اعلان بهروزرسانی را برای همهٔ کلاینتهای آن فرایند خاموش میکند. |
| HTTPS_PROXY و NO_PROXY، یا https_proxy و no_proxy | پراکسیای که cURL از طریق آن وصل میشود، و میزبانهایی که مستقیم وصل میشوند. بخش «پراکسیها و TLS» در پایین را ببینید. |
هر متغیر نخست با getenv() خوانده میشود، سپس از $_SERVER و $_ENV، پس مقداری که فریمورکتان از یک فایل .env بارگذاری کرده هم به حساب میآید. متغیری که تنظیم شده اما خالی است، تنظیمنشده به حساب میآید.
پیش از ارسال چه چیزی را رد میکند
اینها OpenEmail\Exception\InvalidArgumentException را از همان خطی که مقدار نادرست در آن بوده پرتاب میکنند، بهجای آنکه بهصورت شکستی گیجکننده در نخستین ارسال شما ظاهر شوند. پیام میگوید چه چیزی نادرست بوده و بهجایش چه باید داد، و هرگز اعتبارنامه را تکرار نمیکند.
| رد میشود | چرا |
|---|---|
| بدون هیچ اعتبارنامهای | نه apiKey: داده شده و نه accessToken:، و هیچکدام از دو متغیر هم تنظیم نشده بود، پس چیزی برای احراز هویت نیست. هنگام ساختن کلاینت پرتاب میشود. |
| یک کلید و یک توکن با هم | هر درخواست یک اعتبارنامه حمل میکند، پس کلاینت نمیتواند بفهمد منظورتان کدام بوده. |
| یک کوکی نشست، یک توکن نشست یا کلیدی برای سرویسی دیگر | تنها oe_live_ و oe_test_ اینجا احراز هویت میکنند، و API هم همین را میگوید. این بررسی فقط یک پیشوند است و نه بیشتر، پس کلید باطلشده همچنان روی سیم شکست میخورد، بهصورت یک AuthenticationException. |
| baseUrl: ای که یک URL با http یا https نیست، یا URLای که نام کاربری یا گذرواژه در آن باشد | به چیز دیگری نمیتوان دسترسی یافت، و جای اعتبارنامه در apiKey: یا accessToken: است، نه در URL. هنگام ساختن کلاینت پرتاب میشود. |
| اعتبارنامهای که با http ساده به میزبانی فرستاده شود که روی همین دستگاه نیست | توسط خود فراخوانی و پیش از فرستادن هر چیزی پرتاب میشود. از یک URL پایه با https استفاده کنید. |
| timeout: منفی | تعداد ثانیهها را بدهید، یا 0 برای بدون مهلت. هنگام ساختن کلاینت پرتاب میشود، یا برای مهلتی که به یک فراخوانی داده شده، توسط همان فراخوانی. |
| نام سرآیندی که یک token معتبر HTTP نیست، یا شکست خط یا هر نویسهٔ کنترلی دیگر در مقدار یک سرآیند | در headers:، userAgent: و idempotencyKey: بررسی میشود، چون شکست خط یک سرآیند دوم را آغاز میکرد. فاصلهها، tabها و شکستهای خط در دو سر مقدار پیش از آن حذف میشوند، همانطور که fetch حذفشان میکند، پس کلیدی که از فایلی خوانده شود که با یک خط جدید تمام میشود باز هم کار میکند. |
| id خالی یا تماماً نقطه در هر متدی | هنگام فراخوانی متد پرتاب میشود. بخشی از مسیر که فقط نقطه باشد را هر تجزیهگر URL حذف میکند، پس درخواست به اندپوینت دیگری میرسید. شناسهای که UTF-8 معتبر نباشد نیز رد میشود. |
| محتوای پیوستی که base64 نیست | یک رشته همیشه بهصورت base64 خوانده میشود، پس بایتهای خام درون آن بهصورت دادههای بیمعنی فرستاده میشوند. آنها را با OpenEmail::toBase64() کدگذاری کنید، یا یک SplFileInfo، یک stream یا یک stream از نوع PSR-7 بدهید تا کلاینت کدگذاریاش کند. |
این کلاس InvalidArgumentException خودِ PHP را گسترش میدهد، پس کدی که از پیش آن را میگیرد همچنان کار میکند، و مانند هر استثنای دیگری که بسته پرتاب میکند، OpenEmail\Exception\OpenEmailException را پیادهسازی میکند. مقداری از نوع نادرست، مثلاً عددی بهجای شناسهٔ رشتهای، یک TypeError از خودِ PHP است، چون هر متد نوعهایش را اعلام میکند.
گزینهای به نام testMode: وجود ندارد و نخواهد داشت. طرح کلید بخشی از خودِ اعتبارنامه است نه یک اشاره، پس حالت، ویژگیِ کلید است. $client->mode پیشوند را میخواند، live یا test، و دربارهٔ چیزی تصمیم نمیگیرد.
یک کلاینت، چند کلید
کلاینت را یک بار بسازید و به اشتراک بگذارید. کلاینت تازه برای هر درخواست، بیهیچ سودی اتصال باز خود را دور میریزد، و هیچیک از وضعیتهای روی آن مخصوص یک فراخواننده نیست.
برای موردی که در غیر این صورت به ازای هر کلید یک کلاینت لازم میکرد، مثلاً کاری که از طرف چند فضای کاری ارسال میکند، apiKey: را روی همان فراخوانی بدهید. برای آن درخواست جایگزین سرآیند Authorization میشود و چیزی روی کلاینت باقی نمیگذارد.
$message = [ 'from' => '[email protected]', 'to' => '[email protected]', 'subject' => 'Your invoice', 'text' => 'Attached.',];$workspaceKey = (string) getenv('OPENEMAIL_API_KEY'); $client->emails->send($message); $client->emails->send($message, apiKey: $workspaceKey); $client->threads->list(folder: 'inbox', apiKey: $workspaceKey);$client->webhooks->list(apiKey: $workspaceKey);هر متدی بیرون از tempMail آن را بهعنوان آخرین آرگومان نامدارش میگیرد، روی یک فهرست پس از فیلترها، و متدهای tempMail بهجای آن inboxToken: میگیرند. پیش از فرستادن درخواست و با همان قاعدهای که کلاینت به کار میبرد بررسی میشود، پس یک غلط تایپی بهجای 401 دربارهٔ اعتبارنامهای که باید بگردید و پیدایش کنید، یک InvalidArgumentException دربارهٔ apiKey دادهشده به این فراخوانی پرتاب میکند. فراخوانیای که دوباره تلاش میشود همان کلیدی را نگه میدارد که به آن داده شده بود.
$client->mode کلیدی را توصیف میکند که کلاینت در زمان ساخت با آن ساخته شده، و از بازنویسیهای موردی پیروی نمیکند. وقتی یک کلاینت به چند کلید خدمت میکند دیگر یک حالت یکتا برای گزارش وجود ندارد، پس آن را از روی کلیدی که دادهاید بخوانید. var_dump($client) حالت و URL پایه را نشان میدهد، هرگز کلید را، و هر پارامتری که اعتبارنامه میگیرد با #[\SensitiveParameter] علامت خورده است، پس stack trace بهجای آن یک جاینگهدار چاپ میکند.
اندپوینتهایی که هیچ متدی آنها را نمیپوشاند
$client->raw لایهٔ انتقالی است که هر متد از آن عبور میکند. $client->raw->request() مسیری را فراخوانی میکند که هنوز هیچ متدی آن را نمیپوشاند، با اعمال اعتبارنامه، URL پایه، مهلت و سیاست تلاش دوبارهٔ کلاینت، و بدنهٔ تجزیهشده را همانگونه برمیگرداند که یک متد برمیگرداند.
$ping = $client->raw->request('/ping'); $label = $client->raw->request('/labels', method: 'POST', body: ['name' => 'Invoices']); var_dump($ping, $label);| آرگومان نامدار | چه میکند |
|---|---|
| method: | GET، مگر آنکه چیز دیگری بگویید: POST، PUT، PATCH یا DELETE. |
| query: | یک آرایه از پارامترهای کوئری. مقدارهای null و خالی کنار گذاشته میشوند، یک فهرست با کاما به هم وصل میشود، و یک DateTimeInterface بهصورت یک لحظهٔ ISO 8601 به وقت UTC فرستاده میشود. |
| body: | یک آرایه که بهصورت JSON فرستاده میشود. |
| raw: و contentType: | بایتهایی که همانطور که هستند فرستاده میشوند، بهصورت یک رشته، یک منبع stream، یک SplFileInfo یا یک stream از نوع PSR-7، با application/octet-stream مگر آنکه نوعی را نام ببرید. |
| accept: و binary: | accept: ای غیر از JSON بدنه را بهصورت متن برمیگرداند، و binary: true آن را بهصورت یک رشتهٔ بایتی برمیگرداند. |
| idempotent: و idempotencyKey: | idempotent: true یک Idempotency-Key میچسباند که تولید میشود، مگر آنکه کلید خودتان را بدهید. |
| repeatable: | اینکه آیا یک شکست دوباره تلاش میشود یا نه. فقط GET دوباره تلاش میشود، مگر آنکه repeatable: true بدهید. |
| anonymous: | true هیچ اعتبارنامهای نمیفرستد. |
| apiKey:، inboxToken: و timeout: | همان اعتبارنامههای مخصوص هر فراخوانی، و مهلتی برحسب ثانیه فقط برای همین فراخوانی. |
مسیر باید با یک / تنها آغاز شود، و مسیری که URL نهاییاش از origin مربوط به URL پایه بیرون برود، پیش از فرستادن هر چیزی InvalidArgumentException را پرتاب میکند، پس اعتبارنامه هرگز به میزبان دیگری نمیرسد.
صندوقهای یکبارمصرف
OpenEmail::createTempMail() کلاینتی برای صندوقهای یکبارمصرف میسازد که هیچ کلید API حمل نمیکند و هیچ کلیدی هم از محیط نمیخواند. صندوقها را ناشناس میسازد، و هر خواندن توکن صندوقی را میفرستد که create بازگردانده بود، یا توکن تازهتری را که extend بازگرداند، خواه برای هر فراخوانی بهصورت inboxToken: خواه یک بار بهصورت OpenEmail::createTempMail(inboxToken: ...).
use OpenEmail\OpenEmail; $tempMail = OpenEmail::createTempMail(); $inbox = $tempMail->create();$page = $tempMail->listMessages($inbox['id'], inboxToken: $inbox['token']); echo count($page->items), ' ', $page->expiresAt, PHP_EOL;OpenEmail::createTempMail() مانند هر کلاینتی baseUrl:، httpClient:، maxRetries:، timeout:، userAgent:، headers: و disableUpdateNotice: را میگیرد، و وقتی هیچ URL پایهای ندهید OPENEMAIL_BASE_URL را میخواند.
توکنهای دسترسی OAuth
برنامهای که شخصی با OAuth متصل کرده، مثل یک ابزار خط فرمان یا یک عامل، بهجای کلید API یک توکن دسترسی دارد. آن را بهصورت accessToken: بدهید: یا خودِ توکن، یا یک callable که توکن را برگرداند، مانند یک closure یا یک first-class callable. این callable برای هر فراخوانی یک بار اجرا میشود و تلاشهای دوبارهٔ همان فراخوانی از چیزی که برگردانده استفاده میکنند، پس وقتی توکن نزدیک انقضاست آن را درون همان callable تازه کنید تا هرگز لازم نباشد کلاینت را از نو بسازید.
use OpenEmail\OpenEmail; $tokens = ['current' => 'token-from-your-oauth-flow']; $oauthClient = new OpenEmail(accessToken: fn(): string => $tokens['current']); $me = $oauthClient->me->get(); if ($me['object'] === 'oauth_token') { echo $me['clientId'], ' ', $me['expiresAt'], PHP_EOL;}| حالت | چه رخ میدهد |
|---|---|
| apiKey: و accessToken: با هم، یا هیچکدام | کلاینت هنگام ساخته شدن InvalidArgumentException را پرتاب میکند. وقتی هیچکدام نباشد، پیام OPENEMAIL_API_KEY و OPENEMAIL_ACCESS_TOKEN را نام میبرد. |
| مقداری که توکن نیست | توکن 1 تا 512 نویسه است و با oe_ شروع نمیشود، همان بررسیای که OpenEmail::isAccessToken() انجام میدهد. رشتهای که این بررسی را نگذراند هنگام ساختن کلاینت پذیرفته نمیشود، و callableی که چنین مقداری برگرداند باعث میشود فراخوانی پیش از فرستادن هر چیزی InvalidArgumentException را پرتاب کند. |
| OPENEMAIL_ACCESS_TOKEN | وقتی هیچکدام از دو اعتبارنامه را ندهید و OPENEMAIL_API_KEY تنظیم نشده باشد خوانده میشود، پس کلیدی که در محیط باشد مقدم است. |
| callableی که استثنا پرتاب کند | فراخوانی همان استثنا را، بیتغییر، پرتاب میکند و چیزی فرستاده نمیشود. |
| یک apiKey: مخصوص یک فراخوانی | فقط برای همان یک درخواست جای توکن را میگیرد و callable صدا زده نمیشود. |
| $client->mode | با توکن همیشه live. |
| OpenEmail::createTempMail() | هر چه در محیط باشد، هیچ اعتباری نمیفرستد. |
| me->get() و me->ping() | برای توکن، get با object برابر oauth_token، id و roleId برابر null، clientId برنامهٔ متصل، و expiresAt، یعنی زمانی که تأیید شخص برای برنامه تمام میشود، پاسخ میدهد. ping با kind برابر oauth، keyId برابر null و clientId پاسخ میدهد. پیش از خواندن id یا keyId، مقدار object یا kind را بررسی کنید. |
توکن از طرف یک شخص کار میکند و ایمیلش را همانطور که خودش میتواند میخواند، پس آن را مثل کلید روی سرور نگه دارید.
کدهای تأیید هویت
پیش از یک تغییر حساس، مثل حذف یک دامنه یا تغییر یک وبهوک، API از توکن دسترسی همان کد تأیید هویتی را میخواهد که برنامهٔ وب از شخص میخواست. فراخوانی یک PermissionException را پرتاب میکند، یک 403 که isStepUpRequired() آن true است، و چیزی تغییر نکرده است. یک کد بخواهید، کدی را که شخص به شما میدهد تأیید کنید، سپس دوباره فراخوانی کنید. از کلید API هرگز خواسته نمیشود.
use OpenEmail\Exception\ApiException; $domainId = 'b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f'; try { $client->domains->delete($domainId);} catch (ApiException $error) { if (!$error->isStepUpRequired()) { throw $error; } $challenge = $client->security->beginStepUp(); if ($challenge['method'] === 'email') { echo 'Enter the code we emailed to ', $challenge['sentTo'], PHP_EOL; } else { echo 'Enter the code from your authenticator app, or a backup code', PHP_EOL; } $client->security->verifyStepUp(['code' => trim((string) fgets(STDIN))]); $client->domains->delete($domainId);}| متد | چه میکند |
|---|---|
| security->stepUpStatus() | اینکه برنامه همین حالا تأییدشده است یا نه (elevated، elevatedUntil)، کد بعدی چطور بررسی میشود (method، email یا totp)، و minutes، طول بازهٔ زمانی. چیزی نمیفرستد و توقف را گزارش نمیکند. |
| security->beginStepUp() | یک تأیید هویت را آغاز میکند. با email یک کد ششرقمی به نشانیای میرود که شخص با آن وارد میشود و sentTo آن را پوشیده نشان میدهد. با totp شخص کدی را از برنامهٔ احراز هویتش میخواند یا یک کد بازیابی به کار میبرد. تأیید هویتی که هنوز باز است و تلاش باقی دارد دوباره به کار میرود، مگر اینکه ['resend' => true] بدهید، و تأیید هویت قفلشده یا منقضیشده با یک فراخوانی ساده جایگزین میشود. هر برنامه برای هر شخص میتواند 5 تأیید هویت در ساعت و 20 در 24 ساعت آغاز کند، و بعدی یک 429 step_up_throttled را پرتاب میکند. |
| security->verifyStepUp(['code' => ...]) | کد را بررسی میکند و تغییرات حساس را برای این برنامه به مدت 60 دقیقه، تا elevatedUntil، از راه REST و از راه ابزارهای MCP که همان تغییرها را انجام میدهند باز میکند. پس از 10 کد نادرست در 24 ساعت از این برنامه، یا 20 کد از همهٔ برنامههای شخص با هم، این فراخوانی و beginStepUp یک 429 step_up_locked را با پیامی پرتاب میکنند که میگوید تأیید هویت کی از سر گرفته میشود. |
کلاینت هرگز خودش کد نمیخواهد یا فراخوانی را تکرار نمیکند، و هیچکدام از این سه متد خودکار دوباره تلاش نمیشود، چون تلاش دوباره پس از یک پاسخ گمشده ممکن است ایمیل دومی بفرستد یا تلاش دومی را مصرف کند. اسکوپ لازم ندارند، و کلید API که یکی از آنها را فراخوانی کند یک 400 step_up_not_applicable میگیرد. OpenEmail\Constants\StepUpErrorCodes همهٔ راههایی را که تأیید ممکن است شکست بخورد نام میبرد، و صفحهٔ خطاهای API میگوید برای هر کدام چه باید کرد.
اعلان بهروزرسانی
وقتی نسخهٔ تازهتری از بسته روی Packagist باشد، کلاینت این را یک بار در هر فرایند، روی خروجی خطای استاندارد، با خطی مانند ℹ openemail/sdk 0.0.2 is available, you are on 0.0.1. و به دنبالش صفحهٔ بسته اعلام میکند. این بررسی فقط در خط فرمان و وقتی خروجی استاندارد یک ترمینال باشد اجرا میشود، و هرگز زیر وبسرور اجرا نمیشود. با ساخته شدن نخستین کلاینت آغاز میشود و در کنار درخواستهای شما اجرا میشود، و در پایان اسکریپت به اندازهٔ هر چه از بودجهٔ دوثانیهای مانده صبر میکند. ناتوانی در دسترسی به Packagist نادیده گرفته میشود.
این بررسی درخواست خودش را با cURL و بیرون از httpClient: کلاینت میفرستد، پس یک کلاینت HTTP ساختگی در آزمون هرگز آن را نمیبیند. برای خاموش کردنش disableUpdateNotice: true را بدهید یا OPENEMAIL_DISABLE_UPDATE_NOTICE را تنظیم کنید.
پراکسیها و TLS
CurlHttpClient پیشفرض پراکسی را به cURL میسپارد، که برای پراکسی https_proxy یا HTTPS_PROXY و برای میزبانهایی که مستقیم وصل میشوند no_proxy یا NO_PROXY را میخواند. برای اینکه بهجای آن پراکسی را در کد تعیین کنید، proxy: را بدهید. نام کاربری و گذرواژهٔ درون URL پراکسی به پراکسی فرستاده میشوند.
use OpenEmail\Http\CurlHttpClient;use OpenEmail\OpenEmail; $client = new OpenEmail(httpClient: new CurlHttpClient( caBundle: '/etc/ssl/certs/corporate-ca.pem', proxy: 'http://proxy.internal:3128', curlOptions: [CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4],));اتصالها از TLS 1.2 یا بالاتر استفاده میکنند و گواهی و نام میزبان سرور را بررسی میکنند، و تغییرمسیرها هرگز دنبال نمیشوند. caBundle: مراجع صدور گواهی مورد اعتماد را تعیین میکند، برای پراکسیای که TLS را بازرسی میکند. curlOptions: هر گزینهٔ دیگر cURL را تنظیم میکند، اما تنظیماتی که یک درخواست به آنها نیاز دارد همیشه مقدماند: URL و درگاه آن، متد، سرآیندها، بدنه و خاموش ماندن تغییرمسیرها. CURLOPT_REQUEST_TARGET پذیرفته نمیشود، و گزینهای که cURL نپذیرد یک InvalidArgumentException پرتاب میکند که نام آن را میآورد.