From 949fd71bb03c365520d3a4d953782c66101e5e49 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Michal=20Voc=C5=AF?= Date: Wed, 7 Mar 2007 20:16:50 +0000 Subject: [PATCH] * basic HTTP parsing --- org.glite.lb.logger/src-nt/HTTPTransport.H | 14 ++-- org.glite.lb.logger/src-nt/HTTPTransport.cpp | 104 +++++++++++++++++++++++---- org.glite.lb.logger/src-nt/ThreadPool.H | 9 +-- 3 files changed, 105 insertions(+), 22 deletions(-) diff --git a/org.glite.lb.logger/src-nt/HTTPTransport.H b/org.glite.lb.logger/src-nt/HTTPTransport.H index d5bf700..417deea 100644 --- a/org.glite.lb.logger/src-nt/HTTPTransport.H +++ b/org.glite.lb.logger/src-nt/HTTPTransport.H @@ -25,26 +25,32 @@ public: HTTPTransport(Connection *conn) : Transport(conn), state(NONE), - request(), headers(), body(NULL), pos(NULL) + request(), headers(), body(NULL), pos(NULL), + content_length(0) {} virtual ~HTTPTransport(); + +protected: // from ThreadPool::WorkDescription virtual void onReady(); virtual void onTimeout(); virtual void onError(); -protected: +private: enum { NONE, IN_REQUEST, IN_HEADERS, IN_BODY } state; - string request; - string headers; + std::string request; + std::string headers; char *body; char buffer[256]; char *pos; + unsigned int content_length; + + int parseHeader(const char *s, unsigned int len); }; diff --git a/org.glite.lb.logger/src-nt/HTTPTransport.cpp b/org.glite.lb.logger/src-nt/HTTPTransport.cpp index 61d67f2..9847beb 100644 --- a/org.glite.lb.logger/src-nt/HTTPTransport.cpp +++ b/org.glite.lb.logger/src-nt/HTTPTransport.cpp @@ -16,6 +16,8 @@ HTTPTransport::~HTTPTransport() void HTTPTransport::onReady() { + int len; + switch(state) { case NONE: state = IN_REQUEST; @@ -23,30 +25,98 @@ HTTPTransport::onReady() case IN_REQUEST: case IN_HEADERS: - len = conn->read(buffer, sizeof(buffer)); + len = conn->read(pos, sizeof(buffer) - (pos - buffer)); if(len < 0) { // error during request } else if(len == 0) { // other side closed connection } else { - char *cr; - - // parse buffer, look for CRLF - cr = memchr(buffer, '\r', len); - if(cr) { - if((cr < buffer + len - 1) && + char *cr = NULL, *p = buffer, *s = buffer; + bool crlf_seen = false; + + // parse buffer, look for CRLFs + // s - start scan position + // p - start of current token + // cr - current CRLF position + // crlf_seen <=> previous block ends with CRLF + while((state != IN_BODY) && + (s < buffer + len) && + (cr = (char*)memchr(s, '\r', len - (s - buffer)))) { + if((cr < buffer + len - 1) && (cr[1] == '\n')) { // found CRLF - - } else - cr = buffer + len; + if(state == IN_REQUEST) { + // found end of request + request.append(p, cr - p); + // change state + state = IN_HEADERS; + // start new tokens + p = cr + 2; + } else { + // headers continue. parse the current one + parseHeader(s, cr - s); + } + if(crlf_seen && (s == cr)) { + // found CRLFCRLF + state = IN_BODY; + } + // next scan starts after CRLF + s = cr + 2; + // we have seen CRLF + crlf_seen = true; + } else { + if(crlf_seen && (s == cr)) { + if(cr < buffer + len - 1) { + // found CRLFCRx + // continue scan behind this + s = cr + 2; + } else { + // found CRLFCR at the end of buffer + // s points behind buffer => scan ends + s = cr + 1; + // cr points at the CRLFCR => it will be left for next pass + cr = cr - 2; + } + } else { + // single '\r' - skip it, + // or '\r' at the end of buffer - skip it, that ends scanning + s = cr + 1; + } + crlf_seen = false; + } } - // append everything up to the cr into appropriate variable + // copy the current token into appropriate variable, + // but leave the trailing \r[\n] in buffer + if(!cr) cr = buffer + len; if(state == IN_REQUEST) - request.append(buffer, cr - buffer); - else - headers.append(buffer, cr - buffer); + request.append(p, cr - p); + else + headers.append(p, cr - p); + if(state == IN_BODY) { + // we found body + // content-length should be set at the moment + if(content_length > 0) { + body = (char*)malloc(content_length); + if(body == NULL) { + // chyba alokace + } + // move rest of buffer to body + if(s < buffer + len) { + memmove(body, s, buffer + len - s); + pos = body + (buffer + len - s); + } + } else { + // report error + } + } else { + // move the trailing characters to the front + if(cr < buffer + len) + memmove(buffer, cr, buffer + len - cr); + // and set pos to point at the first free place + pos = buffer + (buffer + len - cr); + } } + break; case IN_BODY: break; @@ -67,3 +137,9 @@ HTTPTransport::onError() } +int +HTTPTransport::parseHeader(const char *s, unsigned int len) +{ + std::cout.write(s, len); + return(0); +} diff --git a/org.glite.lb.logger/src-nt/ThreadPool.H b/org.glite.lb.logger/src-nt/ThreadPool.H index 602b86b..9c17de9 100644 --- a/org.glite.lb.logger/src-nt/ThreadPool.H +++ b/org.glite.lb.logger/src-nt/ThreadPool.H @@ -19,6 +19,11 @@ public: WorkDescription(int afd) : fd(afd), event(NONE) {} + + protected: + enum Event { NONE, READY, TIMEOUT, ERROR } event; + void doWork(); + virtual void onReady() {} @@ -27,10 +32,6 @@ public: virtual void onError() {} - - protected: - enum Event { NONE, READY, TIMEOUT, ERROR } event; - void doWork(); }; public: -- 1.8.2.3