diff --git a/lib/dtscmeta.cpp b/lib/dtscmeta.cpp index e73c67d0..30687135 100644 --- a/lib/dtscmeta.cpp +++ b/lib/dtscmeta.cpp @@ -336,7 +336,7 @@ namespace DTSC { /// Returns a DTSC::Scan instance to the contents of this packet. /// May return an invalid instance if this packet is invalid. Scan Packet::getScan() const { - if (!this || !getDataLen() || !getPayloadLen() || getDataLen() <= getPayloadLen()){ + if (!*this || !getDataLen() || !getPayloadLen() || getDataLen() <= getPayloadLen()){ return Scan(); } return Scan(data + (getDataLen() - getPayloadLen()), getPayloadLen()); diff --git a/lib/ftp.cpp b/lib/ftp.cpp index 8e7eb004..96ebe17c 100644 --- a/lib/ftp.cpp +++ b/lib/ftp.cpp @@ -160,15 +160,15 @@ int FTP::User::ParseCommand(std::string Command) { case CMD_LIST: { Socket::Connection Connected = Passive.accept(); if (Connected.connected()) { - Conn.Send("125 Data connection already open; transfer starting.\n"); + Conn.SendNow("125 Data connection already open; transfer starting.\n"); } else { - Conn.Send("150 File status okay; about to open data connection.\n"); + Conn.SendNow("150 File status okay; about to open data connection.\n"); } while (!Connected.connected()) { Connected = Passive.accept(); } std::string tmpstr = MyDir.LIST(ActiveStreams); - Connected.Send(tmpstr); + Connected.SendNow(tmpstr); Connected.close(); return 226; break; @@ -218,15 +218,15 @@ int FTP::User::ParseCommand(std::string Command) { } //Access denied. Socket::Connection Connected = Passive.accept(); if (Connected.connected()) { - Conn.Send("125 Data connection already open; transfer starting.\n"); + Conn.SendNow("125 Data connection already open; transfer starting.\n"); } else { - Conn.Send("150 File status okay; about to open data connection.\n"); + Conn.SendNow("150 File status okay; about to open data connection.\n"); } while (!Connected.connected()) { Connected = Passive.accept(); } std::string tmpstr = MyDir.RETR(Command); - Connected.Send(tmpstr); + Connected.SendNow(tmpstr); Connected.close(); return 226; break; @@ -243,9 +243,9 @@ int FTP::User::ParseCommand(std::string Command) { } //Access denied. Socket::Connection Connected = Passive.accept(); if (Connected.connected()) { - Conn.Send("125 Data connection already open; transfer starting.\n"); + Conn.SendNow("125 Data connection already open; transfer starting.\n"); } else { - Conn.Send("150 File status okay; about to open data connection.\n"); + Conn.SendNow("150 File status okay; about to open data connection.\n"); } while (!Connected.connected()) { Connected = Passive.accept(); diff --git a/lib/http_parser.cpp b/lib/http_parser.cpp index a4f233d6..2ceda241 100644 --- a/lib/http_parser.cpp +++ b/lib/http_parser.cpp @@ -545,19 +545,24 @@ void HTTP::Parser::Chunkify(std::string & bodypart, Socket::Connection & conn) { /// \param size The size of the data to send. /// \param conn The connection to use for sending. void HTTP::Parser::Chunkify(const char * data, unsigned int size, Socket::Connection & conn) { + static char hexa[] = "0123456789abcdef"; if (protocol == "HTTP/1.1") { - char len[10]; - int sizelen = snprintf(len, 10, "%x\r\n", size); //prepend the chunk size and \r\n - conn.SendNow(len, sizelen); + if (!size){ + conn.SendNow("0\r\n\r\n\r\n", 7); + } + size_t offset = 8; + unsigned int t_size = size; + char len[] = "\000\000\000\000\000\000\0000\r\n"; + while (t_size && offset < 9){ + len[--offset] = hexa[t_size & 0xf]; + t_size >>= 4; + } + conn.SendNow(len+offset, 10-offset); //send the chunk itself conn.SendNow(data, size); //append \r\n conn.SendNow("\r\n", 2); - if (!size) { - //append \r\n again if this was the end of the file (required by chunked transfer encoding according to spec) - conn.SendNow("\r\n", 2); - } } else { //just send the chunk itself conn.SendNow(data, size); diff --git a/lib/socket.cpp b/lib/socket.cpp index f4a08097..dab7d591 100644 --- a/lib/socket.cpp +++ b/lib/socket.cpp @@ -413,12 +413,9 @@ std::string Socket::Connection::getStats(std::string C) { return "S " + getHost() + " " + C + " " + uint2string(Util::epoch() - conntime) + " " + uint2string(up) + " " + uint2string(down) + "\n"; } -/// Updates the downbuffer and upbuffer internal variables. +/// Updates the downbuffer internal variable. /// Returns true if new data was received, false otherwise. bool Socket::Connection::spool() { - if (upbuffer.size() > 0) { - iwrite(upbuffer.get()); - } /// \todo Provide better mechanism to prevent overbuffering. if (downbuffer.size() > 10000) { return true; @@ -433,43 +430,18 @@ bool Socket::Connection::peek() { return iread(downbuffer, MSG_PEEK); } -/// Updates the downbuffer and upbuffer internal variables until upbuffer is empty. -/// Returns true if new data was received, false otherwise. -bool Socket::Connection::flush() { - bool bing = isBlocking(); - if (!bing) { - setBlocking(true); - } - while (upbuffer.size() > 0 && connected()) { - iwrite(upbuffer.get()); - } - if (!bing) { - setBlocking(false); - } - /// \todo Provide better mechanism to prevent overbuffering. - if (downbuffer.size() > 1000) { - return true; - } else { - return iread(downbuffer); - } -} - /// Returns a reference to the download buffer. Socket::Buffer & Socket::Connection::Received() { return downbuffer; } /// Will not buffer anything but always send right away. Blocks. -/// This will send the upbuffer (if non-empty) first, then the data. /// Any data that could not be send will block until it can be send or the connection is severed. void Socket::Connection::SendNow(const char * data, size_t len) { bool bing = isBlocking(); if (!bing) { setBlocking(true); } - while (upbuffer.size() > 0 && connected()) { - iwrite(upbuffer.get()); - } unsigned int i = iwrite(data, std::min((long unsigned int)len, 51200ul)); while (i < len && connected()) { i += iwrite(data + i, std::min((long unsigned int)(len - i), 51200ul)); @@ -479,61 +451,19 @@ void Socket::Connection::SendNow(const char * data, size_t len) { } } -/// Appends data to the upbuffer. -/// This will attempt to send the upbuffer (if non-empty) first. -/// If the upbuffer is empty before or after this attempt, it will attempt to send -/// the data right away. Any data that could not be send will be put into the upbuffer. -/// This means this function is blocking if the socket is, but nonblocking otherwise. -void Socket::Connection::Send(const char * data, size_t len) { - while (upbuffer.size() > 0) { - if (!iwrite(upbuffer.get())) { - break; - } - } - if (upbuffer.size() > 0) { - upbuffer.append(data, len); - } else { - unsigned int i = iwrite(data, len); - if (i < len) { - upbuffer.append(data + i, len - i); - } - } -} - /// Will not buffer anything but always send right away. Blocks. -/// This will send the upbuffer (if non-empty) first, then the data. /// Any data that could not be send will block until it can be send or the connection is severed. void Socket::Connection::SendNow(const char * data) { int len = strlen(data); SendNow(data, len); } -/// Appends data to the upbuffer. -/// This will attempt to send the upbuffer (if non-empty) first. -/// If the upbuffer is empty before or after this attempt, it will attempt to send -/// the data right away. Any data that could not be send will be put into the upbuffer. -/// This means this function is blocking if the socket is, but nonblocking otherwise. -void Socket::Connection::Send(const char * data) { - int len = strlen(data); - Send(data, len); -} - /// Will not buffer anything but always send right away. Blocks. -/// This will send the upbuffer (if non-empty) first, then the data. /// Any data that could not be send will block until it can be send or the connection is severed. void Socket::Connection::SendNow(const std::string & data) { SendNow(data.data(), data.size()); } -/// Appends data to the upbuffer. -/// This will attempt to send the upbuffer (if non-empty) first. -/// If the upbuffer is empty before or after this attempt, it will attempt to send -/// the data right away. Any data that could not be send will be put into the upbuffer. -/// This means this function is blocking if the socket is, but nonblocking otherwise. -void Socket::Connection::Send(std::string & data) { - Send(data.c_str(), data.size()); -} - /// Incremental write call. This function tries to write len bytes to the socket from the buffer, /// returning the amount of bytes it actually wrote. /// \param buffer Location of the buffer to write from. diff --git a/lib/socket.h b/lib/socket.h index 979eb6f0..2599a221 100644 --- a/lib/socket.h +++ b/lib/socket.h @@ -53,7 +53,6 @@ namespace Socket { unsigned int down; long long int conntime; Buffer downbuffer; ///< Stores temporary data coming in. - Buffer upbuffer; ///< Stores temporary data going out. int iread(void * buffer, int len, int flags = 0); ///< Incremental read call. unsigned int iwrite(const void * buffer, int len); ///< Incremental write call. bool iread(Buffer & buffer, int flags = 0); ///< Incremental write call that is compatible with Socket::Buffer. @@ -79,13 +78,9 @@ namespace Socket { bool connected() const; ///< Returns the connected-state for this socket. bool isAddress(std::string addr); //buffered i/o methods - bool spool(); ///< Updates the downbuffer and upbuffer internal variables. - bool flush(); ///< Updates the downbuffer and upbuffer internal variables until upbuffer is empty. + bool spool(); ///< Updates the downbufferinternal variables. bool peek(); ///< Clears the downbuffer and fills it with peek Buffer & Received(); ///< Returns a reference to the download buffer. - void Send(std::string & data); ///< Appends data to the upbuffer. - void Send(const char * data); ///< Appends data to the upbuffer. - void Send(const char * data, size_t len); ///< Appends data to the upbuffer. void SendNow(const std::string & data); ///< Will not buffer anything but always send right away. Blocks. void SendNow(const char * data); ///< Will not buffer anything but always send right away. Blocks. void SendNow(const char * data, size_t len); ///< Will not buffer anything but always send right away. Blocks.