Merge fix
This commit is contained in:
commit
9fe909d034
4 changed files with 113 additions and 2 deletions
|
@ -188,10 +188,25 @@ bool HTTP::Parser::parse(){
|
|||
}
|
||||
if (seenHeaders){
|
||||
if (length > 0){
|
||||
/// \todo Include POST variable parsing?
|
||||
if (HTTPbuffer.length() >= length){
|
||||
body = HTTPbuffer.substr(0, length);
|
||||
HTTPbuffer.erase(0, length);
|
||||
std::string tmppost = body;
|
||||
std::string varname;
|
||||
std::string varval;
|
||||
while (tmppost.find('=') != std::string::npos){
|
||||
size_t found = tmppost.find('=');
|
||||
varname = urlunescape((char*)tmppost.substr(0, found).c_str());
|
||||
tmppost.erase(0, found+1);
|
||||
found = tmppost.find('&');
|
||||
varval = urlunescape((char*)tmppost.substr(0, found).c_str());
|
||||
SetVar(varname, varval);
|
||||
if (found == std::string::npos){
|
||||
tmppost.clear();
|
||||
}else{
|
||||
tmppost.erase(0, found+1);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
|
@ -241,3 +256,29 @@ void HTTP::Parser::SendBodyPart(Socket::Connection & conn, std::string bodypart)
|
|||
conn.write(bodypart);
|
||||
}
|
||||
}
|
||||
|
||||
/// Unescapes URLencoded C-strings to a std::string.
|
||||
/// This function *will* destroy the input data!
|
||||
std::string HTTP::Parser::urlunescape(char *s){
|
||||
char *p;
|
||||
for (p = s; *s != '\0'; ++s){
|
||||
if (*s == '%'){
|
||||
if (*++s != '\0'){
|
||||
*p = unhex(*s) << 4;
|
||||
}
|
||||
if (*++s != '\0'){
|
||||
*p++ += unhex(*s);
|
||||
}
|
||||
} else {
|
||||
if (*s == '+'){*p++ = ' ';}else{*p++ = *s;}
|
||||
}
|
||||
}
|
||||
*p = '\0';
|
||||
return std::string(s);
|
||||
}
|
||||
|
||||
/// Helper function for urlunescape.
|
||||
/// Takes a single char input and outputs its integer hex value.
|
||||
int HTTP::Parser::unhex(char c){
|
||||
return( c >= '0' && c <= '9' ? c - '0' : c >= 'A' && c <= 'F' ? c - 'A' + 10 : c - 'a' + 10 );
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace HTTP{
|
|||
void SendBodyPart(Socket::Connection & conn, std::string bodypart);
|
||||
void Clean();
|
||||
bool CleanForNext();
|
||||
std::string urlunescape(char *s); ///< Unescapes URLencoded C-strings to a std::string.
|
||||
std::string body;
|
||||
std::string method;
|
||||
std::string url;
|
||||
|
@ -43,5 +44,6 @@ namespace HTTP{
|
|||
std::map<std::string, std::string> headers;
|
||||
std::map<std::string, std::string> vars;
|
||||
void Trim(std::string & s);
|
||||
int unhex(char c); ///< Helper function for urlunescape.
|
||||
};//HTTP::Parser class
|
||||
};//HTTP namespace
|
||||
|
|
|
@ -3,6 +3,11 @@
|
|||
/// Written by Jaron Vietor in 2010 for DDVTech
|
||||
|
||||
#include "socket.h"
|
||||
#include <poll.h>
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
/// Create a new base socket. This is a basic constructor for converting any valid socket to a Socket::Connection.
|
||||
/// \param sockNo Integer representing the socket to convert.
|
||||
|
@ -69,6 +74,27 @@ Socket::Connection::Connection(std::string address, bool nonblock){
|
|||
}
|
||||
}//Socket::Connection Unix Contructor
|
||||
|
||||
/// Calls poll() on the socket, checking if data is available.
|
||||
/// This function may return true even if there is no data, but never returns false when there is.
|
||||
bool Socket::Connection::canRead(){
|
||||
struct pollfd PFD;
|
||||
PFD.fd = sock;
|
||||
PFD.events = POLLIN;
|
||||
PFD.revents = 0;
|
||||
poll(&PFD, 1, 5);
|
||||
return (PFD.revents & POLLIN) == POLLIN;
|
||||
}
|
||||
/// Calls poll() on the socket, checking if data can be written.
|
||||
bool Socket::Connection::canWrite(){
|
||||
struct pollfd PFD;
|
||||
PFD.fd = sock;
|
||||
PFD.events = POLLOUT;
|
||||
PFD.revents = 0;
|
||||
poll(&PFD, 1, 5);
|
||||
return (PFD.revents & POLLOUT) == POLLOUT;
|
||||
}
|
||||
|
||||
|
||||
/// Returns the ready-state for this socket.
|
||||
/// \returns 1 if data is waiting to be read, -1 if not connected, 0 otherwise.
|
||||
signed int Socket::Connection::ready(){
|
||||
|
@ -348,7 +374,47 @@ Socket::Server::Server(int port, std::string hostname, bool nonblock){
|
|||
}
|
||||
}else{
|
||||
#if DEBUG >= 1
|
||||
fprintf(stderr, "Binding failed! Error: %s\n", strerror(errno));
|
||||
fprintf(stderr, "Binding failed, retrying as IPv4... (%s)\n", strerror(errno));
|
||||
#endif
|
||||
close();
|
||||
}
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock < 0){
|
||||
#if DEBUG >= 1
|
||||
fprintf(stderr, "Could not create socket! Error: %s\n", strerror(errno));
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
on = 1;
|
||||
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
||||
if (nonblock){
|
||||
int flags = fcntl(sock, F_GETFL, 0);
|
||||
flags |= O_NONBLOCK;
|
||||
fcntl(sock, F_SETFL, flags);
|
||||
}
|
||||
struct sockaddr_in addr4;
|
||||
addr4.sin_family = AF_INET;
|
||||
addr4.sin_port = htons(port);//set port
|
||||
if (hostname == "0.0.0.0"){
|
||||
addr4.sin_addr.s_addr = INADDR_ANY;
|
||||
}else{
|
||||
inet_pton(AF_INET, hostname.c_str(), &addr4.sin_addr);//set interface, 0.0.0.0 (default) is all
|
||||
}
|
||||
ret = bind(sock, (sockaddr*)&addr4, sizeof(addr4));//do the actual bind
|
||||
if (ret == 0){
|
||||
ret = listen(sock, 100);//start listening, backlog of 100 allowed
|
||||
if (ret == 0){
|
||||
return;
|
||||
}else{
|
||||
#if DEBUG >= 1
|
||||
fprintf(stderr, "Listen failed! Error: %s\n", strerror(errno));
|
||||
#endif
|
||||
close();
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
#if DEBUG >= 1
|
||||
fprintf(stderr, "IPv4 binding also failed, giving up. (%s)\n", strerror(errno));
|
||||
#endif
|
||||
close();
|
||||
return;
|
||||
|
|
|
@ -27,6 +27,8 @@ namespace Socket{
|
|||
Connection(); ///< Create a new disconnected base socket.
|
||||
Connection(int sockNo); ///< Create a new base socket.
|
||||
Connection(std::string adres, bool nonblock = false); ///< Create a new Unix Socket.
|
||||
bool canRead(); ///< Calls poll() on the socket, checking if data is available.
|
||||
bool canWrite(); ///< Calls poll() on the socket, checking if data can be written.
|
||||
bool Error; ///< Set to true if a socket error happened.
|
||||
bool Blocking; ///< Set to true if a socket is currently or wants to be blocking.
|
||||
signed int ready(); ///< Returns the ready-state for this socket.
|
||||
|
|
Loading…
Add table
Reference in a new issue