LINUX.ORG.RU

Как увидеть отправляемое curl'ом?

 ,


0

1

Безуспешно пытаюсь жрать кактус Net::Curl::Easy :(

Есть какая-то странная проблема с POST'ом, которую уже давно не могу решить.

Мне бы сильно помогла отладка на тему того, что libcurl собственно пуляет на сервер.

Но сервер - разумеется, https, и tcpdump'ом фиг что увидишь.

У CURL есть замечательная опция CURLOPT_VERBOSE - она позволяет увидеть, что приложение получает от сервера. И есть CURLOPT_WRITEFUNCTION, которой можно конечно передать некий хендлер, но явно не perl'овый (пробовал, не котируются здесь perl'овые sub'ы).

Соответственно, внимание, вопрос: как увидеть, до какой степени некорректную фигню шлёт на сервер сам Net::Curl::Easy? :)

Превентивное гигантское всем Спасибо!

★★★★★

Поднять web-сервер на локалхосте с говноскриптом, который тупо будет писать POST в файл или высерать в теле ответа.

Ну как-то так.

Radjah ★★★★★
()

ходить через проксик и на нем собирать инфу

nihirash ★★★
()

Мне бы сильно помогла отладка на тему того, что libcurl собственно пуляет на сервер.

Так что мешает? Укажи в своем коде адрес для POST-а вроде http://localhst:1234, и повесь там nc -l 1234

kawaii_neko ★★★★
()

Через дебаггер - не, никак? Ты детальо сможешь увидеть, что шлет на сервер Net::Curl и что тебе отвечает сервер. Т.е. полный контроль над данными и стеком вызовов подпрограмм в перловом интерпреторе.

perldoc perldebtut
KernelPanic
()
Ответ на: комментарий от Deleted

strace тяжеловат будет для того, чтобы из груды хлама, вытаскивать отправляемое curl'ом в сокет... Хотя конечно как вариант.

Я разобрался, вроде: во-первых, нужны зачем-то обе опции: COOKIE_FILE и COOKIE_JAR, во-вторых с точки зрения странного Redmine'а на той стороне нужно кодировать запрос вот так:

my $post={
                'username'=>'UserTest',
                'password'=>'12345678',
                'login'=>'Login+»',
                'utf8'=>'✓',
                'authenticity_token'=>$authToken,
};

$ua->setopt( 
  CURLOPT_POSTFIELDS =>
  my $postContent=join('&' => 
    map $_->[0].'='.$ua->escape($_->[1]), 
      map [each $post], 1..keys $post)
);
DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от kawaii_neko

Для тестирования чужого портала, да ещё написанного поверх и без того проблемного Redmine'а - localhost точно не поможет.

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от DRVTiny

А нет, достаточно всё-таки только CURLOPT_COOKIEJAR.

Хотя на самом деле мне хранить cookies'ы в файле - вообще даром не сдалось, нужно бы в памяти их накапливать... как-то, непонятно как.

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от DRVTiny

во-первых, нужны зачем-то обе опции: COOKIE_FILE и COOKIE_JAR

  • COOKIE_FILE - из какого файла прочитать начальные печеньки.
  • COOKIE_JAR - в какой файл записать печеньки при закрытии easy сессии.

Обе эти опции нужны, если ты хочешь сохранять печеньки в файлах между сессиям. Если у тебя одна сессия и печеньки ты хочешь хранить в оперативной памяти, то тебе надо в CURLOPT_COOKIEFILE передать пустую строку.

Deleted
()
Ответ на: комментарий от Deleted

Я тут херню написал...

Если https://, то strace.

gdb тут нужен. strace не поможет.

Deleted
()
Ответ на: комментарий от Deleted

ДА!! Есть такое дело, спасибо огромное, Иван!

Действительно

CURLOPT_COOKIEFILE  => ''

-решает проблему сохранения даром ненужных (после завершения сессии) кукисов!

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от DRVTiny

Я вообще не знаю перл, но правильнее скорее всего будет так:

$ua->setopt( CURLOPT_POSTFIELDS, my $postContent=join('&' => map $ua->escape($_->[0]).'='.$ua->escape($_->[1]), map [each $post], 1..keys $post) );
А совсем правильно - найти готовую либу с функцией кодирования пар ключ <=> значение в формат, пригодный для http. 100% такая уже есть.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от DRVTiny

Для тестирования чужого портала, да ещё написанного поверх и без того проблемного Redmine'а - localhost точно не поможет.

Кажется, ты меня неправильно понял.

// console 1
$ curl -F test=one -F test=two http://localhost:1234
// console 2
$ nc -l -p 1234
POST / HTTP/1.1
Host: localhost:1234
User-Agent: curl/7.53.0
Accept: */*
Content-Length: 238
Expect: 100-continue
Content-Type: multipart/form-data; boundary=------------------------22d2e8d1b2a1843e

--------------------------22d2e8d1b2a1843e
Content-Disposition: form-data; name="test"

one
--------------------------22d2e8d1b2a1843e
Content-Disposition: form-data; name="test"

two
--------------------------22d2e8d1b2a1843e--
URL-то подменить для «возможно проблемного запроса» не проблема?

kawaii_neko ★★★★
()
Ответ на: комментарий от Deleted

Если действительно нужно экранировать и L, и R-части выражения, то тогда вот так намного проще и короче:

$ua->setopt( CURLOPT_POSTFIELDS =>
  my $postContent=join('&' => map join('=', map $ua->escape($_), each $post), 1..keys $post)
);
DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от kawaii_neko

Там 2 запроса в цепочку встают: от результата первого запроса зависит то, что пойдёт во второй.

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от DRVTiny

Если действительно нужно экранировать и L, и R-части выражения,

В идеале - да, потому что L тоже может быть любым и содержать любые символы.

Deleted
()

Но сервер - разумеется, https, и tcpdump'ом фиг что увидишь.

sslsplit

utf8nowhere ★★★
()
Ответ на: комментарий от annulen

Да ну его в Ж, у меня получилось и быстрее, и яснее, и use'ы не нужны.

Кстати, да, в Net::Curl::Easy функция escape для чего-то да есть, согласись?

DRVTiny ★★★★★
() автор топика
Последнее исправление: DRVTiny (всего исправлений: 1)

Wireshark в помощь. Либо заскриптуй фейковый сервер через nc.

no-such-file ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.