пытался отправить граффити вконтакт по сокетам.. как составить правильно запрос? вот пример запроса, который был переснят с ВК через CommView. Code: var afile, signature, boundary, cookie, url, Headers, ret, multi, _post : string; begin AFile := 'd:\~tmpPic.png'; // Создаем сигнатуру файла по формуле file -> content -> Base64 -> Copy 1024 bytes -> MD5 Signature := StrTobase64(file_get_contents(AFile), 0); // Получаем контент и кодируем в base64 Signature := Copy(Signature, 0, 1024); // Копируем первые 1024 байта Signature := GetMD5(Signature); // Хэшируем в MD5 url := 'http://vkontakte.ru/graffiti.php?to_id=46405451&group_id=0'; cookie := 'remixsid=куки; remixchk=5'; boundary := '----OLEG-ANDREEV-PAVEL-DUROV-GRAFFITI-POST'; Headers := 'POST /graffiti.php?to_id=46405451&group_id=0 HTTP/1.0' + #13#10 + 'User-Agent: Mozilla/4.8 [en](Windows NT 5.0; U)' + #13#10 + 'Accept: Accept: text/html;q=0.9,*/*;q=0.8' + #13#10 + 'Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7' + #13#10 + 'Accept-Language: ru,en-us;q=0.7,en;q=0.3' + #13#10 + 'Connection: close' + #13#10 + 'Referer: http://vkontakte.ru/graffiti.swf?12' + #13#10 + 'Host: ' + GetHost(url) + #13#10 + 'Cookie: ' + cookie + #13#10 + 'Content-Length: con-len' + #13#10 + 'Content-Type: multipart/form-data; boundary=' + boundary + #13#10#13#10; multi := boundary + #13#10 + 'Content-Disposition: form-data; name="Signature"' + #13#10#13#10 + signature + #13#10 + boundary + #13#10 + 'Content-Disposition: form-data; name="Filedata"; filename="graffiti.png"' + #13#10 + 'Content-Type: image/png' + #13#10#13#10 + file_get_contents(AFile) + #13#10#13#10 + boundary; Headers := StringReplace(Headers, 'con-len', IntToStr(Length(multi)), []); _post := headers + multi; send_packs(GetIPAddress(GetHost(url)), 80, _post, ret); memo2.Text := _post; memo1.Text := ret; end; сервак ответил мне на это таким текстом: PHP: HTTP/1.1 302 Found Server: nginx/0.7.59 Date: Mon, 24 May 2010 20:03:09 GMT Content-Type: text/html; charset=windows-1251 Connection: close X-Powered-By: PHP/5.2.6-1+lenny3 Pragma: no-cache Cache-control: no-store Location: graffiti.php?act=last Vary: Accept-Encoding Content-Length: 0 я перешел по локации, пришедшей мне в заголовках ответа: http://vkontakte.ru/graffiti.php?act=last и у меня открылся рисовальщик граффити вместо нужной страницы с кнопкой отправить.. что не так составленно в запросе?
Если меня не изменяет память, то везде должно быть не Code: boundary + #13#10 а Code: '--' + boundary + #13#10 А в самом конце не: Code: #13#10#13#10 + boundary а Code: #13#10 + '--' + boundary + '--' + #13#10 Возможно присутствую еще какие-то незначительные ошибки. Также, этот код относится к не наилучшему стилю: Code: Headers := StringReplace(Headers, 'con-len', IntToStr(Length(multi)), []); Это нельзя использовать в String: Code: file_get_contents(AFile);
вот запрос выдранный из graffiti.swf Code: POST /graffiti.php?to_id=52505311&group_id=0 HTTP/1.0 Connection: close Content-Type: multipart/form-data; boundary=----OLEG-ANDREEV-PAVEL-DUROV-GRAFFITI-POST Content-Length: 18773 Host: vkontakte.ru Accept: text/html;q=0.9,*/*;q=0.8 Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7 Accept-Language: ru,en-us;q=0.7,en;q=0.3 User-Agent: Mozilla/4.8 [ru](Windows NT 5.0; U) Cookie: remixsid=cookies; remixchk=5 ------OLEG-ANDREEV-PAVEL-DUROV-GRAFFITI-POST Content-Disposition: form-data; name="Signature" a48e6e3b4b07f8e5a668ac2742998c42 ------OLEG-ANDREEV-PAVEL-DUROV-GRAFFITI-POST Content-Disposition: form-data; name="Filedata"; filename="d:\~tmpPic.png" Content-Type: image/png тело файла ------OLEG-ANDREEV-PAVEL-DUROV-GRAFFITI-POST--
Ну так ты присмотрись к этому рядку: Code: Content-Type: multipart/form-data; boundary=[B][COLOR=Red]----[/COLOR][/B]OLEG-ANDREEV-PAVEL-DUROV-GRAFFITI-POST и этому Code: [B][COLOR=Lime]--[/COLOR][COLOR=Red]----[/COLOR][/B]OLEG-ANDREEV-PAVEL-DUROV-GRAFFITI-POST Content-Disposition: form-data; name="Signature"
еть! но всеравно ты заливаешь файл на сервер. Дело не в сложности использования методов (api или стандартный вк метод). Дело в основе
Гыгы, можно, результат будет тот же (P.S. Путаешь стандартные null-terminated строки, у Delphi свой формат, к сожалению)
Я не исключаю что можно использовать AnsiString, но советую использовать либо array of char, либо array of byte. Так будет более правильно.
RedFern.89 мне кажется через пару лет у тебя будет программа с интерфейсом и функциями вконтакта которая будет отправлять HTTP запросы на сервер вконтакта напрямую, а не через wеb интерфейс... RedFern.89 учи js php mySQL и переходи уже на веб кодинг )
ну звиздец какойто просто... Дабы не плодить кучу тем по моим вопросам, задам вопрос тут. Есть 1 функция и одна процедура. Обе взаимосвязанны. Называются Get и Redirect. Думаю человек, знающий протокол HTTP поймет, что за функции. Допустим при выполнении функции GET произошло 2 редиректа. Как сделать так, что бы функция GET закончила свое выполнение, до тех пор, пока все редиректы не закончатся? т.е. вернула страницу конечного редиректа. В моем же случае функция GET возврщает код 1й страницы, а нужно той страницы, на которую произошла переадресация. Получается так, что функция get работает дальше и грузит все страницы, но в том коде, в котором она выполняется она отдала код 1й страницы и все. Привожу коды обеих процедур: Code: // ---- Обрабатываем перенаправление ---- procedure THTTPCli.Redirect(const AData, AHost: string); var Location : string; begin Location := AData; Location := Copy(Location, Pos('Location:', Location) +10, Length(Location)); Delete(Location, Pos(#13, Location), Length(Location)); // Проверка локаций и исправление If Location[1] = '/' Then Get(AHost + Location); If (Location[1] <> '/') And (Pos('http://', location) = 0) Then begin Location := '/' + Location; Get('http://' + AHost + Location); end; If Pos('http://', Location) <> 0 then begin Location := Copy(Location, Length(GetHost(Location)) +8, Length(Location)); Get(Location); end; end; // ---- Отправка GET-запроса ---- ;overload function THTTPCli.Get(const AURL: string): string; var Head : string; Host : string; urlObj : string; begin { Парсим url } urlObj := AURL; urlObj := Copy(urlObj, Length(GetHost(urlObj)) +8, Length(urlObj)); Host := GetHost(AURL); // Составляем заголовок без куков Head := 'GET ' + urlObj + ' HTTP/1.1' + crlf + 'User-Agent: Mozilla/4.8 [en](Windows NT 5.0; U)' + crlf + 'Connection: close' + crlf + 'Host: ' + Host + crlf + crlf; // А если таковые имеются, прибавляем их к заголовку If Length(_cookie) <> 0 Then begin Head := 'GET ' + urlObj + ' HTTP/1.1' + crlf + 'User-Agent: Mozilla/4.8 [en](Windows NT 5.0; U)' + crlf + 'Connection: close' + crlf + 'Cookie: ' + _cookie + crlf + 'Host: ' + Host + crlf + crlf; end; // Отсылаем запрос SendRequest(Host, 80, Head, Result); // Если сервер сказал 302, переходим по сказанной локации If Pos('302', Result) <> 0 then begin Redirect(Result, Host); end; end; блин как запарился уже. Извините за офтоп и кучу всем давно надоевшим вопросам.
Хм, если на странице просто попадется "302" то это будет считаться как редирект? Вообще, если я правильно тебя понял то тебе надо просто организовать цикл. Что-то типа: while Pos('302', Result) <> 0 do Redirect(Result, Host);
Так епт сделай Redirect функцией, которая например возвращает true если редирект был и false если не был Вообше, имхо извращенное у тебя распределение по методам
Нужно чтобы твоя функция Redirect возвращала тело новой скачанной страницы. Тогда можно реализовать цикл, который написал GhostOnline.
Пипец..Ты зациклил 2 метода, в первом вызываешь второй, во втором первый, и т.д.. еще удивляешься почему возвращается "код певрого ответа" Get - функция, она возвращает result. Далее если ответ 302 то ты вызываешь процедуру Redirect и ей передаешь resault. Процедура по определению ничего не возвращает, и с result ничего не делает, потому что: 1. Ты в процедуре не оперируешь параметром AData 2. Даже если бы захотел оперировать, то значение все равно бы не изменилось, ибо: const AData Переходить то ты переходишь, но с какого х** result должна измениться если ты в этой функции с ней ничего больше не делаешь? PS Мораль такова: вызываемая подпрограмма не может изменять результат той подпрограммы в которой она была вызвана, за исключением способа передачи по ссылке(var)