VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox4/src/VBoxNetworkFramework.cpp@ 11401

Last change on this file since 11401 was 11401, checked in by vboxsync, 17 years ago

Fe/Qt4: New Version notifier reworked according latest requirements (package type in url's body and all the extended information in user-agent header). Network framework reworked to use headers+body for POST request instead of just URL.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Revision Author Id
File size: 6.1 KB
Line 
1/** @file
2 *
3 * VBox frontends: Qt GUI ("VirtualBox"):
4 * VBoxNetworkFramework class implementation
5 */
6
7/*
8 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
19 * Clara, CA 95054 USA or visit http://www.sun.com if you need
20 * additional information or have any questions.
21 */
22
23#include <VBoxNetworkFramework.h>
24
25/* Qt includes */
26#include <QApplication>
27
28/* These notifications are used to notify the GUI thread about different
29 * downloading events: Downloading Started, Downloading in Progress,
30 * Downloading Finished, Downloading Error. */
31enum PostingEvents
32{
33 PostBeginEventType = QEvent::User + 500,
34 PostDataEventType,
35 PostFinishEventType,
36 PostErrorEventType
37};
38
39class PostBeginEvent : public QEvent
40{
41public:
42 PostBeginEvent (int aStatus)
43 : QEvent ((QEvent::Type) PostBeginEventType)
44 , mStatus (aStatus) {}
45
46 int mStatus;
47};
48
49class PostDataEvent : public QEvent
50{
51public:
52 PostDataEvent (const char *aData, ulong aSize)
53 : QEvent ((QEvent::Type) PostDataEventType)
54 , mData (aData, aSize) {}
55
56 QByteArray mData;
57};
58
59class PostFinishEvent : public QEvent
60{
61public:
62 PostFinishEvent()
63 : QEvent ((QEvent::Type) PostFinishEventType) {}
64};
65
66class PostErrorEvent : public QEvent
67{
68public:
69 PostErrorEvent (const QString &aInfo)
70 : QEvent ((QEvent::Type) PostErrorEventType)
71 , mInfo (aInfo) {}
72
73 QString mInfo;
74};
75
76/* This callback is used to handle the request procedure beginning. */
77void onBegin (const happyhttp::Response *aResponse, void *aUserdata)
78{
79 VBoxNetworkFramework *obj = static_cast<VBoxNetworkFramework*> (aUserdata);
80 QApplication::postEvent (obj, new PostBeginEvent (aResponse->getstatus()));
81}
82
83/* This callback is used to handle the progress of request procedure. */
84void onData (const happyhttp::Response*, void *aUserdata,
85 const unsigned char *aData, int aSize)
86{
87 VBoxNetworkFramework *obj = static_cast<VBoxNetworkFramework*> (aUserdata);
88 QApplication::postEvent (obj, new PostDataEvent ((const char*) aData, aSize));
89}
90
91/* This callback is used to handle the finish event of every request. */
92void onFinish (const happyhttp::Response*, void *aUserdata)
93{
94 VBoxNetworkFramework *obj = static_cast<VBoxNetworkFramework*> (aUserdata);
95 QApplication::postEvent (obj, new PostFinishEvent());
96}
97
98bool VBoxNetworkFramework::event (QEvent *aEvent)
99{
100 switch (aEvent->type())
101 {
102 case PostBeginEventType:
103 {
104 PostBeginEvent *e = static_cast<PostBeginEvent*> (aEvent);
105 emit netBegin (e->mStatus);
106 return true;
107 }
108 case PostDataEventType:
109 {
110 PostDataEvent *e = static_cast<PostDataEvent*> (aEvent);
111 mDataStream.writeRawData (e->mData.data(), e->mData.size());
112 emit netData (e->mData);
113 return true;
114 }
115 case PostFinishEventType:
116 {
117 emit netEnd (mDataArray);
118 return true;
119 }
120 case PostErrorEventType:
121 {
122 PostErrorEvent *e = static_cast<PostErrorEvent*> (aEvent);
123 emit netError (e->mInfo);
124 return true;
125 }
126 default:
127 break;
128 }
129
130 return QObject::event (aEvent);
131}
132
133void VBoxNetworkFramework::postRequest (const QString &aHost,
134 const QString &aUrl,
135 const QString &aBody,
136 const QStringList &aHeaders)
137{
138 /* Network requests thread class */
139 class Thread : public QThread
140 {
141 public:
142
143 Thread (QObject *aHandler, const QString &aHost, const QString &aUrl,
144 const QString &aBody, const QStringList &aHeaders)
145 : mHandler (aHandler), mHost (aHost), mUrl (aUrl)
146 , mBody (aBody), mHeaders (aHeaders) {}
147
148 virtual void run()
149 {
150 try
151 {
152 /* Create & setup connection */
153 HConnect conn (mHost.toAscii().constData(), 80);
154 conn.setcallbacks (onBegin, onData, onFinish, mHandler);
155
156 /* Format POST request */
157 conn.putrequest ("POST", mUrl.toAscii().constData());
158
159 /* Append standard headers */
160 conn.putheader ("Connection", "close");
161 conn.putheader ("Content-Length", mBody.size());
162 conn.putheader ("Content-type", "application/x-www-form-urlencoded");
163 conn.putheader ("Accept", "text/plain");
164
165 /* Append additional headers */
166 for (int i = 0; i < mHeaders.size(); i = i + 2)
167 conn.putheader (mHeaders [i].toAscii().constData(),
168 mHeaders [i + 1].toAscii().constData());
169
170 /* Finishing header */
171 conn.endheaders();
172
173 /* Append & send body */
174 conn.send ((const unsigned char*) mBody.toAscii().constData(),
175 mBody.toAscii().size());
176
177 /* Pull the connection for response */
178 while (conn.outstanding())
179 conn.pump();
180 }
181 catch (happyhttp::Wobbly &ex)
182 {
183 QApplication::postEvent (mHandler, new PostErrorEvent (ex.what()));
184 }
185 }
186
187 private:
188
189 QObject *mHandler;
190 QString mHost;
191 QString mUrl;
192 QString mBody;
193 QStringList mHeaders;
194 };
195
196 if (mNetworkThread)
197 mNetworkThread->wait (1000);
198 delete mNetworkThread;
199 mNetworkThread = new Thread (this, aHost, aUrl, aBody, aHeaders);
200 mNetworkThread->start();
201}
202
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette