1 year ago

#388349

test-img

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

Accepted video resources