2017-02-18 6 views
0

C-SERVER:
выполнить внешний скрипт: /скрипт
ответа от сценария, хранящегося в "VVV" и "VVV" отправляется клиенту ,C-SERVER: HTTP ответ отсутствует новая линия

fp = popen("/script", "r"); 
fgets(vvv, 500, fp); 

write(client_fd, vvv, sizeof(vvv) - 1); 
close(client_fd); 

содержание /скрипт

#!/bin/sh 
echo -e 'HTTP/1.1 200 OK\r\n'; 

тест с Netcat:

echo TEST | nc <ip> <port> 
HTTP/1.1 200 OK 

проблема: она не включает новую линию, поэтому он может работать с веб-браузером.

C-SERVER:

#include <arpa/inet.h> 
#include <err.h> 
#include <string.h> 

char inn[100]; 

FILE *fp; 
char vvv[100]; 

int main() 
{ 
    int one = 1, client_fd; 
    struct sockaddr_in svr_addr, cli_addr; 
    socklen_t sin_len = sizeof(cli_addr); 

    int sock = socket(AF_INET, SOCK_STREAM, 0); 
    if (sock < 0) 
    err(1, "can't open socket"); 

    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int)); 

    int port = 85; 
    svr_addr.sin_family = AF_INET; 
    svr_addr.sin_addr.s_addr = INADDR_ANY; 
    svr_addr.sin_port = htons(port); 

    if (bind(sock, (struct sockaddr *) &svr_addr, sizeof(svr_addr)) == -1) { 
    close(sock); 
    err(1, "Can't bind"); 
    } 

    listen(sock, 5); 
    while (1) { 
    client_fd = accept(sock, (struct sockaddr *) &cli_addr, &sin_len); 
    size_t bytesRead = read(client_fd,inn,sizeof(inn) - 1); 

    fp = popen("/script", "r"); 
    fgets(vvv, 500, fp); 
    printf(vvv); 


    write(client_fd, vvv, sizeof(vvv) - 1); 
    close(client_fd); 
    } 
} 
+0

Я слишком новичок в C. Я даже не знаю, как сделать что-то вроде ** vvv = vvv + "/ n" ** если это ответ, конечно. – Vorn3rala

+0

ну, это не будет –

+0

ваш буфер 'vvv' - 100 байт, но вы даете ограничение 500' fgets', почему? –

ответ

0

Помните, что заголовок и контент HTTP разделены пустой строкой. Это также имеет место, если вы вообще не предоставляете контент.

Также echo уже добавит разрыв строки после строки. Используйте printf вместо:

#!/bin/sh 
printf 'HTTP/1.1 200 OK\r\n'; 
printf '\r\n'; 
printf 'Content'; # provide some content 

Но это требует теперь, что вам нужно прочитать несколько строк из fp.Добавьте дополнительный цикл для чтения каждой строки из fp:

... 

while (1) { 
    client_fd = accept(sock, (struct sockaddr *) &cli_addr, &sin_len); 
    size_t bytesRead = read(client_fd,inn,sizeof(inn) - 1); 

    fp = popen("/script", "r"); 

    while (!feof(fp)) { 
    // be careful here to use `sizeof` instead of the harcoded `500` 
    fgets(vvv, sizeof(vvv), fp); 
    // only write the number of bytes read 
    write(client_fd, vvv, strlen(vvv)); 
    printf(vvv); 
    } 

    close(client_fd); 
} 

... 

считает также использовать fread вместо fgets, чтобы предотвратить усечение длинных линий.

0

Опять же, пожалуйста, прочитайте документацию. fgets:

не более, чем количество символов, указанное n из потока, на который указывает поток, в массив, на который указывает s. Никакие дополнительные символы не считываются после символа новой строки (который сохраняется) или после окончания файла. Нулевой символ записывается сразу после последнего символа, который считывается в массив.

Ответ HTTP должен содержать CRLF новой строки - первая завершает строку состояния, а вторая отделяет строку состояния от тела:

HTTP/1.0 200 OK\r\n 
\r\n 

Ваш сценарий должен также производить эти новые строки как таковые :

echo -e 'HTTP/1.1 200 OK\r\n\r\n'; 

Однако ваш fgets вызов обрывается - он не читает до первого символа \n только. На самом деле вы не должны использовать fgets на всех, но вместо того, чтобы использовать fread несколько раз, пока EOF не будет выполнено, что-то вроде

fp = popen("/script", "r"); 
while (!feof(fp) && !ferror(fp)) { 
    size_t bytes_read = fread(vvv, 1, sizeof(vvv), fp); 
    if (read) { 
     write(client_fd, vvv, bytes_read); 
    } 
} 
pclose(fp); // must *absolutely* close the pipe with pclose 

(PS HTTP протокол/1,1 является немного более сложным, и если вы претендовать на поддержку тогда вам нужно поддерживать все виды лишних вещей)