Exemplo n.º 1
0
void send_data(int send_to, char *content_type, char *filepath)
{
    if (strcmp(filepath, "./") == 0)
    {
        strcat(filepath, DEFAULT_INDEX_PAGE);
    }
    FILE *file;
    file = fopen(filepath, "r");
    if (file != NULL)
    {
        send_header(send_to, content_type);
        send(send_to, "\r\n", 2, 0);

        char buf[1024];

        fgets(buf, sizeof(buf), file);
        while (!feof(file))
        {
            send(send_to, buf, strlen(buf), 0);
            fgets(buf, sizeof(buf), file);
        }

    } else
    {
        send_header(send_to, content_type);
        send(send_to, "\r\n", 2, 0);
        not_found_404(send_to);
    }
    if (file != NULL)
        fclose(file);

}
Exemplo n.º 2
0
void show_welcome(Serial *serial){
	put_crlf(serial);
	size_t len = strlen(welcomeMsg);
	send_header(serial, len);
	serial->put_s(welcomeMsg);
	put_crlf(serial);
	send_header(serial, len);
	put_crlf(serial);
	show_help(serial);
}
Exemplo n.º 3
0
//request message referred from textbook page 105-106
void send_response(int socket, char *file_name)
{
    //if file name is empty, return
    if (*file_name == '\0')
    {
        send_header(socket, file_name, 0, code_404);
        send(socket, ERROR_404_MESSAGE, strlen(ERROR_404_MESSAGE), 0);
        return;
    }

    FILE *fp = fopen(file_name, "r");

    //if file not found, return
    if (!fp)
    {
        send_header(socket, file_name, 0, code_404);
        send(socket, ERROR_404_MESSAGE, strlen(ERROR_404_MESSAGE), 0);
        return;
    }

    if (!fseek(fp, 0, SEEK_END))
    {
        long file_len = ftell(fp);

        //if file length error, return
        if (file_len < 0)
        {
            send_header(socket, file_name, 0, code_404);
            send(socket, ERROR_404_MESSAGE, strlen(ERROR_404_MESSAGE), 0);
            return;
        }

        char *file_buffer = malloc(sizeof(char) * (file_len + 1));
        fseek(fp, 0, SEEK_SET);

        size_t num_bytes = fread(file_buffer, sizeof(char), file_len, fp);
        file_buffer[num_bytes] = '\0';

        send_header(socket, file_name, num_bytes, code_200);

        //send file to socket
        send(socket, file_buffer, num_bytes, 0);

        free(file_buffer);
    }

    fclose(fp);
}
Exemplo n.º 4
0
int sanlock_request(uint32_t flags, uint32_t force_mode,
		    struct sanlk_resource *res)
{
	int fd, rv, datalen;

	datalen = sizeof(struct sanlk_resource) +
		  sizeof(struct sanlk_disk) * res->num_disks;

	rv = connect_socket(&fd);
	if (rv < 0)
		return rv;

	rv = send_header(fd, SM_CMD_REQUEST, flags, datalen, force_mode, 0);
	if (rv < 0)
		goto out;

	rv = send(fd, res, sizeof(struct sanlk_resource), 0);
	if (rv < 0) {
		rv = -errno;
		goto out;
	}

	rv = send(fd, res->disks, sizeof(struct sanlk_disk) * res->num_disks, 0);
	if (rv < 0) {
		rv = -errno;
		goto out;
	}

	rv = recv_result(fd);
 out:
	close(fd);
	return rv;
}
Exemplo n.º 5
0
int sanlock_read_lockspace(struct sanlk_lockspace *ls, uint32_t flags, uint32_t *io_timeout)
{
	struct sm_header h;
	int rv, fd;

	if (!ls || !ls->host_id_disk.path[0])
		return -EINVAL;

	rv = connect_socket(&fd);
	if (rv < 0)
		return rv;

	rv = send_header(fd, SM_CMD_READ_LOCKSPACE, flags,
			 sizeof(struct sanlk_lockspace),
			 0, 0);
	if (rv < 0)
		goto out;

	rv = send_data(fd, ls, sizeof(struct sanlk_lockspace), 0);
	if (rv < 0) {
		rv = -errno;
		goto out;
	}

	/* receive result, io_timeout and ls struct */

	memset(&h, 0, sizeof(h));

	rv = recv_data(fd, &h, sizeof(h), MSG_WAITALL);
	if (rv < 0) {
		rv = -errno;
		goto out;
	}

	if (rv != sizeof(h)) {
		rv = -1;
		goto out;
	}

	rv = (int)h.data;
	if (rv < 0)
		goto out;

	rv = recv_data(fd, ls, sizeof(struct sanlk_lockspace), MSG_WAITALL);
	if (rv < 0) {
		rv = -errno;
		goto out;
	}

	if (rv != sizeof(struct sanlk_lockspace)) {
		rv = -1;
		goto out;
	}

	*io_timeout = h.data2;
	rv = (int)h.data;
 out:
	close(fd);
	return rv;
}
Exemplo n.º 6
0
static int
do_get(int cfd, const char *path, int path_len)
{
  send_header(cfd, OK);

  return 0;
}
Exemplo n.º 7
0
Arquivo: xetp.cpp Projeto: toppk/xevil
void XETP::send_world_room(OutStreamP out,WorldP world,
                           const RoomIndex &idx,int worldVersion) {
  u_int len = sizeof(int) +             // version
    Rooms::get_write_length() +       // rooms
    RoomIndex::get_write_length() +   // roomIndex
    Dim::get_write_length() +         // dim
    world->get_write_length(idx);     // world room data

  if (out->get_protocol() == GenericStream::UDP) {
    ((UDPOutStreamP)out)->prepare_packet(XETP::add_header(len));
  }

  send_header(out,WORLD_ROOM,len);
  out->write_int(worldVersion);
  Rooms rooms = world->get_rooms();
  rooms.write(out);
  idx.write(out);
  Dim dim = world->get_dim();
  dim.write(out);
  world->write(out,idx); // write one room

  if (out->get_protocol() == GenericStream::UDP) {
    ((UDPOutStreamP)out)->done_packet();
  }
}
Exemplo n.º 8
0
/* Send html page to client*/
void send_page(int socket)
{
  FILE * fp;

  /* Searchs for page in directory htdocs*/
  sprintf(buf_tmp,"htdocs/%s",req_buf);

  #if DEBUG
  printf("send_page: searching for %s\n",buf_tmp);
  #endif

  /* Verifies if file exists*/
  if((fp=fopen(buf_tmp,"rt"))==NULL) {
    /* Page not found, send error to client*/
    printf("send_page: page %s not found, alerting client\n",buf_tmp);
    not_found(socket);
  }
  else {
    /* Page found, send to client*/

    /* First send HTTP header back to client*/
    send_header(socket);

    printf("send_page: sending page %s to client\n",buf_tmp);
    while(fgets(buf_tmp,SIZE_BUF,fp))
      send(socket,buf_tmp,strlen(buf_tmp),0);

      /* Close file*/
      fclose(fp);
    }

    return;

  }
Exemplo n.º 9
0
int sanlock_write_lockspace(struct sanlk_lockspace *ls, int max_hosts,
			    uint32_t flags, uint32_t io_timeout)
{
	int rv, fd;

	if (!ls || !ls->host_id_disk.path[0])
		return -EINVAL;

	rv = connect_socket(&fd);
	if (rv < 0)
		return rv;

	rv = send_header(fd, SM_CMD_WRITE_LOCKSPACE, flags,
			 sizeof(struct sanlk_lockspace),
			 max_hosts, io_timeout);
	if (rv < 0)
		goto out;

	rv = send_data(fd, ls, sizeof(struct sanlk_lockspace), 0);
	if (rv < 0) {
		rv = -errno;
		goto out;
	}

	rv = recv_result(fd);
 out:
	close(fd);
	return rv;
}
Exemplo n.º 10
0
void wo_bwmbackup(char *url)
{
	struct stat st;
	time_t t;
	int i;

	if (stat(hfn, &st) == 0) {
		t = st.st_mtime;
		sleep(1);
	}
	else {
		t = 0;
	}
	killall("rstats", SIGHUP);
	for (i = 10; i > 0; --i) {
		if ((stat(hfn, &st) == 0) && (st.st_mtime != t)) break;
		sleep(1);
	}
	if (i == 0) {
		send_error(500, NULL, NULL);
		return;
	}
	send_header(200, NULL, mime_binary, 0);
	do_file((char *)hfn);
}
Exemplo n.º 11
0
void wo_iptbackup(char *url)
{
	struct stat st;
	time_t t;
	int i;

	if (stat(ifn, &st) == 0) {
		t = st.st_mtime;
		sleep(1);
	}
	else {
		t = 0;
	}
	killall("cstats", SIGHUP);
	for (i = 20; i > 0; --i) { // may take a long time for gzip to complete
		if ((stat(ifn, &st) == 0) && (st.st_mtime != t)) break;
		sleep(1);
	}
	if (i == 0) {
		send_error(500, NULL, NULL);
		return;
	}
	send_header(200, NULL, mime_binary, 0);
	do_file((char *)ifn);
}
Exemplo n.º 12
0
static int
read_directory_files(tcp_con_t *con,const char *parent,GnomeVFSFileInfo *info) {
  int rc;
  char *rel_path;
  char *full_path;
  char *res_message;

  if ( (!con) || (!parent) || (!info) )
    return -EINVAL;

  if ( (!strcmp("..",info->name)) || (!strcmp(".",info->name) ) )
    return -EINVAL;

  if (info->type==GNOME_VFS_FILE_TYPE_REGULAR) {
    rc=create_response(IPMSG_FILE_REGULAR,info->name,info->size,parent,&res_message);
    if (rc<0)
      return rc;
    dbg_out("Send file:%s\n",res_message);
    rc=send_header(con,res_message);
    g_free(res_message);
    if (rc<0)
      return rc;
  }

  rc=-ENOMEM;
  full_path=g_build_filename(parent,info->name,NULL);
  if (!full_path) 
    return rc;
  /* send file */
  tcp_transfer_file(con,full_path,info->size,0);
  g_free(full_path);
  return 0;
}
Exemplo n.º 13
0
int fetch_file(int connfd, const char *filename) {
    int fd, fsize;
    struct stat fs;
    void *mblock;
    const char *mime_type, *suffix;
    int i;

    fd = open(filename, O_RDONLY);
    fstat(fd, &fs);
    fsize = fs.st_size;
    mblock = mmap(NULL, fsize, PROT_WRITE, MAP_PRIVATE, fd, 0);
    if (mblock == MAP_FAILED) {
        close(fd);
        send_error(connfd, 404);
        return 0;
    }

    suffix = filename;
    for (i = (int) strlen(filename) - 1; i >= 0; --i) {
        if (filename[i] == '.') {
            suffix = filename + i;
            break;
        }
    }

    if (strcasecmp(suffix, ".html") == 0 || strcasecmp(suffix, ".htm") == 0) {
        mime_type = "text/html";
    } else if (strcasecmp(suffix, ".css") == 0) {
        mime_type = "text/css";
    } else if (strcasecmp(suffix, ".js") == 0) {
        mime_type = "application/x-javascript";
    } else if (strcasecmp(suffix, ".c") == 0 || strcasecmp(suffix, ".h") == 0) {
        mime_type = "text/plain";
    } else {
        mime_type = "application/octet-stream";
    }

    send_response(connfd, 200, NULL);
    send_header(connfd, "Content-Type", mime_type);
    send_header(connfd, "Content-Length", "%d", fsize);
    end_headers(connfd);

    rio_writen(connfd, mblock, fsize);
    munmap(mblock, fsize);

    return 1;
}
Exemplo n.º 14
0
int pack_and_send(int sockfd, char *msg, uint32_t tag, uint32_t flags, struct packet *buf)
{
				int sent=0;
				pack_msg(msg, tag, flags, buf);
				sent += send_header(sockfd, buf);
				sent += send_msg(sockfd, msg);
				return sent;
}
Exemplo n.º 15
0
void SensorsMessageProcessor::list_sensors() {
  // We don't support sensors yet so we mark all as disabled
  int mask = 0;
  char buf[12];
  snprintf(buf, sizeof(buf), "%d", mask);
  send_header(strlen(buf));
  messenger_->send(buf, strlen(buf));
  finish_message();
}
Exemplo n.º 16
0
Arquivo: httpd.c Projeto: ajsbu/cse506
static int
send_file(struct http_request *req)
{
	int r;
	off_t file_size = -1;
	int fd;

	// open the requested url for reading
	// if the file does not exist, send a 404 error using send_error
	// if the file is a directory, send a 404 error using send_error
	// set file_size to the size of the file

	// LAB 6: Your code here.
	char path[MAXPATHLEN];                                                
        struct Stat stat;
        strcpy(path, req->url);  

	cprintf("Reached in send_file...path = %s\n", path);

        if ((fd = open(path, O_RDONLY)) < 0) {
		cprintf("Failed to open so sending 404...\n");
                send_error(req, 404);
                r = fd;
		close(fd);
		return r;
        }

        if ((r = fstat(fd, &stat)) < 0) {
		cprintf("Failed to get stat so sending 404...\n");
		close(fd);
		return r;
        }

        if (stat.st_isdir) {
		cprintf("it is a directory so sending 404...\n");
                send_error(req, 404);
                r = -1;
		close(fd);
		return r;
        }

        file_size = stat.st_size;

	if ((r = send_header(req, 200)) < 0 || (r = send_size(req, file_size)) < 0 || (r = send_content_type(req)) < 0 || (r = send_header_fin(req)) < 0) {
		cprintf("sending failed so sending 404...\n");
		close(fd);
		return r;
	}

	r = send_data(req, fd);
	close(fd);

	cprintf("send_file() successful...\n");
	return r;

	panic("send_file not implemented");
}
Exemplo n.º 17
0
static void wo_favicon(char *url)
{
	if (nvram_match("web_favicon", "1")) {
		send_header(200, NULL, "image/vnd.microsoft.icon", 0);
		do_file(url);
	}
	else {
		send_error(404, NULL, NULL);
	}
}
Exemplo n.º 18
0
void send_response(FILE *f, int status, char *title, char *extra, char *text)
{
    send_header(f, status, title, extra, "text/html", -1, -1);
    fprintf(f, "<html>");
    set_simple_head(f, title, text, NULL);
    fprintf(f, "<body>");
    fprintf(f, "<h1>%d - %s</h1>", status, title);//naughty HTML
    fprintf(f, "<p>%s\r\n</p>", text);
    fprintf(f, "</body></html>");
}
Exemplo n.º 19
0
void common_redirect(void)
{
	if (atoi(webcgi_safeget("_ajax", ""))) {
		send_header(200, NULL, mime_html, 0);
		web_puts("OK");
	}
	else {
		redirect(webcgi_safeget("_redirect", "/"));
	}
}
Exemplo n.º 20
0
static int
send_file(struct http_request *req)
{
	int r;
	off_t file_size = -1;
	int fd;
	struct Stat stat;
	// open the requested url for reading
	// if the file does not exist, send a 404 error using send_error
	// if the file is a directory, send a 404 error using send_error
	// set file_size to the size of the file

	// LAB 6: Your code here.
	fd = open(req->url, O_RDONLY);
	//struct Fd *open_file = INDEX2FD(i);	
	if(fd < 0)
	{
		cprintf("file %s does not exists\n",req->url);
		r = send_error(req, 404);
		if(r<0)
			cprintf("send_file:send_error failed:%e\n",r);
	}
	r = fstat(fd, &stat);
	if(r<0)
	{
		cprintf("send_file:fstat failed:%e\n",r);
		r = send_error(req, 404);
	}
	if(stat.st_isdir == 1)
	{
		cprintf("file %s is a directory\n",req->url);
		 r = send_error(req, 404);
                if(r<0)
                        cprintf("send_file:send_error failed:%e\n",r);
	}
	file_size = stat.st_size;
	
	if ((r = send_header(req, 200)) < 0)
		goto end;

	if ((r = send_size(req, file_size)) < 0)
		goto end;

	if ((r = send_content_type(req)) < 0)
		goto end;

	if ((r = send_header_fin(req)) < 0)
		goto end;

	r = send_data(req, fd);

end:
	close(fd);
	return r;
}
Exemplo n.º 21
0
static int
send_file(struct http_request *req)
{
	int r;
	off_t file_size = -1;
	int fd;

	// open the requested url for reading
	// if the file does not exist, send a 404 error using send_error
	// if the file is a directory, send a 404 error using send_error
	// set file_size to the size of the file

	// LAB 6: Your code here.

	char path[MAXPATHLEN];                                                 
        struct Stat stat;
        memmove(path, req->url, strlen(req->url));  

	if ((fd = open(path, O_RDONLY)) < 0) {
		send_error(req, 404);  // HTTP page not found
		r = fd;
		goto end;
	}

	if ((r = fstat(fd, &stat)) < 0) {
		goto end;
	}

	if (stat.st_isdir) {
		send_error(req, 404); // HTTP page not found
		r = -1;
		goto end;
	}

	file_size = stat.st_size;

	if ((r = send_header(req, 200)) < 0)
		goto end;

	if ((r = send_size(req, file_size)) < 0)
		goto end;

	if ((r = send_content_type(req)) < 0)
		goto end;

	if ((r = send_header_fin(req)) < 0)
		goto end;

	r = send_data(req, fd);

end:
	close(fd);
	return r;
}
Exemplo n.º 22
0
void send_command(int throttle, int leftright, int forwardbackward)
{
	send_header();
	// TODO: finish...
	send_one();
	send_one();
	send_zero();
	send_zero();
	//send_zero();
	//send_one();
}
Exemplo n.º 23
0
int sanlock_restrict(int sock, uint32_t flags)
{
	int rv;

	rv = send_header(sock, SM_CMD_RESTRICT, flags, 0, 0, -1);
	if (rv < 0)
		return rv;

	rv = recv_result(sock);
	return rv;
}
Exemplo n.º 24
0
Arquivo: httpd.c Projeto: MG47/JOS-MG
static int
send_file(struct http_request *req)
{
	int r;
	off_t file_size = -1;
	int fd;

	// open the requested url for reading
	// if the file does not exist, send a 404 error using send_error
	// if the file is a directory, send a 404 error using send_error
	// set file_size to the size of the file

	// code for lab 6-M.G
    //	panic("send_file not implemented");

    if ((fd = open(req->url, O_RDONLY)) < 0) 
    {
		send_error(req, 404);
		goto end;
	}

	struct Stat s;
	if ((r = stat(req->url, &s)) < 0) 
    {
		send_error(req, 404);
		goto end;
	}

	if (s.st_isdir) 
    {
		send_error(req, 404);
		goto end;
	}
	file_size = s.st_size;

	if ((r = send_header(req, 200)) < 0)
		goto end;

	if ((r = send_size(req, file_size)) < 0)
		goto end;

	if ((r = send_content_type(req)) < 0)
		goto end;

	if ((r = send_header_fin(req)) < 0)
		goto end;

	r = send_data(req, fd);

end:
	close(fd);
	return r;
}
Exemplo n.º 25
0
void send_directory_listing(FILE *f, struct stat statbuf, char* relative_path, char* path)
{
    DIR *dir;
    struct dirent *de;

    send_header(f, 200, "OK", NULL, "text/html", -1, statbuf.st_mtime);

    fprintf(f, "<html>");
    set_simple_head(f, relative_path, relative_path, NULL);
    fprintf(f, "<body>");
    fprintf(f, "<h1>Index of %s</h1>\r\n", relative_path);
    fprintf(f, "<pre><table border=\"0\" width=\"100%%\">");
    fprintf(f, "<tr><th align=\"left\">Name</th><th align=\"left\">Last modified</th><th align=\"left\">Size</th></tr>");
    fprintf(f, "<hr />\r\n"); 

    dir = opendir(path);
    while((de = readdir(dir)) != NULL)
    {
        char timebuf[32];
        struct tm *tm;

        char *pathbuf = calloc(strlen(path) + 128, sizeof(char));
        memcpy(pathbuf, path, strlen(path));
        pathbuf[strlen(pathbuf)] = '\0';
        strcat(pathbuf, de->d_name);

        stat(pathbuf, &statbuf);
        tm = gmtime(&statbuf.st_mtime);
        strftime(timebuf, sizeof(timebuf), "%Y-%b-%d %H:%M:%S", tm);

        fprintf(f, "<tr>");
        if (strcmp(de->d_name, ".") == 0)
            continue;

        //regressive and unecessary to see what's below root
        if (strcmp(relative_path, "/") == 0 && strcmp(de->d_name, "..") == 0)
            continue;

        fprintf(f, "<td><a href=\"%s%s\">", de->d_name, S_ISDIR(statbuf.st_mode) ? "/" : "");
        fprintf(f, "%s%s</a></td>", de->d_name, S_ISDIR(statbuf.st_mode) ? "/" : "");
            
        if (S_ISDIR(statbuf.st_mode))
            fprintf(f, "<td>%s</td>", timebuf);
        else
            fprintf(f, "<td>%s</td> <td>%10llu</td>", timebuf, (unsigned long long)statbuf.st_size);
        fprintf(f, "</tr>");
        free(pathbuf);
    }
    closedir(dir);
    fprintf(f, "</table></pre>\r\n<hr /><address>%s</address>\r\n", SERVER);
    fprintf(f, "</body></html>");
}
Exemplo n.º 26
0
void EtagStoreResource::handle_etag(const Http::Request& request,
                                    Http::Response& response) {
    // TODO http://redmine.webtoolkit.eu/issues/2471
    // const std::string* cookie_value = request.getCookieValue(cookie_name_);
    std::string cookies = request.headerValue("Cookie");
    if (cookies.empty()) {
        return;
    }
    std::string pattern = cookie_name_ + "=";
    int cookie_begin = cookies.find(pattern);
    if (cookie_begin == std::string::npos) {
        return;
    }
    cookie_begin += pattern.length();
    int cookie_end = cookies.find(';', cookie_begin);
    int cookie_length = (cookie_end == -1) ? -1 : (cookie_end - cookie_begin);
    std::string cookie_value = cookies.substr(cookie_begin, cookie_length);
    //
    std::string etag_value = request.headerValue(receive_header());
    boost::mutex::scoped_lock lock(cookie_to_etag_mutex_);
    Map::iterator it = cookie_to_etag_.find(cookie_value);
    if (it == cookie_to_etag_.end()) {
        return;
    }
    Etag& etag = it->second;
    if (etag_value.empty()) {
        etag_value = etag.def;
    }
    etag.from_client = etag_value;
    if (!etag.to_client.empty()) {
        response.addHeader(send_header(), etag.to_client);
        etag.to_client.clear();
    } else {
        etag.handler(etag.from_client);
    }
    if (!etag.from_client.empty()) {
        response.addHeader(send_header(), etag.from_client);
    }
}
Exemplo n.º 27
0
void connection::process()
{
	read_request();
	parse_request();
	make_body();
	make_header();
	send_header();
	if (is_get())
	{
		send_body();
	}
	m_socket.close();
}
Exemplo n.º 28
0
void send_error(int connfd, int code) {
    char *buf = (char *) malloc(MAXBUF);
    const char *message = lookup_resp(code)->resp_msg;

    send_response(connfd, code, message);
    send_header(connfd, "Content-Type", "text/html");
    send_header(connfd, "Connection", "close");
    end_headers(connfd);

    snprintf(buf, MAXBUF,
             "<head>\n"
             "<title>Error Response</title>\n"
             "</head>\n"
             "<body>\n"
             "<h1>Error Response</h1>\n"
             "<p>Error code %d.</p>\n"
             "<p>Message: %s.</p>\n"
             "</body>", code, message);
    rio_writen(connfd, buf, strlen(buf));

    free(buf);
}
Exemplo n.º 29
0
void printerror(int sid, int status, char* title, char* text)
{
	send_header(sid, 0, 200, "OK", "1", "text/html", -1, -1);
	prints("<HTML><HEAD><TITLE>%d %s</TITLE></HEAD>\n", status, title);
	prints("<BODY BGCOLOR=#F0F0F0 TEXT=#000000 LINK=#0000FF ALINK=#0000FF VLINK=#0000FF>\n");
	prints("<H1>%d %s</H1>\n", status, title);
	prints("%s\n", text);
	prints("<HR>\n<ADDRESS>%s</ADDRESS>\n</BODY></HTML>\n", SERVER_NAME);
	conn[sid].dat->out_bodydone=1;
	flushbuffer(sid);
	closeconnect(sid, 1);
	return;
}
Exemplo n.º 30
0
static int
send_file(struct http_request *req)
{
	int r;
	off_t file_size = -1;
	int fd;
	struct Stat stat;

	// open the requested url for reading
	// if the file does not exist, send a 404 error using send_error
	// if the file is a directory, send a 404 error using send_error
	// set file_size to the size of the file

	// LAB 6: Your code here.
	//panic("send_file not implemented");
	fd = open(req->url, O_RDONLY);
	if (fd < 0) {
		send_error(req, 404);
		r = fd;
		goto end;
	}
	r = fstat(fd, &stat);
	if (r < 0) {
		send_error(req, 404);
		goto end;
	}
	if (stat.st_isdir == 1) {
		send_error(req, 404);
		r = 0;
		goto end;
	}
	file_size = stat.st_size;

	if ((r = send_header(req, 200)) < 0)
		goto end;

	if ((r = send_size(req, file_size)) < 0)
		goto end;

	if ((r = send_content_type(req)) < 0)
		goto end;

	if ((r = send_header_fin(req)) < 0)
		goto end;

	r = send_data(req, fd, file_size);

end:
	close(fd);
	return r;
}