Работа с HTTP

Кучи вопросов на форуме antichat.ru посвящены работе с HTTP протоколом.
В посте я не буду вдаваться в подробности работы с сокетами, а лишь дам примеры программ для отправки GET и POST запросов на JavaScript, PHP, PERL, C, Delphi, Assembler.


HTTP

Для поверхностного ознакомления можешь прочитать статью на педовикии, а для глубокого проникновения RFC.

Обычный GET запрос

GET /index.htm HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Referer: http://example.org/
Host: example.org
Accept: text/*;q=0,9
Connection: close
Отправляем GET запрос по адресу http://example.org/index.htm, говоря при этом, что мы пришли с http://example.org/ и используем IE 6.0 нам нужен только текст и мы не собираемся поддерживать постоянное соединение с сервером (после ответа сервер разрывает соединение)

Обычный POST запрос

POST /lol.php HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Referer: http://example.org/
Content-Type: application/x-www-form-urlencoded
Content-Length: 12
Host: example.org
Accept: text/*;q=0,9
Connection: close

login=admin;
Отправляем POST запрос по адресу http://example.org/lol.php где данные формы это обычные данные и поле login заполнено как ‘admin’

Так же в запросе мы можем отправлять файл тогда
Content-Type: multipart/form-data;
и запрос может содержать cookie
Cookie: sess=123; lol=lmd;

Ну-с господа теперь давайте, реализуем это программно.

JavaScript

Вы наверняка слышали о такой замечательной технологии как AJAX, а ведь это не что иное, как асинхронные GET и POST запросы. Основой является ActiveX объект XMLHttpRequest

// функция для обеспечения кросс-браузерности
function createRequestObject()
{
    if (window.XMLHttpRequest) {
        try {
            return new XMLHttpRequest();
        } catch (e){}
    } else if (window.ActiveXObject) {
        try {
            return new ActiveXObject('Msxml2.XMLHTTP');
        } catch (e){
          try {
              return new ActiveXObject('Microsoft.XMLHTTP');
          } catch (e){}
        }
    }
    return null;
}

//функция обработчик ответа
function processReqChange()
{
  try { // Важно!
    // только при состоянии "complete"
    if (req.readyState == 4) {
        // для статуса "OK"
        if (req.status == 200) {
            // обработка ответа
            alert(responseText);
        } else {
            alert("Не удалось получить данные:\n" +
                req.statusText);
        }
    }
  }
  catch( e ) {
      // alert('Caught Exception: ' + e.description);
      // В связи с багом XMLHttpRequest в Firefox приходится отлавливать ошибку
      // Bugzilla Bug 238559 XMLHttpRequest needs a way to report networking errors
      // https://bugzilla.mozilla.org/show_bug.cgi?id=238559
  }
}

Var req=createRequestObject();

// пример отправки GET запроса
req.open("GET", “http://example.org/index.htm”, true);
req.onreadystatechange = processReqChange;
req.send(null);

// пример отправки POST запроса
req.open(“POST", “http://example.org/lol.php”, true);
req.setRequestHeader ("Content-Type", "application/x-www-form-urlencoded");
req.onreadystatechange = processReqChange;
req.send(‘a=b;’);

Это далеко не единственный способ работы с AJAX существует множество библеотек и фреймворков я лишь могу выделить среди них JsHttpRequest и Jquery

PHP

    header('Content-Type: text/plain;');
    error_reporting(E_ALL ^ E_WARNING);
    set_time_limit(0);
    ob_implicit_flush();

    $address = 'example.org';
$path = ‘/index.htm’;
$refferer=’http://’. $address.’/’;
$port    = 80;

    try {
    
        echo 'Create socket ... ';
        $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        if ($socket < 0) {
            throw new Exception('socket_create() failed: '.socket_strerror(socket_last_error())."\n");
        } else {
            echo "OK\n";
        }

        echo 'Connect socket ... ';
        $result = socket_connect($socket, $address, $port);
        if ($result === false) {
            throw new Exception('socket_connect() failed: '.socket_strerror(socket_last_error())."\n");
        } else {
            echo "OK\n";
        }

        
        
        $msg = ="GET $path HTTP/1.1\n"
    ."User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\n"
    ."Referer: $referer\n"
    ."Host: $address\n"
    ."Accept: text/*;q=0,9\n"
    ."Connection: close\n\n";
        echo "Send to server ($msg) ...";
        socket_write($socket, $msg, strlen($msg));
        echo "OK\n";
        
        echo 'Recv: ';
        $out = socket_read($socket, 1024);
        echo $out."\n";
        
  
        
    } catch (Exception $e) {
        echo "\nError: ".$e->getMessage();
    }
    
    if (isset($socket)) {
    
        echo 'Close socket ... ';
        socket_close($socket);
        echo "OK\n";
        
    }

Читаем документацию господа

PERL


Дока - http://perldoc.perl.org/IO/Socket/INET.html

Теперь о языках высокого уровня.

#include 
#include 
#pragma comment(lib,"Winhttp.lib")

BOOL HttpSend(LPCWSTR pswzServerName,LPCWSTR pswzVerb, LPCWSTR pswzObjectName, LPCVOID lpBuffer, DWORD dwBufferLength)
{
 BOOL  bResults = FALSE;
 HINTERNET  hSession = NULL, hConnect = NULL, hRequest = NULL;
 DWORD dwBytesWritten;

 hSession = WinHttpOpen( L"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0 );
 if( hSession )
 {
  hConnect = WinHttpConnect( hSession, pswzServerName,INTERNET_DEFAULT_HTTP_PORT, 0 );
  if( hConnect )
  {
   hRequest = WinHttpOpenRequest( hConnect, pswzVerb, pswzObjectName, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_REFRESH );
   if( hRequest )
   {
    if( pswzVerb[0] == 0x50 ) // POST
     bResults = WinHttpSendRequest( hRequest, L"Content-Type: application/x-www-form-urlencoded", -1L, lpBuffer, dwBufferLength, dwBufferLength, 0 );
    else
     bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, NULL, 0, 0, 0 );

    if( bResults )
     bResults = WinHttpReceiveResponse( hRequest, NULL );
    WinHttpCloseHandle( hRequest );
   }
   WinHttpCloseHandle( hConnect );
  }
  WinHttpCloseHandle( hSession );
 }
 return bResults;
}

int main() 
{
 HttpSend(L"localhost",L"POST",L"/post.php","test=1234",9);
 return 0;
}
^ Наглядное использование WinHTTP на языке С

Так как на них программы получаются довольно объемные я дам ссылки на статьи с исходниками:

Си + WinSock - тыкай
Delphi + WinSock - тыкай раз, тыкай два

FASM + WinSock зная как работать с сокетами, спокойно разберешься здесь.

Ну и как бонус мои простые программки на Си + WinAPI + WinSock32


Комментарии

  1. 1. Для начала стоит отметить, что Яваскипт в большинстве браузеров не позволяет совершать xmlhttprequest на сторонние хосты, из-за безопасности.Стоит покопать в сторону XDomainRequest.
    2. В перле есть модуль LWP::*(LWP::UserAgent, LWP::Simple), не обязательно сокеты(если уж совсем основы, то юзайте Socket с обработкой таймаутов итд, чтобы было нагляднее).
    3. Имхо формочки и компоненты - зло, легче и нагляднее показать на примере консольного приложение, дабы не приучивать школоту компоненты и формочки по воркспейсу раскидывать, тем самым не плодить быдлокодеров.

    ОтветитьУдалить
  2. 2. Я считаю что гораздо лучше для организма разобраться с сокетами, а не с его оберткой заточенной под HTTP. В дальнейшем ораганизму будет легче приспособиться и понять любой протокол. Конечно в сети много готового, но лично я инженер-велосипедист ))
    3. Я согласен с тобой delphi и VCL зло, но ссылки я даю на "правильные" программы, где если и есть GUI то написаный чисто на системных функциях - WinAPI

    З.Ы: появиться время я доработаю статью со всеми пожеланиями )

    ОтветитьУдалить

Отправить комментарий

Популярные сообщения из этого блога

Сказ об убунте заморской

Debian + Openbox