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;
      }
    });
  }
Exemple #2
0
/**
 *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);
}
Exemple #3
0
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);
}
Exemple #4
0
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();
 }