// // 读取一个应答 // FFL::sp<HttpResponse> HttpClient::readResponse() { HttpParser parser; FFL::sp<HttpResponse> response = new HttpResponse(this); if (FFL_OK == parser.parseResponse(&mData, response.get())) { return response; } return NULL; }
// // 读取一个请求 // FFL::sp<HttpRequest> HttpClient::readRequest() { HttpParser parser; FFL::sp<HttpRequest> request = new HttpRequest(this); if (FFL_OK == parser.parseRequest(&mData,request.get())) { return request; } return NULL; }
/** * ブラウザとの間に新しいソケットを開く */ void YASWebProxy::openNewSocket() { QTcpSocket* socket = server->nextPendingConnection(); connect(socket, SIGNAL(readyRead()), this, SLOT(openTunnel())); connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater())); HttpParser* parser = new HttpParser(HttpParser::REQUEST, socket); parser->setObjectName("requestParser"); connect(parser, SIGNAL(completeMessage(QByteArray)), this, SLOT(onRequest(QByteArray))); }
void HTTPNetworkProxy::finish(Buffer& readBuffer, Buffer&) { HttpParser parser; parser.parse(readBuffer.b.begin(), readBuffer.b.end()); if(parser.status() != 200) { throw Ice::ConnectFailedException(__FILE__, __LINE__); } }
CWebSocket* CWebSocketManager::Handle(const char* data, unsigned int length, std::string &response) { if (data == NULL || length <= 0) return NULL; HttpParser header; HttpParser::status_t status = header.addBytes(data, length); switch (status) { case HttpParser::Error: case HttpParser::Incomplete: response.clear(); return NULL; case HttpParser::Done: default: break; } // There must be a "Sec-WebSocket-Version" header const char* value = header.getValue(WS_HEADER_VERSION_LC); if (value == NULL) { CLog::Log(LOGINFO, "WebSocket: missing Sec-WebSocket-Version"); CHttpResponse httpResponse(HTTP::Get, HTTP::BadRequest, HTTP::Version1_1); char *responseBuffer; int responseLength = httpResponse.Create(responseBuffer); response = std::string(responseBuffer, responseLength); return NULL; } CWebSocket *websocket = NULL; if (strncmp(value, "8", 1) == 0) websocket = new CWebSocketV8(); else if (strncmp(value, "13", 2) == 0) websocket = new CWebSocketV13(); if (websocket == NULL) { CLog::Log(LOGINFO, "WebSocket: Unsupported Sec-WebSocket-Version %s", value); CHttpResponse httpResponse(HTTP::Get, HTTP::UpgradeRequired, HTTP::Version1_1); httpResponse.AddHeader(WS_HEADER_VERSION, WS_SUPPORTED_VERSIONS); char *responseBuffer; int responseLength = httpResponse.Create(responseBuffer); response = std::string(responseBuffer, responseLength); return NULL; } if (websocket->Handshake(data, length, response)) return websocket; return NULL; }
void RPCTestNode::sendRequest(const HttpRequest& httpReq, HttpResponse& httpResp) { TcpConnector connector(m_dispatcher, "127.0.0.1", m_rpcPort); TcpConnection connection = connector.connect(); TcpStreambuf streambuf(connection); std::iostream connectionStream(&streambuf); LOG_DEBUG("invoke rpc:" + httpReq.getMethod() + " " + httpReq.getBody()); connectionStream << httpReq; connectionStream.flush(); HttpParser parser; parser.receiveResponse(connectionStream, httpResp); }
bool RPCTestNode::submitBlock(const std::string& block) { HttpRequest httpReq; httpReq.setUrl("/json_rpc"); httpReq.addHeader("Host", "127.0.0.1:" + boost::lexical_cast<std::string>(m_rpcPort)); httpReq.addHeader("Content-Type", "application/json-rpc"); JsonValue request(cryptonote::JsonValue::OBJECT); JsonValue jsonRpc; jsonRpc = "2.0"; request.insert("jsonrpc", jsonRpc); JsonValue methodString; methodString = "submitblock"; request.insert("method", methodString); JsonValue id; id = "sync"; request.insert("id", id); JsonValue params(JsonValue::ARRAY); JsonValue blockstr; blockstr = block.c_str(); params.pushBack(blockstr); request.insert("params", params); std::stringstream jsonOutputStream; jsonOutputStream << request; httpReq.setBody(jsonOutputStream.str()); TcpConnector connector(m_dispatcher, "127.0.0.1", m_rpcPort); TcpConnection connection = connector.connect(); TcpStreambuf streambuf(connection); std::iostream connectionStream(&streambuf); LOG_DEBUG("invoke json-rpc: " + httpReq.getBody()); connectionStream << httpReq; connectionStream.flush(); HttpResponse httpResp; HttpParser parser; parser.receiveResponse(connectionStream, httpResp); connectionStream.flush(); if (httpResp.getStatus() != HttpResponse::STATUS_200) return false; epee::serialization::portable_storage ps; if (!ps.load_from_json(httpResp.getBody())) { LOG_ERROR("cannot parse response from daemon: " + httpResp.getBody()); return false; } epee::json_rpc::response<COMMAND_RPC_SUBMITBLOCK::response, epee::json_rpc::error> jsonRpcResponse; jsonRpcResponse.load(ps); if (jsonRpcResponse.error.code || jsonRpcResponse.error.message.size()) { LOG_ERROR("RPC call of submit_block returned error: " + TO_STRING(jsonRpcResponse.error.code) + ", message: " + jsonRpcResponse.error.message); return false; } if (jsonRpcResponse.result.status != CORE_RPC_STATUS_OK) return false; return true; }
/** * レスポンスを転送する */ void YASWebProxy::forwardResponse() { QTcpSocket* proxySocket = qobject_cast<QTcpSocket*>(sender()); QTcpSocket* socket = qobject_cast<QTcpSocket*>(proxySocket->parent()); QByteArray res = proxySocket->readAll(); HttpParser* parser = proxySocket->findChild<HttpParser*>("responseParser"); if (parser != 0) { parser->input(res); socket->write(parser->dequeueData()); } else { socket->write(res); } }
bool HttpResponse::init(HttpParser& http) { m_arValues[HTTP_RESPONSE_HTTP] = http.get(HTTP_HEAD_HTTP); m_arValues[HTTP_RESPONSE_CODE] = "200 OK"; m_arValues[HTTP_RESPONSE_SERVER] = "LHTTPD/"; m_arValues[HTTP_RESPONSE_SERVER] += LHTTPD_VERSION; m_arValues[HTTP_RESPONSE_SERVER] += " (Win64)"; m_arValues[HTTP_RESPONSE_X_POWERED] = "Lua/5.2"; m_arValues[HTTP_RESPONSE_KEEP_ALIVE] = "timeout=5, max=100"; m_arValues[HTTP_RESPONSE_CONNECTION] = http.get(HTTP_HEAD_CONNECTION); m_arValues[HTTP_RESPONSE_TRANSFER_ENCODING] = "chunked"; m_arValues[HTTP_RESPONSE_CONTENT_TYPE] = "text/html"; return true; }
void HttpClient::request(const HttpRequest &req, HttpResponse &res) { if (!m_connected) { connect(); } try { std::iostream stream(m_streamBuf.get()); HttpParser parser; stream << req; stream.flush(); parser.receiveResponse(stream, res); } catch (const std::exception &) { disconnect(); throw; } }
TEST(TestHttpParser, General) { HttpParser a; std::string str = "POST /path/script.cgi HTTP/1.0\r\n" "From: [email protected]\r\n" "User-Agent: XBMC/snapshot (compatible; MSIE 5.5; Windows NT" " 4.0)\r\n" "Content-Type: application/x-www-form-urlencoded\r\n" "Content-Length: 35\r\n" "\r\n" "home=amejia&favorite+flavor=orange\r\n"; std::string refstr, varstr; EXPECT_EQ(a.Done, a.addBytes(str.c_str(), str.length())); refstr = "POST"; varstr = a.getMethod(); EXPECT_STREQ(refstr.c_str(), varstr.c_str()); refstr = "/path/script.cgi"; varstr = a.getUri(); EXPECT_STREQ(refstr.c_str(), varstr.c_str()); refstr = ""; varstr = a.getQueryString(); EXPECT_STREQ(refstr.c_str(), varstr.c_str()); refstr = "home=amejia&favorite+flavor=orange\r\n"; varstr = a.getBody(); EXPECT_STREQ(refstr.c_str(), varstr.c_str()); refstr = "application/x-www-form-urlencoded"; varstr = a.getValue("content-type"); EXPECT_STREQ(refstr.c_str(), varstr.c_str()); EXPECT_EQ((unsigned)35, a.getContentLength()); }
/** * ブラウザとのソケットと本来のホストとのソケットを接続するトンネルを作成 */ void YASWebProxy::openTunnel() { QTcpSocket* socket = qobject_cast<QTcpSocket*>(sender()); QByteArray data = socket->readAll(); HttpParser* parser = socket->findChild<HttpParser*>("requestParser"); parser->input(data); QTcpSocket* proxySocket = socket->findChild<QTcpSocket*>("tunnel"); if (!proxySocket) { // 本来のホストへのソケットを作成 proxySocket = new QTcpSocket(socket); proxySocket->setObjectName("tunnel"); proxySocket->connectToHost(parser->url.host(), parser->url.port(80)); connect(proxySocket, SIGNAL(disconnected()), this, SLOT(closeProxySocket())); connect(proxySocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(closeProxySocket())); connect(proxySocket, SIGNAL(readyRead()), this, SLOT(forwardResponse())); if (parser->method == "CONNECT") { disconnect(socket, SIGNAL(readyRead()), this, SLOT(openTunnel())); connect(socket, SIGNAL(readyRead()), this, SLOT(forwardRequest())); } else { HttpParser* resParser = new HttpParser(HttpParser::RESPONSE, proxySocket); resParser->setObjectName("responseParser"); resParser->setProperty("url", parser->url.toString()); connect(resParser, SIGNAL(completeMessage(QByteArray)), this, SLOT(onResponse(QByteArray))); } } if (proxySocket->waitForConnected()) { if (parser->method == "CONNECT") { socket->write("HTTP/1.0 200 Connection established\r\n\r\n"); } else { proxySocket->write(parser->dequeueData()); } } else { proxySocket->disconnect(); } }
bool CWebSocketV8::Handshake(const char* data, size_t length, std::string &response) { string strHeader(data, length); const char *value; HttpParser header; if (header.addBytes(data, length) != HttpParser::Done) { CLog::Log(LOGINFO, "WebSocket [hybi-10]: incomplete handshake received"); return false; } // The request must be GET value = header.getMethod(); if (value == NULL || strnicmp(value, WS_HTTP_METHOD, strlen(WS_HTTP_METHOD)) != 0) { CLog::Log(LOGINFO, "WebSocket [hybi-10]: invalid HTTP method received (GET expected)"); return false; } // The request must be HTTP/1.1 or higher int pos; if ((pos = strHeader.find(WS_HTTP_TAG)) == string::npos) { CLog::Log(LOGINFO, "WebSocket [hybi-10]: invalid handshake received"); return false; } pos += strlen(WS_HTTP_TAG); istringstream converter(strHeader.substr(pos, strHeader.find_first_of(" \r\n\t", pos) - pos)); float fVersion; converter >> fVersion; if (fVersion < 1.1f) { CLog::Log(LOGINFO, "WebSocket [hybi-10]: invalid HTTP version %f (1.1 or higher expected)", fVersion); return false; } string websocketKey, websocketProtocol; // There must be a "Host" header value = header.getValue("host"); if (value == NULL || strlen(value) == 0) { CLog::Log(LOGINFO, "WebSocket [hybi-10]: \"Host\" header missing"); return true; } // There must be a base64 encoded 16 byte (=> 24 byte as base64) "Sec-WebSocket-Key" header value = header.getValue(WS_HEADER_KEY_LC); if (value == NULL || (websocketKey = value).size() != 24) { CLog::Log(LOGINFO, "WebSocket [hybi-10]: invalid \"Sec-WebSocket-Key\" received"); return true; } // There might be a "Sec-WebSocket-Protocol" header value = header.getValue(WS_HEADER_PROTOCOL_LC); if (value && strlen(value) > 0) { CStdStringArray protocols; StringUtils::SplitString(value, ",", protocols); for (unsigned int index = 0; index < protocols.size(); index++) { if (protocols.at(index).Trim().Equals(WS_PROTOCOL_JSONRPC)) { websocketProtocol = WS_PROTOCOL_JSONRPC; break; } } } CHttpResponse httpResponse(HTTP::Get, HTTP::SwitchingProtocols, HTTP::Version1_1); httpResponse.AddHeader(WS_HEADER_UPGRADE, WS_HEADER_UPGRADE_VALUE); httpResponse.AddHeader(WS_HEADER_CONNECTION, WS_HEADER_UPGRADE); httpResponse.AddHeader(WS_HEADER_ACCEPT, calculateKey(websocketKey)); if (!websocketProtocol.empty()) httpResponse.AddHeader(WS_HEADER_PROTOCOL, websocketProtocol); char *responseBuffer; int responseLength = httpResponse.Create(responseBuffer); response = std::string(responseBuffer, responseLength); m_state = WebSocketStateConnected; return true; }
void YASWebProxy::onResponse(QByteArray body) { HttpParser* resParser = qobject_cast<HttpParser*>(sender()); QUrl url = QUrl(resParser->property("url").toString()); emit apiResponse(url, body); }