int send_data(int fd,char* data, size_t size)

{

	ssize_t bytes_size;

	while(size>0)

	{

		bytes_size=write(fd,data,size);

		if(bytes_size>=0)

		{

			size-=bytes_size;

			data+=bytes_size;

		}

		else

			return -1;

	}

	return 0;

}

int send_file(int fd, int file)

{

	const int buf_size = 4096;

	char buf[buf_size];

	ssize_t bytes_read=read(file, buf, buf_size);

	int status=0;

	while (bytes_read>0)

       	{

		status=send_data(fd, buf, bytes_read);

		if (status<0) 

			return status;

		bytes_read=read(file, buf, buf_size);

	}

	return status;

}

int send_string(int fd, char* data)

{

	return send_data(fd,data,strlen(data));

}

char* join_string(char *str1, char *str2, size_t *size)

{

	size_t len1 = strlen(str1);

	size_t len2 = strlen(str2);

	char *buffer = (char *) malloc(len1 + len2 + 1);

	memcpy(buffer,str1,len1);

	memcpy(buffer+len1,str2,len2+1);

	if (size != NULL) 

		*size=(len1+len2)*sizeof(char);

	return buffer;

}

int get_file_size(int fd)

{

	struct stat st;

	if (fstat(fd,&st)==-1)

       	{

		return -1;

	}

	return st.st_size;

}

void serve_file(int fd, char* path) {


  /* TODO: PART 2 */

  /* PART 2 BEGIN */


  int file=open(path,O_RDONLY);

  char* content_length=(char*) malloc(sizeof(char)*100);

  snprintf(content_length, 100,"%d",get_file_size(file));

  http_start_response(fd, 200);

  http_send_header(fd, "Content-Type", http_get_mime_type(path));

  http_send_header(fd, "Content-Length", content_length); // TODO: change this line too

  http_end_headers(fd);

  send_file(fd,file);

  close(file);

  /* PART 2 END */


  /* PART 2 END */

}


void serve_directory(int fd, char* path) {

  http_start_response(fd, 200);

  http_send_header(fd, "Content-Type", http_get_mime_type(".html"));

  http_end_headers(fd);


  /* TODO: PART 3 */

  /* PART 3 BEGIN */


  // TODO: Open the directory (Hint: opendir() may be useful here)

  char* index_path = join_string(path, "/index.html", NULL);

  struct stat index_info;

  int result = stat(index_path, &index_info);

  if (result == 0) {

// index.html exists, serve the file

  serve_file(fd, index_path);

  }

  else {

  DIR *directory=opendir(path);

  struct dirent* entry;

  while ((entry = readdir(directory)) != NULL)

  {

		char * file_name_buffer;

		if(strcmp(entry->d_name,"..")!=0)

		{

			int length = strlen("<a href=\"//\"></a><br/>") + strlen(path) + strlen(entry->d_name)*2 + 1;

     	 		file_name_buffer = (char* ) malloc(length * sizeof(char));

      			http_format_href(file_name_buffer, path, entry->d_name);

		}

		else

		{

			int length = strlen("<a href=\"//\"></a><br/>") + strlen("..") + strlen("")*2 + 1;

     			file_name_buffer = (char* ) malloc(length * sizeof(char));

      			http_format_href(file_name_buffer, "..", entry->d_name);

		}

		char* buffer1=(char*) malloc(1);

		buffer1[0]='\0';

		buffer1=join_string(buffer1,file_name_buffer,NULL);

		size_t content_length;

		buffer1=join_string(buffer1,"</center></body></html>",&content_length);

		free(file_name_buffer);

		send_string(fd,buffer1);

		closedir(directory);

		return;

	}

  }

  /**

   * TODO: For each entry in the directory (Hint: look at the usage of readdir() ),

   * send a string containing a properly formatted HTML. (Hint: the http_format_href()

   * function in libhttp.c may be useful here)

   */ 


  /* PART 3 END */

}


/*

 * Reads an HTTP request from client socket (fd), and writes an HTTP response

 * containing:

 *

 *   1) If user requested an existing file, respond with the file

 *   2) If user requested a directory and index.html exists in the directory,

 *      send the index.html file.

 *   3) If user requested a directory and index.html doesn't exist, send a list

 *      of files in the directory with links to each.

 *   4) Send a 404 Not Found response.

 *

 *   Closes the client socket (fd) when finished.

 */

void handle_files_request(int fd) {


  struct http_request* request = http_request_parse(fd);


  if (request == NULL || request->path[0] != '/') {

    http_start_response(fd, 400);

    http_send_header(fd, "Content-Type", "text/html");

    http_end_headers(fd);

    close(fd);

    return;

  }

   


  if (strstr(request->path, "..") != NULL) {

    http_start_response(fd, 403);

    http_send_header(fd, "Content-Type", "text/html");

    http_end_headers(fd);

    close(fd);

    return;

  }


  /* Remove beginning `./` */

  char* path = malloc(2 + strlen(request->path) + 1);

  path[0] = '.';

  path[1] = '/';

  memcpy(path + 2, request->path, strlen(request->path) + 1);


  /*

   * TODO: PART 2 is to serve files. If the file given by `path` exists,

   * call serve_file() on it. Else, serve a 404 Not Found error below.

   * The `stat()` syscall will be useful here.

   *

   * TODO: PART 3 is to serve both files and directories. You will need to

   * determine when to call serve_file() or serve_directory() depending

   * on `path`. Make your edits below here in this function.

   */


  /* PART 2 & 3 BEGIN */

  struct stat info;

  int result=stat(path,&info);

  if(result!=0)

  {

	  if (strcmp(request->path, "/") == 0)

	  {

		char* index_path = malloc(strlen(path) + strlen("index.html") + 1);

		strcpy(index_path, path);

		strcat(index_path, "index.html");

		result = stat(index_path, &info);

		if (result == 0) {

		serve_file(fd, index_path);

	  }

	  else

	  {

		http_start_response(fd, 404);

		http_send_header(fd,"Content-Type", "text/html");

		http_end_headers(fd);

	  }

	  free(index_path);

	  }

	  else

	  {

		http_start_response(fd, 404);

		http_send_header(fd, "Content-Type", "text/html");

		http_end_headers(fd);

	  }

  }

  else

  {

  	if(S_ISDIR(info.st_mode))

	{

		serve_directory(fd,path);

	}

	if(S_ISREG(info.st_mode))

	{

		serve_file(fd,path);

	}

  close(fd);

  return;

  }

  /* PART 2 & 3 END */


  close(fd);

  return;

}
修改代码使得可以通过样例点FAIL [Basic Server] Get the directory listing of the root (1.5 pt)
    Missing test_directory1
    How to reproduce:
        I created an empty directory and put a test_file.txt file and a test_directory1 inside it.
        I started ./httpserver with the --files option.
        I sent a HTTP request for / to the web server, in order to see all the files I created.请将修改部分标红