⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 http.c

📁 ELinks is an advanced and well-established feature-rich text mode web (HTTP/FTP/..) browser. ELinks
💻 C
📖 第 1 页 / 共 2 页
字号:
			post = pd + 1;		}		add_to_str(&hdr, &l, "Content-Length: ");		add_num_to_str(&hdr, &l, strlen(post) / 2);		add_to_str(&hdr, &l, "\r\n");	}	send_cookies(&hdr, &l, host);	add_to_str(&hdr, &l, "\r\n");	if (post) {		while (post[0] && post[1]) {			int h1, h2;			h1 = post[0] <= '9' ? (unsigned)post[0] - '0' : post[0] >= 'A' ? upcase(post[0]) - 'A' + 10 : 0;			if (h1 < 0 || h1 >= 16) h1 = 0;			h2 = post[1] <= '9' ? (unsigned)post[1] - '0' : post[1] >= 'A' ? upcase(post[1]) - 'A' + 10 : 0;			if (h2 < 0 || h2 >= 16) h2 = 0;			add_chr_to_str(&hdr, &l, h1 * 16 + h2);			post += 2;		}	}	write_to_socket(c, c->sock1, hdr, l, http_get_header);	mem_free(hdr);	setcstate(c, S_SENT);}int is_line_in_buffer(struct read_buffer *rb){	int l;	for (l = 0; l < rb->len; l++) {		if (rb->data[l] == 10) return l + 1;		if (l < rb->len - 1 && rb->data[l] == 13 && rb->data[l + 1] == 10) return l + 2;		if (l == rb->len - 1 && rb->data[l] == 13) return 0;		if (rb->data[l] < ' ') return -1;	}	return 0;}void read_http_data(struct connection *c, struct read_buffer *rb){	struct http_connection_info *info = c->info;	set_timeout(c);	if (rb->close == 2) {		setcstate(c, S_OK);		http_end_request(c, 0);		return;	}	if (info->length != -2) {		int l = rb->len;		if (info->length >= 0 && info->length < l) l = info->length;		if (c->from + l < 0) {			setcstate(c, S_LARGE_FILE);			abort_connection(c);			return;		}		c->received += l;		if (add_fragment(c->cache, c->from, rb->data, l) == 1) c->tries = 0;		if (info->length >= 0) info->length -= l;		c->from += l;		kill_buffer_data(rb, l);		if (!info->length && !rb->close) {			setcstate(c, S_OK);			http_end_request(c, 0);			return;		}	} else {		next_chunk:		if (info->chunk_remaining == -2) {			int l;			if ((l = is_line_in_buffer(rb))) {				if (l == -1) {					setcstate(c, S_HTTP_ERROR);					abort_connection(c);					return;				}				kill_buffer_data(rb, l);				if (l <= 2) {					setcstate(c, S_OK);					http_end_request(c, 0);					return;				}				goto next_chunk;			}		} else if (info->chunk_remaining == -1) {			int l;			if ((l = is_line_in_buffer(rb))) {				unsigned char *de;				long n = 0;	/* warning, go away */				if (l != -1) n = strtol(rb->data, (char **)(void *)&de, 16);				if (l == -1 || n < 0 || n >= MAXINT || de == rb->data) {					setcstate(c, S_HTTP_ERROR);					abort_connection(c);					return;				}				kill_buffer_data(rb, l);				if (!(info->chunk_remaining = n)) info->chunk_remaining = -2;				goto next_chunk;			}		} else {			int l = info->chunk_remaining;			if (l > rb->len) l = rb->len;			if (c->from + l < 0) {				setcstate(c, S_LARGE_FILE);				abort_connection(c);				return;			}			c->received += l;			if (add_fragment(c->cache, c->from, rb->data, l) == 1) c->tries = 0;			info->chunk_remaining -= l;			c->from += l;			kill_buffer_data(rb, l);			if (!info->chunk_remaining && rb->len >= 1) {				if (rb->data[0] == 10) kill_buffer_data(rb, 1);				else {					if (rb->data[0] != 13 || (rb->len >= 2 && rb->data[1] != 10)) {						setcstate(c, S_HTTP_ERROR);						abort_connection(c);						return;					}					if (rb->len < 2) goto read_more;					kill_buffer_data(rb, 2);				}				info->chunk_remaining = -1;				goto next_chunk;			}		}					}	read_more:	read_from_socket(c, c->sock1, rb, read_http_data);	setcstate(c, S_TRANS);}int get_header(struct read_buffer *rb){	int i;	if (rb->len <= 0) return 0;	if (rb->data[0] != 'H') return -2;	if (rb->len <= 1) return 0;	if (rb->data[1] != 'T') return -2;	if (rb->len <= 2) return 0;	if (rb->data[2] != 'T') return -2;	if (rb->len <= 3) return 0;	if (rb->data[3] != 'P') return -2;	for (i = 0; i < rb->len; i++) {		unsigned char a = rb->data[i];		if (/*a < ' ' && a != 10 && a != 13*/!a) return -1;		if (i < rb->len - 1 && a == 10 && rb->data[i + 1] == 10) return i + 2;		if (i < rb->len - 3 && a == 13) {			if (rb->data[i + 1] != 10) return -1;			if (rb->data[i + 2] == 13) {				if (rb->data[i + 3] != 10) return -1;				return i + 4;			}		}	}	return 0;}void http_got_header(struct connection *c, struct read_buffer *rb){	int cf;	int state = c->state != S_PROC ? S_GETH : S_PROC;	unsigned char *head;	unsigned char *cookie, *ch;	int a, h, version;	unsigned char *d;	struct cache_entry *e;	struct http_connection_info *info;	unsigned char *host = upcase(c->url[0]) != 'P' ? c->url : get_url_data(c->url);	set_timeout(c);	info = c->info;	if (rb->close == 2) {		unsigned char *h;		if (!c->tries && (h = get_host_name(host))) {			if (info->bl_flags & BL_NO_CHARSET) {				del_blacklist_entry(h, BL_NO_CHARSET);			} else {				add_blacklist_entry(h, BL_NO_CHARSET);				c->tries = -1;			}			mem_free(h);		}		setcstate(c, S_CANT_READ);		retry_connection(c);		return;	}	rb->close = 0;	again:	if ((a = get_header(rb)) == -1) {		setcstate(c, S_HTTP_ERROR);		abort_connection(c);		return;	}	if (!a) {		read_from_socket(c, c->sock1, rb, http_got_header);		setcstate(c, state);		return;	}	if (a != -2) {		head = mem_alloc(a + 1);		memcpy(head, rb->data, a); head[a] = 0;		kill_buffer_data(rb, a);	} else {		head = stracpy("HTTP/0.9 200 OK\r\nContent-Type: text/html\r\n\r\n");	}	if (get_http_code(head, &h, &version) || h == 101) {		mem_free(head);		setcstate(c, S_HTTP_ERROR);		abort_connection(c);		return;	}	if (check_http_server_bugs(host, c->info, head) && is_connection_restartable(c)) {		mem_free(head);		setcstate(c, S_RESTART);		retry_connection(c);		return;	}	ch = head;	while ((cookie = parse_http_header(ch, "Set-Cookie", &ch))) {		unsigned char *host = upcase(c->url[0]) != 'P' ? c->url : get_url_data(c->url);		set_cookie(NULL, host, cookie);		mem_free(cookie);	}	if (h == 100) {		mem_free(head);		state = S_PROC;		goto again;	}	if (h < 200) {		mem_free(head);		setcstate(c, S_HTTP_ERROR);		abort_connection(c);		return;	}	if (h == 204) {		mem_free(head);		setcstate(c, S_HTTP_204);		http_end_request(c, 0);		return;	}	if (h == 304) {		mem_free(head);		setcstate(c, S_OK);		http_end_request(c, 1);		return;	}	if ((h == 500 || h == 502 || h == 503 || h == 504) && http_bugs.retry_internal_errors && is_connection_restartable(c)) {			/* !!! FIXME: wait some time ... */		mem_free(head);		setcstate(c, S_RESTART);		retry_connection(c);		return;	}	if (!c->cache && get_cache_entry(c->url, &c->cache)) {		mem_free(head);		setcstate(c, S_OUT_OF_MEM);		abort_connection(c);		return;	}	e = c->cache;	e->http_code = h;	if (e->head) mem_free(e->head);	e->head = head;	if ((d = parse_http_header(head, "Expires", NULL))) {		time_t t = parse_http_date(d);		if (t && e->expire_time != 1) e->expire_time = t;		mem_free(d);	}	if ((d = parse_http_header(head, "Pragma", NULL))) {		if (!casecmp(d, "no-cache", 8)) e->expire_time = 1;		mem_free(d);	}	if ((d = parse_http_header(head, "Cache-Control", NULL))) {		char *f = d;		while (1) {			while (*f && (*f == ' ' || *f == ',')) f++;			if (!*f) break;			if (!casecmp(f, "no-cache", 8) || !casecmp(f, "must-revalidate", 15)) {				e->expire_time = 1;			}			if (!casecmp(f, "max-age=", 8)) {				if (e->expire_time != 1) e->expire_time = time(NULL) + atoi(f + 8);			}			while (*f && *f != ',') f++;		}		mem_free(d);	}#ifdef HAVE_SSL	if (c->ssl) {		int l = 0;		if (e->ssl_info) mem_free(e->ssl_info);		e->ssl_info = init_str();		add_num_to_str(&e->ssl_info, &l, SSL_get_cipher_bits(c->ssl, NULL));		add_to_str(&e->ssl_info, &l, "-bit ");		add_to_str(&e->ssl_info, &l, SSL_get_cipher_version(c->ssl));		add_to_str(&e->ssl_info, &l, " ");		add_to_str(&e->ssl_info, &l, (unsigned  char *)SSL_get_cipher_name(c->ssl));	}#endif	if (e->redirect) mem_free(e->redirect), e->redirect = NULL;	if (h == 301 || h == 302 || h == 303 || h == 307) {		if ((h == 302 || h == 307) && !e->expire_time) e->expire_time = 1;		if ((d = parse_http_header(e->head, "Location", NULL))) {			unsigned char *user, *ins;			unsigned char *newuser, *newpassword;			if (!parse_url(d, NULL, &user, NULL, NULL, NULL, &ins, NULL, NULL, NULL, NULL, NULL, NULL) && !user && ins && (newuser = get_user_name(host))) {				if (*newuser) {					int ins_off = ins - d;					newpassword = get_pass(host);					if (!newpassword) newpassword = stracpy("");					add_to_strn(&newuser, ":");					add_to_strn(&newuser, newpassword);					add_to_strn(&newuser, "@");					extend_str(&d, strlen(newuser));					ins = d + ins_off;					memmove(ins + strlen(newuser), ins, strlen(ins) + 1);					memcpy(ins, newuser, strlen(newuser));					mem_free(newpassword);				}				mem_free(newuser);			}			if (e->redirect) mem_free(e->redirect);			e->redirect = d;			e->redirect_get = h == 303;		}	}	if (!e->expire_time && strchr(c->url, POST_CHAR)) e->expire_time = 1;	info->close = 0;	info->length = -1;	info->version = version;	if ((d = parse_http_header(e->head, "Connection", NULL)) || (d = parse_http_header(e->head, "Proxy-Connection", NULL))) {		if (!strcasecmp(d, "close")) info->close = 1;		mem_free(d);	} else if (version < 11) info->close = 1;	cf = c->from;	c->from = 0;	if ((d = parse_http_header(e->head, "Content-Range", NULL))) {		if (strlen(d) > 6) {			d[5] = 0;			if (!(strcasecmp(d, "bytes")) && d[6] >= '0' && d[6] <= '9') {#if defined(HAVE_STRTOLL)				long long f = strtoll(d + 6, NULL, 10);#elif defined(HAVE_STRTOQ)				longlong f = strtoq(d + 6, NULL, 10);#else				long f = strtol(d + 6, NULL, 10);				if (f == MAXLONG) f = -1;#endif				if (f >= 0 && (off_t)f >= 0 && (off_t)f == f) c->from = f;			}		}		mem_free(d);	}	if (cf && !c->from && !c->unrestartable) c->unrestartable = 1;	if (c->from > cf || c->from < 0) {		setcstate(c, S_HTTP_ERROR);		abort_connection(c);		return;	}	if ((d = parse_http_header(e->head, "Content-Length", NULL))) {		unsigned char *ep;#if defined(HAVE_STRTOLL)		long long l = strtoll(d, (char **)(void *)&ep, 10);#elif defined(HAVE_STRTOQ)		longlong l = strtoq(d, (char **)(void *)&ep, 10);#else		long l = strtol(d, (char **)(void *)&ep, 10);		if (l == MAXLONG) l = -1;#endif		if (!*ep && l >= 0 && (off_t)l >= 0 && (off_t)l == l) {			if (!info->close || version >= 11) info->length = l;			if (c->from + l >= 0) c->est_length = c->from + l;		}		mem_free(d);	}	if ((d = parse_http_header(e->head, "Accept-Ranges", NULL))) {		if (!strcasecmp(d, "none") && !c->unrestartable) c->unrestartable = 1;		mem_free(d);	} else {		if (!c->unrestartable && !c->from) c->unrestartable = 1;	}	if (info->bl_flags & BL_NO_RANGE && !c->unrestartable) c->unrestartable = 1;	if ((d = parse_http_header(e->head, "Transfer-Encoding", NULL))) {		if (!strcasecmp(d, "chunked")) {			info->length = -2;			info->chunk_remaining = -1;		}		mem_free(d);	}	if (!info->close && info->length == -1) info->close = 1;	if ((d = parse_http_header(e->head, "Last-Modified", NULL))) {		if (e->last_modified && strcasecmp(e->last_modified, d)) {			delete_entry_content(e);			if (c->from) {				c->from = 0;				mem_free(d);				setcstate(c, S_MODIFIED);				retry_connection(c);				return;			}		}		if (!e->last_modified) e->last_modified = d;		else mem_free(d);	}	if (!e->last_modified && (d = parse_http_header(e->head, "Date", NULL)))		e->last_modified = d;	if (info->length == -1 || (version < 11 && info->close)) rb->close = 1;	read_http_data(c, rb);}void http_get_header(struct connection *c){	struct read_buffer *rb;	set_timeout(c);	if (!(rb = alloc_read_buffer(c))) return;	rb->close = 1;	read_from_socket(c, c->sock1, rb, http_got_header);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -