Refactor UrlRequest/UrlProtocol in the Service Kit
* Remove the BUrlRequest class, which was only delegating work to BUrlProtocol and subclasses * Rename BUrlProtocol to BUrlRequest, and BUrlRequestHttp to BHttpRequest * Creating a request is now done through the BUrlProtocolRoster. For now there is just a static MakeRequest method, this will be completed when we get to actually allowing add-ons to provide different request handlers. This allows cleanup of the API for requests: * Remove the universal SetOption method with constants, and have dedicated setters for each protocol option. * Setters can now have multiple parameters, for example you can give BHTTPRequest a BDataIO and a known size * In this case, the BHttpRequest will not use HTTP chunked transfers, which were always used before and made most servers unhappy (tested and failed with lighttpd, google accounts and github).
This commit is contained in:
@@ -60,8 +60,7 @@ public:
|
|||||||
|
|
||||||
// Change behavior
|
// Change behavior
|
||||||
status_t MarkAsFile(const BString& filename,
|
status_t MarkAsFile(const BString& filename,
|
||||||
const BString& mimeType);
|
const BString& mimeType = "");
|
||||||
status_t MarkAsFile(const BString& filename);
|
|
||||||
void UnmarkAsFile();
|
void UnmarkAsFile();
|
||||||
status_t CopyBuffer();
|
status_t CopyBuffer();
|
||||||
|
|
||||||
|
|||||||
@@ -14,22 +14,34 @@
|
|||||||
#include <HttpHeaders.h>
|
#include <HttpHeaders.h>
|
||||||
#include <NetBuffer.h>
|
#include <NetBuffer.h>
|
||||||
#include <NetworkAddress.h>
|
#include <NetworkAddress.h>
|
||||||
#include <UrlProtocol.h>
|
#include <UrlRequest.h>
|
||||||
|
|
||||||
|
|
||||||
class BAbstractSocket;
|
class BAbstractSocket;
|
||||||
|
|
||||||
|
|
||||||
class BUrlProtocolHttp : public BUrlProtocol {
|
class BHttpRequest : public BUrlRequest {
|
||||||
public:
|
public:
|
||||||
BUrlProtocolHttp(BUrl& url, bool ssl = false,
|
BHttpRequest(const BUrl& url,
|
||||||
|
BUrlResult& result, bool ssl = false,
|
||||||
const char *protocolName = "HTTP",
|
const char *protocolName = "HTTP",
|
||||||
BUrlProtocolListener* listener = NULL,
|
BUrlProtocolListener* listener = NULL,
|
||||||
BUrlContext* context = NULL,
|
BUrlContext* context = NULL);
|
||||||
BUrlResult* result = NULL);
|
virtual ~BHttpRequest();
|
||||||
virtual ~BUrlProtocolHttp();
|
|
||||||
|
|
||||||
virtual status_t SetOption(uint32 option, void* value);
|
void SetMethod(int8 method);
|
||||||
|
void SetFollowLocation(bool follow);
|
||||||
|
void SetMaxRedirections(int8 maxRedirections);
|
||||||
|
void SetReferrer(const BString& referrer);
|
||||||
|
void SetUserAgent(const BString& agent);
|
||||||
|
void SetHeaders(BHttpHeaders* headers);
|
||||||
|
void SetDiscardData(bool discard);
|
||||||
|
void SetDisableListener(bool disable);
|
||||||
|
void SetAutoReferrer(bool enable);
|
||||||
|
void SetPostFields(BHttpForm* fields);
|
||||||
|
void SetInputData(BDataIO* data, ssize_t size = -1);
|
||||||
|
void SetUserName(const BString& name);
|
||||||
|
void SetPassword(const BString& password);
|
||||||
|
|
||||||
static bool IsInformationalStatusCode(int16 code);
|
static bool IsInformationalStatusCode(int16 code);
|
||||||
static bool IsSuccessStatusCode(int16 code);
|
static bool IsSuccessStatusCode(int16 code);
|
||||||
@@ -89,6 +101,7 @@ private:
|
|||||||
BHttpHeaders* fOptHeaders;
|
BHttpHeaders* fOptHeaders;
|
||||||
BHttpForm* fOptPostFields;
|
BHttpForm* fOptPostFields;
|
||||||
BDataIO* fOptInputData;
|
BDataIO* fOptInputData;
|
||||||
|
ssize_t fOptInputDataSize;
|
||||||
bool fOptSetCookies : 1;
|
bool fOptSetCookies : 1;
|
||||||
bool fOptFollowLocation : 1;
|
bool fOptFollowLocation : 1;
|
||||||
bool fOptDiscardData : 1;
|
bool fOptDiscardData : 1;
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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);
|
|
||||||
virtual ~BUrlProtocol();
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
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_
|
|
||||||
@@ -17,18 +17,18 @@ public:
|
|||||||
bool transparent = false);
|
bool transparent = false);
|
||||||
virtual ~BUrlProtocolAsynchronousListener();
|
virtual ~BUrlProtocolAsynchronousListener();
|
||||||
|
|
||||||
virtual void ConnectionOpened(BUrlProtocol* caller);
|
virtual void ConnectionOpened(BUrlRequest* caller);
|
||||||
virtual void HostnameResolved(BUrlProtocol* caller,
|
virtual void HostnameResolved(BUrlRequest* caller,
|
||||||
const char* ip);
|
const char* ip);
|
||||||
virtual void ResponseStarted(BUrlProtocol* caller);
|
virtual void ResponseStarted(BUrlRequest* caller);
|
||||||
virtual void HeadersReceived(BUrlProtocol* caller);
|
virtual void HeadersReceived(BUrlRequest* caller);
|
||||||
virtual void DataReceived(BUrlProtocol* caller,
|
virtual void DataReceived(BUrlRequest* caller,
|
||||||
const char* data, ssize_t size);
|
const char* data, ssize_t size);
|
||||||
virtual void DownloadProgress(BUrlProtocol* caller,
|
virtual void DownloadProgress(BUrlRequest* caller,
|
||||||
ssize_t bytesReceived, ssize_t bytesTotal);
|
ssize_t bytesReceived, ssize_t bytesTotal);
|
||||||
virtual void UploadProgress(BUrlProtocol* caller,
|
virtual void UploadProgress(BUrlRequest* caller,
|
||||||
ssize_t bytesSent, ssize_t bytesTotal);
|
ssize_t bytesSent, ssize_t bytesTotal);
|
||||||
virtual void RequestCompleted(BUrlProtocol* caller,
|
virtual void RequestCompleted(BUrlRequest* caller,
|
||||||
bool success);
|
bool success);
|
||||||
|
|
||||||
// Synchronous listener access
|
// Synchronous listener access
|
||||||
|
|||||||
@@ -38,26 +38,23 @@ public:
|
|||||||
const BMessenger& messenger);
|
const BMessenger& messenger);
|
||||||
virtual ~BUrlProtocolDispatchingListener();
|
virtual ~BUrlProtocolDispatchingListener();
|
||||||
|
|
||||||
virtual void ConnectionOpened(BUrlProtocol* caller);
|
virtual void ConnectionOpened(BUrlRequest* caller);
|
||||||
virtual void HostnameResolved(BUrlProtocol* caller,
|
virtual void HostnameResolved(BUrlRequest* caller,
|
||||||
const char* ip);
|
const char* ip);
|
||||||
virtual void ResponseStarted(BUrlProtocol* caller);
|
virtual void ResponseStarted(BUrlRequest* caller);
|
||||||
virtual void HeadersReceived(BUrlProtocol* caller);
|
virtual void HeadersReceived(BUrlRequest* caller);
|
||||||
virtual void DataReceived(BUrlProtocol* caller,
|
virtual void DataReceived(BUrlRequest* caller,
|
||||||
const char* data, ssize_t size);
|
const char* data, ssize_t size);
|
||||||
virtual void DownloadProgress(BUrlProtocol* caller,
|
virtual void DownloadProgress(BUrlRequest* caller,
|
||||||
ssize_t bytesReceived, ssize_t bytesTotal);
|
ssize_t bytesReceived, ssize_t bytesTotal);
|
||||||
virtual void UploadProgress(BUrlProtocol* caller,
|
virtual void UploadProgress(BUrlRequest* caller,
|
||||||
ssize_t bytesSent, ssize_t bytesTotal);
|
ssize_t bytesSent, ssize_t bytesTotal);
|
||||||
virtual void RequestCompleted(BUrlProtocol* caller,
|
virtual void RequestCompleted(BUrlRequest* caller,
|
||||||
bool success);
|
bool success);
|
||||||
virtual void DebugMessage(BUrlProtocol*,
|
|
||||||
BUrlProtocolDebugMessage,
|
|
||||||
const char*) { }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _SendMessage(BMessage* message,
|
void _SendMessage(BMessage* message,
|
||||||
int8 notification, BUrlProtocol* caller);
|
int8 notification, BUrlRequest* caller);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BMessenger fMessenger;
|
BMessenger fMessenger;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
class BUrlProtocol;
|
class BUrlRequest;
|
||||||
|
|
||||||
|
|
||||||
enum BUrlProtocolDebugMessage {
|
enum BUrlProtocolDebugMessage {
|
||||||
@@ -24,15 +24,15 @@ enum BUrlProtocolDebugMessage {
|
|||||||
|
|
||||||
class BUrlProtocolListener {
|
class BUrlProtocolListener {
|
||||||
public:
|
public:
|
||||||
/*
|
/**
|
||||||
ConnectionOpened()
|
ConnectionOpened()
|
||||||
Frequency: Once
|
Frequency: Once
|
||||||
|
|
||||||
Called when the socket is opened.
|
Called when the socket is opened.
|
||||||
*/
|
*/
|
||||||
virtual void ConnectionOpened(BUrlProtocol* caller);
|
virtual void ConnectionOpened(BUrlRequest* caller);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
HostnameResolved(ip)
|
HostnameResolved(ip)
|
||||||
Frequency: Once
|
Frequency: Once
|
||||||
Parameters: ip String representing the IP address of the resource
|
Parameters: ip String representing the IP address of the resource
|
||||||
@@ -40,28 +40,28 @@ public:
|
|||||||
|
|
||||||
Called when the final IP is discovered
|
Called when the final IP is discovered
|
||||||
*/
|
*/
|
||||||
virtual void HostnameResolved(BUrlProtocol* caller,
|
virtual void HostnameResolved(BUrlRequest* caller,
|
||||||
const char* ip);
|
const char* ip);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
ReponseStarted()
|
ReponseStarted()
|
||||||
Frequency: Once
|
Frequency: Once
|
||||||
|
|
||||||
Called when the request has been emitted and the server begins to
|
Called when the request has been emitted and the server begins to
|
||||||
reply. Typically when the HTTP status code is received.
|
reply. Typically when the HTTP status code is received.
|
||||||
*/
|
*/
|
||||||
virtual void ResponseStarted(BUrlProtocol* caller);
|
virtual void ResponseStarted(BUrlRequest* caller);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
HeadersReceived()
|
HeadersReceived()
|
||||||
Frequency: Once
|
Frequency: Once
|
||||||
|
|
||||||
Called when all the server response metadata (such as headers) have
|
Called when all the server response metadata (such as headers) have
|
||||||
been read and parsed.
|
been read and parsed.
|
||||||
*/
|
*/
|
||||||
virtual void HeadersReceived(BUrlProtocol* caller);
|
virtual void HeadersReceived(BUrlRequest* caller);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
DataReceived(data, size)
|
DataReceived(data, size)
|
||||||
Frequency: Zero or more
|
Frequency: Zero or more
|
||||||
Parameters: data Pointer to the data block in memory
|
Parameters: data Pointer to the data block in memory
|
||||||
@@ -69,10 +69,10 @@ public:
|
|||||||
|
|
||||||
Called each time a full block of data is received.
|
Called each time a full block of data is received.
|
||||||
*/
|
*/
|
||||||
virtual void DataReceived(BUrlProtocol* caller,
|
virtual void DataReceived(BUrlRequest* caller,
|
||||||
const char* data, ssize_t size);
|
const char* data, ssize_t size);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
DownloadProgress(bytesReceived, bytesTotal)
|
DownloadProgress(bytesReceived, bytesTotal)
|
||||||
Frequency: Once or more
|
Frequency: Once or more
|
||||||
Parameters: bytesReceived Number of data bytes received
|
Parameters: bytesReceived Number of data bytes received
|
||||||
@@ -80,10 +80,10 @@ public:
|
|||||||
|
|
||||||
Called each time a data block is received.
|
Called each time a data block is received.
|
||||||
*/
|
*/
|
||||||
virtual void DownloadProgress(BUrlProtocol* caller,
|
virtual void DownloadProgress(BUrlRequest* caller,
|
||||||
ssize_t bytesReceived, ssize_t bytesTotal);
|
ssize_t bytesReceived, ssize_t bytesTotal);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
UploadProgress(bytesSent, bytesTotal)
|
UploadProgress(bytesSent, bytesTotal)
|
||||||
Frequency: Once or more
|
Frequency: Once or more
|
||||||
Parameters: bytesSent Number of data bytes sent
|
Parameters: bytesSent Number of data bytes sent
|
||||||
@@ -91,10 +91,10 @@ public:
|
|||||||
|
|
||||||
Called each time a data block is emitted.
|
Called each time a data block is emitted.
|
||||||
*/
|
*/
|
||||||
virtual void UploadProgress(BUrlProtocol* caller,
|
virtual void UploadProgress(BUrlRequest* caller,
|
||||||
ssize_t bytesSent, ssize_t bytesTotal);
|
ssize_t bytesSent, ssize_t bytesTotal);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
RequestCompleted(success)
|
RequestCompleted(success)
|
||||||
Frequency: Once
|
Frequency: Once
|
||||||
Parameters: success true if the resource have been successfully
|
Parameters: success true if the resource have been successfully
|
||||||
@@ -102,17 +102,17 @@ public:
|
|||||||
|
|
||||||
Called once the request is complete.
|
Called once the request is complete.
|
||||||
*/
|
*/
|
||||||
virtual void RequestCompleted(BUrlProtocol* caller,
|
virtual void RequestCompleted(BUrlRequest* caller,
|
||||||
bool success);
|
bool success);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
DebugMessage(type, text)
|
DebugMessage(type, text)
|
||||||
Frequency: zero or more
|
Frequency: zero or more
|
||||||
Parameters: type Type of the verbose message (see BUrlProtocolDebug)
|
Parameters: type Type of the verbose message (see BUrlProtocolDebug)
|
||||||
|
|
||||||
Called each time a debug message is emitted
|
Called each time a debug message is emitted
|
||||||
*/
|
*/
|
||||||
virtual void DebugMessage(BUrlProtocol* caller,
|
virtual void DebugMessage(BUrlRequest* caller,
|
||||||
BUrlProtocolDebugMessage type,
|
BUrlProtocolDebugMessage type,
|
||||||
const char* text);
|
const char* text);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 Haiku Inc. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _B_URL_ROSTER_H_
|
||||||
|
#define _B_URL_ROSTER_H_
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
|
class BUrl;
|
||||||
|
class BUrlContext;
|
||||||
|
class BUrlProtocolListener;
|
||||||
|
class BUrlRequest;
|
||||||
|
|
||||||
|
class BUrlProtocolRoster {
|
||||||
|
public:
|
||||||
|
static BUrlRequest* MakeRequest(const BUrl& url,
|
||||||
|
BUrlProtocolListener* listener = NULL,
|
||||||
|
BUrlContext* context = NULL);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
+67
-38
@@ -6,64 +6,93 @@
|
|||||||
#define _B_URL_REQUEST_H_
|
#define _B_URL_REQUEST_H_
|
||||||
|
|
||||||
|
|
||||||
#include <HttpHeaders.h>
|
|
||||||
#include <Url.h>
|
#include <Url.h>
|
||||||
#include <UrlResult.h>
|
#include <UrlResult.h>
|
||||||
#include <UrlContext.h>
|
#include <UrlContext.h>
|
||||||
#include <UrlProtocol.h>
|
|
||||||
#include <UrlProtocolListener.h>
|
#include <UrlProtocolListener.h>
|
||||||
|
#include <OS.h>
|
||||||
|
|
||||||
enum {
|
|
||||||
B_NO_HANDLER_FOR_PROTOCOL = B_ERROR
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class BUrlRequest {
|
class BUrlRequest {
|
||||||
public:
|
public:
|
||||||
BUrlRequest(const BUrl& url,
|
BUrlRequest(const BUrl& url,
|
||||||
BUrlProtocolListener* listener = NULL,
|
BUrlProtocolListener* listener,
|
||||||
BUrlContext* context = NULL);
|
BUrlContext* context,
|
||||||
BUrlRequest(const BUrlRequest& other);
|
BUrlResult& result,
|
||||||
|
const char* threadName,
|
||||||
|
const char* protocolName);
|
||||||
virtual ~BUrlRequest();
|
virtual ~BUrlRequest();
|
||||||
|
|
||||||
// Request parameters modification
|
// URL protocol thread management
|
||||||
status_t SetUrl(const BUrl& url);
|
virtual thread_id Run();
|
||||||
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
|
|
||||||
virtual status_t Start();
|
|
||||||
virtual status_t Pause();
|
virtual status_t Pause();
|
||||||
virtual status_t Resume();
|
virtual status_t Resume();
|
||||||
virtual status_t Abort();
|
virtual status_t Stop();
|
||||||
|
|
||||||
// Request informations
|
// URL protocol parameters modification
|
||||||
virtual status_t InitCheck() const;
|
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;
|
||||||
|
|
||||||
|
// URL protocol informations
|
||||||
bool IsRunning() const;
|
bool IsRunning() const;
|
||||||
status_t Status() const;
|
status_t Status() const;
|
||||||
|
virtual const char* StatusString(status_t threadStatus)
|
||||||
// Overloaded members
|
const;
|
||||||
BUrlRequest& operator=(const BUrlRequest& other);
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
BUrlProtocolListener* fListener;
|
static int32 _ThreadEntry(void* arg);
|
||||||
BUrlProtocol* fUrlProtocol;
|
virtual status_t _ProtocolLoop();
|
||||||
BUrlResult fResult;
|
virtual void _EmitDebug(BUrlProtocolDebugMessage type,
|
||||||
BUrlContext* fContext;
|
const char* format, ...);
|
||||||
BUrl fUrl;
|
|
||||||
status_t fInitStatus;
|
|
||||||
|
|
||||||
private:
|
// URL result parameters access
|
||||||
status_t _SetupProtocol();
|
BMallocIO& _ResultRawData();
|
||||||
|
BHttpHeaders& _ResultHeaders();
|
||||||
|
void _SetResultStatusCode(int32 statusCode);
|
||||||
|
BString& _ResultStatusText();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BUrl fUrl;
|
||||||
|
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
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _B_URL_REQUEST_H_
|
#endif // _B_URL_REQUEST_H_
|
||||||
|
|||||||
@@ -14,11 +14,11 @@
|
|||||||
#include <Url.h>
|
#include <Url.h>
|
||||||
|
|
||||||
|
|
||||||
class BUrlProtocol;
|
class BUrlRequest;
|
||||||
|
|
||||||
|
|
||||||
class BUrlResult {
|
class BUrlResult {
|
||||||
friend class BUrlProtocol;
|
friend class BUrlRequest;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BUrlResult(const BUrl& url);
|
BUrlResult(const BUrl& url);
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
class BUrlSynchronousRequest : public BUrlRequest, public BUrlProtocolListener {
|
class BUrlSynchronousRequest : public BUrlRequest, public BUrlProtocolListener {
|
||||||
public:
|
public:
|
||||||
BUrlSynchronousRequest(BUrl& url);
|
BUrlSynchronousRequest(BUrlRequest& asynchronousRequest);
|
||||||
virtual ~BUrlSynchronousRequest() { };
|
virtual ~BUrlSynchronousRequest() { };
|
||||||
|
|
||||||
// Synchronous wait
|
// Synchronous wait
|
||||||
@@ -20,23 +20,24 @@ public:
|
|||||||
virtual status_t WaitUntilCompletion();
|
virtual status_t WaitUntilCompletion();
|
||||||
|
|
||||||
// Protocol hooks
|
// Protocol hooks
|
||||||
virtual void ConnectionOpened(BUrlProtocol* caller);
|
virtual void ConnectionOpened(BUrlRequest* caller);
|
||||||
virtual void HostnameResolved(BUrlProtocol* caller,
|
virtual void HostnameResolved(BUrlRequest* caller,
|
||||||
const char* ip);
|
const char* ip);
|
||||||
virtual void ResponseStarted(BUrlProtocol* caller);
|
virtual void ResponseStarted(BUrlRequest* caller);
|
||||||
virtual void HeadersReceived(BUrlProtocol* caller);
|
virtual void HeadersReceived(BUrlRequest* caller);
|
||||||
virtual void DataReceived(BUrlProtocol* caller,
|
virtual void DataReceived(BUrlRequest* caller,
|
||||||
const char* data, ssize_t size);
|
const char* data, ssize_t size);
|
||||||
virtual void DownloadProgress(BUrlProtocol* caller,
|
virtual void DownloadProgress(BUrlRequest* caller,
|
||||||
ssize_t bytesReceived, ssize_t bytesTotal);
|
ssize_t bytesReceived, ssize_t bytesTotal);
|
||||||
virtual void UploadProgress(BUrlProtocol* caller,
|
virtual void UploadProgress(BUrlRequest* caller,
|
||||||
ssize_t bytesSent, ssize_t bytesTotal);
|
ssize_t bytesSent, ssize_t bytesTotal);
|
||||||
virtual void RequestCompleted(BUrlProtocol* caller,
|
virtual void RequestCompleted(BUrlRequest* caller,
|
||||||
bool success);
|
bool success);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool fRequestComplete;
|
bool fRequestComplete;
|
||||||
|
BUrlRequest& fWrappedRequest;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -184,13 +184,6 @@ BHttpFormData::MarkAsFile(const BString& filename, const BString& mimeType)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
BHttpFormData::MarkAsFile(const BString& filename)
|
|
||||||
{
|
|
||||||
return MarkAsFile(filename, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BHttpFormData::UnmarkAsFile()
|
BHttpFormData::UnmarkAsFile()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -277,6 +277,8 @@ BHttpHeaders::Clear()
|
|||||||
BHttpHeaders&
|
BHttpHeaders&
|
||||||
BHttpHeaders::operator=(const BHttpHeaders& other)
|
BHttpHeaders::operator=(const BHttpHeaders& other)
|
||||||
{
|
{
|
||||||
|
Clear();
|
||||||
|
|
||||||
for (int32 i = 0; i < other.CountHeaders(); i++)
|
for (int32 i = 0; i < other.CountHeaders(); i++)
|
||||||
AddHeader(other.HeaderAt(i).Name(), other.HeaderAt(i).Value());
|
AddHeader(other.HeaderAt(i).Name(), other.HeaderAt(i).Value());
|
||||||
|
|
||||||
|
|||||||
+128
-93
@@ -17,10 +17,7 @@
|
|||||||
#include <File.h>
|
#include <File.h>
|
||||||
#include <Socket.h>
|
#include <Socket.h>
|
||||||
#include <SecureSocket.h>
|
#include <SecureSocket.h>
|
||||||
#include <UrlProtocolHttp.h>
|
#include <HttpRequest.h>
|
||||||
|
|
||||||
|
|
||||||
using BPrivate::BUrlProtocolOption;
|
|
||||||
|
|
||||||
|
|
||||||
static const int32 kHttpProtocolReceiveBufferSize = 1024;
|
static const int32 kHttpProtocolReceiveBufferSize = 1024;
|
||||||
@@ -31,11 +28,11 @@ static const char* kHttpProtocolThreadStrStatus[
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
BUrlProtocolHttp::BUrlProtocolHttp(BUrl& url, bool ssl,
|
BHttpRequest::BHttpRequest(const BUrl& url, BUrlResult& result, bool ssl,
|
||||||
const char* protocolName, BUrlProtocolListener* listener,
|
const char* protocolName, BUrlProtocolListener* listener,
|
||||||
BUrlContext* context, BUrlResult* result)
|
BUrlContext* context)
|
||||||
:
|
:
|
||||||
BUrlProtocol(url, listener, context, result, "BUrlProtocol.HTTP", protocolName),
|
BUrlRequest(url, listener, context, result, "BUrlProtocol.HTTP", protocolName),
|
||||||
fSSL(ssl),
|
fSSL(ssl),
|
||||||
fRequestMethod(B_HTTP_GET),
|
fRequestMethod(B_HTTP_GET),
|
||||||
fHttpVersion(B_HTTP_11)
|
fHttpVersion(B_HTTP_11)
|
||||||
@@ -48,83 +45,109 @@ BUrlProtocolHttp::BUrlProtocolHttp(BUrl& url, bool ssl,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BUrlProtocolHttp::~BUrlProtocolHttp()
|
BHttpRequest::~BHttpRequest()
|
||||||
{
|
{
|
||||||
delete fSocket;
|
delete fSocket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
void
|
||||||
BUrlProtocolHttp::SetOption(uint32 name, void* value)
|
BHttpRequest::SetMethod(int8 method)
|
||||||
{
|
{
|
||||||
BUrlProtocolOption option(value);
|
fRequestMethod = method;
|
||||||
|
}
|
||||||
|
|
||||||
switch (name) {
|
|
||||||
case B_HTTPOPT_METHOD:
|
|
||||||
fRequestMethod = option.Int8();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_HTTPOPT_FOLLOWLOCATION:
|
void
|
||||||
fOptFollowLocation = option.Bool();
|
BHttpRequest::SetFollowLocation(bool follow)
|
||||||
break;
|
{
|
||||||
|
fOptFollowLocation = follow;
|
||||||
|
}
|
||||||
|
|
||||||
case B_HTTPOPT_MAXREDIRS:
|
|
||||||
fOptMaxRedirs = option.Int8();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_HTTPOPT_REFERER:
|
void
|
||||||
fOptReferer = option.String();
|
BHttpRequest::SetMaxRedirections(int8 redirections)
|
||||||
break;
|
{
|
||||||
|
fOptMaxRedirs = redirections;
|
||||||
|
}
|
||||||
|
|
||||||
case B_HTTPOPT_USERAGENT:
|
|
||||||
fOptUserAgent = option.String();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_HTTPOPT_HEADERS:
|
void
|
||||||
fOptHeaders = reinterpret_cast<BHttpHeaders*>(option.Pointer());
|
BHttpRequest::SetReferrer(const BString& referrer)
|
||||||
break;
|
{
|
||||||
|
fOptReferer = referrer;
|
||||||
|
}
|
||||||
|
|
||||||
case B_HTTPOPT_DISCARD_DATA:
|
|
||||||
fOptDiscardData = option.Bool();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_HTTPOPT_DISABLE_LISTENER:
|
void
|
||||||
fOptDisableListener = option.Bool();
|
BHttpRequest::SetUserAgent(const BString& agent)
|
||||||
break;
|
{
|
||||||
|
fOptUserAgent = agent;
|
||||||
|
}
|
||||||
|
|
||||||
case B_HTTPOPT_AUTOREFERER:
|
|
||||||
fOptAutoReferer = option.Bool();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_HTTPOPT_POSTFIELDS:
|
void
|
||||||
fOptPostFields = reinterpret_cast<BHttpForm*>(option.Pointer());
|
BHttpRequest::SetHeaders(BHttpHeaders* headers)
|
||||||
|
{
|
||||||
|
fOptHeaders = headers;
|
||||||
|
}
|
||||||
|
|
||||||
if (fOptPostFields != NULL)
|
|
||||||
fRequestMethod = B_HTTP_POST;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_HTTPOPT_INPUTDATA:
|
void
|
||||||
fOptInputData = reinterpret_cast<BDataIO*>(option.Pointer());
|
BHttpRequest::SetDiscardData(bool discard)
|
||||||
break;
|
{
|
||||||
|
fOptDiscardData = discard;
|
||||||
|
}
|
||||||
|
|
||||||
case B_HTTPOPT_AUTHUSERNAME:
|
|
||||||
fOptUsername = option.String();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_HTTPOPT_AUTHPASSWORD:
|
void
|
||||||
fOptPassword = option.String();
|
BHttpRequest::SetDisableListener(bool disable)
|
||||||
break;
|
{
|
||||||
|
fOptDisableListener = disable;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return B_OK;
|
void
|
||||||
|
BHttpRequest::SetAutoReferrer(bool enable)
|
||||||
|
{
|
||||||
|
fOptAutoReferer = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BHttpRequest::SetPostFields(BHttpForm* fields)
|
||||||
|
{
|
||||||
|
fOptPostFields = fields;
|
||||||
|
|
||||||
|
if (fOptPostFields != NULL)
|
||||||
|
fRequestMethod = B_HTTP_POST;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BHttpRequest::SetInputData(BDataIO* data, ssize_t size)
|
||||||
|
{
|
||||||
|
fOptInputData = data;
|
||||||
|
fOptInputDataSize = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BHttpRequest::SetUserName(const BString& name)
|
||||||
|
{
|
||||||
|
fOptUsername = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BHttpRequest::SetPassword(const BString& password)
|
||||||
|
{
|
||||||
|
fOptPassword = password;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*static*/ bool
|
/*static*/ bool
|
||||||
BUrlProtocolHttp::IsInformationalStatusCode(int16 code)
|
BHttpRequest::IsInformationalStatusCode(int16 code)
|
||||||
{
|
{
|
||||||
return (code >= B_HTTP_STATUS__INFORMATIONAL_BASE)
|
return (code >= B_HTTP_STATUS__INFORMATIONAL_BASE)
|
||||||
&& (code < B_HTTP_STATUS__INFORMATIONAL_END);
|
&& (code < B_HTTP_STATUS__INFORMATIONAL_END);
|
||||||
@@ -132,7 +155,7 @@ BUrlProtocolHttp::IsInformationalStatusCode(int16 code)
|
|||||||
|
|
||||||
|
|
||||||
/*static*/ bool
|
/*static*/ bool
|
||||||
BUrlProtocolHttp::IsSuccessStatusCode(int16 code)
|
BHttpRequest::IsSuccessStatusCode(int16 code)
|
||||||
{
|
{
|
||||||
return (code >= B_HTTP_STATUS__SUCCESS_BASE)
|
return (code >= B_HTTP_STATUS__SUCCESS_BASE)
|
||||||
&& (code < B_HTTP_STATUS__SUCCESS_END);
|
&& (code < B_HTTP_STATUS__SUCCESS_END);
|
||||||
@@ -140,7 +163,7 @@ BUrlProtocolHttp::IsSuccessStatusCode(int16 code)
|
|||||||
|
|
||||||
|
|
||||||
/*static*/ bool
|
/*static*/ bool
|
||||||
BUrlProtocolHttp::IsRedirectionStatusCode(int16 code)
|
BHttpRequest::IsRedirectionStatusCode(int16 code)
|
||||||
{
|
{
|
||||||
return (code >= B_HTTP_STATUS__REDIRECTION_BASE)
|
return (code >= B_HTTP_STATUS__REDIRECTION_BASE)
|
||||||
&& (code < B_HTTP_STATUS__REDIRECTION_END);
|
&& (code < B_HTTP_STATUS__REDIRECTION_END);
|
||||||
@@ -148,7 +171,7 @@ BUrlProtocolHttp::IsRedirectionStatusCode(int16 code)
|
|||||||
|
|
||||||
|
|
||||||
/*static*/ bool
|
/*static*/ bool
|
||||||
BUrlProtocolHttp::IsClientErrorStatusCode(int16 code)
|
BHttpRequest::IsClientErrorStatusCode(int16 code)
|
||||||
{
|
{
|
||||||
return (code >= B_HTTP_STATUS__CLIENT_ERROR_BASE)
|
return (code >= B_HTTP_STATUS__CLIENT_ERROR_BASE)
|
||||||
&& (code < B_HTTP_STATUS__CLIENT_ERROR_END);
|
&& (code < B_HTTP_STATUS__CLIENT_ERROR_END);
|
||||||
@@ -156,7 +179,7 @@ BUrlProtocolHttp::IsClientErrorStatusCode(int16 code)
|
|||||||
|
|
||||||
|
|
||||||
/*static*/ bool
|
/*static*/ bool
|
||||||
BUrlProtocolHttp::IsServerErrorStatusCode(int16 code)
|
BHttpRequest::IsServerErrorStatusCode(int16 code)
|
||||||
{
|
{
|
||||||
return (code >= B_HTTP_STATUS__SERVER_ERROR_BASE)
|
return (code >= B_HTTP_STATUS__SERVER_ERROR_BASE)
|
||||||
&& (code < B_HTTP_STATUS__SERVER_ERROR_END);
|
&& (code < B_HTTP_STATUS__SERVER_ERROR_END);
|
||||||
@@ -164,17 +187,17 @@ BUrlProtocolHttp::IsServerErrorStatusCode(int16 code)
|
|||||||
|
|
||||||
|
|
||||||
/*static*/ int16
|
/*static*/ int16
|
||||||
BUrlProtocolHttp::StatusCodeClass(int16 code)
|
BHttpRequest::StatusCodeClass(int16 code)
|
||||||
{
|
{
|
||||||
if (BUrlProtocolHttp::IsInformationalStatusCode(code))
|
if (BHttpRequest::IsInformationalStatusCode(code))
|
||||||
return B_HTTP_STATUS_CLASS_INFORMATIONAL;
|
return B_HTTP_STATUS_CLASS_INFORMATIONAL;
|
||||||
else if (BUrlProtocolHttp::IsSuccessStatusCode(code))
|
else if (BHttpRequest::IsSuccessStatusCode(code))
|
||||||
return B_HTTP_STATUS_CLASS_SUCCESS;
|
return B_HTTP_STATUS_CLASS_SUCCESS;
|
||||||
else if (BUrlProtocolHttp::IsRedirectionStatusCode(code))
|
else if (BHttpRequest::IsRedirectionStatusCode(code))
|
||||||
return B_HTTP_STATUS_CLASS_REDIRECTION;
|
return B_HTTP_STATUS_CLASS_REDIRECTION;
|
||||||
else if (BUrlProtocolHttp::IsClientErrorStatusCode(code))
|
else if (BHttpRequest::IsClientErrorStatusCode(code))
|
||||||
return B_HTTP_STATUS_CLASS_CLIENT_ERROR;
|
return B_HTTP_STATUS_CLASS_CLIENT_ERROR;
|
||||||
else if (BUrlProtocolHttp::IsServerErrorStatusCode(code))
|
else if (BHttpRequest::IsServerErrorStatusCode(code))
|
||||||
return B_HTTP_STATUS_CLASS_SERVER_ERROR;
|
return B_HTTP_STATUS_CLASS_SERVER_ERROR;
|
||||||
|
|
||||||
return B_HTTP_STATUS_CLASS_INVALID;
|
return B_HTTP_STATUS_CLASS_INVALID;
|
||||||
@@ -182,12 +205,12 @@ BUrlProtocolHttp::StatusCodeClass(int16 code)
|
|||||||
|
|
||||||
|
|
||||||
const char*
|
const char*
|
||||||
BUrlProtocolHttp::StatusString(status_t threadStatus) const
|
BHttpRequest::StatusString(status_t threadStatus) const
|
||||||
{
|
{
|
||||||
if (threadStatus < B_PROT_THREAD_STATUS__END)
|
if (threadStatus < B_PROT_THREAD_STATUS__END)
|
||||||
return BUrlProtocol::StatusString(threadStatus);
|
return BUrlRequest::StatusString(threadStatus);
|
||||||
else if (threadStatus >= B_PROT_HTTP_THREAD_STATUS__END)
|
else if (threadStatus >= B_PROT_HTTP_THREAD_STATUS__END)
|
||||||
return BUrlProtocol::StatusString(-1);
|
return BUrlRequest::StatusString(-1);
|
||||||
else
|
else
|
||||||
return kHttpProtocolThreadStrStatus[threadStatus
|
return kHttpProtocolThreadStrStatus[threadStatus
|
||||||
- B_PROT_THREAD_STATUS__END];
|
- B_PROT_THREAD_STATUS__END];
|
||||||
@@ -195,7 +218,7 @@ BUrlProtocolHttp::StatusString(status_t threadStatus) const
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolHttp::_ResetOptions()
|
BHttpRequest::_ResetOptions()
|
||||||
{
|
{
|
||||||
fOptFollowLocation = true;
|
fOptFollowLocation = true;
|
||||||
fOptMaxRedirs = 8;
|
fOptMaxRedirs = 8;
|
||||||
@@ -215,7 +238,7 @@ BUrlProtocolHttp::_ResetOptions()
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
status_t
|
status_t
|
||||||
BUrlProtocolHttp::_ProtocolLoop()
|
BHttpRequest::_ProtocolLoop()
|
||||||
{
|
{
|
||||||
printf("UHP[%p]::{Loop} %s\n", this, fUrl.UrlString().String());
|
printf("UHP[%p]::{Loop} %s\n", this, fUrl.UrlString().String());
|
||||||
|
|
||||||
@@ -252,7 +275,7 @@ BUrlProtocolHttp::_ProtocolLoop()
|
|||||||
if (fOptAutoReferer)
|
if (fOptAutoReferer)
|
||||||
fOptReferer = fUrl.UrlString();
|
fOptReferer = fUrl.UrlString();
|
||||||
|
|
||||||
switch (StatusCodeClass(fResult->StatusCode())) {
|
switch (StatusCodeClass(fResult.StatusCode())) {
|
||||||
case B_HTTP_STATUS_CLASS_INFORMATIONAL:
|
case B_HTTP_STATUS_CLASS_INFORMATIONAL:
|
||||||
// Header 100:continue should have been
|
// Header 100:continue should have been
|
||||||
// handled in the _MakeRequest read loop
|
// handled in the _MakeRequest read loop
|
||||||
@@ -268,7 +291,7 @@ BUrlProtocolHttp::_ProtocolLoop()
|
|||||||
|
|
||||||
// TODO: Some browsers seems to translate POST requests to
|
// TODO: Some browsers seems to translate POST requests to
|
||||||
// GET when following a 302 redirection
|
// GET when following a 302 redirection
|
||||||
if (fResult->StatusCode() == B_HTTP_STATUS_MOVED_PERMANENTLY) {
|
if (fResult.StatusCode() == B_HTTP_STATUS_MOVED_PERMANENTLY) {
|
||||||
BString locationUrl = fHeaders["Location"];
|
BString locationUrl = fHeaders["Location"];
|
||||||
|
|
||||||
// Absolute path
|
// Absolute path
|
||||||
@@ -289,7 +312,7 @@ BUrlProtocolHttp::_ProtocolLoop()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case B_HTTP_STATUS_CLASS_CLIENT_ERROR:
|
case B_HTTP_STATUS_CLASS_CLIENT_ERROR:
|
||||||
switch (fResult->StatusCode()) {
|
switch (fResult.StatusCode()) {
|
||||||
case B_HTTP_STATUS_UNAUTHORIZED:
|
case B_HTTP_STATUS_UNAUTHORIZED:
|
||||||
if (fAuthentication.Method() != B_HTTP_AUTHENTICATION_NONE) {
|
if (fAuthentication.Method() != B_HTTP_AUTHENTICATION_NONE) {
|
||||||
newRequest = false;
|
newRequest = false;
|
||||||
@@ -321,7 +344,7 @@ BUrlProtocolHttp::_ProtocolLoop()
|
|||||||
"%ld headers and %ld bytes of data remaining",
|
"%ld headers and %ld bytes of data remaining",
|
||||||
fHeaders.CountHeaders(), fInputBuffer.Size());
|
fHeaders.CountHeaders(), fInputBuffer.Size());
|
||||||
|
|
||||||
if (fResult->StatusCode() == 404)
|
if (fResult.StatusCode() == 404)
|
||||||
return B_PROT_HTTP_NOT_FOUND;
|
return B_PROT_HTTP_NOT_FOUND;
|
||||||
|
|
||||||
return B_PROT_SUCCESS;
|
return B_PROT_SUCCESS;
|
||||||
@@ -329,7 +352,7 @@ BUrlProtocolHttp::_ProtocolLoop()
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BUrlProtocolHttp::_ResolveHostName()
|
BHttpRequest::_ResolveHostName()
|
||||||
{
|
{
|
||||||
_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Resolving %s",
|
_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Resolving %s",
|
||||||
fUrl.UrlString().String());
|
fUrl.UrlString().String());
|
||||||
@@ -357,7 +380,7 @@ BUrlProtocolHttp::_ResolveHostName()
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BUrlProtocolHttp::_MakeRequest()
|
BHttpRequest::_MakeRequest()
|
||||||
{
|
{
|
||||||
_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Connection to %s on port %d.",
|
_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Connection to %s on port %d.",
|
||||||
fUrl.Authority().String(), fRemoteAddr.Port());
|
fUrl.Authority().String(), fRemoteAddr.Port());
|
||||||
@@ -442,13 +465,19 @@ BUrlProtocolHttp::_MakeRequest()
|
|||||||
read = fOptInputData->Read(outputTempBuffer, 1024);
|
read = fOptInputData->Read(outputTempBuffer, 1024);
|
||||||
|
|
||||||
if (read > 0) {
|
if (read > 0) {
|
||||||
char hexSize[16];
|
if (fOptInputDataSize < 0)
|
||||||
size_t hexLength = sprintf(hexSize, "%ld", read);
|
{
|
||||||
|
// Chunked transfer
|
||||||
|
char hexSize[16];
|
||||||
|
size_t hexLength = sprintf(hexSize, "%ld", read);
|
||||||
|
|
||||||
fSocket->Write(hexSize, hexLength);
|
fSocket->Write(hexSize, hexLength);
|
||||||
fSocket->Write("\r\n", 2);
|
fSocket->Write("\r\n", 2);
|
||||||
fSocket->Write(outputTempBuffer, read);
|
fSocket->Write(outputTempBuffer, read);
|
||||||
fSocket->Write("\r\n", 2);
|
fSocket->Write("\r\n", 2);
|
||||||
|
} else {
|
||||||
|
fSocket->Write(outputTempBuffer, read);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -626,7 +655,7 @@ BUrlProtocolHttp::_MakeRequest()
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BUrlProtocolHttp::_GetLine(BString& destString)
|
BHttpRequest::_GetLine(BString& destString)
|
||||||
{
|
{
|
||||||
// Find a complete line in inputBuffer
|
// Find a complete line in inputBuffer
|
||||||
uint32 characterIndex = 0;
|
uint32 characterIndex = 0;
|
||||||
@@ -653,7 +682,7 @@ BUrlProtocolHttp::_GetLine(BString& destString)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolHttp::_ParseStatus()
|
BHttpRequest::_ParseStatus()
|
||||||
{
|
{
|
||||||
// Status line should be formatted like: HTTP/M.m SSS ...
|
// Status line should be formatted like: HTTP/M.m SSS ...
|
||||||
// With: M = Major version of the protocol
|
// With: M = Major version of the protocol
|
||||||
@@ -682,7 +711,7 @@ BUrlProtocolHttp::_ParseStatus()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolHttp::_ParseHeaders()
|
BHttpRequest::_ParseHeaders()
|
||||||
{
|
{
|
||||||
BString currentHeader;
|
BString currentHeader;
|
||||||
if (_GetLine(currentHeader) == B_ERROR)
|
if (_GetLine(currentHeader) == B_ERROR)
|
||||||
@@ -700,7 +729,7 @@ BUrlProtocolHttp::_ParseHeaders()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolHttp::_CreateRequest()
|
BHttpRequest::_CreateRequest()
|
||||||
{
|
{
|
||||||
BString request;
|
BString request;
|
||||||
|
|
||||||
@@ -748,7 +777,7 @@ BUrlProtocolHttp::_CreateRequest()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolHttp::_AddHeaders()
|
BHttpRequest::_AddHeaders()
|
||||||
{
|
{
|
||||||
// HTTP 1.1 additional headers
|
// HTTP 1.1 additional headers
|
||||||
if (fHttpVersion == B_HTTP_11) {
|
if (fHttpVersion == B_HTTP_11) {
|
||||||
@@ -813,8 +842,14 @@ BUrlProtocolHttp::_AddHeaders()
|
|||||||
fOutputHeaders.AddHeader("Content-Length",
|
fOutputHeaders.AddHeader("Content-Length",
|
||||||
fOptPostFields->ContentLength());
|
fOptPostFields->ContentLength());
|
||||||
} else if (fOptInputData != NULL
|
} else if (fOptInputData != NULL
|
||||||
&& (fRequestMethod == B_HTTP_POST || fRequestMethod == B_HTTP_PUT))
|
&& (fRequestMethod == B_HTTP_POST || fRequestMethod == B_HTTP_PUT))
|
||||||
fOutputHeaders.AddHeader("Transfer-Encoding", "chunked");
|
{
|
||||||
|
if(fOptInputDataSize >= 0) {
|
||||||
|
fOutputHeaders.AddHeader("Content-Length", fOptInputDataSize);
|
||||||
|
} else {
|
||||||
|
fOutputHeaders.AddHeader("Transfer-Encoding", "chunked");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Optional headers specified by the user
|
// Optional headers specified by the user
|
||||||
if (fOptHeaders != NULL) {
|
if (fOptHeaders != NULL) {
|
||||||
@@ -850,7 +885,7 @@ BUrlProtocolHttp::_AddHeaders()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolHttp::_AddOutputBufferLine(const char* line)
|
BHttpRequest::_AddOutputBufferLine(const char* line)
|
||||||
{
|
{
|
||||||
_EmitDebug(B_URL_PROTOCOL_DEBUG_HEADER_OUT, "%s", line);
|
_EmitDebug(B_URL_PROTOCOL_DEBUG_HEADER_OUT, "%s", line);
|
||||||
fOutputBuffer << line << "\r\n";
|
fOutputBuffer << line << "\r\n";
|
||||||
@@ -54,23 +54,20 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
|||||||
# TODO: The HTTP stuff should all go into an add-on. It needs
|
# TODO: The HTTP stuff should all go into an add-on. It needs
|
||||||
# linking against libcrypto.so and only the add-on should link
|
# linking against libcrypto.so and only the add-on should link
|
||||||
# against it.
|
# against it.
|
||||||
# Building of the commented out files has not been completely tested
|
|
||||||
# after integrating the code from the GSoC 2010 "Services Kit"
|
|
||||||
# project and doing some renaming of types, constants and methods.
|
|
||||||
HttpAuthentication.cpp
|
HttpAuthentication.cpp
|
||||||
HttpHeaders.cpp
|
HttpHeaders.cpp
|
||||||
HttpForm.cpp
|
HttpForm.cpp
|
||||||
|
HttpRequest.cpp
|
||||||
HttpTime.cpp
|
HttpTime.cpp
|
||||||
|
|
||||||
$(md5Sources)
|
$(md5Sources)
|
||||||
|
|
||||||
Url.cpp
|
Url.cpp
|
||||||
UrlContext.cpp
|
UrlContext.cpp
|
||||||
UrlProtocol.cpp
|
|
||||||
UrlProtocolAsynchronousListener.cpp
|
UrlProtocolAsynchronousListener.cpp
|
||||||
UrlProtocolDispatchingListener.cpp
|
UrlProtocolDispatchingListener.cpp
|
||||||
UrlProtocolHttp.cpp # TODO: -> add-on, See above.
|
|
||||||
UrlProtocolListener.cpp
|
UrlProtocolListener.cpp
|
||||||
|
UrlProtocolRoster.cpp
|
||||||
UrlRequest.cpp
|
UrlRequest.cpp
|
||||||
UrlResult.cpp
|
UrlResult.cpp
|
||||||
UrlSynchronousRequest.cpp
|
UrlSynchronousRequest.cpp
|
||||||
|
|||||||
@@ -1,303 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010 Haiku Inc. All rights reserved.
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Christophe Huriaux, [email protected]
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <UrlProtocol.h>
|
|
||||||
#include <Debug.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
|
|
||||||
static const char* kProtocolThreadStrStatus[B_PROT_THREAD_STATUS__END+1]
|
|
||||||
= {
|
|
||||||
"Request successfully completed",
|
|
||||||
"Request running",
|
|
||||||
"Socket error",
|
|
||||||
"Connection failed",
|
|
||||||
"Hostname resolution failed",
|
|
||||||
"Network write failed",
|
|
||||||
"Network read failed",
|
|
||||||
"Out of memory",
|
|
||||||
"Protocol-specific error",
|
|
||||||
"Unknown error"
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
BUrlProtocol::BUrlProtocol(const BUrl& url, BUrlProtocolListener* listener,
|
|
||||||
BUrlContext* context, BUrlResult* result, const char* threadName,
|
|
||||||
const char* protocolName)
|
|
||||||
:
|
|
||||||
fUrl(url),
|
|
||||||
fResult(result),
|
|
||||||
fContext(context),
|
|
||||||
fListener(listener),
|
|
||||||
fQuit(false),
|
|
||||||
fRunning(false),
|
|
||||||
fThreadId(0),
|
|
||||||
fThreadName(threadName),
|
|
||||||
fProtocol(protocolName)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BUrlProtocol::~BUrlProtocol()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark URL protocol thread management
|
|
||||||
|
|
||||||
|
|
||||||
thread_id
|
|
||||||
BUrlProtocol::Run()
|
|
||||||
{
|
|
||||||
// Thread already running
|
|
||||||
if (fRunning) {
|
|
||||||
PRINT(("BUrlProtocol::Run() : Oops, already running ! "
|
|
||||||
"[urlProtocol=%p]!\n", this));
|
|
||||||
return fThreadId;
|
|
||||||
}
|
|
||||||
|
|
||||||
fThreadId = spawn_thread(BUrlProtocol::_ThreadEntry, fThreadName,
|
|
||||||
B_NORMAL_PRIORITY, this);
|
|
||||||
|
|
||||||
if (fThreadId < B_OK)
|
|
||||||
return fThreadId;
|
|
||||||
|
|
||||||
status_t launchErr = resume_thread(fThreadId);
|
|
||||||
if (launchErr < B_OK) {
|
|
||||||
PRINT(("BUrlProtocol::Run() : Failed to resume thread %ld\n",
|
|
||||||
fThreadId));
|
|
||||||
return launchErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
fRunning = true;
|
|
||||||
return fThreadId;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
BUrlProtocol::Pause()
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
BUrlProtocol::Resume()
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
BUrlProtocol::Stop()
|
|
||||||
{
|
|
||||||
if (!fRunning)
|
|
||||||
return B_ERROR;
|
|
||||||
|
|
||||||
status_t threadStatus = B_OK;
|
|
||||||
fQuit = true;
|
|
||||||
|
|
||||||
wait_for_thread(fThreadId, &threadStatus);
|
|
||||||
return threadStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark URL protocol parameters modification
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
BUrlProtocol::SetUrl(const BUrl& url)
|
|
||||||
{
|
|
||||||
// We should avoid to change URL while the thread is running ...
|
|
||||||
if (IsRunning())
|
|
||||||
return B_ERROR;
|
|
||||||
|
|
||||||
fUrl = url;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
BUrlProtocol::SetResult(BUrlResult* result)
|
|
||||||
{
|
|
||||||
if (IsRunning())
|
|
||||||
return B_ERROR;
|
|
||||||
|
|
||||||
fResult = result;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
BUrlProtocol::SetContext(BUrlContext* context)
|
|
||||||
{
|
|
||||||
if (IsRunning())
|
|
||||||
return B_ERROR;
|
|
||||||
|
|
||||||
fContext = context;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
BUrlProtocol::SetListener(BUrlProtocolListener* listener)
|
|
||||||
{
|
|
||||||
if (IsRunning())
|
|
||||||
return B_ERROR;
|
|
||||||
|
|
||||||
fListener = listener;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark URL protocol parameters access
|
|
||||||
|
|
||||||
|
|
||||||
const BUrl&
|
|
||||||
BUrlProtocol::Url() const
|
|
||||||
{
|
|
||||||
return fUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BUrlResult*
|
|
||||||
BUrlProtocol::Result() const
|
|
||||||
{
|
|
||||||
return fResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BUrlContext*
|
|
||||||
BUrlProtocol::Context() const
|
|
||||||
{
|
|
||||||
return fContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BUrlProtocolListener*
|
|
||||||
BUrlProtocol::Listener() const
|
|
||||||
{
|
|
||||||
return fListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const BString&
|
|
||||||
BUrlProtocol::Protocol() const
|
|
||||||
{
|
|
||||||
return fProtocol;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark URL protocol informations
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
BUrlProtocol::IsRunning() const
|
|
||||||
{
|
|
||||||
return fRunning;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
BUrlProtocol::Status() const
|
|
||||||
{
|
|
||||||
return fThreadStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const char*
|
|
||||||
BUrlProtocol::StatusString(status_t threadStatus) const
|
|
||||||
{
|
|
||||||
if (threadStatus < B_PROT_THREAD_STATUS__BASE)
|
|
||||||
threadStatus = B_PROT_THREAD_STATUS__END;
|
|
||||||
else if (threadStatus >= B_PROT_PROTOCOL_ERROR)
|
|
||||||
threadStatus = B_PROT_PROTOCOL_ERROR;
|
|
||||||
|
|
||||||
return kProtocolThreadStrStatus[threadStatus];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark Thread management
|
|
||||||
|
|
||||||
|
|
||||||
/*static*/ int32
|
|
||||||
BUrlProtocol::_ThreadEntry(void* arg)
|
|
||||||
{
|
|
||||||
BUrlProtocol* urlProtocol = reinterpret_cast<BUrlProtocol*>(arg);
|
|
||||||
urlProtocol->fThreadStatus = B_PROT_RUNNING;
|
|
||||||
|
|
||||||
status_t protocolLoopExitStatus = urlProtocol->_ProtocolLoop();
|
|
||||||
|
|
||||||
urlProtocol->fRunning = false;
|
|
||||||
urlProtocol->fThreadStatus = protocolLoopExitStatus;
|
|
||||||
|
|
||||||
if (urlProtocol->fListener != NULL)
|
|
||||||
urlProtocol->fListener->RequestCompleted(urlProtocol,
|
|
||||||
protocolLoopExitStatus == B_PROT_SUCCESS);
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
BUrlProtocol::_ProtocolLoop()
|
|
||||||
{
|
|
||||||
// Dummy _ProtocolLoop
|
|
||||||
while (!fQuit)
|
|
||||||
snooze(1000);
|
|
||||||
|
|
||||||
return B_PROT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
BUrlProtocol::_EmitDebug(BUrlProtocolDebugMessage type,
|
|
||||||
const char* format, ...)
|
|
||||||
{
|
|
||||||
if (fListener == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
va_list arguments;
|
|
||||||
va_start(arguments, format);
|
|
||||||
|
|
||||||
char debugMsg[256];
|
|
||||||
vsnprintf(debugMsg, 256, format, arguments);
|
|
||||||
fListener->DebugMessage(this, type, debugMsg);
|
|
||||||
va_end(arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BMallocIO&
|
|
||||||
BUrlProtocol::_ResultRawData()
|
|
||||||
{
|
|
||||||
return fResult->fRawData;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BHttpHeaders&
|
|
||||||
BUrlProtocol::_ResultHeaders()
|
|
||||||
{
|
|
||||||
return fResult->fHeaders;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
BUrlProtocol::_SetResultStatusCode(int32 statusCode)
|
|
||||||
{
|
|
||||||
fResult->fStatusCode = statusCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BString&
|
|
||||||
BUrlProtocol::_ResultStatusText()
|
|
||||||
{
|
|
||||||
return fResult->fStatusString;
|
|
||||||
}
|
|
||||||
@@ -46,52 +46,52 @@ BUrlProtocolAsynchronousListener::~BUrlProtocolAsynchronousListener()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolAsynchronousListener::ConnectionOpened(BUrlProtocol*)
|
BUrlProtocolAsynchronousListener::ConnectionOpened(BUrlRequest*)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolAsynchronousListener::HostnameResolved(BUrlProtocol*, const char*)
|
BUrlProtocolAsynchronousListener::HostnameResolved(BUrlRequest*, const char*)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolAsynchronousListener::ResponseStarted(BUrlProtocol*)
|
BUrlProtocolAsynchronousListener::ResponseStarted(BUrlRequest*)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolAsynchronousListener::HeadersReceived(BUrlProtocol*)
|
BUrlProtocolAsynchronousListener::HeadersReceived(BUrlRequest*)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolAsynchronousListener::DataReceived(BUrlProtocol*, const char*,
|
BUrlProtocolAsynchronousListener::DataReceived(BUrlRequest*, const char*,
|
||||||
ssize_t)
|
ssize_t)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolAsynchronousListener::DownloadProgress(BUrlProtocol*, ssize_t,
|
BUrlProtocolAsynchronousListener::DownloadProgress(BUrlRequest*, ssize_t,
|
||||||
ssize_t)
|
ssize_t)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolAsynchronousListener::UploadProgress(BUrlProtocol*, ssize_t,
|
BUrlProtocolAsynchronousListener::UploadProgress(BUrlRequest*, ssize_t,
|
||||||
ssize_t)
|
ssize_t)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolAsynchronousListener::RequestCompleted(BUrlProtocol*, bool)
|
BUrlProtocolAsynchronousListener::RequestCompleted(BUrlRequest*, bool)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ BUrlProtocolAsynchronousListener::MessageReceived(BMessage* message)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BUrlProtocol* caller;
|
BUrlRequest* caller;
|
||||||
if (message->FindPointer(kUrlProtocolCaller,
|
if (message->FindPointer(kUrlProtocolCaller,
|
||||||
reinterpret_cast<void**>(&caller)) != B_OK)
|
reinterpret_cast<void**>(&caller)) != B_OK)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ BUrlProtocolDispatchingListener::~BUrlProtocolDispatchingListener()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolDispatchingListener::ConnectionOpened(BUrlProtocol* caller)
|
BUrlProtocolDispatchingListener::ConnectionOpened(BUrlRequest* caller)
|
||||||
{
|
{
|
||||||
BMessage message(B_URL_PROTOCOL_NOTIFICATION);
|
BMessage message(B_URL_PROTOCOL_NOTIFICATION);
|
||||||
_SendMessage(&message, B_URL_PROTOCOL_CONNECTION_OPENED, caller);
|
_SendMessage(&message, B_URL_PROTOCOL_CONNECTION_OPENED, caller);
|
||||||
@@ -45,7 +45,7 @@ BUrlProtocolDispatchingListener::ConnectionOpened(BUrlProtocol* caller)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolDispatchingListener::HostnameResolved(BUrlProtocol* caller,
|
BUrlProtocolDispatchingListener::HostnameResolved(BUrlRequest* caller,
|
||||||
const char* ip)
|
const char* ip)
|
||||||
{
|
{
|
||||||
BMessage message(B_URL_PROTOCOL_NOTIFICATION);
|
BMessage message(B_URL_PROTOCOL_NOTIFICATION);
|
||||||
@@ -56,7 +56,7 @@ BUrlProtocolDispatchingListener::HostnameResolved(BUrlProtocol* caller,
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolDispatchingListener::ResponseStarted(BUrlProtocol* caller)
|
BUrlProtocolDispatchingListener::ResponseStarted(BUrlRequest* caller)
|
||||||
{
|
{
|
||||||
BMessage message(B_URL_PROTOCOL_NOTIFICATION);
|
BMessage message(B_URL_PROTOCOL_NOTIFICATION);
|
||||||
_SendMessage(&message, B_URL_PROTOCOL_RESPONSE_STARTED, caller);
|
_SendMessage(&message, B_URL_PROTOCOL_RESPONSE_STARTED, caller);
|
||||||
@@ -64,7 +64,7 @@ BUrlProtocolDispatchingListener::ResponseStarted(BUrlProtocol* caller)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolDispatchingListener::HeadersReceived(BUrlProtocol* caller)
|
BUrlProtocolDispatchingListener::HeadersReceived(BUrlRequest* caller)
|
||||||
{
|
{
|
||||||
BMessage message(B_URL_PROTOCOL_NOTIFICATION);
|
BMessage message(B_URL_PROTOCOL_NOTIFICATION);
|
||||||
_SendMessage(&message, B_URL_PROTOCOL_HEADERS_RECEIVED, caller);
|
_SendMessage(&message, B_URL_PROTOCOL_HEADERS_RECEIVED, caller);
|
||||||
@@ -72,7 +72,7 @@ BUrlProtocolDispatchingListener::HeadersReceived(BUrlProtocol* caller)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolDispatchingListener::DataReceived(BUrlProtocol* caller,
|
BUrlProtocolDispatchingListener::DataReceived(BUrlRequest* caller,
|
||||||
const char* data, ssize_t size)
|
const char* data, ssize_t size)
|
||||||
{
|
{
|
||||||
BMessage message(B_URL_PROTOCOL_NOTIFICATION);
|
BMessage message(B_URL_PROTOCOL_NOTIFICATION);
|
||||||
@@ -83,7 +83,7 @@ BUrlProtocolDispatchingListener::DataReceived(BUrlProtocol* caller,
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolDispatchingListener::DownloadProgress(BUrlProtocol* caller,
|
BUrlProtocolDispatchingListener::DownloadProgress(BUrlRequest* caller,
|
||||||
ssize_t bytesReceived, ssize_t bytesTotal)
|
ssize_t bytesReceived, ssize_t bytesTotal)
|
||||||
{
|
{
|
||||||
BMessage message(B_URL_PROTOCOL_NOTIFICATION);
|
BMessage message(B_URL_PROTOCOL_NOTIFICATION);
|
||||||
@@ -95,7 +95,7 @@ BUrlProtocolDispatchingListener::DownloadProgress(BUrlProtocol* caller,
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolDispatchingListener::UploadProgress(BUrlProtocol* caller,
|
BUrlProtocolDispatchingListener::UploadProgress(BUrlRequest* caller,
|
||||||
ssize_t bytesSent, ssize_t bytesTotal)
|
ssize_t bytesSent, ssize_t bytesTotal)
|
||||||
{
|
{
|
||||||
BMessage message(B_URL_PROTOCOL_NOTIFICATION);
|
BMessage message(B_URL_PROTOCOL_NOTIFICATION);
|
||||||
@@ -108,7 +108,7 @@ BUrlProtocolDispatchingListener::UploadProgress(BUrlProtocol* caller,
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolDispatchingListener::RequestCompleted(BUrlProtocol* caller,
|
BUrlProtocolDispatchingListener::RequestCompleted(BUrlRequest* caller,
|
||||||
bool success)
|
bool success)
|
||||||
{
|
{
|
||||||
BMessage message(B_URL_PROTOCOL_NOTIFICATION);
|
BMessage message(B_URL_PROTOCOL_NOTIFICATION);
|
||||||
@@ -120,7 +120,7 @@ BUrlProtocolDispatchingListener::RequestCompleted(BUrlProtocol* caller,
|
|||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolDispatchingListener::_SendMessage(BMessage* message,
|
BUrlProtocolDispatchingListener::_SendMessage(BMessage* message,
|
||||||
int8 notification, BUrlProtocol* caller)
|
int8 notification, BUrlRequest* caller)
|
||||||
{
|
{
|
||||||
ASSERT(message != NULL);
|
ASSERT(message != NULL);
|
||||||
|
|
||||||
|
|||||||
@@ -9,62 +9,62 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
#include <UrlProtocol.h>
|
#include <UrlRequest.h>
|
||||||
#include <UrlProtocolListener.h>
|
#include <UrlProtocolListener.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolListener::ConnectionOpened(BUrlProtocol*)
|
BUrlProtocolListener::ConnectionOpened(BUrlRequest*)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolListener::HostnameResolved(BUrlProtocol*, const char*)
|
BUrlProtocolListener::HostnameResolved(BUrlRequest*, const char*)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolListener::ResponseStarted(BUrlProtocol*)
|
BUrlProtocolListener::ResponseStarted(BUrlRequest*)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolListener::HeadersReceived(BUrlProtocol*)
|
BUrlProtocolListener::HeadersReceived(BUrlRequest*)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolListener::DataReceived(BUrlProtocol*, const char*, ssize_t)
|
BUrlProtocolListener::DataReceived(BUrlRequest*, const char*, ssize_t)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolListener::DownloadProgress(BUrlProtocol*, ssize_t, ssize_t)
|
BUrlProtocolListener::DownloadProgress(BUrlRequest*, ssize_t, ssize_t)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolListener::UploadProgress(BUrlProtocol*, ssize_t, ssize_t)
|
BUrlProtocolListener::UploadProgress(BUrlRequest*, ssize_t, ssize_t)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolListener::RequestCompleted(BUrlProtocol*, bool)
|
BUrlProtocolListener::RequestCompleted(BUrlRequest*, bool)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlProtocolListener::DebugMessage(BUrlProtocol* caller,
|
BUrlProtocolListener::DebugMessage(BUrlRequest* caller,
|
||||||
BUrlProtocolDebugMessage type, const char* text)
|
BUrlProtocolDebugMessage type, const char* text)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2013 Haiku Inc. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Christophe Huriaux, [email protected]
|
||||||
|
* Adrien Destugues, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <UrlProtocolRoster.h>
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
#include <UrlRequest.h>
|
||||||
|
#include <HttpRequest.h>
|
||||||
|
#include <Debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* static */ BUrlRequest*
|
||||||
|
BUrlProtocolRoster::MakeRequest(const BUrl& url,
|
||||||
|
BUrlProtocolListener* listener, BUrlContext* context)
|
||||||
|
{
|
||||||
|
BUrlResult* result = new BUrlResult(url);
|
||||||
|
// FIXME this is leaked
|
||||||
|
// TODO: instanciate the correct BUrlProtocol using add-on interface
|
||||||
|
if (url.Protocol() == "http") {
|
||||||
|
return new(std::nothrow) BHttpRequest(url, *result, false, "HTTP", listener,
|
||||||
|
context);
|
||||||
|
} else if (url.Protocol() == "https") {
|
||||||
|
return new(std::nothrow) BHttpRequest(url, *result, true, "HTTPS", listener,
|
||||||
|
context);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
@@ -6,240 +6,298 @@
|
|||||||
* Christophe Huriaux, [email protected]
|
* Christophe Huriaux, [email protected]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <new>
|
|
||||||
|
|
||||||
#include <UrlRequest.h>
|
#include <UrlRequest.h>
|
||||||
#include <UrlProtocolHttp.h>
|
|
||||||
#include <Debug.h>
|
#include <Debug.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
static const char* kProtocolThreadStrStatus[B_PROT_THREAD_STATUS__END+1]
|
||||||
|
= {
|
||||||
|
"Request successfully completed",
|
||||||
|
"Request running",
|
||||||
|
"Socket error",
|
||||||
|
"Connection failed",
|
||||||
|
"Hostname resolution failed",
|
||||||
|
"Network write failed",
|
||||||
|
"Network read failed",
|
||||||
|
"Out of memory",
|
||||||
|
"Protocol-specific error",
|
||||||
|
"Unknown error"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
BUrlRequest::BUrlRequest(const BUrl& url, BUrlProtocolListener* listener,
|
BUrlRequest::BUrlRequest(const BUrl& url, BUrlProtocolListener* listener,
|
||||||
BUrlContext* context)
|
BUrlContext* context, BUrlResult& result, const char* threadName,
|
||||||
|
const char* protocolName)
|
||||||
:
|
:
|
||||||
fListener(listener),
|
fUrl(url),
|
||||||
fUrlProtocol(NULL),
|
fResult(result),
|
||||||
fResult(url),
|
|
||||||
fContext(context),
|
fContext(context),
|
||||||
fUrl(),
|
fListener(listener),
|
||||||
fInitStatus(B_ERROR)
|
fQuit(false),
|
||||||
|
fRunning(false),
|
||||||
|
fThreadId(0),
|
||||||
|
fThreadName(threadName),
|
||||||
|
fProtocol(protocolName)
|
||||||
{
|
{
|
||||||
SetUrl(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BUrlRequest::BUrlRequest(const BUrlRequest& other)
|
|
||||||
:
|
|
||||||
fListener(NULL),
|
|
||||||
fUrlProtocol(NULL),
|
|
||||||
fResult(other.fUrl),
|
|
||||||
fContext(),
|
|
||||||
fUrl(),
|
|
||||||
fInitStatus(B_ERROR)
|
|
||||||
{
|
|
||||||
*this = other;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BUrlRequest::~BUrlRequest()
|
BUrlRequest::~BUrlRequest()
|
||||||
{
|
{
|
||||||
if (fUrlProtocol != NULL)
|
|
||||||
delete fUrlProtocol;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// #pragma mark Request parameters modification
|
|
||||||
|
// #pragma mark URL protocol thread management
|
||||||
|
|
||||||
|
|
||||||
status_t
|
thread_id
|
||||||
BUrlRequest::SetUrl(const BUrl& url)
|
BUrlRequest::Run()
|
||||||
{
|
{
|
||||||
fUrl = url;
|
// Thread already running
|
||||||
fResult.SetUrl(url);
|
if (fRunning) {
|
||||||
|
PRINT(("BUrlRequest::Run() : Oops, already running ! "
|
||||||
if (fUrlProtocol != NULL && url.Protocol() == fUrl.Protocol()) {
|
"[urlProtocol=%p]!\n", this));
|
||||||
fUrlProtocol->SetUrl(url);
|
return fThreadId;
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fInitStatus = _SetupProtocol();
|
fThreadId = spawn_thread(BUrlRequest::_ThreadEntry, fThreadName,
|
||||||
return fInitStatus;
|
B_NORMAL_PRIORITY, this);
|
||||||
}
|
|
||||||
|
|
||||||
|
if (fThreadId < B_OK)
|
||||||
|
return fThreadId;
|
||||||
|
|
||||||
void
|
status_t launchErr = resume_thread(fThreadId);
|
||||||
BUrlRequest::SetContext(BUrlContext* context)
|
if (launchErr < B_OK) {
|
||||||
{
|
PRINT(("BUrlRequest::Run() : Failed to resume thread %ld\n",
|
||||||
fContext = context;
|
fThreadId));
|
||||||
|
return launchErr;
|
||||||
if (fUrlProtocol != NULL)
|
|
||||||
fUrlProtocol->SetContext(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
BUrlRequest::SetProtocolListener(BUrlProtocolListener* listener)
|
|
||||||
{
|
|
||||||
fListener = listener;
|
|
||||||
|
|
||||||
if (fUrlProtocol != NULL)
|
|
||||||
fUrlProtocol->SetListener(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
BUrlRequest::SetProtocolOption(int32 option, void* value)
|
|
||||||
{
|
|
||||||
if (fUrlProtocol == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
fUrlProtocol->SetOption(option, value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark Request parameters access
|
|
||||||
|
|
||||||
|
|
||||||
const BUrlProtocol*
|
|
||||||
BUrlRequest::Protocol()
|
|
||||||
{
|
|
||||||
return fUrlProtocol;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const BUrlResult&
|
|
||||||
BUrlRequest::Result()
|
|
||||||
{
|
|
||||||
return fResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const BUrl&
|
|
||||||
BUrlRequest::Url()
|
|
||||||
{
|
|
||||||
return fUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark Request control
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
BUrlRequest::Start()
|
|
||||||
{
|
|
||||||
if (fUrlProtocol == NULL) {
|
|
||||||
PRINT(("BUrlRequest::Perform() : Oops, no BUrlProtocol defined!\n"));
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_id protocolThread = fUrlProtocol->Run();
|
fRunning = true;
|
||||||
|
return fThreadId;
|
||||||
if (protocolThread < B_OK)
|
|
||||||
return protocolThread;
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BUrlRequest::Pause()
|
BUrlRequest::Pause()
|
||||||
{
|
{
|
||||||
if (fUrlProtocol == NULL)
|
// TODO
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
return fUrlProtocol->Pause();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BUrlRequest::Resume()
|
BUrlRequest::Resume()
|
||||||
{
|
{
|
||||||
if (fUrlProtocol == NULL)
|
// TODO
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
return fUrlProtocol->Resume();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BUrlRequest::Abort()
|
BUrlRequest::Stop()
|
||||||
{
|
{
|
||||||
if (fUrlProtocol == NULL)
|
if (!fRunning)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
status_t returnCode = fUrlProtocol->Stop();
|
status_t threadStatus = B_OK;
|
||||||
delete fUrlProtocol;
|
fQuit = true;
|
||||||
fUrlProtocol = NULL;
|
|
||||||
|
|
||||||
return returnCode;
|
wait_for_thread(fThreadId, &threadStatus);
|
||||||
|
return threadStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark Request informations
|
// #pragma mark URL protocol parameters modification
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BUrlRequest::InitCheck() const
|
BUrlRequest::SetUrl(const BUrl& url)
|
||||||
{
|
{
|
||||||
return fInitStatus;
|
// We should avoid to change URL while the thread is running ...
|
||||||
|
if (IsRunning())
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
fUrl = url;
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BUrlRequest::SetResult(BUrlResult& result)
|
||||||
|
{
|
||||||
|
if (IsRunning())
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
fResult = result;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BUrlRequest::SetContext(BUrlContext* context)
|
||||||
|
{
|
||||||
|
if (IsRunning())
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
fContext = context;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BUrlRequest::SetListener(BUrlProtocolListener* listener)
|
||||||
|
{
|
||||||
|
if (IsRunning())
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
fListener = listener;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark URL protocol parameters access
|
||||||
|
|
||||||
|
|
||||||
|
const BUrl&
|
||||||
|
BUrlRequest::Url() const
|
||||||
|
{
|
||||||
|
return fUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BUrlResult&
|
||||||
|
BUrlRequest::Result() const
|
||||||
|
{
|
||||||
|
return fResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BUrlContext*
|
||||||
|
BUrlRequest::Context() const
|
||||||
|
{
|
||||||
|
return fContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BUrlProtocolListener*
|
||||||
|
BUrlRequest::Listener() const
|
||||||
|
{
|
||||||
|
return fListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const BString&
|
||||||
|
BUrlRequest::Protocol() const
|
||||||
|
{
|
||||||
|
return fProtocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark URL protocol informations
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BUrlRequest::IsRunning() const
|
BUrlRequest::IsRunning() const
|
||||||
{
|
{
|
||||||
if (fUrlProtocol == NULL)
|
return fRunning;
|
||||||
return false;
|
|
||||||
|
|
||||||
return fUrlProtocol->IsRunning();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BUrlRequest::Status() const
|
BUrlRequest::Status() const
|
||||||
{
|
{
|
||||||
if (fUrlProtocol == NULL)
|
return fThreadStatus;
|
||||||
return B_ERROR;
|
|
||||||
|
|
||||||
return fUrlProtocol->Status();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark Overloaded members
|
const char*
|
||||||
|
BUrlRequest::StatusString(status_t threadStatus) const
|
||||||
|
|
||||||
BUrlRequest&
|
|
||||||
BUrlRequest::operator=(const BUrlRequest& other)
|
|
||||||
{
|
{
|
||||||
delete fUrlProtocol;
|
if (threadStatus < B_PROT_THREAD_STATUS__BASE)
|
||||||
fUrlProtocol = NULL;
|
threadStatus = B_PROT_THREAD_STATUS__END;
|
||||||
fUrl = other.fUrl;
|
else if (threadStatus >= B_PROT_PROTOCOL_ERROR)
|
||||||
fListener = other.fListener;
|
threadStatus = B_PROT_PROTOCOL_ERROR;
|
||||||
fContext = other.fContext;
|
|
||||||
fResult = BUrlResult(other.fUrl);
|
|
||||||
SetUrl(other.fUrl);
|
|
||||||
|
|
||||||
return *this;
|
return kProtocolThreadStrStatus[threadStatus];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark Thread management
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ int32
|
||||||
|
BUrlRequest::_ThreadEntry(void* arg)
|
||||||
|
{
|
||||||
|
BUrlRequest* urlProtocol = reinterpret_cast<BUrlRequest*>(arg);
|
||||||
|
urlProtocol->fThreadStatus = B_PROT_RUNNING;
|
||||||
|
|
||||||
|
status_t protocolLoopExitStatus = urlProtocol->_ProtocolLoop();
|
||||||
|
|
||||||
|
urlProtocol->fRunning = false;
|
||||||
|
urlProtocol->fThreadStatus = protocolLoopExitStatus;
|
||||||
|
|
||||||
|
if (urlProtocol->fListener != NULL)
|
||||||
|
urlProtocol->fListener->RequestCompleted(urlProtocol,
|
||||||
|
protocolLoopExitStatus == B_PROT_SUCCESS);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BUrlRequest::_SetupProtocol()
|
BUrlRequest::_ProtocolLoop()
|
||||||
{
|
{
|
||||||
// TODO: instanciate the correct BUrlProtocol w/ the services roster
|
// Dummy _ProtocolLoop
|
||||||
delete fUrlProtocol;
|
while (!fQuit)
|
||||||
fUrlProtocol = NULL;
|
snooze(1000);
|
||||||
|
|
||||||
if (fUrl.Protocol() == "http")
|
return B_PROT_SUCCESS;
|
||||||
fUrlProtocol = new(std::nothrow) BUrlProtocolHttp(fUrl, false, "HTTP",
|
}
|
||||||
fListener, fContext, &fResult);
|
|
||||||
else if (fUrl.Protocol() == "https")
|
|
||||||
fUrlProtocol = new(std::nothrow) BUrlProtocolHttp(fUrl, true, "HTTPS",
|
void
|
||||||
fListener, fContext, &fResult);
|
BUrlRequest::_EmitDebug(BUrlProtocolDebugMessage type,
|
||||||
else
|
const char* format, ...)
|
||||||
return B_NO_HANDLER_FOR_PROTOCOL;
|
{
|
||||||
|
if (fListener == NULL)
|
||||||
if (fUrlProtocol == NULL)
|
return;
|
||||||
return B_NO_MEMORY;
|
|
||||||
|
va_list arguments;
|
||||||
return B_OK;
|
va_start(arguments, format);
|
||||||
|
|
||||||
|
char debugMsg[256];
|
||||||
|
vsnprintf(debugMsg, 256, format, arguments);
|
||||||
|
fListener->DebugMessage(this, type, debugMsg);
|
||||||
|
va_end(arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BMallocIO&
|
||||||
|
BUrlRequest::_ResultRawData()
|
||||||
|
{
|
||||||
|
return fResult.fRawData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BHttpHeaders&
|
||||||
|
BUrlRequest::_ResultHeaders()
|
||||||
|
{
|
||||||
|
return fResult.fHeaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BUrlRequest::_SetResultStatusCode(int32 statusCode)
|
||||||
|
{
|
||||||
|
fResult.fStatusCode = statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BString&
|
||||||
|
BUrlRequest::_ResultStatusText()
|
||||||
|
{
|
||||||
|
return fResult.fStatusString;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,10 +13,12 @@
|
|||||||
#define PRINT(x) printf x;
|
#define PRINT(x) printf x;
|
||||||
|
|
||||||
|
|
||||||
BUrlSynchronousRequest::BUrlSynchronousRequest(BUrl& url)
|
BUrlSynchronousRequest::BUrlSynchronousRequest(BUrlRequest& request)
|
||||||
:
|
:
|
||||||
BUrlRequest(url, this),
|
BUrlRequest(request.Url(), this, request.Context(), request.Result(),
|
||||||
fRequestComplete(false)
|
"BUrlSynchronousRequest", request.Protocol()),
|
||||||
|
fRequestComplete(false),
|
||||||
|
fWrappedRequest(request)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,10 +26,16 @@ BUrlSynchronousRequest::BUrlSynchronousRequest(BUrl& url)
|
|||||||
status_t
|
status_t
|
||||||
BUrlSynchronousRequest::Perform()
|
BUrlSynchronousRequest::Perform()
|
||||||
{
|
{
|
||||||
SetProtocolListener(this);
|
fWrappedRequest.SetListener(this);
|
||||||
fRequestComplete = false;
|
fRequestComplete = false;
|
||||||
|
|
||||||
return Start();
|
thread_id worker = fWrappedRequest.Run();
|
||||||
|
// TODO something to do with the thread_id maybe ?
|
||||||
|
|
||||||
|
if (worker < B_OK)
|
||||||
|
return worker;
|
||||||
|
else
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -42,35 +50,35 @@ BUrlSynchronousRequest::WaitUntilCompletion()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlSynchronousRequest::ConnectionOpened(BUrlProtocol*)
|
BUrlSynchronousRequest::ConnectionOpened(BUrlRequest*)
|
||||||
{
|
{
|
||||||
PRINT(("SynchronousRequest::ConnectionOpened()\n"));
|
PRINT(("SynchronousRequest::ConnectionOpened()\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlSynchronousRequest::HostnameResolved(BUrlProtocol*, const char* ip)
|
BUrlSynchronousRequest::HostnameResolved(BUrlRequest*, const char* ip)
|
||||||
{
|
{
|
||||||
PRINT(("SynchronousRequest::HostnameResolved(%s)\n", ip));
|
PRINT(("SynchronousRequest::HostnameResolved(%s)\n", ip));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlSynchronousRequest::ResponseStarted(BUrlProtocol*)
|
BUrlSynchronousRequest::ResponseStarted(BUrlRequest*)
|
||||||
{
|
{
|
||||||
PRINT(("SynchronousRequest::ResponseStarted()\n"));
|
PRINT(("SynchronousRequest::ResponseStarted()\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlSynchronousRequest::HeadersReceived(BUrlProtocol*)
|
BUrlSynchronousRequest::HeadersReceived(BUrlRequest*)
|
||||||
{
|
{
|
||||||
PRINT(("SynchronousRequest::HeadersReceived()\n"));
|
PRINT(("SynchronousRequest::HeadersReceived()\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlSynchronousRequest::DataReceived(BUrlProtocol*, const char*,
|
BUrlSynchronousRequest::DataReceived(BUrlRequest*, const char*,
|
||||||
ssize_t size)
|
ssize_t size)
|
||||||
{
|
{
|
||||||
PRINT(("SynchronousRequest::DataReceived(%zd)\n", size));
|
PRINT(("SynchronousRequest::DataReceived(%zd)\n", size));
|
||||||
@@ -78,7 +86,7 @@ BUrlSynchronousRequest::DataReceived(BUrlProtocol*, const char*,
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlSynchronousRequest::DownloadProgress(BUrlProtocol*,
|
BUrlSynchronousRequest::DownloadProgress(BUrlRequest*,
|
||||||
ssize_t bytesReceived, ssize_t bytesTotal)
|
ssize_t bytesReceived, ssize_t bytesTotal)
|
||||||
{
|
{
|
||||||
PRINT(("SynchronousRequest::DownloadProgress(%zd, %zd)\n", bytesReceived,
|
PRINT(("SynchronousRequest::DownloadProgress(%zd, %zd)\n", bytesReceived,
|
||||||
@@ -87,7 +95,7 @@ BUrlSynchronousRequest::DownloadProgress(BUrlProtocol*,
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlSynchronousRequest::UploadProgress(BUrlProtocol*, ssize_t bytesSent,
|
BUrlSynchronousRequest::UploadProgress(BUrlRequest*, ssize_t bytesSent,
|
||||||
ssize_t bytesTotal)
|
ssize_t bytesTotal)
|
||||||
{
|
{
|
||||||
PRINT(("SynchronousRequest::UploadProgress(%zd, %zd)\n", bytesSent,
|
PRINT(("SynchronousRequest::UploadProgress(%zd, %zd)\n", bytesSent,
|
||||||
@@ -96,7 +104,7 @@ BUrlSynchronousRequest::UploadProgress(BUrlProtocol*, ssize_t bytesSent,
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BUrlSynchronousRequest::RequestCompleted(BUrlProtocol* caller, bool success)
|
BUrlSynchronousRequest::RequestCompleted(BUrlRequest* caller, bool success)
|
||||||
{
|
{
|
||||||
PRINT(("SynchronousRequest::RequestCompleted(%s) : %s\n", (success?"true":"false"),
|
PRINT(("SynchronousRequest::RequestCompleted(%s) : %s\n", (success?"true":"false"),
|
||||||
caller->StatusString(caller->Status())));
|
caller->StatusString(caller->Status())));
|
||||||
|
|||||||
Reference in New Issue
Block a user