1 year ago
#388349
yyny
Beginning of the string snprintf doesn't show
I'm trying to use snprintf to write a request string into the buffer. The first iteration works fine, however, after the second iteration it the beginning of the string disappears.
The function which write into the buffer
char* http_get_request(url_info *info) {
char * request_buffer = (char *) malloc(100 + strlen(info->path) + strlen(info->host)); //malloc spaces for the request buffer pointer
memset(request_buffer, 0, sizeof(*request_buffer));
puts("http get request req_buf address:");
printf("%p\n", request_buffer);
// puts(info->path);
// puts("INFO PATH ADDRESS:");
// printf("%p\n",&info->path);
snprintf(request_buffer, 1024, "GET /%s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n",
info->path, info->host); //writes: "GET <PATH> HTTP/1.1\r\nHost: <HOSTNAME>\r\nConnection: close\r\n\r\n" into the buffer
return request_buffer;
}
Relevant part of the download_page function:
puts("REQUEST BUFFER");
printf("%p\n",request_buffer);
puts(request_buffer);
//retrieve request string
if (connect(mysocket, ptr-> ai_addr, ptr-> ai_addrlen)){
fprintf(stderr, "Could not connect: %s\n", strerror(errno));
return -1;
}
send(mysocket, request_buffer, strlen(request_buffer), 0);
//between receiving data from the server and storing in the buffer
//Some aribitrary big number for length of data buffer written into file
shutdown(mysocket, SHUT_WR); //further transmissions disallowed
free(request_buffer);
Relevant part which iterates are keeps on generating new requests.
// Let's first isolate the first line of the reply
char *status_line = next_line(reply->reply_buffer, reply->reply_buffer_length);
if (status_line == NULL) {
fprintf(stderr, "Could not find status\n");
return 5;
}
*status_line = '\0'; // Make the first line is a null-terminated string
// Now let's read the status (parsing the first line)
int status;
double http_version;
int rv = sscanf(reply->reply_buffer, "HTTP/%lf %d", &http_version, &status);
if (rv != 2) { // if there are not two values http_version and status then return error.
fprintf(stderr, "Could not parse http response first line (rv=%d, %s)\n", rv, reply->reply_buffer);
return 6;
}
int i = 0;
struct http_reply newReply;
url_info info;
while (status == 301 && i < 5){
char *buf = status_line + 2;
char *start = strstr(buf,"Location: ") +10;
char *end = strchr(start, '\r');
size_t diff = end - start +1;
char newUrl[diff];
strncpy(newUrl, start, diff);
printf("New Url:\n%s\n",newUrl);
printf("info pointer: %p\n", &info);
int ret = parse_url(newUrl, &info);
if (ret) {
fprintf(stderr, "Could not parse URL '%s': %s\n", newUrl, parse_url_errstr[ret]);
return 2;
}
ret = download_page(&info, &newReply);
if (ret) {
return 3;
}
char *status_line = next_line(newReply.reply_buffer, newReply.reply_buffer_length);
if (status_line == NULL) {
fprintf(stderr, "Could not find status\n");
return 5;
}
*status_line = '\0'; // Make the first line is a null-terminated string
// Now let's read the status (parsing the first line)
int status;
double http_version;
int rv = sscanf(newReply.reply_buffer, "HTTP/%lf %d", &http_version, &status);
//write to the reply->reply_buffer a reply value.
//seperate the first line, the http reply, then the headers then adat.
if (rv != 2) { // if there are not two values http_version and status then return error.
fprintf(stderr, "Could not parse http response first line (rv=%d, %s)\n", rv, newReply.reply_buffer);
return 6;
}
i++;
if (status == 301){
free(newReply.reply_buffer);
}
}
//if there was at least one redirect,
if (i!=0){
reply = &newReply;
}
if (status != 200) {
fprintf(stderr, "Server returned status %d (should be 200)\n", status);
return 0;
}
//check status redirect, send to the new location.
char *buf = status_line + 2;
char *ptr = reply->reply_buffer;
while(1 == 1){
status_line = next_line(ptr, reply->reply_buffer_length);
buf = status_line +2;
if (ptr+ 2 == buf) break;
ptr = buf;
}
write_data(file_name, buf, reply->reply_buffer + reply->reply_buffer_length - buf);
return 0;
}
This is the output:
Yis-MacBook-Pro:ex05-sockets yao$ ./wgetX http://redirect.epizeuxis.net/make
http get request req_buf address:
0x7fac3e6063c0
REQUEST BUFFER
0x7fac3e6063c0
GET /make HTTP/1.1
Host: redirect.epizeuxis.net
Connection: close
New Url:
http://info.cern.ch/
info pointer: 0x7ffee495a7e0
http get request req_buf address:
0x7fac3e6063c0
REQUEST BUFFER
0x7fac3e6063c0
HTTP/1.1
Host: info.cern.ch
Connection: close
New Url:
http://info.cern.ch/
info pointer: 0x7ffee495a7e0
http get request req_buf address:
0x7fac3e50fe70
REQUEST BUFFER
0x7fac3e50fe70
HTTP/1.1
Host: info.cern.ch
Connection: close
New Url:
http://info.cern.ch/
info pointer: 0x7ffee495a7e0
http get request req_buf address:
0x7fac3fa04080
REQUEST BUFFER
0x7fac3fa04080
HTTP/1.1
Host: info.cern.ch
Connection: close
New Url:
http://info.cern.ch/
info pointer: 0x7ffee495a7e0
http get request req_buf address:
0x7fac3e6063c0
REQUEST BUFFER
0x7fac3e6063c0
HTTP/1.1
Host: info.cern.ch
Connection: close
c
sockets
dynamic-memory-allocation
0 Answers
Your Answer