📄 http_handler.c
字号:
#include <netinet/tcp.h>#include <string.h>#include <sys/epoll.h>#include <strings.h>#include <stdlib.h>#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <fcntl.h>#include <sys/socket.h>#include <netinet/in.h>#include <pthread.h>#include <errno.h>#include "http.h"extern void clear_cmd (struct command *const);extern void wait_cmd (struct command *const);extern void close_restart (int);extern char *base_name (char *);extern void *send_request_get_file (void *const);extern int get_resource_info (const char *);extern void *recv_response_get_file (void *const);struct resource_info resource;struct file_range *files_range;struct command cmd;pthread_mutex_t mutex_cmd = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t cond_cmd_set = PTHREAD_COND_INITIALIZER;pthread_cond_t cond_cmd_clear = PTHREAD_COND_INITIALIZER;int pipe_recv_send[2];extern void *handler (void *url){ pthread_t thread_recv_response_get_file; pthread_t thread_send_request_get_file; pthread_attr_t thread_attr; off_t offset; size_t unit; size_t remain; struct command cmd_copy; char *path; int i = 0; int retval = -1; /* alloc memory for URL path. */ if (NULL == (path = calloc (1, MAX_LEN_PATH + 1))) { fprintf (stderr, "alloc memory failure.\n"); return (void *) -1; } /* get information of resource. */ fprintf (stdout, "Getting information of resource ......\n"); bzero (&resource, sizeof (struct resource_info)); resource.path = path; if (-1 == get_resource_info (url)) goto __FUNCTION__free_buffer_path; /* create pipe for sender and receiver. */ if (-1 == pipe (pipe_recv_send)) { fprintf (stderr, "Create pipe failure.\n"); goto __FUNCTION__free_buffer_path; } /* create thread to receive response. */ clear_cmd (&cmd); if (0 != pthread_create (&thread_recv_response_get_file, NULL, \ recv_response_get_file, (void *) CONNECTS_NUM)) { fprintf (stderr, "Create thread failure.\n"); goto __FUNCTION__close_pipe; } /* is receiver ready ? */ wait_cmd (&cmd_copy); if (CMD_OK != cmd_copy.value) goto __FUNCTION__close_pipe; /* pad struct file_range. */ if (NULL == (files_range = calloc (sizeof (struct file_range), CONNECTS_NUM))) { fprintf (stderr, "Alloc memory failure.\n"); goto __FUNCTION__close_pipe; } unit = resource.size / (CONNECTS_NUM - 1); i = 0; remain = resource.size; offset = 0; while (remain > unit) { (*(files_range + i)).fd = -1; (*(files_range + i)).offset = offset; (*(files_range + i)).nbytes = unit; offset += unit; remain -= unit; i++; } (*(files_range + i)).fd = -1; (*(files_range + i)).offset = offset; (*(files_range + i)).nbytes = remain; /* create thread to send request. */ pthread_attr_init (&thread_attr); pthread_attr_setdetachstate (&thread_attr, PTHREAD_CREATE_DETACHED); while (i >= 0) { if (0 != pthread_create (&thread_send_request_get_file, &thread_attr, \ send_request_get_file, (void *)(files_range + i))) { fprintf (stderr, "Create thread failure.\n"); goto __FUNCTION__free_buffer_files_range; } i--; } /* keep reading the state of receiver. */ i = 0; while (i < MAX_RETRY) { wait_cmd (&cmd_copy); switch (cmd_copy.value) { case CMD_DONE: retval = 0; case CMD_ERR: goto __FUNCTION__free_buffer_files_range; case CMD_RETRY: if (0 != pthread_create (&thread_send_request_get_file, &thread_attr, \ send_request_get_file, (void *) cmd_copy.opt)) { fprintf (stderr, "Create thread failure.\n"); goto __FUNCTION__free_buffer_files_range; } i++; break; default: break; } } fprintf (stderr, "time out to get resource.\n"); __FUNCTION__free_buffer_files_range: free (files_range); __FUNCTION__close_pipe: close_restart (pipe_recv_send[0]); close_restart (pipe_recv_send[1]); __FUNCTION__free_buffer_path: free (path); return (void *) retval;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -