Patch done by Christophe Huriaux as part of GSoC 2010 "Services Kit" project:
Integrated the classes in the Network Kit (libbnetapi.so). Only the foundation classed BUrl, BUrlContext, BNetworkCookie, BNetworkCookieJar and the private HttpTime code is currently compiled. The BUrlProtocol currently contains some misplaced BUrlProtocolHttp specific stuff, and the HTTP stuff itself has a dependency on libcrypto and should live in an add-on instead. I've sprinkled some TODOs in the code, and I've done some renaming compared to the last version of the GSoC patch. Any help to bring this further along is appreciated. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39161 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2010 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _B_HTTP_AUTHENTICATION_H_
|
||||
#define _B_HTTP_AUTHENTICATION_H_
|
||||
|
||||
|
||||
#include <Url.h>
|
||||
#include <String.h>
|
||||
|
||||
// HTTP authentication method
|
||||
enum BHttpAuthenticationMethod {
|
||||
B_HTTP_AUTHENTICATION_NONE = 0,
|
||||
// No authentication
|
||||
B_HTTP_AUTHENTICATION_BASIC = 1,
|
||||
// Basic base64 authentication method (unsecure)
|
||||
B_HTTP_AUTHENTICATION_DIGEST = 2,
|
||||
// Digest authentication
|
||||
B_HTTP_AUTHENTICATION_IE_DIGEST = 4
|
||||
// Slightly modified digest authentication to mimic old IE one
|
||||
};
|
||||
|
||||
|
||||
enum BHttpAuthenticationAlgorithm {
|
||||
B_HTTP_AUTHENTICATION_ALGORITHM_NONE,
|
||||
B_HTTP_AUTHENTICATION_ALGORITHM_MD5,
|
||||
B_HTTP_AUTHENTICATION_ALGORITHM_MD5_SESS
|
||||
};
|
||||
|
||||
|
||||
enum BHttpAuthenticationQop {
|
||||
B_HTTP_QOP_NONE,
|
||||
B_HTTP_QOP_AUTH,
|
||||
B_HTTP_QOP_AUTHINT
|
||||
};
|
||||
|
||||
|
||||
class BHttpAuthentication {
|
||||
public:
|
||||
BHttpAuthentication();
|
||||
BHttpAuthentication(const BString& username,
|
||||
const BString& password);
|
||||
|
||||
// Field modification
|
||||
void SetUserName(const BString& username);
|
||||
void SetPassword(const BString& password);
|
||||
void SetMethod(
|
||||
BHttpAuthenticationMethod type);
|
||||
status_t Initialize(const BString& wwwAuthenticate);
|
||||
|
||||
// Field access
|
||||
const BString& UserName() const;
|
||||
const BString& Password() const;
|
||||
BHttpAuthenticationMethod Method() const;
|
||||
|
||||
BString Authorization(const BUrl& url,
|
||||
const BString& method) const;
|
||||
|
||||
// Base64 encoding
|
||||
// TODO: Move to a common place. We may have multiple implementations
|
||||
// in the Haiku tree...
|
||||
static BString Base64Encode(const BString& string);
|
||||
static BString Base64Decode(const BString& string);
|
||||
|
||||
|
||||
private:
|
||||
BString _DigestResponse(const BString& uri,
|
||||
const BString& method) const;
|
||||
// TODO: Rename these? _H seems to return a hash value,
|
||||
// _KD returns a hash value of the "data" prepended by
|
||||
// the "secret" string...
|
||||
BString _H(const BString& value) const;
|
||||
BString _KD(const BString& secret,
|
||||
const BString& data) const;
|
||||
|
||||
private:
|
||||
BHttpAuthenticationMethod fAuthenticationMethod;
|
||||
BString fUserName;
|
||||
BString fPassword;
|
||||
|
||||
BString fRealm;
|
||||
BString fDigestNonce;
|
||||
mutable BString fDigestCnonce;
|
||||
mutable int fDigestNc;
|
||||
BString fDigestOpaque;
|
||||
bool fDigestStale;
|
||||
BHttpAuthenticationAlgorithm fDigestAlgorithm;
|
||||
BHttpAuthenticationQop fDigestQop;
|
||||
|
||||
BString fAuthorizationString;
|
||||
};
|
||||
|
||||
#endif // _B_HTTP_AUTHENTICATION_H_
|
||||
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright 2010 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _B_HTTP_FORM_H_
|
||||
#define _B_HTTP_FORM_H_
|
||||
|
||||
|
||||
#include <Path.h>
|
||||
#include <String.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
|
||||
enum form_type {
|
||||
B_HTTP_FORM_URL_ENCODED,
|
||||
B_HTTP_FORM_MULTIPART
|
||||
};
|
||||
|
||||
|
||||
enum form_content_type {
|
||||
B_HTTPFORM_UNKNOWN,
|
||||
B_HTTPFORM_STRING,
|
||||
B_HTTPFORM_FILE,
|
||||
B_HTTPFORM_BUFFER
|
||||
};
|
||||
|
||||
|
||||
class BHttpFormData {
|
||||
private:
|
||||
// Empty constructor is only kept for compatibility with map<>::operator[],
|
||||
// but never used (see BHttpForm::operator[] which does the necessary
|
||||
// check up)
|
||||
BHttpFormData();
|
||||
friend class std::map<BString, BHttpFormData>;
|
||||
|
||||
public:
|
||||
BHttpFormData(const BString& name,
|
||||
const BString& value);
|
||||
BHttpFormData(const BString& name,
|
||||
const BPath& file);
|
||||
BHttpFormData(const BString& name,
|
||||
const void* buffer, ssize_t size);
|
||||
BHttpFormData(const BHttpFormData& other);
|
||||
~BHttpFormData();
|
||||
|
||||
// Retrieve data informations
|
||||
bool InitCheck() const;
|
||||
|
||||
const BString& Name() const;
|
||||
const BString& String() const;
|
||||
const BPath& File() const;
|
||||
const void* Buffer() const;
|
||||
ssize_t BufferSize() const;
|
||||
|
||||
bool IsFile() const;
|
||||
const BString& Filename() const;
|
||||
const BString& MimeType() const;
|
||||
form_content_type Type() const;
|
||||
|
||||
// Change behavior
|
||||
status_t MarkAsFile(const BString& filename,
|
||||
const BString& mimeType);
|
||||
status_t MarkAsFile(const BString& filename);
|
||||
void UnmarkAsFile();
|
||||
status_t CopyBuffer();
|
||||
|
||||
// Overloaded operators
|
||||
BHttpFormData& operator=(const BHttpFormData& other);
|
||||
|
||||
private:
|
||||
form_content_type fDataType;
|
||||
bool fCopiedBuffer;
|
||||
bool fFileMark;
|
||||
|
||||
BString fName;
|
||||
BString fStringValue;
|
||||
BPath fPathValue;
|
||||
const void* fBufferValue;
|
||||
ssize_t fBufferSize;
|
||||
|
||||
BString fFilename;
|
||||
BString fMimeType;
|
||||
};
|
||||
|
||||
|
||||
class BHttpForm {
|
||||
public:
|
||||
// Nested types
|
||||
class Iterator;
|
||||
typedef std::map<BString, BHttpFormData> FormStorage;
|
||||
|
||||
public:
|
||||
BHttpForm();
|
||||
BHttpForm(const BHttpForm& other);
|
||||
BHttpForm(const BString& formString);
|
||||
~BHttpForm();
|
||||
|
||||
// Form string parsing
|
||||
void ParseString(const BString& formString);
|
||||
BString RawData() const;
|
||||
|
||||
// Form add
|
||||
status_t AddString(const BString& name,
|
||||
const BString& value);
|
||||
status_t AddInt(const BString& name, int32 value);
|
||||
status_t AddFile(const BString& fieldName,
|
||||
const BPath& file);
|
||||
status_t AddBuffer(const BString& fieldName,
|
||||
const void* buffer, ssize_t size);
|
||||
status_t AddBufferCopy(const BString& fieldName,
|
||||
const void* buffer, ssize_t size);
|
||||
|
||||
// Mark a field as a filename
|
||||
void MarkAsFile(const BString& fieldName,
|
||||
const BString& filename,
|
||||
const BString& mimeType);
|
||||
void MarkAsFile(const BString& fieldName,
|
||||
const BString& filename);
|
||||
void UnmarkAsFile(const BString& fieldName);
|
||||
|
||||
// Change form type
|
||||
void SetFormType(form_type type);
|
||||
|
||||
// Form test
|
||||
bool HasField(const BString& name) const;
|
||||
|
||||
// Form retrieve
|
||||
BString GetMultipartHeader(const BString& fieldName)
|
||||
const;
|
||||
form_content_type GetType(const BString& fieldname) const;
|
||||
|
||||
// Form informations
|
||||
form_type GetFormType() const;
|
||||
const BString& GetMultipartBoundary() const;
|
||||
BString GetMultipartFooter() const;
|
||||
ssize_t ContentLength() const;
|
||||
|
||||
// Form iterator
|
||||
Iterator GetIterator();
|
||||
|
||||
// Form clear
|
||||
void Clear();
|
||||
|
||||
// Overloaded operators
|
||||
BHttpFormData& operator[](const BString& name);
|
||||
|
||||
private:
|
||||
void _ExtractNameValuePair(const BString& string,
|
||||
int32* index);
|
||||
void _GenerateMultipartBoundary();
|
||||
BString _GetMultipartHeader(
|
||||
const BHttpFormData* element) const;
|
||||
form_content_type _GetType(FormStorage::const_iterator it) const;
|
||||
void _Erase(FormStorage::iterator it);
|
||||
|
||||
private:
|
||||
friend class Iterator;
|
||||
|
||||
FormStorage fFields;
|
||||
form_type fType;
|
||||
BString fMultipartBoundary;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class BHttpForm::Iterator {
|
||||
public:
|
||||
Iterator(const Iterator& other);
|
||||
|
||||
BHttpFormData* Next();
|
||||
bool HasNext() const;
|
||||
void Remove();
|
||||
BString MultipartHeader();
|
||||
|
||||
Iterator& operator=(const Iterator& other);
|
||||
|
||||
private:
|
||||
Iterator(BHttpForm* form);
|
||||
void _FindNext();
|
||||
|
||||
private:
|
||||
friend class BHttpForm;
|
||||
|
||||
BHttpForm* fForm;
|
||||
BHttpForm::FormStorage::iterator
|
||||
fStdIterator;
|
||||
BHttpFormData* fElement;
|
||||
BHttpFormData* fPrevElement;
|
||||
};
|
||||
|
||||
#endif // _B_HTTP_FORM_H_
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2010 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _B_HTTP_HEADERS_H_
|
||||
#define _B_HTTP_HEADERS_H_
|
||||
|
||||
|
||||
#include <List.h>
|
||||
#include <String.h>
|
||||
|
||||
|
||||
class BHttpHeader {
|
||||
public:
|
||||
BHttpHeader();
|
||||
BHttpHeader(const char* string);
|
||||
BHttpHeader(const char* name,
|
||||
const char* value);
|
||||
BHttpHeader(const BHttpHeader& copy);
|
||||
|
||||
// Header data modification
|
||||
void SetName(const char* name);
|
||||
void SetValue(const char* value);
|
||||
bool SetHeader(const char* string);
|
||||
|
||||
// Header data access
|
||||
const char* Name() const;
|
||||
const char* Value() const;
|
||||
const char* Header() const;
|
||||
|
||||
// Header data test
|
||||
bool NameIs(const char* name) const;
|
||||
|
||||
// Overloaded members
|
||||
BHttpHeader& operator=(const BHttpHeader& other);
|
||||
|
||||
private:
|
||||
BString fName;
|
||||
BString fValue;
|
||||
|
||||
mutable BString fRawHeader;
|
||||
mutable bool fRawHeaderValid;
|
||||
};
|
||||
|
||||
|
||||
class BHttpHeaders {
|
||||
public:
|
||||
BHttpHeaders();
|
||||
BHttpHeaders(const BHttpHeaders& copy);
|
||||
~BHttpHeaders();
|
||||
|
||||
// Header list access
|
||||
const char* HeaderValue(const char* name) const;
|
||||
BHttpHeader& HeaderAt(int32 index) const;
|
||||
|
||||
// Header count
|
||||
int32 CountHeaders() const;
|
||||
|
||||
// Header list tests
|
||||
int32 HasHeader(const char* name) const;
|
||||
|
||||
// Header add or replacement
|
||||
bool AddHeader(const char* line);
|
||||
bool AddHeader(const char* name,
|
||||
const char* value);
|
||||
bool AddHeader(const char* name,
|
||||
int32 value);
|
||||
|
||||
// Header deletion
|
||||
void Clear();
|
||||
|
||||
// Overloaded operators
|
||||
BHttpHeaders& operator=(const BHttpHeaders& other);
|
||||
BHttpHeader& operator[](int32 index) const;
|
||||
const char* operator[](const char* name) const;
|
||||
|
||||
private:
|
||||
void _EraseData();
|
||||
|
||||
private:
|
||||
BList fHeaderList;
|
||||
};
|
||||
|
||||
#endif // _B_HTTP_HEADERS_H_
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright 2010 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _B_NETWORK_COOKIE_H_
|
||||
#define _B_NETWORK_COOKIE_H_
|
||||
|
||||
|
||||
#include <Archivable.h>
|
||||
#include <DateTime.h>
|
||||
#include <Message.h>
|
||||
#include <String.h>
|
||||
#include <Url.h>
|
||||
|
||||
|
||||
class BNetworkCookie : public BArchivable {
|
||||
public:
|
||||
BNetworkCookie(const char* name,
|
||||
const char* value);
|
||||
BNetworkCookie(const BNetworkCookie& other);
|
||||
BNetworkCookie(const BString& cookieString);
|
||||
BNetworkCookie(const BString& cookieString,
|
||||
const BUrl& url);
|
||||
BNetworkCookie(BMessage* archive);
|
||||
BNetworkCookie();
|
||||
virtual ~BNetworkCookie();
|
||||
|
||||
// Parse a "SetCookie" string, or "name=value"
|
||||
|
||||
BNetworkCookie& ParseCookieStringFromUrl(const BString& string,
|
||||
const BUrl& url);
|
||||
BNetworkCookie& ParseCookieString(const BString& cookieString);
|
||||
|
||||
// Modify the cookie fields
|
||||
BNetworkCookie& SetComment(const BString& comment);
|
||||
BNetworkCookie& SetCommentUrl(const BString& commentUrl);
|
||||
BNetworkCookie& SetDiscard(bool discard);
|
||||
BNetworkCookie& SetDomain(const BString& domain);
|
||||
BNetworkCookie& SetMaxAge(int32 maxAge);
|
||||
BNetworkCookie& SetExpirationDate(time_t expireDate);
|
||||
BNetworkCookie& SetExpirationDate(BDateTime& expireDate);
|
||||
BNetworkCookie& SetPath(const BString& path);
|
||||
BNetworkCookie& SetSecure(bool secure);
|
||||
BNetworkCookie& SetVersion(int8 version);
|
||||
BNetworkCookie& SetName(const BString& name);
|
||||
BNetworkCookie& SetValue(const BString& value);
|
||||
|
||||
// Access the cookie fields
|
||||
const BString& CommentUrl() const;
|
||||
const BString& Comment() const;
|
||||
bool Discard() const;
|
||||
const BString& Domain() const;
|
||||
int32 MaxAge() const;
|
||||
time_t ExpirationDate() const;
|
||||
const BString& ExpirationString() const;
|
||||
const BString& Path() const;
|
||||
bool Secure() const;
|
||||
int8 Version() const;
|
||||
const BString& Name() const;
|
||||
const BString& Value() const;
|
||||
const BString& RawCookie(bool full) const;
|
||||
bool IsSessionCookie() const;
|
||||
bool IsValid(bool strict = false) const;
|
||||
bool IsValidForUrl(const BUrl& url) const;
|
||||
bool IsValidForDomain(const BString& domain) const;
|
||||
bool IsValidForPath(const BString& path) const;
|
||||
|
||||
// Test if cookie fields are defined
|
||||
bool HasCommentUrl() const;
|
||||
bool HasComment() const;
|
||||
bool HasDiscard() const;
|
||||
bool HasDomain() const;
|
||||
bool HasMaxAge() const;
|
||||
bool HasExpirationDate() const;
|
||||
bool HasPath() const;
|
||||
bool HasVersion() const;
|
||||
bool HasName() const;
|
||||
bool HasValue() const;
|
||||
|
||||
// Test if cookie could be deleted
|
||||
bool ShouldDeleteAtExit() const;
|
||||
bool ShouldDeleteNow() const;
|
||||
|
||||
// BArchivable members
|
||||
virtual status_t Archive(BMessage* into,
|
||||
bool deep = true) const;
|
||||
static BArchivable* Instantiate(BMessage* archive);
|
||||
|
||||
// Overloaded operators
|
||||
BNetworkCookie& operator=(const BNetworkCookie& other);
|
||||
BNetworkCookie& operator=(const char* string);
|
||||
bool operator==(const BNetworkCookie& other);
|
||||
bool operator!=(const BNetworkCookie& other);
|
||||
private:
|
||||
void _Reset();
|
||||
void _ExtractNameValuePair(
|
||||
const BString& cookieString, int16* index,
|
||||
bool parseField = false);
|
||||
|
||||
private:
|
||||
mutable BString fRawCookie;
|
||||
mutable bool fRawCookieValid;
|
||||
mutable BString fRawFullCookie;
|
||||
mutable bool fRawFullCookieValid;
|
||||
|
||||
BString fComment;
|
||||
BString fCommentUrl;
|
||||
bool fDiscard;
|
||||
BString fDomain;
|
||||
BDateTime fExpiration;
|
||||
mutable BString fExpirationString;
|
||||
mutable bool fExpirationStringValid;
|
||||
BString fPath;
|
||||
bool fSecure;
|
||||
int8 fVersion;
|
||||
BString fName;
|
||||
BString fValue;
|
||||
|
||||
bool fHasDiscard;
|
||||
bool fHasExpirationDate;
|
||||
bool fSessionCookie;
|
||||
bool fHasVersion;
|
||||
};
|
||||
|
||||
#endif // _B_NETWORK_COOKIE_H_
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright 2010 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _B_NETWORK_COOKIE_JAR_H_
|
||||
#define _B_NETWORK_COOKIE_JAR_H_
|
||||
|
||||
#include <Archivable.h>
|
||||
#include <Flattenable.h>
|
||||
#include <List.h>
|
||||
#include <Message.h>
|
||||
#include <NetworkCookie.h>
|
||||
#include <String.h>
|
||||
#include <Url.h>
|
||||
|
||||
|
||||
typedef BList BNetworkCookieList;
|
||||
|
||||
|
||||
class BNetworkCookieJar : public BArchivable, public BFlattenable {
|
||||
public:
|
||||
// Nested types
|
||||
class Iterator;
|
||||
class UrlIterator;
|
||||
struct PrivateIterator;
|
||||
struct PrivateHashMap;
|
||||
|
||||
public:
|
||||
BNetworkCookieJar();
|
||||
BNetworkCookieJar(
|
||||
const BNetworkCookieJar& other);
|
||||
BNetworkCookieJar(
|
||||
const BNetworkCookieList& otherList);
|
||||
BNetworkCookieJar(BMessage* archive);
|
||||
virtual ~BNetworkCookieJar();
|
||||
|
||||
bool AddCookie(const BNetworkCookie& cookie);
|
||||
bool AddCookie(BNetworkCookie* cookie);
|
||||
bool AddCookies(
|
||||
const BNetworkCookieList& cookies);
|
||||
|
||||
uint32 DeleteOutdatedCookies();
|
||||
uint32 PurgeForExit();
|
||||
|
||||
// BArchivable members
|
||||
virtual status_t Archive(BMessage* into,
|
||||
bool deep = true) const;
|
||||
static BArchivable* Instantiate(BMessage* archive);
|
||||
|
||||
// BFlattenable members
|
||||
virtual bool IsFixedSize() const;
|
||||
virtual type_code TypeCode() const;
|
||||
virtual ssize_t FlattenedSize() const;
|
||||
virtual status_t Flatten(void* buffer, ssize_t size)
|
||||
const;
|
||||
virtual bool AllowsTypeCode(type_code code) const;
|
||||
virtual status_t Unflatten(type_code code,
|
||||
const void* buffer, ssize_t size);
|
||||
|
||||
// Iterators
|
||||
Iterator GetIterator() const;
|
||||
UrlIterator GetUrlIterator(const BUrl& url) const;
|
||||
|
||||
private:
|
||||
void _DoFlatten() const;
|
||||
|
||||
private:
|
||||
friend class Iterator;
|
||||
friend class UrlIterator;
|
||||
|
||||
PrivateHashMap* fCookieHashMap;
|
||||
mutable BString fFlattened;
|
||||
};
|
||||
|
||||
|
||||
class BNetworkCookieJar::Iterator {
|
||||
public:
|
||||
Iterator(const Iterator& other);
|
||||
~Iterator();
|
||||
|
||||
bool HasNext() const;
|
||||
BNetworkCookie* Next();
|
||||
BNetworkCookie* NextDomain();
|
||||
BNetworkCookie* Remove();
|
||||
void RemoveDomain();
|
||||
Iterator& operator=(const Iterator& other);
|
||||
|
||||
private:
|
||||
Iterator(const BNetworkCookieJar* map);
|
||||
|
||||
void _FindNext();
|
||||
|
||||
private:
|
||||
friend class BNetworkCookieJar;
|
||||
|
||||
BNetworkCookieJar* fCookieJar;
|
||||
PrivateIterator* fIterator;
|
||||
BNetworkCookieList* fLastList;
|
||||
BNetworkCookieList* fList;
|
||||
BNetworkCookie* fElement;
|
||||
BNetworkCookie* fLastElement;
|
||||
int32 fIndex;
|
||||
};
|
||||
|
||||
|
||||
class BNetworkCookieJar::UrlIterator {
|
||||
public:
|
||||
UrlIterator(const UrlIterator& other);
|
||||
~UrlIterator();
|
||||
|
||||
bool HasNext() const;
|
||||
BNetworkCookie* Next();
|
||||
BNetworkCookie* Remove();
|
||||
UrlIterator& operator=(const UrlIterator& other);
|
||||
|
||||
private:
|
||||
UrlIterator(const BNetworkCookieJar* map,
|
||||
const BUrl& url);
|
||||
|
||||
bool _SupDomain();
|
||||
void _FindNext();
|
||||
void _FindDomain();
|
||||
bool _FindPath();
|
||||
|
||||
private:
|
||||
friend class BNetworkCookieJar;
|
||||
|
||||
BNetworkCookieJar* fCookieJar;
|
||||
PrivateIterator* fIterator;
|
||||
BNetworkCookieList* fList;
|
||||
BNetworkCookieList* fLastList;
|
||||
BNetworkCookie* fElement;
|
||||
BNetworkCookie* fLastElement;
|
||||
|
||||
int32 fIndex;
|
||||
int32 fLastIndex;
|
||||
|
||||
BUrl fUrl;
|
||||
};
|
||||
|
||||
#endif // _B_NETWORK_COOKIE_JAR_
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright 2010 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _B_URL_H_
|
||||
#define _B_URL_H_
|
||||
|
||||
|
||||
#include <Archivable.h>
|
||||
#include <Message.h>
|
||||
#include <String.h>
|
||||
|
||||
|
||||
class BUrl : public BArchivable {
|
||||
public:
|
||||
BUrl(const char* url);
|
||||
BUrl(BMessage* archive);
|
||||
BUrl(const BUrl& other);
|
||||
BUrl();
|
||||
virtual ~BUrl();
|
||||
|
||||
// URL fields modifiers
|
||||
BUrl& SetUrlString(const BString& url);
|
||||
BUrl& SetProtocol(const BString& scheme);
|
||||
BUrl& SetUserName(const BString& user);
|
||||
BUrl& SetPassword(const BString& password);
|
||||
BUrl& SetHost(const BString& host);
|
||||
BUrl& SetPort(int port);
|
||||
BUrl& SetPath(const BString& path);
|
||||
BUrl& SetRequest(const BString& request);
|
||||
BUrl& SetFragment(const BString& fragment);
|
||||
|
||||
// URL fields access
|
||||
const BString& UrlString() const;
|
||||
const BString& Protocol() const;
|
||||
const BString& UserName() const;
|
||||
const BString& Password() const;
|
||||
const BString& UserInfo() const;
|
||||
const BString& Host() const;
|
||||
int Port() const;
|
||||
const BString& Authority() const;
|
||||
const BString& Path() const;
|
||||
const BString& Request() const;
|
||||
const BString& Fragment() const;
|
||||
|
||||
// URL fields tests
|
||||
bool IsValid() const;
|
||||
bool HasProtocol() const;
|
||||
bool HasUserName() const;
|
||||
bool HasPassword() const;
|
||||
bool HasUserInfo() const;
|
||||
bool HasHost() const;
|
||||
bool HasPort() const;
|
||||
bool HasAuthority() const;
|
||||
bool HasPath() const;
|
||||
bool HasRequest() const;
|
||||
bool HasFragment() const;
|
||||
|
||||
// Url encoding/decoding of needed fields
|
||||
void UrlEncode(bool strict = false);
|
||||
void UrlDecode(bool strict = false);
|
||||
|
||||
// Url encoding/decoding of strings
|
||||
static BString UrlEncode(const BString& url,
|
||||
bool strict = false,
|
||||
bool directory = false);
|
||||
static BString UrlDecode(const BString& url,
|
||||
bool strict = false);
|
||||
|
||||
// BArchivable members
|
||||
virtual status_t Archive(BMessage* into,
|
||||
bool deep = true) const;
|
||||
static BArchivable* Instantiate(BMessage* archive);
|
||||
|
||||
// URL comparison
|
||||
bool operator==(BUrl& other) const;
|
||||
bool operator!=(BUrl& other) const;
|
||||
|
||||
// URL assignment
|
||||
const BUrl& operator=(const BUrl& other);
|
||||
const BUrl& operator=(const BString& string);
|
||||
const BUrl& operator=(const char* string);
|
||||
|
||||
// URL to string conversion
|
||||
operator const char*() const;
|
||||
|
||||
private:
|
||||
void _ResetFields();
|
||||
void _ExplodeUrlString(const BString& urlString);
|
||||
|
||||
void _ExtractProtocol(const BString& urlString,
|
||||
int16* origin);
|
||||
void _ExtractAuthority(const BString& urlString,
|
||||
int16* origin);
|
||||
void _ExtractPath(const BString& urlString,
|
||||
int16* origin);
|
||||
void _ExtractRequestAndFragment(
|
||||
const BString& urlString, int16* origin);
|
||||
|
||||
static BString _DoUrlEncodeChunk(const BString& chunk,
|
||||
bool strict, bool directory = false);
|
||||
static BString _DoUrlDecodeChunk(const BString& chunk,
|
||||
bool strict);
|
||||
|
||||
bool _IsProtocolValid();
|
||||
static bool _IsAuthorityTerminator(char c);
|
||||
static bool _IsPathTerminator(char c);
|
||||
static bool _IsRequestTerminator(char c);
|
||||
static bool _IsUnreserved(char c);
|
||||
static bool _IsGenDelim(char c);
|
||||
static bool _IsSubDelim(char c);
|
||||
|
||||
private:
|
||||
mutable BString fUrlString;
|
||||
mutable BString fAuthority;
|
||||
mutable BString fUserInfo;
|
||||
|
||||
BString fProtocol;
|
||||
BString fUser;
|
||||
BString fPassword;
|
||||
BString fHost;
|
||||
int fPort;
|
||||
BString fPath;
|
||||
BString fRequest;
|
||||
BString fFragment;
|
||||
|
||||
mutable bool fUrlStringValid : 1;
|
||||
mutable bool fAuthorityValid : 1;
|
||||
mutable bool fUserInfoValid : 1;
|
||||
|
||||
bool fBasicUri : 1;
|
||||
|
||||
bool fHasProtocol : 1;
|
||||
bool fHasUserName : 1;
|
||||
bool fHasPassword : 1;
|
||||
bool fHasUserInfo : 1;
|
||||
bool fHasHost : 1;
|
||||
bool fHasPort : 1;
|
||||
bool fHasAuthority : 1;
|
||||
bool fHasPath : 1;
|
||||
bool fHasRequest : 1;
|
||||
bool fHasFragment : 1;
|
||||
};
|
||||
|
||||
#endif // _B_URL_H_
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2010 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _B_URL_CONTEXT_H_
|
||||
#define _B_URL_CONTEXT_H_
|
||||
|
||||
|
||||
#include <NetworkCookieJar.h>
|
||||
|
||||
|
||||
class BUrlContext {
|
||||
public:
|
||||
BUrlContext();
|
||||
|
||||
// Context modifiers
|
||||
void SetCookieJar(
|
||||
const BNetworkCookieJar& cookieJar);
|
||||
|
||||
// Context accessors
|
||||
BNetworkCookieJar& GetCookieJar();
|
||||
|
||||
private:
|
||||
BNetworkCookieJar fCookieJar;
|
||||
};
|
||||
|
||||
#endif // _B_URL_CONTEXT_H_
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright 2010 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _B_URL_PROTOCOL_H_
|
||||
#define _B_URL_PROTOCOL_H_
|
||||
|
||||
|
||||
#include <Url.h>
|
||||
#include <UrlResult.h>
|
||||
#include <UrlContext.h>
|
||||
#include <UrlProtocolListener.h>
|
||||
#include <OS.h>
|
||||
|
||||
|
||||
class BUrlProtocol {
|
||||
public:
|
||||
BUrlProtocol(const BUrl& url,
|
||||
BUrlProtocolListener* listener,
|
||||
BUrlContext* context,
|
||||
BUrlResult* result,
|
||||
const char* threadName,
|
||||
const char* protocolName);
|
||||
|
||||
// URL protocol required members
|
||||
// TODO: (stippi) I know it's sometimes appealing to have these
|
||||
// "simplistic" methods that can do anything, but they remove
|
||||
// type-safety. Why not overload SetOption with all possible types?
|
||||
// Like:
|
||||
// SetOption(uint32 option, bool value);
|
||||
// SetOption(uint32 option, int8 value);
|
||||
// SetOption(uint32 option, int16 value);
|
||||
// SetOption(uint32 option, int32 value);
|
||||
// ...
|
||||
// This keeps the calling side even more simple, since it
|
||||
// don't need to do pointer stuff with the parameters. Also, since
|
||||
// this method is forced to be implemented in derived classes, why
|
||||
// is it here at all? Why not have non-virtual setters for specific
|
||||
// things, where the setter is properly named?
|
||||
virtual status_t SetOption(uint32 name, void* value) = 0;
|
||||
|
||||
// URL protocol thread management
|
||||
virtual thread_id Run();
|
||||
virtual status_t Pause();
|
||||
virtual status_t Resume();
|
||||
virtual status_t Stop();
|
||||
|
||||
// URL protocol parameters modification
|
||||
status_t SetUrl(const BUrl& url);
|
||||
status_t SetResult(BUrlResult* result);
|
||||
status_t SetContext(BUrlContext* context);
|
||||
status_t SetListener(BUrlProtocolListener* listener);
|
||||
|
||||
// URL protocol parameters access
|
||||
const BUrl& Url() const;
|
||||
BUrlResult* Result() const;
|
||||
BUrlContext* Context() const;
|
||||
BUrlProtocolListener* Listener() const;
|
||||
const BString& Protocol() const;
|
||||
// TODO: Does not belong here.
|
||||
BHttpHeaders& Headers() { return fRequestHeaders; }
|
||||
|
||||
// URL protocol informations
|
||||
bool IsRunning() const;
|
||||
status_t Status() const;
|
||||
virtual const char* StatusString(status_t threadStatus)
|
||||
const;
|
||||
|
||||
|
||||
protected:
|
||||
static int32 _ThreadEntry(void* arg);
|
||||
virtual status_t _ProtocolLoop();
|
||||
virtual void _EmitDebug(BUrlProtocolDebugMessage type,
|
||||
const char* format, ...);
|
||||
|
||||
// URL result parameters access
|
||||
BMallocIO& _ResultRawData();
|
||||
BHttpHeaders& _ResultHeaders();
|
||||
void _SetResultStatusCode(int32 statusCode);
|
||||
BString& _ResultStatusText();
|
||||
|
||||
protected:
|
||||
BUrl fUrl;
|
||||
BHttpHeaders fRequestHeaders;
|
||||
// TODO: Does not belong here.
|
||||
BUrlResult* fResult;
|
||||
BUrlContext* fContext;
|
||||
BUrlProtocolListener* fListener;
|
||||
|
||||
bool fQuit;
|
||||
bool fRunning;
|
||||
status_t fThreadStatus;
|
||||
thread_id fThreadId;
|
||||
BString fThreadName;
|
||||
BString fProtocol;
|
||||
};
|
||||
|
||||
|
||||
// TODO: Rename, this is in the global namespace.
|
||||
enum {
|
||||
B_PROT_THREAD_STATUS__BASE = 0,
|
||||
B_PROT_SUCCESS = B_PROT_THREAD_STATUS__BASE,
|
||||
B_PROT_RUNNING,
|
||||
B_PROT_PAUSED,
|
||||
B_PROT_ABORTED,
|
||||
B_PROT_SOCKET_ERROR,
|
||||
B_PROT_CONNECTION_FAILED,
|
||||
B_PROT_CANT_RESOLVE_HOSTNAME,
|
||||
B_PROT_WRITE_FAILED,
|
||||
B_PROT_READ_FAILED,
|
||||
B_PROT_NO_MEMORY,
|
||||
B_PROT_PROTOCOL_ERROR,
|
||||
// Thread status over this one are guaranteed to be
|
||||
// errors
|
||||
B_PROT_THREAD_STATUS__END
|
||||
};
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
|
||||
class BUrlProtocolOption {
|
||||
public:
|
||||
BUrlProtocolOption(void* value) : fValuePtr(value) { }
|
||||
|
||||
bool Bool() const { return *reinterpret_cast<bool*>(fValuePtr); }
|
||||
int8 Int8() const { return *reinterpret_cast<int8*>(fValuePtr); }
|
||||
int16 Int16() const { return *reinterpret_cast<int16*>(fValuePtr); }
|
||||
int32 Int32() const { return *reinterpret_cast<int32*>(fValuePtr); }
|
||||
char* String() const { return reinterpret_cast<char*>(fValuePtr); }
|
||||
void* Pointer() const { return fValuePtr; }
|
||||
|
||||
private:
|
||||
void* fValuePtr;
|
||||
};
|
||||
|
||||
} // namespace BPrivate
|
||||
|
||||
|
||||
#endif // _B_URL_PROTOCOL_H_
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2010 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _B_URL_PROTOCOL_ASYNCHRONOUS_LISTENER_H_
|
||||
#define _B_URL_PROTOCOL_ASYNCHRONOUS_LISTENER_H_
|
||||
|
||||
|
||||
#include <Handler.h>
|
||||
#include <Message.h>
|
||||
#include <UrlProtocolDispatchingListener.h>
|
||||
|
||||
|
||||
class BUrlProtocolAsynchronousListener : public BHandler {
|
||||
public:
|
||||
BUrlProtocolAsynchronousListener(
|
||||
bool transparent = false);
|
||||
virtual ~BUrlProtocolAsynchronousListener();
|
||||
|
||||
virtual void ConnectionOpened(BUrlProtocol* caller);
|
||||
virtual void HostnameResolved(BUrlProtocol* caller,
|
||||
const char* ip);
|
||||
virtual void ResponseStarted(BUrlProtocol* caller);
|
||||
virtual void HeadersReceived(BUrlProtocol* caller);
|
||||
virtual void DataReceived(BUrlProtocol* caller,
|
||||
const char* data, ssize_t size);
|
||||
virtual void DownloadProgress(BUrlProtocol* caller,
|
||||
ssize_t bytesReceived, ssize_t bytesTotal);
|
||||
virtual void UploadProgress(BUrlProtocol* caller,
|
||||
ssize_t bytesSent, ssize_t bytesTotal);
|
||||
virtual void RequestCompleted(BUrlProtocol* caller,
|
||||
bool success);
|
||||
|
||||
// Synchronous listener access
|
||||
BUrlProtocolListener* SynchronousListener();
|
||||
|
||||
// BHandler interface
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
|
||||
private:
|
||||
BUrlProtocolDispatchingListener*
|
||||
fSynchronousListener;
|
||||
};
|
||||
|
||||
#endif // _B_URL_PROTOCOL_ASYNCHRONOUS_LISTENER_H_
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2010 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _B_URL_PROTOCOL_DISPATCHING_LISTENER_H_
|
||||
#define _B_URL_PROTOCOL_DISPATCHING_LISTENER_H_
|
||||
|
||||
|
||||
#include <Messenger.h>
|
||||
#include <Message.h>
|
||||
#include <UrlProtocolListener.h>
|
||||
|
||||
|
||||
//! To be in AppTypes.h
|
||||
enum {
|
||||
B_URL_PROTOCOL_NOTIFICATION = '_UPN'
|
||||
};
|
||||
|
||||
|
||||
// Notification types
|
||||
enum {
|
||||
B_URL_PROTOCOL_CONNECTION_OPENED,
|
||||
B_URL_PROTOCOL_HOSTNAME_RESOLVED,
|
||||
B_URL_PROTOCOL_RESPONSE_STARTED,
|
||||
B_URL_PROTOCOL_HEADERS_RECEIVED,
|
||||
B_URL_PROTOCOL_DATA_RECEIVED,
|
||||
B_URL_PROTOCOL_DOWNLOAD_PROGRESS,
|
||||
B_URL_PROTOCOL_UPLOAD_PROGRESS,
|
||||
B_URL_PROTOCOL_REQUEST_COMPLETED
|
||||
};
|
||||
|
||||
|
||||
class BUrlProtocolDispatchingListener : public BUrlProtocolListener {
|
||||
public:
|
||||
BUrlProtocolDispatchingListener(
|
||||
BHandler* handler);
|
||||
BUrlProtocolDispatchingListener(
|
||||
const BMessenger& messenger);
|
||||
|
||||
virtual void ConnectionOpened(BUrlProtocol* caller);
|
||||
virtual void HostnameResolved(BUrlProtocol* caller,
|
||||
const char* ip);
|
||||
virtual void ResponseStarted(BUrlProtocol* caller);
|
||||
virtual void HeadersReceived(BUrlProtocol* caller);
|
||||
virtual void DataReceived(BUrlProtocol* caller,
|
||||
const char* data, ssize_t size);
|
||||
virtual void DownloadProgress(BUrlProtocol* caller,
|
||||
ssize_t bytesReceived, ssize_t bytesTotal);
|
||||
virtual void UploadProgress(BUrlProtocol* caller,
|
||||
ssize_t bytesSent, ssize_t bytesTotal);
|
||||
virtual void RequestCompleted(BUrlProtocol* caller,
|
||||
bool success);
|
||||
virtual void DebugMessage(BUrlProtocol*,
|
||||
BUrlProtocolDebugMessage,
|
||||
const char*) { }
|
||||
|
||||
private:
|
||||
void _SendMessage(BMessage* message,
|
||||
int8 notification, BUrlProtocol* caller);
|
||||
|
||||
private:
|
||||
BMessenger fMessenger;
|
||||
};
|
||||
|
||||
#endif // _B_URL_PROTOCOL_DISPATCHING_LISTENER_H_
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright 2010 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _B_URL_PROTOCOL_HTTP_H_
|
||||
#define _B_URL_PROTOCOL_HTTP_H_
|
||||
|
||||
|
||||
#include <deque>
|
||||
|
||||
|
||||
#include <HttpAuthentication.h>
|
||||
#include <HttpForm.h>
|
||||
#include <HttpHeaders.h>
|
||||
#include <NetEndpoint.h>
|
||||
#include <NetBuffer.h>
|
||||
#include <UrlProtocol.h>
|
||||
|
||||
|
||||
class BUrlProtocolHttp : public BUrlProtocol {
|
||||
public:
|
||||
BUrlProtocolHttp(BUrl& url,
|
||||
BUrlProtocolListener* listener = NULL,
|
||||
BUrlContext* context = NULL,
|
||||
BUrlResult* result = NULL);
|
||||
|
||||
virtual status_t SetOption(uint32 option, void* value);
|
||||
|
||||
static bool IsInformationalStatusCode(int16 code);
|
||||
static bool IsSuccessStatusCode(int16 code);
|
||||
static bool IsRedirectionStatusCode(int16 code);
|
||||
static bool IsClientErrorStatusCode(int16 code);
|
||||
static bool IsServerErrorStatusCode(int16 code);
|
||||
static int16 StatusCodeClass(int16 code);
|
||||
|
||||
virtual const char* StatusString(status_t threadStatus) const;
|
||||
|
||||
private:
|
||||
void _ResetOptions();
|
||||
status_t _ProtocolLoop();
|
||||
bool _ResolveHostName();
|
||||
status_t _MakeRequest();
|
||||
|
||||
void _CreateRequest();
|
||||
void _AddHeaders();
|
||||
|
||||
status_t _GetLine(BString& destString);
|
||||
|
||||
void _ParseStatus();
|
||||
void _ParseHeaders();
|
||||
|
||||
void _CopyChunkInBuffer(char** buffer,
|
||||
ssize_t* bytesReceived);
|
||||
|
||||
void _AddOutputBufferLine(const char* line);
|
||||
|
||||
|
||||
private:
|
||||
BNetEndpoint fSocket;
|
||||
BNetAddress fRemoteAddr;
|
||||
|
||||
int8 fRequestMethod;
|
||||
int8 fHttpVersion;
|
||||
|
||||
BString fOutputBuffer;
|
||||
BNetBuffer fInputBuffer;
|
||||
|
||||
BHttpHeaders fHeaders;
|
||||
BHttpAuthentication fAuthentication;
|
||||
|
||||
// Request status
|
||||
BHttpHeaders fOutputHeaders;
|
||||
bool fStatusReceived;
|
||||
bool fHeadersReceived;
|
||||
bool fContentReceived;
|
||||
bool fTrailingHeadersReceived;
|
||||
|
||||
|
||||
// Protocol options
|
||||
uint8 fOptMaxRedirs;
|
||||
BString fOptReferer;
|
||||
BString fOptUserAgent;
|
||||
BString fOptUsername;
|
||||
BString fOptPassword;
|
||||
uint32 fOptAuthMethods;
|
||||
BHttpHeaders* fOptHeaders;
|
||||
BHttpForm* fOptPostFields;
|
||||
BDataIO* fOptInputData;
|
||||
bool fOptSetCookies : 1;
|
||||
bool fOptFollowLocation : 1;
|
||||
bool fOptDiscardData : 1;
|
||||
bool fOptDisableListener : 1;
|
||||
bool fOptAutoReferer : 1;
|
||||
};
|
||||
|
||||
// ProtocolLoop return status
|
||||
enum {
|
||||
B_PROT_HTTP_NOT_FOUND = B_PROT_THREAD_STATUS__END,
|
||||
B_PROT_HTTP_THREAD_STATUS__END
|
||||
};
|
||||
|
||||
|
||||
// Request method
|
||||
enum {
|
||||
B_HTTP_GET = 1,
|
||||
B_HTTP_POST,
|
||||
B_HTTP_PUT,
|
||||
B_HTTP_HEAD,
|
||||
B_HTTP_DELETE,
|
||||
B_HTTP_OPTIONS
|
||||
};
|
||||
|
||||
|
||||
// HTTP Version
|
||||
enum {
|
||||
B_HTTP_10 = 1,
|
||||
B_HTTP_11
|
||||
};
|
||||
|
||||
|
||||
// HTTP Protocol options
|
||||
enum {
|
||||
B_HTTPOPT_METHOD = 0,
|
||||
// (int) Request method (see B_HTTP_GET, ...)
|
||||
B_HTTPOPT_FOLLOWLOCATION,
|
||||
// (bool) Follow Location: headers
|
||||
B_HTTPOPT_MAXREDIRS,
|
||||
// (int) Max relocation
|
||||
B_HTTPOPT_HEADERS,
|
||||
// (BHttpHeaders*) Headers to be sent
|
||||
B_HTTPOPT_REFERER,
|
||||
// (string) Referer
|
||||
B_HTTPOPT_USERAGENT,
|
||||
// (string) User-Agent
|
||||
B_HTTPOPT_SETCOOKIES,
|
||||
// (bool) Send cookies from context
|
||||
B_HTTPOPT_DISCARD_DATA,
|
||||
// (bool) Discard incoming data (still notified)
|
||||
B_HTTPOPT_DISABLE_LISTENER,
|
||||
// (bool) Don't send notification to the listener
|
||||
B_HTTPOPT_AUTOREFERER,
|
||||
// (bool) Automatically set the Referer header
|
||||
B_HTTPOPT_POSTFIELDS,
|
||||
// (BHttpForm*) POST data to be sent
|
||||
B_HTTPOPT_INPUTDATA,
|
||||
// (BDataIO*) Input data to be sent (POST, PUT)
|
||||
B_HTTPOPT_AUTHUSERNAME,
|
||||
// (string) Authentication username
|
||||
B_HTTPOPT_AUTHPASSWORD,
|
||||
// (string) Authentication password
|
||||
B_HTTPOPT_AUTHMETHOD,
|
||||
// (int) Allowed authentication methods (see BHttpAuthenticationMethod)
|
||||
|
||||
B_HTTPOPT__OPT_NUM
|
||||
};
|
||||
|
||||
|
||||
// HTTP status classes
|
||||
enum http_status_code_class {
|
||||
B_HTTP_STATUS_CLASS_INVALID = 000,
|
||||
B_HTTP_STATUS_CLASS_INFORMATIONAL = 100,
|
||||
B_HTTP_STATUS_CLASS_SUCCESS = 200,
|
||||
B_HTTP_STATUS_CLASS_REDIRECTION = 300,
|
||||
B_HTTP_STATUS_CLASS_CLIENT_ERROR = 400,
|
||||
B_HTTP_STATUS_CLASS_SERVER_ERROR = 500
|
||||
};
|
||||
|
||||
|
||||
// Known HTTP status codes
|
||||
enum http_status_code {
|
||||
// Informational status codes
|
||||
B_HTTP_STATUS__INFORMATIONAL_BASE = 100,
|
||||
B_HTTP_STATUS_CONTINUE = B_HTTP_STATUS__INFORMATIONAL_BASE,
|
||||
B_HTTP_STATUS_SWITCHING_PROTOCOLS,
|
||||
B_HTTP_STATUS__INFORMATIONAL_END,
|
||||
|
||||
// Success status codes
|
||||
B_HTTP_STATUS__SUCCESS_BASE = 200,
|
||||
B_HTTP_STATUS_OK = B_HTTP_STATUS__SUCCESS_BASE,
|
||||
B_HTTP_STATUS_CREATED,
|
||||
B_HTTP_STATUS_ACCEPTED,
|
||||
B_HTTP_STATUS_NON_AUTHORITATIVE_INFORMATION,
|
||||
B_HTTP_STATUS_NO_CONTENT,
|
||||
B_HTTP_STATUS_RESET_CONTENT,
|
||||
B_HTTP_STATUS_PARTIAL_CONTENT,
|
||||
B_HTTP_STATUS__SUCCESS_END,
|
||||
|
||||
// Redirection status codes
|
||||
B_HTTP_STATUS__REDIRECTION_BASE = 300,
|
||||
B_HTTP_STATUS_MULTIPLE_CHOICE = B_HTTP_STATUS__REDIRECTION_BASE,
|
||||
B_HTTP_STATUS_MOVED_PERMANENTLY,
|
||||
B_HTTP_STATUS_FOUND,
|
||||
B_HTTP_STATUS_SEE_OTHER,
|
||||
B_HTTP_STATUS_NOT_MODIFIED,
|
||||
B_HTTP_STATUS_USE_PROXY,
|
||||
B_HTTP_STATUS_TEMPORARY_REDIRECT,
|
||||
B_HTTP_STATUS__REDIRECTION_END,
|
||||
|
||||
// Client error status codes
|
||||
B_HTTP_STATUS__CLIENT_ERROR_BASE = 400,
|
||||
B_HTTP_STATUS_BAD_REQUEST = B_HTTP_STATUS__CLIENT_ERROR_BASE,
|
||||
B_HTTP_STATUS_UNAUTHORIZED,
|
||||
B_HTTP_STATUS_PAYMENT_REQUIRED,
|
||||
B_HTTP_STATUS_FORBIDDEN,
|
||||
B_HTTP_STATUS_NOT_FOUND,
|
||||
B_HTTP_STATUS_METHOD_NOT_ALLOWED,
|
||||
B_HTTP_STATUS_NOT_ACCEPTABLE,
|
||||
B_HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED,
|
||||
B_HTTP_STATUS_REQUEST_TIMEOUT,
|
||||
B_HTTP_STATUS_CONFLICT,
|
||||
B_HTTP_STATUS_GONE,
|
||||
B_HTTP_STATUS_LENGTH_REQUIRED,
|
||||
B_HTTP_STATUS_PRECONDITION_FAILED,
|
||||
B_HTTP_STATUS_REQUEST_ENTITY_TOO_LARGE,
|
||||
B_HTTP_STATUS_REQUEST_URI_TOO_LARGE,
|
||||
B_HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE,
|
||||
B_HTTP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE,
|
||||
B_HTTP_STATUS_EXPECTATION_FAILED,
|
||||
B_HTTP_STATUS__CLIENT_ERROR_END,
|
||||
|
||||
// Server error status codes
|
||||
B_HTTP_STATUS__SERVER_ERROR_BASE = 500,
|
||||
B_HTTP_STATUS_INTERNAL_SERVER_ERROR = B_HTTP_STATUS__SERVER_ERROR_BASE,
|
||||
B_HTTP_STATUS_NOT_IMPLEMENTED,
|
||||
B_HTTP_STATUS_BAD_GATEWAY,
|
||||
B_HTTP_STATUS_SERVICE_UNAVAILABLE,
|
||||
B_HTTP_STATUS_GATEWAY_TIMEOUT,
|
||||
B_HTTP_STATUS__SERVER_ERROR_END
|
||||
};
|
||||
|
||||
|
||||
// HTTP default User-Agent
|
||||
#define B_HTTP_PROTOCOL_USER_AGENT_FORMAT "ServicesKit (%s)"
|
||||
|
||||
#endif // _B_URL_PROTOCOL_HTTP_H_
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright 2010 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _B_URL_PROTOCOL_LISTENER_H_
|
||||
#define _B_URL_PROTOCOL_LISTENER_H_
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
#include <cstdlib>
|
||||
|
||||
class BUrlProtocol;
|
||||
|
||||
|
||||
enum BUrlProtocolDebugMessage {
|
||||
B_URL_PROTOCOL_DEBUG_TEXT,
|
||||
B_URL_PROTOCOL_DEBUG_ERROR,
|
||||
B_URL_PROTOCOL_DEBUG_HEADER_IN,
|
||||
B_URL_PROTOCOL_DEBUG_HEADER_OUT,
|
||||
B_URL_PROTOCOL_DEBUG_TRANSFER_IN,
|
||||
B_URL_PROTOCOL_DEBUG_TRANSFER_OUT
|
||||
};
|
||||
|
||||
|
||||
class BUrlProtocolListener {
|
||||
public:
|
||||
/*
|
||||
ConnectionOpened()
|
||||
Frequency: Once
|
||||
|
||||
Called when the socket is opened.
|
||||
*/
|
||||
virtual void ConnectionOpened(BUrlProtocol* caller);
|
||||
|
||||
/*
|
||||
HostnameResolved(ip)
|
||||
Frequency: Once
|
||||
Parameters: ip String representing the IP address of the resource
|
||||
host.
|
||||
|
||||
Called when the final IP is discovered
|
||||
*/
|
||||
virtual void HostnameResolved(BUrlProtocol* caller,
|
||||
const char* ip);
|
||||
|
||||
/*
|
||||
ReponseStarted()
|
||||
Frequency: Once
|
||||
|
||||
Called when the request has been emitted and the server begins to
|
||||
reply. Typically when the HTTP status code is received.
|
||||
*/
|
||||
virtual void ResponseStarted(BUrlProtocol* caller);
|
||||
|
||||
/*
|
||||
HeadersReceived()
|
||||
Frequency: Once
|
||||
|
||||
Called when all the server response metadata (such as headers) have
|
||||
been read and parsed.
|
||||
*/
|
||||
virtual void HeadersReceived(BUrlProtocol* caller);
|
||||
|
||||
/*
|
||||
DataReceived(data, size)
|
||||
Frequency: Zero or more
|
||||
Parameters: data Pointer to the data block in memory
|
||||
size Size of the data block
|
||||
|
||||
Called each time a full block of data is received.
|
||||
*/
|
||||
virtual void DataReceived(BUrlProtocol* caller,
|
||||
const char* data, ssize_t size);
|
||||
|
||||
/*
|
||||
DownloadProgress(bytesReceived, bytesTotal)
|
||||
Frequency: Once or more
|
||||
Parameters: bytesReceived Number of data bytes received
|
||||
bytesTotal Total number of data bytes expected
|
||||
|
||||
Called each time a data block is received.
|
||||
*/
|
||||
virtual void DownloadProgress(BUrlProtocol* caller,
|
||||
ssize_t bytesReceived, ssize_t bytesTotal);
|
||||
|
||||
/*
|
||||
UploadProgress(bytesSent, bytesTotal)
|
||||
Frequency: Once or more
|
||||
Parameters: bytesSent Number of data bytes sent
|
||||
bytesTotal Total number of data bytes expected
|
||||
|
||||
Called each time a data block is emitted.
|
||||
*/
|
||||
virtual void UploadProgress(BUrlProtocol* caller,
|
||||
ssize_t bytesSent, ssize_t bytesTotal);
|
||||
|
||||
/*
|
||||
RequestCompleted(success)
|
||||
Frequency: Once
|
||||
Parameters: success true if the resource have been successfully
|
||||
false if not
|
||||
|
||||
Called once the request is complete.
|
||||
*/
|
||||
virtual void RequestCompleted(BUrlProtocol* caller,
|
||||
bool success);
|
||||
|
||||
/*
|
||||
DebugMessage(type, text)
|
||||
Frequency: zero or more
|
||||
Parameters: type Type of the verbose message (see BUrlProtocolDebug)
|
||||
|
||||
Called each time a debug message is emitted
|
||||
*/
|
||||
virtual void DebugMessage(BUrlProtocol* caller,
|
||||
BUrlProtocolDebugMessage type,
|
||||
const char* text);
|
||||
};
|
||||
|
||||
#endif // _B_URL_PROTOCOL_LISTENER_H_
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2010 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _B_URL_REQUEST_H_
|
||||
#define _B_URL_REQUEST_H_
|
||||
|
||||
|
||||
#include <HttpHeaders.h>
|
||||
#include <Url.h>
|
||||
#include <UrlResult.h>
|
||||
#include <UrlContext.h>
|
||||
#include <UrlProtocol.h>
|
||||
#include <UrlProtocolListener.h>
|
||||
|
||||
|
||||
enum {
|
||||
B_NO_HANDLER_FOR_PROTOCOL = B_ERROR
|
||||
};
|
||||
|
||||
|
||||
class BUrlRequest {
|
||||
public:
|
||||
BUrlRequest(const BUrl& url,
|
||||
BUrlProtocolListener* listener);
|
||||
BUrlRequest(const BUrl& url);
|
||||
BUrlRequest(const BUrlRequest& other);
|
||||
virtual ~BUrlRequest() { };
|
||||
|
||||
// Request parameters modification
|
||||
status_t SetUrl(const BUrl& url);
|
||||
void SetContext(BUrlContext* context);
|
||||
void SetProtocolListener(
|
||||
BUrlProtocolListener* listener);
|
||||
bool SetProtocolOption(int32 option,
|
||||
void* value);
|
||||
// Request parameters access
|
||||
const BUrlProtocol* Protocol();
|
||||
const BUrlResult& Result();
|
||||
const BUrl& Url();
|
||||
|
||||
// Request control
|
||||
status_t Identify();
|
||||
virtual status_t Perform();
|
||||
// TODO: Rename to Run() perhaps? "Perform" is used for FBC stuff.
|
||||
virtual status_t Pause();
|
||||
virtual status_t Resume();
|
||||
virtual status_t Abort();
|
||||
|
||||
// Request informations
|
||||
virtual bool InitCheck() const;
|
||||
bool IsRunning() const;
|
||||
status_t Status() const;
|
||||
|
||||
// Overloaded members
|
||||
BUrlRequest& operator=(const BUrlRequest& other);
|
||||
|
||||
|
||||
protected:
|
||||
BUrlProtocolListener* fListener;
|
||||
BUrlProtocol* fUrlProtocol;
|
||||
BUrlResult fResult;
|
||||
BUrlContext* fContext;
|
||||
BUrl fUrl;
|
||||
bool fReady;
|
||||
};
|
||||
|
||||
#endif // _B_URL_REQUEST_H_
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2010 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _B_URL_RESULT_H_
|
||||
#define _B_URL_RESULT_H_
|
||||
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <DataIO.h>
|
||||
#include <HttpHeaders.h>
|
||||
#include <String.h>
|
||||
#include <Url.h>
|
||||
|
||||
|
||||
class BUrlProtocol;
|
||||
|
||||
|
||||
class BUrlResult {
|
||||
friend class BUrlProtocol;
|
||||
|
||||
public:
|
||||
BUrlResult(const BUrl& url);
|
||||
BUrlResult(const BUrlResult& other);
|
||||
|
||||
// Result parameters modifications
|
||||
void SetUrl(const BUrl& url);
|
||||
|
||||
// Result parameters access
|
||||
const BUrl& Url() const;
|
||||
const BMallocIO& RawData() const;
|
||||
const BHttpHeaders& Headers() const;
|
||||
const BString& StatusText() const;
|
||||
int32 StatusCode() const;
|
||||
|
||||
// Result tests
|
||||
bool HasHeaders() const;
|
||||
|
||||
// Overloaded members
|
||||
BUrlResult& operator=(const BUrlResult& other);
|
||||
friend std::ostream& operator<<(std::ostream& out,
|
||||
const BUrlResult& result);
|
||||
|
||||
private:
|
||||
BUrl fUrl;
|
||||
BMallocIO fRawData;
|
||||
BHttpHeaders fHeaders;
|
||||
// TODO: HTTP specific stuff should not live here.
|
||||
|
||||
int32 fStatusCode;
|
||||
BString fStatusString;
|
||||
};
|
||||
|
||||
|
||||
#endif // _B_URL_RESULT_H_
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2010 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _B_URL_SYNCHRONOUS_REQUEST_H_
|
||||
#define _B_URL_SYNCHRONOUS_REQUEST_H_
|
||||
|
||||
|
||||
#include <UrlRequest.h>
|
||||
#include <UrlProtocolListener.h>
|
||||
|
||||
|
||||
class BUrlSynchronousRequest : public BUrlRequest, public BUrlProtocolListener {
|
||||
public:
|
||||
BUrlSynchronousRequest(BUrl& url);
|
||||
virtual ~BUrlSynchronousRequest() { };
|
||||
|
||||
// Synchronous wait
|
||||
virtual status_t Perform();
|
||||
virtual status_t WaitUntilCompletion();
|
||||
|
||||
// Protocol hooks
|
||||
virtual void ConnectionOpened(BUrlProtocol* caller);
|
||||
virtual void HostnameResolved(BUrlProtocol* caller,
|
||||
const char* ip);
|
||||
virtual void ResponseStarted(BUrlProtocol* caller);
|
||||
virtual void HeadersReceived(BUrlProtocol* caller);
|
||||
virtual void DataReceived(BUrlProtocol* caller,
|
||||
const char* data, ssize_t size);
|
||||
virtual void DownloadProgress(BUrlProtocol* caller,
|
||||
ssize_t bytesReceived, ssize_t bytesTotal);
|
||||
virtual void UploadProgress(BUrlProtocol* caller,
|
||||
ssize_t bytesSent, ssize_t bytesTotal);
|
||||
virtual void RequestCompleted(BUrlProtocol* caller,
|
||||
bool success);
|
||||
|
||||
|
||||
protected:
|
||||
bool fRequestComplete;
|
||||
};
|
||||
|
||||
|
||||
#endif // _B_URL_SYNCHRONOUS_REQUEST_H_
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2010 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _B_HTTP_TIME_H_
|
||||
#define _B_HTTP_TIME_H_
|
||||
|
||||
#include <ctime>
|
||||
|
||||
#include <String.h>
|
||||
|
||||
namespace BPrivate {
|
||||
|
||||
enum {
|
||||
B_HTTP_TIME_FORMAT_PARSED = -1,
|
||||
B_HTTP_TIME_FORMAT_RFC1123 = 0,
|
||||
B_HTTP_TIME_FORMAT_PREFERRED = B_HTTP_TIME_FORMAT_RFC1123,
|
||||
B_HTTP_TIME_FORMAT_COOKIE,
|
||||
B_HTTP_TIME_FORMAT_RFC1036,
|
||||
B_HTTP_TIME_FORMAT_ASCTIME
|
||||
};
|
||||
|
||||
|
||||
class BHttpTime {
|
||||
public:
|
||||
BHttpTime();
|
||||
BHttpTime(time_t date);
|
||||
BHttpTime(const BString& dateString);
|
||||
|
||||
// Date modification
|
||||
void SetString(const BString& string);
|
||||
void SetDate(time_t date);
|
||||
|
||||
|
||||
// Date conversion
|
||||
time_t Parse();
|
||||
BString ToString(int8 format = B_HTTP_TIME_FORMAT_PARSED);
|
||||
|
||||
private:
|
||||
BString fDateString;
|
||||
time_t fDate;
|
||||
int8 fDateFormat;
|
||||
};
|
||||
|
||||
}
|
||||
#endif // _B_HTTP_TIME_H_
|
||||
Reference in New Issue
Block a user