GithubHelp home page GithubHelp logo

jqhttpserver's Issues

用于地图瓦片数据的发布中的优化建议(tms)

Hi 188080501
我用JQHttp 发布地图瓦片数据,使用稳定。希望增加一个针对地图数据特点的 replyTmsImage,对地图数据进行预读与缓存,提高地图数据的相应速度。TMS格式的地图瓦片数据访问有一定的规律,简单说就是将当前访问的图片文件的前后图片预读,或者使用进行缓存,缓存数量可以通过参数设定。谢谢!

SSL Error

When i run this JQHttpServer using my valid ssl certification with digicert cert, Got error from third party enggine : "SSL routines:tls_process_server_certificate:certificate verify failed". And also got error message from the application : "JQHttpServer::Session::inspectionBuffer: error3: HEAD". Could you help me to solve this problem?

Thank you.

如何在回调中调用数据库

你好,你这个轻量级http服务器很不错。不够头疼的是5.12以后,在回调中调用数据库一直失败,请问有什么好的方法在收到http请求时调用数据库吗

compile this part in qt 5.2, many errors,

library/JQLibrary/src/JQHttpServer.cpp: In member function ‘bool JQHttpServer::AbstractManage::startServerThread()’:
library/JQLibrary/src/JQHttpServer.cpp:804:7: error: no matching function for call to ‘run(QThreadPool*, JQHttpServer::AbstractManage::startServerThread()::<lambda()>)’
} );
^
In file included from /usr/include/qt5/QtConcurrent/QtConcurrent:14:0,
from library/JQLibrary/src/JQHttpServer.cpp:34:
/usr/include/qt5/QtConcurrent/qtconcurrentrun.h:70:12: note: candidate: template QFuture QtConcurrent::run(T (*)())
QFuture run(T (functionPointer)())
^~~
/usr/include/qt5/QtConcurrent/qtconcurrentrun.h:70:12: note: template argument deduction/substitution failed:
library/JQLibrary/src/JQHttpServer.cpp:804:7: note: mismatched types ‘T()’ and ‘QThreadPool’
} );
^
In file included from /usr/include/qt5/QtConcurrent/QtConcurrent:14:0,
from library/JQLibrary/src/JQHttpServer.cpp:34:
/usr/include/qt5/QtConcurrent/qtconcurrentrun.h:75:12: note: candidate: template<class T, class Param1, class Arg1> QFuture QtConcurrent::run(T (
)(Param1), const Arg1&)
QFuture run(T (*functionPointer)(Param1), const Arg1 &arg1)
^~~

AbstractManage 中的 QMutex 互斥锁是否必要?

我发现在 AbstractManage::newSession 中,使用了 QMutex 对 availableSessions_ 进行了保护,但是这种保护是否必要?

  1. 所有的 Session 对象均在同一个线程(serverThreadPool_ 中的唯一一个线程)。
  2. 根据我的测试,Lambda 槽函数调用时是非跨线程的。
  3. 我没有找到其他的跨线程的对 availableSessions_ 的访问。
    所以应当不会有多线程冲突。
    另外,设置 availableSessions_ 的用途是什么?

静态路由使用不便

现在使用静态路由要自行实现 sessionAccepted 函数,颇为不便,建议增加专用的静态路由功能

探讨是否可以有 QML 接口

在 readme 中提及了并发数的问题。

推荐使用Linux系统或者Unix系统,因为在5.7后,Qt更换了Unix相关系统的底层模型,从select更换为了poll,这样子网络库的并发就脱离了1024个的限制。

看起来应该可以应用方向是小型,实用上。

这里我想探讨一下是否可以有 QML 的接口。或者说 QML 的接口该如何设计呢?

要怎么实现get body部分

put post都可以“const QByteArray &body”,但是get不行,请教大神帮忙解答下。要怎么实现body

如何在session中返回一个自定义的错误?

你好,感谢上一次的回复建议。
这里请教一个问题:就是如何在session中返回一个自定义错误?
代码:

static JQHttpServer::TcpServerManage httpServer( maxThreads ); // 设置最大处理线程数,默认2个
httpServer.setHttpAcceptedCallback( std::bind(onHttpAccepted, std::placeholders::_1 ) );

设置了onHttpAccepted 回调函数,同时在Session 中增加了一个自定义错误代码 internalErrorCode_,
通过如下代码暴露出来:
int JQHttpServer::Session::internalErrorCode() const
{
// JQHTTPSERVER_SESSION_PROTECTION( "internalErrorCode", 0 )

return internalErrorCode_;

}

在session的 replyImage中修改internalErrorCode_,该值在回调函数中不能获得(修改没起作用),是不是哪里有问题 ?
尝试修改:
int JQHttpServer::Session::replyHttpCode() const
中的 replyHttpCode返回,也没有效果,不知是哪里问题?请教!

在次感谢!

failed in compiling with qtcreator

Hello!Thank you for sharing your code firstly!
I want to use your server to test my client,however it was failed when I compiled your code.The error info is as follows.Could you help me to fix this problem?Thank you again.

/home/xue/JQHttpServer/JQHttpServer/library/JQLibrary/src/JQNet.cpp:281: error: conversion from 'const QByteArray' to 'QIODevice*' is ambiguous
     auto reply = manage_.sendCustomRequest( request, "PATCH", appendData );
/home/xue/JQHttpServer/JQHttpServer/library/JQLibrary/src/JQNet.cpp:315: error: conversion from 'const QByteArray' to 'QIODevice*' is ambiguous
     auto reply = manage_.sendCustomRequest( request, "PATCH", appendData );
                                                                          

解析提交的表单数据头

请教一下,用这个server,如何解析提交的文件和键值混和表单数据,主要不知道如何解析出请求头的文件名称

HttpServer接收回调问题

您好,还是原来那个问题,我在linux(Ubuntu18.04)qt(5.14.1)下也测试过。使用lambda函数,好像只能在mian函数内,客户端请求才能收到,一但在不在,客户端请求接收不到,返回false。还请帮忙看看 int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.setWindowTitle("HttpServer");
w.show();
#if 1
JQHttpServer::TcpServerManage tcpServerManage(10); // 设置最大处理线程数,默认2个
tcpServerManage.setHttpAcceptedCallback(
[]( const QPointer< JQHttpServer::Session > &session )
{
// 回调发生在新的线程内,不是主线程,请注意线程安全
// 若阻塞了此回调,那么新的连接将不会得到处理(默认情况下有2个线程可以阻塞2次,第3个连接将不会被处理)
qDebug() << "请求来源IP: "+session->requestSourceIp(); //请求来源IP
qDebug() << "url:"+session->requestUrl(); //url 后面参数
qDebug() << "请求方式: "+session->requestMethod(); //POST GET
qDebug() << "postdata: "+session->requestBody();
QByteArray postdata = session->requestBody();
QString ssize = QString::number(postdata.size(),10);
qDebug() << "postdata.size: "+ssize;
session->replyText( QString( "url:%1\nbody:%2" ).arg( session->requestUrl(), QString( session->requestBody() ) ) );
// 注1:因为一个session对应一个单一的HTTP请求,所以session只能reply一次
// 注2:在reply后,session的生命周期不可控,所以reply后不要再调用session的接口了
} );
qDebug() << "listen:" << tcpServerManage.listen( QHostAddress("192.168.124.128"), 9091);
qDebug() << ("Http服务已启动");
#endif
return a.exec();`

image
image
image

关于服务端主动下发的问题

您好,我想请问一下,我要实现服务端能主动下发,也就是长连接,我测试每次请求都会有新的连接过来,这时候我保留套接字,然后重新new一个session 来应答,这样是否可行?

希望能为replyBytes增加MimeType的选项

如题,因为对于部分网页应用而言,Content-Type的类型是必须的。(如模块化加载JavaScript和图片显示)
这也可以简化对于小型HTTP服务获取文件类型的判断
我目前更改了一下replyBytes的接口,如下:

static QString replyBytesFormat(
        "HTTP/1.1 %1 OK\r\n"
        "Content-Type: %2\r\n"
        "Content-Length: %3\r\n"
        "Access-Control-Allow-Origin: *\r\n"
        "Access-Control-Allow-Headers: Content-Type,X-Requested-With\r\n"
        "\r\n"
    );
void JQHttpServer::Session::replyBytes(const QByteArray &bytes, const int &httpStatusCode,const QString mime)
{
    JQHTTPSERVER_SESSION_REPLY_PROTECTION( "replyBytes" )

    if ( QThread::currentThread() != this->thread( ))
    {
        replyHttpCode_ = httpStatusCode;

        QMetaObject::invokeMethod(this, "replyBytes", Qt::QueuedConnection, Q_ARG(QByteArray, bytes), Q_ARG(int, httpStatusCode), Q_ARG(QString, mime));
        return;
    }

    JQHTTPSERVER_SESSION_REPLY_PROTECTION2( "replyBytes" )

    auto buffer = new QBuffer;
    buffer->setData( bytes );

    if ( !buffer->open( QIODevice::ReadWrite ) )
    {
        qDebug() << "JQHttpServer::Session::replyBytes: open buffer error";
        delete buffer;
        this->deleteLater();
        return;
    }

    ioDeviceForReply_.reset( buffer );
    ioDeviceForReply_->seek( 0 );

    replyBodySize_ = buffer->buffer().size();

    const auto &&data = replyBytesFormat.arg(
                QString::number( httpStatusCode ),
                mime,
                QString::number( replyBodySize_ )
            ).toUtf8();

    waitWrittenByteCount_ = data.size() + buffer->buffer().size();
    ioDevice_->write(data);
}

这样在返回HTTP回复的时候就可以设置Content-Type了

访问一次会有两次处理

用浏览器访问一次,服务器显示处理了两次
第一次为正常请求
Body ""
Header QMap(("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8")("Accept-Encoding", "gzip, deflate")("Accept-Language", "zh-CN,en-US;q=0.8")("Cache-Control", "max-age=0")("Connection", "keep-alive")("Host", "191.167.2.36:23412")("Upgrade-Insecure-Requests", "1")("User-Agent", "Mozilla/5.0 (Linux; Android 7.1.1; 1801-A01 Build/NMF26X; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/59.0.3071.82 Mobile Safari/537.36")("X-Requested-With", "org.qtproject.example.minibrowser"))
Method "GET"
UrlPath ""
Url "/"
UrlQuery QMap()
UrlPathSplitToList ()
第二次为/favicon 请求打印出来如下
Body ""
Header QMap(("Accept", "image/webp,image/apng,image/,/*;q=0.8")("Accept-Encoding", "gzip, deflate")("Accept-Language", "zh-CN,en-US;q=0.8")("Connection", "keep-alive")("Host", "191.167.2.36:23412")("Referer", "http://191.167.2.36:23412/")("User-Agent", "Mozilla/5.0 (Linux; Android 7.1.1; 1801-A01 Build/NMF26X; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/59.0.3071.82 Mobile Safari/537.36")("X-Requested-With", "org.qtproject.example.minibrowser"))
Method "GET"
UrlPath "/favicon.ico"
Url "/favicon.ico"
UrlQuery QMap()
UrlPathSplitToList ("favicon.ico")

不知道为什么会有两次

QT5.15.0中对于API的变更

在Qt5.15.0(Ubuntu20.04自编译)环境下,发现使用JQNet.cpp会提示

‘void QNetworkReply::error(QNetworkReply::NetworkError)’ is deprecated: Use QNetworkReply::errorOccurred(QNetworkReply::NetworkError) instead

看起来是有一些API变更了呢

附带错误提示全文:

../H2server/library/JQLibrary/src/JQNet.cpp: In member function ‘void JQNet::HTTP::handle(QNetworkReply*, const int&, const std::function<void(const QList<QPair<QByteArray, QByteArray> >&, const QByteArray&)>&, const std::function<void(const QList<QPair<QByteArray, QByteArray> >&, const QNetworkReply::NetworkError&, const QByteArray&)>&, const std::function<void()>&)’:
../H2server/library/JQLibrary/src/JQNet.cpp:682:124: warning: ‘void QNetworkReply::error(QNetworkReply::NetworkError)’ is deprecated: Use QNetworkReply::errorOccurred(QNetworkReply::NetworkError) instead [-Wdeprecated-declarations]
  682 |     QObject::connect( reply, static_cast< void( QNetworkReply::* )( QNetworkReply::NetworkError ) >( &QNetworkReply::error ), [ reply, timer, onError, isCalled ](const QNetworkReply::NetworkError &code)
      |                                                                                                                            ^
In file included from /opt/qt5.15.0/include/QtNetwork/QNetworkReply:1,
                 from ../H2server/library/JQLibrary/include/JQNet.h:31,
                 from ../H2server/library/JQLibrary/src/JQNet.cpp:18:
/opt/qt5.15.0/include/QtNetwork/qnetworkreply.h:161:10: note: declared here
  161 |     void error(QNetworkReply::NetworkError);
      |          ^~~~~
../H2server/library/JQLibrary/src/JQNet.cpp:682:124: warning: ‘void QNetworkReply::error(QNetworkReply::NetworkError)’ is deprecated: Use QNetworkReply::errorOccurred(QNetworkReply::NetworkError) instead [-Wdeprecated-declarations]
  682 |     QObject::connect( reply, static_cast< void( QNetworkReply::* )( QNetworkReply::NetworkError ) >( &QNetworkReply::error ), [ reply, timer, onError, isCalled ](const QNetworkReply::NetworkError &code)
      |                                                                                                                            ^
In file included from /opt/qt5.15.0/include/QtNetwork/QNetworkReply:1,
                 from ../H2server/library/JQLibrary/include/JQNet.h:31,
                 from ../H2server/library/JQLibrary/src/JQNet.cpp:18:
/opt/qt5.15.0/include/QtNetwork/qnetworkreply.h:161:10: note: declared here
  161 |     void error(QNetworkReply::NetworkError);
      |          ^~~~~

长时间多次post请求会出现内存泄露?

包含头文件,然后客户端使用示例代码:
const auto &&reply = JQNet::HTTP::post( "http://127.0.0.1:23412/TestUrl", "AppendData" );
进行120ms/次请求,则出现内存不断增长的问题,请问这个问题有什么好的解决方案吗?
服务端正常,客户端出现内存泄露?期待你的交流,我的QQ4589968

跨域

请问C++服务端这边如何支持跨域

server端程序运行崩溃

在CPU负载较高,或回调执行时间较长下,程序可能崩溃。
看了下代码,回调是在另一个线程下运行,当调用session->reply时,session,iodeviece_都有可能随时被删除(如超时);
另外,如果客户端提前超时,关闭连接,那么服务端对accept的TcpSocket未做处理,这种场景下程序运行行为如何,是否导致ioDevice_指向已销毁的socket资源。

win10和ubuntu 16.04下性能测试问题,每个请求20ms

你好,我在win10和ubuntu 16.04下进行性能测试(Qt5.7),发现单次请求、响应时间延迟非常大,每个请求20ms左右。

测试方法为:在同一台电脑上先启动HttpServerDemo,然后运行HttpClientDemo,在client端发起5000次请求(单线程,即在main线程内),方法同benchMarkFor5000,并计算时间。测试过程中,两个进程的cpu利用率以及系统cpu利用率都很低。

折算下来,空跑QPS才50,请问这可能是什么原因导致性能上不去?

长连接时后续请求会被忽略

我在使用 jmeter 多线程测试多个接口时,发现如果都勾选了 keep-alive,每个线程第一个请求之后的请求都会失败。
我看到 JQHttpServer::Session 里有个 30秒 的计时器,推测这个库应该有支持 Http/1.1 的长连接功能。
检查了下代码,发现是由于在 JQHttpServer::Session::onBytesWritten 函数里,大约第826行,调用了 socket_->disconnectFromHost() 关掉了该连接,导致后续请求都不会被接收。
建议 session 增加一个 reset 函数,在一个请求结束后(比如 第826行 的 回复完成后),将 session 的解析参数重置为默认值,以继续解析后续请求。

Server收不到请求

您好,我测试server的回调函数,只能放在mian函数中,否则就无法收不到请求

JQHttpServer浏览器请求的时候如何返回一个本地的html页面

比如浏览器访问:http://localhost:23412/index

服务器收到index后我想返回一个本地已经写好的html页面,以下是demo中的例子:
session->replyText( QString( "url:%1\nbody:%2" ).arg( session->requestUrl(), QString( session->requestBody() ) ) );
session->replyRedirects( QUrl( "http://www.baidu.com" ) );
session->replyJsonObject( { { { "message", "ok测试部" } } } );
session->replyJsonArray( { "a", "b", "c" } );
session->replyFile( "/Users/jason/Desktop/Test1.Test2" );
session->replyImage( QImage( "/Users/jason/Desktop/Test.png" ) );
session->replyBytes(QByteArray(4,'\x24'));

看到请解释下,非常感谢

Error SSL while running HttpsServerDemo

When starting the application "HttpsServerDemo", i got this error:
qt.network.ssl: QSslSocket: cannot resolve TLSv1_1_client_method
qt.network.ssl: QSslSocket: cannot resolve TLSv1_2_client_method
qt.network.ssl: QSslSocket: cannot resolve TLSv1_1_server_method
qt.network.ssl: QSslSocket: cannot resolve TLSv1_2_server_method
qt.network.ssl: QSslSocket: cannot resolve SSL_select_next_proto
qt.network.ssl: QSslSocket: cannot resolve SSL_CTX_set_next_proto_select_cb
qt.network.ssl: QSslSocket: cannot resolve SSL_get0_next_proto_negotiated
qt.network.ssl: QSslSocket: cannot resolve SSL_set_alpn_protos
qt.network.ssl: QSslSocket: cannot resolve SSL_CTX_set_alpn_select_cb
qt.network.ssl: QSslSocket: cannot resolve SSL_get0_alpn_selected
sslCertificate: QSslCertificate("1", "ae:01:71:c8:21:fc:00:c2", "eKXBjkCzjZbWnEvw5NXsWw==", ("Internet Widgits Pty Ltd"), ("Internet Widgits Pty Ltd"), QMap(), QDateTime(2017-04-09 07:07:27.000 UTC Qt::TimeSpec(UTC)), QDateTime(2027-04-07 07:07:27.000 UTC Qt::TimeSpec(UTC)))
sslKey: QSslKey(PrivateKey, RSA, 2048)
caCertificates: ()
listen: true

And when i send packet data to the server, the server got error like this:
qt.network.ssl: QSslSocket: cannot call unresolved function TLSv1_2_server_method
qt.network.ssl: QSslSocket: cannot call unresolved function TLSv1_2_server_method

could you help me, why this happens ?

关于遇到超时的问题

你好我使用 您的库 请求 http 有时会发现 就算外网 不可请求到 也是一直阻塞直到超时 才返回 是否可以 立即返回

Service

请问Service模块的作用是什么?

关于html页面显示图片的问题

我有一个需求是服务器同时返回一段文本和一张图片。
我尝试过的方法:
1、在setHttpAcceptedCallback回调中同时调用
{
session->replyText(...)
session->replyImage(...)
}
这样会出现 服务器程序停止运行

2、我用session->replyFile 函数返回一个html 文件

(代码格式是故意少写了<,不然该页面不能显示)
html>
body >
img src ="http://www.baidu.com/img/bd_logo1.png" />
img src ="http://192.168.31.101:23412/bb.png"/>
/body>
/html>

第一张百度图片显示正常。
第二张图片是我服务器上的图片,不能正常显示。

请问是否我图片路径有问题,通过html方法如何访问我的服务器图片

80端口启动失败

为什么我是用80 端口 listen的时候失败了,8080 可以成功,然后查看了80 端口没有别的应该占用。
我是uos统信 个人版20 。是系统原因吗?
image
image

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.