This \ expected output, not an exit code of 0 is a seg fault. For testing, you would need to request /hello.php? with a curl request instead of a browser. Browsers (firefox and opera in my testing) drop the trailing '?'.
The seg fault occurs here strcpy(query, myQuery); when myQuery is NULL. The second argument to strcpy is a const char * and NULL isn't. (...
This is bad abs_path = malloc(sizeof(LimitRequestLine + 1)); (and query too). Remember, parse receives a pointer to abs_path, which is already allocated on the stack (implicitly) in main. The malloc gives it a new address on the heap. The strncpy updates the contents at that (new) address. But back in main it will be looking for abs_path at the "original" ...
Good troubleshooting. This line abs_path = malloc(40); gives the local abs_path a new address. Alas, as you have discovered, main is looking at the "original" abs_path address acquired here char abs_path[LimitRequestLine + 1];. The local abs_path is a pointer to already-allocated memory. There is no reason to allocate more/different memory.
Have you noticed that every request you send through a browser or curl gives a 501? server returns 501 in 3 places, 2 in this parse and one in main. You might want to take it for a spin in the new debug50 or gdb (tips here) and find out more info. This parse, if it doesn't give any other error, will always throw an error 501 and return false. It should ...
The strtok() call here:
char* absolute_path = strtok(req_tar, "?");
will crop req_tar at the ? and make it always be equal to abs_path.
Because of this, the following condition will never be true and you'll never extract query:
if(strcmp(req_tar, abs_path) != 0)
query = strstr(req_tar, abs_path);
But even if that condition triggered, I don't ...
I rwote multiple test programs to see how the functions work, you can try the following to see how to use strtok to separate the different parts of request line
void printChars(char* string, int len);
char request = "GET /favicon.ico HTTP/1.1\r\n";
int len =...
Scope. Pointers. When you do this abs_path = malloc(_http - sla);, you are giving a new address to the local abs_path. When you return to main, it will be looking in the "old neighborhood", ie the abs_path address from the original declaration here char abs_path[LimitRequestLine + 1];
First suggest you send a request to server from browser or curl. You will discover that server seg faults. (That's what this \ expected output, not an exit code of 0 feedback from check50 indicates).
Next, in Week4 > Section > Dynamic Memory Allocation review the "Three Golden Rules" of memory allocation, around 8:45.
Then review your program for "...
One problem is int pathend = strcspn(abpathstart, lastspace) + 1;. strcspn doesn't work the way you think it does (or wish it did!). From the man page (emphasis added):
The strcspn() function calculates the length of the initial segment of s which consists entirely of bytes not in reject.
strcspn is returning 0, so your pathend is 1.
Why, you may ...
You are getting that error because line is declared a const char*. Review the man page for strtok, specifically [emphasis added]:
Be cautious when using these functions. If you do
use them, note that:
These functions modify their first argument.
These functions cannot be used on constant
The identity of the ...
Why are you hard-coding the strncpy length to 8?
I think the Segmentation Fault is occurring because http_temp is smaller than 8, so when the program try to read beyond the length of http_temp, it produces a segmentation fault.
You should try to make that copy dynamic, so it can handle different sizes.
I now know what exactly causes the 'failed to parse'. The following statement causes the problem
change the statement to:
and now style50 works.
Adding the extra parenthesis fixes style50. The program will compile and work either way, but style50 only works if the parentheses are surrounding the ...
That section of the pset links to a document that goes into this topic in more detail. In particular, server.c needs to support origin-form as specified here: https://tools.ietf.org/html/rfc7230#section-5.3.1
As that page specifies, there are three other ways of formatting the request-target, formats that your program need not take into account. If you read ...
for (int i = 0, j = strlen(line); i < j; i++)
if (line[i] == (char) 32)
if (line[i + 1] != '/')
For a well formed request-line this always gives error 501.Be the computer. Take the request "GET /cat.html HTTP/1.1" through the loop. Encounter ...
When will it stop? The while loop that is. When this (SP[iter] != ' ' || SP[iter] != '?') is false. When is this (SP[iter] != ' ' || SP[iter] != '?') false? Never. If SP[iter] is space then SP[iter] != ' ' is false and SP[iter] != '?' is true. false || true is true. And versa vice. Your segfault eventually occurs here strncpy(&abs_path[iter - 1], &...
server should return 505 in exactly one place, from the parse function http version check. That means that strcmp(HTTP_version, "HTTP/1.1") does not return 0. That means that HTTP_version is not "HTTP/1.1". You could use gdb to determine why. At the least, you could add a printf before the test to see what the value of HTTP_version is. A suggestion is using ...
From the instructions:
absolute-path [ "?" query ]
whereby absolute-path (which will not contain ?) must start with / and might optionally be
followed by a ? followed by a query, which may not contain ".
Notice, the "?" is inside the [ optional clause ], so you may assume that it is not part of absolute-path.
Store at the address in ...
After a lot of help from DinoCoderSaurus, I have finally figured out what was wrong with my code.
First of all, I wasn't incrementing length properly in load.
Then I wasn't returning anything when there was no query.
Also, the load function had a problem. I was storing a lot of EOF's at the end of my string.
The most important problem was scope. A couple ...
This char* linecopy = malloc(sizeof(line)); is a memory leak. line is a pointer, which is 8 bytes. memory leaks cause unpredictable results.
Another allocation issue: char* method = malloc(sizeof(char)*3); is (almost) allocated for success (null terminator not accounted for). The check50 test "Method of 'GETabc' ", will use memory not allocated to method. ...
Good detective work so far. The first problem /hello.html, abs_path and query is empty leads us to here
int i = 0;
haystack = reqt;
needle = strstr(haystack, "?");
if(needle == NULL)
needle = strstr(haystack, "\0");
i = 1;
if(needle == NULL)
According to man strstr:
The terminating null bytes ('\0') are not ...
This test from check50 Requesting cat.exe returns error code 501 could be your key to progress and ultimately, success because program reaches here error(405); and goes no further. Since this is [should be!] be the only error(405); in server, this sounds like a job for gdb. You know exactly the place the program is failing; you only have to find out why/how ...
A big difference between the test program and server is the way you have created line. From the instructions:
Per 3.1.1 of http://tools.ietf.org/html/rfc7230, a request-line is defined as
method SP request-target SP HTTP-version CRLF
Add \r\n to the end of line, and you will see a different result. You should review this line very carefully, if (line[...
Program received signal SIGSEGV, Segmentation fault.
__strcpy_ssse3 () at ../sysdeps/i386/i686/multiarch/strcpy-ssse3.S:84
I would look for another way, for example:
// copy line to new string
char* temp = malloc(strlen(line) + 1);
if(temp == NULL)
The browser did it! It is part of RFC1738. Section 2.2 says:
Characters can be unsafe for a number of reasons. The space
character is unsafe because significant spaces may disappear and
insignificant spaces may be introduced when URLs are transcribed or
typeset or subjected to the treatment of word-processing programs.
All things being equal, the only place that server returns a 505 is the parse function. If this parse function reaches for(int i=0;i<strlen(line);i++), it will always return a 505. Howzat? Assuming a correct HTTP version, when you reach the second space, f == 2, this line if(line[i+1]!='H'||....
is true. What happens next? i is incremented, line[i]...
Notice the difference between the declaration of abs_path/query in main
char abs_path[LimitRequestLine + 1];
char query[LimitRequestLine + 1];
vs. the declaration in parse.
bool parse(const char* line, char* abs_path, char* query)
In main they are char arrays. In parse they are char*. Both your sample outputs should be expected. Both variables appear ...
Your code compiles, but does it process a request through the browser or curl? I think it seg faults here strcpy(method, word); every time.
From man strcpy:
the destination string dest must be large enough to receive the copy.
You haven't allocated any memory for method (or Httpversion or requesttarget).
Your approach is spot on.
break the line ...
Scope. Pointers. Suggest you rewatch Week 4 > Section > Pointers.
When program control is returned to main, abs_path has the same contents as before the call to parse; it's still pointing to the "blue" memory.
Review how you populated tmp. You want to populate abs_path similarly.
That is the main problem causing the check50/server1. You have other ...