GET Request только получает пустую строку - PullRequest
0 голосов
/ 18 июня 2019

Мне был дан пример кода C, который отправляет введенные пользователем запросы на указанный сервер и печатает ответы. Теперь я должен изменить код, чтобы HTTP-запрос отправлялся на http://www.stardrifter.org/cgi-bin/ref.cgi с установленным заголовком Referer. Запрос успешно отправлен, но в ответ я получаю только пустые строки.

Я уже пытался посылать минимальные запросы GET, а также вставлял рабочие запросы от Postman в код, но я всегда получаю только пустую строку в качестве ответа. Кроме того, получение ответа занимает довольно много времени, обычно от 1 до 2 минут.

Пока это мой код. Кажется, установление соединения работает нормально, но формирование и отправка запросов не соответствуют ожиданиям:

#include <stdbool.h>     // use booleans in C
#include <stdlib.h>      // use common functions
#include <stdio.h>       // use input/output functions
#include <string.h>      // use string functions
#include <unistd.h>      // use POSIX functions

#include <sys/socket.h>  // use socket function
#include <netinet/in.h>  // use internet address datatypes
#include <arpa/inet.h>   // use inet_ntoa function
#include <netdb.h>       // use network database functions

int main(int argc, char *argv[]) {
    char *hostname = "stardrifter.org";
    int port = 80;

    /** -- Setup connection -- */

    // Get server host information
    struct hostent *serverInfo = gethostbyname(hostname);
    if (serverInfo == NULL) {
        printf("Failed to get info for host '%s'!\n", hostname);
        return -1;
    }

    // Create TCP/IP socket
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0) {
        printf("Failed to create socket!\n");
        return -1;
    }

    // Set address and port of server
    struct sockaddr_in serverAddr;
    serverAddr.sin_family = serverInfo->h_addrtype;
    serverAddr.sin_port = htons(port);
    memcpy(&serverAddr.sin_addr.s_addr, serverInfo->h_addr, serverInfo->h_length);

    // Connect to server
    if (connect(sock, (struct sockaddr *) &serverAddr, sizeof(serverAddr)) < 0) {
        printf("Failed to connect to server at %s:%d!\n",
               inet_ntoa(serverAddr.sin_addr), ntohs(serverAddr.sin_port));
        return -1;
    } else {
        printf("Connected to server at %s:%d\n\n",
               inet_ntoa(serverAddr.sin_addr), ntohs(serverAddr.sin_port));
    }

    /** -- Main program -- */

    char buffer[1024];
    int len = 0;

    char *request = "GET /cgi-bin/ref.cgi HTTP/1.1\r\nHost: www.stardrifter.org\r\nReferer: I'm a Referer\r\n\r\n";

    memset(buffer, 0, 1024);
    strncpy(buffer, request, sizeof buffer - 1);

    // Send message to server
    if (send(sock, buffer, len, 0) < 0) {
        printf("Failed to send message to server!\n");
    } else {
        printf("Sent message to server: \"%s\"\n", buffer);
    }

    // Receive response from server
    printf("Waiting for response...\n");
    memset(buffer, 0, 1024);
    if (recv(sock, buffer, 1024, 0) < 0) {
        printf("Failed to receive response from server!\n");
    }

    // Print received response
    printf("Received response from server: \"%s\"\n", buffer);

    // Close socket
    close(sock);

    return 0;
}

Я бы ожидал действительный HTTP-ответ с HTML-текстом, но моя программа выдает только:

Connected to server at 69.164.214.143:80

Sent message to server: "GET /cgi-bin/ref.cgi HTTP/1.1
Host: www.stardrifter.org
Referer: I'm a Referer

"
Waiting for response...
Received response from server: ""

Process finished with exit code 0

Я не уверен, действительно ли я получаю это "" в ответ или если есть что-то. как тайм-аут, а затем он просто читает пустой буфер.

1 Ответ

2 голосов
/ 18 июня 2019

Вы отправляете ноль байтов:

char buffer[1024];
int len = 0;

char *request = "GET /cgi-bin/ref.cgi HTTP/1.1\r\nHost: www.stardrifter.org\r\nReferer: I'm a Referer\r\n\r\n";

memset(buffer, 0, 1024);
strncpy(buffer, request, sizeof buffer - 1);

// Send message to server
if (send(sock, buffer, len, 0) < 0) {
    printf("Failed to send message to server!\n");
} else {
    printf("Sent message to server: \"%s\"\n", buffer);
}

или

int len = 0;

...

if (send(sock, buffer, len, 0) < 0) {
...

Почему вы копируете request в buffer? Это работает:

ssize_t bytes_sent = send( sock, request, strlen( request ), 0 );

И send(), и recv() возвращают количество отправленных или полученных байтов. Они делают это по уважительным причинам. Вам нужно проверить это возвращаемое значение и убедиться, что оно точно , что вы ожидаете.

Кроме того, третий аргумент send() - это size_t, а не int.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...