rhodes 2.1.0 → 2.2.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +7 -0
- data/README.textile +4 -5
- data/Rakefile +8 -1
- data/lib/build/jake.rb +22 -16
- data/lib/extensions/rhoxml/rexml/cdata.rb +67 -0
- data/lib/extensions/rhoxml/rexml/document.rb +2 -116
- data/lib/extensions/rhoxml/rexml/element.rb +1 -1
- data/lib/extensions/rhoxml/rexml/text.rb +117 -0
- data/lib/framework/rho/render.rb +19 -11
- data/lib/framework/rho/rho.rb +17 -10
- data/lib/framework/rho/rhobluetooth.rb +103 -0
- data/lib/framework/rho/rhocontroller.rb +2 -0
- data/lib/framework/rho/rhoevent.rb +43 -0
- data/lib/framework/rho/rhoevent_bb.rb +80 -0
- data/lib/framework/rho/rhoevent_c.rb +47 -0
- data/lib/framework/rhodes.rb +2 -2
- data/lib/framework/rhom/rhom_db_adapter.rb +2 -1
- data/lib/framework/rhom/rhom_model.rb +9 -3
- data/lib/framework/rhom/rhom_object_factory.rb +46 -22
- data/lib/framework/rhom/rhom_source.rb +12 -10
- data/lib/framework/version.rb +2 -2
- data/lib/rhodes.rb +2 -2
- data/platform/android/Rhodes/AndroidManifest.xml +23 -2
- data/platform/android/Rhodes/gen/com/rhomobile/rhodes/R.java +54 -38
- data/platform/android/Rhodes/jni/include/rhodes.h +3 -0
- data/platform/android/Rhodes/jni/include/rhodes/JNIRhodes.h +2 -2
- data/platform/android/Rhodes/jni/include/rhodes/details/rhojava.inc +4 -0
- data/platform/android/Rhodes/jni/include/rhodes/jni/com_rhomobile_rhodes_RhodesService.h +16 -0
- data/platform/android/Rhodes/jni/include/rhodes/jni/com_rhomobile_rhodes_bluetooth_RhoBluetoothManager.h +21 -0
- data/platform/android/Rhodes/jni/src/bluetooth.cpp +169 -0
- data/platform/android/Rhodes/jni/src/callbacks.cpp +10 -0
- data/platform/android/Rhodes/jni/src/event.cpp +429 -0
- data/platform/android/Rhodes/jni/src/fileapi.cpp +51 -1
- data/platform/android/Rhodes/jni/src/rhodes.cpp +16 -0
- data/platform/android/Rhodes/jni/src/sslimpl.cpp +3 -0
- data/platform/android/Rhodes/res/layout/bt_device_list.xml +42 -0
- data/platform/android/Rhodes/res/layout/bt_device_name.xml +7 -0
- data/platform/android/Rhodes/res/values/strings.xml +8 -0
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/AndroidR.java +14 -0
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/Capabilities.java +2 -0
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/Push.java +7 -0
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/PushReceiver.java +58 -0
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/PushService.java +53 -0
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/Rhodes.java +8 -0
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/RhodesService.java +144 -3
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/bluetooth/IRhoBluetoothManager.java +66 -0
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/bluetooth/RhoBluetoothDeviceListActivity.java +201 -0
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/bluetooth/RhoBluetoothManager.java +139 -0
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/bluetooth/RhoBluetoothManagerNew.java +401 -0
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/bluetooth/RhoBluetoothManagerOld.java +136 -0
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/bluetooth/RhoBluetoothSession.java +457 -0
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/bluetooth/UUIDHelper.java +71 -0
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/camera/ImageCapture.java +12 -7
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/event/Event.java +19 -0
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/event/EventStore.java +261 -0
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/mainview/SimpleMainView.java +4 -2
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/mainview/TabbedMainView.java +2 -2
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/uri/MailUriHandler.java +10 -2
- data/platform/android/build/RhodesSRC_build.files +33 -22
- data/platform/android/build/android.rake +198 -27
- data/platform/android/build/librhodes_build.files +3 -1
- data/platform/android/build/libruby_build.files +4 -1
- data/platform/bb/Hsqldb/src/com/rho/db/HsqlDBResult.java +2 -2
- data/platform/bb/Hsqldb/src/com/rho/db/HsqlDBRowResult.java +1 -1
- data/platform/bb/Hsqldb/src/org/hsqldb/Expression.java +7 -4
- data/platform/bb/Hsqldb/src/org/hsqldb/Like.java +3 -3
- data/platform/bb/Hsqldb/src/org/hsqldb/Table.java +3 -1
- data/platform/bb/Hsqldb/src/org/hsqldb/Tokenizer.java +1 -1
- data/platform/bb/RubyVM/RubyVM.jdp +1 -0
- data/platform/bb/RubyVM/src/com/rho/RhoConf.java +108 -1
- data/platform/bb/RubyVM/src/com/rho/RhoLogConf.java +7 -1
- data/platform/bb/RubyVM/src/com/rho/RhoRuby.java +7 -4
- data/platform/bb/RubyVM/src/com/rho/ThreadQueue.java +7 -1
- data/platform/bb/RubyVM/src/com/rho/net/AsyncHttp.java +1 -1
- data/platform/bb/RubyVM/src/com/rho/net/NetRequest.java +21 -23
- data/platform/bb/RubyVM/src/com/rho/net/RhoConnection.java +19 -10
- data/platform/bb/RubyVM/src/com/rho/sync/SyncEngine.java +8 -0
- data/platform/bb/RubyVM/src/com/rho/sync/SyncNotify.java +3 -0
- data/platform/bb/RubyVM/src/com/rho/sync/SyncThread.java +14 -17
- data/platform/bb/RubyVM/src/com/xruby/runtime/builtin/RubyFile.java +7 -5
- data/platform/bb/RubyVM/src/com/xruby/runtime/lang/RhoSupport.java +2 -0
- data/platform/bb/RubyVM/src/com/xruby/runtime/lang/RubyRuntime.java +10 -1
- data/platform/bb/RubyVM/src/j2me/io/File.java +7 -6
- data/platform/bb/build/RubyVM_build.files +412 -412
- data/platform/bb/build/bb.rake +42 -18
- data/platform/bb/build/hsqldb_build.files +151 -151
- data/platform/bb/build/rhodes_build.files +44 -40
- data/platform/bb/rhodes/platform/5.0/com/rho/BrowserAdapter5.java +2 -0
- data/platform/bb/rhodes/platform/5.0/com/rho/RhodesApplicationPlatform.java +237 -0
- data/platform/bb/rhodes/platform/common/com/rho/RhodesApplicationPlatform.java +14 -0
- data/platform/bb/rhodes/rhodes.jdp +6 -1
- data/platform/bb/rhodes/src/com/rho/RhoRubyHelper.java +7 -1
- data/platform/bb/rhodes/src/com/rho/RhodesApplicationPlatform.java +14 -0
- data/platform/bb/rhodes/src/com/rho/net/NetworkAccess.java +62 -76
- data/platform/bb/rhodes/src/com/rho/rubyext/RhoCalendar.java +660 -0
- data/platform/bb/rhodes/src/{rhomobile → com/rho/rubyext}/RhoPhonebook.java +95 -38
- data/platform/bb/rhodes/src/com/rho/rubyext/System.java +22 -1
- data/platform/bb/rhodes/src/rhomobile/PushListeningThread.java +26 -6
- data/platform/bb/rhodes/src/rhomobile/RhodesApplication.java +21 -7
- data/platform/bb/rhodes/src/rhomobile/bluetooth/BluetoothManager.java +528 -0
- data/platform/bb/rhodes/src/rhomobile/bluetooth/BluetoothPort.java +281 -0
- data/platform/bb/rhodes/src/rhomobile/bluetooth/BluetoothScreen.java +119 -0
- data/platform/bb/rhodes/src/rhomobile/camera/CameraFilesListener.java +2 -2
- data/platform/iphone/Classes/AppManager/AppManager.m +70 -7
- data/platform/iphone/Classes/Bluetooth/Bluetooth.h +72 -0
- data/platform/iphone/Classes/Bluetooth/Bluetooth.m +414 -0
- data/platform/iphone/Classes/Event/Event.h +12 -0
- data/platform/iphone/Classes/Event/Event.m +300 -0
- data/platform/iphone/Classes/LogOptionsController.h +2 -1
- data/platform/iphone/Classes/LogOptionsController.m +1 -1
- data/platform/iphone/Classes/LogViewController.h +2 -1
- data/platform/iphone/Classes/MapView/MapViewController.h +2 -1
- data/platform/iphone/Classes/RhoViewController.h +16 -0
- data/platform/iphone/Classes/RhoViewController.m +20 -0
- data/platform/iphone/Classes/Rhodes.h +12 -0
- data/platform/iphone/Classes/Rhodes.m +34 -6
- data/platform/iphone/Classes/Signature/SignatureViewController.h +2 -2
- data/platform/iphone/Classes/Signature/SignatureViewController.m +0 -10
- data/platform/iphone/Classes/SimpleMainView.h +2 -2
- data/platform/iphone/Classes/SimpleMainView.m +5 -14
- data/platform/iphone/Classes/SplashViewController.h +2 -2
- data/platform/iphone/Classes/TabbedMainView.h +2 -2
- data/platform/iphone/Classes/TabbedMainView.m +5 -10
- data/platform/iphone/Info.plist +5 -5
- data/platform/iphone/rhorubylib/rhorubylib.xcodeproj/project.pbxproj +39 -0
- data/platform/iphone/rhorunner.xcodeproj/project.pbxproj +47 -4
- data/platform/osx/Rhodes Debugger/NoodleLineNumberView.m +3 -2
- data/platform/shared/common/AutoPointer.h +3 -0
- data/platform/shared/common/RhoConf.cpp +2 -1
- data/platform/shared/common/RhoThread.h +1 -1
- data/platform/shared/common/RhoTime.h +3 -3
- data/platform/shared/common/RhodesApp.cpp +75 -23
- data/platform/shared/common/RhodesApp.h +4 -0
- data/platform/shared/common/RhodesAppBase.h +2 -0
- data/platform/shared/common/ThreadQueue.cpp +23 -18
- data/platform/shared/common/ThreadQueue.h +2 -0
- data/platform/shared/db/res/db/syncdb.schema +39 -39
- data/platform/shared/logging/RhoLogConf.cpp +58 -3
- data/platform/shared/logging/RhoLogConf.h +3 -1
- data/platform/shared/net/CURLNetRequest.cpp +17 -6
- data/platform/shared/net/HttpServer.cpp +125 -25
- data/platform/shared/net/HttpServer.h +4 -3
- data/platform/shared/ruby/ext/bluetooth/bluetooth.i +56 -0
- data/platform/shared/ruby/ext/bluetooth/bluetooth_wrap.c +2563 -0
- data/platform/shared/ruby/ext/calendar/calendar.i +28 -0
- data/platform/shared/ruby/ext/calendar/calendar_wrap.c +2251 -0
- data/platform/shared/ruby/ext/calendar/event.h +41 -0
- data/platform/shared/ruby/ext/calendar/event.i +28 -0
- data/platform/shared/ruby/ext/calendar/event_wrap.c +2151 -0
- data/platform/shared/ruby/ext/rho/rhoruby.c +103 -3
- data/platform/shared/ruby/ext/rho/rhoruby.h +16 -2
- data/platform/shared/ruby/ext/rhoconf/rhoconf.i +12 -0
- data/platform/shared/ruby/ext/rhoconf/rhoconf_wrap.c +101 -0
- data/platform/shared/ruby/ext/system/system.i +14 -0
- data/platform/shared/ruby/ext/system/system_wrap.c +2568 -2208
- data/platform/shared/ruby/main.c +8 -0
- data/platform/shared/rubyext/GeoLocation.cpp +6 -3
- data/platform/shared/rubyext/System.cpp +14 -0
- data/platform/shared/sync/SyncEngine.cpp +9 -1
- data/platform/shared/sync/SyncNotify.cpp +16 -8
- data/platform/shared/sync/SyncNotify.h +1 -0
- data/platform/shared/sync/SyncThread.cpp +7 -12
- data/platform/shared/sync/SyncThread.h +5 -3
- data/platform/wm/build/wm.rake +7 -1
- data/platform/wm/rhodes/Alert.cpp +1 -1
- data/platform/wm/rhodes/MainWindow.cpp +28 -0
- data/platform/wm/rhodes/MainWindow.h +9 -0
- data/platform/wm/rhodes/OutlookApp.cpp +72 -0
- data/platform/wm/rhodes/OutlookApp.h +22 -0
- data/platform/wm/rhodes/Rhodes.cpp +8 -0
- data/platform/wm/rhodes/Rhodes.rc +31 -0
- data/platform/wm/rhodes/bluetooth/Bluetooth.cpp +1274 -0
- data/platform/wm/rhodes/bluetooth/Bluetooth.h +321 -0
- data/platform/wm/rhodes/phonebook/NativeAddressBook.cpp +37 -70
- data/platform/wm/rhodes/phonebook/NativeAddressBook.h +0 -4
- data/platform/wm/rhodes/resource.h +8 -1
- data/platform/wm/rhodes/rho/net/NetRequest.cpp +4 -0
- data/platform/wm/rhodes/rho/net/NetRequestImpl.cpp +6 -4
- data/platform/wm/rhodes/rho/rubyext/calendar.cpp +487 -0
- data/platform/wm/rhodes/rhodes.vcproj +28 -11
- data/platform/wm/rhodes/stdafx.h +1 -0
- data/platform/wm/rubylib/rubylib.vcproj +32 -0
- data/rakefile.rb +8 -1
- data/res/generators/templates/application/Rakefile +1 -1
- data/res/generators/templates/application/app/layout.erb +4 -1
- data/res/generators/templates/application/build.yml +0 -1
- data/res/generators/templates/application/public/css/iphone.css +2 -2
- data/res/generators/templates/application/public/jqtouch/jqtouch-iphone.css +9 -0
- data/res/generators/templates/application/public/jqtouch/jqtouch.css +1 -5
- data/res/generators/templates/application/public/jqtouch/jqtouch.js +3 -2
- data/rhodes.gemspec +1 -1
- data/spec/perfomance_spec/app/Benchmark/benchmark.rb +4 -0
- data/spec/perfomance_spec/app/Benchmark/bulk_results.erb +13 -0
- data/spec/perfomance_spec/app/Benchmark/controller.rb +178 -0
- data/spec/perfomance_spec/app/Benchmark/create_results.erb +13 -0
- data/spec/perfomance_spec/app/Benchmark/customers.erb +35 -0
- data/spec/perfomance_spec/app/Benchmark/index.erb +9 -0
- data/spec/perfomance_spec/app/Benchmark/products.erb +25 -0
- data/spec/perfomance_spec/app/Benchmark/search_results.erb +13 -0
- data/spec/perfomance_spec/app/Customer/customer.rb +6 -0
- data/spec/perfomance_spec/app/Perftest/index.erb +5 -0
- data/spec/perfomance_spec/app/Product/index.erb +25 -0
- data/spec/perfomance_spec/app/Product/product.rb +6 -0
- data/spec/perfomance_spec/app/helpers/application_helper.rb +126 -0
- data/spec/perfomance_spec/app/helpers/browser_helper.rb +18 -0
- data/spec/perfomance_spec/rhoconfig.txt +1 -1
- data/spec/phone_spec/app/Account_s/account_s.rb +5 -2
- data/spec/phone_spec/app/Case/case.rb +1 -0
- data/spec/phone_spec/app/Case_s/case_s.rb +2 -0
- data/spec/phone_spec/app/Data/perftest.json +35 -0
- data/spec/phone_spec/app/Data/testCDATA.xml +11 -0
- data/spec/phone_spec/app/Product/product.rb +1 -1
- data/spec/phone_spec/app/{Spec → spec}/asynchttp_spec.rb +66 -17
- data/spec/phone_spec/app/{Spec → spec}/barcode_spec.rb +0 -0
- data/spec/phone_spec/app/{Spec → spec}/blobsync_spec.rb +0 -0
- data/spec/phone_spec/app/{Spec → spec}/bsearch_spec.rb +0 -0
- data/spec/phone_spec/app/{Spec → spec}/bulksync_spec.rb +0 -0
- data/spec/phone_spec/app/{Spec → spec}/contacts_spec.rb +0 -0
- data/spec/phone_spec/app/{Spec → spec}/crypt_spec.rb +0 -0
- data/spec/phone_spec/app/{Spec → spec}/date_spec.rb +0 -0
- data/spec/phone_spec/app/spec/events_spec.rb +199 -0
- data/spec/phone_spec/app/{Spec → spec}/fixtures/client_info.txt +0 -0
- data/spec/phone_spec/app/{Spec → spec}/fixtures/object_values.txt +0 -0
- data/spec/phone_spec/app/{Spec → spec}/json_spec.rb +11 -2
- data/spec/phone_spec/app/{Spec → spec}/mapview_spec.rb +0 -0
- data/spec/phone_spec/app/{Spec → spec}/nativebar_spec.rb +0 -0
- data/spec/phone_spec/app/{Spec → spec}/navbar_spec.rb +0 -0
- data/spec/phone_spec/app/{Spec → spec}/pagination/fixtures/object_values.txt +0 -0
- data/spec/phone_spec/app/{Spec → spec}/rho_controller_spec.rb +5 -0
- data/spec/phone_spec/app/{Spec → spec}/rho_spec.rb +48 -0
- data/spec/phone_spec/app/{Spec → spec}/rhofile_spec.rb +9 -6
- data/spec/phone_spec/app/{Spec → spec}/rhom_object_spec.rb +188 -9
- data/spec/phone_spec/app/{Spec → spec}/syncengine_spec.rb +0 -0
- data/spec/phone_spec/app/{Spec → spec}/xml_spec.rb +15 -0
- data/spec/phone_spec/app/{Spec → spec}/xruby_spec.rb +0 -0
- data/spec/phone_spec/app/spec_runner.rb +4 -1
- data/spec/phone_spec/build.yml +2 -1
- metadata +95 -31
- data/platform/bb/rhodes/platform/5.0/com/rho/RhoMainScreen.java +0 -36
- data/platform/bb/rhodes/platform/6.0/com/rho/BrowserAdapter5.java +0 -155
- data/platform/bb/rhodes/platform/6.0/com/rho/RhoMainScreen.java +0 -36
@@ -32,16 +32,28 @@ LogSettings::~LogSettings(){
|
|
32
32
|
delete m_pOutputSink;
|
33
33
|
}
|
34
34
|
|
35
|
-
void LogSettings::getLogTextW(StringW& strTextW)
|
35
|
+
void LogSettings::getLogTextW(StringW& strTextW)
|
36
|
+
{
|
37
|
+
boolean bOldSaveToFile = isLogToFile();
|
38
|
+
setLogToFile(false);
|
39
|
+
|
36
40
|
common::CRhoFile oFile;
|
37
41
|
if ( oFile.open( getLogFilePath().c_str(), common::CRhoFile::OpenReadOnly) )
|
38
42
|
oFile.readStringW(strTextW);
|
43
|
+
|
44
|
+
setLogToFile(bOldSaveToFile);
|
39
45
|
}
|
40
46
|
|
41
|
-
void LogSettings::getLogText(String& strText)
|
47
|
+
void LogSettings::getLogText(String& strText)
|
48
|
+
{
|
49
|
+
boolean bOldSaveToFile = isLogToFile();
|
50
|
+
setLogToFile(false);
|
51
|
+
|
42
52
|
common::CRhoFile oFile;
|
43
53
|
if ( oFile.open( getLogFilePath().c_str(), common::CRhoFile::OpenReadOnly) )
|
44
54
|
oFile.readString(strText);
|
55
|
+
|
56
|
+
setLogToFile(bOldSaveToFile);
|
45
57
|
}
|
46
58
|
|
47
59
|
int LogSettings::getLogTextPos()
|
@@ -209,7 +221,7 @@ void rho_logconf_setDisabledCategories(const char* categories) {
|
|
209
221
|
LOGCONF().setDisabledCategories(categories);
|
210
222
|
}
|
211
223
|
|
212
|
-
void
|
224
|
+
void rho_logconf_setSeverity(int nLevel) {
|
213
225
|
LOGCONF().setMinSeverity(nLevel);
|
214
226
|
}
|
215
227
|
|
@@ -230,6 +242,11 @@ void rho_conf_set_property_by_name(char* name, char* value)
|
|
230
242
|
LOGCONF().loadFromConf(RHOCONF());
|
231
243
|
}
|
232
244
|
|
245
|
+
void rho_conf_clean_log()
|
246
|
+
{
|
247
|
+
LOGCONF().clearLog();
|
248
|
+
}
|
249
|
+
|
233
250
|
#ifndef RHO_NO_RUBY
|
234
251
|
VALUE rho_conf_get_property_by_name(char* name)
|
235
252
|
{
|
@@ -237,6 +254,44 @@ VALUE rho_conf_get_property_by_name(char* name)
|
|
237
254
|
|
238
255
|
return rho_ruby_create_string(szValue);
|
239
256
|
}
|
257
|
+
|
258
|
+
VALUE rho_conf_read_log(int limit)
|
259
|
+
{
|
260
|
+
VALUE res = rho_ruby_create_string("");
|
261
|
+
bool bOldSaveToFile = LOGCONF().isLogToFile();
|
262
|
+
LOGCONF().setLogToFile(false);
|
263
|
+
|
264
|
+
rho::common::CRhoFile oFile;
|
265
|
+
if ( oFile.open( LOGCONF().getLogFilePath().c_str(), rho::common::CRhoFile::OpenReadOnly) )
|
266
|
+
{
|
267
|
+
int nFileSize = oFile.size();
|
268
|
+
int nPos = LOGCONF().getLogTextPos();
|
269
|
+
int nMaxSize = nFileSize > nPos ? nFileSize : nPos;
|
270
|
+
if ( limit <= 0 || limit > nMaxSize)
|
271
|
+
limit = nMaxSize;
|
272
|
+
|
273
|
+
res = rho_ruby_create_string_withlen(limit);
|
274
|
+
char* szStr = getStringFromValue(res);
|
275
|
+
|
276
|
+
if ( limit <= nPos )
|
277
|
+
{
|
278
|
+
oFile.setPosTo(nPos-limit);
|
279
|
+
oFile.readData(szStr,0,limit);
|
280
|
+
}else
|
281
|
+
{
|
282
|
+
oFile.setPosTo(nFileSize-(limit-nPos));
|
283
|
+
int nRead = oFile.readData(szStr,0,limit);
|
284
|
+
|
285
|
+
oFile.setPosTo(0);
|
286
|
+
oFile.readData(szStr,nRead,limit-nRead);
|
287
|
+
}
|
288
|
+
|
289
|
+
}
|
290
|
+
|
291
|
+
LOGCONF().setLogToFile(bOldSaveToFile);
|
292
|
+
|
293
|
+
return res;
|
294
|
+
}
|
240
295
|
#endif //RHO_NO_RUBY
|
241
296
|
|
242
297
|
}
|
@@ -111,11 +111,13 @@ int rho_logconf_getSeverity();
|
|
111
111
|
|
112
112
|
void rho_logconf_setEnabledCategories(const char* categories);
|
113
113
|
void rho_logconf_setDisabledCategories(const char* categories);
|
114
|
-
void
|
114
|
+
void rho_logconf_setSeverity(int nLevel);
|
115
115
|
|
116
116
|
void rho_logconf_saveSettings();
|
117
117
|
void rho_logconf_freeString(char* str);
|
118
118
|
|
119
|
+
void rho_conf_clean_log();
|
120
|
+
|
119
121
|
#ifdef __cplusplus
|
120
122
|
}
|
121
123
|
#endif //__cplusplus
|
@@ -53,7 +53,7 @@ public:
|
|
53
53
|
|
54
54
|
virtual boolean isOK()
|
55
55
|
{
|
56
|
-
return m_nRespCode == 200;
|
56
|
+
return m_nRespCode == 200 || m_nRespCode == 206;
|
57
57
|
}
|
58
58
|
|
59
59
|
virtual boolean isUnathorized()
|
@@ -183,7 +183,11 @@ INetResponse* CURLNetRequest::doPull(const char* method, const String& strUrl,
|
|
183
183
|
long statusCode = 0;
|
184
184
|
if (curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &statusCode) != 0)
|
185
185
|
statusCode = 500;
|
186
|
-
|
186
|
+
|
187
|
+
if (statusCode == 416 )
|
188
|
+
{
|
189
|
+
//Do nothing, file is already loaded
|
190
|
+
}else if (statusCode == 206) {
|
187
191
|
if (oFile)
|
188
192
|
oFile->write(strRespChunk.c_str(), strRespChunk.size());
|
189
193
|
else
|
@@ -222,7 +226,7 @@ INetResponse* CURLNetRequest::pullFile(const String& strUrl, const String& strFi
|
|
222
226
|
RAWLOG_INFO2("Pull file. Url: %s; File: %s", strUrl.c_str(), strFilePath.c_str());
|
223
227
|
|
224
228
|
common::CRhoFile oFile;
|
225
|
-
if ( !oFile.open(strFilePath.c_str(),common::CRhoFile::
|
229
|
+
if ( !oFile.open(strFilePath.c_str(),common::CRhoFile::OpenForAppend) )
|
226
230
|
{
|
227
231
|
RAWLOG_ERROR1("pullFile: cannot create file: %s", strFilePath.c_str());
|
228
232
|
return new CURLNetResponseImpl("", nRespCode);
|
@@ -356,14 +360,18 @@ INetResponse* CURLNetRequest::pushFile(const String& strUrl, const String& strFi
|
|
356
360
|
|
357
361
|
int CURLNetRequest::getResponseCode(CURLcode err, const String& strRespBody, IRhoSession* oSession )
|
358
362
|
{
|
359
|
-
if (err != CURLE_OK)
|
360
|
-
|
363
|
+
//if (err != CURLE_OK)
|
364
|
+
// return -1;
|
361
365
|
|
362
366
|
long statusCode = 0;
|
363
367
|
CURL *curl = m_curl.curl();
|
364
368
|
if (curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &statusCode) != 0)
|
365
369
|
statusCode = 500;
|
366
370
|
|
371
|
+
if (statusCode == 416) {
|
372
|
+
statusCode = 206;
|
373
|
+
}
|
374
|
+
|
367
375
|
if (statusCode >= 400) {
|
368
376
|
RAWLOG_ERROR2("Request failed. HTTP Code: %d returned. HTTP Response: %s",
|
369
377
|
(int)statusCode, strRespBody.c_str());
|
@@ -484,6 +492,9 @@ curl_slist *CURLNetRequest::CURLHolder::set_options(const char *method, const St
|
|
484
492
|
curl_easy_setopt(m_curl, CURLOPT_HTTPGET, 1);
|
485
493
|
else if (strcasecmp(method, "POST") == 0)
|
486
494
|
curl_easy_setopt(m_curl, CURLOPT_POST, 1);
|
495
|
+
else
|
496
|
+
curl_easy_setopt(m_curl, CURLOPT_CUSTOMREQUEST, method);
|
497
|
+
|
487
498
|
curl_easy_setopt(m_curl, CURLOPT_URL, strUrl.c_str());
|
488
499
|
|
489
500
|
// Just to enable cookie parser
|
@@ -655,7 +666,7 @@ CURLcode CURLNetRequest::CURLHolder::perform()
|
|
655
666
|
result = msg->data.result;
|
656
667
|
if (result == CURLE_OK && noactivity >= timeout)
|
657
668
|
result = CURLE_OPERATION_TIMEDOUT;
|
658
|
-
if (result == CURLE_OK)
|
669
|
+
if (result == CURLE_OK || result == CURLE_PARTIAL_FILE)
|
659
670
|
RAWTRACE("Operation completed successfully");
|
660
671
|
else
|
661
672
|
RAWLOG_ERROR2("Operation finished with error %d: %s", (int)result, curl_easy_strerror(result));
|
@@ -16,6 +16,8 @@
|
|
16
16
|
#endif
|
17
17
|
#define EAGAIN EWOULDBLOCK
|
18
18
|
|
19
|
+
char *strerror(int errnum ){return "";}
|
20
|
+
|
19
21
|
#endif
|
20
22
|
|
21
23
|
#if defined(OS_WINDOWS) || defined(OS_WINCE)
|
@@ -48,8 +50,12 @@ using namespace rho::common;
|
|
48
50
|
|
49
51
|
IMPLEMENT_LOGCLASS(CHttpServer, "HttpServer");
|
50
52
|
|
51
|
-
|
52
|
-
|
53
|
+
#if defined(OS_WINDOWS) || defined(OS_WINCE)
|
54
|
+
static size_t const FILE_BUF_SIZE = 64*1024;
|
55
|
+
#else
|
56
|
+
static size_t const FILE_BUF_SIZE = 256*1024;
|
57
|
+
#endif
|
58
|
+
|
53
59
|
static bool isid(String const &s)
|
54
60
|
{
|
55
61
|
return s.size() > 2 && s[0] == '{' && s[s.size() - 1] == '}';
|
@@ -154,6 +160,7 @@ static String get_mime_type(String const &path)
|
|
154
160
|
{".torrent", 8, "application/x-bittorrent" },
|
155
161
|
{".wav", 4, "audio/x-wav" },
|
156
162
|
{".mp3", 4, "audio/x-mp3" },
|
163
|
+
{".mp4", 4, "video/mp4" },
|
157
164
|
{".mid", 4, "audio/mid" },
|
158
165
|
{".m3u", 4, "audio/x-mpegurl" },
|
159
166
|
{".ram", 4, "audio/x-pn-realaudio" },
|
@@ -232,22 +239,28 @@ static VALUE create_request_hash(String const &application, String const &model,
|
|
232
239
|
}
|
233
240
|
|
234
241
|
CHttpServer::CHttpServer(int port, String const &root)
|
235
|
-
:m_port(port), verbose(true)
|
242
|
+
:m_active(false), m_port(port), verbose(true)
|
236
243
|
{
|
237
244
|
m_root = CFilePath::normalizePath(root);
|
238
245
|
m_strRhoRoot = m_root.substr(0, m_root.length()-5);
|
239
|
-
m_exit = true;
|
240
246
|
}
|
241
247
|
|
242
248
|
CHttpServer::~CHttpServer()
|
243
249
|
{
|
244
250
|
}
|
245
251
|
|
252
|
+
void CHttpServer::close_listener()
|
253
|
+
{
|
254
|
+
SOCKET l = m_listener;
|
255
|
+
m_listener = INVALID_SOCKET;
|
256
|
+
closesocket(l);
|
257
|
+
}
|
258
|
+
|
246
259
|
void CHttpServer::stop()
|
247
260
|
{
|
248
|
-
|
249
|
-
|
250
|
-
|
261
|
+
m_active = false;
|
262
|
+
RAWTRACE("Close listening socket");
|
263
|
+
close_listener();
|
251
264
|
}
|
252
265
|
|
253
266
|
void CHttpServer::register_uri(String const &uri, CHttpServer::callback_t const &callback)
|
@@ -279,8 +292,7 @@ bool CHttpServer::init()
|
|
279
292
|
{
|
280
293
|
RAWTRACE("Open listening socket...");
|
281
294
|
|
282
|
-
|
283
|
-
closesocket(m_listener);
|
295
|
+
close_listener();
|
284
296
|
m_listener = socket(AF_INET, SOCK_STREAM, 0);
|
285
297
|
if (m_listener == INVALID_SOCKET) {
|
286
298
|
RAWLOG_ERROR1("Can not create listener: %d", RHO_NET_ERROR_CODE);
|
@@ -290,6 +302,7 @@ bool CHttpServer::init()
|
|
290
302
|
int enable = 1;
|
291
303
|
if (setsockopt(m_listener, SOL_SOCKET, SO_REUSEADDR, (const char *)&enable, sizeof(enable)) == SOCKET_ERROR) {
|
292
304
|
RAWLOG_ERROR1("Can not set socket option (SO_REUSEADDR): %d", RHO_NET_ERROR_CODE);
|
305
|
+
close_listener();
|
293
306
|
return false;
|
294
307
|
}
|
295
308
|
|
@@ -300,11 +313,13 @@ bool CHttpServer::init()
|
|
300
313
|
sa.sin_addr.s_addr = INADDR_ANY;
|
301
314
|
if (bind(m_listener, (const sockaddr *)&sa, sizeof(sa)) == SOCKET_ERROR) {
|
302
315
|
RAWLOG_ERROR2("Can not bind to port %d: %d", m_port, RHO_NET_ERROR_CODE);
|
316
|
+
close_listener();
|
303
317
|
return false;
|
304
318
|
}
|
305
319
|
|
306
320
|
if (listen(m_listener, 128) == SOCKET_ERROR) {
|
307
321
|
RAWLOG_ERROR1("Can not listen on socket: %d", RHO_NET_ERROR_CODE);
|
322
|
+
close_listener();
|
308
323
|
return false;
|
309
324
|
}
|
310
325
|
|
@@ -318,17 +333,17 @@ bool CHttpServer::run()
|
|
318
333
|
if (!init())
|
319
334
|
return false;
|
320
335
|
|
321
|
-
|
336
|
+
m_active = true;
|
322
337
|
|
323
338
|
for(;;) {
|
324
339
|
RAWTRACE("Waiting for connections...");
|
325
340
|
rho_ruby_start_threadidle();
|
326
341
|
SOCKET conn = accept(m_listener, NULL, NULL);
|
327
342
|
rho_ruby_stop_threadidle();
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
343
|
+
if (!m_active) {
|
344
|
+
RAWTRACE("Stop HTTP server");
|
345
|
+
return true;
|
346
|
+
}
|
332
347
|
if (conn == INVALID_SOCKET) {
|
333
348
|
#if !defined(OS_WINDOWS) && !defined(OS_WINCE)
|
334
349
|
if (RHO_NET_ERROR_CODE == EINTR)
|
@@ -366,7 +381,7 @@ bool receive_request_test(ByteVector &request, int attempt)
|
|
366
381
|
data += "Host";
|
367
382
|
break;
|
368
383
|
case 3:
|
369
|
-
data += ":
|
384
|
+
data += ": 127.0.0.1\r\n";
|
370
385
|
data += "Content-Length: 4\r\n";
|
371
386
|
break;
|
372
387
|
case 4:
|
@@ -519,7 +534,7 @@ String CHttpServer::create_response(String const &reason, HeaderList const &hdrs
|
|
519
534
|
snprintf(buf, sizeof(buf), "%d", m_port);
|
520
535
|
|
521
536
|
HeaderList headers;
|
522
|
-
headers.push_back(Header("Host", String("
|
537
|
+
headers.push_back(Header("Host", String("127.0.0.1:") + buf));
|
523
538
|
headers.push_back(Header("Connection", "close"));
|
524
539
|
std::copy(hdrs.begin(), hdrs.end(), std::back_inserter(headers));
|
525
540
|
|
@@ -798,7 +813,41 @@ bool CHttpServer::dispatch(String const &uri, Route &route)
|
|
798
813
|
return true;
|
799
814
|
}
|
800
815
|
|
801
|
-
bool
|
816
|
+
static bool parse_range(HttpHeaderList const &hdrs, size_t *pbegin, size_t *pend)
|
817
|
+
{
|
818
|
+
for (HttpHeaderList::const_iterator it = hdrs.begin(), lim = hdrs.end(); it != lim; ++it) {
|
819
|
+
if (strcasecmp(it->name.c_str(), "range") != 0)
|
820
|
+
continue;
|
821
|
+
|
822
|
+
const char *s = strstr(it->value.c_str(), "bytes=");
|
823
|
+
if (!s)
|
824
|
+
continue;
|
825
|
+
|
826
|
+
s += 6; // size of "bytes=" string
|
827
|
+
|
828
|
+
char *e;
|
829
|
+
|
830
|
+
size_t begin = strtoul(s, &e, 10);
|
831
|
+
if (s == e)
|
832
|
+
begin = 0;
|
833
|
+
|
834
|
+
if (*e != '-') // error
|
835
|
+
continue;
|
836
|
+
|
837
|
+
s = e+1;
|
838
|
+
size_t end = strtoul(s, &e, 10);
|
839
|
+
if (s == e)
|
840
|
+
end = (size_t)-1;
|
841
|
+
|
842
|
+
*pbegin = begin;
|
843
|
+
*pend = end;
|
844
|
+
return true;
|
845
|
+
}
|
846
|
+
|
847
|
+
return false;
|
848
|
+
}
|
849
|
+
|
850
|
+
bool CHttpServer::send_file(String const &path, HeaderList const &hdrs)
|
802
851
|
{
|
803
852
|
String fullPath = CFilePath::normalizePath(path);
|
804
853
|
if (String_startsWith(fullPath,"/app/db/db-files") )
|
@@ -834,20 +883,68 @@ bool CHttpServer::send_file(String const &path)
|
|
834
883
|
// Content length
|
835
884
|
char buf[FILE_BUF_SIZE];
|
836
885
|
|
837
|
-
|
838
|
-
|
886
|
+
String start_line;
|
887
|
+
|
888
|
+
size_t file_size = st.st_size;
|
889
|
+
size_t range_begin = 0, range_end = file_size - 1;
|
890
|
+
size_t content_size = file_size;
|
891
|
+
if (parse_range(hdrs, &range_begin, &range_end))
|
892
|
+
{
|
893
|
+
if (range_end >= file_size)
|
894
|
+
range_end = file_size - 1;
|
895
|
+
if (range_begin >= range_end)
|
896
|
+
range_begin = range_end - 1;
|
897
|
+
content_size = range_end - range_begin + 1;
|
898
|
+
|
899
|
+
snprintf(buf, sizeof(buf), "bytes %lu-%lu/%lu", (unsigned long)range_begin,
|
900
|
+
(unsigned long)range_end, (unsigned long)file_size);
|
901
|
+
headers.push_back(Header("Content-Range", buf));
|
902
|
+
|
903
|
+
if (fseek(fp, range_begin, SEEK_SET) == -1) {
|
904
|
+
RAWLOG_ERROR1("Can not seek to specified range start: %lu", (unsigned long)range_begin);
|
905
|
+
fclose(fp);
|
906
|
+
return false;
|
907
|
+
}
|
908
|
+
|
909
|
+
start_line = "206 Partial Content";
|
910
|
+
}
|
911
|
+
else {
|
912
|
+
start_line = "200 OK";
|
913
|
+
}
|
914
|
+
|
915
|
+
|
916
|
+
snprintf(buf, sizeof(buf), "%lu", (unsigned long)content_size);
|
839
917
|
headers.push_back(Header("Content-Length", buf));
|
840
918
|
|
841
919
|
// Send headers
|
842
|
-
if (!send_response(create_response(
|
920
|
+
if (!send_response(create_response(start_line, headers))) {
|
843
921
|
RAWLOG_ERROR1("Can not send headers while sending file %s", path.c_str());
|
844
922
|
fclose(fp);
|
845
923
|
return false;
|
846
924
|
}
|
847
925
|
|
848
926
|
// Send body
|
849
|
-
|
850
|
-
size_t
|
927
|
+
for (size_t start = range_begin; start < range_end + 1;) {
|
928
|
+
size_t need_to_read = range_end - start + 1;
|
929
|
+
if (need_to_read == 0)
|
930
|
+
break;
|
931
|
+
|
932
|
+
if (need_to_read > sizeof(buf))
|
933
|
+
need_to_read = sizeof(buf);
|
934
|
+
size_t n = fread(buf, 1, need_to_read, fp);
|
935
|
+
if (n < 0) {
|
936
|
+
RAWLOG_ERROR2("Can not read part of file (at position %lu): %s", (unsigned long)start, strerror(errno));
|
937
|
+
fclose(fp);
|
938
|
+
return false;
|
939
|
+
}
|
940
|
+
if (n == 0) {
|
941
|
+
RAWLOG_ERROR1("End of file reached, but we expect data (%lu bytes)", (unsigned long)need_to_read);
|
942
|
+
fclose(fp);
|
943
|
+
return false;
|
944
|
+
}
|
945
|
+
|
946
|
+
start += n;
|
947
|
+
|
851
948
|
if (!send_response_body(String(buf, n))) {
|
852
949
|
RAWLOG_ERROR1("Can not send part of data while sending file %s", path.c_str());
|
853
950
|
fclose(fp);
|
@@ -915,8 +1012,11 @@ bool CHttpServer::decide(String const &method, String const &uri, String const &
|
|
915
1012
|
}
|
916
1013
|
|
917
1014
|
RAWTRACE1("Uri %s is index file, call serveIndex", uri.c_str());
|
918
|
-
|
919
|
-
VALUE
|
1015
|
+
|
1016
|
+
VALUE req = create_request_hash(route.application, route.model, route.action, route.id,
|
1017
|
+
method, uri, query, headers, body);
|
1018
|
+
|
1019
|
+
VALUE data = callServeIndex((char *)fullPath.c_str(), req);
|
920
1020
|
String reply(getStringFromValue(data), getStringLenFromValue(data));
|
921
1021
|
rho_ruby_releaseValue(data);
|
922
1022
|
|
@@ -932,7 +1032,7 @@ bool CHttpServer::decide(String const &method, String const &uri, String const &
|
|
932
1032
|
|
933
1033
|
// Try to send requested file
|
934
1034
|
RAWTRACE1("Uri %s should be regular file, trying to send it", uri.c_str());
|
935
|
-
return send_file(uri);
|
1035
|
+
return send_file(uri, headers);
|
936
1036
|
}
|
937
1037
|
|
938
1038
|
} // namespace net
|