Witam.
Mój pierwszy post tutaj, więc krótkie przestawienie się: facet już parę lat po studiach (Elektronika i Telekomunikacja), z zamiłowania elektronik, informatyk, przyrodnik. Programy piszę głównie na własny użytek, tak zwany niedzielny programista ze mnie.
Teraz do rzeczy. Nie mogę za pomocą Delphi 7 + Synapse utworzyć katalogu na Chomiku. W AutoIt poszło jak po maśle, kilka linijek kodu i katalog jest (operacje na plikach też bez problemu), a tu w Delphi ciągle kłody pod nogi. Zainstalowałem nawet Indy i też to samo, odpowiedź 500.
Na forum znalazłem już takie posty jak:
Tworzenie folderu z wykorzystaniem HttpWebRequest
http://4programmers.net/Forum/C_i_.NET/231339-c_logowanie_+_chomikowanie_pliku_-_httpwebresponse
Tworzenie folderu z wykorzystaniem HttpWebRequest
Zmiana nazwy oraz treści kategorii na chomiku
Pobieranie plików z chomikuj.pl
Jedynie dwa ostatnie zasługują na uwagę, ale rozwiązania brak.
Trafiam na praktycznie ten sam problem co poprzednicy. Przy próbie utworzenia katalogu, serwer uparcie odpowiada 500. Kolega Olesio wspomniał, że mu udało się utworzyć katalogi, pozostał problem z kopiowaniem plików (chyba, że w międzyczasie już po problemie?).
Mam nadzieję, że nie dołączę do coraz to większego grona ;-) tych co nie potrafią utworzyć katalogu na Chomiku.
Aby więcej nie marudzić zamieszczam mój kod (trochę w nim śmieci bo wycięty z całości):
unit test_v00;
interface
uses
SysUtils,
Classes,
Windows,
HttpProt,
ShellApi,
StrUtils,
DateUtils,
HTTPSend, blcksock,
Dialogs,
Messages, Controls, Forms,
IdBaseComponent, IdHTTP, HTTPApp, IdURI,
IdCoder, IdCoder3to4, IdCoderMIME, IdMultipartFormData,
StdCtrls, ComCtrls, IdTCPClient, IdTCPConnection, IdComponent, ExtCtrls,
Variants, Graphics, IdTCPServer;
type
TForm1 = class(TForm);
TSearch = String;
TTableee = array of TSearch;
TProgress = class(TObject)
LocalFile : PChar;
RemoteFile : PChar;
tmr : TTimer;
Forum : TIdHTTP;
IdTCPClient1: TIdTCPClient;
private
{ Private declarations }
public
{ Public declarations }
end;
const
naglowek = 'testowanie chomika';
Opera_UserAgent = 'Mozilla/5.0 (Windows NT 5.1; rv:33.0) Gecko/20100101 Firefox/33.0';
ToPost_MimeType = 'application/x-www-form-urlencoded; charset=UTF-8';
Location_Prefix = 'Location:' + #32;
login = 'chomik_testowy1';
haslo = 'Haslo1234';
var
Form1: TForm1;
PreviousPath : string;
CurrentPath : string;
FLIndex : Integer;
PathExe : string;
HttpCli: THttpCli;
HttpCli_nastepna: THttpCli;
FileDate : _FILETIME;
links : string;
FileList : TStringList;
ProgressObject : TProgress;
GetSizeExtensions : string;
SearchRecord : TSearchRec;
LastPage : string;
IsGettingFile : Boolean;
AbortCopy : Boolean;
GetFileNow : string;
Parsed : Boolean;
Debug, Debug2 : Text;
token, chomik_id, chomik_treeticks, cookies : String;
wszystkie_pobrane_strony, tylkonazwapliku : String;
sl_pelna_sciezka : String;
sl_do_wyswietlenia : String;
sl_rozszerzenia : String;
sl_rozmiar : String;
sl_data : String;
sl_id_katalogu : String;
sl_id_pliku : String;
tablica_katalogow : array[0..1] of String;
tablica_wielowymiarowa : array of array of String;
SynHttp : THttpSend;
strona : TMemoryStream;
implementation
{$R *.dfm}
//_________________________________________________________________
// strumień na string
function StreamToString(aStream: TStream): string;
var
SS: TStringStream;
begin
if aStream <> nil then
begin
SS := TStringStream.Create('');
try
SS.CopyFrom(aStream, 0); // No need to position at 0 nor provide size
Result := SS.DataString;
finally
SS.Free;
end;
end else
begin
Result := '';
end;
end;
//______________________________________________________________________________
// funkcja dodana w celu wyszukiwania tekstu między dwoma stringami
function StringBetween(const Input, Delim1, Delim2: string): string;
var
aPos, bPos: Integer;
begin
result := '';
aPos := Pos(Delim1, Input);
if aPos > 0 then begin
bPos := PosEx(Delim2, Input, aPos + Length(Delim1));
if bPos > 0 then begin
result := Copy(Input, aPos + Length(Delim1), bPos - (aPos + Length(Delim1)));
end;
end;
end;
//______________________________________________________________________________
// kompletna procedura do logowania do Chomika za pomocą Synapse
procedure chomik_zaloguj_synapse();
var
adres, komenda, zadanie, wynik : String;
I, Position : integer;
URLData, Str, RedirUrl, FPage : string;
login1, login2 : String;
begin
// LOGOWANIE DO CHOMIKA
strona := TMemoryStream.Create;
SynHttp := THttpSend.Create;
try
// najpierw pobieramy strone logowania
SynHttp.UserAgent := Opera_UserAgent;
SynHttp.Headers.Insert(0, 'Referer: http://chomikuj.pl/');
SynHttp.Headers.Insert(0, 'Accept-Language: pl,en-US;q=0.7,en;q=0.3');
SynHttp.Headers.Insert(0, 'Accept-Encoding: gzip, deflate');
SynHttp.Headers.Insert(0, 'X-Requested-With: XMLHttpRequest');
SynHttp.Headers.Insert(0, 'Accept: */*');
SynHttp.Headers.Insert(0, 'DNT: 1');
SynHttp.KeepAlive := True;
SynHttp.Protocol := '1.1';
SynHttp.MimeType := ToPost_MimeType;
HTTPpostURL('http://chomikuj.pl', '=', strona);
strona.Seek(0,soFromBeginning);
//strona.SaveToFile('C://Test POST GET przed zalogowaniem 22.html');
// teraz z otrzymanego kodu HTML pobieram token i przetwarzamy go
token := StringBetween ( StreamToString(strona), '<input name="__RequestVerificationToken" type="hidden" value="', '==" />');
token := StringReplace(token, '/', '%2F', [rfReplaceAll]);
token := StringReplace(token, '+', '%2B', [rfReplaceAll])+ '%3D%3D';
finally
strona.Free;
end;
try
// teraz logujemy się do Chomika z loginem, haslem i tokenem
adres := 'http://chomikuj.pl';
komenda := '/action/Login/TopBarLogin';
UrlData := 'ReturnUrl=&Login=' + login + '&Password=' + haslo + '&__RequestVerificationToken=' + token;
SynHttp.KeepAlive := True;
SynHttp.Protocol := '1.1';
SynHttp.MimeType := ToPost_MimeType;
SynHttp.UserAgent := Opera_UserAgent;
SynHttp.Headers.Insert(0, 'Referer: http://chomikuj.pl/');
SynHttp.Headers.Insert(0, 'Accept-Language: pl,en-US;q=0.7,en;q=0.3');
SynHttp.Headers.Insert(0, 'Accept-Encoding: gzip, deflate');
SynHttp.Headers.Insert(0, 'X-Requested-With: XMLHttpRequest');
SynHttp.Headers.Insert(0, 'Accept: */*');
SynHttp.Headers.Insert(0, 'DNT: 1');
SynHttp.Document.Write(Pointer(URLData)^, Length(URLData));
SynHttp.HTTPMethod('POST', adres + komenda);
cookies := SynHttp.Cookies.Text;
//MessageBox(0, PChar(cookies), 'chomik zaloguj 1', MB_OK or MB_DEFBUTTON2 or MB_ICONWARNING);
SynHttp.Document.SaveToFile('C://00 logowanie synapse.html');
case SynHttp.ResultCode of
301, 302 :
begin
for I := 0 to SynHttp.Headers.Count - 1 do
begin
Str := SynHttp.Headers[I];
Position := Pos(Location_Prefix, Str);
if Position > 0 then
begin
RedirUrl := Copy(Str, Position + Length(Location_Prefix), MaxInt);
if Pos('/', RedirUrl) = 1 then
begin
RedirUrl := adres + RedirUrl;
end
else
begin
RedirUrl := adres + '/' + RedirUrl;
end;
end;
end;
SynHttp.Headers.Clear;
SynHttp.Document.Write(Pointer(URLData)^, Length(URLData));
SynHttp.HTTPMethod('POST', RedirUrl);
cookies := SynHttp.Cookies.Text;
//MessageBox(0, PChar(cookies), 'chomik zaloguj 2', MB_OK or MB_DEFBUTTON2 or MB_ICONWARNING);
SetLength(FPage, SynHttp.Document.Size);
SynHttp.Document.Read(PChar(FPage)^, Length(FPage));
if Pos('topbarTransferHelp', FPage) > 0 then
begin
MessageBox(0, PChar('Zalogowany prawidłowo.'), PChar(naglowek), MB_ICONINFORMATION + MB_OK);
end;
if Pos('LoginError', FPage) > 0 then
begin
MessageBox(0, PChar('Podane hasło lub login są nieprawidłowe.'), PChar(naglowek), MB_ICONERROR + MB_OK);
end;
end
else
begin
SetLength(FPage, SynHttp.Document.Size);
SynHttp.Document.Read(PChar(FPage)^, Length(FPage));
MessageBox(0, PChar('Problem z łączem. Spróbuj jeszcze raz.'), PChar(naglowek), MB_ICONERROR + MB_OK);
end;
end;
// szukanie unikalnego ID oraz name="TreeTicks" dla naszego Chomika/loginu
chomik_id := StringBetween ( FPage, 'name="ChomikId" value="', '"');
chomik_treeticks := StringBetween ( FPage, 'name="TreeTicks" value="', '" />');
//MessageBox(0, PChar(token + login + haslo + ' ' + cookies), 'fsinit', MB_OK or MB_DEFBUTTON2 or MB_ICONWARNING);
Assign(Debug, 'C://01 zalogowany synapse.html');
Rewrite(Debug);
Writeln(Debug, Fpage);
finally
// tutaj nie zamykac sesji SynHTTP, aby byc widocznym jako ciagle zalogowany do Chomika
// przy wywyolywaniu kolejnych komend HTTP POST i GET
//SynHttp.Free;
end;
end;
//______________________________________________________________________________
procedure chomik_mkdir();
var
adres, komenda_katalogi, komenda_pliki, zadanie, wynik : String;
I, Position : integer;
URLData_pliki, URLData_katalogi, URLData_strona, Str, FPage, Redirurl, DirectLink : string;
referer, id_katalogu, nr_podkatalogu : string;
MemStream : TMemoryStream;
begin
// nie trzeba otwierac nowej sesji SynHttp, bo jestesmy w sesji z funkcji chomik_zaloguj()
// i dzięki temu caly czas jestesmy widoczni jako zalogowani do Chomika
try
// klikamy na utworzenie katalogu (nie jest to konieczne)
// na ten POST dostaję prawidlową odpowiedz,
adres := 'http://chomikuj.pl';
referer := 'http://chomikuj.pl/' + login;
komenda_katalogi := '/action/folderOptions/newFolder';
URLData_katalogi := 'chomikId=' + chomik_id + '&folderId=0&__RequestVerificationToken=' + token;
SynHttp.Headers.Clear;
SynHttp.Clear;
SynHttp.Document.Clear;
SynHttp.UserAgent := 'Mozilla/5.0 (Windows NT 5.1; rv:33.0) Gecko/20100101 Firefox/33.0';
SynHttp.MimeType := 'application/x-www-form-urlencoded; charset=UTF-8';
SynHttp.KeepAlive := True;
SynHttp.Protocol := '1.1';
SynHttp.Headers.Insert(0, 'Accept: */*');
SynHttp.Headers.Insert(0, 'Accept-Language: pl,en-US;q=0.7,en;q=0.3');
SynHttp.Headers.Insert(0, 'Accept-Encoding: gzip, deflate');
SynHttp.Headers.Insert(0, 'DNT: 1');
SynHttp.Headers.Insert(0, 'X-Requested-With: XMLHttpRequest');
SynHttp.Headers.Insert(0, 'Referer: ' + referer);
SynHttp.Headers.Insert(0, 'Pragma: no-cache');
SynHttp.Headers.Insert(0, 'Cache-Control: no-cache');
SynHttp.Document.Write(Pointer(URLData_katalogi)^, Length(URLData_katalogi));
SynHttp.HTTPMethod('POST', adres + komenda_katalogi);
cookies := SynHttp.Cookies.Text;
//MessageBox(0, PChar(cookies), 'mkdir 1', MB_OK or MB_DEFBUTTON2 or MB_ICONWARNING);
case SynHttp.ResultCode of
200 :
begin
cookies := SynHttp.Cookies.Text;
// POST tworzący katalog na Chomki
// dostaję na niego odpowiedź: 500 Internal Server Error
komenda_katalogi := '/action/FolderOptions/NewFolderAction';
URLData_katalogi := 'FolderId=0&ChomikId=' + chomik_id + '&FolderName=foldertestowy&AdultContent=false&NewFolderSetPassword=false&Password=&__RequestVerificationToken=' + token;
SynHttp.Headers.Clear;
SynHttp.Clear;
SynHttp.Document.Clear;
SynHttp.UserAgent := 'Mozilla/5.0 (Windows NT 5.1; rv:33.0) Gecko/20100101 Firefox/33.0';
SynHttp.MimeType := 'application/x-www-form-urlencoded; charset=UTF-8';
//SynHttp.MimeType := 'application/json';
SynHttp.KeepAlive := True;
SynHttp.Protocol := '1.1';
SynHttp.Headers.Insert(0, 'Accept: */*');
SynHttp.Headers.Insert(0, 'Accept-Language: pl,en-US;q=0.7,en;q=0.3');
SynHttp.Headers.Insert(0, 'Accept-Encoding: gzip, deflate');
SynHttp.Headers.Insert(0, 'DNT: 1');
SynHttp.Headers.Insert(0, 'X-Requested-With: XMLHttpRequest');
SynHttp.Headers.Insert(0, 'Referer: ' + referer);
SynHttp.Headers.Insert(0, 'Pragma: no-cache');
SynHttp.Headers.Insert(0, 'Cache-Control: no-cache');
SynHttp.Document.Write(Pointer(URLData_katalogi)^, Length(URLData_katalogi));
SynHttp.HTTPMethod('POST', adres + komenda_katalogi);
cookies := SynHttp.Cookies.Text;
//MessageBox(0, PChar(cookies), 'mkdir 3', MB_OK or MB_DEFBUTTON2 or MB_ICONWARNING);
SetLength(FPage, SynHttp.Document.Size);
SynHttp.Document.Read(PChar(FPage)^, Length(FPage));
Assign(Debug, 'C://03 zalogowany tworzenie katalogu.html');
Rewrite(Debug);
Writeln(Debug, FPage);
end;
end;
finally
//SynHttp.Free;
end;
end;
// Glówny program
begin
chomik_zaloguj_synapse;
chomik_mkdir;
end.
Odpowiedź Chomika na próbę utworzenia katalogu za pomocą procedury chomik_mkdir (z powyższego kodu Delphi):
POST /action/FolderOptions/NewFolderAction HTTP/1.1
Host: chomikuj.pl
Connection: keep-alive
Cookie: rcid=9; guid=55dc2e63-3176-44c4-ab0b-0cc70d9ac118; RememberMe=19717347=793b15d6174f3e2956a2f67b3f3a39b7; ChomikSession=43acb718-ccc7-46dd-827a-cce286a94c20; __RequestVerificationToken_Lw__=gFk4xT2WygG8fUzD6CIbueI1bBj3pchsAcXs0JPPgBEXtx4mEyxdhH41d2fzTv/Fpe89/e4smHcX661oCIlfUkSlLrVwKKs+y3E+ZZg7/4AWPmND7ooxwEgvCF7so3twNx/PhA==
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:33.0) Gecko/20100101 Firefox/33.0
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Content-Length: 285
Cache-Control: no-cache
Pragma: no-cache
Referer: http://chomikuj.pl/chomik_testowy1
X-Requested-With: XMLHttpRequest
DNT: 1
Accept-Encoding: gzip, deflate
Accept-Language: pl,en-US;q=0.7,en;q=0.3
Accept: */*
FolderId=0&ChomikId=19717347&FolderName=foldertestowy&AdultContent=false&NewFolderSetPassword=false&Password=&__RequestVerificationToken=TpEdNts1DXaRXftJt%2Bfa%2F2smty%2BH%2BW7dGMDfxhIAMA9t0MC8y669Dg1sDqrMTIEyFE4qCfwPGrDczmY6r4yY32Khr3IZz4aHjfqC4l2mSqnWiRwmIN4NSWRQ1lmFvoWEtxj46Q%3D%3D
HTTP/1.1 500 Internal Server Error
Cache-Control: private
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/7.5
X-Server: m30
Date: Sun, 01 Mar 2015 23:36:40 GMT
Connection: close
Content-Length: 203
{"Type":"Window","Title":"Błąd","Content":"Niestety podczas przetwarzania żądania wystąpił błąd.","refreshTopBar":false,"IsSuccess":true,"Data":null,"ContainsCaptcha":false,"trackingCodeJS":null}
A poniżej utworzenie katalogu w AutoIt. Jak widać nawet nagłówek ma mniej danych i poszło. W Delphi zrobiłem taki sam nagłówek i nie zadziałało, odpowiedź 500.
POST /action/FolderOptions/NewFolderAction HTTP/1.1
Referer: http://chomikuj.pl/chomik_testowy1
Content-Type: application/x-www-form-urlencoded
Host: chomikuj.pl
Content-Length: 293
Connection: Keep-Alive
Cookie: rcid=7; __RequestVerificationToken_Lw__=r1svj+tG24JzpM6vpUpP+WAif0PO8wtpR8HaWrpJzvcvmS8z3YeHajT5mYq3fwnutxBRLFis0+In5urhHS3oinIw+TIjoCW62Cma2cw/QnFTMcPrCuQxiteTFrXDTe+TJvavOA==; ChomikSession=5e026036-2308-47e7-93e0-d97f4c52654f; guid=9189d54a-b352-4d93-bc26-4c1b2d8374b4; RememberMe=19717347=793b15d6174f3e2956a2f67b3f3a39b7
FolderId=0&ChomikId=19717347&FolderName=katalog_testowy&AdultContent=false&NewFolderSetPassword=false&Password=&__RequestVerificationToken=vGiUsjIR%2Bpzj683SapvmmWEoZtPFG8Q3jvHeBQUVyBCTC%2B1tMUTcoArakrb2MEpzGfy%2BF%2BWACRleUzpgUeGg61zfOa%2FslExxY6ax%2FnCF1VMnfp25HknacKuk7qi3VxmclgA%2B5A%3D%3D
HTTP/1.1 200 OK
Cache-Control: private
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/7.5
X-Server: m32
Date: Mon, 02 Mar 2015 18:41:14 GMT
Connection: close
Content-Length: 166
{"Type":"Growl","Title":"","Content":"Folder został dodany","refreshTopBar":false,"IsSuccess":true,"Data":{"Status":0},"ContainsCaptcha":false,"trackingCodeJS":null}