Використав CURL для вирішення проблеми з відправкою HTTP запитів в проєкті ZennoPoster

Одного разу звернувся до мене замовник з проблемою – будь-який запит до сервісу розпізнавання hcaptcha не доходить, тобто у вікні моніторнг трафіку програми ProjectMaker просто пуста біла лінія, ніякого статусу, і відповіді немає. При чому інколи, все таки якась відповідь приходить.

Рішив я допомогти і вирішити цю проблему. Першим ділом я відправив запит просто звичайним блоком HTTP GET і HTTP POST. Спроба получилась не вдалою. Потім попробував добавити проксі, без проксі – також спроба не втішна. Попробував відправляти запити Стандартним способом і Альтернативним (є такі налаштування свого проєкту в ProjectMaker) – результат ідентичний – немає відповіді.

Тоді вирішив перейти за посиланням в браузері – все чітко працює. Попробував відправити запит використовуючи CURL – і одержав необхідну відповідь, хоча перший запит все таки не вдався і прийшлось добавити аргумент, який дозволяє не перевіряти з’єднання. Звичайно, можна було вказати на сертифікат, проте я подумав що зчитувати його постійно буде помаліше, ніж відказатись від перевірки (тим більше, що запит в цьому випадку проходить корректно).

Сам CURL в мене в якомусь коробковому рішенні був відсутнім. Тому перш за все я пішов на офіційний сайт щоб знайти його. Необхідні файли знаходяться за посиланням:
https://curl.se/windows/

Значить тут я вибрав пункт: curl for 64-bit
Після чого на компьютер мені завантажився архів curl-8.4.0_7-win64-mingw.zip
Всередині архіву знаходиться декілька директорій.
Відкрив я там спочатку: curl-8.4.0_7-win64-mingw.
В ній знайшов і видкрив директорію: bin
І там побачив необхідні і актуальні файли, які просто скопіюю і вони будуть лежати поряд с проєктом:

curl-ca-bundle.crt
libcurl-x64.def
libcurl-x64.dll
curl.exe

На скільки я зрозумів, час від часу необхідно ходити туди, і завантажувати актуальну версію, адже сертифікат curl-ca-bundle.crt може устаріти, і тоді запити можуть не відправлятись.

В одному із класів коду клієнта я підправив метод, в якому спочатку відправлялись дані у вигляді JSON методом POST за допомогою стандартних методів програми ZennoPoster на відправку за допомогою CURL:

private string SubmitPostRequest(string data) {
	string apikey = "key";
	string url = "https://pro.nocaptchaai.com/solve";
	project.SendInfoToLog("Send POST: \n"+data, true);
	string post = Curl(url, data, apikey);
	project.SendInfoToLog("Response POST: \r\n"+post);
	return post;
}

І власне сформував метод, який буде відправляти точно такий запит, з такими ж заголовками, тільки використовуючи CURL:

public string Curl(string url, string json, string api){
	string path = Path.GetTempFileName(); // створюю тимчасовий файл
	File.WriteAllText(path, json);  // записую в нього дані
 
	string[] data = { 
		string.Format("-X POST {0}", url),
		string.Format("-H \"Content-Type: application/json\""),
		string.Format("-H \"apikey: {0}\"", api),// добавляю заголовки		 
		string.Format("-d @{0}", path), // відправляю дані з тимчасового файла
		"-k" // відмовляюсь від перевірки сертифіката
	};

	var setting = new System.Diagnostics.ProcessStartInfo {
		CreateNoWindow = true,
		FileName = Path.Combine(project.Directory, "curl.exe"),
		Arguments = string.Join(" ", data),
		UseShellExecute = false,
		RedirectStandardOutput = true, // перенаправляю результат який прийде від сервісу
		RedirectStandardError = true // перенаправляю повідомлення про помилки, щоб побачити їх
	};

	using (var process = new System.Diagnostics.Process { StartInfo = setting }) {
		process.Start();
		string output = process.StandardOutput.ReadToEnd().Trim();
		string error = process.StandardError.ReadToEnd().Trim();
		process.WaitForExit();

		if (process.ExitCode != 0) {
			throw new Exception("ERROR curl. Exit Code: "+ process.ExitCode.ToString()+ ". Error: "+error.ToString());
		}
		return output;
	}
}

Можна побачити, що я використав тимчасовий файл, щоб добавити в нього дані. Справа в тому, що коли відправляти запит через CURL, то через велику кількість даних параметр -d може видавати помилку ( Выполнение действия CSharp OwnCode. Имя файла или его расширение имеет слишком большую длину ). А щоб уникнути її – прийшлось використовувати тимчасовий файл.

Також в використовую параметр -k, який дозволяє відказатись від перевірки сертифіката, власне саме для того, щоб використати цю можливість і прийшлось використовувати CURL, тому що в програмі ZennoPoster у стандартних блоках немає можливості це зробити. І якщо за допомогою свого C# коду можна було б придумати, то я розумів що відправити запит використовуючи протокол HTTP/2 точно можливості немає, а сам CURL його зможе використати у випадку необхідності автоматично.

Цікаво, якщо б Ви вирішували цю проблему з HTTP запитами – скільки Ви б оцінили вартість часу затраченого на обговорення завдання з замовником, аналіз коду замовника, внесення всіх необхідних змін в код, щоб він запрацював?

А тепер подумайте, якщо б Ви були замовником, і Вам потрібно було б вирішити цю саму проблему з відправкою HTTP запитів – скільки Ви готові були б заплатити за вирішення її в день звернення до потенційного розробника-виконавця роботи?

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *