Форум русскоязычного сообщества Ubuntu


Следите за новостями русскоязычного сообщества Ubuntu в Twitter-ленте @ubuntu_ru_loco

Автор Тема: Язык С HTTP запросы  (Прочитано 4049 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн kolia8888

  • Автор темы
  • Новичок
  • *
  • Сообщений: 9
    • Просмотр профиля
Язык С HTTP запросы
« : 23 Декабря 2012, 19:53:35 »
(Нажмите, чтобы показать/скрыть)


Доброго времени суток, я новичок в данном деле но везде написано что по отправлению простого GET запроса типа GET путь HTTP/1.1\r\n\r\n сервер вернет статус  а следом и страницу. Подскажите что я делаю не так.

Пользователь решил продолжить мысль 23 Декабря 2012, 21:05:13:
kolia88@tux ~ $ ./test --connect ru.wikipedia.org/wiki/%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0 80
1
ru.wikipedia.org/wiki/%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0
GET /wiki/%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0 HTTP/1.1
Host: ru.wikipedia.org
User-Agent: Mozilla/5.0(X11;Linuxx86_64;en,ru;rv:17.0)Gecko/20100101Firefox/17.0
Accept: text/html,application/json,text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,image/jpeg,image/gif;q=0.2,text/css,*;q=0.1
Accept-Language: ru;q=0.50
Accept-Encoding: gzip,deflate,compress;q=0.9
Accept-Charset: ISO-8859-1,utf-8;q=0.66,*;q=0.66
Connection: close


2
3
91.198.174.225:204804
7

8
HTTP/1.0 200 OK
X-Content-Type-Options: nosniff
Content-Language: ru
Content-Encoding: gzip
Content-Length: 24547
Server: Apache
Cache-Control: private, s-maxage=0, max-age=0, must-revalidate
Vary: Accept-Encoding,Cookie
Date: Sun, 23 Dec 2012 16:53:49 GMT
Content-Type: text/html; charset=UTF-8
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Last-Modified: Sun, 23 Dec 2012 14:05:15 GMT
X-Cache: HIT from amssq41.esams.wikimedia.org
X-Cache-Lookup: HIT from amssq41.esams.wikimedia.org:3128
Age: 76
X-Cache: HIT from amssq37.esams.wikimedia.org
X-
200
Исходный код: http://bpaste.net/show/66155/
testegg.c -o test -Wall
использование:
./test --connect ru.wikipedia.org/wiki/%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0 80



(Нажмите, чтобы показать/скрыть)

« Последнее редактирование: 23 Декабря 2012, 21:24:17 от kolia8888 »

Оффлайн Self-Perfection

  • Активист
  • *
  • Сообщений: 331
  • Arch linux, KDE
    • Просмотр профиля
Re: Язык С HTTP запросы
« Ответ #1 : 23 Декабря 2012, 21:17:06 »
Подскажите что я делаю не так.
Возможно, решаете задачу слишком длинным путём (т.к. задача сформулирована не была, приходится гадать). Почему бы не воспользоваться libcurl?...
Читайте документацию, наставницу вашу!
Памятка по описанию проблем:
Для решения [такой-то задачи] делаю [такие-то действия], но вместо [ожидаемый результат] получаю [описание отличий].

Оффлайн kolia8888

  • Автор темы
  • Новичок
  • *
  • Сообщений: 9
    • Просмотр профиля
Re: Язык С HTTP запросы
« Ответ #2 : 23 Декабря 2012, 21:20:21 »
Это не задача и не работа, сам себе поставил задачу для среза умения, как сделать мини браузер в консоле, не прибегая к стороннему по а онли язык Си. Должно же быть простое решение забыл или пробел какой или поток какой другой у меня не хватает опыта пробить эту страницу, опишу в кратце tcpdump показывает прогруз в тот момент когда я запускаю программку прогруз как браузер, но в консоле выводится только ответ с сервера и страницу которая прогружается не вижу. Вобщем задача выполнена ответы есть. а обидно что нету страниц, да и что этот либ курл тоже написан на такой же теме скорее всего.

Пользователь решил продолжить мысль 23 Декабря 2012, 21:36:11:
Блок генерации запросов
(Нажмите, чтобы показать/скрыть)


Ссылаясь на ресурс http://ru.wikipedia.org/wiki/HTTP
Запрос клиента:

GET /wiki/страница HTTP/1.1
Host: ru.wikipedia.org
User-Agent: Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9b5) Gecko/2008050509 Firefox/3.0b5
Accept: text/html
Connection: close
(пустая строка)

Ответ сервера:

HTTP/1.1 200 OK
Date: Wed, 11 Feb 2009 11:20:59 GMT
Server: Apache
X-Powered-By: PHP/5.2.4-2ubuntu5wm1
Last-Modified: Wed, 11 Feb 2009 11:20:59 GMT
Content-Language: ru
Content-Type: text/html; charset=utf-8
Content-Length: 1234
Connection: close
(пустая строка)
(далее следует запрошенная страница в HTML)

« Последнее редактирование: 23 Декабря 2012, 21:44:33 от kolia8888 »

Оффлайн Yurror

  • Старожил
  • *
  • Сообщений: 1966
    • Просмотр профиля
Re: Язык С HTTP запросы
« Ответ #3 : 24 Декабря 2012, 08:08:16 »
Эм... ну википедии будет не достаточно. Но в ней ты сможешь найти ссылки на RFC =) Вперед и с песней.
Попробуй воспользоваться для отладки

telnet ru.wikipedia.org 80
Trying 91.198.174.225...
Connected to wikipedia-lb.esams.wikimedia.org.
Escape character is '^]'.
GET /wiki/HTTP HTTP/1.1
Host: ru.wikipedia.org
Connection: close


Оффлайн kolia8888

  • Автор темы
  • Новичок
  • *
  • Сообщений: 9
    • Просмотр профиля
Re: Язык С HTTP запросы
« Ответ #4 : 24 Декабря 2012, 23:16:39 »
Вот что выводит в данный момент после Энтера должна быть страница думаю я выполнил вышеперечисленное
(Нажмите, чтобы показать/скрыть)

Пользователь решил продолжить мысль 24 Декабря 2012, 23:22:04:
Тогда просто не понятно становиться почему  он выводит посчле ответа часть того что отправил?
« Последнее редактирование: 24 Декабря 2012, 23:22:04 от kolia8888 »

Оффлайн ii343hbka

  • Старожил
  • *
  • Сообщений: 1048
    • Просмотр профиля
Re: Язык С HTTP запросы
« Ответ #5 : 25 Декабря 2012, 00:37:41 »
напечатайте buf после recv
ж)
ммм... Убунточка

Оффлайн kolia8888

  • Автор темы
  • Новичок
  • *
  • Сообщений: 9
    • Просмотр профиля
Re: Язык С HTTP запросы
« Ответ #6 : 25 Декабря 2012, 09:24:50 »
Последняя версия то что напечатано до вашей просьбы реализовано следующим образом:
(Нажмите, чтобы показать/скрыть)

Оффлайн kolia8888

  • Автор темы
  • Новичок
  • *
  • Сообщений: 9
    • Просмотр профиля
Re: Язык С HTTP запросы
« Ответ #7 : 26 Декабря 2012, 13:40:07 »
Вот что выводит последняя версия программки. почему так?
(Нажмите, чтобы показать/скрыть)

Пользователь решил продолжить мысль 26 Декабря 2012, 13:41:57:
а вот ответ от гугля
(Нажмите, чтобы показать/скрыть)

Пользователь решил продолжить мысль 26 Декабря 2012, 13:50:28:
что самое странное на одной машине запускается и так отвечает часть страниц, на другой машине допустим страницы уже не тянет, а просто копирует часть запроса клиента...


Пользователь решил продолжить мысль 26 Декабря 2012, 21:03:02:
Проблему решил всем спасибо!
« Последнее редактирование: 26 Декабря 2012, 21:03:02 от kolia8888 »

Оффлайн Yurror

  • Старожил
  • *
  • Сообщений: 1966
    • Просмотр профиля
Re: Язык С HTTP запросы
« Ответ #8 : 26 Декабря 2012, 21:05:24 »
Заказывая
"Accept-Encoding: gzip,deflate,compress;q=0.9\r\n"Будь готов принимать сжатые данные =) ну это к слову о бездумном копировании всех заголовков подряд

Я дал конкретный рабочий пример
для решения твоей задачи необходимо:
1) открыть сокет и установить соединение с необходимым хостом
2) передать запрос
3) получить ответ
4) закрыть соединение (keep-alive сейчас еще не рассматриваем)

У тебя там всё смешалось, люди, кони... Оформляй всё красиво самому понятно станет! Это я тебе из опыта говорю а не придираюсь. Си не терпит неряшливости. Лучше всего если ты посмотришь стандарты кодирования и выберешь себе какой-нибудь стиль.

/*
 * File:   main.c
 * Author: yurik
 *
 * Created on 26 Декабрь 2012 г., 23:46
 */

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>


int open_socket(const char *remote_host, const char *remote_port)
{
    struct addrinfo hints, *res, *rp;
    int n, fd;
   
    memset(&hints, 0, sizeof hints);
    hints.ai_family = PF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;

    n = getaddrinfo(remote_host, remote_port, &hints, &res);
    if (n != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(n));
        return -1;
    }
   
    for (rp = res; rp != NULL; rp = rp->ai_next) {
        if ((fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol)) < 0) {
            perror("socket");
            continue;
        }
l_start_connect:
        if ((n = connect(fd, rp->ai_addr, rp->ai_addrlen)) < 0) {
            if (errno == EINTR)
                goto l_start_connect;
            perror("connect");
            continue;
        }
        break; /* Success */
    }
   
    freeaddrinfo(res);           /* No longer needed */
   
    if (rp == NULL) { /* No address succeeded */
        fprintf(stderr, "can't establish connection\n");
        return -1;
    }

    return fd;
}

int main(int argc, char** argv)
{
    int fd;
    FILE *fp;
    char *line = NULL;
    size_t len = 0;
    ssize_t read;
   
    if (argc < 4) {
        fprintf(stderr, "Usage %s <host> <port> <URI>\n"
                "\t%s ru.wikipedia.org 80 /wiki/HTTP\n"
                argv[0],
                argv[0]
               );
        return EXIT_FAILURE;
    }
   
    /* Открываем сокет и соединяемся */
    if ((fd = open_socket(argv[1], argv[2])) < 0) {
        return EXIT_FAILURE;
    }
   
    /* Можно поднатужиться и реализовать свою буфферизацию
     * А можно воспользоваться той что уже есть в стандартной библиотеке
     * Будет работать только в блокирующем режиме
     * Для асинхронных сокетов нужна будет своя реализация буфферизации
     * man 3 fdopen
     */
    if ((fp = fdopen(fd, "a+")) == NULL) {
        perror("fdopen");
        return EXIT_FAILURE;
    }
   
    /* Отправить запрос */
    fprintf(fp, "GET %s HTTP/1.1\r\n"
                "Host: %s\r\n"
                "Connection: close\r\n"
                "\r\n",
            argv[3],
            argv[1]
           );
    fflush(fp);

    /* Чтение ответа сервера
     * Читает по строкам. man 3 getline
     * Вместо вывода можно складывать строчки в контейнер,
     * например список чтобы потом распарсить на заголовки и тело ответа
     * Будет работать только с текстовым ответом
     * По хорошему надо строчки считывать до первой пустой строки.
     * Потом считанные строки анализировать и смотреть на статус отвта и искать
     * заголовок с длиной ответа. потом одним BLOB'ом читать тело ответа
     */
    while ((read = getline(&line, &len, fp)) != -1) {
        printf("Retrieved line of length %zu :\n", read);
        printf("\"%s\"\n", line);
    }

    /* По мануалу getline */
    free(line);
   
    /* Закрываем коннект с нашей стороны, освобождаем ресурсы */
    fclose(fp);
   
    return (EXIT_SUCCESS);
}



Оффлайн kolia8888

  • Автор темы
  • Новичок
  • *
  • Сообщений: 9
    • Просмотр профиля
Re: Язык С HTTP запросы
« Ответ #9 : 28 Декабря 2012, 22:51:34 »
Сделал, рабочий клиент для close) у меня не так получилось как у вас, но работает)))

 

Страница сгенерирована за 0.022 секунд. Запросов: 22.