blob: 14338a3d6f5704ebdbc036cc12882fde30ca4ecb [file] [log] [blame]
/*
* Copyright 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Author: jmarantz@google.com (Joshua Marantz)
#ifndef NET_INSTAWEB_HTTP_PUBLIC_HTTP_VALUE_H_
#define NET_INSTAWEB_HTTP_PUBLIC_HTTP_VALUE_H_
#include <cstddef> // for size_t
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/shared_string.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/base/writer.h"
namespace net_instaweb {
class ResponseHeaders;
class MessageHandler;
// Provides shared, ref-counted, copy-on-write storage for HTTP
// contents, to aid sharing between active fetches and filters, and
// the cache, which from which data may be evicted at any time.
class HTTPValue : public Writer {
public:
HTTPValue() : contents_size_(0) {}
// Clears the value (both headers and content)
void Clear();
// Is this HTTPValue empty
bool Empty() const { return storage_.empty(); }
// Sets the HTTP headers for this value. This method may only
// be called once and must be called before or after all of the
// contents are set (using the streaming interface Write).
//
// If Clear() is called, then SetHeaders() can be called once again.
//
// Does NOT take ownership of headers.
// A non-const pointer is required for the response headers so that
// the cache fields can be updated if necessary.
void SetHeaders(ResponseHeaders* headers);
// Writes contents into the HTTPValue object. Write can be called
// multiple times to append more data, and can be called before
// or after SetHeaders. However, SetHeaders cannot be interleaved
// in between calls to Write.
virtual bool Write(const StringPiece& str, MessageHandler* handler);
virtual bool Flush(MessageHandler* handler);
// Retrieves the headers, returning false if empty.
bool ExtractHeaders(ResponseHeaders* headers, MessageHandler* handler) const;
// Retrieves the contents, returning false if empty. Note that the
// contents are only guaranteed valid as long as the HTTPValue
// object is in scope.
bool ExtractContents(StringPiece* str) const;
// Tests whether this reference is the only active one to the string object.
bool unique() const { return storage_.unique(); }
// Assigns the storage of an HTTPValue based on the provided storage. This
// can be used for a cache Get. Returns false if the string is not
// well-formed.
//
// Extracts the headers into the provided ResponseHeaders buffer.
bool Link(SharedString* src, ResponseHeaders* headers,
MessageHandler* handler);
// Links two HTTPValues together, using the contents of 'src' and discarding
// the contents of this.
void Link(HTTPValue* src) {
if (src != this) {
storage_ = src->storage_; // SharedString links via assignment.
contents_size_ = src->contents_size();
}
}
// Access the shared string, for insertion into a cache via Put.
SharedString* share() { return &storage_; }
size_t size() const { return storage_.size(); }
int64 contents_size() { return contents_size_; }
// Useful functions for debugging. See http_value_explorer.
// Convert from HTTPValue format to raw HTTP stream.
static bool Decode(StringPiece encoded_value, GoogleString* http_string,
MessageHandler* handler);
// Convert from raw HTTP stream to HTTPValue format.
static bool Encode(StringPiece http_string, GoogleString* encoded_value,
MessageHandler* handler);
private:
friend class HTTPValueTest;
// Must be called with storage_ non-empty.
char type_identifier() const { return *storage_.data(); }
unsigned int SizeOfFirstChunk() const;
void SetSizeOfFirstChunk(unsigned int size);
int64 ComputeContentsSize() const;
// Disconnects this HTTPValue from other HTTPValues that may share the
// underlying storage, allowing a new buffer.
void CopyOnWrite();
SharedString storage_;
// Member variable to keep the size of body in storage.
int64 contents_size_;
DISALLOW_COPY_AND_ASSIGN(HTTPValue);
};
} // namespace net_instaweb
#endif // NET_INSTAWEB_HTTP_PUBLIC_HTTP_VALUE_H_