Back to index

nordugrid-arc-nox  1.1.0~rc6
Public Types | Public Member Functions | Protected Member Functions | Protected Attributes
Arc::PayloadHTTP Class Reference

This class implements parsing and generation of HTTP messages. More...

#include <PayloadHTTP.h>

Inheritance diagram for Arc::PayloadHTTP:
Inheritance graph
[legend]
Collaboration diagram for Arc::PayloadHTTP:
Collaboration graph
[legend]

List of all members.

Public Types

typedef signed long long int Size_t
typedef signed long long int Size_t

Public Member Functions

 PayloadHTTP (PayloadStreamInterface &stream, bool own=false)
 Constructor - creates object by parsing HTTP request or response from stream.
 PayloadHTTP (const std::string &method, const std::string &url, PayloadStreamInterface &stream)
 Constructor - creates HTTP request to be sent through stream.
 PayloadHTTP (const std::string &method, const std::string &url)
 Constructor - creates HTTP request to be rendered through Raw interface.
 PayloadHTTP (int code, const std::string &reason, PayloadStreamInterface &stream)
 Constructor - creates HTTP response to be sent through stream.
 PayloadHTTP (int code, const std::string &reason)
 Constructor - creates HTTP response to be rendered through Raw interface.
virtual ~PayloadHTTP (void)
virtual operator bool (void)
 Returns true if stream is valid.
virtual bool operator! (void)
 Returns true if stream is invalid.
virtual const std::string & Attribute (const std::string &name)
 Returns HTTP header attribute with specified name.
virtual const std::multimap
< std::string, std::string > & 
Attributes (void)
 Returns all HTTP header attributes.
virtual void Attribute (const std::string &name, const std::string &value)
 Adds HTTP header attribute 'name' = 'value'.
virtual bool Flush (void)
 Send created object through associated stream.
virtual std::string Method ()
virtual std::string Endpoint ()
virtual std::string Reason ()
virtual int Code ()
virtual bool KeepAlive (void)
virtual void KeepAlive (bool keep_alive)
virtual void Body (PayloadRawInterface &body, bool ownership=true)
 Assign HTTP body.
virtual void Body (PayloadStreamInterface &body, bool ownership=true)
virtual char operator[] (PayloadRawInterface::Size_t pos) const
 Returns content of byte at specified position.
virtual char * Content (PayloadRawInterface::Size_t pos=-1)
 Get pointer to buffer content at global position 'pos'.
virtual PayloadRawInterface::Size_t Size (void) const
 Returns logical size of whole structure.
virtual char * Insert (PayloadRawInterface::Size_t pos=0, PayloadRawInterface::Size_t size=0)
 Create new buffer at global position 'pos' of size 'size'.
virtual char * Insert (const char *s, PayloadRawInterface::Size_t pos=0, PayloadRawInterface::Size_t size=-1)
 Create new buffer at global position 'pos' of size 'size'.
virtual char * Buffer (unsigned int num=0)
 Returns pointer to num'th buffer.
virtual PayloadRawInterface::Size_t BufferSize (unsigned int num=0) const
 Returns length of num'th buffer.
virtual PayloadRawInterface::Size_t BufferPos (unsigned int num=0) const
 Returns position of num'th buffer.
virtual bool Truncate (PayloadRawInterface::Size_t size)
 Change size of stored information.
virtual bool Get (char *buf, int &size)
 Extracts information from stream up to 'size' bytes.
virtual bool Get (std::string &buf)
 Read as many as possible (sane amount) of bytes into buf.
virtual std::string Get (void)
 Read as many as possible (sane amount) of bytes.
virtual bool Put (const char *buf, PayloadStreamInterface::Size_t size)
 Push 'size' bytes from 'buf' into stream.
virtual bool Put (const std::string &buf)
 Push information from 'buf' into stream.
virtual bool Put (const char *buf)
 Push null terminated information from 'buf' into stream.
virtual int Timeout (void) const
 Query current timeout for Get() and Put() operations.
virtual void Timeout (int to)
 Set current timeout for Get() and Put() operations.
virtual
PayloadStreamInterface::Size_t 
Pos (void) const
 Returns current position in stream if supported.
virtual
PayloadStreamInterface::Size_t 
Limit (void) const
 Returns position at which stream reading will stop if supported.

Protected Member Functions

bool readline (std::string &line)
 Read from stream till
.
bool read (char *buf, int64_t &size)
 Read up to 'size' bytes from stream_.
bool parse_header (void)
 Read HTTP header and fill internal variables.
bool get_body (void)
 Read Body of HTTP message and attach it to inherited PayloadRaw object.

Protected Attributes

bool valid_
bool fetched_
PayloadStreamInterfacestream_
 true if whole content of HTTP body was fetched and stored in buffers.
bool stream_own_
 stream used to comminicate to outside
PayloadRawInterfacerbody_
 if true stream_ is owned by this
PayloadStreamInterfacesbody_
 associated HTTP Body buffer if any (to avoid copying to own buffer)
bool body_own_
 associated HTTP Body stream if any (to avoid copying to own buffer)
std::string uri_
 if true body_ is owned by this
int version_major_
 URI being contacted.
int version_minor_
 major number of HTTP version - must be 1
std::string method_
 minor number of HTTP version - must be 0 or 1
int code_
 HTTP method being used or requested.
std::string reason_
 HTTP code being sent or supplied.
int64_t length_
 HTTP reason being sent or supplied.
bool chunked_
 Content-length of HTTP message.
bool keep_alive_
 true if content is chunked
std::multimap< std::string,
std::string > 
attributes_
 true if conection should not be closed after response
char tbuf_ [1024]
int tbuflen_
uint64_t stream_offset_
int64_t chunked_size_
uint64_t chunked_offset_
Size_t offset_
Size_t size_
std::vector< PayloadRawBufbuf_

Detailed Description

This class implements parsing and generation of HTTP messages.

It implements only subset of HTTP/1.1 and also provides an PayloadRawInterface for including as payload into Message passed through MCC chains.

Definition at line 26 of file PayloadHTTP.h.


Member Typedef Documentation

typedef signed long long int Arc::PayloadStreamInterface::Size_t [inherited]

Definition at line 18 of file PayloadStream.h.

typedef signed long long int Arc::PayloadRawInterface::Size_t [inherited]

Definition at line 19 of file PayloadRaw.h.


Constructor & Destructor Documentation

Arc::PayloadHTTP::PayloadHTTP ( PayloadStreamInterface stream,
bool  own = false 
)

Constructor - creates object by parsing HTTP request or response from stream.

Supplied stream is associated with object for later use. If own is set to true then stream will be deleted in destructor. Because stream can be used by this object during whole lifetime it is important not to destroy stream till this object is deleted.

Definition at line 248 of file PayloadHTTP.cpp.

                                                               :valid_(false),stream_(&stream),stream_own_(own),fetched_(false),stream_offset_(0),chunked_size_(0),chunked_offset_(0),rbody_(NULL),sbody_(NULL),body_own_(false),keep_alive_(true) {
  tbuf_[0]=0; tbuflen_=0;
  if(!parse_header()) return;
  // If stream_ is owned then body can be fetched later
  // if(!stream_own_) if(!get_body()) return;
  valid_=true;
}

Here is the call graph for this function:

Arc::PayloadHTTP::PayloadHTTP ( const std::string &  method,
const std::string &  url,
PayloadStreamInterface stream 
)

Constructor - creates HTTP request to be sent through stream.

HTTP message is not sent yet.

Definition at line 256 of file PayloadHTTP.cpp.

                                                                                                   :valid_(true),fetched_(true),stream_offset_(0),chunked_size_(0),chunked_offset_(0),stream_(&stream),stream_own_(false),rbody_(NULL),sbody_(NULL),body_own_(false),uri_(url),method_(method),keep_alive_(true) {
  version_major_=1; version_minor_=1;
  // TODO: encode URI properly
}
Arc::PayloadHTTP::PayloadHTTP ( const std::string &  method,
const std::string &  url 
)

Constructor - creates HTTP request to be rendered through Raw interface.

Definition at line 266 of file PayloadHTTP.cpp.

                                                                    :valid_(true),fetched_(true),stream_offset_(0),chunked_size_(0),chunked_offset_(0),stream_(NULL),stream_own_(false),rbody_(NULL),sbody_(NULL),body_own_(false),uri_(url),method_(method),keep_alive_(true) {
  version_major_=1; version_minor_=1;
  // TODO: encode URI properly
}
Arc::PayloadHTTP::PayloadHTTP ( int  code,
const std::string &  reason,
PayloadStreamInterface stream 
)

Constructor - creates HTTP response to be sent through stream.

HTTP message is not sent yet.

Definition at line 261 of file PayloadHTTP.cpp.

                                                                                       :valid_(true),fetched_(true),stream_offset_(0),chunked_size_(0),chunked_offset_(0),stream_(&stream),stream_own_(false),rbody_(NULL),sbody_(NULL),body_own_(false),code_(code),reason_(reason),keep_alive_(true) {
  version_major_=1; version_minor_=1;
  if(reason_.empty()) reason_="OK";
}
Arc::PayloadHTTP::PayloadHTTP ( int  code,
const std::string &  reason 
)

Constructor - creates HTTP response to be rendered through Raw interface.

Definition at line 271 of file PayloadHTTP.cpp.

                                                        :valid_(true),fetched_(true),stream_offset_(0),chunked_size_(0),chunked_offset_(0),stream_(NULL),stream_own_(false),rbody_(NULL),sbody_(NULL),body_own_(false),code_(code),reason_(reason),keep_alive_(true) {
  version_major_=1; version_minor_=1;
  if(reason_.empty()) reason_="OK";
}
Arc::PayloadHTTP::~PayloadHTTP ( void  ) [virtual]

Definition at line 276 of file PayloadHTTP.cpp.

                              {
  if(rbody_ && body_own_) delete rbody_;
  if(sbody_ && body_own_) delete sbody_;
  if(stream_ && stream_own_) delete stream_;
}

Member Function Documentation

const std::string & Arc::PayloadHTTP::Attribute ( const std::string &  name) [virtual]

Returns HTTP header attribute with specified name.

Empty string if no such attribute.

Definition at line 234 of file PayloadHTTP.cpp.

                                                             {
  std::multimap<std::string,std::string>::iterator it = attributes_.find(name);
  if(it == attributes_.end()) return empty_string;
  return it->second;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Arc::PayloadHTTP::Attribute ( const std::string &  name,
const std::string &  value 
) [virtual]

Adds HTTP header attribute 'name' = 'value'.

Definition at line 244 of file PayloadHTTP.cpp.

                                                                        {
  attributes_.insert(std::pair<std::string,std::string>(lower(name),value));
}

Here is the call graph for this function:

const std::multimap< std::string, std::string > & Arc::PayloadHTTP::Attributes ( void  ) [virtual]

Returns all HTTP header attributes.

Definition at line 240 of file PayloadHTTP.cpp.

                                                                    {
  return attributes_;
}

Here is the caller graph for this function:

void Arc::PayloadHTTP::Body ( PayloadRawInterface body,
bool  ownership = true 
) [virtual]

Assign HTTP body.

Assigned object is not copied. Instead it is remembered and made available through Raw interface. If 'ownership' is true then passed object is treated as being owned by this instance and destroyed in destructor.

Definition at line 401 of file PayloadHTTP.cpp.

                                                               {
  if(rbody_ && body_own_) delete rbody_;
  if(sbody_ && body_own_) delete sbody_;
  sbody_ = NULL;
  rbody_=&body; body_own_=ownership;
}

Here is the caller graph for this function:

void Arc::PayloadHTTP::Body ( PayloadStreamInterface body,
bool  ownership = true 
) [virtual]

Definition at line 408 of file PayloadHTTP.cpp.

                                                                  {
  if(rbody_ && body_own_) delete rbody_;
  if(sbody_ && body_own_) delete sbody_;
  rbody_ = NULL;
  sbody_=&body; body_own_=ownership;
}
char * Arc::PayloadHTTP::Buffer ( unsigned int  num = 0) [virtual]

Returns pointer to num'th buffer.

Reimplemented from Arc::PayloadRaw.

Definition at line 464 of file PayloadHTTP.cpp.

                                          {
  if(!get_body()) return NULL;
  if(num < buf_.size()) {
    return PayloadRaw::Buffer(num);
  };
  if(rbody_) {
    return rbody_->Buffer(num-buf_.size());
  };
  if(sbody_) {
    // Not supporting buffer access to stream body
  };
  return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PayloadRawInterface::Size_t Arc::PayloadHTTP::BufferPos ( unsigned int  num = 0) const [virtual]

Returns position of num'th buffer.

Reimplemented from Arc::PayloadRaw.

Definition at line 492 of file PayloadHTTP.cpp.

                                                                       {
  if(!((PayloadHTTP*)this)->get_body()) return 0;
  if(num < buf_.size()) {
    return PayloadRaw::BufferPos(num);
  };
  if(rbody_) {
    return rbody_->BufferPos(num-buf_.size())+PayloadRaw::BufferPos(num);
  };
  if(sbody_) {
    // Not supporting buffer access to stream body
  };
  return PayloadRaw::BufferPos(num);
}

Here is the call graph for this function:

Here is the caller graph for this function:

PayloadRawInterface::Size_t Arc::PayloadHTTP::BufferSize ( unsigned int  num = 0) const [virtual]

Returns length of num'th buffer.

Reimplemented from Arc::PayloadRaw.

Definition at line 478 of file PayloadHTTP.cpp.

                                                                        {
  if(!((PayloadHTTP*)this)->get_body()) return 0;
  if(num < buf_.size()) {
    return PayloadRaw::BufferSize(num);
  };
  if(rbody_) {
    return rbody_->BufferSize(num-buf_.size());
  };
  if(sbody_) {
    // Not supporting buffer access to stream body
  };
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

virtual int Arc::PayloadHTTP::Code ( ) [inline, virtual]

Definition at line 105 of file PayloadHTTP.h.

{ return code_; };

Here is the caller graph for this function:

Get pointer to buffer content at global position 'pos'.

By default to beginning of main buffer whatever that means.

Reimplemented from Arc::PayloadRaw.

Definition at line 429 of file PayloadHTTP.cpp.

                                                        {
  if(!get_body()) return NULL;
  if(pos < PayloadRaw::Size()) {
    return PayloadRaw::Content(pos);
  };
  if(rbody_) {
    return rbody_->Content(pos-Size());
  };
  if(sbody_) {
    // Not supporting content from stream body
  };
  return NULL;
}

Here is the call graph for this function:

virtual std::string Arc::PayloadHTTP::Endpoint ( ) [inline, virtual]

Definition at line 103 of file PayloadHTTP.h.

{ return uri_; };

Here is the caller graph for this function:

bool Arc::PayloadHTTP::Flush ( void  ) [virtual]

Send created object through associated stream.

If there is no stream associated then HTTP specific data is inserted into Raw buffers of this object. In last case this operation should not be repeated till content of buffer is completely rewritten.

Definition at line 282 of file PayloadHTTP.cpp.

                            {
  std::string header;
  bool to_stream = (stream_ != NULL);
  if(method_.empty() && (code_ == 0)) return false;
  // Computing length of Body part
  length_=0;
  std::string range_header;
  if((method_ != "GET") && (method_ != "HEAD")) {
    int64_t start = 0;
    if(sbody_) {
      if(sbody_->Limit() > sbody_->Pos()) {
        length_ = sbody_->Limit() - sbody_->Pos();
      };
      start=sbody_->Pos();
    } else {
      for(int n=0;;++n) {
        if(Buffer(n) == NULL) break;
        length_+=BufferSize(n);
      };
      start=BufferPos(0);
    };
    if(length_ != Size()) {
      // Add range definition if Body represents part of logical buffer size
      // and adjust HTTP code accordingly
      int64_t end = start+length_;
      std::string length_str;
      std::string range_str;
      if(end <= Size()) {
        length_str=tostring(Size());
      } else {
        length_str="*";
      }; 
      if(end > start) {
        range_str=tostring(start)+"-"+tostring(end-1);
        if(code_ == HTTP_OK) {
          code_=HTTP_PARTIAL;
          reason_="Partial content";
        };
      } else {
        range_str="*";
        if(code_ == HTTP_OK) {
          code_=HTTP_RANGE_NOT_SATISFIABLE;
          reason_="Range not satisfiable";
        };
      };
      range_header="Content-Range: bytes "+range_str+"/"+length_str+"\r\n";
    };
    range_header+="Content-Length: "+tostring(length_)+"\r\n";
  };
  // Starting header
  if(!method_.empty()) {
    header=method_+" "+uri_+
           " HTTP/"+tostring(version_major_)+"."+tostring(version_minor_)+"\r\n";
  } else if(code_ != 0) {
    char tbuf[256]; tbuf[255]=0;
    snprintf(tbuf,255,"HTTP/%i.%i %i",version_major_,version_minor_,code_);
    header="HTTP/"+tostring(version_major_)+"."+tostring(version_minor_)+" "+
           tostring(code_)+" "+reason_+"\r\n";
  };
  if((version_major_ == 1) && (version_minor_ == 1) && (!method_.empty())) {
    std::map<std::string,std::string>::iterator it = attributes_.find("host");
    if(it == attributes_.end()) {
      std::string host;
      if(!uri_.empty()) {
        std::string::size_type p1 = uri_.find("://");
        if(p1 != std::string::npos) {
          std::string::size_type p2 = uri_.find('/',p1+3);
          if(p2 != std::string::npos) {
            host=uri_.substr(p1+3,p2-p1-3);
          };
        };
      };
      header+="Host: "+host+"\r\n";
    };
  };
  // Adding previously generated range specifier
  header+=range_header;
  bool keep_alive = false;
  if((version_major_ == 1) && (version_minor_ == 1)) keep_alive=keep_alive_;
  if(keep_alive) {
    header+="Connection: keep-alive\r\n";
  } else {
    header+="Connection: close\r\n";
  };
  for(std::map<std::string,std::string>::iterator a = attributes_.begin();a!=attributes_.end();++a) {
    header+=(a->first)+": "+(a->second)+"\r\n";
  };
  header+="\r\n";
  if(to_stream) {
    if(!stream_->Put(header)) return false;
    if(length_ > 0) {
      if(sbody_) {
        // stream to stream transfer
        // TODO: choose optimal buffer size
        int tbufsize = (length_>1024*1024)?(1024*1024):length_;
        char* tbuf = new char[tbufsize];
        if(!tbuf) return false;
        for(;;) {
          int lbuf = tbufsize;
          if(!sbody_->Get(tbuf,lbuf)) break;
          if(!stream_->Put(tbuf,lbuf)) { delete[] tbuf; return false; };
        };
        delete[] tbuf;
      } else {
        for(int n=0;;++n) {
          char* tbuf = Buffer(n);
          if(tbuf == NULL) break;
          int64_t lbuf = BufferSize(n);
          if(lbuf > 0) if(!stream_->Put(tbuf,lbuf)) return false;
        };
      };
    };
    //if(!keep_alive) stream_->Close();
  } else {
    Insert(header.c_str(),0,header.length());
  };
  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool Arc::PayloadHTTP::Get ( char *  buf,
int &  size 
) [virtual]

Extracts information from stream up to 'size' bytes.

'size' contains number of read bytes on exit. Returns true in case of success.

Implements Arc::PayloadStreamInterface.

Definition at line 523 of file PayloadHTTP.cpp.

                                         {
  if(fetched_) {
    // Read from buffers
    uint64_t bo = 0;
    for(int num = 0;num<buf_.size();++num) {
      uint64_t bs = PayloadRaw::BufferSize(num);
      if((bo+bs) > stream_offset_) {
        char* p = PayloadRaw::Buffer(num);
        p+=(stream_offset_-bo);
        bs-=(stream_offset_-bo);
        if(bs>size) bs=size;
        memcpy(buf,p,bs);
        size=bs; stream_offset_+=bs;
        return true;
      };
      bo+=bs;
    };
    if(rbody_) {
      for(int num = 0;;++num) {
        char* p = PayloadRaw::Buffer(num);
        if(!p) break;
        uint64_t bs = PayloadRaw::BufferSize(num);
        if((bo+bs) > stream_offset_) {
          p+=(stream_offset_-bo);
          bs-=(stream_offset_-bo);
          if(bs>size) bs=size;
          memcpy(buf,p,bs);
          size=bs; stream_offset_+=bs;
          return true;
        };
        bo+=bs;
      };
    } else if(sbody_) {
      if(sbody_->Get(buf,size)) {
        stream_offset_+=size;
        return true;
      };
    };
    return false;
  };
    // TODO: Check for methods and responses which can't have body
  if(chunked_) {
    if(chunked_size_ == -1) { // chunked stream is over
      size=0;
      return false;
    };
    if(chunked_size_ == chunked_offset_) {
      // read chunk size
      std::string line;
      if(!readline(line)) return false;
      char* e;
      chunked_size_ = strtoll(line.c_str(),&e,16);
      if(((*e != ';') && (*e != 0)) || (e == line.c_str())) {
        chunked_size_=-1; // No more stream
        valid_=false; // Object becomes invalid
        size=0;
        return false;
      };
      chunked_offset_=0;
      if(chunked_size_ == 0) {
        // end of stream
        chunked_size_=-1; size=0;
        return false;
      };
    };
    // read chunk content
    int64_t bs = chunked_size_-chunked_offset_;
    if(bs > size) bs=size;
    if(!read(buf,bs)) { size=bs; return false; };
    chunked_offset_+=bs;
    size=bs; stream_offset_+=bs;
    return true;
  };
  if(length_ == 0) {
    // No body
    size=0;
    return false;
  };
  if(length_ > 0) {
    // Ordinary stream with known length
    int64_t bs = length_-stream_offset_;
    if(bs == 0) { size=0; return false; }; // End of content
    if(bs > size) bs=size;
    if(!read(buf,bs)) {
      valid_=false; // This is not expected, hence invalidate object
      size=bs; return false;
    };
    size=bs; stream_offset_+=bs;
    return true;
  };
  // Ordinary stream with no length known
  int64_t tsize = size;
  bool r = read(buf,tsize);
  if(r) stream_offset_+=tsize;
  size=tsize;
  // TODO: adjust logical parameters of buffers
  return r;
}

Here is the call graph for this function:

bool Arc::PayloadHTTP::Get ( std::string &  buf) [virtual]

Read as many as possible (sane amount) of bytes into buf.

Implements Arc::PayloadStreamInterface.

Definition at line 622 of file PayloadHTTP.cpp.

                                    {
  char tbuf[1024];
  int l = sizeof(tbuf);
  bool result = Get(tbuf,l);
  buf.assign(tbuf,l);
  return result;
}

Here is the call graph for this function:

std::string Arc::PayloadHTTP::Get ( void  ) [virtual]

Read as many as possible (sane amount) of bytes.

Implements Arc::PayloadStreamInterface.

Definition at line 630 of file PayloadHTTP.cpp.

                               {
  std::string s;
  Get(s);
  return s;
}

Here is the caller graph for this function:

bool Arc::PayloadHTTP::get_body ( void  ) [protected]

Read Body of HTTP message and attach it to inherited PayloadRaw object.

Definition at line 178 of file PayloadHTTP.cpp.

                               {
  if(fetched_) return true; // Already fetched body
  fetched_=true; // Even attempt counts
  valid_=false; // But object is invalid till whole body is available
  // TODO: Check for methods and responses which can't have body
  char* result = NULL;
  int64_t result_size = 0;
  if(chunked_) {
    for(;;) {
      std::string line;
      if(!readline(line)) return false;
      char* e;
      int64_t chunk_size = strtoll(line.c_str(),&e,16);
      if((*e != ';') && (*e != 0)) { free(result); return false; };
      if(e == line.c_str()) { free(result); return false; };
      if(chunk_size == 0) break;
      char* new_result = (char*)realloc(result,result_size+chunk_size+1);
      if(new_result == NULL) { free(result); return false; };
      result=new_result;
      if(!read(result+result_size,chunk_size)) { free(result); return false; };
      result_size+=chunk_size;
      if(!readline(line)) return false;
      if(!line.empty()) return false;
    };
  } else if(length_ == 0) {
    valid_=true;
    return true;
  } else if(length_ > 0) {
    result=(char*)malloc(length_+1);
    if(!read(result,length_)) { free(result); return false; };
    result_size=length_;
  } else {
    // Read till connection closed
    for(;;) {
      int64_t chunk_size = 4096;
      char* new_result = (char*)realloc(result,result_size+chunk_size+1);
      if(new_result == NULL) { free(result); return false; };
      result=new_result;
      if(!read(result+result_size,chunk_size)) break;
      result_size+=chunk_size;
    };
  };
  if (result == NULL) {
    return false;
  }
  result[result_size]=0;
  // Attach result to buffer exposed to user
  PayloadRawBuf b;
  b.data=result; b.size=result_size; b.length=result_size; b.allocated=true;
  buf_.push_back(b);
  // If size of object was not reported then try to deduce it.
  if(size_ == 0) size_=offset_+result_size;
  valid_=true;
  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Create new buffer at global position 'pos' of size 'size'.

Reimplemented from Arc::PayloadRaw.

Definition at line 454 of file PayloadHTTP.cpp.

                                                                                      {
  if(!get_body()) return NULL;
  return PayloadRaw::Insert(pos,size);
}

Here is the call graph for this function:

Here is the caller graph for this function:

char * Arc::PayloadHTTP::Insert ( const char *  s,
PayloadRawInterface::Size_t  pos = 0,
PayloadRawInterface::Size_t  size = -1 
) [virtual]

Create new buffer at global position 'pos' of size 'size'.

Created buffer is filled with content of memory at 's'. If 'size' is negative content at 's' is expected to be null-terminated.

Reimplemented from Arc::PayloadRaw.

Definition at line 459 of file PayloadHTTP.cpp.

                                                                                                    {
  if(!get_body()) return NULL;
  return PayloadRaw::Insert(s,pos,size);
}

Here is the call graph for this function:

virtual bool Arc::PayloadHTTP::KeepAlive ( void  ) [inline, virtual]

Definition at line 106 of file PayloadHTTP.h.

{ return keep_alive_; };

Here is the caller graph for this function:

virtual void Arc::PayloadHTTP::KeepAlive ( bool  keep_alive) [inline, virtual]

Definition at line 107 of file PayloadHTTP.h.

{ keep_alive_=keep_alive; };

Returns position at which stream reading will stop if supported.

That may be not same as Size() if instance is meant to provide access to only part of underlying obejct.

Implements Arc::PayloadStreamInterface.

Definition at line 664 of file PayloadHTTP.cpp.

                                                          {
  return Size();
}

Here is the call graph for this function:

virtual std::string Arc::PayloadHTTP::Method ( ) [inline, virtual]

Definition at line 102 of file PayloadHTTP.h.

{ return method_; };

Here is the caller graph for this function:

virtual Arc::PayloadHTTP::operator bool ( void  ) [inline, virtual]

Returns true if stream is valid.

Implements Arc::PayloadStreamInterface.

Definition at line 86 of file PayloadHTTP.h.

{ return valid_; };
virtual bool Arc::PayloadHTTP::operator! ( void  ) [inline, virtual]

Returns true if stream is invalid.

Implements Arc::PayloadStreamInterface.

Definition at line 87 of file PayloadHTTP.h.

{ return !valid_; };
char Arc::PayloadHTTP::operator[] ( PayloadRawInterface::Size_t  pos) const [virtual]

Returns content of byte at specified position.

Specified position 'pos' is treated as global one and goes through all buffers placed one after another.

Reimplemented from Arc::PayloadRaw.

Definition at line 415 of file PayloadHTTP.cpp.

                                                                {
  if(!((PayloadHTTP*)this)->get_body()) return 0;
  if(pos < PayloadRaw::Size()) {
    return PayloadRaw::operator[](pos);
  };
  if(rbody_) {
    return rbody_->operator[](pos-Size());
  };
  if(sbody_) {
    // Not supporting direct read from stream body
  };
  return 0;
}

Here is the call graph for this function:

bool Arc::PayloadHTTP::parse_header ( void  ) [protected]

Read HTTP header and fill internal variables.

Definition at line 56 of file PayloadHTTP.cpp.

                                   {
  method_.resize(0);
  code_=0;
  keep_alive_=false;
  // Skip empty lines
  std::string line;
  for(;line.empty();) if(!readline(line)) {
    method_="END";  // Special name to repsent closed connection
    chunked_=false; length_=0;
    return true;
  };
  // Parse request/response line
  std::string::size_type pos2 = line.find(' ');
  if(pos2 == std::string::npos) return false;
  std::string word1 = line.substr(0,pos2);
  // Identify request/response
  if(ParseHTTPVersion(line.substr(0,pos2),version_major_,version_minor_)) {
    // Response
    std::string::size_type pos3 = line.find(' ',pos2+1);
    if(pos3 == std::string::npos) return false;
    code_=strtol(line.c_str()+pos2+1,NULL,10);
    reason_=line.substr(pos3+1);
  } else {
    // Request
    std::string::size_type pos3 = line.rfind(' ');
    if((pos3 == pos2) || (pos2 == std::string::npos)) return false;
    if(!ParseHTTPVersion(line.substr(pos3+1),version_major_,version_minor_)) return false;
    method_=line.substr(0,pos2);
    uri_=line.substr(pos2+1,pos3-pos2-1);
  };
  if((version_major_ > 1) || ((version_major_ == 1) && (version_minor_ >= 1))) {
    keep_alive_=true;
  };
  // Parse header lines
  for(;readline(line) && (!line.empty());) {
    std::string::size_type pos = line.find(':');
    if(pos == std::string::npos) continue;
    std::string name = line.substr(0,pos);
    for(++pos;pos<line.length();++pos) if(!isspace(line[pos])) break;
    if(pos<line.length()) {
      std::string value = line.substr(pos);
      // for(std::string::size_type p=0;p<value.length();++p) value[p]=tolower(value[p]);
      Attribute(name,value);
    } else {
      Attribute(name,"");
    };
  };
  length_=-1; chunked_=false;
  std::map<std::string,std::string>::iterator it;
  it=attributes_.find("content-length");
  if(it != attributes_.end()) {
    length_=strtoll(it->second.c_str(),NULL,10);
  };
  it=attributes_.find("content-range");
  if(it != attributes_.end()) {
    const char* token = it->second.c_str();
    const char* p = token; for(;*p;p++) if(isspace(*p)) break;
    int64_t range_start,range_end,entity_size;
    if(strncasecmp("bytes",token,p-token) == 0) {
      for(;*p;p++) if(!isspace(*p)) break;
      char *e;
      range_start=strtoull(p,&e,10);
      if((*e) == '-') {
        p=e+1; range_end=strtoull(p,&e,10); p=e;
        if(((*e) == '/') || ((*e) == 0)) {
          if(range_start <= range_end) {
            offset_=range_start;
          };
          if((*p) == '/') {
            p++; entity_size=strtoull(p,&e,10);
            if((*e) == 0) {
              size_=entity_size;
            };
          };
        };
      };
    };
  };
  it=attributes_.find("transfer-encoding");
  if(it != attributes_.end()) {
    if(strcasecmp(it->second.c_str(),"chunked") != 0) {
      // Non-implemented encoding
      return false;
    };
    chunked_=true;
  };
  it=attributes_.find("connection");
  if(it != attributes_.end()) {
    if(strcasecmp(it->second.c_str(),"keep-alive") == 0) {
      keep_alive_=true;
    } else {
      keep_alive_=false;
    };
  };
  // In case of keep_alive (HTTP1.1) there must be length specified
  if(keep_alive_ && (length_ == -1)) length_=0;
  // If size of object was not reported then try to deduce it.
  if((size_ == 0) && (length_ != -1)) size_=offset_+length_;
  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Returns current position in stream if supported.

Implements Arc::PayloadStreamInterface.

Definition at line 659 of file PayloadHTTP.cpp.

                                                        {
  if(!stream_) return 0;
  return offset_+stream_offset_;
}
bool Arc::PayloadHTTP::Put ( const char *  buf,
PayloadStreamInterface::Size_t  size 
) [virtual]

Push 'size' bytes from 'buf' into stream.

Returns true on success.

Implements Arc::PayloadStreamInterface.

Definition at line 638 of file PayloadHTTP.cpp.

                                                                       {
  return false;
}
bool Arc::PayloadHTTP::Put ( const std::string &  buf) [virtual]

Push information from 'buf' into stream.

Returns true on success.

Implements Arc::PayloadStreamInterface.

Definition at line 642 of file PayloadHTTP.cpp.

                                          {
  return false;
}
bool Arc::PayloadHTTP::Put ( const char *  buf) [virtual]

Push null terminated information from 'buf' into stream.

Returns true on success.

Implements Arc::PayloadStreamInterface.

Definition at line 646 of file PayloadHTTP.cpp.

                                     {
  return false;
}
bool Arc::PayloadHTTP::read ( char *  buf,
int64_t &  size 
) [protected]

Read up to 'size' bytes from stream_.

Definition at line 157 of file PayloadHTTP.cpp.

                                              {
//char* buff = buf;
//memset(buf,0,size);
  if(tbuflen_ >= size) {
    memcpy(buf,tbuf_,size);
    memmove(tbuf_,tbuf_+size,tbuflen_-size+1);
    tbuflen_-=size;
  } else {
    memcpy(buf,tbuf_,tbuflen_);
    buf+=tbuflen_; 
    int64_t l = size-tbuflen_;
    size=tbuflen_; tbuflen_=0; tbuf_[0]=0; 
    for(;l;) {
      int l_ = (l>INT_MAX)?INT_MAX:l;
      if(!stream_->Get(buf,l_)) return (size>0);
      size+=l_; buf+=l_; l-=l_;
    };
  };
  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool Arc::PayloadHTTP::readline ( std::string &  line) [protected]

Read from stream till
.

Definition at line 35 of file PayloadHTTP.cpp.

                                          {
  line.resize(0);
  for(;;) {
    char* p = strchr(tbuf_,'\n');
    if(p) {
      *p=0;
      line+=tbuf_;
      tbuflen_-=(p-tbuf_)+1;
      memmove(tbuf_,p+1,tbuflen_+1); 
      if(line[line.length()-1] == '\r') line.resize(line.length()-1);
      return true;
    };
    line+=tbuf_;
    tbuflen_=sizeof(tbuf_)-1;
    if(!stream_->Get(tbuf_,tbuflen_)) break;
    tbuf_[tbuflen_]=0;
  }; 
  tbuf_[tbuflen_]=0;
  return false;
}

Here is the call graph for this function:

Here is the caller graph for this function:

virtual std::string Arc::PayloadHTTP::Reason ( ) [inline, virtual]

Definition at line 104 of file PayloadHTTP.h.

{ return reason_; };

Here is the caller graph for this function:

Returns logical size of whole structure.

Reimplemented from Arc::PayloadRaw.

Definition at line 443 of file PayloadHTTP.cpp.

                                                      {
  if(!((PayloadHTTP*)this)->get_body()) return 0;
  if(rbody_) {
    return PayloadRaw::Size() + (rbody_->Size());
  };
  if(sbody_) {
    return PayloadRaw::Size() + (sbody_->Size());
  };
  return PayloadRaw::Size();
}

Here is the call graph for this function:

Here is the caller graph for this function:

int Arc::PayloadHTTP::Timeout ( void  ) const [virtual]

Query current timeout for Get() and Put() operations.

Implements Arc::PayloadStreamInterface.

Definition at line 650 of file PayloadHTTP.cpp.

                                   {
  if(!stream_) return 0;
  return stream_->Timeout();
}

Here is the call graph for this function:

void Arc::PayloadHTTP::Timeout ( int  to) [virtual]

Set current timeout for Get() and Put() operations.

Implements Arc::PayloadStreamInterface.

Definition at line 655 of file PayloadHTTP.cpp.

                                {
  if(stream_) stream_->Timeout(to);
}

Here is the call graph for this function:

Change size of stored information.

If size exceeds end of allocated buffer, buffers are not re-allocated, only logical size is extended. Buffers with location behind new size are deallocated.

Reimplemented from Arc::PayloadRaw.

Definition at line 506 of file PayloadHTTP.cpp.

                                                         {
  if(!get_body()) return false;
  if(size < PayloadRaw::Size()) {
    if(rbody_ && body_own_) delete rbody_;
    if(sbody_ && body_own_) delete sbody_;
    rbody_=NULL; sbody_=NULL;
    return PayloadRaw::Truncate(size);
  };
  if(rbody_) {
    return rbody_->Truncate(size-Size());
  };
  if(sbody_) {
    // Stream body does not support Truncate yet
  };
  return false;
}

Here is the call graph for this function:


Member Data Documentation

std::multimap<std::string,std::string> Arc::PayloadHTTP::attributes_ [protected]

true if conection should not be closed after response

Definition at line 50 of file PayloadHTTP.h.

bool Arc::PayloadHTTP::body_own_ [protected]

associated HTTP Body stream if any (to avoid copying to own buffer)

Definition at line 38 of file PayloadHTTP.h.

std::vector<PayloadRawBuf> Arc::PayloadRaw::buf_ [protected, inherited]

Definition at line 65 of file PayloadRaw.h.

bool Arc::PayloadHTTP::chunked_ [protected]

Content-length of HTTP message.

Definition at line 48 of file PayloadHTTP.h.

uint64_t Arc::PayloadHTTP::chunked_offset_ [protected]

Definition at line 55 of file PayloadHTTP.h.

int64_t Arc::PayloadHTTP::chunked_size_ [protected]

Definition at line 54 of file PayloadHTTP.h.

int Arc::PayloadHTTP::code_ [protected]

HTTP method being used or requested.

Definition at line 43 of file PayloadHTTP.h.

bool Arc::PayloadHTTP::fetched_ [protected]

Definition at line 29 of file PayloadHTTP.h.

true if content is chunked

Definition at line 49 of file PayloadHTTP.h.

int64_t Arc::PayloadHTTP::length_ [protected]

HTTP reason being sent or supplied.

Definition at line 45 of file PayloadHTTP.h.

std::string Arc::PayloadHTTP::method_ [protected]

minor number of HTTP version - must be 0 or 1

Definition at line 42 of file PayloadHTTP.h.

Size_t Arc::PayloadRaw::offset_ [protected, inherited]

Definition at line 63 of file PayloadRaw.h.

if true stream_ is owned by this

Definition at line 36 of file PayloadHTTP.h.

std::string Arc::PayloadHTTP::reason_ [protected]

HTTP code being sent or supplied.

Definition at line 44 of file PayloadHTTP.h.

associated HTTP Body buffer if any (to avoid copying to own buffer)

Definition at line 37 of file PayloadHTTP.h.

Size_t Arc::PayloadRaw::size_ [protected, inherited]

Definition at line 64 of file PayloadRaw.h.

true if whole content of HTTP body was fetched and stored in buffers.

Otherwise only header was fetched and part of body in tbuf_ and rest is to be read through stream_.

Definition at line 34 of file PayloadHTTP.h.

uint64_t Arc::PayloadHTTP::stream_offset_ [protected]

Definition at line 53 of file PayloadHTTP.h.

stream used to comminicate to outside

Definition at line 35 of file PayloadHTTP.h.

char Arc::PayloadHTTP::tbuf_[1024] [protected]

Definition at line 51 of file PayloadHTTP.h.

int Arc::PayloadHTTP::tbuflen_ [protected]

Definition at line 52 of file PayloadHTTP.h.

std::string Arc::PayloadHTTP::uri_ [protected]

if true body_ is owned by this

Definition at line 39 of file PayloadHTTP.h.

bool Arc::PayloadHTTP::valid_ [protected]

Definition at line 28 of file PayloadHTTP.h.

URI being contacted.

Definition at line 40 of file PayloadHTTP.h.

major number of HTTP version - must be 1

Definition at line 41 of file PayloadHTTP.h.


The documentation for this class was generated from the following files: