0

In a simple TCP server written in C, I have a function that reads a string from a client, and then checks in a if-query if it matches "GET /index.html HTTP/1.0\r\n". However, when a Client sends exactly this string from a terminal, the query always goes into the else-case. How can this be?

This is the function that reads the string from the client:

void html_echo(int sockfd) {
    ssize_t n;
    char clientInputString[MAXLINE];
    n = readline(sockfd, clientInputString, sizeof(clientInputString));
    if (strcmp(clientInputString, "GET /index.html HTTP/1.0\r\n") == 0 ||
        strcmp(clientInputString, "GET /index.html HTTP/1.1\r\n") == 0 ){
        printf("Anfrage passt\n");
    } else{
        printf("Falsche Anfrage: %s, Länge: %lu\n", clientInputString, strlen(clientInputString));
    }

}

This is the function that reads a whole line from the client:

ssize_t readline(int fd, void *vptr, size_t maxlen)
{
    ssize_t n, rc;
    char c, *ptr;

    ptr = vptr;
    
    for( n=1; n<maxlen; n++ ) {
        again:
        if( (rc=read(fd, &c, 1)) == 1 ) {
            *ptr++ = c;
            if( c=='\n' )
                break;
        } else if( rc == 0 ) {
            if( n == 1 )
                return(0);  /* EOF, no data */
            else
                break;      /* EOF, some data */
        } else {
            if( errno == EINTR )
                goto again; /* doit again */
            return(-1);     /* Error */
        }
    }
    *ptr = '\0';
    return(n);
}

This is how the string is sent by the client:

Client Terminal

This is how the string is receeved by the server:

string received from server

This is the content of the string, as per @user3386109's suggested function:

47
45
54
20
2f
69
6e
64
65
78
2e
68
74
6d
6c
20
48
54
54
50
2f
31
2e
30
5c
72
5c
6e
0a

I tried adding an additional \r\n on the client side, because maybe the terminal appends some characters, but this didn't help. I also tried it without \r\n at all, and it still doesn't work.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Kinematikk
  • 15
  • 4
  • `readline()` is not a standard C function. Does your implementation include the newline when it returns the string? – Barmar Apr 25 '23 at 21:53
  • 2
    Is the user typing `\r\n` lilterally in `netcat`? They shouldn't. They're supposed to send carriage return and line feed characters, not escape sequences. – Barmar Apr 25 '23 at 21:55
  • If you want to match literal `\r\n`, you need to escape the backslashes: `"GET /index.html HTTP/1.0\\r\\n"` – Barmar Apr 25 '23 at 21:55
  • To debug this, you need to print the contents of the buffer, and see what you actually got. `for (int i=0; i – user3386109 Apr 25 '23 at 23:18
  • "when a Client sends" Could you show how the client send this? – Gerhardh Apr 26 '23 at 06:25
  • @Barmer yes the client was typing `\r\n` in netcat. Thank you for your answer, it cleared it up! – Kinematikk Apr 26 '23 at 14:26
  • 1
    @Kinematikk In your string content, `5c 72 5c 6e` are the literal characters ```'\'```, `'r'`, ```'\'```, `'n'`, and `0a` is an actual `LF` line break character. Your code is expecting the client to send a `CRLF` line break characters `0d 0a` (```'\r'```, ```'\n'```). In this case, the user's terminal is only sending `0a` when pressing Enter. You should adjust your logic to handle both `CRLF` and `LF` line breaks equally, ie have `readline()` stop reading when `LF` is received (as it does now) but omit `LF` and any preceeding `CR` in the returned string, and omit `\r\n` from your `strcmp()`. – Remy Lebeau Apr 27 '23 at 22:22

0 Answers0