1
0
mirror of https://github.com/astaxie/beego.git synced 2025-07-11 14:01:01 +00:00

288 Commits

Author SHA1 Message Date
56d89cc55c Merge pull request #8 from flycash/fix4734-1x
do not reset id to 0
2021-08-20 19:54:42 +08:00
e048377594 do not reset id to 0 2021-08-20 19:53:51 +08:00
34334a52be Merge pull request #7 from flycash/fix4734-1x
Fix 4734: we don't need to reset the id to 0
2021-08-19 21:52:16 +08:00
7cdf96d21a Fix 4734: we don't need to reset the id to 0 2021-08-19 21:49:37 +08:00
fad897346f Merge pull request #4325 from flycash/revert1
Revert "Merge pull request #4254 from astaxie/develop-2.0"
2020-11-26 20:18:35 +08:00
650fde66aa Revert "Merge pull request #4254 from astaxie/develop-2.0"
This reverts commit e284b0ddae, reversing
changes made to 8ef8fd2606.
2020-11-26 17:48:29 +08:00
e284b0ddae Merge pull request #4254 from astaxie/develop-2.0
Prepare Release v2.0.0-beta
2020-11-07 21:20:18 +08:00
20a0de6bd0 Merge pull request #4290 from flycash/develop-2.0
fix init error of global instance
2020-11-05 23:51:52 +08:00
b4396c97bb fix init error of global instance 2020-11-05 22:00:43 +08:00
471ebba64d Merge pull request #4281 from flycash/httplibTest
Add test for httplib
2020-10-27 22:08:35 +08:00
d07a1eaa8e Add test for httplib 2020-10-27 21:58:39 +08:00
9524036aab Merge pull request #4278 from flycash/defaultCfg
Add global instance for config module
2020-10-24 22:27:12 +08:00
45260e4119 Add global instance for config module 2020-10-24 22:13:15 +08:00
02234dc503 Merge pull request #4277 from flycash/session
support using json string to init session
2020-10-22 09:53:55 +08:00
05f4e0c146 support using json string to init session 2020-10-21 22:24:53 +08:00
ae108ec826 Merge pull request #4276 from flycash/newHttpServer
Change NewHttpServer API
2020-10-21 21:59:45 +08:00
7c61eb058f Change NewHttpServer API 2020-10-21 20:54:33 +08:00
03ba495b7f Merge pull request #4275 from flycash/fix-4224
add MaxUploadFile to provide more safety uploading controll
2020-10-21 10:04:32 +08:00
d26683799a add MaxUploadFile to provide more safety uploading controll 2020-10-20 23:36:34 +08:00
f9075e8274 Merge pull request #4272 from jianzhiyao/fix-4224
fix 4224:form entity too large casue run out of memory
2020-10-20 20:53:19 +08:00
022ad862ac Merge pull request #4274 from flycash/loadCfg
Fix ini Unmarshall method
2020-10-19 21:51:37 +08:00
93bdf97068 Fix ini Unmarshall method 2020-10-19 21:04:57 +08:00
3c48719999 complete condition 2020-10-19 00:22:55 +08:00
cbb3de741d fix application/x-www-form-urlencoded request body oversize 2020-10-18 23:38:08 +08:00
c510926cb8 fix 4224:form entity too large casue run out of memory 2020-10-18 23:18:13 +08:00
140a4b90a3 Merge pull request #4266 from flycash/loadCfg
Using unmarshaler to parse config in web module
2020-10-14 22:26:12 +08:00
c07acaebbc Support unmarshaler 2020-10-14 22:20:25 +08:00
105b874477 Merge pull request #4265 from flycash/rft/configCtx
Upgrade toml version
2020-10-14 00:28:30 +08:00
3fc21ae6ec Upgrade toml version 2020-10-14 00:25:31 +08:00
ccf873fa8b Merge pull request #4264 from flycash/rft/configCtx
remove config API's context parameter
2020-10-13 22:52:46 +08:00
2572094a8d remove config API's context parameter 2020-10-13 22:33:39 +08:00
568626cd57 Merge pull request #4262 from flycash/ftr/toml
Support toml config
2020-10-12 22:55:55 +08:00
34d6a733e9 Support toml config 2020-10-11 23:26:48 +08:00
e44f16c672 Merge pull request #4257 from flycash/fix/adapter
Remove scripts directory & update readme
2020-10-09 08:48:08 +08:00
d41abdb5e4 Remove scripts directory; update readme 2020-10-08 23:18:10 +08:00
f1358cf78d Merge pull request #4255 from flycash/fix/adapter
Reorganize packages
2020-10-08 18:37:42 +08:00
14c1b76569 remove pkg directory;
remove build directory;
remove githook directory;
2020-10-08 18:29:36 +08:00
2708916f96 Merge pull request #4252 from flycash/fix/adapter
Reset func call depth & add adapter.sh
2020-10-06 18:33:45 +08:00
034cb3222e Add adapter script which is used to replace v1 package with v2 adapter package 2020-10-06 16:43:16 +08:00
66804324f2 Fix: Set func call depth as 3 2020-10-06 11:52:24 +08:00
dc65055cf6 Merge pull request #4250 from flycash/adt/logs
logs Adapter
2020-10-05 23:26:55 +08:00
8cc74652a2 Fix: adapter's controller must implement ControllerInterface 2020-10-05 23:00:20 +08:00
6aa6c55f07 logs Adapter 2020-10-05 21:55:26 +08:00
ff762b561c Merge pull request #4249 from flycash/rft/moveSession
move core/session to web/session
2020-10-05 19:45:38 +08:00
d8e8f41230 move core/session to web/session 2020-10-05 19:04:57 +08:00
9e6b8fcf34 Merge pull request #4248 from flycash/rft/renameInfra
rename infrastructure to core
2020-10-05 18:40:20 +08:00
48e98482f7 rename infrastructure to core 2020-10-05 18:14:01 +08:00
ff7a8b966b Merge pull request #4247 from flycash/adt/cache
Adapter: cache API
2020-10-05 14:46:13 +08:00
f9bef68aa9 Adapter: cache API 2020-10-05 14:35:12 +08:00
484beb8bad Merge pull request #4245 from flycash/ftr/cache-ctx
Add context to cache API
2020-10-05 14:25:09 +08:00
43560dede4 Merge pull request #4246 from jianzhiyao/frt/seperate_orm_alone
seperate orm alone & deadlock in task module
2020-10-05 14:24:51 +08:00
c435d231ab complete check 2020-10-05 10:38:14 +08:00
b838683731 add api for testing 2020-10-05 10:33:23 +08:00
70cca5e298 make code testable in task module 2020-10-05 10:13:29 +08:00
f1cca45d8d fix deadlock about changed sign 2020-10-05 01:31:27 +08:00
4dc694411f fix deadlock in task module 2020-10-05 00:16:58 +08:00
3364c609de Add context to cache API 2020-10-04 23:12:29 +08:00
c5d43e87fe seperate orm alone 2020-10-04 22:16:19 +08:00
b89d9511ab Merge pull request #4237 from flycash/rft/cache-decup
Decouple web module from cache module
2020-10-04 19:01:31 +08:00
325a0821c1 Merge pull request #4239 from flycash/rft/httplib
decouple httplib module from web module and config module
2020-09-29 22:22:27 +08:00
dd3f1ce9be decouple httplib from config 2020-09-27 00:44:02 +08:00
463e96447a decouple httplib from web module 2020-09-27 00:37:46 +08:00
03498529b9 Decouple web module from cache module 2020-09-22 22:58:58 +08:00
9a7c43c404 Merge pull request #4235 from flycash/ftr/adminCommand
decouple web module and task module
2020-09-21 22:50:08 +08:00
44127edefc design Command for governor module & decouple web module from task module 2020-09-20 14:52:29 +00:00
089006525e Merge pull request #4234 from flycash/ftr/multi-sever
Multi server support
2020-09-20 22:44:32 +08:00
2846043f2a Fix UT 2020-09-20 14:27:30 +00:00
e6a257f987 Fix BUG 2020-09-20 12:02:28 +00:00
2473e69417 Rewrite admin service by using multiple server feature 2020-09-20 15:36:53 +08:00
d455805a0a Multiple server refactor 2020-09-20 15:36:53 +08:00
bd1cfefec7 rft: Move build info to pkg 2020-09-20 15:36:53 +08:00
7effdb0e7d Merge pull request #4233 from flycash/esIndexName
Add IndexNaming interface
2020-09-20 14:22:32 +08:00
b027968c0b Merge pull request #4231 from flycash/ut/log
Add tests for log module
2020-09-20 13:50:22 +08:00
961f300c14 Fix JL tests 2020-09-20 13:15:48 +08:00
7570abd310 Merge pull request #4232 from flycash/stale-workflows
Add stale.yml
2020-09-19 23:57:40 +08:00
7c8136710c Add stale.yml 2020-09-19 23:54:33 +08:00
a3ece98cec Add IndexNaming interface so users can custom the index name when they use es as the logger 2020-09-19 23:49:52 +08:00
a31dce6216 Merge pull request #4230 from jianzhiyao/frt/movement_for_4198
movement for 4198
2020-09-19 23:24:57 +08:00
a1782cc22d Add tests for log module 2020-09-19 23:14:17 +08:00
67f64afa85 movement for 4198 2020-09-19 21:45:37 +08:00
2539fe3831 Merge pull request #4229 from wangle201210/develop-2.0
Provides a quick format method by PatternLogFormatter struct
2020-09-19 21:25:12 +08:00
05c125ec2d change to pointer receiver 2020-09-19 20:18:09 +08:00
6e638ef6c8 Provides a quick format method by PatternLogFormatter struct 2020-09-19 18:28:53 +08:00
df043f22fc Merge pull request #4225 from HITWHTigerLiu/develop-2.0
Empty field in validator.Error when label struct tag is not declared #4222
2020-09-17 21:27:18 +08:00
fbaf3380c6 Merge pull request #4203 from jianzhiyao/frt/proposal_4105
warpping for global modelCache
2020-09-17 21:11:33 +08:00
b7bc57c4d1 delete interface 2020-09-16 19:46:14 +08:00
32cdda96bd Merge pull request #4205 from AllenX2018/postgres-query-builder
PostgresQueryBuilder
2020-09-14 21:21:59 +08:00
5995b00fa2 Merge branch 'develop-2.0' into frt/proposal_4105 2020-09-14 19:16:09 +08:00
5618df8c76 Empty field in validator.Error when label struct tag is not declared #4222 2020-09-14 16:18:24 +08:00
c6c9ad46f9 PostgresQueryBuilder 2020-09-14 09:50:28 +08:00
5973ef107c Merge pull request #4221 from flycash/ftr/log_format
fix 4219
2020-09-12 00:02:51 +08:00
b575fa1ebe fix 4219 2020-09-11 23:48:45 +08:00
6bbca96c6c Merge pull request #4220 from flycash/ftr/log_format
refactor log module
2020-09-11 22:08:05 +08:00
63cd8e4e15 refactor log module 2020-09-11 21:47:22 +08:00
93736a8e66 Merge pull request #4216 from flycash/ftr/log_format
Log format support
2020-09-11 00:11:27 +08:00
654d87b210 Merge log_format 2020-09-10 23:31:49 +08:00
0048b7d158 Merge pull request #4188 from IamCathal/custom-log-formatter-third-pr
Custom logging format PR#3
2020-09-10 22:40:48 +08:00
00e44952ff optimize modelCache 2020-09-09 19:04:34 +08:00
8982f5d702 Add unit tests for custom log formatter
Also moved is Colorful check to WriteMsg function to make the interface for user's using the custom logging formatting simpler. The user does not have to check if the text is colorful now, the WriteMsg function handles it.
2020-09-09 00:23:57 +01:00
6612bc4c2a Merge pull request #4214 from flycash/rft/dbOption
Optimize orm by using BDOption rather than hints
2020-09-09 00:06:44 +08:00
f580a714d5 Optimize orm by using BDOption rather than hints 2020-09-08 21:44:14 +08:00
9ccd58bfff Merge pull request #4211 from flycash/adt/all
allow users to ignore some table when run orm commands
2020-09-07 21:52:39 +08:00
0f50b07a20 allow users to ignore some table when run orm commands 2020-09-07 21:40:44 +08:00
b86cf22fc4 Merge pull request #4210 from flycash/adt/all
Move pr 3784
2020-09-07 20:53:45 +08:00
6bf01eaeca Move pr 3784 here 2020-09-07 20:37:05 +08:00
8e015deee5 Merge pull request #4208 from flycash/adt/all
Adapter: all module
2020-09-06 19:58:46 +08:00
3acda41bc7 Fix UT 2020-09-06 10:39:20 +00:00
5b3dd7e50f Adapter: orm 2020-09-06 13:33:52 +08:00
f4a43814be Adapter: utils 2020-09-05 18:07:42 +08:00
35f1bd2119 Adapter: testing 2020-09-05 16:58:49 +08:00
f6c95ad534 Adapter: swagger module 2020-09-05 16:56:56 +08:00
f1950482c2 Adapter: plugin 2020-09-05 16:54:22 +08:00
1dae2c9eb3 Adapter: web module 2020-09-05 16:24:19 +08:00
8ef9965eef Adapter: session module 2020-09-03 23:37:07 +08:00
3530457ff9 Adapter: toolbox module 2020-09-03 21:34:57 +08:00
cbd51616f1 adapter: validation module 2020-09-02 23:23:48 +08:00
bdd8df6751 adapt migration 2020-09-02 21:01:54 +08:00
8fc4f8847c adapt grace and metric 2020-09-02 20:43:35 +08:00
3bf5cde38c adapt context 2020-09-02 20:36:53 +08:00
7a53baaf9b rename modelRegister to modelCacheHandler 2020-09-02 00:33:46 +08:00
7574b91760 add type modelRegister interface into Ormer 2020-09-02 00:26:25 +08:00
78d91062c9 Adapt new API to old API: httplib 2020-09-01 22:16:49 +08:00
23792401b5 Merge pull request #4201 from jianzhiyao/frt/proposal_4105
WIP:supports for proposal 4105
2020-09-01 22:05:15 +08:00
e54dbabf0b movement for global modelCache 2020-09-01 21:56:48 +08:00
cdc8110ea4 Merge pull request #4202 from flycash/adt/config
Using new API to adapt to old API
2020-09-01 21:50:08 +08:00
185d55eb46 adapt config 2020-09-01 21:29:26 +08:00
8e879726fe Merge pull request #4200 from flycash/ftr/config-sub
Implement Sub, Unmarshaler and OnChange methods for yaml, json, xml
2020-08-31 22:29:14 +08:00
33b052bc7a support json 2020-08-31 14:15:01 +00:00
087399c44a support xml 2020-08-31 13:57:26 +00:00
f4f200cf04 enhance yaml 2020-08-31 13:02:38 +00:00
0a58428220 Merge pull request #4199 from flycash/rft/task-api
Add ctx to Task module API
2020-08-31 19:43:53 +08:00
c0462f75bf Add ctx to Task module API 2020-08-30 16:18:59 +00:00
5cf33f2655 Merge pull request #4197 from flycash/rft/session-api
Add ctx to session API
2020-08-31 00:14:52 +08:00
670064686e Add ctx to session API 2020-08-30 15:39:07 +00:00
0019e0fc1b Merge pull request #4195 from flycash/ftr/etcd
Add contect as first parameter for all config method
2020-08-30 00:42:15 +08:00
03bec05714 Add contect as first parameter for all config method 2020-08-29 16:25:20 +00:00
e831b97eb8 Merge pull request #4194 from flycash/ftr/etcd
Support etcd
2020-08-29 22:44:55 +08:00
81b9a1382a Fix UT 2020-08-29 14:27:06 +00:00
0189e6329a Add global logging override 2020-08-28 18:47:28 +01:00
6684924e99 empty commit to restart CI again 2020-08-28 18:30:41 +01:00
e0a934af1d empty commit to restart CI 2020-08-28 18:24:57 +01:00
8178f035a0 Custom formatting opts implementation 2020-08-28 18:18:28 +01:00
2b39ff7837 New opts formatter working for console 2020-08-28 18:00:45 +01:00
c2361170b3 Support etcd 2020-08-29 00:07:33 +08:00
5b35bf6065 Merge pull request #4192 from AllenX2018/supplement-datetimePrecision-UT
supplement datetime precision UT
2020-08-26 19:52:19 +08:00
14c911e9d7 Merge pull request #4190 from flycash/ftr/time-precision
Support precision
2020-08-26 12:45:17 +08:00
9472cba6c9 Fix UT 2020-08-26 04:16:09 +00:00
b83094ac1e supplement datetime precision UT 2020-08-26 11:51:05 +08:00
1cb0ff560d Support precision 2020-08-25 13:07:21 +00:00
cceecad8c2 Merge pull request #4186 from AllenX2018/Feature-datetime-precision
Feature: implement the time precison for time.Time type
2020-08-25 21:05:08 +08:00
d24f861629 empty commit to restart CI 2020-08-24 21:00:58 +01:00
c2471b22ad Remove ineffectual assignments
Removed 3 lines due to warning from test suite saying these lines had innefectual assignments
2020-08-24 20:54:55 +01:00
c5970766a3 Add init to es.go 2020-08-24 20:41:39 +01:00
48a98ec1a5 Fix init for alils.go 2020-08-24 20:39:53 +01:00
ed1d2c7f6e Add custom logging format functionality and global formatter functionality 2020-08-24 20:22:38 +01:00
7a94996e22 Feature: implement the time precison for time.Time type 2020-08-24 20:23:54 +08:00
597c55d547 Merge pull request #4183 from flycash/rft/module-2
Reorganize package
2020-08-23 21:43:48 +08:00
026e8bc55a Merge branch 'develop-2.0' of https://github.com/astaxie/beego into rft/module-2 2020-08-23 21:25:15 +08:00
581e48679e Merge pull request #4173 from AllenX2018/fix-bug-queryRow
Fix issue 3866
2020-08-23 21:04:34 +08:00
09afe0ae8e Merge pull request #4179 from IamCathal/custom-log-formatter-secondpr
Custom log formatter secondpr
2020-08-22 21:36:50 +08:00
08e49ca323 Test empty commit 2020-08-20 19:32:42 +01:00
e1da804b2b Add format func to alils 2020-08-20 19:20:30 +01:00
705e091593 Add format call before logging 2020-08-20 19:06:51 +01:00
6bdedff457 LogFormatter Implementation 2020-08-20 19:00:35 +01:00
f3be6dd2e9 Merge pull request #4173 from AllenX2018/fix-bug-queryRow
Fix issue 3866
2020-08-20 22:25:37 +08:00
9fe353dd0b Fix issue 3886 2020-08-20 10:00:49 +08:00
9003ca3eef Merge pull request #4174 from IamCathal/custom-log-formatter-firstpr
Custom Log Formatter PR#1
2020-08-19 23:37:44 +08:00
ff5ac3adf4 Update signature of WriteMsg in es.go 2020-08-19 16:20:19 +01:00
ca4a217783 Merge branch 'develop-2.0' into custom-log-formatter-firstpr 2020-08-19 16:05:42 +01:00
e6ea307549 Merge pull request #4175 from flycash/ftr/config
Add more methods to Configer
2020-08-19 22:44:43 +08:00
2c16c7b917 Add more methods to Configer 2020-08-19 22:09:05 +08:00
77ddc3338f Fix file path logging for enableFullFilePath 2020-08-19 15:07:46 +01:00
ac3a549187 Fix test with new parameters 2020-08-19 14:21:29 +01:00
fe56de06b5 Add enableFullFilePath field to BeeLogger 2020-08-18 21:30:39 +01:00
6c002a3124 Update WriteMsg signatures for custom log formatting update 2020-08-18 21:30:11 +01:00
cead72c6df Merge pull request #4170 from flycash/rft/ormFilter
Refactor orm filter
2020-08-18 22:46:45 +08:00
7fe4eaef50 Refactor orm filter 2020-08-18 14:31:06 +00:00
63599c0032 Merge pull request #4168 from flycash/ftr/layout
Add git hooks
2020-08-18 21:08:56 +08:00
4db256c9fb Add git hooks 2020-08-18 20:56:15 +08:00
c548764c8e Merge pull request #4163 from flycash/ftr/rmFiles
Remove files
2020-08-16 23:17:05 +08:00
b4a85c8f13 Remove files 2020-08-16 23:09:19 +08:00
94f476fa39 Merge pull request #4158 from jianzhiyao/frt/fix_spk_upsert
fix:return error when calling ``InsertOrUpdate`` is successful with string primary key
2020-08-16 21:21:25 +08:00
8574e30b3a Merge pull request #4160 from AllenX2018/Improve-orm.Fielder-function
fix issue #3776
2020-08-14 22:20:07 +08:00
7442919f5a fix issue #3776 2020-08-14 17:11:52 +08:00
f6ec4efc70 Merge pull request #4156 from flycash/ftr/bean
Supporting default value by using filter
2020-08-14 15:47:50 +08:00
7b899aa9af add ErrLastInsertIdUnavailable 2020-08-14 15:09:47 +08:00
f73eee75ff Merge develop-2.0 2020-08-14 14:34:59 +08:00
739b8bab0c fix UT 2020-08-14 10:31:08 +08:00
139c393f08 add const ErrLastInsertIdUnavailable 2020-08-14 09:59:11 +08:00
bdec93986b Bean: Support autowire by tag
Orm: Support default value filter
2020-08-13 21:26:39 +08:00
7ce0fde171 fix:return error when calling `InsertOrUpdate` is successful with string primary key 2020-08-13 19:14:00 +08:00
d6a2621b3c Merge pull request #4137 from phiphi282/change_redis_provider
Add additional options to redis session prov
2020-08-12 13:38:44 +08:00
813a4df3c5 Make sure expiry time is in seconds 2020-08-11 16:21:43 +02:00
7267f5e573 Add new config option into provider struct 2020-08-11 16:09:29 +02:00
5bc8d90d7f Merge pull request #4150 from jianzhiyao/frt/fix_3830
fix:return error after inserting data when primary key is string
2020-08-11 21:22:17 +08:00
2d1c02e1c1 Merge branch 'develop-2.0' of https://github.com/astaxie/beego into frt/fix_3830
# Conflicts:
#	pkg/orm/orm_test.go
2020-08-11 17:37:24 +08:00
9ca9535c48 fix:return error after inserting data when primary key is string 2020-08-11 16:53:31 +08:00
d1d9df74c7 Merge branch 'develop-2.0' of github.com:astaxie/beego into change_redis_provider 2020-08-11 10:47:06 +02:00
d326d74c34 Merge pull request #4148 from flycash/fix/end2end
Fix prometheus and opentracing bug found in end2end tests
2020-08-11 16:33:54 +08:00
82178a487b Merge develop-2.0 and resolve conflict 2020-08-11 08:16:04 +00:00
a1b7fd3c93 Merge pull request #4147 from jianzhiyao/frt/specify_index_2
specify index
2020-08-11 16:13:13 +08:00
0813471202 Merge branch 'develop-2.0' of github.com:astaxie/beego into change_redis_provider 2020-08-11 09:52:53 +02:00
ce698aacf6 rm some methods 2020-08-11 12:06:02 +08:00
c22af4c611 Fix Tracing and prometheus bug 2020-08-11 03:23:38 +00:00
f8c0e6fec5 fix UT 2020-08-11 00:06:36 +08:00
882f1273c8 add UT for specifying indexes 2020-08-10 23:27:03 +08:00
5a1fa4e1ec specify index 2020-08-10 18:46:16 +08:00
d05460237c Merge pull request #4145 from flycash/ftr/ormTracing
Support prometheus and opentracing for ORM and httplib module
2020-08-10 13:53:23 +08:00
75107f735e Support opentracing filter 2020-08-09 14:59:41 +00:00
2e891152dd deprecated httplib and then support prometheus for httplib 2020-08-09 14:59:41 +00:00
dec98f004c Support opentracing filter for Orm 2020-08-09 14:59:41 +00:00
26b016a3a4 Merge pull request #4143 from flycash/fix/moveIni
Move init so it will be default implementation of config
2020-08-09 22:51:47 +08:00
19aae0b7e1 Merge pull request #4107 from AllenX2018/fix-comment-router-issue
add comment router path configuration
2020-08-09 19:23:05 +08:00
2e192e1ed0 Depracated config module and recommend using pkg/config 2020-08-08 13:26:30 +00:00
f9a3eae9d5 Move init so it will be default implementation of config 2020-08-08 13:17:49 +00:00
7fc1e4de96 Merge pull request #4141 from flycash/ftr/ormInterceptor
Orm filter support
2020-08-08 20:52:37 +08:00
993ccac2bd fix comment router generate issue 2020-08-08 16:17:12 +08:00
2fd65a469c Support prometheus 2020-08-07 14:14:07 +00:00
a2fa073072 Merge pull request #4139 from IamCathal/coc-grammar-fixes
More minor grammar fixes
2020-08-07 22:00:22 +08:00
08cec9178f Orm filter support 2020-08-07 13:45:24 +00:00
63b3fc4a99 Fix retry amount comment 2020-08-06 16:09:06 +01:00
1b4bb43df0 More minor grammar fixes 2020-08-06 16:07:18 +01:00
ec55edfbc4 Add additional options to redis session prov
Adding option for frequency of checking timed out connections as well as
an option to specify retries.

These changes make redis provider more stable since connection problems
are becoming fewer.

Since redigo does not have this options and since redis_sentinel and
redis_cluster are using go-redis as a client, this commit changes from
redigo to go-redis for redis session provider.

Added tests for redis session provider as well.
2020-08-06 11:14:36 +02:00
2fce8f9d1b Merge pull request #4124 from phiphi282/session_exists_return_err
Update session provider interface to return errors on SessionExist
2020-08-06 09:17:49 +08:00
15489fa76a Merge pull request #4135 from IamCathal/grammar-fixes
Minor grammar fixes
2020-08-06 09:05:30 +08:00
e7d8bab5d9 Improved definition of DefaultEvery 2020-08-05 17:56:11 +01:00
2f5683610f Minor grammar fixes 2020-08-05 17:50:05 +01:00
5c8c088684 Revert "Change interface in session README"
This reverts commit 6f5c5bd3a6.
2020-08-05 18:33:17 +02:00
009074725e Move interface change to pkg/session/README.md 2020-08-05 18:32:33 +02:00
ce50ca22d7 Merge branch 'develop-2.0' of github.com:astaxie/beego into session_exists_return_err 2020-08-05 18:30:19 +02:00
3052c64b6c Revert "Add error to SessionExist interface"
This reverts commit 28e6b3b924.
2020-08-05 18:29:47 +02:00
5f2f6e4f86 Add interface change in pkg folder 2020-08-05 18:29:22 +02:00
3382a5baa1 Merge pull request #4134 from flycash/ftr/ormInterceptor
Deprecated old web module
2020-08-05 22:22:59 +08:00
882aa9b967 Deprecated old web module 2020-08-05 21:57:20 +08:00
02972d8702 Merge pull request #4130 from flycash/ftr/prometheuseAndOpentracing
Support prometheus and opentracing by using FilterChainFunc
2020-08-05 15:46:03 +08:00
261b704d8b Fix UT 2020-08-05 07:25:34 +00:00
6c6cf91741 Support prometheus and opentracing filter 2020-08-04 23:15:42 +08:00
ae8461f95d Merge pull request #4125 from flycash/ftr/middleware
Support FilterChain
2020-08-04 23:06:18 +08:00
aa3987f816 Merge remote-tracking branch 'origin/develop' into ftr/middleware 2020-08-04 22:26:01 +08:00
3dc5ec1060 Merge pull request #4129 from astaxie/revert-4128-fix-ci-fail
Revert "fix CI fail for connection log test"
2020-08-04 21:38:50 +08:00
1961c1e441 Revert "fix CI fail for connection log test" 2020-08-04 21:37:46 +08:00
787bb60b42 Merge pull request #4128 from AllenX2018/fix-ci-fail
fix CI fail for connection log test
2020-08-04 21:14:45 +08:00
12b984861d fix CI fail for connection log test 2020-08-04 20:32:07 +08:00
79ffef90e3 support filter chain 2020-08-04 07:26:51 +00:00
6f5c5bd3a6 Change interface in session README 2020-08-03 13:33:30 +02:00
28e6b3b924 Add error to SessionExist interface
Implement changed interface for all default providers as well and change
tests accordingly
2020-08-03 13:31:49 +02:00
9e1346ef4d Merge pull request #4113 from flycash/ftr/usingPkg
using pkg module
2020-07-31 13:40:39 +08:00
9f295067b7 Resolve conflict 2020-07-30 22:44:44 +08:00
71776e4bef Merge pull request #4114 from wangle201210/develop-2.0
Add the operator(>,>=,<,<=,=,!=) of orm
2020-07-30 16:51:02 +08:00
d4074b5004 Merge pull request #4103 from flycash/ftr/newOrmWithDB
Enhance: NewOrmUsingDB & remove useless methods
2020-07-30 11:43:47 +08:00
22b8cae73b Add the operator(>,>=,<,<=,=,!=) of orm
eg:
qs.Filter("counts__>=","20")
qs.Filter("counts__!=","20")
2020-07-29 23:23:02 +08:00
aa06a10493 uing pkg module 2020-07-29 14:42:27 +00:00
9b58c2836c Merge develop-2.0 and resolve confilct 2020-07-29 22:26:29 +08:00
7312197732 Merge pull request #4098 from jianzhiyao/frt/stmt_config
make stmt cache size configurable & wrap kv
2020-07-29 20:57:07 +08:00
e87de70c6d adapt wrapping kv 2020-07-29 00:45:41 +08:00
4304b40a82 Merge branch 'frt/wrap_kv' into frt/stmt_config
# Conflicts:
#	pkg/orm/constant.go
#	pkg/orm/db_alias.go
2020-07-28 18:32:24 +08:00
e8facd28f5 wrap kv 2020-07-28 17:37:36 +08:00
54ef476600 add tag interfaces and remove log.go 2020-07-28 06:28:51 +00:00
756df9385f make stmt cache size configurable 2020-07-28 12:57:19 +08:00
21f281655d remove QueryRelated and QueryRelatedCtx 2020-07-27 21:22:40 +08:00
2e7fb81348 deprecated orm.go and add NewOrmUsingDB method 2020-07-27 21:19:34 +08:00
ebc0207909 Merge pull request #4096 from jianzhiyao/request_context
fix memory leak of request context
2020-07-27 18:04:37 +08:00
2386c9c80d delete useless if-stmt 2020-07-26 22:37:42 +08:00
b9f9fcca5f Merge pull request #4099 from jianzhiyao/fix_3869
orm.rawPrepare support FlatParams
2020-07-26 21:01:39 +08:00
16d71893cd orm.rawPrepare support FlatParams 2020-07-26 19:40:13 +08:00
cfff0f3b46 fix memory leak of request context 2020-07-25 00:00:34 +08:00
93eb7c6b83 Merge pull request #4091 from flycash/ftr/moveToPkg
Ftr: move to pkg
2020-07-23 09:36:29 +08:00
79c2157ad4 Fix UT 2020-07-22 15:46:29 +00:00
30eb889a91 Format code 2020-07-22 23:00:06 +08:00
9c51952db4 Move package 2020-07-22 22:55:59 +08:00
16b66509f6 Merge pull request #4083 from IamCathal/content-length
Add Content-length field for logging
2020-07-21 15:47:58 +08:00
d5695060c5 Merge pull request #4082 from flycash/ftr/newOrm
Refactor RegisterDatabase
2020-07-21 15:47:40 +08:00
af2143f8fb Merge pull request #4084 from astaxie/develop
Align develop-2.0
2020-07-21 09:36:54 +08:00
a66b9950e7 Add Content-length field for logging 2020-07-20 21:23:21 +01:00
44460bc457 Refactor RegisterDatabase 2020-07-20 15:52:40 +00:00
41feb3a711 Merge pull request #4078 from jianzhiyao/frt/orm_merge
refactor orm
2020-07-20 23:50:40 +08:00
b6f7d30f9f fix unit test 2020-07-20 19:10:57 +08:00
4aad313de7 do not judge tx status in txOrm 2020-07-20 17:34:58 +08:00
aefe21b63a complete error log 2020-07-20 17:25:27 +08:00
32da446eb1 refactor orm 2020-07-19 23:46:42 +08:00
d9c016ed98 Merge pull request #4076 from flycash/ftr/taskLog
Store nearest error info
2020-07-19 23:23:13 +08:00
7258ef113a Store nearest error info 2020-07-19 14:34:57 +00:00
d6779c4a90 Merge pull request #4075 from flycash/fix/stable-ut
Fix orm test when using Driver = mysql
2020-07-19 21:22:36 +08:00
192a278a2a Fix orm test when using Driver = mysql 2020-07-19 12:56:58 +00:00
9d936c58bf Merge pull request #4070 from flycash/develop-2.0
Move orm to pkg/orm
2020-07-15 10:50:05 +08:00
ffe1d52120 Move orm to pkg/orm 2020-07-15 10:05:11 +08:00
8ef8fd2606 Merge pull request #4036 from astaxie/develop
V1.12.2
2020-06-30 23:25:29 +08:00
0cd80525e7 Merge branch 'develop' 2020-02-07 16:25:41 +08:00
59 changed files with 172 additions and 1089 deletions

View File

@ -8,15 +8,6 @@ It is inspired by Tornado, Sinatra and Flask. beego has some Go-specific feature
## Quick Start
#### Create `hello` directory, cd `hello` directory
mkdir hello
cd hello
#### Init module
go mod init
#### Download and install
go get github.com/astaxie/beego

View File

@ -21,7 +21,6 @@ import (
"net/http"
"os"
"reflect"
"strconv"
"text/template"
"time"
@ -72,7 +71,7 @@ func init() {
// AdminIndex is the default http.Handler for admin module.
// it matches url pattern "/".
func adminIndex(rw http.ResponseWriter, _ *http.Request) {
writeTemplate(rw, map[interface{}]interface{}{}, indexTpl, defaultScriptsTpl)
execTpl(rw, map[interface{}]interface{}{}, indexTpl, defaultScriptsTpl)
}
// QpsIndex is the http.Handler for writing qps statistics map result info in http.ResponseWriter.
@ -92,7 +91,7 @@ func qpsIndex(rw http.ResponseWriter, _ *http.Request) {
}
}
writeTemplate(rw, data, qpsTpl, defaultScriptsTpl)
execTpl(rw, data, qpsTpl, defaultScriptsTpl)
}
// ListConf is the http.Handler of displaying all beego configuration values as key/value pair.
@ -129,7 +128,7 @@ func listConf(rw http.ResponseWriter, r *http.Request) {
}
data["Content"] = content
data["Title"] = "Routers"
writeTemplate(rw, data, routerAndFilterTpl, defaultScriptsTpl)
execTpl(rw, data, routerAndFilterTpl, defaultScriptsTpl)
case "filter":
var (
content = M{
@ -172,7 +171,7 @@ func listConf(rw http.ResponseWriter, r *http.Request) {
data["Content"] = content
data["Title"] = "Filters"
writeTemplate(rw, data, routerAndFilterTpl, defaultScriptsTpl)
execTpl(rw, data, routerAndFilterTpl, defaultScriptsTpl)
default:
rw.Write([]byte("command not support"))
}
@ -280,7 +279,9 @@ func profIndex(rw http.ResponseWriter, r *http.Request) {
http.Error(rw, err.Error(), http.StatusInternalServerError)
return
}
writeJSON(rw, dataJSON)
rw.Header().Set("Content-Type", "application/json")
rw.Write(dataJSON)
return
}
@ -289,12 +290,12 @@ func profIndex(rw http.ResponseWriter, r *http.Request) {
if command == "gc summary" {
defaultTpl = gcAjaxTpl
}
writeTemplate(rw, data, profillingTpl, defaultTpl)
execTpl(rw, data, profillingTpl, defaultTpl)
}
// Healthcheck is a http.Handler calling health checking and showing the result.
// it's in "/healthcheck" pattern in admin module.
func healthcheck(rw http.ResponseWriter, r *http.Request) {
func healthcheck(rw http.ResponseWriter, _ *http.Request) {
var (
result []string
data = make(map[interface{}]interface{})
@ -321,49 +322,10 @@ func healthcheck(rw http.ResponseWriter, r *http.Request) {
*resultList = append(*resultList, result)
}
queryParams := r.URL.Query()
jsonFlag := queryParams.Get("json")
shouldReturnJSON, _ := strconv.ParseBool(jsonFlag)
if shouldReturnJSON {
response := buildHealthCheckResponseList(resultList)
jsonResponse, err := json.Marshal(response)
if err != nil {
http.Error(rw, err.Error(), http.StatusInternalServerError)
} else {
writeJSON(rw, jsonResponse)
}
return
}
content["Data"] = resultList
data["Content"] = content
data["Title"] = "Health Check"
writeTemplate(rw, data, healthCheckTpl, defaultScriptsTpl)
}
func buildHealthCheckResponseList(healthCheckResults *[][]string) []map[string]interface{} {
response := make([]map[string]interface{}, len(*healthCheckResults))
for i, healthCheckResult := range *healthCheckResults {
currentResultMap := make(map[string]interface{})
currentResultMap["name"] = healthCheckResult[0]
currentResultMap["message"] = healthCheckResult[1]
currentResultMap["status"] = healthCheckResult[2]
response[i] = currentResultMap
}
return response
}
func writeJSON(rw http.ResponseWriter, jsonData []byte) {
rw.Header().Set("Content-Type", "application/json")
rw.Write(jsonData)
execTpl(rw, data, healthCheckTpl, defaultScriptsTpl)
}
// TaskStatus is a http.Handler with running task status (task name, status and the last execution).
@ -409,10 +371,10 @@ func taskStatus(rw http.ResponseWriter, req *http.Request) {
content["Data"] = resultList
data["Content"] = content
data["Title"] = "Tasks"
writeTemplate(rw, data, tasksTpl, defaultScriptsTpl)
execTpl(rw, data, tasksTpl, defaultScriptsTpl)
}
func writeTemplate(rw http.ResponseWriter, data map[interface{}]interface{}, tpls ...string) {
func execTpl(rw http.ResponseWriter, data map[interface{}]interface{}, tpls ...string) {
tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl))
for _, tpl := range tpls {
tmpl = template.Must(tmpl.Parse(tpl))

View File

@ -1,32 +1,10 @@
package beego
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"net/http/httptest"
"reflect"
"strings"
"testing"
"github.com/astaxie/beego/toolbox"
)
type SampleDatabaseCheck struct {
}
type SampleCacheCheck struct {
}
func (dc *SampleDatabaseCheck) Check() error {
return nil
}
func (cc *SampleCacheCheck) Check() error {
return errors.New("no cache detected")
}
func TestList_01(t *testing.T) {
m := make(M)
list("BConfig", BConfig, m)
@ -97,143 +75,3 @@ func oldMap() M {
m["BConfig.Log.Outputs"] = BConfig.Log.Outputs
return m
}
func TestWriteJSON(t *testing.T) {
t.Log("Testing the adding of JSON to the response")
w := httptest.NewRecorder()
originalBody := []int{1, 2, 3}
res, _ := json.Marshal(originalBody)
writeJSON(w, res)
decodedBody := []int{}
err := json.NewDecoder(w.Body).Decode(&decodedBody)
if err != nil {
t.Fatal("Could not decode response body into slice.")
}
for i := range decodedBody {
if decodedBody[i] != originalBody[i] {
t.Fatalf("Expected %d but got %d in decoded body slice", originalBody[i], decodedBody[i])
}
}
}
func TestHealthCheckHandlerDefault(t *testing.T) {
endpointPath := "/healthcheck"
toolbox.AddHealthCheck("database", &SampleDatabaseCheck{})
toolbox.AddHealthCheck("cache", &SampleCacheCheck{})
req, err := http.NewRequest("GET", endpointPath, nil)
if err != nil {
t.Fatal(err)
}
w := httptest.NewRecorder()
handler := http.HandlerFunc(healthcheck)
handler.ServeHTTP(w, req)
if status := w.Code; status != http.StatusOK {
t.Errorf("handler returned wrong status code: got %v want %v",
status, http.StatusOK)
}
if !strings.Contains(w.Body.String(), "database") {
t.Errorf("Expected 'database' in generated template.")
}
}
func TestBuildHealthCheckResponseList(t *testing.T) {
healthCheckResults := [][]string{
[]string{
"error",
"Database",
"Error occurred while starting the db",
},
[]string{
"success",
"Cache",
"Cache started successfully",
},
}
responseList := buildHealthCheckResponseList(&healthCheckResults)
if len(responseList) != len(healthCheckResults) {
t.Errorf("invalid response map length: got %d want %d",
len(responseList), len(healthCheckResults))
}
responseFields := []string{"name", "message", "status"}
for _, response := range responseList {
for _, field := range responseFields {
_, ok := response[field]
if !ok {
t.Errorf("expected %s to be in the response %v", field, response)
}
}
}
}
func TestHealthCheckHandlerReturnsJSON(t *testing.T) {
toolbox.AddHealthCheck("database", &SampleDatabaseCheck{})
toolbox.AddHealthCheck("cache", &SampleCacheCheck{})
req, err := http.NewRequest("GET", "/healthcheck?json=true", nil)
if err != nil {
t.Fatal(err)
}
w := httptest.NewRecorder()
handler := http.HandlerFunc(healthcheck)
handler.ServeHTTP(w, req)
if status := w.Code; status != http.StatusOK {
t.Errorf("handler returned wrong status code: got %v want %v",
status, http.StatusOK)
}
decodedResponseBody := []map[string]interface{}{}
expectedResponseBody := []map[string]interface{}{}
expectedJSONString := []byte(`
[
{
"message":"database",
"name":"success",
"status":"OK"
},
{
"message":"cache",
"name":"error",
"status":"no cache detected"
}
]
`)
json.Unmarshal(expectedJSONString, &expectedResponseBody)
json.Unmarshal(w.Body.Bytes(), &decodedResponseBody)
if len(expectedResponseBody) != len(decodedResponseBody) {
t.Errorf("invalid response map length: got %d want %d",
len(decodedResponseBody), len(expectedResponseBody))
}
if !reflect.DeepEqual(decodedResponseBody, expectedResponseBody) {
t.Errorf("handler returned unexpected body: got %v want %v",
decodedResponseBody, expectedResponseBody)
}
}

2
app.go
View File

@ -197,7 +197,7 @@ func (app *App) Run(mws ...MiddleWare) {
pool.AppendCertsFromPEM(data)
app.Server.TLSConfig = &tls.Config{
ClientCAs: pool,
ClientAuth: BConfig.Listen.ClientAuth,
ClientAuth: tls.RequireAndVerifyClientCert,
}
}
if err := app.Server.ListenAndServeTLS(BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile); err != nil {

View File

@ -23,7 +23,7 @@ import (
const (
// VERSION represent beego web framework version.
VERSION = "1.12.3"
VERSION = "1.12.2"
// DEV is for develop
DEV = "dev"

View File

@ -38,9 +38,8 @@ import (
"github.com/gomodule/redigo/redis"
"strings"
"github.com/astaxie/beego/cache"
"strings"
)
var (

View File

@ -15,9 +15,7 @@
package beego
import (
"crypto/tls"
"fmt"
"net/http"
"os"
"path/filepath"
"reflect"
@ -67,7 +65,6 @@ type Listen struct {
HTTPSCertFile string
HTTPSKeyFile string
TrustCaFile string
ClientAuth tls.ClientAuthType
EnableAdmin bool
AdminAddr string
AdminPort int
@ -109,7 +106,6 @@ type SessionConfig struct {
SessionEnableSidInHTTPHeader bool // enable store/get the sessionId into/from http headers
SessionNameInHTTPHeader string
SessionEnableSidInURLQuery bool // enable get the sessionId from Url Query params
SessionCookieSameSite http.SameSite
}
// LogConfig holds Log related config
@ -154,9 +150,6 @@ func init() {
filename = os.Getenv("BEEGO_RUNMODE") + ".app.conf"
}
appConfigPath = filepath.Join(WorkPath, "conf", filename)
if configPath := os.Getenv("BEEGO_CONFIG_PATH"); configPath != "" {
appConfigPath = configPath
}
if !utils.FileExists(appConfigPath) {
appConfigPath = filepath.Join(AppPath, "conf", filename)
if !utils.FileExists(appConfigPath) {
@ -238,7 +231,6 @@ func newBConfig() *Config {
AdminPort: 8088,
EnableFcgi: false,
EnableStdIo: false,
ClientAuth: tls.RequireAndVerifyClientCert,
},
WebConfig: WebConfig{
AutoRender: true,
@ -269,7 +261,6 @@ func newBConfig() *Config {
SessionEnableSidInHTTPHeader: false, // enable store/get the sessionId into/from http headers
SessionNameInHTTPHeader: "Beegosessionid",
SessionEnableSidInURLQuery: false, // enable get the sessionId from Url Query params
SessionCookieSameSite: http.SameSiteDefaultMode,
},
},
Log: LogConfig{

View File

@ -145,7 +145,7 @@ httpport = 8080
# enable db
[dbinfo]
# db type name
# support mysql,sqlserver
# suport mysql,sqlserver
name = mysql
`
@ -161,7 +161,7 @@ httpport=8080
# enable db
[dbinfo]
# db type name
# support mysql,sqlserver
# suport mysql,sqlserver
name=mysql
`
)

View File

@ -296,7 +296,7 @@ func (c *ConfigContainer) getData(key string) (interface{}, error) {
case map[string]interface{}:
{
tmpData = v.(map[string]interface{})
if idx == len(keys)-1 {
if idx == len(keys) - 1 {
return tmpData, nil
}
}

View File

@ -150,7 +150,7 @@ func (ctx *Context) XSRFToken(key string, expire int64) string {
token, ok := ctx.GetSecureCookie(key, "_xsrf")
if !ok {
token = string(utils.RandomCreateBytes(32))
ctx.SetSecureCookie(key, "_xsrf", token, expire, "", "", true, true)
ctx.SetSecureCookie(key, "_xsrf", token, expire)
}
ctx._xsrfToken = token
}

View File

@ -17,10 +17,7 @@ package context
import (
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
func TestXsrfReset_01(t *testing.T) {
@ -47,8 +44,4 @@ func TestXsrfReset_01(t *testing.T) {
if token == c._xsrfToken {
t.FailNow()
}
ck := c.ResponseWriter.Header().Get("Set-Cookie")
assert.True(t, strings.Contains(ck, "Secure"))
assert.True(t, strings.Contains(ck, "HttpOnly"))
}

View File

@ -332,15 +332,9 @@ func (input *BeegoInput) Query(key string) string {
if val := input.Param(key); val != "" {
return val
}
if input.Context.Request.Form == nil {
input.dataLock.Lock()
if input.Context.Request.Form == nil {
input.Context.Request.ParseForm()
}
input.dataLock.Unlock()
}
input.dataLock.RLock()
defer input.dataLock.RUnlock()
return input.Context.Request.Form.Get(key)
}

View File

@ -205,13 +205,3 @@ func TestParams(t *testing.T) {
}
}
func BenchmarkQuery(b *testing.B) {
beegoInput := NewInput()
beegoInput.Context = NewContext()
beegoInput.Context.Request, _ = http.NewRequest("POST", "http://www.example.com/?q=foo", nil)
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
beegoInput.Query("q")
}
})
}

View File

@ -1,10 +1,8 @@
package param
import (
"reflect"
"testing"
"time"
)
import "testing"
import "reflect"
import "time"
type testDefinition struct {
strValue string

View File

@ -255,7 +255,7 @@ func (c *Controller) RenderString() (string, error) {
// RenderBytes returns the bytes of rendered template string. Do not send out response.
func (c *Controller) RenderBytes() ([]byte, error) {
buf, err := c.renderTemplate()
// if the controller has set layout, then first get the tplName's content set the content to the layout
//if the controller has set layout, then first get the tplName's content set the content to the layout
if err == nil && c.Layout != "" {
c.Data["LayoutContent"] = template.HTML(buf.String())
@ -642,13 +642,12 @@ func (c *Controller) DelSession(name interface{}) {
// SessionRegenerateID regenerates session id for this session.
// the session data have no changes.
func (c *Controller) SessionRegenerateID() (err error) {
func (c *Controller) SessionRegenerateID() {
if c.CruSession != nil {
c.CruSession.SessionRelease(c.Ctx.ResponseWriter)
}
c.CruSession, err = GlobalSessions.SessionRegenerateID(c.Ctx.ResponseWriter, c.Ctx.Request)
c.CruSession = GlobalSessions.SessionRegenerateID(c.Ctx.ResponseWriter, c.Ctx.Request)
c.Ctx.Input.CruSession = c.CruSession
return
}
// DestroySession cleans session data and session cookie.

View File

@ -19,10 +19,9 @@ import (
"strconv"
"testing"
"github.com/astaxie/beego/context"
"os"
"path/filepath"
"github.com/astaxie/beego/context"
)
func TestGetInt(t *testing.T) {
@ -126,8 +125,8 @@ func TestGetUint64(t *testing.T) {
}
func TestAdditionalViewPaths(t *testing.T) {
dir1 := tmpDir("TestAdditionalViewPaths1")
dir2 := tmpDir("TestAdditionalViewPaths2")
dir1 := "_beeTmp"
dir2 := "_beeTmp2"
defer os.RemoveAll(dir1)
defer os.RemoveAll(dir2)

View File

@ -359,20 +359,6 @@ func gatewayTimeout(rw http.ResponseWriter, r *http.Request) {
)
}
// show 413 Payload Too Large
func payloadTooLarge(rw http.ResponseWriter, r *http.Request) {
responseError(rw, r,
413,
`<br>The page you have requested is unavailable.
<br>Perhaps you are here because:<br><br>
<ul>
<br>The request entity is larger than limits defined by server.
<br>Please change the request entity and try again.
</ul>
`,
)
}
func responseError(rw http.ResponseWriter, r *http.Request, errCode int, errContent string) {
t, _ := template.New("beegoerrortemp").Parse(errtpl)
data := M{

3
go.mod
View File

@ -22,7 +22,6 @@ require (
github.com/lib/pq v1.0.0
github.com/mattn/go-sqlite3 v2.0.3+incompatible
github.com/pelletier/go-toml v1.2.0 // indirect
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.7.0
github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644
github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec
@ -30,7 +29,7 @@ require (
github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c // indirect
github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b // indirect
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 // indirect
golang.org/x/tools v0.0.0-20200117065230-39095c1d176c
gopkg.in/yaml.v2 v2.2.8
)

11
go.sum
View File

@ -53,6 +53,7 @@ github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8w
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-yaml/yaml v0.0.0-20180328195020-5420a8b6744d h1:xy93KVe+KrIIwWDEAfQBdIfsiHJkepbYsDr+VY3g9/o=
github.com/go-yaml/yaml v0.0.0-20180328195020-5420a8b6744d/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
@ -113,10 +114,11 @@ github.com/pelletier/go-toml v1.0.1/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/peterh/liner v1.0.1-0.20171122030339-3681c2a91233/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
github.com/pingcap/tidb v2.0.11+incompatible/go.mod h1:I8C6jrPINP2rrVunTRd7C9fRRhQrtR43S1/CL5ix/yQ=
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
@ -162,7 +164,9 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a h1:gOpx8G595UYyvj8UK4+OFyY4rx037g3fmfhe5SasG3U=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@ -171,6 +175,7 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -184,6 +189,8 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20200117065230-39095c1d176c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=

View File

@ -34,7 +34,6 @@ func registerDefaultErrorHandler() error {
"504": gatewayTimeout,
"417": invalidxsrf,
"422": missingxsrf,
"413": payloadTooLarge,
}
for e, h := range m {
if _, ok := ErrorMaps[e]; !ok {
@ -61,7 +60,6 @@ func registerSession() error {
conf.EnableSidInHTTPHeader = BConfig.WebConfig.Session.SessionEnableSidInHTTPHeader
conf.SessionNameInHTTPHeader = BConfig.WebConfig.Session.SessionNameInHTTPHeader
conf.EnableSidInURLQuery = BConfig.WebConfig.Session.SessionEnableSidInURLQuery
conf.CookieSameSite = BConfig.WebConfig.Session.SessionCookieSameSite
} else {
if err = json.Unmarshal([]byte(sessionConfig), conf); err != nil {
return err

View File

@ -144,7 +144,6 @@ type BeegoHTTPSettings struct {
Gzip bool
DumpBody bool
Retries int // if set to -1 means will retry forever
RetryDelay time.Duration
}
// BeegoHTTPRequest provides more useful methods for requesting one url than http.Request.
@ -203,11 +202,6 @@ func (b *BeegoHTTPRequest) Retries(times int) *BeegoHTTPRequest {
return b
}
func (b *BeegoHTTPRequest) RetryDelay(delay time.Duration) *BeegoHTTPRequest {
b.setting.RetryDelay = delay
return b
}
// DumpBody setting whether need to Dump the Body.
func (b *BeegoHTTPRequest) DumpBody(isdump bool) *BeegoHTTPRequest {
b.setting.DumpBody = isdump
@ -518,13 +512,11 @@ func (b *BeegoHTTPRequest) DoRequest() (resp *http.Response, err error) {
// retries default value is 0, it will run once.
// retries equal to -1, it will run forever until success
// retries is setted, it will retries fixed times.
// Sleeps for a 400ms in between calls to reduce spam
for i := 0; b.setting.Retries == -1 || i <= b.setting.Retries; i++ {
resp, err = client.Do(b.req)
if err == nil {
break
}
time.Sleep(b.setting.RetryDelay)
}
return resp, err
}

View File

@ -15,7 +15,6 @@
package httplib
import (
"errors"
"io/ioutil"
"net"
"net/http"
@ -34,34 +33,6 @@ func TestResponse(t *testing.T) {
t.Log(resp)
}
func TestDoRequest(t *testing.T) {
req := Get("https://goolnk.com/33BD2j")
retryAmount := 1
req.Retries(1)
req.RetryDelay(1400 * time.Millisecond)
retryDelay := 1400 * time.Millisecond
req.setting.CheckRedirect = func(redirectReq *http.Request, redirectVia []*http.Request) error {
return errors.New("Redirect triggered")
}
startTime := time.Now().UnixNano() / int64(time.Millisecond)
_, err := req.Response()
if err == nil {
t.Fatal("Response should have yielded an error")
}
endTime := time.Now().UnixNano() / int64(time.Millisecond)
elapsedTime := endTime - startTime
delayedTime := int64(retryAmount) * retryDelay.Milliseconds()
if elapsedTime < delayedTime {
t.Errorf("Not enough retries. Took %dms. Delay was meant to take %dms", elapsedTime, delayedTime)
}
}
func TestGet(t *testing.T) {
req := Get("http://httpbin.org/get")
b, err := req.Bytes()

View File

@ -16,9 +16,9 @@ package logs
import (
"bytes"
"strings"
"encoding/json"
"fmt"
"strings"
"time"
)

View File

@ -63,10 +63,7 @@ func (c *connWriter) WriteMsg(when time.Time, msg string, level int) error {
defer c.innerWriter.Close()
}
_, err := c.lg.writeln(when, msg)
if err != nil {
return err
}
c.lg.writeln(when, msg)
return nil
}
@ -104,6 +101,7 @@ func (c *connWriter) connect() error {
func (c *connWriter) needToConnectOnMsg() bool {
if c.Reconnect {
c.Reconnect = false
return true
}

View File

@ -15,65 +15,11 @@
package logs
import (
"net"
"os"
"testing"
)
// ConnTCPListener takes a TCP listener and accepts n TCP connections
// Returns connections using connChan
func connTCPListener(t *testing.T, n int, ln net.Listener, connChan chan<- net.Conn) {
// Listen and accept n incoming connections
for i := 0; i < n; i++ {
conn, err := ln.Accept()
if err != nil {
t.Log("Error accepting connection: ", err.Error())
os.Exit(1)
}
// Send accepted connection to channel
connChan <- conn
}
ln.Close()
close(connChan)
}
func TestConn(t *testing.T) {
log := NewLogger(1000)
log.SetLogger("conn", `{"net":"tcp","addr":":7020"}`)
log.Informational("informational")
}
func TestReconnect(t *testing.T) {
// Setup connection listener
newConns := make(chan net.Conn)
connNum := 2
ln, err := net.Listen("tcp", ":6002")
if err != nil {
t.Log("Error listening:", err.Error())
os.Exit(1)
}
go connTCPListener(t, connNum, ln, newConns)
// Setup logger
log := NewLogger(1000)
log.SetPrefix("test")
log.SetLogger(AdapterConn, `{"net":"tcp","reconnect":true,"level":6,"addr":":6002"}`)
log.Informational("informational 1")
// Refuse first connection
first := <-newConns
first.Close()
// Send another log after conn closed
log.Informational("informational 2")
// Check if there was a second connection attempt
select {
case second := <-newConns:
second.Close()
default:
t.Error("Did not reconnect")
}
}

View File

@ -374,14 +374,14 @@ func (w *fileLogWriter) deleteOldLog() {
return
}
if w.Hourly {
if !info.IsDir() && info.ModTime().Add(1*time.Hour*time.Duration(w.MaxHours)).Before(time.Now()) {
if !info.IsDir() && info.ModTime().Add(1 * time.Hour * time.Duration(w.MaxHours)).Before(time.Now()) {
if strings.HasPrefix(filepath.Base(path), filepath.Base(w.fileNameOnly)) &&
strings.HasSuffix(filepath.Base(path), w.suffix) {
os.Remove(path)
}
}
} else if w.Daily {
if !info.IsDir() && info.ModTime().Add(24*time.Hour*time.Duration(w.MaxDays)).Before(time.Now()) {
if !info.IsDir() && info.ModTime().Add(24 * time.Hour * time.Duration(w.MaxDays)).Before(time.Now()) {
if strings.HasPrefix(filepath.Base(path), filepath.Base(w.fileNameOnly)) &&
strings.HasSuffix(filepath.Base(path), w.suffix) {
os.Remove(path)

View File

@ -30,12 +30,11 @@ func newLogWriter(wr io.Writer) *logWriter {
return &logWriter{writer: wr}
}
func (lg *logWriter) writeln(when time.Time, msg string) (int, error) {
func (lg *logWriter) writeln(when time.Time, msg string) {
lg.Lock()
h, _, _ := formatTimeHeader(when)
n, err := lg.writer.Write(append(append(h, msg...), '\n'))
lg.writer.Write(append(append(h, msg...), '\n'))
lg.Unlock()
return n, err
}
const (

View File

@ -37,7 +37,7 @@ func PrometheusMiddleWare(next http.Handler) http.Handler {
"appname": beego.BConfig.AppName,
},
Help: "The statics info for http request",
}, []string{"pattern", "method", "status"})
}, []string{"pattern", "method", "status", "duration"})
prometheus.MustRegister(summaryVec)
@ -95,5 +95,5 @@ func report(dur time.Duration, writer http.ResponseWriter, q *http.Request, vec
logs.Warn("we can not find the router info for this request, so request will be recorded as UNKNOWN: " + q.URL.String())
}
ms := dur / time.Millisecond
vec.WithLabelValues(ptn, q.Method, strconv.Itoa(status)).Observe(float64(ms))
vec.WithLabelValues(ptn, q.Method, strconv.Itoa(status), strconv.Itoa(int(ms))).Observe(float64(ms))
}

View File

@ -35,7 +35,7 @@ func TestPrometheusMiddleWare(t *testing.T) {
},
Method: "POST",
}
vec := prometheus.NewSummaryVec(prometheus.SummaryOpts{}, []string{"pattern", "method", "status"})
vec := prometheus.NewSummaryVec(prometheus.SummaryOpts{}, []string{"pattern", "method", "status", "duration"})
report(time.Second, writer, request, vec)
middleware.ServeHTTP(writer, request)

View File

@ -198,8 +198,8 @@ func getDbCreateSQL(al *alias) (sqls []string, tableIndexes map[string][]dbIndex
column = strings.Replace(column, "%COL%", fi.column, -1)
}
if fi.description != "" && al.Driver != DRSqlite {
column += " " + fmt.Sprintf("COMMENT '%s'", fi.description)
if fi.description != "" && al.Driver!=DRSqlite {
column += " " + fmt.Sprintf("COMMENT '%s'",fi.description)
}
columns = append(columns, column)

View File

@ -38,7 +38,6 @@ var (
operators = map[string]bool{
"exact": true,
"iexact": true,
"strictexact": true,
"contains": true,
"icontains": true,
// "regex": true,
@ -703,13 +702,6 @@ func (d *dbBase) Delete(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.
return 0, err
}
if num > 0 {
if mi.fields.pk.auto {
if mi.fields.pk.fieldType&IsPositiveIntegerField > 0 {
ind.FieldByIndex(mi.fields.pk.fieldIndex).SetUint(0)
} else {
ind.FieldByIndex(mi.fields.pk.fieldIndex).SetInt(0)
}
}
err := d.deleteRels(q, mi, args, tz)
if err != nil {
return num, err
@ -1203,7 +1195,7 @@ func (d *dbBase) GenerateOperatorSQL(mi *modelInfo, fi *fieldInfo, operator stri
}
sql = d.ins.OperatorSQL(operator)
switch operator {
case "exact", "strictexact":
case "exact":
if arg == nil {
params[0] = "IS NULL"
}

View File

@ -18,11 +18,10 @@ import (
"context"
"database/sql"
"fmt"
lru "github.com/hashicorp/golang-lru"
"reflect"
"sync"
"time"
lru "github.com/hashicorp/golang-lru"
)
// DriverType database driver constant int.
@ -426,6 +425,7 @@ func GetDB(aliasNames ...string) (*sql.DB, error) {
type stmtDecorator struct {
wg sync.WaitGroup
lastUse int64
stmt *sql.Stmt
}
@ -433,12 +433,9 @@ func (s *stmtDecorator) getStmt() *sql.Stmt {
return s.stmt
}
// acquire will add one
// since this method will be used inside read lock scope,
// so we can not do more things here
// we should think about refactor this
func (s *stmtDecorator) acquire() {
s.wg.Add(1)
s.lastUse = time.Now().Unix()
}
func (s *stmtDecorator) release() {
@ -456,13 +453,12 @@ func (s *stmtDecorator) destroy() {
func newStmtDecorator(sqlStmt *sql.Stmt) *stmtDecorator {
return &stmtDecorator{
stmt: sqlStmt,
lastUse: time.Now().Unix(),
}
}
func newStmtDecoratorLruWithEvict() *lru.Cache {
// temporarily solution
// we fixed this problem in v2.x
cache, _ := lru.NewWithEvict(50, func(key interface{}, value interface{}) {
cache, _ := lru.NewWithEvict(1000, func(key interface{}, value interface{}) {
value.(*stmtDecorator).destroy()
})
return cache

View File

@ -24,7 +24,6 @@ import (
var mysqlOperators = map[string]string{
"exact": "= ?",
"iexact": "LIKE ?",
"strictexact": "= BINARY ?",
"contains": "LIKE BINARY ?",
"icontains": "LIKE ?",
// "regex": "REGEXP BINARY ?",

View File

@ -53,24 +53,18 @@ func (e *SliceStringField) FieldType() int {
}
func (e *SliceStringField) SetRaw(value interface{}) error {
f := func(str string) {
if len(str) > 0 {
parts := strings.Split(str, ",")
switch d := value.(type) {
case []string:
e.Set(d)
case string:
if len(d) > 0 {
parts := strings.Split(d, ",")
v := make([]string, 0, len(parts))
for _, p := range parts {
v = append(v, strings.TrimSpace(p))
}
e.Set(v)
}
}
switch d := value.(type) {
case []string:
e.Set(d)
case string:
f(d)
case []byte:
f(string(d))
default:
return fmt.Errorf("<SliceStringField.SetRaw> unknown value `%v`", value)
}
@ -102,8 +96,6 @@ func (e *JSONFieldTest) SetRaw(value interface{}) error {
switch d := value.(type) {
case string:
return json.Unmarshal([]byte(d), e)
case []byte:
return json.Unmarshal(d, e)
default:
return fmt.Errorf("<JSONField.SetRaw> unknown value `%v`", value)
}

View File

@ -242,13 +242,7 @@ func (o *orm) Update(md interface{}, cols ...string) (int64, error) {
func (o *orm) Delete(md interface{}, cols ...string) (int64, error) {
mi, ind := o.getMiInd(md, true)
num, err := o.alias.DbBaser.Delete(o.db, mi, ind, o.alias.TZ, cols)
if err != nil {
return num, err
}
if num > 0 {
o.setPk(mi, ind, 0)
}
return num, nil
}
// create a models to models queryer

View File

@ -61,7 +61,7 @@ func debugLogQueies(alias *alias, operaton, query string, t time.Time, err error
con += " - " + err.Error()
}
logMap["sql"] = fmt.Sprintf("%s-`%s`", query, strings.Join(cons, "`, `"))
if LogFunc != nil {
if LogFunc != nil{
LogFunc(logMap)
}
DebugLog.Println(con)

View File

@ -19,8 +19,6 @@ import (
"fmt"
"reflect"
"time"
"github.com/pkg/errors"
)
// raw sql string prepared statement
@ -370,17 +368,9 @@ func (o *rawSet) QueryRow(containers ...interface{}) error {
field.Set(mf)
field = mf.Elem().FieldByIndex(fi.relModelInfo.fields.pk.fieldIndex)
}
if fi.isFielder {
fd := field.Addr().Interface().(Fielder)
err := fd.SetRaw(value)
if err != nil {
return errors.Errorf("set raw error:%s", err)
}
} else {
o.setFieldValue(field, value)
}
}
}
} else {
for i := 0; i < ind.NumField(); i++ {
f := ind.Field(i)
@ -519,17 +509,9 @@ func (o *rawSet) QueryRows(containers ...interface{}) (int64, error) {
field.Set(mf)
field = mf.Elem().FieldByIndex(fi.relModelInfo.fields.pk.fieldIndex)
}
if fi.isFielder {
fd := field.Addr().Interface().(Fielder)
err := fd.SetRaw(value)
if err != nil {
return 0, errors.Errorf("set raw error:%s", err)
}
} else {
o.setFieldValue(field, value)
}
}
}
} else {
// define recursive function
var recursiveSetField func(rv reflect.Value)

View File

@ -769,20 +769,6 @@ func TestCustomField(t *testing.T) {
throwFailNow(t, AssertIs(user.Extra.Name, "beego"))
throwFailNow(t, AssertIs(user.Extra.Data, "orm"))
var users []User
Q := dDbBaser.TableQuote()
n, err := dORM.Raw(fmt.Sprintf("SELECT * FROM %suser%s where id=?", Q, Q), 2).QueryRows(&users)
throwFailNow(t, err)
throwFailNow(t, AssertIs(n, 1))
throwFailNow(t, AssertIs(users[0].Extra.Name, "beego"))
throwFailNow(t, AssertIs(users[0].Extra.Data, "orm"))
user = User{}
err = dORM.Raw(fmt.Sprintf("SELECT * FROM %suser%s where id=?", Q, Q), 2).QueryRow(&user)
throwFailNow(t, err)
throwFailNow(t, AssertIs(user.Extra.Name, "beego"))
throwFailNow(t, AssertIs(user.Extra.Data, "orm"))
}
func TestExpr(t *testing.T) {
@ -822,17 +808,6 @@ func TestOperators(t *testing.T) {
throwFail(t, err)
throwFail(t, AssertIs(num, 1))
if IsMysql {
// Now only mysql support `strictexact`
num, err = qs.Filter("user_name__strictexact", "Slene").Count()
throwFail(t, err)
throwFail(t, AssertIs(num, 0))
num, err = qs.Filter("user_name__strictexact", "slene").Count()
throwFail(t, err)
throwFail(t, AssertIs(num, 1))
}
num, err = qs.Filter("user_name__contains", "e").Count()
throwFail(t, err)
throwFail(t, AssertIs(num, 2))

View File

@ -49,6 +49,7 @@ func init() {
var (
lastupdateFilename = "lastupdate.tmp"
commentFilename string
pkgLastupdate map[string]int64
genInfoList map[string][]ControllerComments
@ -69,13 +70,16 @@ var (
}
)
const commentFilename = "commentsRouter.go"
const commentPrefix = "commentsRouter_"
func init() {
pkgLastupdate = make(map[string]int64)
}
func parserPkg(pkgRealpath, pkgpath string) error {
rep := strings.NewReplacer("\\", "_", "/", "_", ".", "_")
commentFilename, _ = filepath.Rel(AppPath, pkgRealpath)
commentFilename = commentPrefix + rep.Replace(commentFilename) + ".go"
if !compareFile(pkgRealpath) {
logs.Info(pkgRealpath + " no changed")
return nil
@ -98,10 +102,7 @@ func parserPkg(pkgRealpath, pkgpath string) error {
if specDecl.Recv != nil {
exp, ok := specDecl.Recv.List[0].Type.(*ast.StarExpr) // Check that the type is correct first beforing throwing to parser
if ok {
err = parserComments(specDecl, fmt.Sprint(exp.X), pkgpath)
if err != nil {
return err
}
parserComments(specDecl, fmt.Sprint(exp.X), pkgpath)
}
}
}
@ -499,7 +500,7 @@ func genRouterCode(pkgRealpath string) {
beego.GlobalControllerRouter["` + k + `"] = append(beego.GlobalControllerRouter["` + k + `"],
beego.ControllerComments{
Method: "` + strings.TrimSpace(c.Method) + `",
` + "Router: `" + c.Router + "`" + `,
` + `Router: "` + c.Router + `"` + `,
AllowHTTPMethods: ` + allmethod + `,
MethodParams: ` + methodParams + `,
Filters: ` + filters + `,

View File

@ -40,11 +40,10 @@
package authz
import (
"net/http"
"github.com/astaxie/beego"
"github.com/astaxie/beego/context"
"github.com/casbin/casbin"
"net/http"
)
// NewAuthorizer returns the authorizer.

View File

@ -15,14 +15,13 @@
package authz
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/astaxie/beego"
"github.com/astaxie/beego/context"
"github.com/astaxie/beego/plugins/auth"
"github.com/casbin/casbin"
"net/http"
"net/http/httptest"
"testing"
)
func testRequest(t *testing.T, handler *beego.ControllerRegister, user string, path string, method string, code int) {

View File

@ -742,12 +742,6 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request)
if r.Method != http.MethodGet && r.Method != http.MethodHead {
if BConfig.CopyRequestBody && !context.Input.IsUpload() {
// connection will close if the incoming data are larger (RFC 7231, 6.5.11)
if r.ContentLength > BConfig.MaxMemory {
logs.Error(errors.New("payload too large"))
exception("413", context)
goto Admin
}
context.Input.CopyBody(BConfig.MaxMemory)
}
context.Input.ParseFormOrMulitForm(BConfig.MaxMemory)

View File

@ -15,7 +15,6 @@
package beego
import (
"bytes"
"net/http"
"net/http/httptest"
"strings"
@ -72,6 +71,7 @@ func (tc *TestController) GetEmptyBody() {
tc.Ctx.Output.Body(res)
}
type JSONController struct {
Controller
}
@ -656,14 +656,17 @@ func beegoBeforeRouter1(ctx *context.Context) {
ctx.WriteString("|BeforeRouter1")
}
func beegoBeforeExec1(ctx *context.Context) {
ctx.WriteString("|BeforeExec1")
}
func beegoAfterExec1(ctx *context.Context) {
ctx.WriteString("|AfterExec1")
}
func beegoFinishRouter1(ctx *context.Context) {
ctx.WriteString("|FinishRouter1")
}
@ -706,27 +709,3 @@ func TestYAMLPrepare(t *testing.T) {
t.Errorf(w.Body.String())
}
}
func TestRouterEntityTooLargeCopyBody(t *testing.T) {
_MaxMemory := BConfig.MaxMemory
_CopyRequestBody := BConfig.CopyRequestBody
BConfig.CopyRequestBody = true
BConfig.MaxMemory = 20
b := bytes.NewBuffer([]byte("barbarbarbarbarbarbarbarbarbar"))
r, _ := http.NewRequest("POST", "/user/123", b)
w := httptest.NewRecorder()
handler := NewControllerRegister()
handler.Post("/user/:id", func(ctx *context.Context) {
ctx.Output.Body([]byte(ctx.Input.Param(":id")))
})
handler.ServeHTTP(w, r)
BConfig.CopyRequestBody = _CopyRequestBody
BConfig.MaxMemory = _MaxMemory
if w.Code != http.StatusRequestEntityTooLarge {
t.Errorf("TestRouterRequestEntityTooLarge can't run")
}
}

View File

@ -31,16 +31,14 @@
//
// more docs: http://beego.me/docs/module/session.md
package redis_cluster
import (
"net/http"
"strconv"
"strings"
"sync"
"time"
"github.com/astaxie/beego/session"
rediss "github.com/go-redis/redis"
"time"
)
var redispder = &Provider{}
@ -103,7 +101,7 @@ func (rs *SessionStore) SessionRelease(w http.ResponseWriter) {
return
}
c := rs.p
c.Set(rs.sid, string(b), time.Duration(rs.maxlifetime)*time.Second)
c.Set(rs.sid, string(b), time.Duration(rs.maxlifetime) * time.Second)
}
// Provider redis_cluster session provider
@ -193,10 +191,10 @@ func (rp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error)
// oldsid doesn't exists, set the new sid directly
// ignore error here, since if it return error
// the existed value will be 0
c.Set(sid, "", time.Duration(rp.maxlifetime)*time.Second)
c.Set(sid, "", time.Duration(rp.maxlifetime) * time.Second)
} else {
c.Rename(oldsid, sid)
c.Expire(sid, time.Duration(rp.maxlifetime)*time.Second)
c.Expire(sid, time.Duration(rp.maxlifetime) * time.Second)
}
return rp.SessionRead(sid)
}

View File

@ -33,14 +33,13 @@
package redis_sentinel
import (
"github.com/astaxie/beego/session"
"github.com/go-redis/redis"
"net/http"
"strconv"
"strings"
"sync"
"time"
"github.com/astaxie/beego/session"
"github.com/go-redis/redis"
)
var redispder = &Provider{}

View File

@ -15,11 +15,11 @@
package session
import (
"errors"
"fmt"
"io/ioutil"
"net/http"
"os"
"errors"
"path"
"path/filepath"
"strings"
@ -180,11 +180,6 @@ func (fp *FileProvider) SessionExist(sid string) bool {
filepder.lock.Lock()
defer filepder.lock.Unlock()
if len(sid) < 2 {
SLogger.Println("min length of session id is 2", sid)
return false
}
_, err := os.Stat(path.Join(fp.savePath, string(sid[0]), string(sid[1]), sid))
return err == nil
}

View File

@ -1,386 +0,0 @@
// Copyright 2014 beego Author. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package session
import (
"fmt"
"os"
"sync"
"testing"
"time"
)
const sid = "Session_id"
const sidNew = "Session_id_new"
const sessionPath = "./_session_runtime"
var (
mutex sync.Mutex
)
func TestFileProvider_SessionInit(t *testing.T) {
mutex.Lock()
defer mutex.Unlock()
os.RemoveAll(sessionPath)
defer os.RemoveAll(sessionPath)
fp := &FileProvider{}
_ = fp.SessionInit(180, sessionPath)
if fp.maxlifetime != 180 {
t.Error()
}
if fp.savePath != sessionPath {
t.Error()
}
}
func TestFileProvider_SessionExist(t *testing.T) {
mutex.Lock()
defer mutex.Unlock()
os.RemoveAll(sessionPath)
defer os.RemoveAll(sessionPath)
fp := &FileProvider{}
_ = fp.SessionInit(180, sessionPath)
if fp.SessionExist(sid) {
t.Error()
}
_, err := fp.SessionRead(sid)
if err != nil {
t.Error(err)
}
if !fp.SessionExist(sid) {
t.Error()
}
}
func TestFileProvider_SessionExist2(t *testing.T) {
mutex.Lock()
defer mutex.Unlock()
os.RemoveAll(sessionPath)
defer os.RemoveAll(sessionPath)
fp := &FileProvider{}
_ = fp.SessionInit(180, sessionPath)
if fp.SessionExist(sid) {
t.Error()
}
if fp.SessionExist("") {
t.Error()
}
if fp.SessionExist("1") {
t.Error()
}
}
func TestFileProvider_SessionRead(t *testing.T) {
mutex.Lock()
defer mutex.Unlock()
os.RemoveAll(sessionPath)
defer os.RemoveAll(sessionPath)
fp := &FileProvider{}
_ = fp.SessionInit(180, sessionPath)
s, err := fp.SessionRead(sid)
if err != nil {
t.Error(err)
}
_ = s.Set("sessionValue", 18975)
v := s.Get("sessionValue")
if v.(int) != 18975 {
t.Error()
}
}
func TestFileProvider_SessionRead1(t *testing.T) {
mutex.Lock()
defer mutex.Unlock()
os.RemoveAll(sessionPath)
defer os.RemoveAll(sessionPath)
fp := &FileProvider{}
_ = fp.SessionInit(180, sessionPath)
_, err := fp.SessionRead("")
if err == nil {
t.Error(err)
}
_, err = fp.SessionRead("1")
if err == nil {
t.Error(err)
}
}
func TestFileProvider_SessionAll(t *testing.T) {
mutex.Lock()
defer mutex.Unlock()
os.RemoveAll(sessionPath)
defer os.RemoveAll(sessionPath)
fp := &FileProvider{}
_ = fp.SessionInit(180, sessionPath)
sessionCount := 546
for i := 1; i <= sessionCount; i++ {
_, err := fp.SessionRead(fmt.Sprintf("%s_%d", sid, i))
if err != nil {
t.Error(err)
}
}
if fp.SessionAll() != sessionCount {
t.Error()
}
}
func TestFileProvider_SessionRegenerate(t *testing.T) {
mutex.Lock()
defer mutex.Unlock()
os.RemoveAll(sessionPath)
defer os.RemoveAll(sessionPath)
fp := &FileProvider{}
_ = fp.SessionInit(180, sessionPath)
_, err := fp.SessionRead(sid)
if err != nil {
t.Error(err)
}
if !fp.SessionExist(sid) {
t.Error()
}
_, err = fp.SessionRegenerate(sid, sidNew)
if err != nil {
t.Error(err)
}
if fp.SessionExist(sid) {
t.Error()
}
if !fp.SessionExist(sidNew) {
t.Error()
}
}
func TestFileProvider_SessionDestroy(t *testing.T) {
mutex.Lock()
defer mutex.Unlock()
os.RemoveAll(sessionPath)
defer os.RemoveAll(sessionPath)
fp := &FileProvider{}
_ = fp.SessionInit(180, sessionPath)
_, err := fp.SessionRead(sid)
if err != nil {
t.Error(err)
}
if !fp.SessionExist(sid) {
t.Error()
}
err = fp.SessionDestroy(sid)
if err != nil {
t.Error(err)
}
if fp.SessionExist(sid) {
t.Error()
}
}
func TestFileProvider_SessionGC(t *testing.T) {
mutex.Lock()
defer mutex.Unlock()
os.RemoveAll(sessionPath)
defer os.RemoveAll(sessionPath)
fp := &FileProvider{}
_ = fp.SessionInit(1, sessionPath)
sessionCount := 412
for i := 1; i <= sessionCount; i++ {
_, err := fp.SessionRead(fmt.Sprintf("%s_%d", sid, i))
if err != nil {
t.Error(err)
}
}
time.Sleep(2 * time.Second)
fp.SessionGC()
if fp.SessionAll() != 0 {
t.Error()
}
}
func TestFileSessionStore_Set(t *testing.T) {
mutex.Lock()
defer mutex.Unlock()
os.RemoveAll(sessionPath)
defer os.RemoveAll(sessionPath)
fp := &FileProvider{}
_ = fp.SessionInit(180, sessionPath)
sessionCount := 100
s, _ := fp.SessionRead(sid)
for i := 1; i <= sessionCount; i++ {
err := s.Set(i, i)
if err != nil {
t.Error(err)
}
}
}
func TestFileSessionStore_Get(t *testing.T) {
mutex.Lock()
defer mutex.Unlock()
os.RemoveAll(sessionPath)
defer os.RemoveAll(sessionPath)
fp := &FileProvider{}
_ = fp.SessionInit(180, sessionPath)
sessionCount := 100
s, _ := fp.SessionRead(sid)
for i := 1; i <= sessionCount; i++ {
_ = s.Set(i, i)
v := s.Get(i)
if v.(int) != i {
t.Error()
}
}
}
func TestFileSessionStore_Delete(t *testing.T) {
mutex.Lock()
defer mutex.Unlock()
os.RemoveAll(sessionPath)
defer os.RemoveAll(sessionPath)
fp := &FileProvider{}
_ = fp.SessionInit(180, sessionPath)
s, _ := fp.SessionRead(sid)
s.Set("1", 1)
if s.Get("1") == nil {
t.Error()
}
s.Delete("1")
if s.Get("1") != nil {
t.Error()
}
}
func TestFileSessionStore_Flush(t *testing.T) {
mutex.Lock()
defer mutex.Unlock()
os.RemoveAll(sessionPath)
defer os.RemoveAll(sessionPath)
fp := &FileProvider{}
_ = fp.SessionInit(180, sessionPath)
sessionCount := 100
s, _ := fp.SessionRead(sid)
for i := 1; i <= sessionCount; i++ {
_ = s.Set(i, i)
}
_ = s.Flush()
for i := 1; i <= sessionCount; i++ {
if s.Get(i) != nil {
t.Error()
}
}
}
func TestFileSessionStore_SessionID(t *testing.T) {
mutex.Lock()
defer mutex.Unlock()
os.RemoveAll(sessionPath)
defer os.RemoveAll(sessionPath)
fp := &FileProvider{}
_ = fp.SessionInit(180, sessionPath)
sessionCount := 85
for i := 1; i <= sessionCount; i++ {
s, err := fp.SessionRead(fmt.Sprintf("%s_%d", sid, i))
if err != nil {
t.Error(err)
}
if s.SessionID() != fmt.Sprintf("%s_%d", sid, i) {
t.Error(err)
}
}
}
func TestFileSessionStore_SessionRelease(t *testing.T) {
mutex.Lock()
defer mutex.Unlock()
os.RemoveAll(sessionPath)
defer os.RemoveAll(sessionPath)
fp := &FileProvider{}
_ = fp.SessionInit(180, sessionPath)
filepder.savePath = sessionPath
sessionCount := 85
for i := 1; i <= sessionCount; i++ {
s, err := fp.SessionRead(fmt.Sprintf("%s_%d", sid, i))
if err != nil {
t.Error(err)
}
s.Set(i, i)
s.SessionRelease(nil)
}
for i := 1; i <= sessionCount; i++ {
s, err := fp.SessionRead(fmt.Sprintf("%s_%d", sid, i))
if err != nil {
t.Error(err)
}
if s.Get(i).(int) != i {
t.Error()
}
}
}

View File

@ -106,7 +106,6 @@ type ManagerConfig struct {
SessionNameInHTTPHeader string `json:"SessionNameInHTTPHeader"`
EnableSidInURLQuery bool `json:"EnableSidInURLQuery"`
SessionIDPrefix string `json:"sessionIDPrefix"`
CookieSameSite http.SameSite `json:"cookieSameSite"`
}
// Manager contains Provider and its configuration.
@ -233,7 +232,6 @@ func (manager *Manager) SessionStart(w http.ResponseWriter, r *http.Request) (se
HttpOnly: !manager.config.DisableHTTPOnly,
Secure: manager.isSecure(r),
Domain: manager.config.Domain,
SameSite: manager.config.CookieSameSite,
}
if manager.config.CookieLifeTime > 0 {
cookie.MaxAge = manager.config.CookieLifeTime
@ -273,9 +271,7 @@ func (manager *Manager) SessionDestroy(w http.ResponseWriter, r *http.Request) {
HttpOnly: !manager.config.DisableHTTPOnly,
Expires: expiration,
MaxAge: -1,
Domain: manager.config.Domain,
SameSite: manager.config.CookieSameSite,
}
Domain: manager.config.Domain}
http.SetCookie(w, cookie)
}
@ -295,36 +291,25 @@ func (manager *Manager) GC() {
}
// SessionRegenerateID Regenerate a session id for this SessionStore who's id is saving in http request.
func (manager *Manager) SessionRegenerateID(w http.ResponseWriter, r *http.Request) (Store, error) {
func (manager *Manager) SessionRegenerateID(w http.ResponseWriter, r *http.Request) (session Store) {
sid, err := manager.sessionID()
if err != nil {
return nil, err
return
}
var session Store
cookie, err := r.Cookie(manager.config.CookieName)
if err != nil || cookie.Value == "" {
// delete old cookie
session, err = manager.provider.SessionRead(sid)
if err != nil {
return nil, err
}
//delete old cookie
session, _ = manager.provider.SessionRead(sid)
cookie = &http.Cookie{Name: manager.config.CookieName,
Value: url.QueryEscape(sid),
Path: "/",
HttpOnly: !manager.config.DisableHTTPOnly,
Secure: manager.isSecure(r),
Domain: manager.config.Domain,
SameSite: manager.config.CookieSameSite,
}
} else {
oldsid, err := url.QueryUnescape(cookie.Value)
if err != nil {
return nil, err
}
session, err = manager.provider.SessionRegenerate(oldsid, sid)
if err != nil {
return nil, err
}
oldsid, _ := url.QueryUnescape(cookie.Value)
session, _ = manager.provider.SessionRegenerate(oldsid, sid)
cookie.Value = url.QueryEscape(sid)
cookie.HttpOnly = true
cookie.Path = "/"
@ -343,7 +328,7 @@ func (manager *Manager) SessionRegenerateID(w http.ResponseWriter, r *http.Reque
w.Header().Set(manager.config.SessionNameInHTTPHeader, sid)
}
return session, nil
return
}
// GetActiveSession Get all active sessions count number.

View File

@ -16,13 +16,12 @@ package beego
import (
"bytes"
"github.com/astaxie/beego/testdata"
"github.com/elazarl/go-bindata-assetfs"
"net/http"
"os"
"path/filepath"
"testing"
"github.com/astaxie/beego/testdata"
"github.com/elazarl/go-bindata-assetfs"
)
var header = `{{define "header"}}
@ -46,12 +45,8 @@ var block = `{{define "block"}}
<h1>Hello, blocks!</h1>
{{end}}`
func tmpDir(s string) string {
return filepath.Join(os.TempDir(), s)
}
func TestTemplate(t *testing.T) {
dir := tmpDir("TestTemplate")
dir := "_beeTmp"
files := []string{
"header.tpl",
"index.tpl",
@ -112,7 +107,7 @@ var user = `<!DOCTYPE html>
`
func TestRelativeTemplate(t *testing.T) {
dir := tmpDir("TestRelativeTemplate")
dir := "_beeTmp"
//Just add dir to known viewPaths
if err := AddViewPath(dir); err != nil {
@ -223,7 +218,7 @@ var output = `<!DOCTYPE html>
`
func TestTemplateLayout(t *testing.T) {
dir := tmpDir("TestTemplateLayout")
dir := "_beeTmp"
files := []string{
"add.tpl",
"layout_blog.tpl",

14
test.sh
View File

@ -1,14 +0,0 @@
#!/bin/bash
docker-compose -f test_docker_compose.yaml up -d
export ORM_DRIVER=mysql
export TZ=UTC
export ORM_SOURCE="beego:test@tcp(localhost:13306)/orm_test?charset=utf8"
go test ./...
# clear all container
docker-compose -f test_docker_compose.yaml down

View File

@ -1,39 +0,0 @@
version: "3.8"
services:
redis:
container_name: "beego-redis"
image: redis
environment:
- ALLOW_EMPTY_PASSWORD=yes
ports:
- "6379:6379"
mysql:
container_name: "beego-mysql"
image: mysql:5.7.30
ports:
- "13306:3306"
environment:
- MYSQL_ROOT_PASSWORD=1q2w3e
- MYSQL_DATABASE=orm_test
- MYSQL_USER=beego
- MYSQL_PASSWORD=test
postgresql:
container_name: "beego-postgresql"
image: bitnami/postgresql:latest
ports:
- "5432:5432"
environment:
- ALLOW_EMPTY_PASSWORD=yes
ssdb:
container_name: "beego-ssdb"
image: wendal/ssdb
ports:
- "8888:8888"
memcache:
container_name: "beego-memcache"
image: memcached
ports:
- "11211:11211"

3
testdata/bindata.go vendored
View File

@ -11,14 +11,13 @@ import (
"bytes"
"compress/gzip"
"fmt"
"github.com/elazarl/go-bindata-assetfs"
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
"time"
"github.com/elazarl/go-bindata-assetfs"
)
func bindataRead(data []byte, name string) ([]byte, error) {

View File

@ -341,7 +341,7 @@ func (t *Tree) match(treePattern string, pattern string, wildcardValues []string
if runObject == nil && len(t.fixrouters) > 0 {
// Filter the .json .xml .html extension
for _, str := range allowSuffixExt {
if strings.HasSuffix(seg, str) && strings.HasSuffix(treePattern, seg) {
if strings.HasSuffix(seg, str) {
for _, subTree := range t.fixrouters {
if subTree.prefix == seg[:len(seg)-len(str)] {
runObject = subTree.match(treePattern, pattern, wildcardValues, ctx)

View File

@ -213,7 +213,7 @@ func parseFunc(vfunc, key string, label string) (v ValidFunc, err error) {
return
}
tParams, err := trim(name, key+"."+name+"."+label, params)
tParams, err := trim(name, key+"."+ name + "." + label, params)
if err != nil {
return
}

View File

@ -16,14 +16,13 @@ package validation
import (
"fmt"
"github.com/astaxie/beego/logs"
"reflect"
"regexp"
"strings"
"sync"
"time"
"unicode/utf8"
"github.com/astaxie/beego/logs"
)
// CanSkipFuncs will skip valid if RequiredFirst is true and the struct field's value is empty