Code Monkey home page Code Monkey logo

tinywebserver's Introduction

Visitor count

Welcome 👋

  • 📙 Interested in Backend Dev && Cloud Native
  • ⚡ Golang / Python / C++.
  • 🐱 CatKeeper

tinywebserver's People

Contributors

byfate avatar ek1ng avatar mamil avatar maplefu avatar qinguoyi avatar sundxu avatar yukunj avatar zjuhong avatar zwiley avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tinywebserver's Issues

http_conn.cpp中write()好像有问题

bool http_conn::write()
{
    int temp = 0;

    if (bytes_to_send == 0)
    {
        modfd(m_epollfd, m_sockfd, EPOLLIN, m_TRIGMode);
        init();
        return true;
    }

    //int mv0len = m_iv[0].iov_len;

    while (1)
    {
        temp = writev(m_sockfd, m_iv, m_iv_count);

        if (temp < 0)
        {
            if (errno == EAGAIN)
            {
                modfd(m_epollfd, m_sockfd, EPOLLOUT, m_TRIGMode);
                return true;
            }
            unmap();
            return false;
        }

        bytes_have_send += temp;
        bytes_to_send -= temp;

        if (bytes_have_send >= m_iv[0].iov_len)
        {
            m_iv[0].iov_len = 0;
            m_iv[1].iov_base = m_file_address + (bytes_have_send - m_write_idx);
            m_iv[1].iov_len = bytes_to_send;
            //printf("1: >= \n");
        }
        else
        {
            m_iv[0].iov_base = m_write_buf + bytes_have_send;
            m_iv[0].iov_len = m_iv[0].iov_len - bytes_have_send;
            //printf("2: < \n");
        }

        // if (bytes_have_send >= mv0len)
        // {
        //     m_iv[0].iov_len = 0;
        //     m_iv[1].iov_base = m_file_address + (bytes_have_send - m_write_idx);
        //     m_iv[1].iov_len = bytes_to_send;
        // }
        // else 
        // {
        //     m_iv[0].iov_base = m_write_buf + bytes_have_send;
        //     m_iv[0].iov_len = m_iv[0].iov_len - temp;
        // }

        if (bytes_to_send <= 0)
        {
            unmap();
            modfd(m_epollfd, m_sockfd, EPOLLIN, m_TRIGMode);

            if (m_linger)
            {
                init();
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}

使用作者的wirtev后的处理方式跑,图片视屏传输正常,但是printf("2\n")没有执行过,也就是writev每次都把m_iv[0]的内容一次发送完毕,但是看作者的if(bytes_have_send >= m_iv[0].iov_len) else{}这里的else逻辑明显有问题,只是因为如上原因没有执行过,
假设writev第一次没有发出iov0的全部内容if (bytes_have_send >= m_iv[0].iov_len)不执行,则第二论的while()的if (bytes_have_send >= m_iv[0].iov_len)这里的m_iv[0].iov_len明显不是iov0的全部长度,按照博主的判断流程这里应该修改我注视的代码,不知道博主怎么认为的.

关于线程池和请求队列的问题

在webserver中每次需要处理完一个就绪事件才能将下一个事件放入请求队列,那这样的话就会保持请求队列始终只有一个请求,线程池的线程也只用上一个?

定时器组件存在bug

Utils::u_epollfd = m_epollfd;

秦院好,这里u_epoll先于m_epoll被赋有效值前赋值,导致定时器回调函数中使用的该值为无效值,测试过好像真滴是bug,请秦院修复

不过我手头代码版本较旧(大概一个月前吧),如果已经修复了还请秦院无视

clang: error: cannot specify -o when generating multiple output files

g++ -o server main.c ./timer/lst_timer.h ./timer/lst_timer.cpp ./threadpool/threadpool.h ./http/http_conn.cpp ./http/http_conn.h ./lock/locker.h ./log/log.cpp ./log/log.h ./CGImysql/sql_connection_pool.cpp ./CGImysql/sql_connection_pool.h webserver.h webserver.cpp config.h config.cpp -lpthread -lmysqlclient
clang: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated [-Wdeprecated]
clang: warning: treating 'c-header' input as 'c++-header' when in C++ mode, this behavior is deprecated [-Wdeprecated]
clang: warning: treating 'c-header' input as 'c++-header' when in C++ mode, this behavior is deprecated [-Wdeprecated]
clang: warning: treating 'c-header' input as 'c++-header' when in C++ mode, this behavior is deprecated [-Wdeprecated]
clang: warning: treating 'c-header' input as 'c++-header' when in C++ mode, this behavior is deprecated [-Wdeprecated]
clang: warning: treating 'c-header' input as 'c++-header' when in C++ mode, this behavior is deprecated [-Wdeprecated]
clang: warning: treating 'c-header' input as 'c++-header' when in C++ mode, this behavior is deprecated [-Wdeprecated]
clang: warning: treating 'c-header' input as 'c++-header' when in C++ mode, this behavior is deprecated [-Wdeprecated]
clang: warning: treating 'c-header' input as 'c++-header' when in C++ mode, this behavior is deprecated [-Wdeprecated]
clang: error: cannot specify -o when generating multiple output files
make: *** [server] Error 1
g++ -o ./root/CGISQL.cgi ./CGImysql/sign.cpp ./CGImysql/sql_connection_pool.cpp ./CGImysql/sql_connection_pool.h -lmysqlclient -lpthread
clang: warning: treating 'c-header' input as 'c++-header' when in C++ mode, this behavior is deprecated [-Wdeprecated]
clang: error: cannot specify -o when generating multiple output files
make: *** [CGISQL.cgi] Error 1

代码调试疑问

你好,我最近在阅读调试源码时,在Ubuntu中进行make时,系统报错 :在http_conn.cpp文件中第549行,temp=writev(m_sockfd,m_iv,m_iv_count); writev函数并没有在此文件中定义,所以make失败了,烦请大佬解释一波,不甚感激!

视频无法播放

在centos7里面用 火狐 打开 IP:9006可以正常显示界面,但是无法播放视频(显示没有找到支持的视频格式) 可能是浏览器问题
另外在win10里以 IP:9006 无法打开界面

调试

想问下大佬在Ubuntu底下是如何进行调试的呢?使用Clion这种IDE还是GDB?

log.cpp中的log::init函数中的异步问题

这里是通过条件变量来实现数组大小的同步问题吧,那个异步体现在了哪里? 代码中说的是//flush_log_thread为回调函数,这里表示创建线程异步写日志,这里只是开了一个线程来运行flush_log_thread函数吧,我认为本质应该还是线程同步问题吧,这里还请解答一下

只能主机访问,不能远程访问

我运行成功了,可是却只能在运行server的这台计算机上访问,使用其他的计算机,输入相同的ip和端口却不能访问,有人能帮我解答下这是为什么吗,谢谢。

代码调试中的疑问

你好:我最近一直在学习研读调试你的Tinywebserver ,想请教一下,在http_conn.cpp文件中,有关修改数据库初始化信息,中有connection_pool *connPool=connection_pool::GetInstance("localhost", "root","root","yourdb",3306,5);这其中 “localhost” 应该输入啥? 我的开发环境是在VMware workstation 12 Pro 上安装 ubuntu16.04LTS ,服务器程序实在VMware workstation12 上的ubuntu16.04上编译的,请问此处的"localhost"应该填虚拟机ubuntu16.04的ip地址还是我笔记本的ip地址?如能帮忙解答,将不胜感激!我微信号15829468779,如能与你成为微信好友,深感荣幸!

http_conn类的线程安全问题

比如http_conn类中的bytes_to_send 字段,在写线程和读线程中都有用到,但时并未加锁,我觉得是有线程安全问题的。

关于写数据问题

当一个write()或read_once()阻塞时,webserver是否就会被阻塞在 这一步无法处理下一个请求和新的就绪事件

m_cond.wait( )的问题

//pop时,如果当前队列没有元素,将会等待条件变量
bool pop(T &item)
{

    m_mutex.lock();
    while (m_size <= 0)
    {
        // 这里若线程wait成功,函数返回0
        if (!m_cond.wait(m_mutex.get()))
        {
            m_mutex.unlock();
            return false;
        }
    }

    m_front = (m_front + 1) % m_max_size;
    item = m_array[m_front];
    m_size--;
    m_mutex.unlock();
    return true;
}

这是源码中block_queue中的pop函数,wait那一行是不是存在逻辑错误?

而在微信公众号解析代码中:if (0 != pthread_cond_wait(m_cond, m_mutex)) ,两者有出入

常见问题与解决方案

大家在运行项目时遇到问题,优先查阅本lssue。

如果本issue不能解决你的问题,欢迎盖楼或直接公号私信我,我会尽快回复。

webbench测试硬件参数

请问readme中的QPS是在什么硬件条件下测试的?
另外有在云服务器上测试过QPS吗?(一般都是1核cpu配置)
想参考一下数据,谢谢!

cmakelists文件

请问有cmakelists文件吗,我根据makefile写的cmakelists但是运行后不能进入,命令行上一直显示close17 close16

writev 使用好像有问题

我发现使用 writev 向 socket 写数据时,如果没有一次写完,就需要调整 iov 数组,不然图片会显示不完整。

我是在虚拟机上启动 server,然后在实体机上请求图片的,这时候 writev 会连续写几次才能写完,这时候就会出问题(图片显示不完整)。而在本地(同样在虚拟机中)请求图片的话,writev 可以一次性写完,图片可以完整的显示出来。

我自己的代码如下:

/* 写 HTTP 响应 */
bool http_conn::write() {
  int tmp = 0;
  printf("---debug---%d bytes to send\n", __bytes_to_send);
  if (__bytes_to_send == 0) {
    modfd(epollfd, __sockfd, EPOLLIN);
    __init();
    return true;
  }
  while (1) {
    tmp = Writev(__sockfd, __iv, __iv_cnt);
    if (tmp < 0) {
      if (errno == EAGAIN) {
        /* 若写缓冲区没有空间,则等待缓冲区可写,在此期间无法接收客户端请求 */
        modfd(epollfd, __sockfd, EPOLLOUT);
        return true;
      }
      __unmap();
      return false;
    }
    printf("---debug---sent %d bytes\n", tmp);
    __bytes_to_send -= tmp;
    __bytes_have_sent += tmp;
    __adjust_iv();

    if (__bytes_to_send <= 0) {
      __unmap();
      /* HTTP 响应发送成功,根据 Connection 字段决定是否立即关闭连接 */
      if (__linger) {
        __init();
        modfd(epollfd, __sockfd, EPOLLIN);
        return true;
      } else {
        modfd(epollfd, __sockfd, EPOLLIN);
        return false;
      }
    }
  }
  return false;
}

___adjust_iv 函数:

/* 每次调用 writev 都需要调整 __iv */
void http_conn::__adjust_iv() {
  if (__bytes_have_sent >= __write_idx) {
    __iv[0].iov_len = 0;
    __iv[1].iov_base = __file_addr + (__bytes_have_sent - __write_idx);
    __iv[1].iov_len = __bytes_to_send;
  } else {
    __iv[0].iov_base = __write_buf + __bytes_have_sent;
    __iv[0].iov_len = __write_idx - __bytes_have_sent;
  }
}

some security issues in the code

sql injection

https://github.com/qinguoyi/TinyWebServer/blob/master/http/http_conn.cpp#L426
user’s inputs are directly spliced ​​into the SQL statement
Attack vector:server supports the http protocol, capture the packet in the registration interface, and modify the packet to a malicious statement.

heap overflow

https://github.com/qinguoyi/TinyWebServer/blob/master/http/http_conn.cpp#L425
Because the length of the sql statement is not limited, the variable sql_insert overflows. The memory storing sql_insert is called later, causing the program to crash.

stack overflow

https://github.com/qinguoyi/TinyWebServer/blob/master/http/http_conn.cpp#L410
The program does not limit the length of the input of variable name and variable password.Users can enter characters of any length to cause stack overflow

http_conn.cpp中http::process有问题?

void http_conn::process()
{
HTTP_CODE read_ret = process_read();
if (read_ret == NO_REQUEST)
{
modfd(m_epollfd, m_sockfd, EPOLLIN, m_TRIGMode);
return;
}
bool write_ret = process_write(read_ret); //如果返回false,close_conn()就会执行(m_sockfd=-1),连接关闭,然后还要注册写事件?
if (!write_ret)
{
close_conn();
}
modfd(m_epollfd, m_sockfd, EPOLLOUT, m_TRIGMode);
}

http_conn类问题

前辈你好:
http_conn.c 文件的users(就是用户的map),是不是应该设置成staic类型的。如果是非static类型的,每次来一个链接,就应该从数据库拷贝一次用户名和密码表,但http_conn::init()函数没有进行这一操作,webserver.c也只是拷贝了一次。另外,微信群怎么加入啊,希望和大家一起讨论。

编译出错

我修改好数据库配置后,再运行make server,出现如下报错:
image
请问要怎么解决?

为什么write完成后,清空读缓冲区?

http_conn.h和http_conn.cpp中,如果read_once函数读取的数据跨越了前一个请求和后一个请求的HTTP报文,那么在调用write函数在某些条件下,调用了init()函数,清空了读缓冲区,那么后一个请求的一部分数据不就丢失了?

关于webserver代码问题

前辈你好,我有几个疑问
1.webserver类中定义了一个sort_timer_lst变量timer_lst,代码中操作的也都是变量timer_lst。但是最后在eventloop函数使用了utils.timer_hander()函数。utils对象的初始化使用的是最开始定义的timer_lst,后面utils对象的m_timer_lst没有进行更新.
我觉得是不是把utils对象的初始化放在webserver类的构造函数,后面统一对utils.m_timer_lst操作。要么就是改eventloop中的代码。
2.
//处理新到的客户连接
if (sockfd == m_listenfd)
{
bool flag = dealclinetdata();
if (false == flag)//?????
continue;
}
这里的if判断条件是什么作用呢?我猜测是不是你想在flag==false的情况下输出日志,代码未完成吗?感谢解答

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.