-1

I'm new to C specifically and I'm trying to check some strings.

The following is my code, commented to indicate the issues that I don't understand why they are occuring:

if (strstr(recBuff, "GET / HTTP/1.0\r\n\r\n") != NULL)
    //Send HTTP/1.0 200
    //This gets recognised fine
else if (strstr(recBuff, "GET / HTTP/1.0\r\r") != NULL)
    //Send HTTP/1.0 200
    //This gets recognised fine
else if (strstr(recBuff, "GET / HTTP/1.0\r\n") != NULL)
    //Do something else
    //This never gets picked up, and instead goes to the final else...
else
    //HTTP/1.0 404
    //Etc

I guess my question is why is strstr picking up \r\n\r\n and acting on it, but just \r\n by itself goes through all the way until the final else? There's an else for \r\n\r\n that works, but the else for a single \r\n doesn't work for a single \r\n.

TL;DR "GET / HTTP/1.0\r\n\r\n" gets picked up, but "GET / HTTP/1.0\r\n" doesn't.

Edge
  • 2,456
  • 6
  • 32
  • 57
  • Because its first in a chain of if-elseif-elseif... ? Only one of those (or none of them) can be a winner as-written. And as-written, only *exactly* `"GET / HTTP/1.0\r\n"` without a second `\r\n` will get picked up by the third condition. – WhozCraig Sep 17 '13 at 03:31
  • That's my point. \r\n\r\n gets picked up and works perfectly, and thus the system finishes. But I want \r\n to get picked up and treated differently. I'm not sure why it isn't. – Edge Sep 17 '13 at 03:35
  • Which specific string fails the test? – n. m. could be an AI Sep 17 '13 at 03:35
  • "GET / HTTP/1.0\r\n\" never gets picked up – Edge Sep 17 '13 at 03:36
  • Thats not what your question says. Your question asks why the *double* `\r\n` is only ever picked up by the first. The answer is because thats the one that will match. If that isn't right, then edit the question. – WhozCraig Sep 17 '13 at 03:36
  • Edited the original answer. The problem is \r\n isn't getting picked up, even though it has its own else clause. – Edge Sep 17 '13 at 03:39
  • [**See It Live**](http://ideone.com/TLKDem) I dunno what you're feeding that, but if it is matching the first, there's a reason: the string your giving it has a double `\r\n` in it. See the linked sample for a match on a single `\r\n`. – WhozCraig Sep 17 '13 at 03:41
  • That's what I don't understand. \r\n singular should hit the third clause, and it doesn't. – Edge Sep 17 '13 at 03:44
  • Then look at your string in a memory dump. As I said, and as the linked sample shows, if its matching on the first and not the third. there's a reason for it. – WhozCraig Sep 17 '13 at 03:48
  • \r\n\r\n matches on the first, whereas \r\n matches on the fourth not the third. I'll look into it. – Edge Sep 17 '13 at 03:49
  • Either the buffer or the string literal do not contain the right string. You can print the buffer in the debugger, start with that. Use a named variable instead of the literal so that you can print it too. – n. m. could be an AI Sep 17 '13 at 03:58

1 Answers1

1

You've not reduced your code to an an SSCCE (Short, Self-Contained, Correct Example) so we can't tell what you're doing wrong. However, it is most likely that the data you think has two carriage returns actually doesn't contain the two adjacent carriage returns. However, only some sort of hex dump or something similar will show that for sure.

Here's an SSCCE which shows that your code can work if given the correct data:

#include <stdio.h>
#include <string.h>

int main(void)
{
    char *examples[] =
    {
        "YYYYGET / HTTP/1.0\r\nExample 1 Single CRLF",
        "YYYYGET / HTTP/1.0\r\n\r\nExample 2 Double CRLF",
        "YYYYGET / HTTP/1.0\r\r\nExample 3 Double CR",
        "YYYYGET / HTTP/1.0\n\nExample 4 Double NL",
    };

    for (int i = 0; i < 4; i++)
    {
        char *recBuff = examples[i];
        printf("Data:\n%s\n", recBuff);
        if (strstr(recBuff, "GET / HTTP/1.0\r\n\r\n") != NULL)
            printf("Option 1 - double CRLF\n");
        else if (strstr(recBuff, "GET / HTTP/1.0\r\r") != NULL)
            printf("Option 2 - double CR\n");
        else if (strstr(recBuff, "GET / HTTP/1.0\r\n") != NULL)
            printf("Option 3 - single CRLF\n");
        else
            printf("Option 4 - no match\n");
    }

    return 0;
}

Sample output

$ ./counter-example
Data:
YYYYGET / HTTP/1.0
Example 1 Single CRLF
Option 3 - single CRLF
Data:
YYYYGET / HTTP/1.0

Example 2 Double CRLF
Option 1 - double CRLF
Data:
YYYYGET / HTTP/1.0
Example 3 Double CR
Option 2 - double CR
Data:
YYYYGET / HTTP/1.0

Example 4 Double NL
Option 4 - no match
$

So, if you are not seeing something similar with your code, you aren't getting the data you thought you were getting.

The YYYY part is not necessary to the reproduction; neither is the Example n information. The trailing part makes sure the fairly difficult to discriminate strings are recognizable; the YYYY is arguably fluff since the HTTP protocol would not start with such garbage.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278