📄 http.c
字号:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <ctype.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <unistd.h>#include <arpa/inet.h>#include <fcntl.h>#include <pthread.h>#include <sys/time.h>#include <host.h>#include <http.h>#include <ants.h>#include <wait_read.h>#include <skip_lock.h>#include <config.h> int get_http_size(struct mission *pms) { signed long i; int s, err = 0; char cmd[256]; char msg_hdr[1024]; char *p; sprintf(cmd, "GET %s HTTP/1.1\r\nHost: %s:%d\r\nReferer: %s\r\nConnection: close\r\n\r\n", pms->path, pms->host, pms->port, pms->referer);#ifdef DEBUG printf("cmd line is \n%s.\n", cmd);#endif for(i = 0; i < TIMES; i++) { while(1) { if((s = connect_host(pms->host, pms->port)) <= 0) sleep(1); else{ break; } printf("connect host again.\n"); } if(send(s, cmd, strlen(cmd), 0) != strlen(cmd)) { printf("write error.\n"); err = 1; } else { int state;#ifdef DEBUG printf("writes ok\n");#endif _wait_read(s, state, 20); /*macro*/ if(state < 1) { sleep(2); continue; } if(recv(s, msg_hdr, 1024, 0) < 0) { printf("read error.\n"); err = 1; } else err = 0; } if(!(err)) break; sleep(2); } if(err) return 0; #ifdef DEBUG printf("size read ok\n");#endif close(s);#ifdef DEBUG i = find_start(msg_hdr, 1024); msg_hdr[i - 2] = 0; printf("%s", msg_hdr);#endif i = (int)(strstr(msg_hdr, "200") - msg_hdr); if( (i <= 0) || i > 20) { /*add error handler code here.*/ return 0; } if((p = strstr(msg_hdr, "Content-Length")) || (p = strstr(msg_hdr, "Content-length:"))) p+= 16; else { p = msg_hdr; while((p = strstr(p, "\r\n"))) { /*fixup some file don't have string "Content-Length", I hope it works ok! */ p = p + 2; if((*p <= '9') && (*p >= '0')) break; } if(!p) return 0; } s = atoi(p); printf("Content-length: %d\n", s); return s; } static void down_http_fragment(struct ants *ant) { char cmd[256]; char data[PACKSIZE]; char *buffer_start; char *buffer; int s, fd, size, speed, offset, packsize; int first, read, state, bytesleft; struct mission *pms; first = 1; pms = ant->pms; size = ant->buf_size; buffer_start = malloc(size); sprintf(cmd, "GET %s HTTP/1.1\r\nRange: bytes=%d-\r\nHost: %s:%d\r\nReferer: %s\r\n\r\n",pms->path, ant->position, pms->host, pms->port, pms->referer); do { while(1) { if((s = connect_host(pms->host, pms->port)) <= 0) sleep(1); else{ ant->s = s; break; } printf("connect host again.\n"); } if(send(s, cmd, strlen(cmd), 0) != strlen(cmd)) { close(s); sleep(5); continue; } } while (0); chdir(pms->file_path); fd = open(pms->file, O_WRONLY|O_CREAT, 0644); retry: offset = 0; packsize = PACKSIZE; buffer = buffer_start; bytesleft = ant->end - ant->position + 1 ; lseek(fd, ant->position, 0); while(bytesleft) { _wait_read(s, state, 30); /*macro*/ if(state < 1){ sleep(2); continue; } if(offset + packsize > size) packsize = size - offset; if(packsize > bytesleft) packsize = bytesleft; if(first) { int start_text; first = 0; read = recv(s, data, packsize, MSG_WAITALL); /*extract head of http connect*/ start_text = find_start(data, read); if(start_text == -1) { ant->ret = -1; goto bad_head; } read -= start_text; memcpy(buffer, data + start_text, read); } else { read = recv(s, data, packsize, MSG_WAITALL); memcpy(buffer, data, read); } buffer += read; bytesleft -= read; offset += read; speed = -1; /*skip save buffer flag*/ if(bytesleft && ((offset + packsize) <= size)) continue; write(fd, buffer_start, offset); ant->position += offset; if(!skip_lock(&pms->skip_lock)) { /*save download state, if abort, we can continue*/ state_save(pms); speed = statistic(ant); skip_unlock(&pms->skip_lock); } if(bytesleft) goto retry; else break; } ant->ret = 0;bad_head: close(s); close(fd); free(buffer_start);#ifdef DEBUG printf("thread %d exit.\n", ant->thread);#endif pthread_exit(NULL);} void down_http(struct mission *pms) { int i, time, thread; struct timeval now, last; struct ants *ant; char file[MAX_HOSTNAME]; pthread_t *pthread; ant = pms->first_ant; thread = pms->thread; pthread = malloc(sizeof(pthread_t) * thread); gettimeofday(&last, NULL); for(i = 0; i < thread; i++) { pthread_create(&pthread[i], NULL, (void *)down_http_fragment, (void *)&ant[i]); } for(i = 0; i < thread; i++) { if(ant[i].ret == -1) { printf("the %d thread error.\n", i); } pthread_join(pthread[i], NULL); } gettimeofday(&now, NULL); time = (now.tv_sec - last.tv_sec) * 1000000 +(now.tv_usec - last.tv_usec); time /= 1000; printf("cost time %d.%d s\n", (time / 1000), (time / 10)); printf("100%% download\n"); free(pthread); free(pms->first_ant); close(pms->fd); sprintf(file, "%s%s.nat",pms->file_path, pms->file); del_file(file);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -