FTP with CERN-Based Proxy Using WinInet API

Тема в разделе "WASM.NETWORKS", создана пользователем vg, 3 мар 2009.

  1. vg

    vg New Member

    Публикаций:
    0
    Регистрация:
    16 апр 2007
    Сообщения:
    475
    Как эту строку получить программно, в моём коде?
     
  2. dag

    dag New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2004
    Сообщения:
    446
    в твоём случае если hConnect == NULL то смотрим что вернёт InternetGetLastResponseInfo
    P.S.
    Это всё есть в MSDN
    P.P.S.
    Делай лучше через CONNECT и разруливай сам ситуации
    P.P.P.S.
    Хотя как хотИШЬ (я вижу не MSDN не RFC читать не хочешь)
     
  3. dag

    dag New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2004
    Сообщения:
    446
    Позволю выдержку из MSDN (надеюсь не обидиться бОльшой брат)
     
  4. dag

    dag New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2004
    Сообщения:
    446
    http://muffin.doit.org/docs/rfc/tunneling_ssl.html
    тут есть про создание тунеля через цюрих
     
  5. vg

    vg New Member

    Публикаций:
    0
    Регистрация:
    16 апр 2007
    Сообщения:
    475
    В том то и дело, что если с прокси всё нормально, то hConnect == NULL ВСЕГДА. В то время, как целевой FTP мог вернуть ошибку, например, 530 или 11001. Прокси определяет и сообщает об этом (можно увидеть через бараузер). Как мне эту ошибку определить в моём коде, программно? Не читать же возвращаемую прокси сервером HTML-страницу через InternetReadFile и искать в ней код ошибки.
    Я знаю и читаю, но ответ на свой вопрос пока не нашёл.
     
  6. dag

    dag New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2004
    Сообщения:
    446
    InternetGetLastResponseInfo вернет строку с ответом сервера
     
  7. vg

    vg New Member

    Публикаций:
    0
    Регистрация:
    16 апр 2007
    Сообщения:
    475
    Прокси-сервера.
    Получается то же, о чём я писал в предыдущем посте.
    Если с прокси всё нормально, то InternetGetLastResponseInfo ВСЕГДА показывает, что всё ОК (dwError=0), даже если к целевому FTP не удалось подключиться.
    Т. е. InternetGetLastResponseInfo показывает состояние прокси-сервера, а не целевого FTP.
     
  8. vg

    vg New Member

    Публикаций:
    0
    Регистрация:
    16 апр 2007
    Сообщения:
    475
    А мне нужно то, что ответил целевой FTP.
     
  9. dag

    dag New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2004
    Сообщения:
    446
    HttpQueryInfo тебе в помощь
    Код (Text):
    1. int _tmain(int argc, _TCHAR* argv[])
    2. {
    3.     DWORD mError;
    4.     DWORD mSize=4;
    5.     HINTERNET hOpen;
    6.     HINTERNET hConnect;
    7.     hOpen=::InternetOpen(L"WinInetExample",INTERNET_OPEN_TYPE_PRECONFIG , NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION);
    8.     hConnect = InternetOpenUrl(hOpen,L"ftp://ftp.google.ru/1.html",NULL,NULL,INTERNET_FLAG_DONT_CACHE |INTERNET_FLAG_KEEP_CONNECTION |INTERNET_FLAG_RELOAD, 0);
    9.     HttpQueryInfo(hConnect,HTTP_QUERY_STATUS_CODE,&mError,&mSize,NULL);
    10.              printf("Error Code: %i",mError);
    11.     return 0;
    12. }
     
  10. vg

    vg New Member

    Публикаций:
    0
    Регистрация:
    16 апр 2007
    Сообщения:
    475
    То же самое, третий параметр всегда HTTP_STATUS_OK.
     
  11. dag

    dag New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2004
    Сообщения:
    446
    Код покажи свой, у меня на многих серверах (на всех которые пробовал) всё Ok и с InternetGetLastResponseInfo и HttpQueryInfo
     
  12. vg

    vg New Member

    Публикаций:
    0
    Регистрация:
    16 апр 2007
    Сообщения:
    475
    Код (Text):
    1.     DWORD dwCode, dwSize, dwLength;
    2.     TCHAR  msg[1024];
    3.     CHAR *szBuffer;
    4.     BOOL bInitalRequest = TRUE;
    5.  
    6.     // 1) Starting session
    7.     HINTERNET hInternet = InternetOpen(_T("foo"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION);
    8.    
    9.     if(!hInternet)
    10.     {
    11.         AfxMessageBox(_T("Не удалось начать сеанс"), MB_OK);
    12.         return;
    13.     }
    14.    
    15.     // 2) Try to connect
    16.     HINTERNET hConnect = InternetOpenUrl(hInternet, _T("ftp://ftp.microsoft.com/"), NULL, 0, INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_RELOAD, 0);
    17.  
    18.     if (!hConnect)
    19.     {
    20.         wsprintf(msg, _T("%d"), GetLastError());
    21.         MessageBox(0, msg, _T("InternetOpenUrl error"),MB_OK);
    22.         return;
    23.     }
    24.  
    25.     again:
    26.    
    27.     if (!bInitalRequest)
    28.     {
    29.         if (!HttpSendRequest (hConnect, NULL,0,NULL, 0))
    30.         {
    31.             wsprintf(msg, _T("%d"), GetLastError());
    32.             MessageBox(0, msg, _T("HttpSendRequest error"),MB_OK);
    33.             return;
    34.         }      
    35.     }
    36.  
    37.     dwSize = sizeof(dwCode);
    38.     if (!InternetQueryOption(hConnect, INTERNET_OPTION_HANDLE_TYPE, &dwCode, &dwSize))
    39.     {
    40.         wsprintf(msg, _T("%d"), GetLastError());
    41.         MessageBox(0, msg, _T("InternetQueryOption error"),MB_OK);
    42.         return;
    43.     }
    44.  
    45.     if ((dwCode == INTERNET_HANDLE_TYPE_HTTP_REQUEST) || (dwCode == INTERNET_HANDLE_TYPE_CONNECT_HTTP))
    46.     {
    47.         // if were are here, it means that we use HTTP to talk the proxy
    48.         dwSize = sizeof (DWORD);  
    49.         if (!HttpQueryInfo (hConnect, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwCode, &dwSize, NULL))
    50.         {
    51.             wsprintf(msg, _T("%d"), GetLastError());
    52.             MessageBox(0, msg, _T("HttpQueryInfo error"),MB_OK);
    53.             return;
    54.         }
    55.        
    56.         if (dwCode == HTTP_STATUS_PROXY_AUTH_REQ)
    57.         {
    58.             if (!InternetQueryDataAvailable (hConnect, &dwLength, 0,0))
    59.             {
    60.                 wsprintf(msg, _T("%d"), GetLastError());
    61.                 MessageBox(0, msg, _T("InternetQueryDataAvailable error"),MB_OK);
    62.                 return;
    63.             }
    64.  
    65.             // Acquire user credentials.
    66.             TCHAR szUser[50];
    67.             TCHAR szPass[50];
    68.             if ( !InternetSetOption (hConnect, INTERNET_OPTION_PROXY_USERNAME, (LPVOID) szUser, lstrlen (szUser) ))
    69.             {
    70.                 wsprintf(msg, _T("%d"), GetLastError());
    71.                 MessageBox(0, msg, _T("InternetSetOption error"),MB_OK);
    72.                 return;
    73.             }
    74.  
    75.             if (!InternetSetOption (hConnect, INTERNET_OPTION_PROXY_PASSWORD, (LPVOID) szPass, lstrlen (szPass) ))
    76.             {
    77.                 wsprintf(msg, _T("%d"), GetLastError());
    78.                 MessageBox(0, msg, _T("InternetSetOption error"),MB_OK);
    79.                 return;
    80.             }
    81.  
    82.             bInitalRequest = FALSE;
    83.             goto again;
    84.  
    85.         }   // if ( dwCode == HTTP_STATUS_PROXY_AUTH_REQ
    86.         else
    87.         {
    88.  
    89.             wsprintf(msg, _T("%d"), dwCode);
    90.             MessageBox(0, (LPCTSTR)msg,0 ,MB_OK);
    91.  
    92.         }
    93.     }   // if ( (dwCode == INTERNET_HANDLE_TYPE_HTTP_REQUEST
    94.  
    95.     // 3) Close connection
    96.     InternetCloseHandle(hConnect);
    97.     InternetCloseHandle(hInternet);
    98. }
     
  13. dag

    dag New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2004
    Сообщения:
    446
    Всё Ок, например попробуй в качестве proxy 212.56.203.196:3128, или
    41.154.2.4:3128 в случае ошибки закрывает соединение =)
    P.S.
    Посмотри что возвращает тебе proxy в живую с помощью тогоже Wireshark, если на любую ошибку 200 => он так настроен и придётся тебе парсить хтмлный код
     
  14. dag

    dag New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2004
    Сообщения:
    446
    он = proxy server
     
  15. vg

    vg New Member

    Публикаций:
    0
    Регистрация:
    16 апр 2007
    Сообщения:
    475
    А эти прокси CERN-based?
    Как тогда работает, например, Total Commander с FTP? Не хтмл же он парсит?
    Не понял. Что это значит?
     
  16. dag

    dag New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2004
    Сообщения:
    446
    он = сервер
    Based не based, но compatible точно, причём 212.56.203.196 ,похоже, более compatible чем тот что 41.154.2.4 (оба SQUID 1 представи=) А ты на чистом CERN/W3C httpd тестируешь? Разница то какая? Общение с удалёным сервером идёт через представителя по HTTP протоколу.

    212.56.203.196
    Код (Text):
    1. GET ftp://ftp.microsoft.com/ HTTP/1.1
    2. User-Agent: foo
    3. Host: ftp.microsoft.com:21
    4. Proxy-Connection: Keep-Alive
    5. Pragma: no-cache
    6.  
    7. HTTP/1.0 200 OK
    8. Server: squid/2.5.STABLE11
    9. Mime-Version: 1.0
    10. Date: Mon, 25 May 2009 23:03:59 GMT
    11. Content-Type: text/html
    12. X-Cache: MISS from proxy
    13. Proxy-Connection: closeonnection: keep-alive
    41.154.2.4
    Код (Text):
    1. GET ftp://ftp.microsoft.com/ HTTP/1.1
    2. User-Agent: foo
    3. Host: ftp.microsoft.com:21
    4. Proxy-Connection: Keep-Alive
    5. Pragma: no-cache
    6.  
    7. HTTP/1.0 200 Gatewaying
    8. Server: squid/3.0.STABLE13
    9. Mime-Version: 1.0
    10. Date: Mon, 25 May 2009 20:06:15 GMT
    11. Content-Type: text/html
    12. X-Cache: MISS from localhost
    13. X-Cache-Lookup: MISS from localhost:3128
    14. Via: 1.0 localhost (squid/3.0.STABLE13)
    15. Proxy-Connection: close
     
  17. dag

    dag New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2004
    Сообщения:
    446
    А TotalCommander через WinInet работает (я не знаю, могу канечно посмотреть, но возможно он через CONNECT пытается работать, ну или чтото подобное)
     
  18. dag

    dag New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2004
    Сообщения:
    446
    WinCMD умеет работать как через CONNECT так и через CERN + куча других способов и при этом он, похоже, не использует InternetOpenUrl для этого.
     
  19. vg

    vg New Member

    Публикаций:
    0
    Регистрация:
    16 апр 2007
    Сообщения:
    475
    Это как?
     
  20. dag

    dag New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2004
    Сообщения:
    446
    Грубо говоря - организуя туннель через представителя. Посылаешь представителю комманду CONNECT adress:port, если на нём разрешены соединения подобного рода то соответсвенно он устанавливает соединение и все данные напрямую перебрасывает между тобой и удалённым сервером, а ты уже общаешься с потусторонним сервером как тебе надобно, в нашем случае по FTP протоколу.

    Если хочешь именно через WinInet работать то все данные у тебя уже есть, посмотри снифером любым поток как общается WinInet с твоим представителем. В общем виде тебе от представителя необходимо ловить то что выдают InternetGetLastResponseInfo и HttpQueryInfo, тоесть заголовки ответов прокси серверв. FTP протокол тебе в этом случае недоступен, ибо ты общаешься с удалённым FTP сервером через, скажем так, интелектуального посредника (удалённого FTP клиента), и управляешь ты им HTTP запросами. Через заголовки ответов Proxy Server иммено так тебе и сообщает что ему требуется авторизация на удалённом сервере или файл ненайден или адрес неверен etc., ну или разрывает связь давая, без объяснений причины, тебе понять что какойто параметр ты задал неверно (пароль, адрес и т.д.).