Several stability improvements and optimizations for HTTP handling and parsing (also, should fix HTTP Progressive under Windows - again).
This commit is contained in:
parent
682ecd2a0e
commit
a08f8e3033
4 changed files with 203 additions and 250 deletions
|
@ -20,13 +20,6 @@ void HTTP::Parser::Clean(){
|
||||||
vars.clear();
|
vars.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Re-initializes the HTTP::Parser, leaving the internal data buffer alone, then tries to parse a new request or response.
|
|
||||||
/// Does the same as HTTP::Parser::Clean(), then returns HTTP::Parser::parse().
|
|
||||||
bool HTTP::Parser::CleanForNext(){
|
|
||||||
Clean();
|
|
||||||
return parse();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a string containing a valid HTTP 1.0 or 1.1 request, ready for sending.
|
/// Returns a string containing a valid HTTP 1.0 or 1.1 request, ready for sending.
|
||||||
/// The request is build from internal variables set before this call is made.
|
/// The request is build from internal variables set before this call is made.
|
||||||
/// To be precise, method, url, protocol, headers and body are used.
|
/// To be precise, method, url, protocol, headers and body are used.
|
||||||
|
@ -115,34 +108,20 @@ void HTTP::Parser::SetVar(std::string i, std::string v){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempt to read a whole HTTP request or response from Socket::Connection.
|
/// Attempt to read a whole HTTP request or response from a std::string buffer.
|
||||||
/// \param sock The socket to use.
|
/// If a whole request could be read, it is removed from the front of the given buffer.
|
||||||
/// \param nonblock When true, will not block even if the socket is blocking.
|
/// \param strbuf The buffer to read from.
|
||||||
/// \return True of a whole request or response was read, false otherwise.
|
/// \return True if a whole request or response was read, false otherwise.
|
||||||
bool HTTP::Parser::Read(Socket::Connection & sock, bool nonblock){
|
bool HTTP::Parser::Read(std::string & strbuf){
|
||||||
if (nonblock && (sock.ready() < 1)){return parse();}
|
return parse(strbuf);
|
||||||
sock.read(HTTPbuffer);
|
}//HTTPReader::Read
|
||||||
return parse();
|
|
||||||
}//HTTPReader::ReadSocket
|
|
||||||
|
|
||||||
/// Reads a full set of HTTP responses/requests from file F.
|
/// Attempt to read a whole HTTP response or request from a data buffer.
|
||||||
/// \return Always false. Use HTTP::Parser::CleanForNext() to parse the contents of the file.
|
|
||||||
bool HTTP::Parser::Read(FILE * F){
|
|
||||||
//returned true als hele http packet gelezen is
|
|
||||||
int b = 1;
|
|
||||||
char buffer[500];
|
|
||||||
while (b > 0){
|
|
||||||
b = fread(buffer, 1, 500, F);
|
|
||||||
HTTPbuffer.append(buffer, b);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}//HTTPReader::ReadSocket
|
|
||||||
|
|
||||||
/// Attempt to read a whole HTTP response or request from the internal data buffer.
|
|
||||||
/// If succesful, fills its own fields with the proper data and removes the response/request
|
/// If succesful, fills its own fields with the proper data and removes the response/request
|
||||||
/// from the internal data buffer.
|
/// from the data buffer.
|
||||||
|
/// \param HTTPbuffer The data buffer to read from.
|
||||||
/// \return True on success, false otherwise.
|
/// \return True on success, false otherwise.
|
||||||
bool HTTP::Parser::parse(){
|
bool HTTP::Parser::parse(std::string & HTTPbuffer){
|
||||||
size_t f;
|
size_t f;
|
||||||
std::string tmpA, tmpB, tmpC;
|
std::string tmpA, tmpB, tmpC;
|
||||||
while (HTTPbuffer != ""){
|
while (HTTPbuffer != ""){
|
||||||
|
@ -194,16 +173,6 @@ bool HTTP::Parser::parse(){
|
||||||
return false; //we should never get here...
|
return false; //we should never get here...
|
||||||
}//HTTPReader::parse
|
}//HTTPReader::parse
|
||||||
|
|
||||||
/// Sends data as response to conn.
|
|
||||||
/// The response is automatically first build using HTTP::Parser::BuildResponse().
|
|
||||||
/// \param conn The Socket::Connection to send the response over.
|
|
||||||
/// \param code The HTTP response code. Usually you want 200.
|
|
||||||
/// \param message The HTTP response message. Usually you want "OK".
|
|
||||||
void HTTP::Parser::SendResponse(Socket::Connection & conn, std::string code, std::string message){
|
|
||||||
std::string tmp = BuildResponse(code, message);
|
|
||||||
conn.write(tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
/// Parses GET or POST-style variable data.
|
/// Parses GET or POST-style variable data.
|
||||||
/// Saves to internal variable structure using HTTP::Parser::SetVar.
|
/// Saves to internal variable structure using HTTP::Parser::SetVar.
|
||||||
|
@ -237,31 +206,16 @@ void HTTP::Parser::parseVars(std::string data){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sends data as HTTP/1.1 bodypart to conn.
|
/// Converts a string to chunked format if protocol is HTTP/1.1 - does nothing otherwise.
|
||||||
/// HTTP/1.1 chunked encoding is automatically applied if needed.
|
/// \param bodypart The data to convert - will be converted in-place.
|
||||||
/// \param conn The Socket::Connection to send the part over.
|
void HTTP::Parser::Chunkify(std::string & bodypart){
|
||||||
/// \param buffer The buffer to send.
|
|
||||||
/// \param len The length of the buffer.
|
|
||||||
void HTTP::Parser::SendBodyPart(Socket::Connection & conn, char * buffer, int len){
|
|
||||||
std::string tmp;
|
|
||||||
tmp.append(buffer, len);
|
|
||||||
SendBodyPart(conn, tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sends data as HTTP/1.1 bodypart to conn.
|
|
||||||
/// HTTP/1.1 chunked encoding is automatically applied if needed.
|
|
||||||
/// \param conn The Socket::Connection to send the part over.
|
|
||||||
/// \param bodypart The data to send.
|
|
||||||
void HTTP::Parser::SendBodyPart(Socket::Connection & conn, std::string bodypart){
|
|
||||||
if (protocol == "HTTP/1.1"){
|
if (protocol == "HTTP/1.1"){
|
||||||
static char len[10];
|
static char len[10];
|
||||||
int sizelen;
|
int sizelen = snprintf(len, 10, "%x\r\n", (unsigned int)bodypart.size());
|
||||||
sizelen = snprintf(len, 10, "%x\r\n", (unsigned int)bodypart.size());
|
//prepend the chunk size and \r\n
|
||||||
conn.write(len, sizelen);
|
bodypart.insert(0, len, sizelen);
|
||||||
conn.write(bodypart);
|
//append \r\n
|
||||||
conn.write(len+sizelen-2, 2);
|
bodypart.append("\r\n", 2);
|
||||||
}else{
|
|
||||||
conn.write(bodypart);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "socket.h"
|
|
||||||
|
|
||||||
/// Holds all HTTP processing related code.
|
/// Holds all HTTP processing related code.
|
||||||
namespace HTTP{
|
namespace HTTP{
|
||||||
|
@ -14,8 +13,7 @@ namespace HTTP{
|
||||||
class Parser{
|
class Parser{
|
||||||
public:
|
public:
|
||||||
Parser();
|
Parser();
|
||||||
bool Read(Socket::Connection & sock, bool nonblock = true);
|
bool Read(std::string & strbuf);
|
||||||
bool Read(FILE * F);
|
|
||||||
std::string GetHeader(std::string i);
|
std::string GetHeader(std::string i);
|
||||||
std::string GetVar(std::string i);
|
std::string GetVar(std::string i);
|
||||||
void SetHeader(std::string i, std::string v);
|
void SetHeader(std::string i, std::string v);
|
||||||
|
@ -25,11 +23,8 @@ namespace HTTP{
|
||||||
void SetBody(char * buffer, int len);
|
void SetBody(char * buffer, int len);
|
||||||
std::string BuildRequest();
|
std::string BuildRequest();
|
||||||
std::string BuildResponse(std::string code, std::string message);
|
std::string BuildResponse(std::string code, std::string message);
|
||||||
void SendResponse(Socket::Connection & conn, std::string code, std::string message);
|
void Chunkify(std::string & bodypart);
|
||||||
void SendBodyPart(Socket::Connection & conn, char * buffer, int len);
|
|
||||||
void SendBodyPart(Socket::Connection & conn, std::string bodypart);
|
|
||||||
void Clean();
|
void Clean();
|
||||||
bool CleanForNext();
|
|
||||||
static std::string urlunescape(const std::string & in);
|
static std::string urlunescape(const std::string & in);
|
||||||
static std::string urlencode(const std::string & in);
|
static std::string urlencode(const std::string & in);
|
||||||
std::string body;
|
std::string body;
|
||||||
|
@ -40,9 +35,9 @@ namespace HTTP{
|
||||||
private:
|
private:
|
||||||
bool seenHeaders;
|
bool seenHeaders;
|
||||||
bool seenReq;
|
bool seenReq;
|
||||||
bool parse();
|
bool parse(std::string & HTTPbuffer);
|
||||||
void parseVars(std::string data);
|
void parseVars(std::string data);
|
||||||
std::string HTTPbuffer;
|
std::string read_buffer;
|
||||||
std::map<std::string, std::string> headers;
|
std::map<std::string, std::string> headers;
|
||||||
std::map<std::string, std::string> vars;
|
std::map<std::string, std::string> vars;
|
||||||
void Trim(std::string & s);
|
void Trim(std::string & s);
|
||||||
|
|
|
@ -32,6 +32,7 @@ namespace Connector_HTTP{
|
||||||
|
|
||||||
/// Returns AMF-format metadata for Adobe HTTP Dynamic Streaming.
|
/// Returns AMF-format metadata for Adobe HTTP Dynamic Streaming.
|
||||||
std::string GetMetaData( ) {
|
std::string GetMetaData( ) {
|
||||||
|
/// \todo Make this actually do what it should - even though it seems to be ignored completely by all media players.
|
||||||
AMF::Object amfreply("container", AMF::AMF0_DDV_CONTAINER);
|
AMF::Object amfreply("container", AMF::AMF0_DDV_CONTAINER);
|
||||||
amfreply.addContent(AMF::Object("onMetaData",AMF::AMF0_STRING));
|
amfreply.addContent(AMF::Object("onMetaData",AMF::AMF0_STRING));
|
||||||
amfreply.addContent(AMF::Object("",AMF::AMF0_ECMA_ARRAY));
|
amfreply.addContent(AMF::Object("",AMF::AMF0_ECMA_ARRAY));
|
||||||
|
@ -95,31 +96,32 @@ namespace Connector_HTTP{
|
||||||
void Progressive(FLV::Tag & tag, HTTP::Parser HTTP_S, Socket::Connection & conn, DTSC::Stream & Strm){
|
void Progressive(FLV::Tag & tag, HTTP::Parser HTTP_S, Socket::Connection & conn, DTSC::Stream & Strm){
|
||||||
static bool progressive_has_sent_header = false;
|
static bool progressive_has_sent_header = false;
|
||||||
if (!progressive_has_sent_header){
|
if (!progressive_has_sent_header){
|
||||||
HTTP_S.Clean();//troep opruimen die misschien aanwezig is...
|
HTTP_S.Clean();//make sure no parts of old requests are left in any buffers
|
||||||
HTTP_S.SetHeader("Content-Type", "video/x-flv");//FLV files hebben altijd dit content-type.
|
HTTP_S.SetHeader("Content-Type", "video/x-flv");//Send the correct content-type for FLV files
|
||||||
//HTTP_S.SetHeader("Transfer-Encoding", "chunked");
|
//HTTP_S.SetHeader("Transfer-Encoding", "chunked");
|
||||||
HTTP_S.protocol = "HTTP/1.0";
|
HTTP_S.protocol = "HTTP/1.0";
|
||||||
HTTP_S.SendResponse(conn, "200", "OK");//geen SetBody = unknown length! Dat willen we hier.
|
conn.Send(HTTP_S.BuildResponse("200", "OK"));//no SetBody = unknown length - this is intentional, we will stream the entire file
|
||||||
//HTTP_S.SendBodyPart(CONN_fd, FLVHeader, 13);//schrijf de FLV header
|
conn.Send(std::string(FLV::Header, 13));//write FLV header
|
||||||
conn.write(FLV::Header, 13);
|
|
||||||
static FLV::Tag tmp;
|
static FLV::Tag tmp;
|
||||||
|
//write metadata
|
||||||
tmp.DTSCMetaInit(Strm);
|
tmp.DTSCMetaInit(Strm);
|
||||||
conn.write(tmp.data, tmp.len);
|
conn.Send(std::string(tmp.data, tmp.len));
|
||||||
|
//write video init data, if needed
|
||||||
if (Strm.metadata.getContentP("video") && Strm.metadata.getContentP("video")->getContentP("init")){
|
if (Strm.metadata.getContentP("video") && Strm.metadata.getContentP("video")->getContentP("init")){
|
||||||
tmp.DTSCVideoInit(Strm);
|
tmp.DTSCVideoInit(Strm);
|
||||||
conn.write(tmp.data, tmp.len);
|
conn.Send(std::string(tmp.data, tmp.len));
|
||||||
}
|
}
|
||||||
|
//write audio init data, if needed
|
||||||
if (Strm.metadata.getContentP("audio") && Strm.metadata.getContentP("audio")->getContentP("init")){
|
if (Strm.metadata.getContentP("audio") && Strm.metadata.getContentP("audio")->getContentP("init")){
|
||||||
tmp.DTSCAudioInit(Strm);
|
tmp.DTSCAudioInit(Strm);
|
||||||
conn.write(tmp.data, tmp.len);
|
conn.Send(std::string(tmp.data, tmp.len));
|
||||||
}
|
}
|
||||||
progressive_has_sent_header = true;
|
progressive_has_sent_header = true;
|
||||||
#if DEBUG >= 1
|
#if DEBUG >= 1
|
||||||
fprintf(stderr, "Sent progressive FLV header\n");
|
fprintf(stderr, "Sent progressive FLV header\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
//HTTP_S.SendBodyPart(CONN_fd, tag->data, tag->len);//schrijf deze FLV tag onbewerkt weg
|
conn.Send(std::string(tag.data, tag.len));//write the tag contents
|
||||||
conn.write(tag.data, tag.len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles Flash Dynamic HTTP streaming requests
|
/// Handles Flash Dynamic HTTP streaming requests
|
||||||
|
@ -129,6 +131,9 @@ namespace Connector_HTTP{
|
||||||
if (Strm.getPacket(0).getContentP("keyframe")){
|
if (Strm.getPacket(0).getContentP("keyframe")){
|
||||||
if (FlashBuf != ""){
|
if (FlashBuf != ""){
|
||||||
Flash_FragBuffer.push(FlashBuf);
|
Flash_FragBuffer.push(FlashBuf);
|
||||||
|
while (Flash_FragBuffer.size() > 2){
|
||||||
|
Flash_FragBuffer.pop();
|
||||||
|
}
|
||||||
#if DEBUG >= 4
|
#if DEBUG >= 4
|
||||||
fprintf(stderr, "Received a fragment. Now %i in buffer.\n", (int)Flash_FragBuffer.size());
|
fprintf(stderr, "Received a fragment. Now %i in buffer.\n", (int)Flash_FragBuffer.size());
|
||||||
#endif
|
#endif
|
||||||
|
@ -165,11 +170,12 @@ namespace Connector_HTTP{
|
||||||
int temp;
|
int temp;
|
||||||
int Flash_RequestPending = 0;
|
int Flash_RequestPending = 0;
|
||||||
unsigned int lastStats = 0;
|
unsigned int lastStats = 0;
|
||||||
//int CurrentFragment = -1; later herbruiken?
|
conn.setBlocking(false);//do not block on conn.spool() when no data is available
|
||||||
|
|
||||||
while (conn.connected()){
|
while (conn.connected()){
|
||||||
//only parse input if available or not yet init'ed
|
//only parse input if available or not yet init'ed
|
||||||
if (HTTP_R.Read(conn, ready4data)){
|
if (conn.spool()){
|
||||||
|
if (HTTP_R.Read(conn.Received())){
|
||||||
handler = HANDLER_PROGRESSIVE;
|
handler = HANDLER_PROGRESSIVE;
|
||||||
#if DEBUG >= 4
|
#if DEBUG >= 4
|
||||||
std::cout << "Received request: " << HTTP_R.url << std::endl;
|
std::cout << "Received request: " << HTTP_R.url << std::endl;
|
||||||
|
@ -181,7 +187,7 @@ namespace Connector_HTTP{
|
||||||
HTTP_S.Clean();
|
HTTP_S.Clean();
|
||||||
HTTP_S.SetHeader("Content-Type", "text/xml");
|
HTTP_S.SetHeader("Content-Type", "text/xml");
|
||||||
HTTP_S.SetBody("<?xml version=\"1.0\"?><!DOCTYPE cross-domain-policy SYSTEM \"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd\"><cross-domain-policy><allow-access-from domain=\"*\" /><site-control permitted-cross-domain-policies=\"all\"/></cross-domain-policy>");
|
HTTP_S.SetBody("<?xml version=\"1.0\"?><!DOCTYPE cross-domain-policy SYSTEM \"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd\"><cross-domain-policy><allow-access-from domain=\"*\" /><site-control permitted-cross-domain-policies=\"all\"/></cross-domain-policy>");
|
||||||
HTTP_S.SendResponse(conn, "200", "OK");
|
conn.Send(HTTP_S.BuildResponse("200", "OK"));
|
||||||
#if DEBUG >= 3
|
#if DEBUG >= 3
|
||||||
printf("Sending crossdomain.xml file\n");
|
printf("Sending crossdomain.xml file\n");
|
||||||
#endif
|
#endif
|
||||||
|
@ -203,7 +209,7 @@ namespace Connector_HTTP{
|
||||||
}
|
}
|
||||||
response += "";
|
response += "";
|
||||||
HTTP_S.SetBody(response);
|
HTTP_S.SetBody(response);
|
||||||
HTTP_S.SendResponse(conn, "200", "OK");
|
conn.Send(HTTP_S.BuildResponse("200", "OK"));
|
||||||
#if DEBUG >= 3
|
#if DEBUG >= 3
|
||||||
printf("Sending embed code for %s\n", streamname.c_str());
|
printf("Sending embed code for %s\n", streamname.c_str());
|
||||||
#endif
|
#endif
|
||||||
|
@ -233,7 +239,7 @@ namespace Connector_HTTP{
|
||||||
printf("Manifest: %s\n", manifest.c_str());
|
printf("Manifest: %s\n", manifest.c_str());
|
||||||
#endif
|
#endif
|
||||||
HTTP_S.SetBody(manifest);
|
HTTP_S.SetBody(manifest);
|
||||||
HTTP_S.SendResponse(conn, "200", "OK");
|
conn.Send(HTTP_S.BuildResponse("200", "OK"));
|
||||||
#if DEBUG >= 3
|
#if DEBUG >= 3
|
||||||
printf("Sent manifest\n");
|
printf("Sent manifest\n");
|
||||||
#endif
|
#endif
|
||||||
|
@ -254,7 +260,12 @@ namespace Connector_HTTP{
|
||||||
printf( "Opening progressive stream: %s\n", streamname.c_str());
|
printf( "Opening progressive stream: %s\n", streamname.c_str());
|
||||||
#endif
|
#endif
|
||||||
}//PROGRESSIVE handler
|
}//PROGRESSIVE handler
|
||||||
HTTP_R.CleanForNext(); //clean for any possinble next requests
|
HTTP_R.Clean(); //clean for any possinble next requests
|
||||||
|
}else{
|
||||||
|
#if DEBUG >= 3
|
||||||
|
fprintf(stderr, "Could not parse the following:\n%s\n", conn.Received().c_str());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (ready4data){
|
if (ready4data){
|
||||||
if (!inited){
|
if (!inited){
|
||||||
|
@ -277,22 +288,18 @@ namespace Connector_HTTP{
|
||||||
HTTP_S.SetHeader("Content-Type","video/mp4");
|
HTTP_S.SetHeader("Content-Type","video/mp4");
|
||||||
HTTP_S.SetBody(MP4::mdatFold(Flash_FragBuffer.front()));
|
HTTP_S.SetBody(MP4::mdatFold(Flash_FragBuffer.front()));
|
||||||
Flash_FragBuffer.pop();
|
Flash_FragBuffer.pop();
|
||||||
HTTP_S.SendResponse(conn, "200", "OK");//schrijf de HTTP response header
|
conn.Send(HTTP_S.BuildResponse("200", "OK"));
|
||||||
Flash_RequestPending--;
|
Flash_RequestPending--;
|
||||||
#if DEBUG >= 3
|
#if DEBUG >= 3
|
||||||
fprintf(stderr, "Sending a video fragment. %i left in buffer, %i requested\n", (int)Flash_FragBuffer.size(), Flash_RequestPending);
|
fprintf(stderr, "Sending a video fragment. %i left in buffer, %i requested\n", (int)Flash_FragBuffer.size(), Flash_RequestPending);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (inited){
|
|
||||||
unsigned int now = time(0);
|
unsigned int now = time(0);
|
||||||
if (now != lastStats){
|
if (now != lastStats){
|
||||||
lastStats = now;
|
lastStats = now;
|
||||||
std::string stat = "S "+conn.getStats("HTTP");
|
ss.Send("S "+conn.getStats("HTTP"));
|
||||||
ss.write(stat);
|
|
||||||
}
|
}
|
||||||
}
|
if (ss.spool() || ss.Received() != ""){
|
||||||
if (ss.canRead()){
|
|
||||||
ss.spool();
|
|
||||||
if (Strm.parsePacket(ss.Received())){
|
if (Strm.parsePacket(ss.Received())){
|
||||||
tag.DTSCLoader(Strm);
|
tag.DTSCLoader(Strm);
|
||||||
if (handler == HANDLER_FLASH){
|
if (handler == HANDLER_FLASH){
|
||||||
|
|
|
@ -88,7 +88,6 @@ void WriteFile( std::string Filename, std::string contents ) {
|
||||||
|
|
||||||
class ConnectedUser{
|
class ConnectedUser{
|
||||||
public:
|
public:
|
||||||
std::string writebuffer;
|
|
||||||
Socket::Connection C;
|
Socket::Connection C;
|
||||||
HTTP::Parser H;
|
HTTP::Parser H;
|
||||||
bool Authorized;
|
bool Authorized;
|
||||||
|
@ -439,7 +438,7 @@ int main(int argc, char ** argv){
|
||||||
uplink->H.Clean();
|
uplink->H.Clean();
|
||||||
uplink->H.SetBody("command="+HTTP::Parser::urlencode(Response.toString()));
|
uplink->H.SetBody("command="+HTTP::Parser::urlencode(Response.toString()));
|
||||||
uplink->H.BuildRequest();
|
uplink->H.BuildRequest();
|
||||||
uplink->writebuffer += uplink->H.BuildResponse("200", "OK");
|
uplink->C.Send(uplink->H.BuildResponse("200", "OK"));
|
||||||
uplink->H.Clean();
|
uplink->H.Clean();
|
||||||
//Log("UPLK", "Sending server data to uplink.");
|
//Log("UPLK", "Sending server data to uplink.");
|
||||||
}else{
|
}else{
|
||||||
|
@ -459,8 +458,7 @@ int main(int argc, char ** argv){
|
||||||
buffers.erase(it);
|
buffers.erase(it);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
it->spool();
|
if (it->spool()){
|
||||||
if (it->Received() != ""){
|
|
||||||
size_t newlines = it->Received().find("\n\n");
|
size_t newlines = it->Received().find("\n\n");
|
||||||
while (newlines != std::string::npos){
|
while (newlines != std::string::npos){
|
||||||
Request = it->Received().substr(0, newlines);
|
Request = it->Received().substr(0, newlines);
|
||||||
|
@ -489,10 +487,8 @@ int main(int argc, char ** argv){
|
||||||
users.erase(it);
|
users.erase(it);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (it->writebuffer != ""){
|
if (it->C.spool()){
|
||||||
it->C.iwrite(it->writebuffer);
|
if (it->H.Read(it->C.Received())){
|
||||||
}
|
|
||||||
if (it->H.Read(it->C)){
|
|
||||||
Response.null(); //make sure no data leaks from previous requests
|
Response.null(); //make sure no data leaks from previous requests
|
||||||
if (it->clientMode){
|
if (it->clientMode){
|
||||||
// In clientMode, requests are reversed. These are connections we initiated to GearBox.
|
// In clientMode, requests are reversed. These are connections we initiated to GearBox.
|
||||||
|
@ -516,7 +512,7 @@ int main(int argc, char ** argv){
|
||||||
it->H.Clean();
|
it->H.Clean();
|
||||||
it->H.SetBody("command="+HTTP::Parser::urlencode(Response.toString()));
|
it->H.SetBody("command="+HTTP::Parser::urlencode(Response.toString()));
|
||||||
it->H.BuildRequest();
|
it->H.BuildRequest();
|
||||||
it->writebuffer += it->H.BuildResponse("200", "OK");
|
it->C.Send(it->H.BuildResponse("200", "OK"));
|
||||||
it->H.Clean();
|
it->H.Clean();
|
||||||
Log("UPLK", "Attempting login to uplink.");
|
Log("UPLK", "Attempting login to uplink.");
|
||||||
}
|
}
|
||||||
|
@ -566,13 +562,14 @@ int main(int argc, char ** argv){
|
||||||
}else{
|
}else{
|
||||||
it->H.SetBody(jsonp+"("+Response.toString()+");\n\n");
|
it->H.SetBody(jsonp+"("+Response.toString()+");\n\n");
|
||||||
}
|
}
|
||||||
it->writebuffer += it->H.BuildResponse("200", "OK");
|
it->C.Send(it->H.BuildResponse("200", "OK"));
|
||||||
it->H.Clean();
|
it->H.Clean();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Log("CONF", "Controller shutting down");
|
Log("CONF", "Controller shutting down");
|
||||||
Util::Procs::StopAll();
|
Util::Procs::StopAll();
|
||||||
WriteFile("config.json", Storage.toString());
|
WriteFile("config.json", Storage.toString());
|
||||||
|
|
Loading…
Add table
Reference in a new issue