void http_session::read_http_body(size_t body_length) { auto self = shared_from_this(); boost::asio::async_read(_socket, _buffer_request, [this, self, body_length](boost::system::error_code ec, std::size_t length) { // condition if (!ec) { return body_length - _buffer_request.size(); } else { return (size_t)0; // terminate ... } }, [self, body_length](boost::system::error_code ec, std::size_t length) { // callback if (!ec) { std::string body(boost::asio::buffer_cast<const char*>(self->_buffer_request.data()), body_length); self->_buffer_request.consume(body_length); // consume the body LOG_DEBUG << "body : " << body; self->_tpool.run_task([self, body]() {self->_dispatcher.execute(self, std::move(body));}); if (!self->_connection_close) { self->read_http_header(); } } else { LOG_ERROR << "error while reading body " << ec; } }); }
/** *0 读取结束,其他没有结束 * */ int read_header(http_connect_t *con) { pool_t *p; buffer *header; p =(pool_t *) con->p; if(con->in->header == NULL)con->in->header = buffer_init(p); header = con->in->header; return read_http_header(header, p, con->fd); }
int get_file_over_http (net_t *netpolicy) { char buffer[HUGE0]; unsigned long received, filesz; int rval; struct stat st; struct hostent *phostent; struct sockaddr_in client; slassert (netpolicy != NULL); fprintf (stdout, netpolicy->msg); fflush (stdout); /* sanity check */ if (!netpolicy->savepart) slassert (!netpolicy->checkstamp); if (!netpolicy->overwrite && file_exist (netpolicy->destpath, &st, true)) /* regular file exist */ { return shutdown_net_t (netpolicy, FILE_DOWNLOADED, "Already downloaded"); } __act (phostent = gethostbyname (netpolicy->hostname), -1, "Cannot resolve host"); client.sin_family = phostent->h_addrtype; client.sin_port = htons ((unsigned short) netpolicy->port); memcpy (&client.sin_addr.s_addr, phostent->h_addr_list[0], phostent->h_length); __act ((netpolicy->sd = socket (client.sin_family, SOCK_STREAM, 0)) >= 0, -1, NULL); __act (!t_connect (netpolicy->sd, (struct sockaddr *)&client, sizeof client, netpolicy->timeout), -1, NULL); snprintf (buffer, HUGE, HTTP_TEMPLATE, netpolicy->srcpath, netpolicy->hostname); __act (send (netpolicy->sd, buffer, strlen(buffer), 0) == (int) strlen(buffer), -1, NULL); /* receive http header and save to `filesz' length of file required */ __act ((rval = read_http_header (netpolicy->sd)) > 0, FILE_NOT_DOWNLOADED, "File Not Found"); filesz = (unsigned long) rval; checkstamp (netpolicy, netpolicy->sd); __act (netpolicy->oldstamp != 0, FILE_ALREADY_UPDATE, "Already update"); if (netpolicy->savepart) { slassert ((strlen (netpolicy->destpath) + strlen (".part")) < sizeof (netpolicy->destpath)); strcat (netpolicy->destpath, ".part"); } __act (netpolicy->fddest = fopen (netpolicy->destpath, "wb"), -1, netpolicy->destpath); if (netpolicy->oldstamp == 1) { fwrite (netpolicy->stamprecv, 1, STAMPSZ, netpolicy->fddest); } received = (netpolicy->checkstamp) ? STAMPSZ : 0; netstat (NETSTAT_INIT, 0, 0, 0); /* init */ while ((rval = recv (netpolicy->sd, buffer, HUGE, 0)) > 0) { received += rval; fprintf (stdout, "\r%s [%s]", netpolicy->msg, netstat (0, 1, received, filesz)); fflush (stdout); fwrite (buffer, 1, rval, netpolicy->fddest); } fprintf (stdout, "\r%s [%s]\n", netpolicy->msg, netstat (NETSTAT_END, 1, received, filesz)); /* finish, flush 100% */ fflush (stdout); return shutdown_net_t (netpolicy, 0, NULL); }
static int prepare_http(int fd, char *buf) { int host_fd, hdr_size, len_diff; unsigned size, path_len, host_len, move_len; char *h, *p, *host = NULL, *referer = NULL, *referer_end, *path; if ((size = read_http_header(fd, buf)) == -1U) return ERR_READ_REQ; hdr_size = size >> 16; size &= 0xffff; if (invalid(buf, buf, hdr_size + 4)) return ERR_BAD_REQ; // buf has enough space after size even when "\r\n\r\n" was not found, // because MAX_HEADERS_SIZE - BUF_SIZE > 2 buf[hdr_size + 2] = 0; // "\r\n\r\n" -> "\r\n\0\n" if (!(path = strpbrk(buf, " \r\n"))) return ERR_BAD_REQ; path_len = strcspn(++path, " \r\n"); p = strstr(path + path_len, "\r\n"); while (p && (!host || !referer) && (p = strstr(h = p + 2, "\r\n"))) if (!strncasecmp(h, "host:", 5)) { host = h + 5; host += strspn(host, " \t"); host_len = p - host; } else if (!strncasecmp(h, "referer:", 8)) { referer = h + 8; referer += strspn(referer, " \t"); referer += strcspn(referer, "/\r\n"); referer += strspn(referer, "/"); referer_end = p; } if (invalid(buf, host, host_len + 1)) return ERR_NO_HOST; host[host_len] = 0; if (referer && no_referer_match(host, referer)) { if (path_len > 3 && !memcmp(path + path_len - 3, ".js", 3)) { syslog(LOG_DEBUG | LOG_DAEMON, "refused: %s", host); return ERR_REFUSED; // javascript cross-reference } if (memmem(path, path_len, ".gif?", 5)) { syslog(LOG_DEBUG | LOG_DAEMON, "refused gif: %s", host); return ERR_EMPTY_GIF; } } else { referer = NULL; // matches, don't remove } host_fd = connect_host(host); if (host_fd < 0) return host_fd; host[host_len] = '\r'; buf[hdr_size + 2] = '\r'; len_diff = BUF_SIZE; if (referer) len_diff = host_len + 1 - (referer_end - referer); if (len_diff < BUF_SIZE - MAX_HEADERS_SIZE) { p = host_len + 1 + referer; move_len = buf + size - referer_end; if (invalid(buf, p, move_len) || invalid(buf, referer_end, move_len) || invalid(buf, referer, host_len)) return ERR_BAD_REQ; memmove(p, referer_end, move_len); size += len_diff; if (host > referer) host += len_diff; memcpy(referer, host, host_len); referer[host_len] = '/'; } if (full_write(host_fd, buf, size) <= 0) { close(host_fd); return ERR_WRITE; } return host_fd; }
void http_session::start() { read_http_header(); }