Merge branch 'master' into sam460ex

This commit is contained in:
François Revol 2013-02-12 19:48:05 +01:00
commit 8d96ebeb59
19 changed files with 643 additions and 408 deletions

View File

@ -135,7 +135,7 @@
\returns A status code.
\retval B_OK Initialization was successful.
\retval B_BAD_VALUE \c NULL \a ref.
\retval B_BAD_VALUE \a ref was \c NULL.
\retval B_NAME_TOO_LONG The pathname was longer than \c B_PATH_NAME_LENGTH.
*/
@ -148,7 +148,7 @@
\returns A status code.
\retval B_OK Initialization was successful.
\retval B_BAD_VALUE \c NULL \a ref.
\retval B_BAD_VALUE \a ref was \c NULL.
\retval B_NAME_TOO_LONG The pathname was longer than \c B_PATH_NAME_LENGTH.
*/
@ -173,7 +173,7 @@
\returns A status code.
\retval B_OK Initialization was successful.
\retval B_BAD_VALUE \c NULL \a ref.
\retval B_BAD_VALUE \a ref was \c NULL.
\retval B_NAME_TOO_LONG The pathname was longer than \c B_PATH_NAME_LENGTH.
*/
@ -196,7 +196,7 @@
\returns A status code.
\retval B_OK Initialization was successful.
\retval B_BAD_VALUE \c NULL \a ref.
\retval B_BAD_VALUE \a ref was \c NULL.
\retval B_NAME_TOO_LONG The pathname was longer than \c B_PATH_NAME_LENGTH.
*/
@ -204,7 +204,7 @@
/*!
\fn void BPath::Unset()
\brief Returns the object to an uninitialized state.
Frees any resources it allocated and marks the object as uninitialized.
*/
@ -238,7 +238,7 @@
\returns A status code.
\retval B_OK Initialization was successful.
\retval B_BAD_VALUE \c NULL \a ref.
\retval B_BAD_VALUE \a ref was \c NULL.
\retval B_NAME_TOO_LONG The pathname was longer than \c B_PATH_NAME_LENGTH.
*/
@ -285,7 +285,7 @@
\returns A status code.
\retval B_OK Everything went fine.
\retval B_BAD_VALUE \c NULL \a path.
\retval B_BAD_VALUE \a path was \c NULL.
\retval B_ENTRY_NOT_FOUND The BPath object represents the root path and
thus has no parent.
*/
@ -389,7 +389,7 @@
/*!
\name BFlattenable override methods
\name BFlattenable method implementations
*/
@ -398,7 +398,7 @@
/*!
\fn bool BPath::IsFixedSize() const
\brief Overrides BFlattenable::IsFixedSize(). Always returns \c false.
\brief Implements BFlattenable::IsFixedSize(). Always returns \c false.
\return \c false
*/
@ -406,7 +406,7 @@
/*!
\fn type_code BPath::TypeCode() const
\brief Overrides BFlattenable::TypeCode() Always returns \c B_REF_TYPE.
\brief Implements BFlattenable::TypeCode(). Always returns \c B_REF_TYPE.
\return \c B_REF_TYPE
*/
@ -414,7 +414,7 @@
/*!
\fn ssize_t BPath::FlattenedSize() const
\brief Overrides BFlattenable::FlattenedSize() Gets the size of the
\brief Implements BFlattenable::FlattenedSize(). Gets the size of the
flattened entry_ref struct that represents the path in bytes.
\return The size of the flattened entry_ref struct that represents the
@ -424,7 +424,7 @@
/*!
\fn status_t BPath::Flatten(void* buffer, ssize_t size) const
\brief Overrides BFlattenable::Flatten(). Converts the path of the object
\brief Implements BFlattenable::Flatten(). Converts the path of the object
to an entry_ref and writes it into <em>buffer</em>.
\param buffer The buffer that the data is to be stored in.
@ -432,13 +432,13 @@
\returns A status code.
\retval B_OK Everything went fine.
\retval B_BAD_VALUE \c NULL buffer or the buffer is of insufficient size.
\retval B_BAD_VALUE \a buffer was \c NULL or of insufficient size.
*/
/*!
\fn bool BPath::AllowsTypeCode(type_code code) const
\brief Overrides BFlattenable::AllowsTypeCode(). Checks if type code is
\brief Implements BFlattenable::AllowsTypeCode(). Checks if type code is
equal to \c B_REF_TYPE.
\param code The type code to test.
@ -450,7 +450,7 @@
/*!
\fn status_t BPath::Unflatten(type_code code, const void* buffer,
ssize_t size)
\brief Overrides BFlattenable::Unflatten(). Initializes the object with
\brief Implements BFlattenable::Unflatten(). Initializes the object with
the flattened entry_ref data from the passed in buffer.
The type code must be set to \c B_REF_TYPE.
@ -461,7 +461,7 @@
\returns A status code.
\retval B_OK Everything went fine.
\retval B_BAD_VALUE \a buffer is \c NULL or doesn't contain an entry_ref.
\retval B_BAD_VALUE \a buffer was \c NULL or didn't contain an entry_ref.
*/
@ -475,8 +475,8 @@
status_t BPath::_SetPath(const char* path)
\brief Sets the supplied path.
The path is copied. If \a path is \c NULL path of the object is set to
\c NULL as well. The object's old path is deleted.
The path is copied, if \a path is \c NULL the path of the object is set to
\c NULL as well. The old path is deleted.
\param path the path to be set

View File

@ -15,14 +15,14 @@
class BUrlProtocol {
public:
BUrlProtocol(const BUrl& url,
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
@ -39,7 +39,7 @@ public:
// 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();
@ -51,27 +51,25 @@ public:
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)
virtual const char* StatusString(status_t threadStatus)
const;
protected:
static int32 _ThreadEntry(void* arg);
virtual status_t _ProtocolLoop();
virtual void _EmitDebug(BUrlProtocolDebugMessage type,
virtual void _EmitDebug(BUrlProtocolDebugMessage type,
const char* format, ...);
// URL result parameters access
@ -79,15 +77,13 @@ protected:
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;
@ -110,7 +106,7 @@ enum {
B_PROT_WRITE_FAILED,
B_PROT_READ_FAILED,
B_PROT_NO_MEMORY,
B_PROT_PROTOCOL_ERROR,
B_PROT_PROTOCOL_ERROR,
// Thread status over this one are guaranteed to be
// errors
B_PROT_THREAD_STATUS__END
@ -118,18 +114,18 @@ enum {
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;
};

View File

@ -30,7 +30,7 @@ public:
virtual ~BUrlProtocolHttp();
virtual status_t SetOption(uint32 option, void* value);
static bool IsInformationalStatusCode(int16 code);
static bool IsSuccessStatusCode(int16 code);
static bool IsRedirectionStatusCode(int16 code);
@ -39,49 +39,49 @@ public:
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,
void _CopyChunkInBuffer(char** buffer,
ssize_t* bytesReceived);
void _AddOutputBufferLine(const char* line);
private:
BAbstractSocket* fSocket;
BNetworkAddress fRemoteAddr;
bool fSSL;
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;
@ -128,21 +128,21 @@ enum {
enum {
B_HTTPOPT_METHOD = 0,
// (int) Request method (see B_HTTP_GET, ...)
B_HTTPOPT_FOLLOWLOCATION,
B_HTTPOPT_FOLLOWLOCATION,
// (bool) Follow Location: headers
B_HTTPOPT_MAXREDIRS,
B_HTTPOPT_MAXREDIRS,
// (int) Max relocation
B_HTTPOPT_HEADERS,
B_HTTPOPT_HEADERS,
// (BHttpHeaders*) Headers to be sent
B_HTTPOPT_REFERER,
B_HTTPOPT_REFERER,
// (string) Referer
B_HTTPOPT_USERAGENT,
B_HTTPOPT_USERAGENT,
// (string) User-Agent
B_HTTPOPT_SETCOOKIES,
B_HTTPOPT_SETCOOKIES,
// (bool) Send cookies from context
B_HTTPOPT_DISCARD_DATA,
B_HTTPOPT_DISCARD_DATA,
// (bool) Discard incoming data (still notified)
B_HTTPOPT_DISABLE_LISTENER,
B_HTTPOPT_DISABLE_LISTENER,
// (bool) Don't send notification to the listener
B_HTTPOPT_AUTOREFERER,
// (bool) Automatically set the Referer header
@ -156,7 +156,7 @@ enum {
// (string) Authentication password
B_HTTPOPT_AUTHMETHOD,
// (int) Allowed authentication methods (see BHttpAuthenticationMethod)
B_HTTPOPT__OPT_NUM
};
@ -179,7 +179,7 @@ enum http_status_code {
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,
@ -190,7 +190,7 @@ enum http_status_code {
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,
@ -201,7 +201,7 @@ enum http_status_code {
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,
@ -223,7 +223,7 @@ enum http_status_code {
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,

View File

@ -22,36 +22,34 @@ enum {
class BUrlRequest {
public:
BUrlRequest(const BUrl& url,
BUrlProtocolListener* listener);
BUrlRequest(const BUrl& url);
BUrlProtocolListener* listener = NULL,
BUrlContext* context = NULL);
BUrlRequest(const BUrlRequest& other);
virtual ~BUrlRequest() { };
virtual ~BUrlRequest();
// Request parameters modification
status_t SetUrl(const BUrl& url);
void SetContext(BUrlContext* context);
void SetProtocolListener(
BUrlProtocolListener* listener);
bool SetProtocolOption(int32 option,
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 Start();
virtual status_t Pause();
virtual status_t Resume();
virtual status_t Abort();
// Request informations
virtual bool InitCheck() const;
virtual status_t InitCheck() const;
bool IsRunning() const;
status_t Status() const;
// Overloaded members
BUrlRequest& operator=(const BUrlRequest& other);
@ -62,7 +60,10 @@ protected:
BUrlResult fResult;
BUrlContext* fContext;
BUrl fUrl;
bool fReady;
status_t fInitStatus;
private:
status_t _SetupProtocol();
};
#endif // _B_URL_REQUEST_H_

View File

@ -16,6 +16,7 @@
class AboutView;
class BBitmap;
class BPoint;
class BHandler;
@ -26,6 +27,7 @@ class BAboutWindow : public BWindow {
virtual ~BAboutWindow();
virtual bool QuitRequested();
virtual void Show();
BPoint AboutPosition(float width, float height);
void AddDescription(const char* description);
@ -37,6 +39,15 @@ class BAboutWindow : public BWindow {
void AddVersionHistory(const char** history);
void AddExtraInfo(const char* extraInfo);
BBitmap* Icon();
void SetIcon(BBitmap* icon);
const char* Name();
void SetName(const char* name);
const char* Version();
void SetVersion(const char* version);
private:
AboutView* fAboutView;
BHandler* fCaller;

View File

@ -133,7 +133,6 @@ TBarMenuTitle::DrawContent()
rgb_color menuColor = menu->LowColor();
rgb_color dark = tint_color(menuColor, B_DARKEN_1_TINT);
rgb_color light = tint_color(menuColor, B_LIGHTEN_2_TINT);
rgb_color black = {0, 0, 0, 255};
bool inExpandoMode = dynamic_cast<TExpandoMenuBar*>(menu) != NULL;
@ -161,7 +160,10 @@ TBarMenuTitle::DrawContent()
frame.InsetBy(1, 1);
menu->SetHighColor(menuColor);
menu->FillRect(frame);
menu->SetHighColor(black);
if (IsSelected())
menu->SetHighColor(ui_color(B_MENU_SELECTED_ITEM_TEXT_COLOR));
else
menu->SetHighColor(ui_color(B_MENU_ITEM_TEXT_COLOR));
frame.InsetBy(-1, -1);
if (inExpandoMode)
frame.top -= 1;
@ -177,7 +179,10 @@ TBarMenuTitle::DrawContent()
menu->StrokeLine(frame.LeftTop(), frame.LeftBottom());
}
menu->SetHighColor(black);
if (IsSelected())
menu->SetHighColor(ui_color(B_MENU_SELECTED_ITEM_TEXT_COLOR));
else
menu->SetHighColor(ui_color(B_MENU_ITEM_TEXT_COLOR));
}
menu->SetDrawingMode(B_OP_ALPHA);

View File

@ -283,6 +283,18 @@ PreferencesWindow::QuitRequested()
}
void
PreferencesWindow::Show()
{
if (IsHidden()) {
// move to current workspace
SetWorkspaces(B_CURRENT_WORKSPACE);
}
BWindow::Show();
}
void
PreferencesWindow::WindowActivated(bool active)
{

View File

@ -35,6 +35,7 @@ public:
virtual void MessageReceived(BMessage* message);
virtual bool QuitRequested();
virtual void Show();
virtual void WindowActivated(bool active);
void UpdateRecentCounts();

View File

@ -395,9 +395,6 @@ TTeamMenuItem::DrawContent()
menu->MovePenTo(drawLoc);
}
// set the pen to black so that either method will draw in the same color
// low color is set in inherited::DrawContent, override makes sure its
// what we want
if (fDrawLabel) {
menu->SetDrawingMode(B_OP_OVER);
menu->SetHighColor(ui_color(B_MENU_ITEM_TEXT_COLOR));
@ -513,6 +510,11 @@ TTeamMenuItem::DrawContentLabel()
else
menu->SetLowColor(menu->LowColor());
if (IsSelected())
menu->SetHighColor(ui_color(B_MENU_SELECTED_ITEM_TEXT_COLOR));
else
menu->SetHighColor(ui_color(B_MENU_ITEM_TEXT_COLOR));
menu->DrawString(label);
free(truncLabel);

View File

@ -272,8 +272,11 @@ TWindowMenuItem::DrawContent()
+ ((frame.Height() - fTitleAscent - fTitleDescent) / 2) + 1.0f;
menu->MovePenTo(contLoc);
// Set the pen color so that the label is always visible.
menu->SetHighColor(ui_color(B_MENU_ITEM_TEXT_COLOR));
if (IsSelected())
menu->SetHighColor(ui_color(B_MENU_SELECTED_ITEM_TEXT_COLOR));
else
menu->SetHighColor(ui_color(B_MENU_ITEM_TEXT_COLOR));
BMenuItem::DrawContent();

View File

@ -77,7 +77,7 @@ PowerStatusView::PowerStatusView(BMessage* archive)
PowerStatusView::~PowerStatusView()
{
if (fAboutWindow != NULL)
if (fAboutWindow != NULL && fAboutWindow->Lock())
fAboutWindow->Quit();
}

View File

@ -39,6 +39,7 @@
#include <Catalog.h>
#include <CheckBox.h>
#include <Clipboard.h>
#include <ControlLook.h>
#include <Directory.h>
#include <Entry.h>
#include <File.h>
@ -56,6 +57,7 @@
#include <Roster.h>
#include <Screen.h>
#include <SeparatorView.h>
#include <Size.h>
#include <SpaceLayoutItem.h>
#include <StatusBar.h>
#include <StringView.h>
@ -424,6 +426,12 @@ BrowserWindow::BrowserWindow(BRect frame, SettingsMessage* appSettings,
const float kElementSpacing = 5;
// Find group
fFindCloseButton = new BButton("\xc3\x97", // multiplication sign
new BMessage(EDIT_HIDE_FIND_GROUP));
fFindCloseButton->SetExplicitMinSize(
BSize(be_control_look->DefaultItemSpacing() * 3, B_SIZE_UNSET));
fFindCloseButton->SetExplicitMaxSize(
BSize(be_control_look->DefaultItemSpacing() * 3, B_SIZE_UNSET));
fFindTextControl = new BTextControl("find", B_TRANSLATE("Find:"), "",
new BMessage(EDIT_FIND_NEXT));
fFindTextControl->SetModificationMessage(new BMessage(FIND_TEXT_CHANGED));
@ -431,18 +439,15 @@ BrowserWindow::BrowserWindow(BRect frame, SettingsMessage* appSettings,
new BMessage(EDIT_FIND_PREVIOUS));
fFindNextButton = new BButton(B_TRANSLATE("Next"),
new BMessage(EDIT_FIND_NEXT));
fFindCloseButton = new BButton(B_TRANSLATE("Close"),
new BMessage(EDIT_HIDE_FIND_GROUP));
fFindCaseSensitiveCheckBox = new BCheckBox(B_TRANSLATE("Match case"));
BGroupLayout* findGroup = BLayoutBuilder::Group<>(B_VERTICAL, 0.0)
.Add(new BSeparatorView(B_HORIZONTAL, B_PLAIN_BORDER))
.Add(BGroupLayoutBuilder(B_HORIZONTAL, kElementSpacing)
.Add(BGroupLayoutBuilder(B_HORIZONTAL, B_USE_DEFAULT_SPACING)
.Add(fFindCloseButton)
.Add(fFindTextControl)
.Add(fFindPreviousButton)
.Add(fFindNextButton)
.Add(fFindCaseSensitiveCheckBox)
.Add(BSpaceLayoutItem::CreateGlue())
.Add(fFindCloseButton)
.SetInsets(kInsetSpacing, kInsetSpacing,
kInsetSpacing, kInsetSpacing)
)
@ -2332,5 +2337,3 @@ BrowserWindow::_HandlePageSourceResult(const BMessage* message)
alert->Go(NULL);
}
}

View File

@ -222,9 +222,12 @@ struct MimeAttribute
MimeAttribute(BMessage& msg, int32 index);
MimeAttribute(TUserArgs& args);
MimeAttribute(const MimeAttribute& src);
status_t InitCheck() { return fStatus; }
MimeAttribute& operator=(const MimeAttribute& src);
void Dump();
void SyncWith(TUserArgs& args) throw(Error);
void StoreInto(BMessage* target);
@ -288,12 +291,43 @@ MimeAttribute::MimeAttribute(BMessage& msg, int32 index)
MimeAttribute::MimeAttribute(TUserArgs& args)
:
fStatus(B_NO_INIT),
fType('CSTR'),
fViewable(true),
fEditable(false),
fExtra(false),
fWidth(0),
fAlignment(0)
{
SyncWith(args);
fStatus = B_OK;
}
MimeAttribute::MimeAttribute(const MimeAttribute& src)
{
*this = src;
}
MimeAttribute&
MimeAttribute::operator=(const MimeAttribute& src)
{
fStatus = src.fStatus;
fName = src.fName;
fPublicName = src.fPublicName;
fType = src.fType;
fViewable = src.fViewable;
fEditable = src.fEditable;
fExtra = src.fExtra;
fWidth = src.fWidth;
fAlignment = src.fAlignment;
return *this;
}
void
MimeAttribute::SyncWith(TUserArgs& args) throw(Error)
{
@ -609,7 +643,7 @@ MimeType::_Init(char** argv) throw (Error)
throw Error("'%s' allowed only after the '%s' <name>",
name, kAttribute);
if (!*++arg)
if (!*++arg || **arg == '-')
throw Error("'%s', argument should be specified", name);
TUserArgsI A = fUserAttributes.back().find(key);

View File

@ -28,9 +28,9 @@ static const char* kProtocolThreadStrStatus[B_PROT_THREAD_STATUS__END+1]
BUrlProtocol::BUrlProtocol(const BUrl& url, BUrlProtocolListener* listener,
BUrlContext* context, BUrlResult* result, const char* threadName,
BUrlContext* context, BUrlResult* result, const char* threadName,
const char* protocolName)
:
:
fUrl(url),
fResult(result),
fContext(context),
@ -61,20 +61,20 @@ BUrlProtocol::Run()
"[urlProtocol=%p]!\n", this));
return fThreadId;
}
fThreadId = spawn_thread(BUrlProtocol::_ThreadEntry, fThreadName,
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",
PRINT(("BUrlProtocol::Run() : Failed to resume thread %ld\n",
fThreadId));
return launchErr;
}
fRunning = true;
return fThreadId;
}
@ -101,11 +101,11 @@ BUrlProtocol::Stop()
{
if (!fRunning)
return B_ERROR;
status_t threadStatus = B_OK;
fQuit = true;
wait_for_thread(fThreadId, &threadStatus);
wait_for_thread(fThreadId, &threadStatus);
return threadStatus;
}
@ -119,7 +119,7 @@ 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;
}
@ -130,7 +130,7 @@ BUrlProtocol::SetResult(BUrlResult* result)
{
if (IsRunning())
return B_ERROR;
fResult = result;
return B_OK;
}
@ -138,10 +138,10 @@ BUrlProtocol::SetResult(BUrlResult* result)
status_t
BUrlProtocol::SetContext(BUrlContext* context)
{
{
if (IsRunning())
return B_ERROR;
fContext = context;
return B_OK;
}
@ -152,7 +152,7 @@ BUrlProtocol::SetListener(BUrlProtocolListener* listener)
{
if (IsRunning())
return B_ERROR;
fListener = listener;
return B_OK;
}
@ -226,23 +226,23 @@ BUrlProtocol::StatusString(status_t threadStatus) const
// #pragma mark Thread management
/*static*/ int32
BUrlProtocol::_ThreadEntry(void* arg)
{
BUrlProtocol* urlProtocol = reinterpret_cast<BUrlProtocol*>(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,
urlProtocol->fListener->RequestCompleted(urlProtocol,
protocolLoopExitStatus == B_PROT_SUCCESS);
return B_OK;
}
@ -253,13 +253,13 @@ BUrlProtocol::_ProtocolLoop()
// Dummy _ProtocolLoop
while (!fQuit)
snooze(1000);
return B_PROT_SUCCESS;
}
void
BUrlProtocol::_EmitDebug(BUrlProtocolDebugMessage type,
BUrlProtocol::_EmitDebug(BUrlProtocolDebugMessage type,
const char* format, ...)
{
if (fListener == NULL)
@ -267,7 +267,7 @@ BUrlProtocol::_EmitDebug(BUrlProtocolDebugMessage type,
va_list arguments;
va_start(arguments, format);
char debugMsg[256];
vsnprintf(debugMsg, 256, format, arguments);
fListener->DebugMessage(this, type, debugMsg);
@ -275,7 +275,7 @@ BUrlProtocol::_EmitDebug(BUrlProtocolDebugMessage type,
}
BMallocIO&
BMallocIO&
BUrlProtocol::_ResultRawData()
{
return fResult->fRawData;

View File

@ -31,10 +31,10 @@ static const char* kHttpProtocolThreadStrStatus[
};
BUrlProtocolHttp::BUrlProtocolHttp(BUrl& url, bool ssl,
const char *protocolName, BUrlProtocolListener* listener,
BUrlContext* context, BUrlResult* result)
:
BUrlProtocolHttp::BUrlProtocolHttp(BUrl& url, bool ssl,
const char* protocolName, BUrlProtocolListener* listener,
BUrlContext* context, BUrlResult* result)
:
BUrlProtocol(url, listener, context, result, "BUrlProtocol.HTTP", protocolName),
fSSL(ssl),
fRequestMethod(B_HTTP_GET),
@ -45,7 +45,6 @@ BUrlProtocolHttp::BUrlProtocolHttp(BUrl& url, bool ssl,
fSocket = new BSecureSocket();
else
fSocket = new BSocket();
}
@ -59,67 +58,67 @@ status_t
BUrlProtocolHttp::SetOption(uint32 name, void* value)
{
BUrlProtocolOption option(value);
switch (name) {
case B_HTTPOPT_METHOD:
fRequestMethod = option.Int8();
break;
case B_HTTPOPT_FOLLOWLOCATION:
fOptFollowLocation = option.Bool();
break;
case B_HTTPOPT_MAXREDIRS:
fOptMaxRedirs = option.Int8();
break;
case B_HTTPOPT_REFERER:
fOptReferer = option.String();
break;
case B_HTTPOPT_USERAGENT:
fOptUserAgent = option.String();
break;
case B_HTTPOPT_HEADERS:
fOptHeaders = reinterpret_cast<BHttpHeaders*>(option.Pointer());
break;
case B_HTTPOPT_DISCARD_DATA:
fOptDiscardData = option.Bool();
break;
case B_HTTPOPT_DISABLE_LISTENER:
fOptDisableListener = option.Bool();
break;
case B_HTTPOPT_AUTOREFERER:
fOptAutoReferer = option.Bool();
break;
case B_HTTPOPT_POSTFIELDS:
fOptPostFields = reinterpret_cast<BHttpForm*>(option.Pointer());
if (fOptPostFields != NULL)
fRequestMethod = B_HTTP_POST;
break;
case B_HTTPOPT_INPUTDATA:
fOptInputData = reinterpret_cast<BDataIO*>(option.Pointer());
break;
case B_HTTPOPT_AUTHUSERNAME:
fOptUsername = option.String();
break;
case B_HTTPOPT_AUTHPASSWORD:
fOptPassword = option.String();
break;
default:
return B_ERROR;
}
return B_OK;
}
@ -177,7 +176,7 @@ BUrlProtocolHttp::StatusCodeClass(int16 code)
return B_HTTP_STATUS_CLASS_CLIENT_ERROR;
else if (BUrlProtocolHttp::IsServerErrorStatusCode(code))
return B_HTTP_STATUS_CLASS_SERVER_ERROR;
return B_HTTP_STATUS_CLASS_INVALID;
}
@ -190,11 +189,11 @@ BUrlProtocolHttp::StatusString(status_t threadStatus) const
else if (threadStatus >= B_PROT_HTTP_THREAD_STATUS__END)
return BUrlProtocol::StatusString(-1);
else
return kHttpProtocolThreadStrStatus[threadStatus
return kHttpProtocolThreadStrStatus[threadStatus
- B_PROT_THREAD_STATUS__END];
}
void
BUrlProtocolHttp::_ResetOptions()
{
@ -204,7 +203,7 @@ BUrlProtocolHttp::_ResetOptions()
fOptUserAgent = "Services Kit (Haiku)";
fOptUsername = "";
fOptPassword = "";
fOptAuthMethods = B_HTTP_AUTHENTICATION_BASIC | B_HTTP_AUTHENTICATION_DIGEST
fOptAuthMethods = B_HTTP_AUTHENTICATION_BASIC | B_HTTP_AUTHENTICATION_DIGEST
| B_HTTP_AUTHENTICATION_IE_DIGEST;
fOptHeaders = NULL;
fOptPostFields = NULL;
@ -217,16 +216,16 @@ BUrlProtocolHttp::_ResetOptions()
#include <stdio.h>
status_t
BUrlProtocolHttp::_ProtocolLoop()
{
{
printf("UHP[%p]::{Loop} %s\n", this, fUrl.UrlString().String());
// Initialize the request redirection loop
int8 maxRedirs = fOptMaxRedirs;
bool newRequest;
do {
newRequest = false;
// Result reset
fOutputBuffer.Truncate(0, true);
fOutputHeaders.Clear();
@ -234,61 +233,61 @@ BUrlProtocolHttp::_ProtocolLoop()
_ResultHeaders().Clear();
_ResultRawData().Seek(SEEK_SET, 0);
_ResultRawData().SetSize(0);
if (!_ResolveHostName()) {
_EmitDebug(B_URL_PROTOCOL_DEBUG_ERROR,
"Unable to resolve hostname, aborting.");
return B_PROT_CANT_RESOLVE_HOSTNAME;
}
_CreateRequest();
_AddHeaders();
_AddOutputBufferLine("");
status_t requestStatus = _MakeRequest();
if (requestStatus != B_PROT_SUCCESS)
return requestStatus;
// Prepare the referer for the next request if needed
if (fOptAutoReferer)
fOptReferer = fUrl.UrlString();
switch (StatusCodeClass(fResult->StatusCode())) {
case B_HTTP_STATUS_CLASS_INFORMATIONAL:
// Header 100:continue should have been
// handled in the _MakeRequest read loop
break;
case B_HTTP_STATUS_CLASS_SUCCESS:
break;
case B_HTTP_STATUS_CLASS_REDIRECTION:
// Redirection has been explicitly disabled
if (!fOptFollowLocation)
break;
// TODO: Some browsers seems to translate POST requests to
// GET when following a 302 redirection
if (fResult->StatusCode() == B_HTTP_STATUS_MOVED_PERMANENTLY) {
BString locationUrl = fHeaders["Location"];
// Absolute path
if (locationUrl[0] == '/')
fUrl.SetPath(locationUrl);
// URI
else
fUrl.SetUrlString(locationUrl);
if (--maxRedirs > 0) {
newRequest = true;
_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT,
"Following: %s\n",
"Following: %s\n",
fUrl.UrlString().String());
}
}
break;
case B_HTTP_STATUS_CLASS_CLIENT_ERROR:
switch (fResult->StatusCode()) {
case B_HTTP_STATUS_UNAUTHORIZED:
@ -296,7 +295,7 @@ BUrlProtocolHttp::_ProtocolLoop()
newRequest = false;
break;
}
newRequest = false;
if (fOptUsername.Length() > 0
&& fAuthentication.Initialize(fHeaders["WWW-Authenticate"])
@ -308,21 +307,20 @@ BUrlProtocolHttp::_ProtocolLoop()
break;
}
break;
case B_HTTP_STATUS_CLASS_SERVER_ERROR:
break;
default:
case B_HTTP_STATUS_CLASS_INVALID:
break;
}
} while (newRequest);
_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT,
"%ld headers and %ld bytes of data remaining",
fHeaders.CountHeaders(),
fInputBuffer.Size());
"%ld headers and %ld bytes of data remaining",
fHeaders.CountHeaders(), fInputBuffer.Size());
if (fResult->StatusCode() == 404)
return B_PROT_HTTP_NOT_FOUND;
@ -335,27 +333,23 @@ BUrlProtocolHttp::_ResolveHostName()
{
_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Resolving %s",
fUrl.UrlString().String());
if (fUrl.HasPort())
fRemoteAddr = BNetworkAddress(fUrl.Host(), fUrl.Port());
else {
if (fSSL)
fRemoteAddr = BNetworkAddress(fUrl.Host(), 443);
else
fRemoteAddr = BNetworkAddress(fUrl.Host(), 80);
fRemoteAddr = BNetworkAddress(fUrl.Host(), fSSL ? 443 : 80);
}
if (fRemoteAddr.InitCheck() != B_OK)
return false;
//! ProtocolHook:HostnameResolved
if (fListener != NULL)
fListener->HostnameResolved(this,
const_cast<const char*>(fRemoteAddr.ToString().String()));
_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Hostname resolved to: %s",
fRemoteAddr.ToString().String());
fListener->HostnameResolved(this, fRemoteAddr.ToString().String());
_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Hostname resolved to: %s",
fRemoteAddr.ToString().String());
return true;
}
@ -363,58 +357,58 @@ BUrlProtocolHttp::_ResolveHostName()
status_t
BUrlProtocolHttp::_MakeRequest()
{
_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Connection to %s.",
_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Connection to %s.",
fUrl.Authority().String());
status_t connectError = fSocket->Connect(fRemoteAddr);
if (connectError != B_OK) {
_EmitDebug(B_URL_PROTOCOL_DEBUG_ERROR, "Socket connection error.");
return B_PROT_CONNECTION_FAILED;
}
//! ProtocolHook:ConnectionOpened
if (fListener != NULL)
fListener->ConnectionOpened(this);
_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Connection opened.");
_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Sending request (size=%d)",
fOutputBuffer.Length());
fSocket->Write(fOutputBuffer.String(), fOutputBuffer.Length());
fOutputBuffer.Truncate(0);
_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Request sent.");
if (fRequestMethod == B_HTTP_POST && fOptPostFields != NULL) {
if (fOptPostFields->GetFormType() != B_HTTP_FORM_MULTIPART) {
fOutputBuffer = fOptPostFields->RawData();
_EmitDebug(B_URL_PROTOCOL_DEBUG_TRANSFER_OUT,
_EmitDebug(B_URL_PROTOCOL_DEBUG_TRANSFER_OUT,
fOutputBuffer.String());
fSocket->Write(fOutputBuffer.String(), fOutputBuffer.Length());
} else {
for (BHttpForm::Iterator it = fOptPostFields->GetIterator();
const BHttpFormData* currentField = it.Next();
) {
_EmitDebug(B_URL_PROTOCOL_DEBUG_TRANSFER_OUT,
_EmitDebug(B_URL_PROTOCOL_DEBUG_TRANSFER_OUT,
it.MultipartHeader().String());
fSocket->Write(it.MultipartHeader().String(),
fSocket->Write(it.MultipartHeader().String(),
it.MultipartHeader().Length());
switch (currentField->Type()) {
case B_HTTPFORM_UNKNOWN:
ASSERT(0);
break;
case B_HTTPFORM_STRING:
fSocket->Write(currentField->String().String(),
fSocket->Write(currentField->String().String(),
currentField->String().Length());
break;
case B_HTTPFORM_FILE:
{
BFile upFile(currentField->File().Path(),
BFile upFile(currentField->File().Path(),
B_READ_ONLY);
char readBuffer[1024];
ssize_t readSize;
ssize_t readSize;
readSize = upFile.Read(readBuffer, 1024);
while (readSize > 0) {
@ -423,45 +417,45 @@ BUrlProtocolHttp::_MakeRequest()
}
}
break;
case B_HTTPFORM_BUFFER:
fSocket->Write(currentField->Buffer(),
fSocket->Write(currentField->Buffer(),
currentField->BufferSize());
break;
}
fSocket->Write("\r\n", 2);
}
fSocket->Write(fOptPostFields->GetMultipartFooter().String(),
fSocket->Write(fOptPostFields->GetMultipartFooter().String(),
fOptPostFields->GetMultipartFooter().Length());
}
} else if ((fRequestMethod == B_HTTP_POST || fRequestMethod == B_HTTP_PUT)
} else if ((fRequestMethod == B_HTTP_POST || fRequestMethod == B_HTTP_PUT)
&& fOptInputData != NULL) {
char outputTempBuffer[1024];
ssize_t read = 0;
while (read != -1) {
read = fOptInputData->Read(outputTempBuffer, 1024);
if (read > 0) {
char hexSize[16];
size_t hexLength = sprintf(hexSize, "%ld", read);
fSocket->Write(hexSize, hexLength);
fSocket->Write("\r\n", 2);
fSocket->Write(outputTempBuffer, read);
fSocket->Write("\r\n", 2);
}
}
fSocket->Write("0\r\n\r\n", 5);
}
fOutputBuffer.Truncate(0, true);
fStatusReceived = false;
fHeadersReceived = false;
// Receive loop
bool receiveEnd = false;
bool parseEnd = false;
@ -473,38 +467,38 @@ BUrlProtocolHttp::_MakeRequest()
ssize_t bytesTotal = 0;
char* inputTempBuffer = NULL;
fQuit = false;
while (!fQuit && !(receiveEnd && parseEnd)) {
if (!receiveEnd) {
fSocket->WaitForReadable();
BNetBuffer chunk(receiveBufferSize);
bytesRead = fSocket->Read(chunk.Data(), receiveBufferSize);
if (bytesRead < 0) {
readError = true;
fQuit = true;
continue;
continue;
} else if (bytesRead == 0)
receiveEnd = true;
fInputBuffer.AppendData(chunk.Data(), bytesRead);
}
else
bytesRead = 0;
if (!fStatusReceived) {
_ParseStatus();
//! ProtocolHook:ResponseStarted
if (fStatusReceived && fListener != NULL)
fListener->ResponseStarted(this);
} else if (!fHeadersReceived) {
_ParseHeaders();
if (fHeadersReceived) {
receiveBufferSize = kHttpProtocolReceiveBufferSize;
_ResultHeaders() = fHeaders;
//! ProtocolHook:HeadersReceived
if (fListener != NULL)
fListener->HeadersReceived(this);
@ -516,10 +510,10 @@ BUrlProtocolHttp::_MakeRequest()
}
}
}
if (BString(fHeaders["Transfer-Encoding"]) == "chunked")
readByChunks = true;
int32 index = fHeaders.HasHeader("Content-Length");
if (index != B_ERROR)
bytesTotal = atoi(fHeaders.HeaderAt(index).Value());
@ -531,7 +525,7 @@ BUrlProtocolHttp::_MakeRequest()
// chunk in buffer before handling it
if (readByChunks) {
_CopyChunkInBuffer(&inputTempBuffer, &bytesRead);
// A chunk of 0 bytes indicates the end of the chunked transfer
if (bytesRead == 0) {
receiveEnd = true;
@ -539,50 +533,50 @@ BUrlProtocolHttp::_MakeRequest()
}
else {
bytesRead = fInputBuffer.Size();
if (bytesRead > 0) {
inputTempBuffer = new char[bytesRead];
fInputBuffer.RemoveData(inputTempBuffer, bytesRead);
}
}
if (bytesRead > 0) {
bytesReceived += bytesRead;
_EmitDebug(B_URL_PROTOCOL_DEBUG_TRANSFER_IN, "%d bytes",
_EmitDebug(B_URL_PROTOCOL_DEBUG_TRANSFER_IN, "%d bytes",
bytesRead);
if (fListener != NULL) {
fListener->DataReceived(this, inputTempBuffer, bytesRead);
fListener->DownloadProgress(this, bytesReceived,
fListener->DownloadProgress(this, bytesReceived,
bytesTotal);
}
ssize_t dataWrite = _ResultRawData().Write(inputTempBuffer,
ssize_t dataWrite = _ResultRawData().Write(inputTempBuffer,
bytesRead);
if (dataWrite != bytesRead) {
_EmitDebug(B_URL_PROTOCOL_DEBUG_ERROR,
"Unable to write %dbytes of data (%d).", bytesRead,
_EmitDebug(B_URL_PROTOCOL_DEBUG_ERROR,
"Unable to write %dbytes of data (%d).", bytesRead,
dataWrite);
return B_PROT_NO_MEMORY;
}
if (bytesTotal > 0 && bytesReceived >= bytesTotal)
receiveEnd = true;
delete[] inputTempBuffer;
}
}
}
parseEnd = (fInputBuffer.Size() == 0);
}
fSocket->Disconnect();
if (readError)
return B_PROT_READ_FAILED;
return fQuit?B_PROT_ABORTED:B_PROT_SUCCESS;
return fQuit ? B_PROT_ABORTED : B_PROT_SUCCESS;
}
@ -591,23 +585,23 @@ BUrlProtocolHttp::_GetLine(BString& destString)
{
// Find a complete line in inputBuffer
uint32 characterIndex = 0;
while ((characterIndex < fInputBuffer.Size())
while ((characterIndex < fInputBuffer.Size())
&& ((fInputBuffer.Data())[characterIndex] != '\n'))
characterIndex++;
if (characterIndex == fInputBuffer.Size())
return B_ERROR;
char* temporaryBuffer = new(std::nothrow) char[characterIndex + 1];
fInputBuffer.RemoveData(temporaryBuffer, characterIndex + 1);
// Strip end-of-line character(s)
if (temporaryBuffer[characterIndex-1] == '\r')
destString.SetTo(temporaryBuffer, characterIndex - 1);
else
destString.SetTo(temporaryBuffer, characterIndex);
destString.SetTo(temporaryBuffer, characterIndex);
delete[] temporaryBuffer;
return B_OK;
}
@ -624,19 +618,19 @@ BUrlProtocolHttp::_ParseStatus()
BString statusLine;
if (_GetLine(statusLine) == B_ERROR)
return;
if (statusLine.CountChars() < 12)
return;
fStatusReceived = true;
BString statusCodeStr;
BString statusText;
statusLine.CopyInto(statusCodeStr, 9, 3);
_SetResultStatusCode(atoi(statusCodeStr.String()));
statusLine.CopyInto(_ResultStatusText(), 13, statusLine.Length() - 13);
_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Status line received: Code %d (%s)",
atoi(statusCodeStr.String()), _ResultStatusText().String());
}
@ -648,14 +642,14 @@ BUrlProtocolHttp::_ParseHeaders()
BString currentHeader;
if (_GetLine(currentHeader) == B_ERROR)
return;
// Empty line
if (currentHeader.Length() == 0) {
fHeadersReceived = true;
return;
}
_EmitDebug(B_URL_PROTOCOL_DEBUG_HEADER_IN, "%s", currentHeader.String());
_EmitDebug(B_URL_PROTOCOL_DEBUG_HEADER_IN, "%s", currentHeader.String());
fHeaders.AddHeader(currentHeader.String());
}
@ -665,7 +659,7 @@ BUrlProtocolHttp::_CopyChunkInBuffer(char** buffer, ssize_t* bytesReceived)
{
static ssize_t chunkSize = -1;
BString chunkHeader;
if (chunkSize >= 0) {
if ((ssize_t)fInputBuffer.Size() >= chunkSize + 2) {
// 2 more bytes to handle the closing CR+LF
@ -684,22 +678,22 @@ BUrlProtocolHttp::_CopyChunkInBuffer(char** buffer, ssize_t* bytesReceived)
*bytesReceived = -1;
return;
}
// Format of a chunk header:
// <chunk size in hex>[; optional data]
int32 semiColonIndex = chunkHeader.FindFirst(";", 0);
// Cut-off optional data if present
if (semiColonIndex != -1)
chunkHeader.Remove(semiColonIndex,
chunkHeader.Remove(semiColonIndex,
chunkHeader.Length() - semiColonIndex);
chunkSize = strtol(chunkHeader.String(), NULL, 16);
chunkSize = strtol(chunkHeader.String(), NULL, 16);
PRINT(("BHP[%p] Chunk %s=%ld\n", this, chunkHeader.String(), chunkSize));
if (chunkSize == 0) {
fContentReceived = true;
}
*bytesReceived = -1;
*buffer = NULL;
}
@ -710,46 +704,46 @@ void
BUrlProtocolHttp::_CreateRequest()
{
BString request;
switch (fRequestMethod) {
switch (fRequestMethod) {
case B_HTTP_POST:
request << "POST";
break;
case B_HTTP_PUT:
request << "PUT";
break;
default:
case B_HTTP_GET:
request << "GET";
break;
}
if (Url().HasPath())
request << ' ' << Url().Path();
else
request << " /";
if (Url().HasRequest())
request << '?' << Url().Request();
if (Url().HasFragment())
request << '#' << Url().Fragment();
request << ' ';
switch (fHttpVersion) {
case B_HTTP_11:
request << "HTTP/1.1";
break;
default:
case B_HTTP_10:
request << "HTTP/1.0";
break;
}
_AddOutputBufferLine(request.String());
}
@ -760,93 +754,77 @@ BUrlProtocolHttp::_AddHeaders()
// HTTP 1.1 additional headers
if (fHttpVersion == B_HTTP_11) {
fOutputHeaders.AddHeader("Host", Url().Host());
fOutputHeaders.AddHeader("Accept", "*/*");
fOutputHeaders.AddHeader("Accept-Encoding", "chunked");
// Allow the remote server to send dynamic content by chunks
// Allow the remote server to send dynamic content by chunks
// rather than waiting for the full content to be generated and
// sending us data.
fOutputHeaders.AddHeader("Connection", "close");
// Let the remote server close the connection after response since
// Let the remote server close the connection after response since
// we don't handle multiple request on a single connection
}
// Classic HTTP headers
if (fOptUserAgent.CountChars() > 0)
fOutputHeaders.AddHeader("User-Agent", fOptUserAgent.String());
if (fOptReferer.CountChars() > 0)
fOutputHeaders.AddHeader("Referer", fOptReferer.String());
// Authentication
if (fAuthentication.Method() != B_HTTP_AUTHENTICATION_NONE) {
BString request;
switch (fRequestMethod) {
switch (fRequestMethod) {
case B_HTTP_POST:
request = "POST";
break;
case B_HTTP_PUT:
request = "PUT";
break;
default:
case B_HTTP_GET:
request = "GET";
break;
}
fOutputHeaders.AddHeader("Authorization",
fOutputHeaders.AddHeader("Authorization",
fAuthentication.Authorization(fUrl, request));
}
// Required headers for POST data
if (fOptPostFields != NULL && fRequestMethod == B_HTTP_POST) {
BString contentType;
switch (fOptPostFields->GetFormType()) {
case B_HTTP_FORM_MULTIPART:
contentType << "multipart/form-data; boundary="
<< fOptPostFields->GetMultipartBoundary() << "";
break;
case B_HTTP_FORM_URL_ENCODED:
contentType << "application/x-www-form-urlencoded";
break;
}
fOutputHeaders.AddHeader("Content-Type", contentType);
fOutputHeaders.AddHeader("Content-Length",
fOutputHeaders.AddHeader("Content-Length",
fOptPostFields->ContentLength());
} else if (fOptInputData != NULL
} else if (fOptInputData != NULL
&& (fRequestMethod == B_HTTP_POST || fRequestMethod == B_HTTP_PUT))
fOutputHeaders.AddHeader("Transfer-Encoding", "chunked");
// Request headers
for (int32 headerIndex = 0;
headerIndex < fRequestHeaders.CountHeaders();
headerIndex++) {
BHttpHeader& optHeader = fRequestHeaders[headerIndex];
int32 replaceIndex = fOutputHeaders.HasHeader(optHeader.Name());
// Add or replace the current option header to the
// output header list
if (replaceIndex == -1)
fOutputHeaders.AddHeader(optHeader.Name(), optHeader.Value());
else
fOutputHeaders[replaceIndex].SetValue(optHeader.Value());
}
// Optional headers specified by the user
if (fOptHeaders != NULL) {
for (int32 headerIndex = 0;
headerIndex < fOptHeaders->CountHeaders();
headerIndex++) {
if (fOptHeaders != NULL) {
for (int32 headerIndex = 0; headerIndex < fOptHeaders->CountHeaders();
headerIndex++) {
BHttpHeader& optHeader = (*fOptHeaders)[headerIndex];
int32 replaceIndex = fOutputHeaders.HasHeader(optHeader.Name());
// Add or replace the current option header to the
// Add or replace the current option header to the
// output header list
if (replaceIndex == -1)
fOutputHeaders.AddHeader(optHeader.Name(), optHeader.Value());
@ -854,22 +832,20 @@ BUrlProtocolHttp::_AddHeaders()
fOutputHeaders[replaceIndex].SetValue(optHeader.Value());
}
}
// Context cookies
if (fOptSetCookies && (fContext != NULL)) {
BNetworkCookie* cookie;
for (BNetworkCookieJar::UrlIterator
it(fContext->GetCookieJar().GetUrlIterator(fUrl));
(cookie = it.Next()) != NULL;
)
fOutputHeaders.AddHeader("Cookie", cookie->RawCookie(false));
for (BNetworkCookieJar::UrlIterator it
= fContext->GetCookieJar().GetUrlIterator(fUrl);
(cookie = it.Next()) != NULL;)
fOutputHeaders.AddHeader("Cookie", cookie->RawCookie(false));
}
// Write output headers to output stream
for (int32 headerIndex = 0;
headerIndex < fOutputHeaders.CountHeaders();
headerIndex++)
for (int32 headerIndex = 0; headerIndex < fOutputHeaders.CountHeaders();
headerIndex++)
_AddOutputBufferLine(fOutputHeaders.HeaderAt(headerIndex).Header());
}

View File

@ -13,27 +13,15 @@
#include <Debug.h>
BUrlRequest::BUrlRequest(const BUrl& url, BUrlProtocolListener* listener)
:
BUrlRequest::BUrlRequest(const BUrl& url, BUrlProtocolListener* listener,
BUrlContext* context)
:
fListener(listener),
fUrlProtocol(NULL),
fResult(url),
fContext(),
fContext(context),
fUrl(),
fReady(false)
{
SetUrl(url);
}
BUrlRequest::BUrlRequest(const BUrl& url)
:
fListener(NULL),
fUrlProtocol(NULL),
fResult(url),
fContext(),
fUrl(),
fReady(false)
fInitStatus(B_ERROR)
{
SetUrl(url);
}
@ -46,12 +34,18 @@ BUrlRequest::BUrlRequest(const BUrlRequest& other)
fResult(other.fUrl),
fContext(),
fUrl(),
fReady(false)
fInitStatus(B_ERROR)
{
*this = other;
}
BUrlRequest::~BUrlRequest()
{
if (fUrlProtocol != NULL)
delete fUrlProtocol;
}
// #pragma mark Request parameters modification
@ -60,16 +54,14 @@ BUrlRequest::SetUrl(const BUrl& url)
{
fUrl = url;
fResult.SetUrl(url);
if (fUrlProtocol != NULL && url.Protocol() == fUrl.Protocol())
if (fUrlProtocol != NULL && url.Protocol() == fUrl.Protocol()) {
fUrlProtocol->SetUrl(url);
else {
status_t err = Identify();
if (err != B_OK)
return err;
return B_OK;
}
return B_OK;
fInitStatus = _SetupProtocol();
return fInitStatus;
}
@ -84,7 +76,7 @@ void
BUrlRequest::SetProtocolListener(BUrlProtocolListener* listener)
{
fListener = listener;
if (fUrlProtocol != NULL)
fUrlProtocol->SetListener(listener);
}
@ -95,7 +87,7 @@ BUrlRequest::SetProtocolOption(int32 option, void* value)
{
if (fUrlProtocol == NULL)
return false;
fUrlProtocol->SetOption(option, value);
return true;
}
@ -129,44 +121,18 @@ BUrlRequest::Url()
status_t
BUrlRequest::Identify()
{
// TODO: instanciate the correct BUrlProtocol w/ the services roster
delete fUrlProtocol;
fUrlProtocol = NULL;
if (fUrl.Protocol() == "http") {
fUrlProtocol = new(std::nothrow) BUrlProtocolHttp(fUrl, false, "HTTP",
fListener, fContext,
&fResult);
fReady = true;
return B_OK;
} else if (fUrl.Protocol() == "https") {
fUrlProtocol = new(std::nothrow) BUrlProtocolHttp(fUrl, true, "HTTPS",
fListener, fContext,
&fResult);
fReady = true;
return B_OK;
}
fReady = false;
return B_NO_HANDLER_FOR_PROTOCOL;
}
status_t
BUrlRequest::Perform()
BUrlRequest::Start()
{
if (fUrlProtocol == NULL) {
PRINT(("BUrlRequest::Perform() : Oops, no BUrlProtocol defined!\n"));
return B_ERROR;
}
thread_id protocolThread = fUrlProtocol->Run();
if (protocolThread < B_OK)
return protocolThread;
return B_OK;
}
@ -176,7 +142,7 @@ BUrlRequest::Pause()
{
if (fUrlProtocol == NULL)
return B_ERROR;
return fUrlProtocol->Pause();
}
@ -186,7 +152,7 @@ BUrlRequest::Resume()
{
if (fUrlProtocol == NULL)
return B_ERROR;
return fUrlProtocol->Resume();
}
@ -196,11 +162,11 @@ BUrlRequest::Abort()
{
if (fUrlProtocol == NULL)
return B_ERROR;
status_t returnCode = fUrlProtocol->Stop();
delete fUrlProtocol;
fUrlProtocol = NULL;
return returnCode;
}
@ -208,10 +174,10 @@ BUrlRequest::Abort()
// #pragma mark Request informations
bool
status_t
BUrlRequest::InitCheck() const
{
return fReady;
return fInitStatus;
}
@ -220,7 +186,7 @@ BUrlRequest::IsRunning() const
{
if (fUrlProtocol == NULL)
return false;
return fUrlProtocol->IsRunning();
}
@ -230,7 +196,7 @@ BUrlRequest::Status() const
{
if (fUrlProtocol == NULL)
return B_ERROR;
return fUrlProtocol->Status();
}
@ -248,6 +214,29 @@ BUrlRequest::operator=(const BUrlRequest& other)
fContext = other.fContext;
fResult = BUrlResult(other.fUrl);
SetUrl(other.fUrl);
return *this;
}
status_t
BUrlRequest::_SetupProtocol()
{
// TODO: instanciate the correct BUrlProtocol w/ the services roster
delete fUrlProtocol;
fUrlProtocol = NULL;
if (fUrl.Protocol() == "http")
fUrlProtocol = new(std::nothrow) BUrlProtocolHttp(fUrl, false, "HTTP",
fListener, fContext, &fResult);
else if (fUrl.Protocol() == "https")
fUrlProtocol = new(std::nothrow) BUrlProtocolHttp(fUrl, true, "HTTPS",
fListener, fContext, &fResult);
else
return B_NO_HANDLER_FOR_PROTOCOL;
if (fUrlProtocol == NULL)
return B_NO_MEMORY;
return B_OK;
}

View File

@ -14,7 +14,7 @@
BUrlSynchronousRequest::BUrlSynchronousRequest(BUrl& url)
:
:
BUrlRequest(url, this),
fRequestComplete(false)
{
@ -26,8 +26,8 @@ BUrlSynchronousRequest::Perform()
{
SetProtocolListener(this);
fRequestComplete = false;
return BUrlRequest::Perform();
return Start();
}
@ -36,7 +36,7 @@ BUrlSynchronousRequest::WaitUntilCompletion()
{
while (!fRequestComplete)
snooze(10000);
return B_OK;
}
@ -70,7 +70,7 @@ BUrlSynchronousRequest::HeadersReceived(BUrlProtocol*)
void
BUrlSynchronousRequest::DataReceived(BUrlProtocol*, const char*,
BUrlSynchronousRequest::DataReceived(BUrlProtocol*, const char*,
ssize_t size)
{
PRINT(("SynchronousRequest::DataReceived(%zd)\n", size));
@ -78,7 +78,7 @@ BUrlSynchronousRequest::DataReceived(BUrlProtocol*, const char*,
void
BUrlSynchronousRequest::DownloadProgress(BUrlProtocol*,
BUrlSynchronousRequest::DownloadProgress(BUrlProtocol*,
ssize_t bytesReceived, ssize_t bytesTotal)
{
PRINT(("SynchronousRequest::DownloadProgress(%zd, %zd)\n", bytesReceived,
@ -98,7 +98,7 @@ BUrlSynchronousRequest::UploadProgress(BUrlProtocol*, ssize_t bytesSent,
void
BUrlSynchronousRequest::RequestCompleted(BUrlProtocol* 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())));
fRequestComplete = true;
}

View File

@ -20,7 +20,10 @@
#include <Font.h>
#include <GroupLayoutBuilder.h>
#include <GroupView.h>
#include <InterfaceDefs.h>
#include <LayoutBuilder.h>
#include <Message.h>
#include <MessageFilter.h>
#include <Point.h>
#include <Roster.h>
#include <Screen.h>
@ -42,6 +45,46 @@ using BPrivate::gSystemCatalog;
#define B_TRANSLATION_CONTEXT "AboutWindow"
class EscapeFilter : public BMessageFilter {
public:
EscapeFilter(BWindow* target)
:
BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE),
fTarget(target)
{
}
virtual ~EscapeFilter()
{
}
virtual filter_result
Filter(BMessage* message, BHandler** target)
{
filter_result result = B_DISPATCH_MESSAGE;
switch (message->what) {
case B_KEY_DOWN:
case B_UNMAPPED_KEY_DOWN: {
uint32 key;
if (message->FindInt32("raw_char",
(int32*)&key) >= B_OK) {
if (key == B_ESCAPE) {
result = B_SKIP_MESSAGE;
fTarget->PostMessage(
B_QUIT_REQUESTED);
}
}
break;
}
default:
break;
}
return result;
}
private:
BWindow* fTarget;
};
class StripeView : public BView {
public:
StripeView(BBitmap* icon);
@ -49,6 +92,9 @@ class StripeView : public BView {
virtual void Draw(BRect updateRect);
BBitmap* Icon() const { return fIcon; };
void SetIcon(BBitmap* icon);
private:
BBitmap* fIcon;
};
@ -62,14 +108,24 @@ class AboutView : public BGroupView {
BTextView* InfoView() const { return fInfoView; };
BBitmap* Icon();
status_t SetIcon(BBitmap* icon);
const char* Name();
status_t SetName(const char* name);
const char* Version();
status_t SetVersion(const char* version);
protected:
const char* AppVersion(const char* signature);
BBitmap* AppIcon(const char* signature);
const char* _GetVersionFromSignature(const char* signature);
BBitmap* _GetIconFromSignature(const char* signature);
private:
BStringView* fNameView;
BStringView* fVersionView;
BTextView* fInfoView;
StripeView* fStripeView;
};
@ -81,13 +137,14 @@ StripeView::StripeView(BBitmap* icon)
BView("StripeView", B_WILL_DRAW),
fIcon(icon)
{
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
float width = 0.0f;
if (icon != NULL)
width += icon->Bounds().Width() + 32.0f;
SetExplicitMinSize(BSize(width, B_SIZE_UNSET));
SetExplicitPreferredSize(BSize(width, B_SIZE_UNLIMITED));
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
}
@ -116,7 +173,24 @@ StripeView::Draw(BRect updateRect)
}
// #pragma mark -
void
StripeView::SetIcon(BBitmap* icon)
{
if (fIcon != NULL)
delete fIcon;
fIcon = icon;
float width = 0.0f;
if (icon != NULL)
width += icon->Bounds().Width() + 32.0f;
SetExplicitMinSize(BSize(width, B_SIZE_UNSET));
SetExplicitPreferredSize(BSize(width, B_SIZE_UNLIMITED));
};
// #pragma mark - AboutView
AboutView::AboutView(const char* appName, const char* signature)
@ -131,7 +205,8 @@ AboutView::AboutView(const char* appName, const char* signature)
fNameView->SetFont(&font, B_FONT_FAMILY_AND_STYLE | B_FONT_SIZE
| B_FONT_FLAGS);
fVersionView = new BStringView("version", AppVersion(signature));
fVersionView = new BStringView("version",
_GetVersionFromSignature(signature));
fInfoView = new BTextView("info", B_WILL_DRAW);
fInfoView->SetExplicitMinSize(BSize(210.0, 160.0));
@ -145,10 +220,12 @@ AboutView::AboutView(const char* appName, const char* signature)
"infoViewScroller", fInfoView, B_WILL_DRAW | B_FRAME_EVENTS,
false, true, B_PLAIN_BORDER);
fStripeView = new StripeView(_GetIconFromSignature(signature));
GroupLayout()->SetSpacing(0);
BLayoutBuilder::Group<>(this)
.AddGroup(B_HORIZONTAL, 0)
.Add(new StripeView(AppIcon(signature)))
.Add(fStripeView)
.AddGroup(B_VERTICAL, B_USE_SMALL_SPACING)
.SetInsets(0, B_USE_DEFAULT_SPACING,
B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING)
@ -166,8 +243,11 @@ AboutView::~AboutView()
}
// #pragma mark - AboutView protected methods
const char*
AboutView::AppVersion(const char* signature)
AboutView::_GetVersionFromSignature(const char* signature)
{
if (signature == NULL)
return NULL;
@ -228,7 +308,7 @@ AboutView::AppVersion(const char* signature)
BBitmap*
AboutView::AppIcon(const char* signature)
AboutView::_GetIconFromSignature(const char* signature)
{
if (signature == NULL)
return NULL;
@ -251,7 +331,64 @@ AboutView::AppIcon(const char* signature)
}
// #pragma mark -
// #pragma mark - AboutView public methods
const char*
AboutView::Name()
{
return fNameView->Text();
}
status_t
AboutView::SetName(const char* name)
{
fNameView->SetText(name);
return B_OK;
}
const char*
AboutView::Version()
{
return fVersionView->Text();
}
status_t
AboutView::SetVersion(const char* version)
{
fVersionView->SetText(version);
return B_OK;
}
BBitmap*
AboutView::Icon()
{
if (fStripeView == NULL)
return NULL;
return fStripeView->Icon();
}
status_t
AboutView::SetIcon(BBitmap* icon)
{
if (fStripeView == NULL)
return B_NO_INIT;
fStripeView->SetIcon(icon);
return B_OK;
}
// #pragma mark - BAboutWindow
BAboutWindow::BAboutWindow(const char* appName, const char* signature)
@ -272,6 +409,8 @@ BAboutWindow::BAboutWindow(const char* appName, const char* signature)
AddChild(fAboutView);
MoveTo(AboutPosition(Frame().Width(), Frame().Height()));
AddCommonFilter(new EscapeFilter(this));
}
@ -283,6 +422,9 @@ BAboutWindow::~BAboutWindow()
}
// #pragma mark - BAboutWindow virtual methods
bool
BAboutWindow::QuitRequested()
{
@ -292,7 +434,19 @@ BAboutWindow::QuitRequested()
}
// #pragma mark -
void
BAboutWindow::Show()
{
if (IsHidden()) {
// move to current workspace
SetWorkspaces(B_CURRENT_WORKSPACE);
}
BWindow::Show();
}
// #pragma mark - BAboutWindow public methods
BPoint
@ -463,3 +617,45 @@ BAboutWindow::AddExtraInfo(const char* extraInfo)
fAboutView->InfoView()->Insert(extra.String());
}
const char*
BAboutWindow::Name()
{
return fAboutView->Name();
}
void
BAboutWindow::SetName(const char* name)
{
fAboutView->SetName(name);
}
const char*
BAboutWindow::Version()
{
return fAboutView->Version();
}
void
BAboutWindow::SetVersion(const char* version)
{
fAboutView->SetVersion(version);
}
BBitmap*
BAboutWindow::Icon()
{
return fAboutView->Icon();
}
void
BAboutWindow::SetIcon(BBitmap* icon)
{
fAboutView->SetIcon(icon);
}

View File

@ -70,11 +70,11 @@ const uint32 kRevertButtonPressed = 'Rebp';
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "TrackerSettingsWindow"
TrackerSettingsWindow::TrackerSettingsWindow()
:
BWindow(BRect(80, 80, 450, 350), B_TRANSLATE("Tracker preferences"),
B_TITLED_WINDOW, B_NOT_MINIMIZABLE | B_NOT_RESIZABLE
| B_NO_WORKSPACE_ACTIVATION | B_NOT_ANCHORED_ON_ACTIVATE
| B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE
| B_AUTO_UPDATE_SIZE_LIMITS)
{
@ -184,6 +184,12 @@ TrackerSettingsWindow::Show()
Unlock();
}
if (IsHidden()) {
// move to current workspace
SetWorkspaces(B_CURRENT_WORKSPACE);
}
_inherited::Show();
}