166 lines
5.0 KiB
C++
166 lines
5.0 KiB
C++
#include "TessesFramework/Http/HttpStream.hpp"
|
|
#include "TessesFramework/TextStreams/StreamWriter.hpp"
|
|
#include "TessesFramework/TextStreams/StreamReader.hpp"
|
|
#include <sstream>
|
|
#include <iostream>
|
|
using StreamWriter = Tesses::Framework::TextStreams::StreamWriter;
|
|
using StreamReader = Tesses::Framework::TextStreams::StreamReader;
|
|
namespace Tesses::Framework::Http
|
|
{
|
|
HttpStream::HttpStream(Tesses::Framework::Streams::Stream* strm, bool owns, int64_t length, bool recv, bool http1_1)
|
|
{
|
|
this->strm = strm;
|
|
this->owns = owns;
|
|
this->length = length;
|
|
this->recv = recv;
|
|
this->http1_1 = http1_1;
|
|
this->offset = 0;
|
|
this->read = 0;
|
|
this->position = 0;
|
|
this->done=false;
|
|
}
|
|
HttpStream::HttpStream(Tesses::Framework::Streams::Stream& strm, int64_t length, bool recv,bool http1_1) : HttpStream(&strm,false,length,recv,http1_1)
|
|
{
|
|
|
|
}
|
|
bool HttpStream::CanRead()
|
|
{
|
|
if(this->done) return false;
|
|
if(!this->recv) return false;
|
|
if(this->offset < this->read) return true;
|
|
return this->strm->CanRead();
|
|
}
|
|
bool HttpStream::CanWrite()
|
|
{
|
|
if(this->recv) return false;
|
|
return this->strm->CanWrite();
|
|
}
|
|
bool HttpStream::EndOfStream()
|
|
{
|
|
if(this->done) return true;
|
|
if(!this->recv) return true;
|
|
if(this->offset < this->read) return false;
|
|
return this->strm->EndOfStream();
|
|
}
|
|
int64_t HttpStream::GetLength()
|
|
{
|
|
return this->length;
|
|
}
|
|
int64_t HttpStream::GetPosition()
|
|
{
|
|
return this->position;
|
|
}
|
|
size_t HttpStream::Read(uint8_t* buff, size_t len)
|
|
{
|
|
if(this->done) return 0;
|
|
if(!this->recv) return 0;
|
|
if(this->length == 0) return 0;
|
|
if(this->length > 0)
|
|
{
|
|
len = std::min((size_t)(this->length - this->position), len);
|
|
if(len > 0)
|
|
len = this->strm->Read(buff,len);
|
|
this->position += len;
|
|
return len;
|
|
}
|
|
else
|
|
{
|
|
if(this->http1_1)
|
|
{
|
|
if(this->offset < this->read)
|
|
{
|
|
len = std::min((size_t)(this->read - this->offset), len);
|
|
if(len > 0)
|
|
len = this->strm->Read(buff,len);
|
|
this->offset += len;
|
|
this->position += len;
|
|
if(this->offset >= this->read)
|
|
{
|
|
StreamReader reader(this->strm, false);
|
|
reader.ReadLine();
|
|
}
|
|
return len;
|
|
}
|
|
else
|
|
{
|
|
StreamReader reader(this->strm, false);
|
|
std::string line = reader.ReadLine();
|
|
if(!line.empty())
|
|
{
|
|
this->read = std::stoull(line, NULL, 16);
|
|
|
|
|
|
if(this->read == 0)
|
|
{
|
|
reader.ReadLine();
|
|
this->done=true;
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
this->offset=0;
|
|
|
|
len = std::min((size_t)(this->read - this->offset), len);
|
|
if(len > 0)
|
|
len = this->strm->Read(buff,len);
|
|
this->offset += len;
|
|
this->position += len;
|
|
return len;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
return this->strm->Read(buff,len);
|
|
}
|
|
}
|
|
}
|
|
size_t HttpStream::Write(const uint8_t* buff, size_t len)
|
|
{
|
|
if(this->recv) return 0;
|
|
if(this->length == 0) return 0;
|
|
if(this->length > 0)
|
|
{
|
|
len = std::min((size_t)(this->length - this->position), len);
|
|
if(len > 0)
|
|
len = this->strm->Write(buff,len);
|
|
this->position += len;
|
|
return len;
|
|
}
|
|
else
|
|
{
|
|
if(this->http1_1)
|
|
{
|
|
std::stringstream strm;
|
|
strm << std::hex << len;
|
|
|
|
StreamWriter writer(this->strm,false);
|
|
writer.newline = "\r\n";
|
|
writer.WriteLine(strm.str());
|
|
|
|
this->strm->WriteBlock(buff, len);
|
|
|
|
writer.WriteLine();
|
|
return len;
|
|
}
|
|
else
|
|
{
|
|
return this->strm->Write(buff,len);
|
|
}
|
|
}
|
|
}
|
|
HttpStream::~HttpStream()
|
|
{
|
|
if(this->length == -1 && this->http1_1)
|
|
{
|
|
StreamWriter writer(this->strm,false);
|
|
writer.newline = "\r\n";
|
|
writer.WriteLine("0");
|
|
writer.WriteLine();
|
|
}
|
|
if(this->owns) delete this->strm;
|
|
}
|
|
} |