1
0
mirror of https://github.com/astaxie/beego.git synced 2025-07-17 12:02:17 +00:00

3288 Commits

Author SHA1 Message Date
Ming Deng
3b6d634f55 Merge pull request #4 from flycash/fix-bug-1.x
Fix BUG: /abc.html/aaa match /abc/aaa
2021-01-25 23:58:18 +08:00
Ming Deng
d0847e866e Fix BUG: /abc.html/aaa match /abc/aaa 2021-01-25 23:56:52 +08:00
Ming Deng
19e6ba8e7c Merge pull request #3 from flycash/develop-1
Remove duration from prometheus label
2020-12-26 21:56:49 +08:00
Ming Deng
5fddd26069 Remove duration from prometheus label 2020-12-26 21:54:57 +08:00
Ming Deng
89d4c9a3df Merge pull request #2 from flycash/develop-1
Fix generated code 4384
2020-12-26 21:32:13 +08:00
Ming Deng
db6af39bcd Using commentRouter.go as generated file name 2020-12-22 21:29:23 +08:00
Ming Deng
9418b243d0 Fix generated code 4384 2020-12-22 21:19:13 +08:00
Ming Deng
3d93903f9e Merge pull request #4324 from flycash/fix4321
Expose error from SessionRegenerateID
2020-11-26 18:06:40 +08:00
Ming Deng
2781f88173 Expose error from SessionRegenerateID 2020-11-25 21:13:04 +08:00
Ming Deng
cbbb6bfb08 Merge pull request #4284 from flycash/develop
Upgrade version
2020-11-03 22:49:59 +08:00
Ming Deng
b2a96234ab Upgrade version 2020-11-03 22:21:32 +08:00
Ming Deng
db3defa76a Merge pull request #4261 from flycash/reduceCache
make stmt cache smaller
2020-10-10 22:10:43 +08:00
Ming Deng
1dffa20435 make stmt cache smaller 2020-10-10 21:35:58 +08:00
Ming Deng
8e37fe3b78 Merge pull request #4251 from sc0Vu/fix-typo
Fix typo
2020-10-06 19:44:27 +08:00
sc0vu
91e18996bd Fix typo 2020-10-06 18:20:06 +08:00
Ming Deng
b8c1e133bf Merge pull request #4226 from vinicio/feature/same-site
session: adds CookieSameSite to ManagerConfig
2020-10-05 23:05:30 +08:00
Vinício Augusto
d66321fe4e session: adds CookieSameSite config to hooks.go#registerSession 2020-10-05 11:39:20 -03:00
Ming Deng
0b7ece44cf Merge pull request #4244 from AllenX2018/develop
testing: fix temporary create failed on Windows
2020-10-04 18:55:37 +08:00
Allen.M
6ffbc0a2b8 testing: fix temporary create failed on Windows
We are creating temporary files on the root directory of beego now
This PR using system temporary directory for testing.

Fixes #4243
2020-09-30 15:50:40 +08:00
Vinício Augusto
26208a53e6 session: adds CookieSameSite to ManagerConfig 2020-09-15 18:05:33 -03:00
Ming Deng
f6519b29a8 Merge pull request #4198 from CadenGuo/enhancement/orm_mysql_operator_consolidate
Enhancement/Add a new MySQL operator for strict case sensitive query
2020-09-01 21:33:41 +08:00
CadenGuo
91410be722 orm_test:use predefined variable to check db driver 2020-08-31 15:47:37 +00:00
CadenGuo
ff53e12191 skip strictexact operator test for db drivers other than mysql 2020-08-31 15:29:48 +00:00
CadenGuo
60bb057783 add a new mysql operator for force case sensitie query 2020-08-31 03:40:18 +00:00
CadenGuo
8736ffaf6f use 'BINARY' key word for exact operator for mysql db 2020-08-30 23:38:52 +08:00
Ming Deng
f946a35acd Merge pull request #4191 from mchtech/rawseter_fielder
fix issue #3776
2020-08-26 10:49:38 +08:00
michuan
9bd3a27e80 fix #3776 2020-08-25 23:36:15 +08:00
Ming Deng
310161f9d4 Merge pull request #4126 from flycash/fix/secureFlagV1
XSRF add secure and http only flag
2020-08-03 21:24:23 +08:00
Ming Deng
a0d1c42dac XSRF add secure and http only flag 2020-08-03 21:04:33 +08:00
Ming Deng
87b40ee9e7 Merge pull request #4116 from livelyRyan/patch-2
添加 BConfig.Listen.ClientAuth 字段及处理逻辑
2020-07-30 16:07:00 +08:00
Mr. Myy
7831638f37 移除多余的条件判断 2020-07-30 14:48:46 +08:00
Mr. Myy
5203804165 调整默认配置中的 ClientAuth 值,使之与原来的行为保持一致 2020-07-30 14:46:17 +08:00
Mr. Myy
0815e77f9a 修复笔误产生的拼写错误 2020-07-30 11:20:22 +08:00
Mr. Myy
c46ba86215 修复笔误产生的拼写错误 2020-07-30 11:18:14 +08:00
Mr. Myy
9d23e5a3fb 简化代码写法 2020-07-30 11:03:32 +08:00
Mr. Myy
513a4afff1 对 Listen 结构体增加 ClientAuth 字段
对 Listen 结构体增加 ClientAuth 字段,赋予默认配置对象该字段值为 tls.VerifyClientCertIfGiven,与原代码逻辑的默认值保持一致
2020-07-30 10:59:32 +08:00
Mr. Myy
15e11931fc 添加对 BConfig.Listen.ClientAuth 字段的逻辑处理。当指定了该配置时,使用配置的值来作为验证客户端的方式。如果没指定,使用默认值 tls.RequireAndVerifyClientCert 2020-07-30 10:53:30 +08:00
Ming Deng
7d561607d8 Merge pull request #4111 from liuhaogui/develop
添加配置文件路径环境变量
2020-07-30 09:14:12 +08:00
刘豪贵
15f04b8da4 add env BEEGO_CONFIG_PATH 2020-07-29 21:57:16 +08:00
Ming Deng
7a48fbb698 Merge pull request #4066 from playHing/self-dev
Fix concurrent issue of context/input Query method
2020-07-16 13:52:11 +08:00
playHing
3e2c795410 Rlock for form query 2020-07-15 20:44:59 +08:00
playHing
55e6298f29 Fix concurrent form parsing and getting 2020-07-15 20:44:59 +08:00
playHing
b50fb44950 Add bench test on context input query 2020-07-15 20:44:59 +08:00
Ming Deng
1c0714405a Merge pull request #4068 from jianzhiyao/fix_3898
fix `index out of range` when sid len = 1
2020-07-15 00:03:59 +08:00
jianzhiyao
678b90385b add log 2020-07-14 09:57:13 +08:00
jianzhiyao
5940ae33c2 fix index out of range when sid len = 1
add unit test for sess_file.go
2020-07-13 19:14:53 +08:00
Ming Deng
3db31385cf Merge pull request #4065 from Acmefocus/develop
update README.md
2020-07-11 23:16:36 +08:00
Acmefocus
2b9aaa5b0d update README.md
Signed-off-by: Acmefocus <107723772@qq.com>
2020-07-10 09:58:06 +08:00
Acmefocus
dced745d55 Merge branch 'develop' of https://github.com/Acmefocus/beego into develop 2020-07-09 18:15:25 +08:00
Acmefocus
25ba78ea72 update README.md
Signed-off-by: Acmefocus <107723772@qq.com>
2020-07-09 18:14:31 +08:00
Acmefocus
863b5bd0f4 Merge branch 'develop' of https://github.com/Acmefocus/beego into develop
Signed-off-by: Acmefocus <107723772@qq.com>
2020-07-09 17:59:07 +08:00
Acmefocus
ba3153621a Merge branch 'develop' of https://github.com/Acmefocus/beego into develop 2020-07-09 17:47:46 +08:00
Acmefocus
40cdc877b6 Update README.md
Signed-off-by: Acmefocus <107723772@qq.com>
2020-07-09 17:38:08 +08:00
Acmefocus
76debb1899 Update README.md 2020-07-09 17:18:01 +08:00
Ming Deng
35dcc3df7c Merge pull request #4058 from a631807682/fix/issues/4054
Fix response payload too large
2020-07-09 16:41:11 +08:00
Chenrui
c3f14a0ad6 refactor: log error when payload too large 2020-07-09 09:45:40 +08:00
Ming Deng
8ee167bc7b Merge pull request #4051 from gmelodie/sleep-on-reconnect-3972
Add sleep on reconnect
2020-07-09 09:41:04 +08:00
Cathal
2eccb23461 Add sleep on reconnect functionality 2020-07-08 17:30:34 +01:00
Ming Deng
28d3f624a3 Merge pull request #4055 from tayoogunbiyi/develop
Allow Healthcheck endpoint return JSON for Kubernetes
2020-07-08 23:51:03 +08:00
Ming Deng
926b80d1d8 Merge pull request #4061 from flycash/race-condition
Fix 4059
2020-07-08 23:49:54 +08:00
Ming Deng
c08b27111c Fix 4059 2020-07-08 23:32:18 +08:00
Chenrui
03f78b2e4a fix: add error code support 2020-07-08 18:09:01 +08:00
Chenrui
946a42c021 fix: response http 413 when body size larger then MaxMemory. 2020-07-08 17:14:52 +08:00
Eyitayo Ogunbiyi
d7b0d55357 added extra check for same response lengths 2020-07-07 17:23:52 +01:00
Eyitayo Ogunbiyi
728bf34006 refacted cache health check from toolbox 2020-07-07 16:46:59 +01:00
Eyitayo Ogunbiyi
e0f8c6832d added test for buildingHealthCheckResponse 2020-07-07 16:28:16 +01:00
Eyitayo Ogunbiyi
469dc7bea9 refactored the building of healthcheck response map 2020-07-07 16:09:22 +01:00
Eyitayo Ogunbiyi
ca0c64b69e refactored tests for health check endpoint 2020-07-07 15:21:38 +01:00
Eyitayo Ogunbiyi
5a4a082af0 renamed functions for clarity 2020-07-07 14:54:21 +01:00
Ming Deng
9dc660c1da Merge pull request #4056 from gmelodie/reconn-bug-3971
Fix reconnection bug in logs/conn.go
2020-07-07 20:25:44 +08:00
Gabriel Cruz
d8724cb122 Add error returning to writeln 2020-07-06 21:38:47 +02:00
Gabriel Cruz
fc56c562db Fix logger reconnection 2020-07-06 21:38:47 +02:00
Eyitayo Ogunbiyi
8d1a9bc92e added tests for health check endpoints 2020-07-06 19:34:48 +01:00
Eyitayo Ogunbiyi
db547a7c84 added test for execJson 2020-07-06 16:04:29 +01:00
Eyitayo Ogunbiyi
7c575585e9 added conditional json flag when trying to view healthchecks 2020-07-06 15:27:12 +01:00
Ming Deng
289f86247e Merge pull request #4053 from flycash/ftr/test-docker
Add docker-compose to support running unit test locally
2020-07-05 22:08:20 +08:00
Ming Deng
ca9b21bb30 Add docker-compose to support running test 2020-07-04 13:42:20 +00:00
Ming Deng
d6ef33feee Merge pull request #4045 from flycash/preprare-1.12.2
Remove tidb dependency
2020-06-30 23:16:41 +08:00
Ming Deng
2f5ed5b433 Remove tidb dependency 2020-06-30 21:04:37 +08:00
Ming Deng
9c18dbe7dc Merge pull request #4044 from flycash/upgrade_version
upgrade version
2020-06-30 20:58:14 +08:00
Ming Deng
01219944a4 upgrade version 2020-06-30 20:55:31 +08:00
Ming Deng
4fac6ceb3f Merge pull request #4039 from flycash/fixbug
Fix ES bug
2020-06-30 13:18:13 +08:00
Ming Deng
1c4085e7ea Update es.go 2020-06-30 10:12:10 +08:00
Ming Deng
2117562113 Update es.go 2020-06-30 10:09:36 +08:00
Ming Deng
1f9da8d75b Fix ES bug 2020-06-29 22:25:22 +08:00
Ming Deng
9dea9f9ae7 Merge pull request #3994 from HarryWang29/develop
update support bit operation
2020-06-29 20:27:36 +08:00
harry890829
0f6735e20d Merge branch 'develop' of https://github.com/astaxie/beego into develop
 Conflicts:
	go.mod
	go.sum
2020-06-29 16:48:03 +08:00
Ming Deng
ad68e8d866 Merge pull request #4033 from jianzhiyao/develop
make redis client idle timeout configurable
2020-06-28 23:14:28 +08:00
Ming Deng
26beef756f Merge pull request #4038 from flycash/fixbug
Fix ES index problem
2020-06-28 23:14:07 +08:00
jianzhiyao
5c9cc805a1 make redis client idle timeout configurable 2020-06-28 22:20:46 +08:00
Ming Deng
de51bd28d7 Fix ES index problem 2020-06-28 21:12:12 +08:00
Ming Deng
6b6a0e8a56 Merge pull request #4032 from jianzhiyao/develop
fix strings.Repeat panic
2020-06-26 17:51:47 +08:00
Ming Deng
8039cc8e59 Merge pull request #4017 from guhan121/fix#4000
Prohibit multiple calls SetDefaultMessage.
2020-06-26 17:49:36 +08:00
jianzhiyao
b88b7d2899 fix strings.Repeat panic 2020-06-25 23:48:07 +08:00
qiantao
e725192072 fix #4000 2020-06-25 22:11:32 +08:00
Ming Deng
469f2c226d Merge pull request #3998 from guhan121/go_modules_route_compatibility
for go modules, generate route by `GO111MODULE=on`
2020-06-25 20:30:27 +08:00
Ming Deng
828b20163d Merge pull request #4029 from flycash/feature/buildInfo
Add build info for prometheus
2020-06-25 18:37:11 +08:00
Ming Deng
9c5eab4834 Add build info for prometheus 2020-06-25 17:44:40 +08:00
Ming Deng
1813d414ae Merge pull request #4027 from flycash/develop
Move many PR's change here since the original authors are responseless
2020-06-25 02:17:49 +08:00
Ming Deng
6052524a28 Merge pull request #4028 from jianzhiyao/develop
acquire() in Lock
2020-06-23 23:58:42 +08:00
Ming Deng
3ce68d6a30 Move many PR's change here since the original authors are responseless 2020-06-23 23:14:51 +08:00
jianzhiyao
89420eacd0 go destroy 2020-06-23 23:05:58 +08:00
jianzhiyao
6d9862b924 acquire() in Lock 2020-06-23 22:29:41 +08:00
Ming Deng
96658121dc Merge pull request #3818 from dbt4516/develop
Get the real location of the log directory before using filepath.Walk function when remove old logs
2020-06-23 21:17:14 +08:00
Ming Deng
43a3623f51 Merge pull request #3803 from yinggaozhen/fix-statistics
GetMapData change to read lock
2020-06-23 21:08:32 +08:00
Ming Deng
089dfbdbee Merge pull request #4016 from huija/develop
Update redis.go
2020-06-23 20:41:42 +08:00
Ming Deng
526a5463d6 Merge pull request #4025 from jianzhiyao/develop
Fix: Too Many Prepare Statement
2020-06-23 20:33:04 +08:00
jianzhiyao
a28d294a83 upgrade acquire method return *sql.Stmt 2020-06-23 13:46:19 +08:00
huija
f70fd5babf add comments on Scan func 2020-06-23 12:32:26 +08:00
qiantao
a764e17fbf check ci 2020-06-23 10:43:51 +08:00
Ming Deng
f5c580a403 Merge pull request #3739 from nuczzz/develop
fix graceful bug: old process didn't exist when graceful restart
2020-06-23 00:10:53 +08:00
Ming Deng
7210dc24b6 Merge pull request #3743 from Colstuwjx/fix/orm-end-printstack
Fix/orm end printstack
2020-06-22 23:59:16 +08:00
Ming Deng
1060dc7df8 Merge pull request #4026 from flycash/develop
fix UT
2020-06-22 23:36:25 +08:00
Ming Deng
3ab1e48217 fix UT 2020-06-22 23:24:15 +08:00
jianzhiyao
a5e8344a0a add stmt garbage recycle 2020-06-22 23:23:52 +08:00
Ming Deng
e1386c448c Merge pull request #4022 from jianzhiyao/develop
stmt: fix bug of non concurrent security & add double check
2020-06-21 18:01:14 +08:00
askuy
6e4d0917b2 Merge pull request #4023 from flycash/feature/prometheus
Change prometheus patter
2020-06-21 17:39:02 +08:00
Ming Deng
9b43a90138 Change prometheus patter 2020-06-21 17:36:13 +08:00
askuy
b7833fb297 Merge pull request #4021 from flycash/feature/prometheus
Add prometheus support
2020-06-21 17:11:00 +08:00
Ming Deng
16b81d09a7 Add prometheus support 2020-06-21 17:10:34 +08:00
Ming Deng
0056b92d0b Merge pull request #4007 from flycash/fix3949
Store RouterPattern before filter execute
2020-06-21 17:05:04 +08:00
jianzhiyao
decc75e025 fix bug of non concurrent security & add double check 2020-06-21 16:25:32 +08:00
huija
f2bae3e367 add UT for Scan function 2020-06-19 22:55:40 +08:00
askuy
6eeea141d8 Merge pull request #4018 from flycash/fix/xss
Using HTMLEscapeString in adminui.go to avoid XSS attack
2020-06-19 22:21:51 +08:00
Ming Deng
6c0db4db3d Using HTMLEscapeString in adminui.go to avoid XSS attack 2020-06-19 21:49:17 +08:00
Ming Deng
b9fbcbd906 Merge pull request #4014 from jianzhiyao/develop
over size file do not run openFile
2020-06-19 20:19:16 +08:00
huija
40181c1042 Update redis.go
use `scan` instead of `keys`
2020-06-19 14:21:12 +08:00
qiantao
3879fd9c34 修改测试用例 2020-06-18 17:25:48 +08:00
qiantao
af238ee047 Merge remote-tracking branch 'origin/develop' into go_modules_route_compatibility
# Conflicts:
#	go.mod
#	go.sum
2020-06-18 16:41:03 +08:00
Ming Deng
86935ada01 Merge pull request #3943 from zhlicen/master
#3942 fix encoded url(with slash) router match problem
2020-06-18 16:04:16 +08:00
jianzhiyao
8160059182 big size file lead to memory leak 2020-06-16 14:56:58 +08:00
harry890829
dc70e9fc47 update go test 2020-06-15 18:16:40 +08:00
Ming Deng
bac2b31afe Merge pull request #3975 from nicowaisman/patch-2
Change permission mask
2020-06-13 23:40:13 +08:00
harry890829
a134cb8d17 update go test 2020-06-11 23:45:06 +08:00
Ming Deng
4ad699b7b8 Merge pull request #3981 from zwei0526/develop
Update parser.go
2020-06-10 16:38:15 +08:00
Ming Deng
14fc935cb6 Merge pull request #4005 from keminar/develop
fix graceful bug
2020-06-10 16:34:32 +08:00
harry890829
d9f262e277 update go test 2020-06-10 12:31:38 +08:00
harry890829
131748bb3d update go.mod&go.sum 2020-06-10 11:34:58 +08:00
harry890829
2c3c66ccea Merge remote-tracking branch 'origin/develop' into develop 2020-06-10 11:16:17 +08:00
harry890829
71cb1379b4 update support bit operation 2020-06-10 11:15:23 +08:00
harry890829
b351f02525 Merge branch 'develop' of https://github.com/astaxie/beego into develop
 Conflicts:
	go.sum
2020-06-10 11:05:57 +08:00
liminggui
8e29300f85 fix graceful bug 2020-06-09 12:20:08 +08:00
flycash
5f31bf45d4 Fix #3949 : store RouterPattern before filter execute so that filter can use the pattern 2020-06-07 23:16:26 +08:00
askuy
3e30f37172 Merge pull request #4006 from flycash/develop
fix CI and UT
2020-06-06 21:16:08 +08:00
flycash
ce4ce74c8d Fix validation test 2020-06-06 20:50:48 +08:00
flycash
ce0e7525ad Fix ES client 2020-06-06 20:14:01 +08:00
flycash
d0b7244d57 Fix ledis 2020-06-06 19:21:57 +08:00
Ming Deng
5100a8c396 fix CI and UT 2020-06-06 18:16:36 +08:00
Ming Deng
b8efb3ef45 Merge pull request #3984 from jianzhiyao/develop
fix bug:static can not real hit cache & memory leak
2020-06-06 13:10:58 +08:00
Ming Deng
ae15b54f83 Merge pull request #3992 from maxshine/fix-3991
[Fix-Issue-3991] Fix Read with SQLite not supporting SELECT FOR UPDAT…
2020-06-06 13:10:08 +08:00
Ming Deng
0dab959c95 Merge pull request #4004 from gokangaroo/develop
avoid `panic: send on closed channel` after closing logger.
2020-06-06 13:09:36 +08:00
Ming Deng
ee615dd08f Merge pull request #3985 from leapsea/develop
修复多线程下数据库连接异常问题
2020-06-06 12:40:50 +08:00
huija
b879a07b3a avoid panic: send on closed channel after closing logger. 2020-06-04 14:52:54 +08:00
jianzhiyao
c265f6e49c add comment 2020-06-02 20:02:58 +08:00
jianzhiyao
690e91e1b6 static file module:make cache file size and cache file numbers configurable 2020-06-02 18:22:47 +08:00
jianzhiyao
50f71a8a21 fix bug of getting int error 2020-06-02 18:10:17 +08:00
Yang, Gao
677d010d86 [Fix-Issue-3991] Add warn for SQLite Read is invoked isForUpdate=true 2020-06-01 23:12:12 +08:00
Ming Deng
db2a1134ce Merge pull request #3993 from skanger/develop
fix httplib PostFile method
2020-06-01 22:05:01 +08:00
qiantao
c2771397be delete vendor 2020-06-01 15:06:49 +08:00
qiantao
70733d9810 fix label == `` #4001 2020-06-01 15:06:33 +08:00
Ming Deng
11740cede6 Merge pull request #3996 from bharrat/3995-fix-middleware-not-working-with-graceful
Fixes #3995 Use handlers with middleware when starting Graceful server
2020-05-31 22:23:05 +08:00
qiantao
4ffe26a1d2 for go modules, generate route by GO111MODULE=on 2020-05-22 11:35:45 +08:00
Bharat Patel
075db4773b Fixes #3995 Use handlers with middleware when starting Graceful server 2020-05-18 10:00:14 -07:00
harry890829
2fd9dfca7b update support bit operation 2020-05-18 19:18:35 +08:00
skanger
eea20f6ceb fix httplib PostFile method 2020-05-16 11:00:15 +08:00
Yang, Gao
8055357576 [Fix-Issue-3991] Fix Read with SQLite not supporting SELECT FOR UPDATE syntax 2020-05-15 17:36:01 +08:00
jianzhiyao
9fda81b7f3 modify static cache total size about 100m 2020-05-09 18:24:14 +08:00
jianzhiyao
4b12e053b7 fix 2020-05-09 17:58:10 +08:00
jianzhiyao
0307c8b110 set static file cahce limit:file size & file count 2020-05-09 17:57:00 +08:00
leapsea
867f83de34 修复数据库连接异常问题 2020-05-09 16:31:30 +08:00
jianzhiyao
af19822293 not modify go.mod 2020-05-09 14:06:51 +08:00
jianzhiyao
2449aad105 add cache-hit test example 2020-05-09 10:44:37 +08:00
jianzhiyao
d31975a752 complete test example 2020-05-08 17:35:02 +08:00
jianzhiyao
b28d5e2716 fix bug:static canot real hit cache
opt:reduce risk of memory leak with lru cache
2020-05-08 17:10:19 +08:00
zwei0526
ab33d683ea Update parser.go
修复genRouterCode方法解析  router 注释(// @router) 单双引号引起的bug
2020-04-26 19:26:10 +08:00
Nico Waisman
f99cbe0fa4 Change permission mask 2020-04-22 08:42:54 -07:00
HANG ZHOU
0aa82d875a Update input.go 2020-03-05 14:46:17 +00:00
astaxie
8f3d1c5f42 Merge pull request #3922 from BurtonQin/bug-1-2-3-inconsistent-field-protection
cache, context, session: add lock to fix inconsistent field protection
2020-02-22 15:09:25 +08:00
astaxie
2410b364af Merge pull request #3923 from timchenxiaoyu/develop
fix exist typo
2020-02-22 11:25:13 +08:00
陈晓宇
713503e43d fix exist typo 2020-02-14 16:47:47 +08:00
BurtonQin
cfdd1cd5be cache, context, session: add lock to fix inconsistent field protection 2020-02-10 21:49:46 +08:00
astaxie
de5650b723 version 1.12.1 2020-02-07 16:23:57 +08:00
astaxie
e5e4a3bea7 Merge pull request #3868 from holtyuzhuyanbo/fix_session_destory
fix: session destory
2020-02-07 11:49:54 +08:00
astaxie
90d0b43f34 Merge pull request #3888 from gavin2014/develop
[Fix] Fix create table with SQLite not supporting COMMENT syntax
2020-02-07 11:46:52 +08:00
astaxie
1b7f5ba2c4 Merge pull request #3900 from aixiaoxiang/develop
httplib:fixes network request failed to create an invalid file and automatically created file directory
2020-02-07 11:10:56 +08:00
astaxie
96f01079cb Merge pull request #3905 from ywk253100/200110_context
Send the request from context rather than the original one to handlers
2020-02-07 11:05:01 +08:00
astaxie
9d4b5b313f Merge pull request #3911 from liuzhang/develop
验证调整,增加label, xx不能为空
2020-02-07 11:04:11 +08:00
astaxie
b882009979 Merge pull request #3919 from wy65701436/develop-sha256
update hash algorithm for signing the cookie for xsrf token
2020-02-07 11:01:10 +08:00
wang yan
a768bf8f00 update hash algorithm for signing the cookie for xsrf token
Due to the chosen-prefix collision in SHA-1(details at https://sha-mbles.github.io/), SHA-1 hash functions should to be deprecated and SHA-2/SHA-3 should be used instead.

Signed-off-by: wang yan <wangyan@vmware.com>
2020-02-06 17:31:24 +08:00
Liu Zhang
034599ca1d 验证调整,增加label, xx不能为空 2020-01-17 16:47:19 +08:00
Wenkai Yin
5a02c556b2 Send the request from context rather than the original one to handlers
The filters may do some changes to the request, such as putting values in the request's context

Signed-off-by: Wenkai Yin <yinw@vmware.com>
2020-01-10 17:58:00 +08:00
axx
dc5c42e981 httplib:fixes network request failed to create an invalid file and automatically created file directory 2019-12-30 11:24:55 +08:00
大盖文
92a4119258 Update cmd_utils.go
[Fix] Fix create table with SQLite not supporting COMMENT syntax
2019-12-11 16:50:08 +08:00
astaxie
aa90c67a75 Merge pull request #3867 from ywk253100/191119_xsrf
Abort with the pre-defined status code when handling XSRF error
2019-11-29 18:43:02 +08:00
holtyuzhuyanbo
38a144c68f fix: session destory 2019-11-19 21:25:30 +08:00
Wenkai Yin
793047097c Abort with the pre-defined status code when handling XSRF error
As the status codes(422 and 417) are set in the error map, abort with them directly to active the pre-defined error handlers

Signed-off-by: Wenkai Yin <yinw@vmware.com>
2019-11-19 18:55:54 +08:00
astaxie
1923b8c767 Merge pull request #3841 from HKail/develop
添加16开头手机号验证
2019-10-23 22:22:52 +08:00
Allen
fb640f0075 更新16开头手机号的正则测试 2019-10-22 17:07:22 +08:00
Allen
241f10b429 添加16开头手机号验证,162电信,165移动,166/167联通。 2019-10-22 16:58:05 +08:00
Allen
b8d626bbea 添加16开头手机号验证,162电信,165移动,166/167联通。 2019-10-22 16:28:19 +08:00
astaxie
2a6ceca861 Update README.md 2019-10-10 11:23:19 +08:00
astaxie
10236b9f2d Merge pull request #3814 from cloudzhou/patch-2
leak opened file
2019-10-10 00:48:24 +08:00
dbt4516
b3ae5d4ac6 Update file.go
According to issue#4759 (https://github.com/golang/go/issues/4759) filepath.Walk function in golang cannot handle symbolic path, meanwhile symbolic path for log directory is pretty common used. In such scenario this deleteOldLog function will fail without any error log. Get the real location of the log directory before using walk function can fix this.
2019-10-09 15:53:22 +08:00
wanghz
77fc8e4e38 According to issue#4759 (https://github.com/golang/go/issues/4759) filepath.Walk function in golang cannot handle symbolic path, meanwhile symbolic path for log directory is pretty common used. In such scenario this deleteOldLog function will fail without any error log. Get the real location of the log directory before using walk function can fix this. 2019-10-09 15:33:38 +08:00
cloudzhou
5a5482c77f leak opened file
should defer file.Close()
2019-09-27 19:27:44 +08:00
astaxie
11774c87a5 update version 1.13 2019-09-19 00:19:33 +08:00
didi
6d47b4a2e0 GetMapData change to read lock 2019-09-09 17:44:10 +08:00
Dennis
8395a26061 Merge pull request #3801 from DennisMao/develop
fix annotation on orm/utils #3777
2019-09-09 00:46:36 +08:00
Razil
4348356d0a fix annotation on orm/utils 2019-09-09 00:47:20 +08:00
colstuwjx
b551949a2b Add PrintStack() while orm abnormally exit. 2019-07-31 14:08:58 +08:00
nuczzz
32cd76396d fix graceful bug 2019-07-27 18:54:13 +08:00
astaxie
5620608418 Update README.md 2019-07-21 22:58:28 +08:00
astaxie
32ee728078 Merge pull request #3586 from astaxie/develop
V1.12.0
2019-07-05 12:26:39 +08:00
astaxie
de7ce2f9b0 v1.12.0 2019-07-05 11:58:41 +08:00
astaxie
d6c2a9fd4b Merge pull request #3703 from jkylin/develop
email的Attach和AttachFile 的参数检查逻辑有误。len(args) < 1 && len(args) > 2 改为 l…
2019-07-05 11:35:47 +08:00
astaxie
582a4fa34b Merge pull request #3699 from orgmatileg/develop
router.go: add comment func LogAccess
2019-07-05 11:34:59 +08:00
astaxie
99647986de Merge pull request #3689 from GeorgeXc/addStmt
Add stmt
2019-07-05 11:34:40 +08:00
BaoyangChai
5bcde306ea Revert "update"
This reverts commit 2909ff3366.
2019-06-28 23:37:32 +08:00
BaoyangChai
2909ff3366 update 2019-06-28 23:23:01 +08:00
BaoyangChai
40078cba2c update 2019-06-28 23:13:18 +08:00
BaoyangChai
5d0c0a03d7 update 2019-06-28 22:56:32 +08:00
hsht
8cfd7f5c19 email的Attach和AttachFile 的参数检查逻辑有误。len(args) < 1 && len(args) > 2 改为 len(args) < 1 || len(args) > 2 2019-06-28 20:09:23 +08:00
Luqmanul Hakim
62d96c2e93 router.go: add comment func LogAccess 2019-06-25 08:04:21 +07:00
astaxie
e844058aed Merge pull request #3632 from Wusuluren/develop
fix concurrent map access problem on BeegoInput.data
2019-06-18 12:09:34 +08:00
astaxie
1eab6bb32a Merge pull request #3669 from xfwduke/develop
fix bugs of ParseForm about time in RFC3339 format
2019-06-18 12:08:55 +08:00
astaxie
c265d32c36 Merge pull request #3685 from Anderson-Lu/fix_orm_datarace
fix orm datarace
2019-06-18 12:05:54 +08:00
BaoyangChai
06692c3e27 update 2019-06-17 23:38:07 +08:00
luxueyan
394a73c75f fix orm datarace 2019-06-14 14:43:02 +08:00
Wusuluren
cbcde8bd1f Merge branch 'develop' of https://github.com/Wusuluren/beego into develop 2019-06-09 22:10:22 +08:00
Wusuluren
b17e49e6aa fix concurrent map access problem on BeegoInput.data 2019-06-09 22:09:38 +08:00
BaoyangChai
873f62edff update 2019-06-09 01:19:17 +08:00
BaoyangChai
cc0eacbe02 update 2019-06-08 23:53:42 +08:00
oberontang
649c5c861d fix bugs of ParseForm about time in RFC3339 format 2019-05-31 15:52:19 +08:00
Faissal Elamraoui
206a7ed1fc Merge pull request #3662 from npu21/develop
fix typos
2019-05-27 11:07:52 +02:00
张勇
3c046a4dbf fix two typos 2019-05-27 16:38:30 +08:00
astaxie
f2be6af2ca Merge pull request #3658 from priyesh-lb/patch-1
Beego skipping some migrations
2019-05-18 09:38:09 +08:00
astaxie
804b9769e0 Merge pull request #3642 from GeorgeXc/fixBatchUpdate
Fix BatchUpdate not update the auto_now field
2019-05-18 09:28:22 +08:00
astaxie
585df01899 Merge pull request #3635 from edwardhey/develop
Incr和Decr应该改成排它锁,否则在并发的时候会出现非期望的结果值
2019-05-18 09:27:38 +08:00
astaxie
1a529c061c Merge pull request #3633 from MarxGo/develop
fix:utils.GetGOPATHs() when go version equal or after go1.10
2019-05-18 09:27:08 +08:00
Priyesh
fcacfc08e3 Beego skipping some migrations
Beego skipping some migrations #3657
2019-05-17 16:19:26 +05:30
BaoyangChai
a0ca3d61d6 update 2019-05-08 23:11:57 +08:00
Edward.Yang
39bd40e512 Incr和Decr应该改成排它锁,否则在并发的时候会出现非期望的结果值 2019-05-01 13:10:21 +08:00
Guo
8748de95c7 fix:utils.GetGOPATHs() when go version equal or after go1.10 func does not return defaultGoPATH() 2019-04-30 06:43:25 +08:00
Wusuluren
0939e8e493 fix concurrent map access problem on BeegoInput.data 2019-04-30 00:15:24 +08:00
hwave
6a33feee46 Merge pull request #1 from astaxie/develop
update
2019-04-29 23:19:27 +08:00
astaxie
58b2ac702c Merge pull request #3623 from Martinho0330/develop
make routers configurable for beego multi-instance in the same repo
2019-04-29 18:19:22 +08:00
astaxie
175714f69a Merge pull request #3627 from haleyly/develop
route request put amendment
2019-04-29 18:18:19 +08:00
haley
d5b70118a3 Merge branch 'develop' of https://github.com/haleyLy/beego into dev 2019-04-28 08:51:34 +08:00
haley
a9629f707e route request put amendment 2019-04-28 08:50:30 +08:00
astaxie
6123c72752 Merge pull request #3621 from guanle/guanle-patch-1
Update templatefunc.go  for default value tag
2019-04-27 23:28:35 +08:00
astaxie
56afa5c2bf Merge pull request #3625 from hsluoyz/develop
remove the 1000-row limit for ORM result set
2019-04-27 23:27:58 +08:00
astaxie
0c576dac82 Merge pull request #3599 from Wusuluren/cache_file
fix bug on cache/file
2019-04-27 23:27:27 +08:00
astaxie
8462372c03 Merge pull request #3598 from Wusuluren/develop
fix race problem on toolbox/task
2019-04-27 23:26:29 +08:00
astaxie
20ff97d53d Merge pull request #3595 from JessonChan/log_revet
Log revet
2019-04-27 23:26:06 +08:00
astaxie
8ce5b6cc52 Merge pull request #3593 from JessonChan/trace_method
Trace method
2019-04-27 23:25:44 +08:00
Yang Luo
afb787d49d remove the 1000-row limit for ORM result set 2019-04-27 16:58:00 +08:00
hetingyao
0b165b78a1 make routers configurable for beego multi-instance in the same repo 2019-04-22 22:18:37 +08:00
guanle
fa97488bdc Update templatefunc.go 2019-04-21 10:27:35 +08:00
astaxie
3086081ec0 v1.11.2 2019-04-06 13:50:14 +08:00
Wusuluren
dfab44c24a fix bug on cache/file 2019-04-05 22:32:28 +08:00
Wusuluren
1900246054 fix bug on cache/file 2019-04-05 22:17:56 +08:00
Wusuluren
e980f92c63 fix race problem on toolbox/task 2019-04-05 20:28:24 +08:00
JessonChan
ce3800e3ef // Deprecated: use github.com/astaxie/beego/logs instead. 2019-04-03 14:13:38 +08:00
JessonChan
e3d668f450 revet to log.go
https://github.com/astaxie/beego/issues/3591
https://github.com/astaxie/beego/issues/3588
2019-04-03 14:08:42 +08:00
JessonChan
75b4bc5896 it's no need to override Trace method. 2019-04-03 10:19:09 +08:00
astaxie
c0ecf32d17 update travis 2019-04-02 21:53:01 +08:00
JessonChan
3155f07ccd no need to override Trace method. 2019-03-27 13:43:27 +08:00
JessonChan
02bead5097 handle trace request must NOT CACHE
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Cache-Control
2019-03-27 13:40:34 +08:00
JessonChan
e8b29c9fd1 handle trace request 2019-03-27 13:34:46 +08:00
astaxie
610f27d684 Merge pull request #3530 from GeorgeXc/develop
[orm] add ignore auto_now_add field when update
2019-03-27 00:14:07 +08:00
astaxie
59466f6678 Merge pull request #3554 from grahamjamesaddis/travis-ci-build
Allow forked beego project to pass travis ci builds
2019-03-26 19:24:06 +08:00
astaxie
3ddd8f860e Merge pull request #3561 from JessonChan/develop
refactor color logger
2019-03-26 19:23:14 +08:00
astaxie
8535ec0819 Merge pull request #3567 from bsdelf/feature/ensure-custom-error-handler
Ensure custom error handler is called
2019-03-26 19:22:54 +08:00
astaxie
f294121ab7 Merge pull request #3583 from maxshine/develop
[Fix] Fix the issue that genRouterCode results in @Import annotations getting overwritten
2019-03-26 19:13:44 +08:00
GeorgeXc
0b8ebaf387 Update db.go 2019-03-26 01:00:04 +08:00
Yang, Gao
3b00cfccec [Fix] Fix the issue that genRouterCode incorrect logic results in @Import annotations getting overwritten 2019-03-24 14:41:28 +08:00
BaoyangChai
005391be81 update 2019-03-23 00:33:26 +08:00
Faissal Elamraoui
bc8fffe347 Merge pull request #3571 from dxas90/patch-1
Fixes #3570
2019-03-14 19:16:15 +01:00
Daniel Ramirez Grave de Peralta
914bbfd710 Update apiauth.go fixed infinite recursive call 2019-03-14 09:14:12 -04:00
Yanhui Shen
be31bd2bbd Ensure custom error handler is called 2019-03-13 16:24:04 +08:00
JessonChan
95ff817019 undefined: beego.BeeLogger fixed 2019-03-13 09:41:13 +08:00
JessonChan
ea91e7638c move log function to log package 2019-03-12 17:01:23 +08:00
JessonChan
4564e9810c logger_test imported and not used: "bytes" 2019-03-12 16:36:00 +08:00
JessonChan
44a1a8f6be println is builtin function 2019-03-12 15:51:43 +08:00
JessonChan
9cecb22170 NewAnsiColorWriter remove 2019-03-12 15:13:54 +08:00
JessonChan
7693502aaa logAdapter is more readable 2019-03-12 13:20:13 +08:00
JessonChan
c0fae547e9 remove ansicolor code,import ansicolor package 2019-03-12 12:14:09 +08:00
JessonChan
0ba77a0d87 colorful is the switch to level label 2019-03-12 12:12:59 +08:00
JessonChan
661dcbb6ca router logger modify 2019-03-12 12:11:25 +08:00
JessonChan
578440a18d add ansicolor to beego 2019-03-12 12:09:41 +08:00
JessonChan
93485df3d2 color should be false by default otherwise the http logger's color would be wrong 2019-03-08 14:42:06 +08:00
JessonChan
121fab61f1 ResetColor function 2019-03-08 12:18:45 +08:00
JessonChan
915eec7943 Merge branch 'develop' of github.com:astaxie/beego into develop 2019-03-08 12:16:00 +08:00
JessonChan
8432a1c758 better comment for color map 2019-03-08 12:10:57 +08:00
JessonChan
4a5e108527 logger color function refactor,easy to read and run more quickly 2019-03-08 11:50:30 +08:00
JessonChan
6dd5171fdf logger color function refactor,easy to read and run more quickly 2019-03-08 11:08:39 +08:00
astaxie
c2b6cb5c3a Merge pull request #3560 from JessonChan/develop
TestToJson bug fixed
2019-03-08 00:18:39 +08:00
JessonChan
1f93040af6 Merge remote-tracking branch 'upstream/develop' into develop 2019-03-07 18:07:37 +08:00
JessonChan
52f8ccd06c TestToJson bug fixed 2019-03-07 17:15:30 +08:00
astaxie
3b86feab8a Merge pull request #3555 from hellomrleeus/develop
spelling mistake of word "Header"
2019-03-06 09:58:54 +08:00
hellomrlee
aba51d99a1 spelling mistake of word "Header" 2019-03-04 11:05:29 +08:00
grahamjamesaddis
8454e8417e Allow forked beego project to pass travis ci builds 2019-03-01 14:00:20 +00:00
astaxie
422e8285b5 Merge pull request #3494 from nuczzz/develop
simplify beego grace with http.Shutdown
2019-02-26 16:31:40 +08:00
astaxie
bb6ca6b100 Merge pull request #3522 from saromanov/check-input-data
SessionRead: check of the length for input sid variable
2019-02-25 23:17:57 +08:00
astaxie
1483c1f545 Merge pull request #3524 from Quasilyte/quasilyte/bytesreader
config/yaml: s/bytes.NewBuffer/bytes.NewReader/
2019-02-25 23:16:39 +08:00
astaxie
3d6a68de77 Merge pull request #3535 from gadelkareem/develop
Make LogAccess() function public
2019-02-25 23:11:14 +08:00
astaxie
387d387080 Merge pull request #3547 from snedzad/patch-1
Register .gohtml extension
2019-02-25 11:43:37 +08:00
Nedzad Smajic
94ed35e781 Register .gohtml extension
Goland as of 2018.3 seems to support only '.tpl.gohtml" and ".gohtml" templates. The regular ".tpl" templates will be rendered as plain text files which is not acceptable.
2019-02-23 22:49:32 +01:00
Waleed Gadelkareem
8995b291a9 Make LogAccess public 2019-02-14 16:30:25 +01:00
Waleed Gadelkareem
1942438b22 Merge pull request #3 from astaxie/develop
develop
2019-02-14 16:23:35 +01:00
astaxie
40d653e659 Merge pull request #3533 from tvanriper/patch-1
APIBaiscAuth is misspelling of APIBasicAuth
2019-02-13 02:10:25 +08:00
Joseph Edwards Van Riper III
ddcd28e67f APIBaiscAuth is misspelling of APIBasicAuth
Corrected APIBaiscAuth to APIBasicAuth.  Maintained old name (forwarding to new one) for those still using the previous API function name.
2019-02-12 13:00:11 -05:00
BaoyangChai
65f587d5e9 fix ineffectual assignment 2019-02-12 19:05:22 +08:00
BaoyangChai
2fefd8cbbf update len 2019-02-12 18:53:34 +08:00
BaoyangChai
ba17bdd366 add ignore auto_now_add field when update 2019-02-12 18:05:29 +08:00
Iskander Sharipov
c998e52cc0 config/yaml: s/bytes.NewBuffer/bytes.NewReader/
When io.Reader is required out of []byte,
it's better to use bytes.NewReader than bytes.NewBuffer.

Signed-off-by: Iskander Sharipov <quasilyte@gmail.com>
2019-02-10 20:37:43 +03:00
Faissal Elamraoui
3224369ac9 Merge pull request #3523 from Quasilyte/quasilyte/boolExprSimplify
Simplify boolean expressions
2019-02-09 16:16:31 +01:00
Iskander Sharipov
67666dbe0f all: simplify boolean expressions
- !(a == b) => a != b
- !(a != b) => a == b

Signed-off-by: Iskander Sharipov <quasilyte@gmail.com>
2019-02-09 17:18:59 +03:00
Sergey
d7430eb921 SessionRead: check of the length for input sid variable 2019-02-04 11:03:27 +05:00
astaxie
26a6b426f1 Merge pull request #3487 from duyazhe/patch-1
Update orm_log.go
2019-02-04 11:26:42 +08:00
astaxie
6f35ce67f7 Merge pull request #3493 from bharat-p/3492-add-db-stats-to-ormer
Add DBStats method wrapper to provide sql.DBStats when using ormer
2019-02-04 11:24:13 +08:00
astaxie
3406d58797 Merge pull request #3503 from wtospit/develop
fix: when parse post form it didnt parse fields correctly
2019-02-04 11:23:23 +08:00
astaxie
7925458fc0 Merge pull request #3502 from Quasilyte/patch-1
cache: remove excessive type assertions
2019-02-02 16:43:04 +08:00
astaxie
b6854aaf9f Merge pull request #3506 from DennisMao/hotfixFileCachePanic
fix panic cause by the map
2019-02-02 16:38:11 +08:00
astaxie
656f595226 Merge pull request #3508 from Quasilyte/patch-2
replace unchecked Compile calls with MustCompile
2019-02-02 16:36:15 +08:00
astaxie
280aaf9d3b Merge pull request #3519 from zav8/add_support_for_pointer_fields
add support for pointer fields of structs to method QueryRows()
2019-02-02 16:35:41 +08:00
zav8
7abdb05f91 little fix 2019-02-01 15:39:40 +08:00
zav8
af4464ce58 add support for pointer fields of structs to method QueryRows() 2019-02-01 15:27:10 +08:00
Iskander (Alex) Sharipov
6ca0978777 replace unchecked Compile calls with MustCompile
For constant patterns and especially when errors are ignored,
`regexp.MustCompile` is a better choice than `regexp.Compile`.

Signed-off-by: Iskander Sharipov <quasilyte@gmail.com>
2019-01-26 14:13:53 +03:00
DennisMao
8506194d2c fix panic cause by the map 2019-01-25 19:08:39 +08:00
Witaya Tospitakkul
3bd7614ade refactoring code after discussion 2019-01-25 11:00:24 +07:00
Witaya Tospitakkul
bd1b421491 fix: adding test for issue due to testing is not reflect changed 2019-01-25 09:04:01 +07:00
Witaya Tospitakkul
920207f72c add testing for ParseForm when form post has a slice in body 2019-01-25 00:38:14 +07:00
Witaya Tospitakkul
12fdc04f1b fix: when parse post form it didnt parse fields which have same name but the first index is empty but another is not 2019-01-25 00:15:40 +07:00
astaxie
d0c744ae6a Merge pull request #3499 from JessonChan/develop
fix download filename(chinese) bug
2019-01-24 17:27:29 +08:00
Iskander (Alex) Sharipov
dc07fa7085 cache: remove excessive type assertions
Assign type switch variable to get properly-typed value
inside case clauses.

Signed-off-by: Iskander Sharipov <quasilyte@gmail.com>
2019-01-24 08:52:30 +03:00
JessonChan
1c893996c0 improve the download func code 2019-01-23 12:36:14 +08:00
JessonChan
a9ffc2a078 https://github.com/astaxie/beego/issues/3446
Use UTF-8 as the encoding of the "filename*" parameter, when
                           present, because at least one existing implementation only
                           implements that encoding.
2019-01-23 12:30:57 +08:00
astaxie
712bbfe575 Merge pull request #3498 from JessonChan/develop
change gosimple to staticcheck
2019-01-23 11:31:37 +08:00
JessonChan
0145fe3486 remove SA1024 staticchek 2019-01-22 20:52:06 +08:00
JessonChan
2a579eb27c staticcheck checks -ST1003 remove 2019-01-22 20:41:07 +08:00
JessonChan
5b42afa324 modiyf staticcheck checks 2019-01-22 20:30:05 +08:00
JessonChan
97713849a1 delete stackcheck config file and ignore some staticcheck checks 2019-01-22 20:21:00 +08:00
JessonChan
abc9c38224 ignore some staticcheck checks 2019-01-22 20:04:30 +08:00
JessonChan
f237ff049a redis_sentinel test ignore 2019-01-22 19:45:32 +08:00
JessonChan
00264650b5 modify travis and redis_sentinel test 2019-01-22 19:29:53 +08:00
JessonChan
2956d33bab no need gosimple 2019-01-22 19:12:25 +08:00
JessonChan
c3eca637fb no need gosimple 2019-01-22 19:10:23 +08:00
JessonChan
0d54bbff02 make staticcheck happy 2019-01-22 19:09:57 +08:00
JessonChan
e65a9cbc00 Gosimple has been deprecated. Please use staticcheck instead. 2019-01-22 18:01:14 +08:00
JessonChan
3ed82c0882 Gosimple has been deprecated. Please use staticcheck instead. 2019-01-22 17:43:55 +08:00
JessonChan
475feb7e24 camel name style 2019-01-22 16:25:17 +08:00
JessonChan
30b80cba92 errors is better style 2019-01-22 16:23:10 +08:00
nuczzz
fe519bd2a0 update tls KeepAlive setting 2019-01-20 11:17:10 +08:00
Bharat Patel
f508f8d959 Nil check 2019-01-18 16:51:40 -08:00
nuczzz
e295c3c7c3 add shutdown log 2019-01-18 19:50:22 +08:00
nuczzz
313be996cd call cancel after shutdown 2019-01-18 19:33:45 +08:00
Bharat Patel
2ae480556d Add DBStats method wrapper to provide sql.DBStats when using ormer 2019-01-17 09:56:42 -08:00
nuczzz
7173fd7490 modify http graceful 2019-01-17 20:17:57 +08:00
duyazhe
d792536c23 Update orm_log.go
orm log支持用户自定义函数处理
2019-01-14 15:14:11 +08:00
astaxie
80aabdd372 Merge pull request #3472 from sangheee/develop
fix: negative WaitGroup counter has not been resolved yet.
2019-01-08 23:54:40 +08:00
astaxie
6892369cc6 Merge pull request #3464 from zhl11b/develop
手机号起始三位补全
2019-01-08 23:54:00 +08:00
astaxie
5b80a56c36 Merge pull request #3468 from DennisMao/hotfix/UpdateDependencyGoes
update dependency
2019-01-08 23:52:39 +08:00
sanghee
bf15535a5b fix panic: sync: negative WaitGroup counter 2019-01-03 22:44:32 +09:00
DennisMao
edb1c52dee fix function changes 2019-01-02 17:01:46 +08:00
DennisMao
6e16b8cdcf fix ci losing dependency 2019-01-02 16:46:27 +08:00
DennisMao
24215fb3eb update dependency 2019-01-02 15:37:41 +08:00
zhl11b
d02699a189 add new test case for china mobile phone 2018-12-30 20:51:21 +08:00
zhl11b
2034d1b101 联通171,175 电信173 2018-12-29 17:41:59 +08:00
astaxie
5fe19d639f Merge pull request #3456 from japettyjohn/master
Fix bug in memcache sessions
2018-12-28 22:35:11 +08:00
James Pettyjohn
1dea80d4ea Fixed error handling in memcache sessions 2018-12-27 16:20:26 -08:00
astaxie
28f0008075 Merge pull request #3434 from zav8/add_sql_null_support
Add support for field of type sql.NullXxx in rawSet.setFieldValue()
2018-12-19 22:26:23 +08:00
zav8
ffe1b00baf Merge branch 'develop' of https://github.com/astaxie/beego into add_sql_null_support 2018-12-18 10:41:17 +08:00
zav8
d2c289193a add test case for QueryRow and QueryRows 2018-12-18 10:37:41 +08:00
astaxie
f867583256 Merge pull request #3433 from DennisMao/FixOrmDescriptionTag
Fix Issue #3337
2018-12-18 09:20:36 +08:00
astaxie
98dfb92e17 Merge pull request #3443 from zhiquan911/develop
add GetProvider
2018-12-18 09:10:17 +08:00
郭一鸣
c8f22be675 Add redis sentinel session support (#3427)
Add Redis Sentinel session support
2018-12-17 14:47:47 +01:00
Chance
f03a7d1128 add GetProvider 2018-12-13 15:37:19 +08:00
zav8
6da4a66c20 merge switch cases 2018-12-06 16:09:39 +08:00
zav8
5e4241fc87 add support for field of type sql.NullXxx in rawSet.setFieldValue() 2018-12-06 16:07:07 +08:00
DennisMao
bf468c8d0c fix format 2018-12-06 10:57:32 +08:00
DennisMao
0d77a3f8d2 FixOrmDescrptionTag 2018-12-06 10:49:50 +08:00
astaxie
1b6edafc96 Merge pull request #3412 from astaxie/develop
v1.11.1
2018-11-30 21:54:26 +08:00
astaxie
8152ade1b6 Merge pull request #3419 from xpzouying/close_fs_when_is_not_nil
Close fs when is not nil
2018-11-30 16:57:49 +08:00
astaxie
6350f8b904 Merge pull request #3420 from xpzouying/format_list_travis_yml
format list in .travis.yml
2018-11-30 16:57:25 +08:00
astaxie
0c5398a19c update travis 2018-11-30 16:42:44 +08:00
astaxie
4b656268d3 travis 2018-11-28 16:17:53 +08:00
astaxie
10729a1fc5 update vendor & module 2018-11-28 16:05:15 +08:00
Ying Zou
cdb3ef808f format list in .travis.yml 2018-11-28 08:59:27 +08:00
Ying Zou
a5a2471f2c close fs only when fs open without error
panic when close nil filesystem
2018-11-28 08:55:20 +08:00
astaxie
6282747f6d update vendor 2018-11-27 14:11:14 +08:00
astaxie
d5fd5cad38 Merge pull request #3417 from xpzouying/update_code_format
better format
2018-11-27 14:01:59 +08:00
Ying Zou
fab7c6b6d0 better format
- add comments for public function
- format import order in admin.go
- better format for NewControllerRegister in router.go
2018-11-26 23:19:05 +08:00
astaxie
42ade6aa49 v1.11.1 2018-11-22 13:10:52 +08:00
astaxie
55d9b69cd9 update mod 2018-11-22 13:08:39 +08:00
astaxie
2a8d6f943f Merge pull request #3408 from nlimpid/develop
add different column name parse strategy
2018-11-21 17:18:39 +08:00
nlimpid
6b0155c4fb add different column name parse strategy 2018-11-20 22:47:56 +08:00
astaxie
e22a5143bc Merge pull request #3403 from nlimpid/develop
add context for db operation
2018-11-20 15:44:25 +08:00
astaxie
a17eb54515 Merge pull request #3405 from coldnight/feature-add-elapsed-in-response
Add .Elapsed in context.ResponseWriter for monitor purpose
2018-11-20 15:39:13 +08:00
nlimpid
d5cf1050db check qs is nil before get forContext 2018-11-19 23:42:56 +08:00
wanghui
b021686521 Add .Elapsed in context.ResponseWriter for monitor purpose
With this commit we can record per requests's elapsed time,
so we can easy to monitor that by use a filter.
2018-11-19 16:38:14 +08:00
astaxie
b0e2bbce2a Merge pull request #3391 from astaxie/develop
V1.11.0
2018-11-19 14:40:43 +08:00
astaxie
7a50ea7e36 Merge pull request #3395 from astaxie/AddTestForSnakeString
#3192 AddTestSnakeString
2018-11-18 21:59:48 +08:00
astaxie
3070cfc60b Merge pull request #3396 from astaxie/FixAnnotationOnSnakeString
Fix #3192
2018-11-18 21:59:35 +08:00
nlimpid
e56d1b718f add context for db operation 2018-11-18 21:54:25 +08:00
Dennis
c4c3067a31 Update utils.go 2018-11-15 15:16:41 +08:00
Dennis
81346fe641 Update utils_test.go 2018-11-15 14:50:38 +08:00
astaxie
1a66ad56c6 Merge pull request #3317 from HSoshiant/master
Lock
2018-11-14 19:24:23 +08:00
astaxie
31f2adb79d Update session.go 2018-11-14 19:24:10 +08:00
astaxie
f514ae309b Update session.go 2018-11-14 19:23:10 +08:00
astaxie
277d3d98e3 v1.11.0 2018-11-14 17:01:12 +08:00
astaxie
2c46877b36 Merge pull request #3390 from astaxie/FixDataRaceOnCache
Fix  #3354
2018-11-14 15:58:20 +08:00
astaxie
cfe54a02c5 Merge pull request #3388 from s00500/develop
Closes #2515 Autodetect timezone in NewOrmWithDB()
2018-11-13 16:48:18 +08:00
astaxie
55f390d08a Merge pull request #3387 from wuyumin/master
dynamically add task #2708
2018-11-13 14:51:41 +08:00
astaxie
cf31222643 Merge pull request #3386 from DennisMao/AddTransportSetting
add transport setting
2018-11-13 14:50:28 +08:00
Dennis
9e036bcab5 Update memory.go 2018-11-13 14:43:23 +08:00
d02170e3cb Closes #2515 Autodetect timezone in NewOrmWithDB() 2018-11-12 10:18:05 +01:00
Yumin Wu
2d6f1af1a5 dynamically add task 2018-11-12 17:17:06 +08:00
Dennis
430457609f Update httplib_test.go 2018-11-12 13:04:17 +08:00
astaxie
0333e26b3e Merge pull request #3382 from lxShaDoWxl/add_custom_fs_template
Add custom fs template
2018-11-10 22:44:28 +08:00
Viktor Vassilyev
d0d28566b9 chore(GoMod): add dependency go-bindata-assetfs in vendor dir 2018-11-10 13:41:47 +06:00
Viktor Vassilyev
872b787e6c refactor(FileSystem): add comments function 2018-11-10 12:34:53 +06:00
Viktor Vassilyev
01a99edf80 chore(GoMod): add dependency go-bindata-assetfs 2018-11-10 12:26:19 +06:00
Viktor Vassilyev
6050d37d2a Merge remote-tracking branch 'me/develop' into add_custom_fs_template 2018-11-10 11:39:28 +06:00
astaxie
876dce8e54 fix the routerInfo is nil 2018-11-09 18:03:26 +08:00
astaxie
24885c28f2 fix the comments update 2018-11-09 17:54:20 +08:00
astaxie
5ea04bdfd3 update mod 2018-11-09 12:37:28 +08:00
astaxie
9fdc1eaf3a Merge pull request #3352 from SongLiangChen/develop
add sessionid prefix
2018-11-08 23:29:05 +08:00
astaxie
6b5a70d246 Merge pull request #3378 from nukc/develop
orm: support filter raw sql
2018-11-08 23:28:30 +08:00
astaxie
8391d26220 Merge pull request #3383 from LockGit/develop
security question, fix arbitrary file read
2018-11-08 23:21:18 +08:00
Viktor Vassilyev
f193e313a3 refactor(FileSystem): using single-line if 2018-11-07 20:21:34 +06:00
Viktor Vassilyev
9ac4928113 refactor(Template): a detailed description of the error 2018-11-07 20:20:10 +06:00
lock
9865779f14 security question, fix arbitrary file read 2018-11-07 11:31:27 +08:00
Viktor Vassilyev
aa6d0f9f0b fix(Template): correct check error 2018-11-06 21:40:43 +06:00
Viktor Vassilyev
68b0bd98fd fix(Template): error handling when reading files 2018-11-06 20:41:05 +06:00
Viktor Vassilyev
3447798494 fix(Template): dependencies in travis 2018-11-06 20:18:48 +06:00
Viktor Vassilyev
ca1b96f986 feat(Template): use interface http.FileSystem 2018-11-06 20:06:21 +06:00
Viktor Vassilyev
771fe35431 feat(Template): testing fs bindata 2018-11-05 22:58:59 +06:00
Viktor Vassilyev
2f00ad1602 fix(Template): close open file 2018-11-05 22:51:20 +06:00
Viktor Vassilyev
f740b71ded fix(Template): remove duplicate check open/exists 2018-11-05 21:08:03 +06:00
Viktor Vassilyev
7aae58a543 feat(Template): create interface FileSystem for to create custom fs 2018-11-05 21:05:19 +06:00
SongLiang
c8da875f83 add sessionId prefix 2018-11-05 09:51:27 +08:00
SongLiang
501d8a97f6 add sessionId prefix 2018-11-05 09:50:19 +08:00
nukc
736e66fcda orm: support filter raw sql 2018-11-05 03:47:21 +08:00
SongLiang
d3ad810f16 add sessionId prefix 2018-10-29 13:35:31 +08:00
SongLiang
abc8b78065 add sessionId prefix 2018-10-29 12:18:06 +08:00
astaxie
f64e6b72e9 Merge pull request #3362 from SmartBrave/develop
modify qbs to qps
2018-10-28 20:01:23 +08:00
astaxie
4e83b4400a Merge pull request #3371 from HaraldNordgren/go_versions
Bump Go versions and use 1.n.x to get latest minor versions
2018-10-28 19:49:27 +08:00
Harald Nordgren
f6f61513a1 Bump Go versions and use 1.n.x to get latest minor versions 2018-10-28 00:58:36 +02:00
yangzhiyong
8217817a0b modify qbs to qps 2018-10-24 10:38:59 +08:00
astaxie
833f54d818 Merge pull request #3319 from Colstuwjx/annotated-filter
Annotated filter
2018-10-23 13:45:18 +08:00
astaxie
706c086bc5 Merge pull request #3345 from dingyuanhong/develop
fix / can use dynamic directory
2018-10-23 13:43:45 +08:00
SongLiangChen
187add9b84 add sessionid prefix 2018-10-10 11:02:45 +08:00
astaxie
5b8e468a13 Merge pull request #3344 from akhedrane/patch-1
duo to #3278 numRow should be 0
2018-10-05 21:16:18 +08:00
dingyuanhong
dff9c8f5fa fix / can use dynamic directory 2018-10-01 15:16:35 +08:00
Atallah khedrane
21a8623002 duo to #3278 numRow should be 0 2018-09-30 10:45:18 +01:00
astaxie
ea9c5822e6 Merge pull request #3292 from SongLiangChen/master
Read over 4096 length values
2018-09-30 16:03:45 +08:00
astaxie
ad0d166d46 Merge pull request #3295 from GNURub/feature/outputWithformat
feature/outputwithformat
2018-09-30 16:01:07 +08:00
astaxie
2c2ace9a60 Merge pull request #3313 from oiooj/pr-module
support go modules
2018-09-30 15:55:57 +08:00
astaxie
8134a89e81 Merge pull request #3333 from akhedrane/patch-1
Return error when wrong filtering field
2018-09-30 15:45:23 +08:00
astaxie
e342a0099f Merge pull request #3340 from GNURub/feature/update-travis
Add go 1.11 version
2018-09-30 15:44:46 +08:00
astaxie
c4ed5030da Merge pull request #3339 from GNURub/hotfix/redis-uri
Support redis URI format
2018-09-30 15:43:41 +08:00
astaxie
7b9c24567d Merge pull request #3335 from GNURub/hotfix/ranking-response-times
Added link to time ranking
2018-09-30 15:42:05 +08:00
Ruben Cid
6906c5ce30 Updated travis go version 2018-09-27 18:27:38 +02:00
Ruben Cid
e4605f232b Support redis URI 2018-09-26 18:05:09 +02:00
Ruben Cid
6092e737a1 Added link to ranking 2018-09-24 18:33:56 +02:00
Atallah khedrane
0e4d954fa7 Return error when wrong filtering field
When end user put wrong filtering field ORM should return error instead of Panic()
so developers can handle this error.
2018-09-23 12:18:15 +02:00
Colstuwjx
1cbba4d56f Add annotated filter, support @Import, @Filter.
Signed-off-by: Colstuwjx <Colstuwjx@gmail.com>
2018-09-07 15:59:57 +08:00
kun
cf5d1f3f3c support go modules 2018-09-05 14:05:16 +08:00
Hossein Karimy
1097ac3682 GetProvider 2018-08-28 15:12:28 -04:00
Ruben Cid
755cc98ef7 Fix content type 2018-08-21 12:32:16 +02:00
Ruben Cid
5c407ff2e3 Add map shortcut and ServeFormatted method in output 2018-08-20 22:55:50 +02:00
SongLiangChen
8f455ef199 Read over 4096 length values 2018-08-17 11:40:00 +08:00
astaxie
7e0649d661 Merge pull request #3289 from nezorflame/patch-1
Remove panic from Redirect()
2018-08-16 09:22:22 +08:00
Ilya Danilkin
1a3dcb4f84 Remove panic from Redirect()
This `panic(ErrAbort)` is unnecessary in `Redirect` function and causes problems in the production code.
2018-08-12 05:11:03 +03:00
astaxie
b606f1f73f Merge pull request #3283 from JessonChan/develop
typo fixed
2018-08-09 17:05:25 +08:00
astaxie
8241f219fd Merge pull request #3278 from hurisheng/revert-3247-develop
Revert "send ErrNoRows if the query returns zero rows ... in method orm_query…"
2018-08-09 17:05:01 +08:00
hurisheng
dea45a3d6c fix TestAll() 2018-08-07 16:36:27 +08:00
JessonChan
34a812d45f typo fixed
#3260
2018-08-07 12:08:15 +08:00
astaxie
842336834f Merge pull request #3275 from WiFeng/master
fix bug of tasks that only some but not all are executed
2018-08-07 10:07:29 +08:00
astaxie
58fe012446 Merge pull request #3274 from gombaniro/improvement/make-TestSet-on-map-self-contained
breaks dependency on TestNewBeeMap Testcase
2018-08-07 10:02:29 +08:00
astaxie
bf0d40bca6 Merge pull request #3280 from GNURub/feature/pusher
Add access to pusher
2018-08-07 09:58:56 +08:00
Ruben Cid
48e6658eca Add access to pusher 2018-08-03 12:33:46 +02:00
Hu Risheng
1bd3fb7a33 Revert "send ErrNoRows if the query returns zero rows ... in method orm_query…" 2018-08-03 13:35:48 +08:00
liuweifeng
d86410a631 fix bug of tasks that only some but not all are executed 2018-08-01 11:20:22 +08:00
Jean Claude
6b62502b99 breaks rely on TestNewBeeMap 2018-08-01 10:24:39 +08:00
astaxie
053a075344 Merge pull request #3271 from astaxie/develop
add vendor gopkg.in/yaml.v2
2018-07-31 21:18:48 +08:00
astaxie
9dd7d19ce7 add vendor gopkg.in/yaml.v2 2018-07-31 21:18:07 +08:00
astaxie
efe0f67388 Merge pull request #3267 from astaxie/develop
beego 1.10.1
2018-07-31 20:52:47 +08:00
astaxie
de66d2bdfd beego 1.10.1 2018-07-31 20:09:08 +08:00
astaxie
0e4fe4d177 Merge pull request #3270 from astaxie/revert-3269-master
Revert "hible"
2018-07-31 20:07:18 +08:00
astaxie
6d84db1e93 Revert "hible" 2018-07-31 20:07:03 +08:00
astaxie
2486f3826a Merge pull request #3269 from 514366607/master
hible
2018-07-31 20:06:55 +08:00
astaxie
d7b8aa8b52 only add golang.org vendor 2018-07-31 19:25:43 +08:00
hible
c7c0b01ec5 hible
cache add function
// IncrBy increase counter by num.
IncrBy(key string, num int)
// DecrBy decrease counter by num.
DecrBy(key string, num int)
2018-07-31 17:19:09 +08:00
astaxie
6d69047fff update go vet 2018-07-30 15:13:04 +08:00
astaxie
787ab12605 Merge branch 'develop' of https://github.com/astaxie/beego into develop 2018-07-30 15:01:58 +08:00
astaxie
f4112accef update go vet 2018-07-30 15:01:49 +08:00
astaxie
42c394e28b Merge pull request #3263 from guomao545/master
Support return middle level value
2018-07-30 12:27:05 +08:00
astaxie
5051d902fb Merge pull request #2986 from oxgo/hourlylog
add hourly log rotate
2018-07-30 12:26:37 +08:00
astaxie
48acfa08be add vendor 2018-07-30 12:05:51 +08:00
guomao545
39fc30b8b2 Support return middle level value
fix multilevel yaml config can't correct return middle level value bug
2018-07-27 15:33:24 +08:00
two
046cb248e0 edit test case 2018-07-26 15:08:14 +08:00
two
31c746d9d7 fix all confict 2018-07-26 14:34:25 +08:00
two
38a2f32252 fix one confict 2018-07-26 14:29:26 +08:00
astaxie
d55f54a8ab Merge pull request #3149 from liaoishere/feature/support-begintx
Support DB.BeginTx in go 1.8
2018-07-23 20:25:17 +08:00
Penghui Liao
feb0e67fd7 upgrade go version from 1.9.2 to 1.9.7 in test env.
upgrade to avoid bug: https://github.com/golang/go/issues/22976

Signed-off-by: Penghui Liao <liaoishere@gmail.com>
2018-07-23 15:58:12 +08:00
astaxie
a09bafbf2a Merge pull request #3233 from astaxie/develop
beego 1.10.0
2018-07-21 15:55:28 +08:00
astaxie
03de7456ca Merge pull request #3250 from 0x0400/develop
acquire lock when access config data
2018-07-21 15:25:23 +08:00
Xingang Zhang
78f2fd8d14 acquire lock when access config data 2018-07-21 14:56:09 +08:00
astaxie
a048ed51a7 ready to release 1.10.0 2018-07-21 09:29:00 +08:00
astaxie
164a9231e8 Merge pull request #3249 from GNURub/feature/autocert
Feature/autocert
2018-07-21 09:20:07 +08:00
Ruben Cid
aaa7e33778 Autocert ok 2018-07-20 19:54:25 +02:00
Ruben Cid
f7008e2877 Removed patch 2018-07-20 19:02:09 +02:00
Ruben Cid
cf6e825547 Domains 2018-07-20 18:59:45 +02:00
Ruben Cid
38f9a3c49e AutoCert 2018-07-20 18:53:57 +02:00
astaxie
f18283a517 Merge pull request #3181 from GNURub/feature/YAML
Feature/yaml
2018-07-20 23:41:15 +08:00
astaxie
61aec396e0 Update .travis.yml 2018-07-20 23:40:11 +08:00
astaxie
5ba9e63086 Merge branch 'develop' into feature/YAML 2018-07-20 23:24:51 +08:00
astaxie
5acc56648d Merge branch 'develop' into feature/support-begintx 2018-07-20 23:16:12 +08:00
astaxie
bc773039ca Merge pull request #2997 from DennisMao/master
fix the model can not be registered correctly on Ubuntu 32bit
2018-07-20 23:14:41 +08:00
astaxie
868fc2a29f fix go1.10.3 orm test failed 2018-07-20 22:45:44 +08:00
astaxie
81f69f12ab Merge branch 'develop' of https://github.com/astaxie/beego into develop 2018-07-20 22:30:25 +08:00
astaxie
0711c3289f fix the orm test 2018-07-20 19:58:56 +08:00
Penghui Liao
b8868d6d2d remove unnecessary conversion
Signed-off-by: Penghui Liao <liaoishere@gmail.com>
2018-07-20 17:07:17 +08:00
Penghui Liao
30bbc81a2e fix test case that calls All()
Signed-off-by: Penghui Liao <liaoishere@gmail.com>
2018-07-20 16:51:36 +08:00
Penghui Liao
1a3f1d66c1 rename orm_go18.go to orm.go
Signed-off-by: Penghui Liao <liaoishere@gmail.com>
2018-07-20 16:36:06 +08:00
Penghui Liao
6bdd152d91 upgrade postgres in travis
Signed-off-by: Penghui Liao <liaoishere@gmail.com>
2018-07-20 16:36:06 +08:00
Penghui Liao
443c77b303 support DB.BeginTx of golang 1.8
Signed-off-by: Penghui Liao <liaoishere@gmail.com>
2018-07-20 16:36:06 +08:00
Penghui Liao
0dff771707 fix unquoted identifier that may be misleading in postgres
Signed-off-by: Penghui Liao <liaoishere@gmail.com>
2018-07-20 16:36:06 +08:00
astaxie
c9b6e4f825 Merge pull request #2981 from TankTheFrank/fix_template_render_with_automatic_parameter_routing
fixes template rendering with automatic mapped parameters (see #2979)
2018-07-20 15:39:10 +08:00
astaxie
abd02c7de4 Merge pull request #2985 from terryding77/fix_orm_Field_SetRaw_function_error_judge_problem
fix orm fields SetRaw function error judge problem
2018-07-20 15:36:40 +08:00
astaxie
eb4e0e4030 Merge pull request #3022 from chenpeiyuan/develop
do html escape before display path, avoid xss
2018-07-20 15:33:12 +08:00
astaxie
96dffcd27f Merge pull request #3105 from ckahi/hotfix_log_dir
auto create log dir
2018-07-20 15:32:42 +08:00
astaxie
0d0d87f600 Merge branch 'develop' of https://github.com/astaxie/beego into develop 2018-07-20 15:25:04 +08:00
astaxie
2c779a4287 Merge pull request #3141 from gadelkareem/patch-2
Improve access log
2018-07-20 15:20:15 +08:00
astaxie
f25893832f Merge pull request #3142 from amitash1109/fix_response_http_code
Fix response http code
2018-07-20 15:18:54 +08:00
astaxie
af73a2d515 Merge branch 'develop' into fix_response_http_code 2018-07-20 15:18:30 +08:00
astaxie
67a6b8723c Merge pull request #3146 from Wang-Kai/master
Add code style for logs README
2018-07-20 15:17:31 +08:00
astaxie
fdccd85330 Merge pull request #3152 from joshtechnologygroup/staticfile_unexpected_eof_bug_gix
[#2973] Fix Unexpected EOF bug in staticfile
2018-07-20 15:09:07 +08:00
astaxie
ca394fc8ab Merge pull request #3182 from GNURub/feature/autobind
Add method to set the data depending on the accepted
2018-07-20 15:05:28 +08:00
astaxie
9c9ba0129f Merge pull request #3226 from jianjianzhu/master
Fix the wrong status code in prod
2018-07-20 14:53:08 +08:00
astaxie
b61c91d93d remove unnecessary conversion 2018-07-20 14:47:11 +08:00
astaxie
f15732798f Merge pull request #3239 from wilhelmguo/develop
add session redis IdleTimeout config
2018-07-20 14:44:07 +08:00
astaxie
efbe655d6a Merge pull request #3245 from 0x0400/patch-1
fix typo
2018-07-20 14:43:38 +08:00
astaxie
27ced1d9c3 Merge pull request #3247 from mohan2808/develop
send ErrNoRows if the query returns zero rows ... in method orm_query…
2018-07-20 14:34:23 +08:00
astaxie
8f6bce3b87 fix test case 2018-07-20 14:26:43 +08:00
astaxie
be75f93d43 add miss dep 2018-07-20 12:14:27 +08:00
astaxie
541fb181fe Merge branch 'master' into develop 2018-07-20 12:00:53 +08:00
mohan2808
293b54192f send ErrNoRows if the query returns zero rows ... in method orm_queryset.All() 2018-07-19 18:51:16 +05:30
Xingang Zhang
0e0718d110 fix typo
hasReuired --> hasRequired
2018-07-17 23:32:11 +08:00
guoshaowei
6fec0a7831 add session redis IdleTimeout config 2018-07-12 10:48:50 +08:00
astaxie
654ebebe3c Merge pull request #3217 from jinxjinxagain/develop
fix: When multiply comment routers on one func
2018-07-08 16:13:21 +08:00
astaxie
08c3ca642e Merge pull request #3230 from Colstuwjx/fix/correct-httplib-maxidleconnection-default-value
Fix: correct MaxIdleConnsPerHost value to net/http default 100.
2018-07-08 16:11:35 +08:00
Colstuwjx
b3c46a87ac Fix: correct MaxIdleConnsPerHost value to net/http default 100. 2018-07-05 19:15:42 +08:00
zhujianjian
464d080518 fix httpcode in prod 2018-07-02 11:21:06 +08:00
jinxjinxagain
227c04c9e6 fix: When multiply comment routers on one func, only generates the last one controller 2018-06-28 15:54:17 +08:00
astaxie
e5d68aceed Merge pull request #3185 from kaka89/master
Fix defaut value bug, and add config for maxfiles
2018-06-23 22:54:35 +08:00
astaxie
67d9241abc Merge pull request #3171 from whomm/master
debug stringsToJSON
2018-06-23 22:50:11 +08:00
astaxie
110dbcb31f Merge pull request #3208 from hurisheng/qs_forupdate
add 'FOR UPDATE' support for querySet
2018-06-23 22:49:01 +08:00
astaxie
740bf72f0c Merge pull request #3202 from openset/develop
Update: Htmlquote Htmlunquote
2018-06-23 22:43:53 +08:00
astaxie
6b3b8607a0 Merge branch 'develop' into develop 2018-06-23 22:43:45 +08:00
astaxie
b21c59ee70 Merge pull request #3206 from whilei/gofmt-2018-Jun-17-00-39
gofmt
2018-06-23 22:38:07 +08:00
hurisheng
fc2c96a177 add 'FOR UPDATE' support for querySet 2018-06-23 22:25:05 +08:00
ia
87ba3f3cd3 all: gofmt
Run standard gofmt command on project root.

- go version go1.10.3 darwin/amd64

Signed-off-by: ia <isaac.ardis@gmail.com>
2018-06-17 00:47:51 +02:00
Openset
b80b7b06fc Update: Redundant semicolon disableEscapeHTML 2018-06-14 11:55:07 +08:00
Openset
ad6c97ec1b Update: Htmlquote Htmlunquote 2018-06-13 15:43:01 +08:00
astaxie
d3d97de312 Merge pull request #3200 from openset/master
Update: use PathEscape replace QueryEscape
2018-06-12 22:45:14 +08:00
Sandy
bf915c3280 Update: use PathEscape replace QueryEscape
If filename contain space(" "), QueryEscape use "+" instead.
2018-06-12 16:15:20 +08:00
astaxie
19c5cd130d Merge pull request #3190 from NSObjects/develop
add field comment on create table
2018-06-07 11:06:23 +08:00
lintao
1df2662924 add field comment on create table 2018-06-06 12:33:28 +08:00
umasuo
f979050a45 Fix defaut value bug, and add default maxfiles
1. add default value for maxlines(100000), maxsize(1 << 28)
2. add maxfiles for configure, just like `maxlines` & maxsize
2018-06-03 23:08:03 +08:00
Ruben Cid
45b68d444d Add method to set the data depending on the accepted 2018-06-01 19:11:01 +02:00
Ruben Cid
732f79e758 Add dep travis 2018-05-31 14:52:47 +02:00
Ruben Cid
4e954e32b8 Test YAML 2018-05-31 13:48:24 +02:00
Ruben Cid
92e81ccf50 Merge branch 'develop' into feature/YAML 2018-05-31 13:35:44 +02:00
Ruben Cid
91f2005067 Test YAML 2018-05-31 13:35:23 +02:00
Ruben Cid
7c80bf6f9d Add YAML 2018-05-30 16:06:40 +02:00
astaxie
cc2c98c112 update travis 2018-05-30 22:01:59 +08:00
astaxie
c3c0adbf55 Merge pull request #3175 from mo0feng/master
Create redis_cluster.go
2018-05-28 16:48:06 +08:00
jz
04c305f273 fix use it comments
fix  use it comments
2018-05-24 15:14:56 +08:00
jz
8c8cf46b55 Create redis_cluster.go
super redis cluster
2018-05-23 17:30:13 +08:00
whomm
e96ae0c24a debug stringsToJSON
json char: \u four-hex-digits number(http://json.org/)
2018-05-21 15:18:18 +08:00
Amit Yadav
98a3cda260 Fix Unexpected EOF bug in staticfile 2018-05-07 13:51:05 +05:30
Wang-Kai
1fd7fa5df7 make example runable 2018-05-03 22:04:49 +08:00
astaxie
3d3f2ed4c5 Merge pull request #3127 from kaka89/master
Refactor yaml config for support multilevel
2018-05-03 14:07:59 +08:00
Wang-Kai
0f73050567 add code style for logs README 2018-05-03 12:05:59 +08:00
astaxie
a40899e6be Merge pull request #3145 from gadelkareem/develop
Allow log prefix
2018-05-03 11:27:50 +08:00
Waleed Gadelkareem
a9a15e2c54 Allow log prefix 2018-05-02 00:24:09 +02:00
Waleed Gadelkareem
896c258e44 Log redirects and abort after redirect 2018-04-30 17:48:01 +02:00
Amit Ashkenazi
6df42d63e2 Fix response http code 2018-04-29 15:12:32 +03:00
Waleed Gadelkareem
33bf80b052 Merge branch 'pr/3141' into patch-2 2018-04-28 20:07:23 +02:00
Waleed Gadelkareem
d5c1c0e9a4 log errors in access log and make static request logging optional 2018-04-28 20:03:39 +02:00
Waleed Gadelkareem
8e61a6a6de Allow access log regardless of the log level 2018-04-28 17:15:19 +02:00
umasuo
ccaa2dd9e0 Update yaml.go
delete white line.
2018-04-20 19:44:22 +08:00
astaxie
507ea757d7 Merge pull request #3039 from cloudzhou/patch-1
execElem.FieldByName as local variable
2018-04-20 19:41:07 +08:00
astaxie
9d526dfd50 Merge pull request #3100 from godcong/master
change github.com/garyburd/redigo to newest branch github.com/gomodul…
2018-04-20 19:40:30 +08:00
umasuo
ba89253e4a Update yaml.go
add support for multilevel yaml config
2018-04-20 19:40:06 +08:00
astaxie
0d6f190e72 Merge pull request #3107 from sergeylanzman/patch-1
Update .travis.yml golang 1.10
2018-04-20 19:33:50 +08:00
astaxie
91b9a65db0 Merge pull request #3109 from Jeff885/Jeff885-patch-1
When log maxSize set big int,FileWrite Init fail
2018-04-20 19:33:33 +08:00
astaxie
e96a5fb3ca Merge pull request #3115 from m4grio/minor-typo
Amend a very minor typo in a variable name
2018-04-20 19:26:42 +08:00
astaxie
f5f70f386d Merge pull request #3126 from aruhi/master
In dev mode, template parse error cause program lock
2018-04-20 19:26:24 +08:00
astaxie
242efcf7fa Merge pull request #3103 from qshuai/master
fix typo
2018-04-20 19:26:00 +08:00
aruhi
51cc6fc257 Update template.go 2018-04-20 19:42:50 +09:00
Mario Álvarez
5fb29cb772 Amend a very minor typo in a variable name 2018-04-10 12:19:50 +08:00
MinJie Gu
2da894d4a7 When log maxSize set big int,FileWrite Init fail
example:
beego.SetLogger("multifile", {"filename":"logs/liverelay.log","separate":[ "emergency", "error", "info", "debug"],"maxsize":250000000}).

json: cannot unmarshal number 2.5e+08 into Go value of type int

The err should return and show the developer.
2018-04-06 00:50:35 +08:00
Sergey Lanzman
2623b15ce0 Update .travis.yml 2018-04-05 16:30:08 +03:00
chenkaihui
6db9ad7002 auto create log dir 2018-04-04 15:59:52 +08:00
qshuai
889408136b fix typo 2018-03-28 00:26:06 +08:00
godcong
886fefe738 change github.com/garyburd/redigo to newest branch github.com/gomodule/redigo 2018-03-26 16:59:01 +08:00
astaxie
768406f134 Merge pull request #3076 from gadelkareem/patch-1
Set default Beego RunMode to production
2018-03-11 16:26:00 +08:00
astaxie
075e63b2bd Merge pull request #2999 from moririnson/fix_unable_to_add_column
fix the issue #2998
2018-03-11 16:18:50 +08:00
astaxie
0057c08a90 Merge pull request #3085 from WUMUXIAN/swagger
Swagger: Allow example values with different types, allow example for enum.
2018-03-11 10:48:48 +08:00
WUMUXIAN
09b073356d Swagger:
1. Allow example value to be given based on the field type, previously it's a string.
2. Allow to give example values for Enum values.

This is for the beego/bee pull request to work well.
2018-03-10 17:15:24 +08:00
Waleed Gadelkareem
3c9ed48630 Set default Beego RunMode to production 2018-03-02 18:23:20 +01:00
astaxie
65d8b4f544 Merge pull request #3064 from takeo-lvgs/dev
fix the issue #3063
2018-02-22 17:22:39 +08:00
astaxie
6d18d4dcdd Merge pull request #3066 from takeo-lvgs/fix_3065
fix the issue #3065
2018-02-22 17:16:38 +08:00
takeo-lvgs
21fe2d519e fix the issue #3065 2018-02-20 17:40:18 +09:00
takeo-lvgs
9a7554fa01 fix the issue #3063 2018-02-20 11:39:29 +09:00
astaxie
37d1c13603 Merge pull request #3046 from aspacca/master
Handle pointer validation
2018-02-02 18:57:13 +08:00
Andrea Spacca
5ed112e946 added CanSkipAlso 2018-02-02 10:22:43 +01:00
Andrea Spacca
453f112094 added more test case 2018-02-01 18:31:04 +01:00
Andrea Spacca
faa3341603 Fix after test failure 2018-01-28 18:19:27 +01:00
Andrea Spacca
ee9cf05796 Handle pointer validation 2018-01-28 17:40:05 +01:00
cloudzhou
6de538b136 execElem.FieldByName as local variable
execElem.FieldByName(fieldType.Name) as local variable
2018-01-25 17:52:09 +08:00
陈培远
47c1072b78 do html escape before display path, avoid xss 2018-01-08 19:35:53 +08:00
astaxie
e81f1e53bf Merge pull request #3017 from Medicean/develop
Update: Fix migration generate SQL
2018-01-05 00:10:16 +08:00
Medicean
cf92d2c6ef Update: Fix migration generate SQL 2018-01-04 10:42:39 +08:00
astaxie
0507076c3f Merge pull request #3004 from pcallewaert/develop
redis cache: make MaxIdle configurable
2017-12-30 13:54:11 +08:00
Pieter Callewaert
59fd3952b7 bug: restore the default value 2017-12-26 11:48:34 +01:00
Pieter Callewaert
7fd80e6aa1 feat(redis.go): make MaxIdle configurable 2017-12-26 11:48:08 +01:00
smori
24fa6189b5 fix the issue #2998 2017-12-23 16:41:56 +09:00
dennismao
0bde9cbd91 fix the issue #2995 2017-12-22 16:21:23 +08:00
astaxie
122414d789 Merge pull request #2992 from priteshgudge/develop
Update Documentation in Output.go
2017-12-21 17:08:10 +08:00
Pritesh Gudge
aac69674ad Update Documentation in Output.go
Fix Documentation for HTTP status codes descriptions.
2017-12-21 13:50:28 +05:30
chenxiaonan01
1a42154c64 add file test 2017-12-20 17:54:40 +08:00
chenxiaonan01
e81cca304b add file test 2017-12-20 16:19:58 +08:00
chenxiaonan01
07aa97aa9a add hourly rotate file.go 2017-12-20 15:56:36 +08:00
Terry Ding
94fba0b2aa fix orm fields SetRaw function error judge problem 2017-12-20 14:53:00 +08:00
astaxie
80aa47f605 Merge pull request #2976 from szyhf/develop
Fix #2975
2017-12-19 23:34:17 +08:00
astaxie
f16688817a Merge pull request #2978 from BorisBorshevsky/fix_reflection_bug
fix bug #2972
2017-12-18 19:18:59 +08:00
TankTheFrank
2670a86005 fix #2979 2017-12-14 17:55:08 +02:00
BorisBorshevsky
0e369e6df8 fix bug 2017-12-13 15:27:32 +02:00
Back Yu
84443b9c05 Fix #2975
修复AccessLog输出会多换一行的bug
2017-12-12 12:21:55 +08:00
astaxie
33be6803a3 Merge pull request #2970 from gcy3y/master
update log.go add GetLevel Function to Log
2017-12-10 20:26:46 +08:00
astaxie
aef2f1c66e Merge pull request #2971 from PureWhiteWu/fix_typo
fix a typo
2017-12-10 18:47:54 +08:00
Pure White
619cd2d908 fix a typo 2017-12-08 23:01:21 +08:00
GuoChunYang
4613acd88e update log.go add GetLevel Function to Log 2017-12-08 15:35:12 +08:00
astaxie
bf5c5626ab Merge pull request #2943 from astaxie/develop
1.9.2
2017-12-06 23:37:36 +08:00
astaxie
0fbbc67c3d Merge pull request #2961 from zhlicen/master
Add lock while releasing session
2017-12-06 14:44:25 +08:00
astaxie
3e1916ec3c Merge pull request #2953 from szyhf/develop
Proposal to #2952
2017-12-06 14:43:12 +08:00
astaxie
b068a676dd Merge pull request #2950 from huhaocc/change_httpmethod_type
Change the type of HTTPMETHOD
2017-12-06 14:42:35 +08:00
HANG ZHOU
ed73bdcfab Add lock while releasing session
Solve the problem of SessionRead failure while ReleaseSession is in progress
2017-12-05 16:18:56 +08:00
astaxie
ae94b705ea Merge pull request #2954 from axetroy/master
test: Improve test case for utils/safemap, make it 100% cover
2017-12-01 23:33:46 +08:00
axetroy
08fb921053 test: Improve test case for utils/safemap, make it 100% cover 2017-12-01 01:04:15 +08:00
Back Yu
e67e57f8fb orm: 修复logic enum因为type enum改变而产生的位错位。 2017-11-30 20:26:34 +08:00
Back Yu
b30969704a Proposal to #2952 2017-11-30 18:12:49 +08:00
hao.hu
646acc423e Change HTTPMETHOD type 2017-11-30 01:43:50 +08:00
astaxie
c3a81a23f9 beego 1.9.2 2017-11-27 15:52:31 +08:00
astaxie
103dd22151 remove mysq travis 2017-11-27 15:42:18 +08:00
astaxie
ec6cb43711 fix ci failed 2017-11-27 14:07:05 +08:00
astaxie
84cb9a5986 update to go1.9.2 2017-11-26 14:35:37 +08:00
astaxie
9b8bc2aef7 Merge pull request #2941 from BorisBorshevsky/report-card
add report card to readme.md
2017-11-26 14:32:57 +08:00
astaxie
9710d9e961 Merge pull request #2940 from BorisBorshevsky/golint
fix golint comments
2017-11-26 14:32:40 +08:00
BorisBorshevsky
58bb49a78c add report card to readme.md 2017-11-25 19:23:46 +02:00
BorisBorshevsky
df37739c7d fix golint comments 2017-11-25 19:18:37 +02:00
astaxie
a5dd5d161d Merge pull request #2659 from ansiz/master
to close issue #1899(redis cache doubt)
2017-11-19 11:13:42 +08:00
astaxie
6827107177 Merge pull request #2706 from fat4lix/bugfix
Fix run controller if it set by RumController and RunMethod in Filterfunc
2017-11-19 11:12:48 +08:00
astaxie
a30a89e57e Merge pull request #2849 from iclinux/grace-patch
Make parent process exit gracefully.
2017-11-19 11:09:13 +08:00
astaxie
d352e4abcb Merge pull request #2852 from Radar8/master
validation: fix ErrorMap, added AddError(key, message)
2017-11-19 11:08:31 +08:00
astaxie
a948d4c1e1 set default to apache format 2017-11-19 11:07:57 +08:00
astaxie
b7eb3963f5 Merge pull request #2863 from gadelkareem/develop
Add JSON or Apache access log formatting option to config:  AccessLogsFormat = JSON_FORMAT or APACHE_FORMAT  ref #2738
2017-11-19 11:05:12 +08:00
astaxie
f7afb3cb75 Merge pull request #2878 from silviucm/master
Add the ability to unregister fixed routes
2017-11-19 10:41:40 +08:00
astaxie
348bf51a42 Merge pull request #2914 from AbelZhou/master
Add sys env feature
2017-11-19 10:41:22 +08:00
astaxie
dfea2cc5f3 Merge pull request #2928 from ilylia/develop
add Enum field to Schema
2017-11-19 10:27:11 +08:00
astaxie
532eab8e1d Merge pull request #2932 from lotus-wu/Branch_v1.9.0
1.Add Mutual HTTPS  Option!
2017-11-19 10:26:59 +08:00
lotus
3872382a4b 1.Add Mutual HTTPS Option! 2017-11-15 22:42:30 +08:00
ilylia
4018693fbd add Enum field to Schema 2017-11-13 14:36:08 +08:00
astaxie
3b829504f6 Merge pull request #2920 from chenpeiyuan/develop
avoid unnecessary read of large log file
2017-11-07 09:35:09 -06:00
陈培远
80fa51468c avoid unnecessary read of large log file
If w.MaxLines is not set, there is no need to calc large log file’s lines. It may takes more than 10mins to calc a 10G file.
2017-11-07 22:58:39 +08:00
Abel
3504d2a4da Add host env feature. 2017-10-31 19:19:14 +08:00
Abel
229d8b9530 Add host env feature. 2017-10-30 13:54:36 +08:00
Silviu Capota-Mera
9536d460d0 Create test file for the route unregistering functionality 2017-10-28 14:49:41 -04:00
astaxie
e211e4839c Merge pull request #2906 from mlgd/patch-1
Update for MySQL timezone detection bug
2017-10-27 09:47:09 -05:00
mlgd
3332dbe595 Update for MySQL timezone detection bug
Use "DefaultTimeLoc" for "al.TZ" default value
Don't set TZ on alias when t.Location() is empty

You can set your MySQL server timezone on main.go init function.
Example :
orm.DefaultTimeLoc, _ = time.LoadLocation("Europe/Paris")
2017-10-26 14:32:42 +02:00
Abel
b9c8c08c03 Add host env feature. 2017-10-26 19:25:05 +08:00
astaxie
663f22d849 Merge pull request #2893 from melotusme/master
Typo fixed
2017-10-23 06:48:46 -05:00
astaxie
fbaa4d1233 Merge pull request #2898 from skOak/swagger
remove omitempty for swagger.Response.Description, because it's Required according to Swagger2.0 Spec
2017-10-23 06:48:22 -05:00
astaxie
7dc8991140 Merge pull request #2894 from skOak/develop
add custom middleware options for beego.Run()
2017-10-23 06:48:03 -05:00
hemin
0ce70b8c99 remove omitempty for swagger.Response.Description, because it's Required according to Swagger2.0 Spec 2017-10-18 22:34:24 +08:00
astaxie
b169ea4b63 Merge pull request #2896 from tinycedar/master
misc: fix typos
2017-10-17 21:22:27 +08:00
Daniel Lin
72ec4df679 Merge branch 'master' into master 2017-10-17 04:30:59 -05:00
hzlinqien
b91263a254 misc: fix typos 2017-10-17 17:27:03 +08:00
hemin
e91afb1938 add custom middleware options for beego.Run() 2017-10-16 14:55:08 +08:00
zhirong
74eb613919 Typo fixed 2017-10-16 00:06:20 +08:00
astaxie
32d4310861 Merge pull request #2886 from hurisheng/patch-1
add XMLBody method for httplib
2017-10-14 07:57:02 -05:00
astaxie
c56704f3fd Merge branch 'master' into develop 2017-10-14 17:53:40 +08:00
astaxie
c5118e9535 Merge pull request #2889 from lidaobing/fix_typo
fix typo
2017-10-14 03:28:56 -05:00
LI Daobing
9b57566963 fix typo 2017-10-11 14:35:31 +08:00
Silviu Capota-Mera
8d59e7afd1 for the root path, all methods must be covered
use continue instead of return
2017-10-07 13:16:36 -04:00
Silviu Capota-Mera
fd733f76f0 simplify replacement of the base (root) tree 2017-10-07 12:14:28 -04:00
Hu Risheng
37d4bb3df5 add XMLBody method for httplib 2017-10-05 14:34:52 -05:00
Silviu Capota-Mera
5697c6d7cc Remove redundant return to pass gosimple Travis check 2017-09-25 23:17:57 -04:00
Silviu Capota-Mera
51a6162363 Update app.go 2017-09-25 21:45:42 -04:00
Silviu Capota-Mera
5a12b3d020 Add the ability to unregister fixed routes
Certain web application inherit most of the routes from a base application by using the underscore import 
(e.g. import _ "myoldapp.com/routers").
The new application might want to only overwrite certain pages, such as "/about" or "/faq"

The proposed new UnregisterFixedRoute method allows unregistering of the specified paths.
 Usage (replace "GET" with "*" for all methods):
  beego.UnregisterFixedRoute("/yourpreviouspath", "GET")
  beego.Router("/yourpreviouspath", yourControllerAddress, "get:GetNewPage")
The children paths are left intact.
For example, /yourpreviouspath/oldchildsubpath should still continue to function in legacy mode.
2017-09-25 20:52:19 -04:00
Waleed Gadelkareem
bebd2c469d Remove typo 2017-09-13 22:15:40 +02:00
Waleed Gadelkareem
d15e66a4ff check if SetEscapeHTML exists instead of checking Go version 2017-09-13 22:14:41 +02:00
Waleed Gadelkareem
c04d43695c fix dependency go-version for travis 2017-09-13 03:16:33 +02:00
Waleed Gadelkareem
d813334a24 Merge branch 'develop' of github.com:gadelkareem/beego into develop 2017-09-13 03:10:08 +02:00
Waleed Gadelkareem
9fef2f2eb4 Do not escape html if Golang version < 1.7 2017-09-13 03:09:53 +02:00
Waleed Gadelkareem
0c746f4547 Merge branch 'master' into develop 2017-09-13 02:16:50 +02:00
Waleed Gadelkareem
f5c8b1c6ac Merge branch 'master' of github.com:gadelkareem/beego 2017-09-13 02:05:15 +02:00
Waleed Gadelkareem
4921014c64 Add JSON or Apache access log formatting option to config: AccessLogsFormat = JSON_FORMAT or APACHE_FORMAT ref #2738 2017-09-13 02:03:46 +02:00
astaxie
520753415f Merge pull request #2846 from hikenote/master
return template build error rather than log error
2017-09-09 06:42:02 +08:00
astaxie
3162da131d Merge pull request #2858 from astaxie/revert-2854-master
Revert "should use time.Since instead of time.Now().Sub"
2017-09-09 06:29:59 +08:00
astaxie
a7354d2d08 Revert "should use time.Since instead of time.Now().Sub" 2017-09-09 06:29:38 +08:00
astaxie
07a9a2d0f3 Merge pull request #2854 from wgliang/master
should use time.Since instead of time.Now().Sub
2017-09-09 06:29:31 +08:00
wangguoliang
c8c25549e7 should use time.Since instead of time.Now().Sub
Signed-off-by: wgliang <liangcszzu@163.com>
2017-09-07 19:01:34 +08:00
Radar8
6641a436a2 validation: fix ErrorMap, added func AddError(key, message) 2017-09-06 16:49:21 +08:00
iclinux
1dd50fb65f Make parent process exit gracefully.
With beego.BConfig.Listen.Graceful  enabled, when received SIGHUP, we'll fork a child process.
But the parent process still have jobs to finish, So we can't kill the parent process directly.
2017-09-05 11:53:42 +08:00
zhufanmao
4bc4f77c29 return template build error 2017-09-02 17:55:26 +08:00
zhufanmao
ef36ecd376 avoid some proxy not support select command 2017-08-31 20:26:32 +08:00
astaxie
c6cef853c7 Merge pull request #2813 from mlgd/develop
Add IPV6 compatibility
2017-08-23 16:54:59 +08:00
astaxie
33ad8d5db4 Merge pull request #2815 from wisererik/patch-1
Fix the quick start section of the orm/README.md
2017-08-23 16:53:41 +08:00
astaxie
33e6d57754 Merge pull request #2820 from crazcalm/doc_error
fixed mispelled word
2017-08-22 23:18:31 +08:00
Marcus Willock
afa57ca1f2 fixed mispelled word 2017-08-20 23:32:11 +08:00
Erik
510dd02a06 Fix the quick start section of the orm/README.md
Increase the init method by adding the `RunSyncdb` method to resolve the problem that the table is not created.
2017-08-11 11:34:18 +08:00
mlgd
166e88c103 Update input.go 2017-08-09 21:05:06 +02:00
mlgd
51b6adeb24 Add IPV6 compatibility 2017-08-09 10:23:03 +02:00
astaxie
51c19c374a Merge pull request #2801 from nightlyone/patch-1
fix bad error code in seesion handling
2017-08-06 22:29:05 +08:00
astaxie
b23452dc3f Merge pull request #2805 from ninjacn/master
comment edit
2017-08-06 22:28:36 +08:00
astaxie
f61038e6bd Merge pull request #2803 from iamzhout/log_add_milliseconds
add millisecond to timestamp in log output
2017-08-06 22:28:19 +08:00
Tao Zhou
b9117e2ff1 add millisecond to timestamp in log output 2017-08-04 00:11:59 +08:00
姚鹏鸣
5a7a3da909 comment edit 2017-08-03 19:15:32 +08:00
Ingo Oeser
3f4502990a fix bad error code
By providing a unique error code instead of a format specifier without using an error formatting function.
2017-08-03 01:52:24 +02:00
astaxie
e14113aa0e Merge pull request #2656 from BorisBorshevsky/develop
Allow injecting dependencies to controllers
2017-07-30 23:36:52 +08:00
astaxie
d96289a81b Merge pull request #2771 from astaxie/develop
v1.9.0
2017-07-19 00:56:48 +08:00
astaxie
4fc95b0d69 gofmt and golint 2017-07-19 00:52:27 +08:00
astaxie
aa3d6c5363 fix the gosimple 2017-07-19 00:37:42 +08:00
astaxie
5ac0cb929c v1.9.0 2017-07-18 23:58:22 +08:00
astaxie
b27ab53017 fix issue for runMethod and runRouter from context 2017-07-18 23:41:50 +08:00
astaxie
1aba294405 Merge pull request #2740 from xlwcom/master
fix the bugs in the "ParseBool" function in the file of config.go
2017-07-18 13:39:45 +08:00
astaxie
657e55ed59 Merge pull request #2692 from jerson/master
added statusCode and pattern to FilterMonitorFunc
2017-07-17 11:06:09 +08:00
astaxie
621c25396e Merge pull request #2766 from yangsf5/master
sort ControllerComments
2017-07-17 11:02:28 +08:00
astaxie
715ba918f0 Merge pull request #2744 from gnanakeethan/feature/database-migration
[Proposal] Database Migrations;
2017-07-17 10:54:44 +08:00
Gnanakeethan Balasubramaniam
8bb0a70847 Update: Fix in SQL Generation
Signed-off-by: Gnanakeethan Balasubramaniam <gnanakeethan@gmail.com>
2017-07-16 08:48:44 +05:30
Gnanakeethan Balasubramaniam
94e79eddcf Update: removing remnant of revert commit ( a call to function
m.DDLSpec() )

Signed-off-by: Gnanakeethan Balasubramaniam <gnanakeethan@gmail.com>
2017-07-16 08:37:27 +05:30
Gnanakeethan Balasubramaniam
749a4028b4 Revert "Update: removing the need to call DDLSpec in the migration file"
The odds of getting this perfectly up is not good.

This reverts commit d58ad2ee36.
2017-07-16 08:11:10 +05:30
Gnanakeethan Balasubramaniam
fc55c2b57c Update: missed to call DDLSpec in Down migration
Signed-off-by: Gnanakeethan Balasubramaniam <gnanakeethan@gmail.com>
2017-07-16 07:30:53 +05:30
Gnanakeethan Balasubramaniam
d58ad2ee36 Update: removing the need to call DDLSpec in the migration file
Signed-off-by: Gnanakeethan Balasubramaniam <gnanakeethan@gmail.com>
2017-07-16 07:24:58 +05:30
Gnanakeethan Balasubramaniam
cb38ab4f85 Update: fixing a SQL generation code
Signed-off-by: Gnanakeethan Balasubramaniam <gnanakeethan@gmail.com>
2017-07-16 07:10:09 +05:30
shanfeng.yang
fc86f6422d sort ControllerComments 2017-07-15 17:26:20 +08:00
Gnanakeethan Balasubramaniam
d453242e48 Update: moving package to bottom
Signed-off-by: Gnanakeethan Balasubramaniam <gnanakeethan@gmail.com>
2017-07-14 14:42:56 +05:30
Gnanakeethan Balasubramaniam
7c2ec075a4 Update: fixing some methods and adding documentation
Signed-off-by: Gnanakeethan Balasubramaniam <gnanakeethan@gmail.com>
2017-07-13 21:03:30 +05:30
Gerson Alexander Pardo Gamez
c903de41e4 updated sample for FilterMonitorFunc
added pattern to sample
2017-07-12 09:51:37 -05:00
astaxie
e8c8366308 Merge pull request #2754 from imiskolee/develop
supported gzip for req.Header has `Content-Encoding: gzip`
2017-07-12 19:57:29 +08:00
astaxie
4901567bba Merge pull request #2749 from satng/patch-4
oracle插入占位符
2017-07-12 19:49:32 +08:00
MiskoLee
29bcd31b27 supported gzip for req.Header has Content-Encoding: gzip 2017-07-10 21:27:54 +08:00
satng
83a563c0ab oracle插入占位符 2017-07-09 12:25:51 +08:00
Gnanakeethan Balasubramaniam
e888fee4e0 Update: Foreign Key & Comments
Summary: Foreign Key functions are now available

Signed-off-by: Gnanakeethan Balasubramaniam <gnanakeethan@gmail.com>
2017-07-06 20:26:37 +05:30
Gnanakeethan Balasubramaniam
c1ba11f531 Fixing typo
Signed-off-by: Gnanakeethan Balasubramaniam <gnanakeethan@gmail.com>
2017-07-06 14:58:40 +05:30
Gnanakeethan Balasubramaniam
ed558a0e70 Fix: typo due to find and replace migration renamed to m
Signed-off-by: Gnanakeethan Balasubramaniam <gnanakeethan@gmail.com>
2017-07-06 07:45:07 +05:30
Gnanakeethan Balasubramaniam
6b9c3f4824 [Proposal] Database Migrations;
Summary: The database migrations now can be created using the methods on
the migration struct. it does not break any existing migration features.
it upgrades the migration struct and adds few more struct types so that
the migrations can be efficiently generated for create, alter, reverse,
drop.

Current Features:
* Supports creation of columns
   * `m.NewCol("name").SetDataType("VARCHAR(10)").SetNullable("true")`
   * **NOTE** `SetNullable` & `SetDefault` methods should not be called on
   same column for consistency
* Supports addition of primary keys
   * `m.PriCol("id").SetDataType("INT(10)").SetNullable("true")`
   * **NOTE** `setAuto(true)` can be only called on Primary keys
* Supports addition of unique keys
   * `m.UniCol("unique_index","column_name").SetDataType("VARCHAR(23)").SetNullable("true")`
   * **NOTE** `UniCol` can be called again with the same index name to
   add column to the index
* Supports rename of columns
   * `m.RenameColumn("from_name","to_name")`
   * Allows standard column methods and methods such that, `SetOldDefault` allows
   reversibility of renames

* TODO:
   * ForeignKey

Signed-off-by: Gnanakeethan Balasubramaniam <gnanakeethan@gmail.com>
2017-07-06 07:44:48 +05:30
astaxie
7ec819deed fix #2725 big form 2017-07-04 21:16:59 +08:00
astaxie
4cfb3678f8 Merge pull request #2741 from miraclesu/validation
validation: support required option for some struct tag valids
2017-07-04 15:49:36 +08:00
xlwcom
3c17e2a7e6 remove the comments 2017-07-04 11:03:49 +08:00
miraclesu
e72b02b7cc validation: support required option for some struct tag valids 2017-07-03 16:26:23 +08:00
astaxie
82586c70e9 Merge pull request #2683 from jialijelly/master
Provide permission to access old files to everyone
2017-07-03 11:23:49 +08:00
astaxie
cb86bcc9e8 Merge pull request #2728 from miraclesu/validation
validation: support int64 int32 int16 and int8 type on 64-bit platform
2017-07-01 15:35:48 +08:00
xlwcom
234708062a fix the bug in the "ParseBool" function in the file of config.go 2017-06-29 13:32:40 +08:00
miraclesu
6e34f43721 Fix break API change
support int64 on 64-bit platform
2017-06-28 16:56:37 +08:00
Jia Li Ong
3249ec8ebf Merge branch 'master' of https://github.com/jialijelly/beego 2017-06-27 10:49:10 +08:00
Jia Li Ong
31b2b21dbc Merge branch 'master' of https://github.com/jialijelly/beego 2017-06-27 10:48:52 +08:00
Jia Li Ong
d0c1936922 Merge branch 'master' of https://github.com/jialijelly/beego 2017-06-22 19:18:49 +08:00
Jia Li Ong
338a23a12b Merge branch 'master' of https://github.com/jialijelly/beego 2017-06-22 19:18:34 +08:00
Jia Li Ong
932def1ed2 Merge branch 'master' of https://github.com/jialijelly/beego 2017-06-22 18:55:37 +08:00
Jia Li Ong
16b5a11484 Merge branch 'master' of https://github.com/jialijelly/beego 2017-06-22 18:55:25 +08:00
Jia Li Ong
547fbce86c Merge branch 'master' of https://github.com/jialijelly/beego 2017-06-22 18:53:29 +08:00
Jia Li Ong
5a2eea07cb Provide permission to access old log files to everyone 2017-06-22 18:51:52 +08:00
miraclesu
2231841d74 validation: support int64 int32 int16 and int8 type 2017-06-21 14:13:30 +08:00
astaxie
805a674825 Merge pull request #2712 from eyalpost/develop
incorrect error rendering (wrong status)
2017-06-16 13:34:28 +08:00
astaxie
f2925978f1 Merge pull request #2717 from huwenbo/master
fix panic sync: negative WaitGroup counter
2017-06-16 13:26:36 +08:00
astaxie
fe3a224a23 Merge pull request #2724 from JessonChan/develop
AddAPPStartHook func modify
2017-06-16 08:20:45 +08:00
astaxie
2754edc849 Merge pull request #2726 from moqiancong/develop
fix cache/memory fatal error: concurrent map iteration and map write
2017-06-16 08:20:03 +08:00
moqiancong
79f60274a0 fix cache/memory fatal error: concurrent map iteration and map write 2017-06-16 01:26:55 +08:00
JessonChan
a87c1c5e8e AddAPPStartHook func modify 2017-06-15 17:36:37 +08:00
huwenbo
2b00b7d66d fix panic: sync: negative WaitGroup counter 2017-06-13 20:15:43 +08:00
huwenbo
3d9286f089 fix panic: sync: negative WaitGroup counter 2017-06-13 15:34:57 +08:00
huwenbo
55e6c15073 fix panic: sync: negative WaitGroup counter 2017-06-13 15:19:51 +08:00
eyalpost
8b504e7d51 incorrect error rendering (wrong status) 2017-06-12 21:05:40 +03:00
Илья Маслов
47ef2b343e Fix run controller if it set by RumController and RunMethod in Filterfunc 2017-06-09 15:53:03 +03:00
Илья Маслов
80dcdb8645 Fix run controller if it set by RumController and RunMethod in FilterFunc 2017-06-09 15:27:26 +03:00
astaxie
d1c3bd8416 Merge pull request #2701 from eyalpost/develop
correctly handle multiple params with same type
2017-06-09 15:33:37 +08:00
eyalpost
0240e182c6 correctly handle multiple params with same type 2017-06-09 10:15:36 +03:00
Gerson Alexander Pardo Gamez
7f2e3feb3c added pattern to FilterMonitorFunc 2017-06-05 18:21:31 -05:00
Gerson Alexander Pardo Gamez
d15dd2795c added statusCode in FilterMonitorFunc 2017-06-03 15:24:45 -05:00
Jia Li Ong
0ea34fff27 Provide permission to access old log files to everyone 2017-06-02 10:56:55 +08:00
xhzhang
4e8f212069 refactor: #1899 redis cache module refactor
redis cache module refactor, to view the discussion:

  https://github.com/astaxie/beego/issues/1899
2017-05-20 19:56:38 +08:00
xhzhang
eb71d0ea7f Merge remote-tracking branch 'upstream/master' 2017-05-20 19:39:24 +08:00
BorisBorshevsky
b24ddb953c merge from upstram + resolve conflicts 2017-05-20 02:42:00 +03:00
BorisBorshevsky
12f8fbe37f Allow injecting dependencies to controllers 2017-05-20 02:06:28 +03:00
astaxie
5e8312bc23 Merge pull request #2654 from casbin/master
Fix the new repo address for casbin.
2017-05-19 23:34:58 +08:00
Yang Luo
88d07058a5 Fix the new repo address for casbin. 2017-05-19 22:19:31 +08:00
astaxie
cab8458c1c Merge pull request #2651 from astaxie/develop
v1.8.3
2017-05-19 21:19:18 +08:00
astaxie
f0b95c552b Merge pull request #2315 from sch00lb0y/master
issue no:#2261 fix for xsrf panic error
2017-05-19 18:50:56 +08:00
பாலாஜி
ce677202e5 issue no:#2261 fix for xsrf panic error 2017-05-19 14:02:14 +05:30
astaxie
720c323e20 Merge pull request #2652 from gouyang/gouyang/dev
Support timeformat "2006-01-02T15:04:05"
2017-05-19 09:48:35 +08:00
Guohua Ouyang
47e351e11d Support timeformat "2006-01-02T15:04:05"
Fixes #2649

Signed-off-by: Guohua Ouyang <guohuaouyang@gmail.com>
2017-05-19 09:22:27 +08:00
astaxie
248beab557 v1.8.3 2017-05-18 22:55:10 +08:00
astaxie
388a5610fa Merge pull request #2365 from chesedo/RequiredValidationCatchSpaces
[WIP]Have Required validator trim strings to fix #2361
2017-05-18 22:44:15 +08:00
astaxie
41498758fe Merge pull request #2620 from hsluoyz/authz
Add an authorization plugin that supports ACL, RBAC based on casbin.
2017-05-18 18:18:12 +08:00
astaxie
655484b4df Merge pull request #2586 from eyalpost/develop
Automatic Parameter Router
2017-05-18 18:14:49 +08:00
Eyal Post
11b4bf8aaa move to context 2017-05-18 10:38:12 +03:00
Eyal Post
2513bcf584 remove Redirect to avoid confusion 2017-05-18 10:32:51 +03:00
Eyal Post
3e51823c0f move response 2017-05-18 09:05:49 +03:00
Eyal Post
e32a18203b fix gosimple 2017-05-17 21:27:32 +03:00
Eyal Post
ee1d8bc30e fix gosimple 2017-05-17 20:50:41 +03:00
Eyal Post
828cbbdf5d Refactor a bit to consolidate packages 2017-05-17 20:38:59 +03:00
Eyal Post
d54cd4fa5f Merge remote-tracking branch 'upstream/develop' into develop 2017-05-17 20:02:40 +03:00
astaxie
7747e9ec8b Merge branch 'develop' of https://github.com/astaxie/beego into develop 2017-05-17 20:52:53 +08:00
astaxie
9765519f38 Merge pull request #2637 from alexsunxl/develop
allow o.Raw(sql).QueryRows(&container) pass nested struct
2017-05-17 16:45:14 +08:00
astaxie
69f0b94745 fix gosimple 2017-05-16 22:21:43 +08:00
astaxie
3c9b6c99b7 Merge pull request #2643 from rbw0/master
Spelling fixes
2017-05-16 11:26:16 +08:00
Robert Wikman
b5c6eb54d2 Missing PK error spelling fix 2017-05-16 00:58:20 +02:00
Robert Wikman
e1c90bfc09 Table not found spelling fixes 2017-05-16 00:27:57 +02:00
astaxie
91400f10b0 Merge pull request #2640 from franzwilhelm/master
Moved Security to Operation struct to support swagger API security auth
2017-05-14 19:15:20 +08:00
franzwilhelm
c814893d65 add support for global security 2017-05-14 12:13:35 +02:00
alexsunxl
2325090101 add test case that used nested struct test QueryRows 2017-05-14 12:03:34 +08:00
franzwilhelm
40bc52b844 fix security struct placement and formatting 2017-05-14 00:42:09 +02:00
sunxinle
589f3755f0 允许o.Raw(sql).QueryRows(&container) 传入的container包含结构的嵌套 2017-05-12 18:11:42 +08:00
eyalpost
1004678005 popular status codes 2017-05-12 09:57:56 +03:00
eyalpost
0ac2e47162 location=>paramType 2017-05-12 09:28:46 +03:00
eyalpost
b6a35a8944 more tests 2017-05-12 09:25:12 +03:00
Eyal Post
74dc3c7500 tests 2017-05-11 19:32:44 +03:00
Eyal Post
cb4f252a06 defValue -> defaultValue 2017-05-11 17:58:25 +03:00
astaxie
bceefc9075 Merge pull request #2636 from guanly/master
ISSUE2630 使用sqlite,orm中通过filter后的delete删除不成功
2017-05-11 22:04:27 +08:00
guanly
10cd1070f4 使用sqlite,orm中通过filter后的delete删除不成功
https://github.com/astaxie/beego/issues/2630
2017-05-11 21:45:38 +08:00
guanly
9b01b1c63d ISSUE2630 使用sqlite,orm中通过filter后的delete删除不成功
https://github.com/astaxie/beego/issues/2630
2017-05-11 14:49:01 +08:00
Yang Luo
b2e7720fcd Add an authorization plugin that supports ACL, RBAC based on casbin. It requires the built-in HTTP basic authentication by default. 2017-05-04 14:02:21 +08:00
astaxie
83814a76cc hotfix: err nil 2017-05-02 12:47:15 +08:00
Eyal Post
d3a16dca85 Redirect should returns error 2017-05-01 08:57:57 +03:00
astaxie
7452151bee Merge pull request #2611 from astaxie/develop
1.8.2
2017-05-01 13:01:59 +08:00
Eyal Post
1b8f05cef1 golint fixes 2017-04-30 19:28:26 +03:00
Eyal Post
cfb2f68dd6 Merge remote-tracking branch 'upstream/develop' into develop 2017-04-30 18:59:50 +03:00
astaxie
e76423e6dc revert #2518, fix #2605 2017-04-30 23:59:38 +08:00
astaxie
947980b5eb beego 1.8.2 2017-04-30 23:43:46 +08:00
astaxie
44bdf1df63 ignore NilErr 2017-04-30 23:38:48 +08:00
astaxie
79b66ef053 fix the beego ORM test 2017-04-30 22:55:39 +08:00
astaxie
a91e2e9950 add golint check and fix all golints 2017-04-30 22:41:23 +08:00
astaxie
ea3d0690cf golint 2017-04-29 09:13:28 +08:00
astaxie
1c32c011a1 fix misspell 2017-04-28 23:37:40 +08:00
astaxie
64b475d7d6 fix ReadOrCreate test case 2017-04-28 22:58:17 +08:00
astaxie
aa8f7bc146 fix ineffectual 2017-04-28 22:36:28 +08:00
astaxie
3e29078f68 add check ineffect and gofmt 2017-04-28 21:38:08 +08:00
eyalpost
a1bc94e648 dont generate comment if router not found 2017-04-26 01:00:25 +03:00
eyalpost
4cba78afd9 small fixes 2017-04-25 23:42:35 +03:00
ansiz
f311ae9ebe feature: Export function printTree (#2597)
This exports PrintTree function which allow to set Role Based Access Control, Create our own requests statistics...etc
2017-04-25 18:12:03 +02:00
eyalpost
cbd831042a move under context 2017-04-25 18:39:42 +03:00
astaxie
522b3a4a70 Merge pull request #2596 from astaxie/develop
beego 1.8.1
2017-04-25 22:51:23 +08:00
astaxie
cd67f13bf9 add template layout test #2481 2017-04-25 22:21:27 +08:00
astaxie
0f554d9b1a update travis to latest go version 2017-04-25 22:21:08 +08:00
eyalpost
9b79437778 all types working + controller comments generation 2017-04-25 16:00:49 +03:00
astaxie
3742d1178c httplib support delete params fix #2593 2017-04-25 20:42:43 +08:00
xhzhang
b9e3cbbf44 feat: export function printTree
we can do more thing with an exported PrintTree function, such as
  set role base access control,create our own requests statistics.
2017-04-25 12:42:36 +08:00
ansiz
3c0c87f473 Merge pull request #1 from astaxie/master
merge from origin repo
2017-04-25 12:38:32 +08:00
eyalpost
3b29a9c12a Merge remote-tracking branch 'upstream/develop' into develop 2017-04-24 18:23:58 +03:00
astaxie
d03285a0ee Merge pull request #2555 from Liaodd/master
Update ini.go: change the key to lowercase when set a new key for ini configer
2017-04-24 22:37:25 +08:00
astaxie
e810f2e930 add more oracle alias 2017-04-24 21:36:07 +08:00
astaxie
41aac79ac0 Merge pull request #2590 from amrfaissal/fix-2587
Fix warnings raised by gometalinter and gosimple
2017-04-24 21:14:00 +08:00
astaxie
52f916a28a support Go1.8 default GOPATH 2017-04-24 21:10:03 +08:00
eyalpost
864693d2f8 mall fixes 2017-04-24 02:35:04 +03:00
eyalpost
08ea9b3339 Merge remote-tracking branch 'upstream/develop' into develop 2017-04-23 22:07:46 +03:00
Eyal Post
19f4a6ac0b slice support 2017-04-23 21:37:09 +03:00
Faissal Elamraoui
bf6bd6b292 Fixes #2587
Fixes warnings and errors raised by gometalinter and gosimple.
2017-04-23 19:19:05 +02:00
eyalpost
89e01d125c all types implemented 2017-04-23 01:33:50 +03:00
astaxie
3bb4ca5adc Merge pull request #2583 from OlegFX/develop
Fixed InsertOrUpdate bug
2017-04-22 11:19:15 +08:00
OlegFX
712df81c99 Fixed InsertOrUpdate bug 2017-04-21 19:57:04 +03:00
OlegFX
3d7ef599cc Merge pull request #2 from astaxie/develop
Update
2017-04-21 19:50:33 +03:00
eyalpost
9aedb4d05a phase #1 2017-04-21 15:26:41 +03:00
astaxie
453691728a gofmt simplify 2017-04-20 10:56:09 +08:00
astaxie
e7e3ca77ad Merge pull request #2491 from chendx79/master
Fix routing bug for splat matching
2017-04-19 21:20:30 +08:00
astaxie
d3f3956def Merge pull request #2574 from extrlibs/master
Fix the following template reference
2017-04-19 21:18:26 +08:00
astaxie
7206214105 Merge pull request #2575 from PaulChen2016/master
Beego 运行过程中动态增减定时任务时,now的时间需要更新,否则等待时间会不正确
2017-04-19 21:17:38 +08:00
astaxie
b08ace7532 Merge pull request #2577 from ggicci/develop
Fix ini parsing error for multiple users on one machine.
2017-04-19 20:17:45 +08:00
Ggicci
d1a2583972 Fix ini parsing error for multiple users on one machine.
If there were multiple users working on one machine, it's common that
"/tmp/beego" will be owned by one of them, and the others won't be able
to access to it. So, it's better to add an "id-like" postfix to the
temporary directory.
2017-04-19 19:50:11 +08:00
PaulChen2016
0cb8de4218 Beego 运行过程中动态增减定时任务时,now的时间需要更新,否则等待时间会不正确
beego 启动时,执行toolbox.StartTask()
运行过程中,动态添加定时任务(这个是now时间已经不是starttask的时间了,需要刷新)     
     case <-changed:
			now = time.Now().Local()
			continue
2017-04-19 16:22:58 +08:00
Orefa
0cd31a247f fix Template nesting problem 2017-04-19 07:47:05 +08:00
HSoshiant
7886e69236 Update sess_file.go 2017-04-17 12:37:54 -04:00
astaxie
405c170d45 Merge pull request #2556 from zjjott/master
fix: log mode should be 0440 should not be 440
2017-04-10 21:14:34 +08:00
zjjott
932019770d fix: log mode 0440 should not be 440 2017-04-10 17:37:55 +08:00
Liaodd
d5c03f5b8f Update ini.go
change the key to lowercase when set a new key for ini configer
2017-04-10 11:30:23 +08:00
astaxie
3d20c0b8f4 Merge pull request #2543 from Bobochka/fix_route_hander_docs
Fix example for Hander func
2017-04-07 23:04:38 +08:00
Faissal Elamraoui
a4fb4c6a03 Merge pull request #2547 from TrueFurby/patch-1
Update README.md
2017-04-03 20:25:41 +02:00
Ondrej Fabry
a9941b6edc Merge branch 'develop' into patch-1 2017-04-02 13:46:06 +02:00
Ondrej Fabry
6a32b048bd Update README.md 2017-04-02 11:04:08 +02:00
Vladimir Shteinman
fb04d3cff1 Fix example for Hander func 2017-03-30 12:53:12 +03:00
astaxie
5c7673e73d update to 1.8.1 2017-03-29 10:22:27 +08:00
astaxie
54b05377d9 Merge pull request #2466 from gouyang/gouyang/develop
Parse form time by its length
2017-03-29 10:01:03 +08:00
astaxie
f49f3f92ec Merge pull request #2533 from cnxh/redis-session-poolsize
redis poolsize could set to zero
2017-03-29 10:00:28 +08:00
astaxie
b18b94f03b Merge pull request #2539 from astaxie/revert-2421-develop
Revert "close mysql connection"
2017-03-29 09:57:54 +08:00
astaxie
bf469f0b55 Revert "close mysql connection" 2017-03-29 09:57:18 +08:00
astaxie
c12709dbc9 Merge pull request #2536 from ChristophPech/master
Fix for IndexExists in SQLite driver
2017-03-29 09:53:55 +08:00
Christoph Pech
2808a13f07 Fix for IndexExists in SQLite driver, they added the "origin" and "partial" columns to the index_list pragma.
see: https://www.sqlite.org/src/info/2743846cdba572f6
2017-03-28 12:38:27 +02:00
Faissal Elamraoui
a8d48aa5ea Merge pull request #2535 from ketanhwr/patch-1
Update README.md
2017-03-28 10:49:52 +02:00
Ketan Gupta
fdb2660a2a Update README.md 2017-03-28 11:29:20 +05:30
xia hao
7c3a997735 poolsize could set to zero
sometimes we may want disable the redis pool
2017-03-27 23:34:58 +08:00
astaxie
1760f0ceca Merge pull request #2532 from vbalien/patch-1
Fix markdown formatting
2017-03-27 13:34:19 +08:00
Jisu Kim
c387aeeb36 fix markdown formatting 2017-03-27 14:30:42 +09:00
Guohua Ouyang
83d4385f1f Support time.RFC3339
Signed-off-by: Guohua Ouyang <guohuaouyang@gmail.com>
2017-03-25 07:52:43 +08:00
astaxie
ae0a75c464 console debug use diffrent color 2017-03-21 23:55:40 +08:00
astaxie
a05e5a7c09 Merge branches 'master' and 'develop' of https://github.com/astaxie/beego into develop 2017-03-21 23:47:32 +08:00
astaxie
75ca7b77b6 Merge pull request #2518 from sicojuy/develop
Fix set cookie bug, zero max age is not valid.
2017-03-21 09:44:37 +08:00
liaoziqian
b0e2012a17 Fix set cookie bug, zero max age is not valid. 2017-03-21 09:15:30 +08:00
astaxie
12dff072fa Merge pull request #2509 from sergeylanzman/add-gosimple
add go simple support
2017-03-18 13:37:31 +08:00
astaxie
d956444965 Merge branch 'develop' into add-gosimple 2017-03-18 11:20:30 +08:00
astaxie
8dbf9eb0bf Merge pull request #2512 from sergeylanzman/add-unconvert
add unconverted support
2017-03-18 11:05:28 +08:00
astaxie
faa981fb6a Merge pull request #2511 from sergeylanzman/drop-go1.4-1.5-travis
drop support go1.4/5 in travis yml
2017-03-18 11:02:39 +08:00
astaxie
1ea3c13ff5 Merge branch 'develop' into drop-go1.4-1.5-travis 2017-03-18 11:02:15 +08:00
astaxie
46d8fef0ad Merge pull request #2510 from sergeylanzman/travis-add-1.7-1.8
add support go1.7/8 to travis yml
2017-03-18 11:01:27 +08:00
Sergey Lanzman
37c1ffc57a add go simple support 2017-03-17 20:22:20 +02:00
Sergey Lanzman
856fde28dc add unconverted support 2017-03-17 19:45:30 +02:00
Sergey Lanzman
3204d7631b drop support go1.4/5 in travis yml 2017-03-17 19:33:54 +02:00
Sergey Lanzman
f5fc2edfd3 add support go1.7/8 to travis yml 2017-03-17 19:32:31 +02:00
astaxie
21d1267c14 Merge pull request #2501 from sergeylanzman/change-template-error-log
temple parse error write in log as trace. change to error
2017-03-14 20:04:42 +08:00
Sergey Lanzman
3e37b97549 temple parse error write in log as trace. change to error 2017-03-14 12:55:40 +02:00
astaxie
206f736819 Merge pull request #2496 from eyalpost/develop
Don't panic during AddViewPath if adding the same path twice
2017-03-14 12:54:48 +08:00
Eyal Post
24d4a27842 Don't panic during AddViewPath if adding the same path twice 2017-03-13 08:46:57 +02:00
astaxie
46f3ea4f43 Merge pull request #2494 from miraclesu/develop
validation: fix email valid
2017-03-12 22:26:25 +08:00
miraclesu
c9cc642d37 validation: amend email test case 2017-03-12 20:27:09 +08:00
miraclesu
b34853f8cc validattion: add test case for email valid 2017-03-12 19:30:23 +08:00
miraclesu
d41f4c0a3a validation: fix email valid 2017-03-12 19:23:46 +08:00
chendingxing
8e46decc8e fix routing bug for splat 2017-03-10 09:28:25 +08:00
astaxie
323a1c4214 Merge pull request #2485 from astaxie/develop
beego 1.8.0
2017-03-06 21:59:04 +08:00
astaxie
c5f838e785 beego 1.8.0 2017-03-06 21:29:41 +08:00
astaxie
f53e98d11b Merge pull request #2348 from hongliang81/develop
Add Aliyun Logger
2017-03-05 22:45:32 +08:00
astaxie
c2f7f3efa7 Merge pull request #2380 from fugr/config
config:fix handle include other.conf
2017-03-05 22:41:45 +08:00
astaxie
1e5051e112 Merge pull request #2381 from chesedo/OrmStrongRelationships
Add strong relationship support to orm
2017-03-05 22:39:45 +08:00
astaxie
fa44ff54bb Merge pull request #2479 from marianofevola/develop
Fix typo
2017-03-05 22:07:08 +08:00
astaxie
4c6de379e0 Merge pull request #2480 from ysqi/fix
Fixed #2456 and strengthen bind
2017-03-05 22:06:46 +08:00
ysqi
6d997366ed Fixed 2456 and strengthen bind 2017-03-04 20:23:55 +08:00
Mariano Fevola
e0250e2871 Fix typo 2017-03-03 16:24:02 +00:00
astaxie
3d629e7320 Merge pull request #2468 from antony66/ssdb_cache_fix_is_exist
Fixes issue #2467 with ssdb cache IsExist
2017-02-27 18:58:53 +08:00
Anton Khalikov
74045090cc This fixes issue #2467 with ssdb cache IsExist 2017-02-27 14:14:16 +05:00
Guohua Ouyang
49fffe3ebe Parse form time by its length
Fix #2451

Signed-off-by: Guohua Ouyang <guohuaouyang@gmail.com>
2017-02-27 14:43:16 +08:00
astaxie
50e294be32 fix the broken test 2017-02-27 09:41:15 +08:00
astaxie
b235b48de4 Merge branch 'develop' of https://github.com/astaxie/beego into develop 2017-02-26 22:21:37 +08:00
astaxie
28011a5835 fix #2462 2017-02-26 22:20:11 +08:00
astaxie
b03b0779dc Merge pull request #2455 from jyk1987/develop
Improve json coding performance
2017-02-25 19:01:12 +08:00
jiayukun
393e4c4969 Improve json coding performance 2017-02-22 17:38:26 +08:00
astaxie
1d49a4bcbd Merge pull request #2417 from eyalpost/develop
support for multiple view paths
2017-02-13 12:37:17 +08:00
Eyal Post
fc2c0f4fba Don't allow AddViewPath after beego run 2017-02-11 22:00:30 +02:00
astaxie
2117aecf65 Merge pull request #2428 from awengo/master
Add http methods
2017-02-11 00:31:43 +08:00
awengo
8a2b697625 Add http methods 2017-02-10 17:45:47 +09:00
astaxie
be586572e0 Merge pull request #2423 from ansiz/master
Add config field EnableErrorsRender
2017-02-10 13:19:20 +08:00
astaxie
4e047bd483 Merge pull request #2427 from code1986/develop
Develop
2017-02-10 13:17:21 +08:00
liming
db67ffbb94 1.simplify reading and writing file code
2.add apiauth test
2017-02-10 09:35:23 +08:00
astaxie
90b03d34cc Merge pull request #2421 from code1986/develop
close mysql connection
2017-02-09 14:36:39 +08:00
liming
872a964145 1.add "defer f.close()" in SessionRead to fix file handle leak if DecodeGob failed
2.rewrite SessionRegenerate
2017-02-09 14:18:30 +08:00
liming
dade92d98b close mysql connection 2017-02-09 14:16:23 +08:00
Eyal Post
dfa74faf43 support for multiple view paths 2017-02-07 22:18:33 +02:00
astaxie
95562cff41 Merge pull request #2406 from xqbumu/patch-1
fix the bug to prevent rewrite t
2017-02-07 11:07:37 +08:00
xhzhang
9b714a7518 Add config field EnableErrorsRender
Add config field EnableErrorsRender to disable errors output
  with the template data, sometimes we do not want errors output
  with it even in dev mode, especially in API projects.
2017-02-06 12:33:15 +08:00
astaxie
2a660820c9 Merge pull request #2389 from amrfaissal/feature-env-support
Package env for working with environment variables inside Beego
2017-01-23 21:15:06 +08:00
astaxie
b55e20ac60 Merge pull request #2395 from duyazhe/fix_bug_orm_ne
fix filter with __ne bug
2017-01-23 21:12:58 +08:00
astaxie
b0dcb5b91d Merge pull request #2400 from kerwin/master
Add GetCond func to querySet
2017-01-23 21:12:29 +08:00
kerwin
5c76f62103 Add GetCond func to querySet 2017-01-18 17:04:23 +08:00
Faissal Elamraoui
126dbdae2f use BeeMap instead of a regular map 2017-01-16 10:08:53 +01:00
杜亚哲
24d8290a3f fix filter with __ne bug 2017-01-16 10:32:33 +08:00
Faissal Elamraoui
957c0630c0 moved the env package to config/ 2017-01-14 10:15:02 +01:00
卜木
e32d173b0d fix the bug to prevent rewrite t
the t have paresed in line 212.
2017-01-14 15:03:49 +08:00
Faissal Elamraoui
fbc9f8e640 Package env for working with env variables inside Beego
The package env makes it trivial to work with environment variables.
It allows getting values with defaults as a fallback.
New ENV variables can be set safely on the current process environment.
2017-01-13 18:10:25 +01:00
chesedo
82d2ace3bd Add strong relationship support to orm 2017-01-11 20:16:38 +02:00
fugr
3fa7fc6e41 config:fix handle include other.conf
When include other.conf,other.conf is either absolute directory or under beego in default temporary directory(/tmp/beego).
maybe replace by current directory is better.
2017-01-11 18:55:53 +08:00
Faissal Elamraoui
d1b58a00ce Merge pull request #2373 from fugr/config
avoid creating tmp files to read/parse config
2017-01-11 09:34:57 +01:00
fugr
6a2ee371a5 avoid creating new file to implements Config
There is no need to create new file in ParseData(data []byte) (Configer, error).Tet's make code simply.
2017-01-09 21:04:11 +08:00
chesedo
a8a2dffc59 Have Required validator trim strings to fix #2361
This will cause the Required validator not to consider fields that has
only spaces or new lines to be regarded as valid. This is done by
checking if the trimmed version of the string is valid.
2017-01-06 10:12:22 +02:00
astaxie
9266ece7a4 fix the retried 2017-01-05 18:27:23 +08:00
洪亮
09c405990c Add Aliyun Logger 2017-01-04 15:53:20 +08:00
astaxie
61e694f388 add retry 2017-01-03 22:50:45 +08:00
astaxie
195c9b24eb Merge pull request #2359 from kbynd/patch-1
content-length not set in case EnableGZIP=true
2017-01-02 11:49:11 +08:00
kbynd
2f6da122fd Update output.go 2017-01-02 09:17:17 +05:30
kbynd
f0d1d7149b Update output.go 2016-12-31 16:14:38 +05:30
kbynd
96387e9a9b EnableGZip=true,then content-length header missing
This results in responses with Content-Type as gzip as opposed to original content type.
This affects ServeJSON() function.
2016-12-31 16:04:34 +05:30
Faissal Elamraoui
86f6470fb2 Merge pull request #2353 from skariuki/master
Fixed typo in orm/models_boot.go
2016-12-29 22:50:41 +01:00
Faissal Elamraoui
d77160dafe ignore .vscode folder 2016-12-29 22:30:56 +01:00
Kariuki, Stanley (Contractor)
caca5e37ba fixed typo in models_boot 2016-12-29 12:26:20 -05:00
Faissal Elamraoui
189c73986b Merge pull request #2351 from amrfaissal/add-safemap-count
Add Count method to BeeMap struct
2016-12-29 11:42:47 +01:00
Faissal Elamraoui
fe21305bb3 Removes redundant check if key exists in BeeMap 2016-12-29 11:11:39 +01:00
Faissal Elamraoui
75ec8d33a2 Rewrite safemap_test suite 2016-12-28 12:44:35 +01:00
Faissal Elamraoui
d736d0ca87 Adds Count method to BeeMap struct
This adds a Count() method to BeeMap struct that returns the number of
items within the safe map.
2016-12-28 12:44:35 +01:00
astaxie
99093693c8 Merge pull request #2346 from legendtkl/master
Modify func camelString() to be more robust
2016-12-26 20:24:49 +08:00
legendtkl
c9c284be27 Modify func camelString to be more robust
1. In previous edition, for case "pic_url_1", the func will return
"PicUrl_1", but "PicUrl1" seems to be more reasonable.
2. More test cases please refer to utils_test.go
2016-12-25 21:09:06 +08:00
astaxie
fa12dcf792 Merge pull request #2341 from kabab/content_type
Changing content type for template
2016-12-23 23:06:52 +08:00
astaxie
b93f5c6f9c Merge pull request #2311 from amrfaissal/fix-2310
Ability to register pre/post signal handlers
2016-12-23 20:06:25 +08:00
astaxie
f9791c1221 Merge pull request #2319 from mlgd/patch-1
Remove a regression on AppPath
2016-12-23 20:03:32 +08:00
Amine KABAB
8fac2d8d58 Don't rewrite content-type 2016-12-14 17:19:31 +00:00
mlgd
e90f4bee1a Remove a regression on AppPath
The application path is incorrect on Windows with the command line "go run". AppPath is assigned to the temp directory instead the folder project
2016-12-09 09:37:10 +01:00
Faissal Elamraoui
eb50221a15 Added method to register Pre/Post signal handlers 2016-12-06 13:48:31 +01:00
Faissal Elamraoui
fc4801494d Added hookable signals 2016-12-06 13:48:31 +01:00
astaxie
eba6afd6fb Merge pull request #2307 from CodeJuan/master
set perm of rotated log to 440
2016-12-06 15:10:00 +08:00
astaxie
81328b72fa Merge pull request #2309 from mengskysama/patch-1
statistics lock
2016-12-06 15:03:10 +08:00
mengskysama
c0c113036b statistics lock 2016-12-06 14:57:15 +08:00
codejuan
b788d74fd1 set perm of rotated log to 440 2016-12-06 12:44:00 +08:00
astaxie
90999717dd Merge branch 'develop' 2016-12-05 23:14:26 +08:00
astaxie
a20ccde90d beego 1.7.2 2016-12-05 22:58:29 +08:00
astaxie
d548ddeb5b Merge pull request #2267 from centos-ren/develop
Fix :supervisor work dir
2016-12-05 22:57:38 +08:00
astaxie
de99ac5da5 Merge pull request #2197 from OlegFX/master
policies implementation
2016-12-05 22:45:07 +08:00
astaxie
e2d9d34c75 Merge pull request #2272 from szyhf/Fix#2263
Another Fix to #2263
2016-12-05 22:40:54 +08:00
astaxie
bdb525831d Merge pull request #2293 from DusanKasan/develop
resolves #2291, introduces AndNotCond/OrNotCond to orm.Condition
2016-12-05 22:40:35 +08:00
astaxie
22dba90ec4 Merge pull request #2305 from songtianyi/fixtypo-Getfiles
typo fix in comments, Getfiles-->GetFiles
2016-12-05 15:09:57 +08:00
songtianyi
7af6dad58e typo fix in comments, Getfiles-->GetFiles 2016-12-05 12:49:21 +08:00
astaxie
5af26446ec Merge pull request #2299 from amrfaissal/fix-2294
Fix xml.GetSection() function which causes a panic
2016-11-30 14:25:14 +08:00
Faissal Elamraoui
39d40ba8fa This fixes #2294 2016-11-29 14:55:57 +01:00
Faissal Elamraoui
5bc3e30653 Added ToString method which converts values of any type to string 2016-11-29 14:55:56 +01:00
Dusan Kasan
34e2b26b99 resolves #2291, introduces AndNotCond/OrNotCond to orm.Condition 2016-11-28 09:49:06 +01:00
astaxie
24015e9ace Merge pull request #2285 from cat2neat/fix-bodyclose
Fix http body may not be closed
2016-11-20 19:48:09 +08:00
cat2neat
9ff88f0b35 Fix http body may not be closed 2016-11-20 05:16:52 +00:00
astaxie
27c59a8017 Merge pull request #2278 from mgenov/err_fix
beego/session: return proper error when session is not found
2016-11-13 16:03:55 +08:00
Miroslav Genov
a74ebaa1eb beego/session: return proper error when session is not found
Parent errs was returned instead of err which is returned from the last
statement.
2016-11-13 10:01:29 +02:00
Back
b5c29d6143 Fix #2263
Update db_mysql.go instead of db.go, in order to avoid affect other database.
2016-11-08 13:39:31 +08:00
Daniel
0a822209c8 Fix :supervisor work dir 2016-11-08 11:14:48 +08:00
astaxie
3baac14095 Merge pull request #2257 from xiaoqiang0/develop
swagger: add 'Default' for Parameter
2016-11-07 22:48:06 +08:00
Zhang Qiang
ef3655877a swagger: add 'Default' for Parameter 2016-11-03 22:59:23 +08:00
astaxie
5a8c40710c Merge pull request #2228 from Hepri/develop
Rework getFlatParams for time.Time
2016-10-30 10:48:49 +08:00
astaxie
b635af5a8c Merge pull request #2248 from smacker/RouterPattern-in-ctx
Add RouterPattern to context.Input
2016-10-30 10:48:15 +08:00
Maxim Sukharev
683e6856ef Add RouterPattern to context.Input
Right now beego adds this param only in dev mode, but I noticed that it's very useful to have in prod environment to.
My current use case - filter that sends logs in newrelic. Pattern there will help a lot to generate correct transaction name.
2016-10-28 10:44:16 +07:00
Sergey Shcherbina
8beefc8bfd Fixed bug when all "time.Time" params in raw sql queries formatted as time 2016-10-17 21:51:31 +05:00
astaxie
e430de3307 Merge pull request #2223 from tailnode/develop
修复windows上app.conf中include其他配置文件时找不到文件的BUG
2016-10-14 21:11:25 +08:00
mengyuan
2b442e842e fix path issue in windows 2016-10-14 16:52:03 +08:00
astaxie
41633900da Merge pull request #2218 from WatchtowerSecurity/NameFix
Name fix
2016-10-13 21:24:11 +08:00
astaxie
aaf6e775d6 Merge pull request #2216 from WatchtowerSecurity/httponlyfix
HTTPOnly Configurable
2016-10-13 21:19:28 +08:00
astaxie
2f6fc3f62b Merge pull request #2213 from axyu/develop
fix log func call depth bug
2016-10-13 21:18:54 +08:00
astaxie
84310b1652 Merge pull request #2205 from jirfag/master
add GetUint(8|16|32|64) to controller
2016-10-13 21:17:54 +08:00
astaxie
5ceac1dd04 string convert int fail use math/big fix #756 2016-10-12 15:04:31 +08:00
GrimTheReaper
51b31c6cb0 Changed the name to match. 2016-10-11 11:06:52 -05:00
GrimTheReaper
5488a5bbd7 Forgot to fix it here 2016-10-11 11:06:22 -05:00
GrimTheReaper
33f7f46670 Updated the name 2016-10-11 10:49:19 -05:00
GrimTheReaper
3c05eafbc4 HTTP Only Configurable 2016-10-10 09:50:34 -05:00
yuanxuan
dfa9e03980 fix log func call depth bug 2016-10-09 15:19:21 +08:00
astaxie
53e996d4c3 Merge pull request #2211 from ihippik/patch-2
Default values
2016-10-08 17:52:07 +08:00
Konstantin
b151a9616e Default values 2016-10-08 11:28:47 +03:00
Denis Isaev
1effb6ce30 add GetUint(8|16|32|64) to controller 2016-10-02 07:42:06 +00:00
olegdemchenko
0be05eb47c policies implementation 2016-09-28 21:21:07 +03:00
astaxie
1090ca0154 Merge pull request #2190 from szyhf/develop
fix to advice in #2187
2016-09-28 20:17:41 +08:00
astaxie
a328584238 Merge pull request #2193 from LyricTian/develop
httplib add CheckRedirect
2016-09-28 20:16:48 +08:00
lyric
f19ad3fdd3 httplib add CheckRedirect 2016-09-28 18:04:51 +08:00
Back
836be7ab9a fix to advice in #2187
Clear BConfig.Log.Outputs's default "console" while user has set "LogOutputs" in config file.
2016-09-28 16:20:41 +08:00
astaxie
bba04dd864 Merge pull request #2184 from rahal/master
Emailer : Should use config Username only if no From is provided.
2016-09-28 07:56:12 +08:00
rahal
9499b3eb90 Emailer : Should use config Username only if no From is provided.
Should fix the case where Username is not an email.
2016-09-27 16:21:41 +01:00
astaxie
9f6bbe3c51 add foundation link 2016-09-23 14:16:16 +08:00
astaxie
2d87d4feaf Merge branch 'master' into develop 2016-09-22 23:18:45 +08:00
astaxie
15a45ccc7b change to 1.7.1 2016-09-22 23:18:22 +08:00
astaxie
e0c59fcf0b add more comments 2016-09-22 23:17:41 +08:00
astaxie
083f697c59 Merge pull request #2173 from axyu/develop
fix a spelling mistake
2016-09-21 19:45:46 +08:00
yuanxuan
a5a6546b91 fix a spelling mistake 2016-09-21 19:33:12 +08:00
astaxie
9cafbf6a21 Merge pull request #2170 from ysqi/develop
Support load app config before test Beego
2016-09-19 20:55:20 +08:00
ysqi
faba0d7273 Support load app config before test Beego 2016-09-19 18:38:56 +08:00
ysqi
c3116d3601 Merge branch 'astaxie/develop' into develop 2016-09-19 18:16:47 +08:00
astaxie
868e14b8ba fix #2017 2016-09-15 20:04:45 +08:00
astaxie
421bf97b84 Support custome recover func fix #2004 2016-09-15 12:16:24 +08:00
astaxie
c16507607c fix #2161 2016-09-15 11:11:34 +08:00
astaxie
2b7dd85b92 access log add client request ip 2016-09-15 10:58:46 +08:00
astaxie
a58115fed2 orm log delete repetition time 2016-09-15 10:54:21 +08:00
astaxie
f9b5b0f551 Merge pull request #2162 from sergeylanzman/develop
improve Swagger
2016-09-15 08:56:27 +08:00
Sergey Lanzman
e53c147129 improve Swagger
1. Add yaml
2. Fix typo scurity => security
3. Make license optional
2016-09-15 00:15:02 +03:00
Sergey Lanzman
da0e6e790d Update swagger.go 2016-09-14 23:36:38 +03:00
astaxie
58ffc6f5f8 fix #1877 2016-09-13 22:43:40 +08:00
astaxie
d5fb74aa94 Merge pull request #2158 from simpleelegant/develop
Add support "SELECT FOR UPDATE" to orm. Resolve issue #2157
2016-09-12 21:48:14 +08:00
Wang Yujian
11247d41a7 Add support "SELECT FOR UPDATE" to orm. Resolve issue #2157 2016-09-12 20:07:30 +00:00
astaxie
5b21c7cd71 fix #1802 2016-09-12 21:13:21 +08:00
astaxie
dd0f05b1f1 fix the method color 2016-09-11 22:00:14 +08:00
astaxie
a32241e7d3 fix #2142 2016-09-11 21:27:27 +08:00
astaxie
0ef357ebd7 session:output error 2016-09-11 21:02:11 +08:00
astaxie
32dd976620 Merge pull request #2146 from philchia/develop
Fix the typo
2016-09-08 17:42:10 +08:00
Phil
fcd8a2024e Add jianliao and slack log adapter 2016-09-08 17:21:11 +08:00
Phil
30661472c8 Fix the typo 2016-09-07 13:33:11 +08:00
astaxie
6ced26660e Merge branch 'develop' of https://github.com/astaxie/beego into develop 2016-09-06 23:05:54 +08:00
astaxie
7d6c45d4c9 add RegisterModelWithSuffix #2140 2016-09-06 23:05:41 +08:00
astaxie
98740fddac Merge pull request #2138 from kbynd/patch-1
RequestURI captures the signature field as well.
2016-09-04 16:52:59 +08:00
kbynd
6d3042f5e5 RequestURI captures the signature field as well.
This in turn results is failure of signature based validation. So what is need is only "/api/resource/action". which is given by ctx.Input.URL()
2016-09-04 11:36:17 +05:30
astaxie
8b9d6eee1a Merge pull request #2132 from Zaaksam/master
beego.ParseForm() improvement
2016-09-02 16:23:14 +08:00
Zaaksam
11ef5929aa update TestParseForm 2016-09-02 16:08:04 +08:00
astaxie
c697b98006 enhancement 2016-09-01 23:28:34 +08:00
Zaaksam
7c2e563879 beego.ParseForm() improvement 2016-09-01 15:04:57 +08:00
astaxie
56aa224a6e simplfy the code 2016-08-31 22:47:31 +08:00
astaxie
8c37a07adb optimize the ORM 2016-08-31 00:07:19 +08:00
astaxie
161c061376 fix cache/memcache test 2016-08-30 23:24:30 +08:00
astaxie
aa091cea42 improvement the error if use &&Struct 2016-08-30 22:02:11 +08:00
astaxie
7df74c0a30 fix #1521 2016-08-30 21:24:56 +08:00
astaxie
1e1e900278 fix #2126 2016-08-30 21:00:27 +08:00
astaxie
fb2343567b fix #2125 2016-08-30 20:40:46 +08:00
astaxie
3f67c62dd8 revert the snakeString 2016-08-30 00:15:02 +08:00
astaxie
bb860d2752 Merge pull request #2124 from astaxie/revert-2071-issue_accept_encoding
Revert "route variables should not have underline"
2016-08-29 13:42:53 +08:00
astaxie
f280dab880 Revert "route variables should not have underline" 2016-08-29 13:42:40 +08:00
astaxie
7283aead42 Merge pull request #2116 from raphael10241024/self
fix#2039 & test
2016-08-24 23:15:53 +08:00
YakunZ
0ad4038d9f fix#2039 & test 2016-08-24 16:04:22 +08:00
astaxie
227678c2ef Set SetLogFuncCallDepth default to 4 2016-08-23 23:48:47 +08:00
astaxie
c611da2e3c Merge pull request #2112 from lday0321/master
log output format improvement
2016-08-23 23:18:10 +08:00
chenlei106
00e986cd3b log output format improvement
move log level info ahead to filename info, better readability
2016-08-23 16:16:57 +08:00
astaxie
bed907653e Merge pull request #2102 from tnextday/develop
update swagger ParameterItems
2016-08-22 11:42:22 +08:00
tnextday
7253ff2f8c update schema define 2016-08-20 15:03:41 +08:00
tnextday
715c2c4312 Merge commit 'efbde1ee77517486eac03e814e01d724ddad18e6' into develop 2016-08-20 11:22:17 +08:00
tnextday
9224cd3ef7 add ParameterItems in Parameter 2016-08-20 11:22:03 +08:00
astaxie
efbde1ee77 add *Item into Schema 2016-08-19 23:52:19 +08:00
astaxie
8b525b1aa5 fix #1656 2016-08-19 00:31:46 +08:00
astaxie
86b3162aff fix #1695 update docs 2016-08-19 00:11:19 +08:00
astaxie
3c016a0b2d Merge pull request #2100 from tnextday/develop
update swagger define
2016-08-18 23:29:06 +08:00
tnextday
ffd748bf75 update swagger 2016-08-18 22:26:15 +08:00
tnextday
1c54ff27c4 update swagger define 2016-08-18 21:24:54 +08:00
astaxie
7760d24761 fix the typo 2016-08-17 23:52:34 +08:00
astaxie
3672f96a9d fix the typo 2016-08-17 22:56:21 +08:00
astaxie
68311b286e gofmt -s -w . 2016-08-17 22:49:30 +08:00
astaxie
bed1d9bd27 update the performance 2016-08-17 22:33:36 +08:00
astaxie
44a57e86dd fix #2090 2016-08-17 22:05:54 +08:00
astaxie
3362f83662 change to v1.7.0 2016-08-16 23:54:52 +08:00
astaxie
7813cb5783 Merge pull request #2096 from Maxgis/feature_session
session.NewManager second params shoube be a object not a string
2016-08-16 23:51:35 +08:00
maxin
ef0d3d80dc set session.managerconfig public 2016-08-13 21:07:27 +08:00
astaxie
47b238728d Merge branch 'develop' of https://github.com/astaxie/beego into develop 2016-08-13 14:44:22 +08:00
astaxie
1b4f30e11e update swagger 2016-08-13 14:43:56 +08:00
astaxie
61c9387edd Merge pull request #2085 from danielscottt/reset-params
adds ability to reset params after a filter runs
2016-08-09 07:24:08 +08:00
astaxie
957db1362f update swagger definistion 2016-08-08 16:45:11 +08:00
dan pittman
0e786fa4af adds ability to reset params after a filter runs
When a filter is run _after_ the router completes, it's input params,
such as `":splat"` will have been overwritten by the filter's router pass.
This commit adds the ability to tell the router to revert to the previous input
params after running a filter.
2016-08-07 07:44:30 -07:00
astaxie
01c3812520 Merge pull request #2086 from Maxgis/issue_accept_encoding
Refactoring
2016-08-07 16:25:51 +08:00
maxin
ce6f19871c Refactoring 2016-08-06 21:13:58 +08:00
astaxie
74778bb9d4 Merge pull request #1900 from redfoxli/patch-1
close socket when http client request over
2016-08-02 10:01:53 +08:00
astaxie
7b542e612f Merge pull request #1964 from qAison/master
fix fk field null value
2016-08-02 10:00:24 +08:00
astaxie
3ca68f9e30 Merge pull request #1976 from ysqi/develop
Fxied bug and Optimized code
2016-08-02 09:58:58 +08:00
astaxie
1a52a34544 Merge pull request #2003 from GuyCheung/develop
add os.Chmod when create log file
2016-08-02 09:57:51 +08:00
astaxie
86528c7b3c Merge pull request #2030 from saturn4er/feature/add_template_prefix_field
Add template prefix field to controller
2016-08-02 09:54:01 +08:00
astaxie
ce6d673933 Merge pull request #2045 from Maxgis/master
avoid  error when the  callback function not exisit
2016-08-02 09:50:52 +08:00
astaxie
c2aeab78aa Merge pull request #2053 from fudali113/develop
orm insert or update
2016-08-02 09:40:43 +08:00
astaxie
0cad8207ec Merge pull request #2071 from Maxgis/issue_accept_encoding
route variables should not have underline
2016-08-01 14:28:25 +08:00
maxin
6f0a985755 update test 2016-07-30 23:14:29 +08:00
maxin
15c048d6ca update test 2016-07-30 22:07:35 +08:00
maxin
d5c339530a remove debug 2016-07-30 22:05:59 +08:00
maxin
b89bfe76d0 update route variables should not have underline 2016-07-30 21:57:23 +08:00
astaxie
125030800b Merge pull request #1997 from amrfaissal/newfeature-enhanced-logs
Enhanced logging during DEV mode
2016-07-29 21:37:22 +08:00
astaxie
e4fe54f6cd Merge pull request #2067 from Maxgis/issue_accept_encoding
reflection
2016-07-29 09:59:59 +08:00
Faissal Elamraoui
d85293b7c0 Fixed bug and added more tests 2016-07-28 11:37:28 +02:00
Maxgis
5d1e60b468 reflection 2016-07-28 11:56:55 +08:00
Faissal Elamraoui
2b867f8152 Removed external dependency 2016-07-27 17:42:28 +02:00
astaxie
909afa9352 Merge pull request #2065 from Maxgis/issue_accept_encoding
remove not support encoding
2016-07-27 14:13:13 +08:00
astaxie
d08e3d1b11 Merge pull request #2064 from Maxgis/feature_static
redirect path should add  query params
2016-07-27 12:55:21 +08:00
Maxgis
5485e1334f remove not support encoding 2016-07-27 09:31:53 +08:00
Maxgis
4b3ed53158 redirect should add query params 2016-07-26 19:54:10 +08:00
“fudali113”
cacf6cde19 update db.go 2016-07-26 14:27:22 +08:00
“fudali113”
4e10100575 update orm_test 2016-07-26 12:44:16 +08:00
“fudali113”
f471ee9025 update orm_test 2016-07-26 12:19:06 +08:00
“fudali113”
182a21172f Optimize the code logic 2016-07-26 11:15:59 +08:00
astaxie
02330c6085 Merge pull request #2062 from Maxgis/feature_static
减少没有必要的代码以及静态前缀前面有/
2016-07-25 22:19:38 +08:00
Maxgis
e951c555e4 Merge branch 'astaxie-develop' into feature_static 2016-07-24 18:01:49 +08:00
Maxgis
6a4ebc67ac merge 2016-07-24 18:01:19 +08:00
Maxgis
33ef34b95d 减少没有必要的代码以及静态前缀前面有/ 2016-07-24 15:29:34 +08:00
“fudali113”
bf17558d06 update “modification hardcode 2 2016-07-22 12:25:30 +08:00
“fudali113”
e0e888ab8f update “modification hardcode 2016-07-22 12:10:37 +08:00
“fudali113”
3583ad8cc0 update annotation 2016-07-21 15:49:55 +08:00
“fudali113”
e2316c4b9e update 2016-07-20 17:28:26 +08:00
“fudali113”
6d1b203bca update 2016-07-20 16:52:14 +08:00
“fudali113”
50c5df32b1 update 2016-07-20 16:26:02 +08:00
“fudali113”
530c32017c update 2016-07-20 15:33:30 +08:00
“fudali113”
ec521ad166 update 2016-07-20 15:13:18 +08:00
“fudali113”
4b8ecced83 orm insert or update 2016-07-20 14:37:05 +08:00
astaxie
d11823548b Merge pull request #2050 from simpleton/bug/original_scheme
fix(context): retrieve scheme from X-Forwarded-Proto when it isn't none
2016-07-19 11:13:14 +08:00
simsun
ee26279311 fix(context): retrieve scheme from X-Forwarded-Proto when it isn't none 2016-07-19 00:36:51 +08:00
maxin[马鑫]
8099a81b7a avoid error when the callback function not exisit 2016-07-15 19:13:35 +08:00
saturn4er
0943ef9e74 Add TplPrefix to TplName also. 2016-07-14 11:48:49 +03:00
astaxie
a2e63a3820 Merge pull request #1993 from NerdsvilleCEO/develop
Add meta fields with required flag on RenderForm
2016-07-14 10:47:21 +08:00
astaxie
a08e937cf0 Merge pull request #2032 from ShevYan/make-go-vet-pass
use keyed fields to pass go vet
2016-07-14 10:38:05 +08:00
shev_yan
9ab5f6d808 use keyed fields to pass go vet 2016-07-06 12:53:47 +08:00
saturn4er
fee06a23bd Add template prefix field to controller 2016-07-03 14:44:11 +03:00
Joshua Santos
e0393b721c Change meta to required, and refactor a bit to cover edge cases 2016-06-30 10:32:53 -07:00
Joshua Santos
84b6bef7d0 Required field useful for not only input 2016-06-28 16:39:09 -07:00
Joshua Santos
8917fe44a9 Add test functions 2016-06-28 16:31:45 -07:00
Joshua Santos
21c7821692 Add test function 2016-06-28 16:24:32 -07:00
Joshua Santos
f9f92b4f61 Merge meta tag into parseFormField 2016-06-28 15:19:58 -07:00
Faissal Elamraoui
c893b3472c added dep to .travis.yml 2016-06-24 15:51:59 +02:00
Faissal Elamraoui
479dfdbd40 added support for Windows terminals 2016-06-24 15:38:18 +02:00
astaxie
1f68e5a705 Merge pull request #2006 from victorpopkov/develop
Add support for time.Time pointer in struct types
2016-06-24 12:33:37 +08:00
Victor Popkov
415b9cf310 add support for time.Time pointer in struct types
Allow to use pointer *time.Time as a type in combination with orm tags in struct. This enables to treat them as "empty" in JSON marshaling/unmarshaling when using 'json:"null,omitempty'.
2016-06-22 16:57:05 +03:00
astaxie
ed474b517d Merge pull request #1979 from ysqi/ormfix
ignore case of tag and fixed bug for columName
2016-06-22 12:00:37 +08:00
GuyCheung
9572fdcf9a update error on type of w.Perm; change unit test perm value 2016-06-22 09:57:16 +08:00
GuyCheung
cb3f240f44 add os.Chmod when create log file 2016-06-21 15:52:31 +08:00
Faissal Elamraoui
844a3b0ffd removed unused import 2016-06-17 17:47:12 +02:00
Faissal Elamraoui
448be6e58c added compatibility for go1.4 2016-06-17 17:39:32 +02:00
Faissal Elamraoui
2bd743fcff Enhanced logging during DEV mode 2016-06-17 15:56:52 +02:00
Joshua Santos
0d3a806c23 Add meta fields with required flag 2016-06-15 17:17:50 -07:00
ysqi
2c1cea08dd New func to find router info for context 2016-06-05 14:03:20 +08:00
ysqi
3f016840db fixed test error 2016-06-04 10:41:55 +08:00
ysqi
d528fafd43 ignore case of tag and fixed bug for columName 2016-06-03 22:06:43 +08:00
ysqi
b7e3402995 Sport Error exeception for outside 2016-06-01 21:30:04 +08:00
ysqi
b807362c39 Reset 2016-06-01 20:33:10 +08:00
ysqi
d9b05e6b3f Print complete URL after running 2016-06-01 20:18:11 +08:00
ysqi
e9f967102c Fixed parese ini file with empty space line 2016-06-01 19:58:35 +08:00
ysqi
2e0bcf611c go fmt 2016-06-01 19:57:08 +08:00
ysqi
2ebf3cd450 Merge branch 'astaxie/develop' into develop 2016-06-01 19:54:35 +08:00
astaxie
1fe2226c11 Merge pull request #1968 from wy65701436/develop
modify the error log for registerModel.
2016-05-30 10:41:46 +08:00
wy65701436
d4d7621942 modify the error log for registerModel to tell user the default hard code PK is 'id'. 2016-05-27 02:03:58 -07:00
qAison
761b6c129c count func add support group by 2016-05-27 14:34:45 +08:00
qAison
8f0749ddee fix fk field null value 2016-05-27 13:53:28 +08:00
astaxie
7b051e7ad1 Merge pull request #1940 from MachineShop-IOT/develop
More flexible support for template engines
2016-05-24 11:54:39 +08:00
Mark Mindenhall
24b8870637 move paren to new line 2016-05-23 21:43:18 -06:00
astaxie
cef91db28e Merge pull request #1956 from gitchs/master
Ctx.Redirect patch
2016-05-23 13:50:59 +08:00
astaxie
2165fb6e67 Merge pull request #1938 from wincss/develop
fix #1936
2016-05-22 21:29:32 +08:00
astaxie
05e929ed8c Merge pull request #1948 from nullne/develop
fix bug with file permission in log module
2016-05-22 21:25:17 +08:00
tinyproxy
f32392e956 net/http will do it better 2016-05-21 15:19:21 +08:00
astaxie
e21b425957 Merge pull request #1953 from lcbluestorm/master
add ssdb session provider
2016-05-20 22:53:23 +08:00
lcbluestorm
e77a591a6c delete test file 2016-05-20 17:25:22 +08:00
lcbluestorm
4890dd708c clear code 2016-05-20 10:27:18 +08:00
lcbluestorm
6234b50111 test done 2016-05-19 21:00:04 +08:00
nullne
2c12383263 remove attribute perm to make it more brief 2016-05-17 10:29:05 +08:00
lcbluestorm
e50f4f5631 complete sess_ssdb.go 2016-05-15 12:15:40 +08:00
nullne
d679a4b865 fix bug with file permission in log module 2016-05-14 10:54:09 +08:00
Mark Mindenhall
153d76e200 More flexible support for template engines 2016-05-10 22:54:33 -06:00
lcbluestorm
0e4b9563ae add test file 2016-05-10 20:08:15 +08:00
lcbluestorm
27be1e7ca3 add ssdb-session interface 2016-05-10 19:56:45 +08:00
wincss
a4d4b8de77 fix #1936 2016-05-10 17:45:06 +08:00
astaxie
dae2a36eb5 Merge pull request #1924 from ysqi/develop
implement some features
2016-05-06 13:58:29 +08:00
ysqi
7ceff43db6 Fixed error in window os 2016-05-06 13:26:48 +08:00
astaxie
85a8c5c4f4 Merge pull request #1927 from JessonChan/log_daily_rotate
file rotate by day
2016-05-06 12:55:21 +08:00
JessonChan
b28581a463 make daily rotate 2016-05-06 12:11:14 +08:00
JessonChan
fa8d94fa69 file rotate by day test 2016-05-06 12:09:00 +08:00
ysqi
3c8ed9adfc Merge branch 'astaxie/develop' into develop
# Conflicts:
#	parser.go
2016-05-05 19:30:31 +08:00
ysqi
8210fd12d1 Fixed router fileName error in window 2016-05-05 19:28:09 +08:00
ysqi
77ff15ee33 Implement Error interface for validation error 2016-05-05 19:26:03 +08:00
astaxie
4d8e1f93ff Merge pull request #1909 from albertma/master
Start timer task Multiple times
2016-04-29 11:34:52 +08:00
albertma
e607be6fa6 gofmt the code 2016-04-29 10:28:10 +08:00
astaxie
73f499948a Merge pull request #1906 from Maxgis/issue_redundancy
remove redundancy code and add port confict tip
2016-04-28 09:59:47 +08:00
astaxie
a7452388d9 Merge pull request #1912 from ysqi/issue02
Fixed some bug
2016-04-28 09:44:08 +08:00
ysqi
2a2b433e19 go fmt 2016-04-27 23:57:36 +08:00
ysqi
272271f588 Change comment router file info 2016-04-27 23:57:22 +08:00
ysqi
fa7416452e Change set test mode way 2016-04-27 22:26:32 +08:00
ysqi
245664010c Go Vet 2016-04-27 22:18:22 +08:00
ysqi
9e17f518b8 Fixed print format error info 2016-04-27 22:17:53 +08:00
ysqi
830985b90b QueryEscape Download File Name 2016-04-27 22:05:31 +08:00
albertma
a271d67ba4 1.fix blank issue 2016-04-26 18:13:52 +08:00
albertma
710c7c79d4 1.fix start task twice issue 2016-04-26 18:11:49 +08:00
maxin[马鑫]
5402c753fb remove redundancy code and add port confict tip 2016-04-26 10:16:53 +08:00
astaxie
520a417cca Merge pull request #1874 from Maxgis/master
change limit 1000 to 1,reduce the amount the data
2016-04-26 09:56:44 +08:00
maxin[马鑫]
56dc9bf622 add return ErrMultiRows 2016-04-25 15:51:12 +08:00
redfoxli
b36afadbdc close socket when http client request over
To avoid a large number of  TIME_WAIT in server which http client talk with
2016-04-22 13:54:55 +08:00
astaxie
e89f562396 Merge pull request #1897 from yuyongsheng/develop
add/get session id into/from http header, check the session name in http header
2016-04-21 13:04:28 +08:00
yuyongsheng
5aa085bf41 1. remove the invalid comments.
2. allow the user to config "Enable" store/get sessionId into/from http header
3. allow the user to config "Enable" get sessionId from Url query
4. when enable sessionId in http header, check the sessionName format as CanonicalMIMRHeaderKey, then panic if not.
2016-04-21 09:57:44 +08:00
astaxie
70f3f6b8b1 Merge pull request #1883 from JessonChan/config_improve
Config improve
2016-04-20 13:19:47 +08:00
astaxie
86e18bf6f9 Merge pull request #1882 from miraclesu/fix/orm_multi_insert
orm: fix multi insert panic
2016-04-20 13:06:47 +08:00
astaxie
14159eaa7e Merge pull request #1891 from gitchs/develop
fix spell error
2016-04-20 09:49:11 +08:00
Leon Chan
df27c96102 fix spell error 2016-04-18 19:37:38 +08:00
JessonChan
5ac254bf61 ut bug fixed 2016-04-18 19:18:46 +08:00
JessonChan
423f2dad35 list the config to map 2016-04-18 19:16:39 +08:00
JessonChan
203ab3eba8 ut fix 2016-04-18 18:41:40 +08:00
JessonChan
0c32255d14 config test 2016-04-18 17:45:39 +08:00
maxin[马鑫]
9ce6dc4cdf remove test ; because rows are returned in an unspecified order 2016-04-13 21:04:46 +08:00
miraclesu
903e21bef2 orm: add test case for InsertMulti 2016-04-13 20:22:27 +08:00
miraclesu
3a3f70027c orm: fix panic multi insert when slice lenght is 1 & the value is pointer 2016-04-13 20:14:02 +08:00
JessonChan
4cd2408248 log to Stderr 2016-04-13 19:41:07 +08:00
JessonChan
cb0c006cfa add session config 2016-04-13 19:37:55 +08:00
JessonChan
ce4fc7bfcd simplify the value assign 2016-04-13 17:51:54 +08:00
maxin[马鑫]
81c6c898cf remove orm one function thorw ErrMultiRows error 2016-04-13 10:36:12 +08:00
astaxie
002dcaab23 Merge pull request #1880 from JessonChan/log_rotate_fix
Log rotate fix
2016-04-13 09:54:41 +08:00
JessonChan
abaa1bbcac file rotate file test 2016-04-13 09:05:16 +08:00
astaxie
314a447d57 Merge pull request #1879 from miraclesu/feature/orm_text
orm: use `text` as postgres default type
2016-04-12 23:19:22 +08:00
maxin[马鑫]
9679f5e22a reduce the data transmission 2016-04-12 21:28:29 +08:00
miraclesu
5185816942 orm: use text as postgres default type 2016-04-12 21:19:43 +08:00
JessonChan
22617aeb13 file rotate name fixed 2016-04-12 15:05:35 +08:00
astaxie
9c400778d3 Merge pull request #1863 from JessonChan/xsrf_fix
Xsrf fix
2016-04-12 14:26:20 +08:00
astaxie
f6ad2cf848 Merge pull request #1875 from miraclesu/feature/orm_json
orm: add json & jsonb type support
2016-04-12 14:25:54 +08:00
astaxie
7906b18d89 Merge pull request #1864 from yoki123/patch-2
Update README.md
2016-04-12 12:02:04 +08:00
miraclesu
99f1e6c8b5 orm: fix golint 2016-04-12 11:00:31 +08:00
miraclesu
e95bef1331 orm: add test case for json & jsonb type support 2016-04-12 11:00:31 +08:00
miraclesu
657744efb1 orm: add json & jsonb type support 2016-04-12 11:00:31 +08:00
astaxie
6da765c465 Using a different PostgreSQL Version 2016-04-11 23:12:35 +08:00
astaxie
1cac38b664 show postgres versionn 2016-04-11 21:19:10 +08:00
astaxie
ba3a1f8457 update go vet 2016-04-11 13:15:14 +08:00
astaxie
d7f41ccd0c update vet 2016-04-11 12:51:44 +08:00
astaxie
881d010c01 upgrade swagger from 1.2 to 2.0 2016-04-11 11:56:43 +08:00
maxin[马鑫]
553078d956 change limit 1000 to 1,reduce the amount the data 2016-04-11 09:02:22 +05:30
Yoki
528f273e58 Update README.md
fix url
2016-04-08 14:28:45 +08:00
JessonChan
53d680a493 rand func modify 2016-04-08 14:24:23 +08:00
JessonChan
ed0e6419f0 context xsrf test 2016-04-08 14:07:39 +08:00
JessonChan
a99c0d4025 context xsrf test 2016-04-08 14:04:25 +08:00
JessonChan
301dcfb626 context xsrf bug fixed 2016-04-08 14:04:10 +08:00
astaxie
6362dc397a Merge pull request #1856 from b055/develop
added functionality for column type time
2016-04-06 09:25:46 +08:00
astaxie
813f47fd41 gofmt test files 2016-04-05 15:38:42 +08:00
astaxie
933ac0f369 Merge pull request #1858 from ysqi/issue
fix the issue #1850,the source of the problem is PR #1805
2016-04-05 09:06:14 +08:00
ysqi
885d45db05 fix the issue #1850,the source of the problem is PR #1805 2016-04-04 21:32:43 +08:00
Ivan Cadri
d49c7f96cb added functionality for column type time
updated the model_fields to cater for the time field type
2016-04-03 16:58:19 +02:00
astaxie
ebdf4412b3 Merge pull request #1848 from JessonChan/template_fix
make template execution be expected
2016-04-01 21:03:39 +08:00
JessonChan
8ec6dd93cf make template execution be expected 2016-04-01 18:10:00 +08:00
astaxie
fe4fa6a095 Merge pull request #1636 from ysqi/environmentVar
Support get environment variables in config
2016-04-01 13:50:38 +08:00
astaxie
ccc84dd8eb Merge pull request #1762 from saturn4er/htmlEngines
Implemented possibility to add custom template engines
2016-03-30 16:43:39 +08:00
astaxie
734bbb3337 remove some space 2016-03-30 15:48:38 +08:00
astaxie
caa404cec1 Merge pull request #1840 from youngsterxyf/develop
To support `go run`
2016-03-30 15:46:47 +08:00
astaxie
52fbab329d Merge pull request #1844 from mishudark/master
delete not used variable (status int) in output.go functions
2016-03-30 15:44:32 +08:00
astaxie
8ce9f69b4d Merge pull request #1843 from JessonChan/beelog_bug_fix
Beelog bug fix
2016-03-30 15:44:20 +08:00
JessonChan
96a5d09ef0 add format header test 2016-03-30 15:13:01 +08:00
JessonChan
814b673e3c add a comment to the future bug 2016-03-30 14:51:46 +08:00
JessonChan
99436a75b1 format time header 5% faster than before 2016-03-30 14:31:28 +08:00
JessonChan
8e82ed319b beelog bug fixed 2016-03-30 14:31:16 +08:00
mishudark
eae2147735 chore(output.go): delete not used variable (status int) in check status functions 2016-03-29 23:28:53 -06:00
youngsterxyf
e281b6e82a improve 2016-03-30 10:49:39 +08:00
saturn4er
adaa4ab929 Fix index out of range if there is no file extension 2016-03-29 17:15:43 +03:00
ysqi
7e65338c87 Change key format
key format : ${ENV_PART||defaultValue} or  ${ENV_PART}
2016-03-29 21:47:33 +08:00
ysqi
5bd7d8c43f Merge branch 'astaxie/develop' into environmentVar 2016-03-29 20:55:29 +08:00
youngsterxyf
561e7115f3 To support go run 2016-03-29 18:16:38 +08:00
astaxie
220cf91180 Merge pull request #1837 from JessonChan/develop
add function of beego/logs
2016-03-29 11:37:09 +08:00
astaxie
cbd6f31b66 Merge pull request #1839 from JessonChan/log_rotate_fix
file rotate bug
2016-03-29 11:35:44 +08:00
JessonChan
221306fff4 file rotate bug 2016-03-29 10:05:56 +08:00
JessonChan
f05bb2ecd3 add function of beego/logs 2016-03-28 15:18:51 +08:00
astaxie
699de2ae75 Merge pull request #1826 from miraclesu/feature/orm_auto
orm: support insert a specified value to auto field
2016-03-28 12:04:31 +08:00
miraclesu
fb77464d69 golink: map range only key stlye 2016-03-27 15:07:51 +08:00
miraclesu
1794c52d65 orm: fix postgres sequence value 2016-03-27 15:06:57 +08:00
miraclesu
3ca44071e6 orm: insert specified values for insertMulti 2016-03-26 21:51:05 +08:00
miraclesu
e0a36fb61e Merge branch 'develop' into feature/orm_auto 2016-03-26 21:16:52 +08:00
astaxie
85a9b05495 Merge pull request #1833 from youngsterxyf/develop
in `session` package, add some helpful tools to help subpackage logging information
2016-03-25 21:15:23 +08:00
astaxie
70108131e6 Merge pull request #1832 from JessonChan/log_enhancement
Log enhancement
2016-03-25 21:12:06 +08:00
JessonChan
45f2390128 logger changed 2016-03-25 15:13:28 +08:00
JessonChan
826f81f479 remove from init method 2016-03-25 15:04:52 +08:00
astaxie
4dbbae61e0 Merge pull request #1828 from miraclesu/fix/orm_read_or_create
orm: fix painc when pk is uint on ReadOrCreate
2016-03-25 14:44:41 +08:00
JessonChan
e59271662c fix bee fix 2016-03-25 13:25:29 +08:00
JessonChan
fa4a231cd4 duration change to second 2016-03-25 11:46:19 +08:00
JessonChan
850dc59b6e should remove when 2.0 is released 2016-03-25 11:13:39 +08:00
JessonChan
6d0fe8c4f4 go fmt cache file 2016-03-25 11:05:20 +08:00
JessonChan
2db8c753fd bee fix 2016-03-25 10:56:15 +08:00
youngsterxyf
56860d1fea not just export a variable 2016-03-25 10:48:59 +08:00
JessonChan
94bde3a777 change to logs 2016-03-25 10:31:48 +08:00
youngsterxyf
3300db832b in session package, add a helpful variable SLogger to help subpackage logging information 2016-03-24 22:43:57 +08:00
JessonChan
52a0b657b7 for better performance 2016-03-24 20:27:00 +08:00
JessonChan
f02ff0420d no need to call Sprintf when no args 2016-03-24 20:22:42 +08:00
miraclesu
3e2ffa545f orm: fix postgres returning id error 2016-03-24 20:03:45 +08:00
JessonChan
06299fa47b makes console as default logger 2016-03-24 19:32:29 +08:00
JessonChan
d8bed89c44 set console as default logger 2016-03-24 19:15:14 +08:00
JessonChan
0814eefa62 refactor writeMsg function 2016-03-24 18:21:52 +08:00
JessonChan
8344a60552 add to upper case 2016-03-24 17:49:39 +08:00
JessonChan
0fb4a8af24 function change 2016-03-24 17:46:52 +08:00
JessonChan
a6c1377f91 change to 0 logger 2016-03-24 17:43:45 +08:00
JessonChan
cdfd830f65 rename log format 2016-03-24 17:43:16 +08:00
JessonChan
98dfecfd8a change beego log function to logs function 2016-03-24 17:39:29 +08:00
JessonChan
03840f3fe8 give each of the adapter a neme 2016-03-24 17:38:26 +08:00
JessonChan
2e6a23743b refactor logs package 2016-03-24 17:37:56 +08:00
astaxie
2362ca00b5 Merge pull request #1827 from ysqi/issue
Check file before download
2016-03-24 13:33:44 +08:00
YuShuangqi
b7d1afbf86 Remote empty line 2016-03-24 08:35:42 +08:00
miraclesu
eaf38bb096 orm: add test case for uint pk read or create 2016-03-23 21:59:09 +08:00
miraclesu
3be6688cd1 orm: fix painc when pk is uint on ReadOrCreate 2016-03-23 21:57:57 +08:00
ysqi
1eab11ca90 fixed #1815 check file before download 2016-03-23 21:27:28 +08:00
ysqi
c4276d31c5 Merge branch 'astaxie/develop' into issue 2016-03-23 21:26:55 +08:00
miraclesu
8f70df6c7b orm: add test case for insert specified value to auto field 2016-03-23 20:28:22 +08:00
miraclesu
1786b16e61 orm: support insert a specified value to auto field 2016-03-23 20:16:18 +08:00
astaxie
9f18813c2b Merge branch 'master' into develop 2016-03-23 17:05:50 +08:00
astaxie
88c5dfa6ea update issue template 2016-03-23 17:05:40 +08:00
astaxie
0a86926522 Merge branch 'master' into develop 2016-03-23 16:56:53 +08:00
astaxie
b78de2b440 add ISSUE_TEMPLATE 2016-03-23 16:56:40 +08:00
astaxie
6c0979c314 Merge pull request #1805 from JessonChan/abort_panic_bug
Abort panic bug
2016-03-23 10:22:32 +08:00
JessonChan
5858607f49 go fmt error_test.go 2016-03-22 18:32:14 +08:00
JessonChan
1a401af23b copyright 2016-03-22 18:28:44 +08:00
JessonChan
b2098266a3 add error test 2016-03-22 18:27:29 +08:00
astaxie
3ac90df5fa Merge pull request #1794 from youngsterxyf/issue1789
fix issue1789: when testing, load config explicitly and forcibly
2016-03-22 17:21:57 +08:00
astaxie
9e9671d8cd Merge pull request #1799 from JessonChan/router_develop
Router Filter Improve
2016-03-22 17:15:28 +08:00
astaxie
d3b54c46e3 Merge pull request #1808 from JessonChan/gzip_improve
Gzip improve
2016-03-22 17:13:20 +08:00
JessonChan
7bad3d1c67 change the compress leve to [0~9] 2016-03-22 16:47:11 +08:00
JessonChan
4db78f243e change the function args of init gzip method 2016-03-22 16:42:42 +08:00
astaxie
ba7a809de8 Merge pull request #1810 from miraclesu/fix/orm_miss_pk
orm: fix miss pk when pk is negative
2016-03-22 10:09:35 +08:00
astaxie
630f77bca3 update travis 2016-03-21 11:18:38 +08:00
astaxie
f2ed27cc8f make sure works for travis 2016-03-21 11:10:57 +08:00
JessonChan
959b9a5a58 config index out of range bug fixed 2016-03-21 09:32:41 +08:00
astaxie
142f4c9f42 Merge branch 'develop' of https://github.com/astaxie/beego into develop 2016-03-21 09:15:47 +08:00
astaxie
33ae75b251 golint check only works on Go 1.5 2016-03-21 08:50:56 +08:00
miraclesu
84ae930c64 orm: Add test case for integer pk 2016-03-18 21:58:11 +08:00
astaxie
99c0b1e338 Merge pull request #1803 from JessonChan/log_develop
fix rotate  read-write lock race
2016-03-18 15:43:46 +08:00
JessonChan
4caf044be2 getMethodOnly assign fixed 2016-03-18 15:18:00 +08:00
miraclesu
a3d4218d9d orm: fix miss pk when pk is negative 2016-03-17 21:41:35 +08:00
JessonChan
9f21928a90 some typo fixed 2016-03-17 20:07:24 +08:00
JessonChan
0b401481ef go fmt the comment 2016-03-17 19:59:48 +08:00
JessonChan
57eace07a7 comment update 2016-03-17 19:52:09 +08:00
JessonChan
35e34261ab gzip method support 2016-03-17 19:40:29 +08:00
JessonChan
5a9bff2000 init gzip level 2016-03-17 19:09:38 +08:00
JessonChan
48147f50d8 add some gzip future 2016-03-17 19:09:21 +08:00
JessonChan
0859ec570c refactor of error response and fix err code bug 2016-03-17 09:46:34 +08:00
JessonChan
443d71397c write error to response 2016-03-17 09:35:14 +08:00
JessonChan
ec35bd0c28 orm log header flag 2016-03-16 18:04:27 +08:00
JessonChan
2b1316c738 data race bug fixed 2016-03-16 18:04:07 +08:00
JessonChan
94599013fc url to lower case 2016-03-16 07:53:36 +08:00
JessonChan
565c4a4d59 make the code run more fast 2016-03-15 18:50:18 +08:00
JessonChan
34615ee8fc add router filter enable flag 2016-03-15 18:37:54 +08:00
JessonChan
c51bc86d3f goto bug fixed 2016-03-15 16:51:21 +08:00
JessonChan
8660a54fac make router fast 2016-03-15 11:49:23 +08:00
ysqi
1b04571c0b test the env use GOPATH not GOROOT 2016-03-14 19:22:00 +08:00
ysqi
9c7d95b071 go vet 2016-03-14 19:21:09 +08:00
astaxie
c8bbfb75f0 Merge pull request #1782 from JessonChan/some_wip
BeeLogger can be the writer of  http server's log
2016-03-14 14:47:29 +08:00
youngsterxyf
549a39c478 fix issue1789: when testing, load config explicitly and forcibly 2016-03-14 11:26:26 +08:00
astaxie
e4066d820d Merge pull request #1790 from miraclesu/feature/orm_inline_struct
orm: inline struct relate test case
2016-03-14 10:35:00 +08:00
astaxie
cc2b5f5b62 Merge pull request #1792 from youngsterxyf/issue1787
fix issue#1787: if `/m` is a static path mapping to a static dir,and we set `beego.BConfig.WebConfig.DirectoryIndex = true`, then it should redirect to `/m/`
2016-03-14 10:33:47 +08:00
JessonChan
c92c3fc8b5 make the BeegoLogger a adapter of http server ErrorLog 2016-03-14 10:21:07 +08:00
youngsterxyf
9aa2e5b575 fix issue#1787: The cause is that if the url is /m,and we set beego.BConfig.WebConfig.DirectoryIndex = true, then it should redirect to /m/ 2016-03-13 21:39:26 +08:00
miraclesu
dcfcb2789e orm: inline struct relate test case 2016-03-13 21:04:39 +08:00
astaxie
d90195061f fix #1783 2016-03-13 11:16:19 +08:00
astaxie
474bdd2e6b Merge pull request #1785 from KilledKenny/pathError
Fixed infinite loop in ini config adapter
2016-03-12 21:11:04 +08:00
ysqi
1642cbd420 Merge branch 'astaxie/develop' into develop 2016-03-12 14:51:24 +08:00
ysqi
b2a06c5fa0 Update config suport environment variable logic 2016-03-12 14:32:39 +08:00
lcbluestorm
cfef97175e change import sort 2016-03-12 12:34:54 +08:00
Simon Rawet
8b0957cf2e Fixed infinite loop in ini config adapter
If parseFile recived a directory it would go into a infinit loop
2016-03-12 00:20:19 +01:00
astaxie
88816348b9 window console can't output colorful 2016-03-11 15:29:52 +08:00
saturn4er
66423f6935 Fix formatting with gofmt
Rename BeeTemplateEngines->beeTemplateEngines.  Create templateHandler function type
Fix var name in comment BeeTemplatePreprocessors -> beeTemplatePreprocessors
Rename TemplateI -> TemplateRenderer
2016-03-11 08:40:54 +02:00
JessonChan
9872041f12 timeDur is used only when need 2016-03-11 14:14:58 +08:00
astaxie
83fe43f331 gofmt -s -w 2016-03-11 13:00:58 +08:00
astaxie
40b41cc121 fix the misspell99 2016-03-11 12:14:18 +08:00
astaxie
1aeb3d9051 release 1.6.1 2016-03-11 11:35:24 +08:00
astaxie
778a5a11ac Merge pull request #1781 from JessonChan/develop
duplicate adapter logger  bug fixed
2016-03-11 11:19:07 +08:00
JessonChan
4801099675 duplicate adapter logger bug fixed 2016-03-11 10:12:17 +08:00
astaxie
420cd507b2 update output information 2016-03-11 10:07:44 +08:00
astaxie
22196d7841 add mis function NSHandler 2016-03-11 09:21:13 +08:00
astaxie
571f9b4b65 Merge pull request #1780 from goodloop/develop
fix static pattern match for leaf
2016-03-11 09:07:53 +08:00
astaxie
1f0a65f0a2 fix the orm test 2016-03-10 22:21:21 +08:00
Gavin Fang
90e7d252a7 fix static pattern match for leaf 2016-03-10 22:16:41 +08:00
astaxie
31f7524dae fix the golint travis 2016-03-10 21:47:50 +08:00
astaxie
3a12e238cc support oracle 2016-03-10 21:23:13 +08:00
ysqi
86c7f1db9e Merge branch 'astaxie/develop' into environmentVar
# Conflicts:
#	config/fake.go
#	config/xml/xml_test.go
#	config/yaml/yaml_test.go
2016-03-10 19:57:16 +08:00
astaxie
f45b271b96 Merge pull request #1723 from miraclesu/feature/orm_inline_struct
orm: inline struct support
2016-03-10 14:31:44 +08:00
astaxie
589616b303 Merge pull request #1768 from aolu11/master
fix json extra newline
2016-03-09 21:11:20 +08:00
astaxie
65b13eddad Merge pull request #1719 from JessonChan/err_ctrler
multiple response.WriteHeader calls
2016-03-09 19:18:09 +08:00
astaxie
686d2e834e Merge pull request #1765 from saturn4er/fix_layout_rebuild_in_dev
Add layout rebuilding on each request in dev mode
2016-03-09 19:02:46 +08:00
saturn4er
adbae18e8c Fix formatting with gofmt 2016-03-09 10:47:09 +02:00
JessonChan
f21cff0166 some typo fixed 2016-03-09 16:00:52 +08:00
JessonChan
3dd9020249 Merge remote-tracking branch 'remotes/upstream/develop' into err_ctrler 2016-03-09 15:59:13 +08:00
JessonChan
9a2696d216 accept asta's idea see the talk
https://github.com/astaxie/beego/pull/1719
2016-03-09 15:56:18 +08:00
miraclesu
64e0858d44 orm: add inline struct test case 2016-03-08 22:24:38 +08:00
astaxie
d86ab2ed31 Merge pull request #1721 from JessonChan/log_enhancement
Log enhancement
2016-03-08 21:35:31 +08:00
JessonChan
b2f071395b rename files to mulitfile 2016-03-08 18:44:39 +08:00
JessonChan
54b5120a64 rename files to mulitfile 2016-03-08 18:43:09 +08:00
aolu
5e2384e95a fix json extra newline 2016-03-08 17:04:14 +08:00
astaxie
adb41eb299 Merge pull request #1761 from lcbluestorm/develop
add ssdb cache adapter
2016-03-08 15:47:45 +08:00
liuchun
bd04be4470 move time to the top 2016-03-08 14:44:37 +08:00
liuchun
ef59a0ed63 fix travis.yml 2016-03-08 14:03:33 +08:00
liuchun
14be252d2a fix travis.yml 2016-03-08 14:01:33 +08:00
astaxie
5698b5dc92 Merge pull request #1709 from mlgd/develop
Fix cookies in accordance with the "net / http" and Flash usage
2016-03-08 13:53:43 +08:00
liuchun
0a0fc351e7 fix ssdb_test 2016-03-08 12:59:19 +08:00
liuchun
662bea352f modify travis 2016-03-08 12:45:54 +08:00
astaxie
2f18b9103b Merge pull request #1679 from ysqi/emptybodyfix
fix #1669 and return IO error
2016-03-08 09:48:17 +08:00
saturn4er
2c5ef8ccc8 Add layout rebuilding on each request in dev mode 2016-03-07 23:24:52 +02:00
liuchun
1ddb1ce2fe add ssdb travis 2016-03-07 15:50:13 +08:00
saturn4er
9ee9f81861 Add functions passing to template engine callback 2016-03-07 09:37:47 +02:00
liuchun
9ddc2f5474 fix panic err 2016-03-07 15:00:03 +08:00
liuchun
e29f4b57a3 fix travis.yml 2016-03-07 14:53:36 +08:00
saturn4er
10ddb06782 Implemented possibility to add custom template engines 2016-03-07 08:45:49 +02:00
liuchun
0caadb9b66 rename vars 2016-03-07 14:45:45 +08:00
liuchun
22e3900403 add .travis.yml 2016-03-07 14:34:40 +08:00
liuchun
b39830dff3 add .travis.yml 2016-03-07 10:31:56 +08:00
liuchun
be23c42674 Merge branches 'master' and 'develop' of lcbluestorm.github.com:lcbluestorm/beego into develop 2016-03-07 10:19:55 +08:00
ysqi
90344a7b8f fix conflicts 2016-03-06 21:25:43 +08:00
ysqi
920862884d Merge branch 'astaxie/develop' into emptybodyfix
# Conflicts:
#	config.go
2016-03-06 21:19:04 +08:00
liuchun
48ec7f736e fix GetMulti bug 2016-03-06 14:46:13 +08:00
liuchun
292d8f2c00 add ssdb cache adapter 2016-03-06 13:17:16 +08:00
astaxie
f6f34306ee Merge pull request #1740 from ysqi/configer
Fixed #1735 Return nil if config value does not exist or is empty
2016-03-05 22:05:43 +08:00
astaxie
a40c0dd156 Merge pull request #1750 from JessonChan/staticfile_map_race
static file map race bug fixed
2016-03-05 20:43:00 +08:00
astaxie
795092bdd2 Merge pull request #1751 from FlamingTree/develop
Update phone regexp
2016-03-05 20:41:52 +08:00
astaxie
524446c857 Merge pull request #1752 from JessonChan/ab_lock_race
fix template  read-write lock race
2016-03-05 20:40:14 +08:00
JessonChan
f5adec31c6 improve the template reader function 2016-03-04 14:49:16 +08:00
JessonChan
6747c55a81 remove unused cache 2016-03-04 12:01:04 +08:00
JessonChan
1f46c1d231 add template read lock when dev mode 2016-03-04 12:00:43 +08:00
FlamingTree
8bd1be8e29 Update validators.go
增加178号段
2016-03-04 11:16:47 +08:00
JessonChan
226e54e0d8 static file map race bug fixed 2016-03-04 10:54:54 +08:00
JessonChan
3379a2b7ed remove file bug fixed
remove file by filename and file suffix
2016-03-04 10:43:57 +08:00
ysqi
19d921d3f5 Return nil not empty []string{}
Return nil if config value does not exist or is empty
2016-03-03 20:03:23 +08:00
astaxie
4b99e41880 Merge pull request #1688 from ysqi/configIssue
fixed handle config issue
2016-03-03 09:50:14 +08:00
ysqi
8ff74e71cb Fixed #1735 Return empty []string
Need return empty []string  if config value is empty.

split `“”` ==> []string{}, Not []string{“”}
2016-03-02 22:44:20 +08:00
JessonChan
2a148473e9 Merge remote-tracking branch 'remotes/upstream/develop' into log_enhancement 2016-03-02 13:34:37 +08:00
JessonChan
b30ce768f8 Merge remote-tracking branch 'remotes/upstream/develop' into err_ctrler 2016-03-02 13:34:00 +08:00
astaxie
70e63570f5 Merge pull request #1731 from math345/develop
fix bug: session id undecoded when destroy and sesssion memory provider push wrong
2016-03-02 13:26:57 +08:00
astaxie
36e3160904 add go1.6.0 and remove 1.3.3 2016-03-01 21:41:44 +08:00
JessonChan
ca3c57fbc6 add a line of comment 2016-03-01 17:13:50 +08:00
JessonChan
387dd6ec0e add a line of comment 2016-03-01 17:12:21 +08:00
JessonChan
26cc040f9a daily log name dot fixed 2016-03-01 17:00:24 +08:00
astaxie
d81a768802 change couchbase to beego/go-couchbase 2016-03-01 16:54:37 +08:00
astaxie
f0dcaa7f84 remove couchbase dependence 2016-03-01 16:43:56 +08:00
JessonChan
9da4d1d847 Merge branch 'develop' into log_enhancement 2016-03-01 13:59:27 +08:00
iexploree
a144f117a3 remove comment 2016-03-01 13:39:36 +08:00
iexploree
477de9a3f3 fix bug: session id undecoded when destroy and sesssion memory provider push wrong 2016-03-01 10:51:47 +08:00
ysqi
ffbb45e567 Revert "ignore parse include config file error"
This reverts commit 891016a0a2.
2016-02-27 20:18:59 +08:00
astaxie
67fbafb380 Merge pull request #1680 from ysqi/fix-router-error
fix #1595
2016-02-26 16:17:53 +08:00
astaxie
6eaa5537f5 Merge pull request #1652 from JessonChan/develop
colorful console and go fmt
2016-02-26 16:10:11 +08:00
astaxie
62cc987620 Merge pull request #1639 from youngsterxyf/logger-flush-close
try to fix the little bug when calling Close or Flush in async mode
2016-02-26 16:04:29 +08:00
astaxie
f0a41f978f Merge pull request #1727 from JessonChan/templates_bug_fix
lock the templates map when goroutie update the map
2016-02-26 15:56:47 +08:00
JessonChan
3da28535fe lock the templates map when goroutie update the map 2016-02-25 17:37:28 +08:00
miraclesu
85f55fcb41 orm: inline struct support 2016-02-24 18:46:14 +08:00
JessonChan
8c37e76503 the net/http should set header first,the set http status code and then write the content 2016-02-24 14:14:16 +08:00
JessonChan
76d69b6e51 prevent auto detect of content-type
https://golang.org/src/net/http/server.go#L1031
2016-02-24 10:34:20 +08:00
JessonChan
20301bc212 multiple response.WriteHeader calls 2016-02-24 10:31:44 +08:00
Mickaël GALLARD
9119f766d2 Fix cookies in accordance with the "net / http" and Flash usage
Fixed issue of Flash cookies that are deleted before being read
Max-age parameter conform to "net/http" Cookie
2016-02-22 13:35:54 +01:00
ysqi
891016a0a2 ignore parse include config file error 2016-02-14 18:55:42 +08:00
ysqi
d5f07d65bb panic parse config error 2016-02-14 18:54:40 +08:00
ysqi
9411063574 fix #1595 2016-02-12 14:45:45 +08:00
ysqi
23860e6807 go fmt 2016-02-12 11:36:59 +08:00
ysqi
d35c50a8e0 return write body error 2016-02-12 11:36:25 +08:00
ysqi
810f6db8d2 fix #1669 write empty body panic error 2016-02-12 11:27:59 +08:00
ysqi
36f69a04a9 remove interfaceToStr function to package config 2016-02-04 20:15:37 +08:00
JessonChan
1f716dda3e add test files and bug fixed 2016-02-03 17:54:58 +08:00
JessonChan
f8c4b3aa4c add files logger to separate different logs 2016-02-03 17:11:53 +08:00
JessonChan
51b1095e73 add files logger 2016-02-03 16:32:59 +08:00
JessonChan
68cc53e92b when rotate by date ,there's no num after log file 2016-02-03 15:43:15 +08:00
JessonChan
6caa3ecd91 when rotate by date ,there's no num after log file 2016-02-03 15:31:59 +08:00
JessonChan
304a5ccea0 comment fix 2016-02-03 15:06:53 +08:00
JessonChan
9806a43783 make more fast 2016-02-03 15:03:37 +08:00
JessonChan
a1cb000701 remove log package 2016-02-03 14:42:38 +08:00
astaxie
2b23764ee0 Merge pull request #1657 from lei-cao/slack
Added slack
2016-02-03 08:58:24 +08:00
Lei Cao
2301633d42 Added slack 2016-02-02 23:34:32 +08:00
youngsterxyf
2efe7c4c89 merge multi commit 2016-02-02 17:12:47 +08:00
youngsterxyf
c71ac7431d Merge branch 'develop' into logger-flush-close 2016-02-02 17:11:41 +08:00
JessonChan
360220161b remove useless var , name style fixed 2016-02-02 16:52:53 +08:00
JessonChan
5dec3d127c colorful console only the terminal supports 2016-02-02 16:37:09 +08:00
astaxie
16b01c362a Merge branch 'develop' of https://github.com/astaxie/beego into develop 2016-02-02 12:45:01 +08:00
astaxie
441f795a1a Merge pull request #1651 from thanhtranjs/develop
Add GroupBy to QuerySeter
2016-02-02 12:44:49 +08:00
astaxie
4906b600e3 fix the static url with / problem 2016-02-02 12:43:58 +08:00
Thanh Tran
bb50383aa9 Add GroupBy to QuerySeter 2016-02-02 11:28:43 +07:00
astaxie
631b4d36f9 Merge pull request #1647 from youngsterxyf/fix-issue1641
fix issue #1641
2016-02-02 09:23:12 +08:00
youngsterxyf
da38cbfe41 fix issue #1641 2016-02-01 22:40:34 +08:00
astaxie
09193213a0 add travis hooks 2016-01-31 23:28:56 +08:00
astaxie
0382146c60 fix the go vet for go tip 2016-01-29 13:11:11 +08:00
astaxie
1bf52e8922 Merge branch 'develop' of https://github.com/astaxie/beego into develop 2016-01-29 10:26:40 +08:00
astaxie
5cd1ed8106 add test for tip 2016-01-29 00:01:04 +08:00
astaxie
bd79972d85 Merge pull request #1638 from pjoe/log_console_nocolor
Add noColor option for console logger
2016-01-28 22:39:02 +08:00
youngsterxyf
ecab397073 try to fix the little bug when calling Close or Flush in async mode 2016-01-28 21:53:44 +08:00
Pelle Johnsen
a043432398 Change option name from noColor to color
Still same default behavior (with color)
2016-01-28 07:50:07 +01:00
ysqi
1222c87be3 optimization code 2016-01-28 14:49:44 +08:00
Pelle Johnsen
7f888e3d18 Add noColor option for console logger
- Also added simple test
2016-01-27 19:20:58 +01:00
astaxie
85c0fcd335 Merge pull request #1637 from pjoe/input_param_fix
Fix Context.Input.SetParam not overwriting existing value
2016-01-27 23:01:10 +08:00
astaxie
f769016126 Merge pull request #1632 from youngsterxyf/config-logic
Config logic
2016-01-27 22:25:00 +08:00
Pelle Johnsen
453d744db9 Fix Context.Input.SetParam not overwriting existing value
- Also added tests for Context.Input.Param handling
2016-01-27 14:58:50 +01:00
ysqi
484ca3a643 fixed test code error 2016-01-27 21:13:11 +08:00
ysqi
cd31c816cc Config support get environment variable
get environment variable if config item  has prefix "$ENV_" .
e.g.
```ini
[demo]
password = $ENV_MyPWD
```
2016-01-27 20:46:30 +08:00
youngsterxyf
31ef4ae507 rename AppConfigPath, AppConfigProvider to appConfigPath, appConfigProvider, make public to private 2016-01-27 16:43:01 +08:00
youngsterxyf
ccce566ba7 accept @astaxie suggestion: change the sequence adapterName and configPath 2016-01-27 16:19:10 +08:00
youngsterxyf
e357f6846b accept @ysqi suggestion 2016-01-27 13:30:34 +08:00
youngsterxyf
321bcc606a fix bug of test case 2016-01-27 12:26:37 +08:00
youngsterxyf
e549d0fd9c move some code piece 2016-01-27 12:13:26 +08:00
youngsterxyf
c59a029ce7 Merge branch 'develop' into config-logic 2016-01-27 10:58:38 +08:00
astaxie
4ce094a29a Merge branch 'master' into develop 2016-01-27 10:14:34 +08:00
astaxie
fbb98fbe1f Merge pull request #1631 from yunkai/issue1
Fix regression caused by commit ad65479
2016-01-27 10:13:30 +08:00
youngsterxyf
20efd5236e fix bug 2016-01-27 00:42:07 +08:00
youngsterxyf
330b3b1931 enhancement code 2016-01-27 00:17:56 +08:00
youngsterxyf
d9e6250d08 fix config logic 2016-01-27 00:10:21 +08:00
Yunkai Zhang
e3810b599d Fix regression caused by commit ad65479
Commit ad65479 will cause "Method Not Allow" in preflight response
when enable CORS plugin.

The root cause is that CORS plugin didn't generate http output after applied
commit ad65479, so the value of `ctx.ResponseWriter.Started` will be keep
`false`, and then later filter chains will be go on to run when CORS filter
finished.

This path will both fix "Method Not Allow" and the original bug
"multiple response.WriteHeader calls".

Signed-off-by: Yunkai Zhang <qiushu.zyk@taobao.com>
2016-01-26 23:27:26 +08:00
astaxie
e1f9491aed Merge pull request #1608 from ysqi/iniSaveErrorFix
Fixed #1607
2016-01-26 21:46:31 +08:00
astaxie
6aeff53d8c Merge pull request #1625 from miraclesu/fix/mail_from
Fix utils mail some bugs
2016-01-26 21:42:21 +08:00
miraclesu
bf870eb9a2 mv mime.QEncoding.Encode logic to mail
it is named qEncode
2016-01-26 20:50:03 +08:00
miraclesu
f26d360ec9 Fix vet fail 2016-01-26 14:54:36 +08:00
astaxie
f73eaf6393 Merge pull request #1626 from JessonChan/develop
log file name bug fixed
2016-01-26 13:42:47 +08:00
JessonChan
e11d150e8b replace \t with space 2016-01-26 09:35:39 +08:00
JessonChan
f2567bc114 some typo fixed 2016-01-26 09:29:04 +08:00
JessonChan
b5a07c6ba8 log file name bug fixed
this bug happens when daily rotate. ex,when it is 2016-01-22 23:59:59 and need a rotate,the file name should named with 2016-01-22 but named with 2016-01-23(next day)
2016-01-26 09:20:49 +08:00
astaxie
01ccc75d6b Merge pull request #1615 from ysqi/routerErrorFix
Fixed #1586
2016-01-26 00:31:01 +08:00
astaxie
b19f9bf88c Merge branch 'develop' of https://github.com/astaxie/beego into develop 2016-01-26 00:27:44 +08:00
astaxie
6cc3d4470a Merge pull request #1616 from coseyo/path_patch
fix path issue #1613
2016-01-26 00:27:34 +08:00
astaxie
61e9dc74c9 make sure the memcache testing success 2016-01-26 00:27:02 +08:00
astaxie
8611862fd7 Merge pull request #1609 from youngsterxyf/fix-issue1566
fix issue #1566
2016-01-26 00:07:43 +08:00
coseyo
d1481ea659 move assignment to init 2016-01-25 23:00:09 +08:00
miraclesu
5930f27da7 Fix mail Chinese subject garbled bug 2016-01-25 22:55:40 +08:00
miraclesu
4de91f675d show from when Config from is empty 2016-01-25 22:29:45 +08:00
astaxie
15e9ba19c0 fix the range only used in Go 1.4 fix #1623 2016-01-25 21:39:44 +08:00
astaxie
f8004b69ad fix the go vet 2016-01-25 21:33:57 +08:00
astaxie
3dac344ff6 fix the vet url 2016-01-25 21:20:10 +08:00
astaxie
e7d4452af0 add golint and go test 2016-01-25 21:13:56 +08:00
astaxie
7e3ad5bcb0 fix #1585 2016-01-25 21:08:29 +08:00
astaxie
87650ce8bc make golint happy 2016-01-25 20:57:41 +08:00
astaxie
fdce4af9c8 fix #1619 2016-01-25 20:53:52 +08:00
youngsterxyf
bcac4bb8e3 accept @JessonChan suggestion 2016-01-25 20:53:25 +08:00
youngsterxyf
0e17e2a3d2 accept @JessonChan suggestion 2016-01-25 20:20:53 +08:00
miraclesu
a80feb00b8 Fix utils mail from field can't including Chinese bug 2016-01-25 18:15:08 +08:00
ysqi
cf055c9db2 Merge branch 'astaxie/develop' into iniSaveErrorFix
# Conflicts:
#	config/ini_test.go
2016-01-24 11:37:43 +08:00
ysqi
3d7354b9d2 import reset 2016-01-24 11:10:04 +08:00
coseyo
09d3d89c6f fix test error again 2016-01-24 00:47:37 +08:00
coseyo
3031bdd176 fix test error 2016-01-24 00:40:03 +08:00
coseyo
4c1cfc1386 fix path issue 2016-01-24 00:18:16 +08:00
astaxie
57d522a96a Merge pull request #1606 from ysqi/configWork
Support Parse Bool with more diffrent values
2016-01-23 23:03:03 +08:00
astaxie
fd7473466b Merge pull request #1581 from hbejgel/patch-2
Checks if index is greater than the length of the wildcards. #1580
2016-01-23 23:01:22 +08:00
ysqi
007af6224e Fixed #1586 2016-01-23 19:13:19 +08:00
youngsterxyf
cbc7f43e88 fix issue #1601 2016-01-23 17:12:46 +08:00
youngsterxyf
ecf24640fd fix issue #1566 2016-01-23 16:56:54 +08:00
ysqi
51ae45a799 Fixed #1607 2016-01-23 14:53:52 +08:00
ysqi
be544f963e Support Parse Bool with more diffrent values
ParseBool returns the boolean value represented by the string.
It accepts 1, 1.0, t, T, TRUE, true, True, YES, yes, Yes,Y, y, ON, on,
On,
 0, 0.0, f, F, FALSE, false, False, NO, no, No, N,n, OFF, off, Off.
Any other value returns an error.
2016-01-23 11:02:40 +08:00
astaxie
af346e871b Merge pull request #1603 from coseyo/remote_develop
fix conf load bug
2016-01-22 20:34:46 +08:00
coseyo
cb5fd49612 fix conf load bug 2016-01-22 18:03:02 +08:00
astaxie
0f85c82a21 Merge pull request #1594 from nemtsevp/patch-2
Exceptions in controller methods
2016-01-21 14:57:02 +08:00
nemtsevp
93b04e8a3b Exceptions in controller methods
Exceptions in methods names should be changed according to controller.go
2016-01-21 09:44:17 +03:00
astaxie
07937dea9a Merge pull request #1588 from Kavin-Cao/master
template.go 的beegoTplFuncMap注释有误
2016-01-20 14:18:35 +08:00
bradycao
5757e6548e template.go 的urlfor Func注释有误
template.go 的urlfor Func注释有误
2016-01-19 10:14:16 +08:00
bradycao
b48f251043 Merge remote-tracking branch 'refs/remotes/astaxie/master' 2016-01-19 09:43:43 +08:00
Henrique Bejgel
35e340b937 Checks if index is greater than the length of the wildcards. #1580 2016-01-18 21:35:14 -02:00
astaxie
befeac5b61 Merge branch 'develop' of https://github.com/astaxie/beego into develop 2016-01-18 23:30:12 +08:00
astaxie
23bb36d35c fix the issue #1573 2016-01-18 23:29:56 +08:00
astaxie
4b52a38183 Merge pull request #1575 from youngsterxyf/develop
simplify the implementation of splitPath in tree.go
2016-01-18 16:33:23 +08:00
youngsterxyf
30e5634bdb simplify the implementation of splitPath in tree.go 2016-01-18 16:13:31 +08:00
astaxie
fa8f6e5a53 session destroy 2016-01-18 16:11:27 +08:00
astaxie
6e987bfdaf Merge branch 'develop' of https://github.com/astaxie/beego into develop 2016-01-18 15:28:18 +08:00
astaxie
918b9e510f fix the add tempfunc 2016-01-18 15:27:33 +08:00
astaxie
12e5584c01 Merge pull request #1574 from youngsterxyf/develop
DRY
2016-01-18 15:24:53 +08:00
youngsterxyf
ac3b013de7 DRY 2016-01-18 15:17:42 +08:00
astaxie
089242eda0 memcache test mulit return map has no sequence 2016-01-18 00:36:05 +08:00
astaxie
92d0b9ae95 golint the config.go 2016-01-18 00:22:31 +08:00
astaxie
6f786e1dea golint config.go 2016-01-18 00:22:11 +08:00
astaxie
eb0bc084ec make the code mode readable
golint all the files
2016-01-18 00:18:52 +08:00
astaxie
f925bb9058 golint all the files 2016-01-18 00:18:21 +08:00
astaxie
da36d1d0e7 fix the wrong io.Writer 2016-01-18 00:03:39 +08:00
astaxie
48f19b4191 Merge pull request #1571 from astaxie/develop
beego 1.6.0 released
2016-01-17 23:58:34 +08:00
astaxie
9adf20d72e gofmt -s 2016-01-17 23:57:07 +08:00
astaxie
90d1349665 fix typo 2016-01-17 23:48:17 +08:00
astaxie
9b2597be68 fix the mail send empty subject 2016-01-17 23:48:09 +08:00
astaxie
895748d632 beego 1.6.0 released 2016-01-17 22:55:09 +08:00
astaxie
566aab4354 mail send support Address format 2016-01-17 22:49:02 +08:00
astaxie
a304bb9c25 Revert "add test case for tidb"
This reverts commit f70d2cc373.
2016-01-17 18:35:11 +08:00
astaxie
f70d2cc373 add test case for tidb 2016-01-17 18:24:29 +08:00
astaxie
897cf57840 use travis-ci.org as build-status 2016-01-15 14:59:16 +08:00
astaxie
8e6b0a6d7b Merge pull request #1567 from JessonChan/develop
some typo fixed
2016-01-15 14:40:14 +08:00
astaxie
797571c85f fix the ORM test case 2016-01-15 14:36:45 +08:00
JessonChan
814e4ac031 rename the docsSepc to docs_spec 2016-01-15 14:14:09 +08:00
JessonChan
52083de720 typo fixed
seperator => separator
2016-01-15 14:07:37 +08:00
astaxie
a069c73b3a test case bool default value is true 2016-01-15 14:02:08 +08:00
astaxie
7dbeb2c39a fix the default value 2016-01-15 08:43:02 +08:00
astaxie
4375ca84d1 fix the sqlite m2m 2016-01-14 23:49:28 +08:00
astaxie
0eaf923a27 Merge pull request #1560 from JessonChan/log_enhancement
Log enhancement
2016-01-13 22:57:39 +08:00
astaxie
9c55985915 update readme 2016-01-13 22:20:34 +08:00
astaxie
6976c0f51d add CONTRIBUTING.md 2016-01-13 22:02:36 +08:00
JessonChan
5befc67389 Merge remote-tracking branch 'remotes/upstream/develop' into log_enhancement 2016-01-13 10:15:00 +08:00
JessonChan
fb5b04506a code refactor and format 2016-01-13 09:24:27 +08:00
JessonChan
7663d50c97 remove the lock writer 2016-01-13 09:21:55 +08:00
JessonChan
58730e3528 test file modify 2016-01-13 09:21:32 +08:00
JessonChan
e1b73b33d0 improve code 2016-01-13 08:21:44 +08:00
JessonChan
c535dc386e fast format 2016-01-12 22:54:39 +08:00
JessonChan
69804afc1b use pool to logMsg 2016-01-12 22:39:40 +08:00
JessonChan
164366ae0d return error 2016-01-12 22:33:52 +08:00
JessonChan
2b9d7ff714 remove log package 2016-01-12 22:32:36 +08:00
JessonChan
bd0f3c29fa decr malloc new object 2016-01-12 22:32:20 +08:00
astaxie
6660720ce6 update some config name 2016-01-12 21:55:02 +08:00
JessonChan
12e7f0f94a extract a func to write to every logger 2016-01-12 21:15:25 +08:00
JessonChan
482b7a62bd use array not map 2016-01-12 21:05:06 +08:00
astaxie
b90a28bafb Merge pull request #1546 from youngsterxyf/develop
fix #1530
2016-01-12 20:01:51 +08:00
JessonChan
baa2e9d64a code format 2016-01-12 19:44:28 +08:00
JessonChan
5511e03b52 embedding file writer 2016-01-12 19:25:33 +08:00
JessonChan
9507e59c2f camel name fixed 2016-01-12 19:10:08 +08:00
JessonChan
2479e61db9 add asynchronous and call depth benchmark 2016-01-12 19:09:00 +08:00
JessonChan
c9b890b10e add asynchronous benchmark 2016-01-12 17:59:23 +08:00
JessonChan
e32e3a759c console type no need to bench 2016-01-12 17:46:10 +08:00
astaxie
391f897eb1 simplify sessionID 2016-01-11 16:49:56 +08:00
astaxie
dc278da17c fix the sqlite3 & cache sleep 11 second 2016-01-08 23:30:19 +08:00
astaxie
c7146d22f4 add all dependence 2016-01-08 23:20:25 +08:00
astaxie
1aff26cc31 add dependence database 2016-01-08 23:10:50 +08:00
astaxie
c59bc431e3 mulit variable 2016-01-08 23:00:22 +08:00
astaxie
d0dd68351a update travis 2016-01-08 22:34:23 +08:00
youngsterxyf
0c48738841 for issue #1530, fix incompatible bug 2016-01-08 21:29:12 +08:00
youngsterxyf
0b0904db13 for issue #1530, accept @JessonChan's suggestion 2016-01-08 20:16:58 +08:00
astaxie
fd608d2bf6 disable tidb testing 2016-01-08 19:59:20 +08:00
astaxie
5b028796b8 fix the test case for input 2016-01-08 16:24:59 +08:00
astaxie
d2de71d8ab update the dependence 2016-01-08 16:01:07 +08:00
astaxie
302b1ef7df fix the data 2016-01-08 15:52:57 +08:00
astaxie
77fa891499 update dependence 2016-01-08 15:47:13 +08:00
astaxie
69bcbcdb31 add travis 2016-01-08 15:34:02 +08:00
youngsterxyf
bb43d3a78c fix #1530 2016-01-08 13:47:14 +08:00
astaxie
01012fa898 admin configure 2016-01-08 01:40:19 +08:00
astaxie
9167587929 add Params for input 2016-01-08 01:20:34 +08:00
astaxie
c68505e451 read config from app.conf for session 2016-01-07 23:55:55 +08:00
astaxie
98f3fecc03 fix the typo 2016-01-07 23:35:01 +08:00
astaxie
c6141f5d94 add httpsaddr 2016-01-07 23:31:33 +08:00
astaxie
43ca13b516 Merge pull request #1543 from miraclesu/validation
Add validation custom function
2016-01-07 23:24:31 +08:00
miraclesu
687266fb64 Add 179 to valid Phone number 2016-01-07 23:03:32 +08:00
miraclesu
21f767784b Add custom validation function doc 2016-01-07 22:55:12 +08:00
miraclesu
103ac3ee5b Add custom validation function 2016-01-07 22:42:04 +08:00
astaxie
db2918b0aa Merge pull request #1542 from ysqi/develop
fix issues  #1473, #1502
2016-01-07 21:02:42 +08:00
ysqi
6eff2e433f fix #1502,Notes error repair 2016-01-07 20:55:28 +08:00
ysqi
58e2a7c099 fix #1473,Only update redis session if it already exist 2016-01-07 20:42:26 +08:00
astaxie
434544060a Merge pull request #1540 from ysqi/develop
TplNames renamed TplName ,fix #1229,Remember modify bee tool.
2016-01-07 17:03:22 +08:00
ysqi
4c0c0ec2a7 TplNames renamed TplName ,fix #1229,Remember modify bee tool. 2016-01-07 16:16:39 +08:00
astaxie
ecc6bcba3f Merge pull request #1539 from ysqi/develop
change get sessionID logic from cookie
2016-01-07 13:49:33 +08:00
ysqi
80912b6210 change get sessionID logic from cookie 2016-01-07 13:15:40 +08:00
astaxie
3fdf72f14c Merge pull request #1532 from JessonChan/develop
mem cache put function fixed
2016-01-07 12:56:47 +08:00
JessonChan
3821b2cb26 createdTime typo fixed 2016-01-07 09:37:50 +08:00
JessonChan
8aed4c13d7 isExist func will check if the value is expired 2016-01-07 09:36:23 +08:00
JessonChan
6465dbd703 no more goroutine ,i will be GCed at a gc goroutine 2016-01-07 09:28:40 +08:00
JessonChan
98e0626f0c rename vals 2016-01-07 09:25:06 +08:00
JessonChan
b0b9812de6 extract a expire fun 2016-01-07 09:13:47 +08:00
JessonChan
eff200e014 modify as xuxiaohei suggest
https://github.com/astaxie/beego/issues/1259
2016-01-07 09:08:00 +08:00
JessonChan
8832334d6a tiny fix for error description and comment 2016-01-06 15:12:25 +08:00
JessonChan
0b39091292 mem cache put function fixed
when a expire duration==0,it means forever
https://github.com/astaxie/beego/issues/1260
2016-01-06 15:05:29 +08:00
astaxie
a411042416 fix the init parse for config 2016-01-06 14:55:18 +08:00
astaxie
8929814126 fix the log carsh before init 2016-01-06 11:48:23 +08:00
miraclesu
bef6bca397 Add function to set validation default messages 2016-01-05 21:14:35 +08:00
astaxie
f7ef4aa7e5 recover for conn.Close fix #1333 2016-01-04 23:34:45 +08:00
astaxie
5c18d02b17 fix #1268 2016-01-04 22:41:25 +08:00
astaxie
3bb22d149e add the comments 2016-01-04 22:22:42 +08:00
astaxie
f0be45dfff fix the comments and json tag 2016-01-04 22:18:59 +08:00
astaxie
7fbaf82897 fix #1424 2016-01-04 22:10:18 +08:00
astaxie
73168d2f7d Merge pull request #1527 from JessonChan/develop
reuse compress writer
2016-01-04 14:36:40 +08:00
astaxie
a03fa0fb73 improve cache modules. support mulit instances 2016-01-04 10:50:04 +08:00
JessonChan
fd2ded190b EnableGzip bug fixed 2016-01-04 09:27:58 +08:00
JessonChan
d23291ccc7 remove a dump err 2016-01-04 08:50:59 +08:00
astaxie
92d157736b add testing to test #1511 2016-01-03 21:06:35 +08:00
astaxie
6585e66f97 all the browser should support delete and put now 2016-01-03 20:36:16 +08:00
JessonChan
3ebf275157 fixed camel style name 2016-01-03 15:40:44 +08:00
JessonChan
ee2322e83b add any level compress 2016-01-03 15:35:32 +08:00
JessonChan
59fa248292 use sync.Pool to decrease new compression writer 2015-12-31 18:50:52 +08:00
astaxie
9519fc6c96 Merge pull request #1519 from vvelikodny/develop
Refactoring: Move dev & prod runmodes to const
2015-12-30 21:03:54 +08:00
Vitaly Velikodny
4b368d9f5e Refactoring: keep config package beego independent 2015-12-30 11:22:09 +03:00
Vitaly Velikodny
48fd9675ad Refactoring: Move dev & prod runmodes to const 2015-12-29 21:32:37 +03:00
astaxie
ac3a447479 fix the session update issues 2015-12-27 14:09:20 +08:00
astaxie
37dff6be28 Merge pull request #1507 from yydzero/develop
Retrieve session identifier from cookie and query parameters
2015-12-27 11:01:04 +08:00
astaxie
cdde5bdc62 Merge pull request #1516 from johndoejdg/patch-2
Add link to russian
2015-12-27 11:00:24 +08:00
John Doe
2d4cc6e33d Add link to russian
Add link to russian
2015-12-26 16:43:49 +03:00
astaxie
5336e83469 Merge pull request #1506 from fuxiaohei/develop
clean code in docs.go, error.go, filter.go and hooks.go
2015-12-23 12:12:08 +08:00
Yandong Yao
da39082d4f Retrieve session identifier from cookie and query parameters 2015-12-22 10:30:44 +08:00
fud
cd514803a4 simplify filter.go hooks.go 2015-12-22 10:02:59 +08:00
fud
2ddda59605 Merge branch 'develop' of https://github.com/astaxie/beego into develop 2015-12-22 09:57:47 +08:00
astaxie
25337aec27 Merge branch 'develop' of https://github.com/astaxie/beego into develop 2015-12-21 22:54:22 +08:00
astaxie
351dfac653 context.Response should implement Hijack/Flush/CloseNotify 2015-12-21 22:51:18 +08:00
astaxie
9105fee453 Merge pull request #1503 from fuxiaohei/develop
simplfy config.go and controller.go
2015-12-21 19:49:22 +08:00
fud
bbd42ce152 simplify docs.go and error.go, use http.StatusText instead of string codes 2015-12-21 17:16:58 +08:00
fud
92711e80a3 refactor controller.go 2015-12-21 16:23:31 +08:00
fud
c43e3d6684 fix type mismatch error 2015-12-21 16:05:26 +08:00
fud
f6c508f138 Merge branch 'develop' of https://github.com/astaxie/beego into develop 2015-12-21 15:49:23 +08:00
astaxie
130ce7eb1f Merge pull request #1501 from nkbai/develop
cors test benchmark doesn't use b.N
2015-12-19 13:45:04 +08:00
nkbai
083c155079 cors test benchmark doesn't use b.N 2015-12-19 10:29:12 +08:00
astaxie
a71c4283e8 Merge pull request #1498 from JessonChan/develop
compress level test fixed
2015-12-18 10:18:42 +08:00
JessonChan
80ac8aa40e compress level test fixed 2015-12-18 09:28:40 +08:00
astaxie
5e249772d5 reduce loop 2015-12-18 00:14:28 +08:00
astaxie
a4f674e7f4 Merge pull request #1483 from nkbai/develop
为orm接口添加注释
2015-12-17 22:23:32 +08:00
astaxie
ae52d4aa18 improve the splitPath 2015-12-17 21:31:44 +08:00
fuxiaohei
f9138c5a99 simplify config.go 2015-12-17 20:05:00 +08:00
astaxie
e5096be32b Merge pull request #1490 from pjoe/orm_pk_rel_many
Fix joins for reverse(many) with custom pk
2015-12-17 14:56:06 +08:00
astaxie
9b87f528ec Merge pull request #1494 from astaxie/revert-1489-develop
Revert "go test fixed"
2015-12-17 14:45:17 +08:00
astaxie
c3d1e4d088 Revert "go test fixed" 2015-12-17 14:45:10 +08:00
astaxie
77113e843c Merge pull request #1489 from JessonChan/develop
go test fixed
2015-12-17 14:44:29 +08:00
astaxie
46aa340b1d Merge pull request #1478 from fuxiaohei/develop
clean compliated codes, refactor if sections in app.go
2015-12-17 14:44:14 +08:00
JessonChan
8771634fe4 Merge remote-tracking branch 'remotes/upstream/develop' into develop 2015-12-17 09:25:15 +08:00
astaxie
2aa50c240f Merge pull request #1486 from KilledKenny/oomDos
Added MaxMemory limit to CopyBody() Supersedes #1484
2015-12-16 23:44:42 +08:00
astaxie
dbc4ac6945 reduce the slicegrow 2015-12-16 23:43:32 +08:00
astaxie
29752e2575 refactor router 2015-12-16 23:11:03 +08:00
Simon Rawet
52c4c1fb98 Added MaxMemory limit to CopyBody()
Beego only uses the MaxMemory flag when using go's built in functions
for parsing forms. However the CopyBody() function have no limit an will
coppy anny amount of data into memory using ioutil.ReedAll() on the
request body whitout anny size validation or limit.

This fix wrapps input.Requst.Body in a LimitedReader using the same
memory limit as ParseFormOrMulitForm()
2015-12-16 10:37:21 +01:00
Pelle Johnsen
906637ae8b Fix issue with reverse(many) for models with custom pk
- Also add test covering the issue
2015-12-15 17:39:08 +01:00
nkbai
3daaaeb32b add commit for orm/types.go 2015-12-15 19:48:28 +08:00
JessonChan
ccc008c257 compress fixed 2015-12-15 14:29:07 +08:00
JessonChan
fd9a6ff7bb Merge remote-tracking branch 'remotes/upstream/develop' into develop 2015-12-15 14:27:43 +08:00
JessonChan
e63d24637d go test fixed 2015-12-15 14:08:58 +08:00
astaxie
7dcbcf0748 Merge branch 'develop' of https://github.com/astaxie/beego into develop 2015-12-15 14:05:58 +08:00
astaxie
1576add9a2 Merge pull request #1488 from astaxie/revert-1487-develop
Revert "compress method fixed"
2015-12-15 14:05:43 +08:00
astaxie
58aa0545b6 Revert "compress method fixed" 2015-12-15 14:05:33 +08:00
astaxie
10cbe7a867 Merge branch 'develop' of https://github.com/astaxie/beego into develop 2015-12-15 13:18:09 +08:00
astaxie
d6f23afdbb Merge pull request #1487 from JessonChan/develop
compress method fixed
2015-12-15 11:49:19 +08:00
JessonChan
499e2b59e4 compress method fixed
in http,the deflate is zlib compress method accoding to the sec
http://tools.ietf.org/html/rfc2616#section-3.5
The "zlib" format defined in RFC 1950 [31] in combination with
        the "deflate" compression mechanism described in RFC 1951 [29].
2015-12-15 11:34:26 +08:00
nkbai
d99c62df1f Merge remote-tracking branch 'upstream/develop' into develop 2015-12-14 15:09:06 +08:00
nkbai
b079456fcf add comments for orm/types.go 2015-12-14 15:04:17 +08:00
fuxiaohei
a06022f75c clean compliated codes, refactor if sections in app.go 2015-12-12 14:10:02 +08:00
astaxie
2b651fbae2 reuse map in tree.Match 2015-12-11 13:51:01 +08:00
astaxie
80bc372f17 pool.Put 2015-12-11 00:20:17 +08:00
astaxie
f70f338025 use sync.Pool to reuse Context 2015-12-10 21:59:54 +08:00
astaxie
f2edfbe7ae make the other three beauty 2015-12-10 00:12:52 +08:00
astaxie
4f829af7aa gofmt the config default 2015-12-10 00:11:24 +08:00
astaxie
9f2a2507fd fmt it and remove the init var 2015-12-09 23:47:44 +08:00
astaxie
be60f47488 Merge pull request #1455 from nkbai/develop
windows下静态文件映射找不到问题以及 grace init延后
2015-12-09 23:44:45 +08:00
astaxie
d1bba02958 refact beego config 2015-12-09 23:35:04 +08:00
nkbai
e8fe859a58 格式调整 2015-12-09 09:03:10 +08:00
nkbai
82e0105d22 Revert "windows下静态文件映射找不到问题,"
windows下路径需要filepath.ToSlash

This reverts commit 2c8cb5693e.
2015-12-04 23:15:06 +08:00
nkbai
ff0762cc19 Merge remote-tracking branch 'upstream/develop' into develop 2015-12-03 15:50:21 +08:00
astaxie
3d4ad560f8 Merge pull request #1423 from JessonChan/fargo
fix the  accept encoding
2015-12-02 21:08:34 +08:00
astaxie
36664634f9 Merge pull request #1467 from astaxie/revert-1464-master
Revert "Update orm_querym2m.go"
2015-12-02 16:35:44 +08:00
astaxie
ed99c013a6 Revert "Update orm_querym2m.go" 2015-12-02 16:35:36 +08:00
astaxie
a1d5f958c5 Merge pull request #1464 from gobenon/master
Update orm_querym2m.go
2015-12-02 16:35:05 +08:00
astaxie
5d902264e5 Merge pull request #1459 from ryanchapman/develop
Log config parsing errors
2015-12-02 16:34:35 +08:00
gobenon
50f8f3bd20 Update orm_querym2m.go 2015-11-30 18:23:58 +02:00
nkbai
74ebcd28b2 grace init中的工作可以延后进行
实际上如果没有使用graceful启动,这些init的工作完全没用
当然其他模块也应该存在这样的工作,比如session中的sess_utils.go中的init工作
2015-11-30 16:15:35 +08:00
Ryan A. Chapman
7151b96465 Log config parsing errors
Beego currently handles the case of "conf/app.conf"
not existing, but all other errors are not logged.
This fixes that.

I ran into an issue where beego was not listening on the
correct port, and it turned out that the conf/app.conf file
had a colon ":" instead of an equal sign "=" (confusion of
INI vs YAML formats).  When there was a parsing error, beego
would give up on parsing app.conf and not log anything to the
console.
2015-11-29 15:09:28 -07:00
nkbai
2c8cb5693e windows下静态文件映射找不到问题,
path.Clean和filepath.Clean是有区别的
2015-11-27 12:10:39 +08:00
nkbai
d693ecf046 Revert "这种if型的初始化是有问题的"
This reverts commit 50132df809.
2015-11-26 20:37:36 +08:00
nkbai
6aaca2eca8 router.go Header 毫无用处
context/output.go 简化一下代码,更清晰
2015-11-26 14:56:39 +08:00
nkbai
f0474214fe GetInt等函数稍微简化一下,这样看上去更合理一些 2015-11-25 23:39:26 +08:00
astaxie
2c94d9eab2 Merge pull request #1451 from gobenon/master
fix issue 1438 opened by Ayelet Regev
2015-11-25 09:29:28 +08:00
JessonChan
40700a8532 Merge remote-tracking branch 'remotes/upstream/develop' into fargo
# Conflicts:
#	memzipfile.go
2015-11-25 09:11:32 +08:00
astaxie
fb7314f8ac Merge pull request #1450 from astaxie/revert-1439-master
Revert "Adding support for junction tables with other fields which arent FK and PK."
2015-11-24 23:00:15 +08:00
astaxie
b7fcd4f0b9 Revert "Adding support for junction tables with other fields which arent FK and PK." 2015-11-24 23:00:07 +08:00
astaxie
e48e09a4ab Merge pull request #1439 from gobenon/master
Adding support for junction tables with other fields which arent FK and PK.
2015-11-24 23:00:04 +08:00
astaxie
235b58504a Merge pull request #1449 from nkbai/master
controller_test.go 既然叫test,那就按照go的规则进行test吧
2015-11-24 15:54:46 +08:00
nkbai
5e915cb614 controller_test.go 既然叫test,那就按照go的规则进行test吧 2015-11-24 14:55:59 +08:00
JessonChan
9170b91075 go style format (remove the blank after comments) 2015-11-21 08:46:19 +08:00
astaxie
25320bf86a Merge pull request #1441 from nkbai/master
fix #1433
2015-11-20 21:50:55 +08:00
nkbai
50132df809 这种if型的初始化是有问题的 2015-11-20 21:34:01 +08:00
nkbai
83696a40f6 fix #1433 2015-11-20 11:18:45 +08:00
gobenon
efd30bdba7 Update orm_querym2m.go 2015-11-19 16:46:14 +02:00
gobenon
01aa1085e0 Merge pull request #1 from gobenon/gobenon-m2mpatch-1
Update orm_querym2m.go
2015-11-19 14:32:24 +02:00
gobenon
ca37557a26 Update orm_querym2m.go 2015-11-19 14:30:14 +02:00
astaxie
5a1e821a42 Merge pull request #1434 from WnP/pg-fix
fix postgres syntax error during migration
2015-11-19 12:25:21 +08:00
Steeve Chailloux
29ac961c10 fix postgres syntax error during migration 2015-11-18 06:46:44 -06:00
JessonChan
5d01afe3a6 isOk to check whether the file is latest 2015-11-16 14:05:05 +08:00
JessonChan
d963bb79bd avoid map-lock delete 2015-11-16 10:31:27 +08:00
JessonChan
bc2195b07f code simplify 2015-11-12 16:59:07 +08:00
JessonChan
46fbeaadad refactor accept encoder ,simplify the struct 2015-11-12 12:03:53 +08:00
JessonChan
214030fad4 bytes reader replace string reader 2015-11-12 11:44:29 +08:00
JessonChan
f8db8ae9c3 add some comments 2015-11-12 10:48:36 +08:00
JessonChan
a9881388f7 accept encoder header setting fixed 2015-11-12 10:08:57 +08:00
JessonChan
1200b7c347 method refactor 2015-11-11 18:06:18 +08:00
JessonChan
b25a1355f9 remove old code 2015-11-11 16:27:41 +08:00
JessonChan
d2c60619fa new static file support code 2015-11-11 16:22:40 +08:00
JessonChan
82c50b972d new test file 2015-11-11 16:22:05 +08:00
JessonChan
15b0b9b66d delete old static file code 2015-11-11 16:21:04 +08:00
JessonChan
e4c6e5d2e1 change package 2015-11-11 13:47:47 +08:00
JessonChan
f457ea0fe9 refactor encoder package 2015-11-11 13:47:36 +08:00
JessonChan
7ef9b3d55b runnable typo fixed 2015-11-10 14:07:26 +08:00
JessonChan
39e29caf9b refactor to fix encoder type bug 2015-11-10 13:42:10 +08:00
JessonChan
7ccf049a50 bug fixed 2015-11-10 13:27:33 +08:00
JessonChan
7964f7f163 test bug fixed 2015-11-10 13:16:16 +08:00
JessonChan
8603127c81 beego package file path rewrite 2015-11-10 13:10:42 +08:00
JessonChan
07c93cd32c mem zip file test ,add license 2015-11-10 11:59:32 +08:00
JessonChan
83ec39d02e refactor max age cookies setting 2015-11-10 11:47:10 +08:00
JessonChan
8f42193610 better compress func design 2015-11-10 11:32:18 +08:00
JessonChan
891be34fc6 encoding should be specify 2015-11-10 11:20:13 +08:00
JessonChan
0bc70e88f0 ignore the other compress method 2015-11-10 11:00:29 +08:00
JessonChan
3872c48349 accept encoding refactor and bug fixed 2015-11-10 10:55:47 +08:00
JessonChan
dc28e37606 Merge branch 'develop' into fargo 2015-11-09 17:18:00 +08:00
astaxie
821b2f832e fix the type assert 2015-11-09 11:03:57 +08:00
astaxie
9b725c73c3 Merge pull request #1376 from JessonChan/develop
static file code refactor and bug fixed
2015-11-08 23:21:16 +08:00
JessonChan
860568cb6c modified as astaxie reviews
https://github.com/astaxie/beego/pull/1376
2015-11-06 18:51:53 +08:00
astaxie
dc3e324f38 Merge pull request #1418 from ElvizLai/patch-1
Update context.go
2015-11-05 22:39:34 +08:00
Yongzheng Lai
b8fc42d38d Update context.go
all this status was setting in error.go, this line will cause multi-resp
2015-11-05 21:20:57 +08:00
astaxie
a26dee556d fix #1335 2015-11-05 00:19:09 +08:00
astaxie
fd4630c6dd impove the ResponseWriter. fix #1410 2015-11-04 23:52:42 +08:00
astaxie
e3120226fa Merge pull request #1414 from FlamingTree/develop
bugfix: graceful failed when both enable http and https
2015-11-04 23:27:27 +08:00
astaxie
25bec8bbe9 Merge pull request #1381 from ADone/m2m_reverse_bug
fix #671
2015-11-04 23:20:22 +08:00
astaxie
a257a924a1 Merge pull request #1379 from pjoe/non_int_fk
orm: Fix handling of rel(fk) to model with string pk
2015-11-04 22:26:33 +08:00
astaxie
c7e9a86b00 Merge pull request #1415 from johndeng/develop
Fixed typos
2015-11-04 13:08:37 +08:00
John Deng
205de8418d Fixed typos 2015-11-03 23:43:34 +08:00
shaoguang
f81929c28c bugfix: graceful failed when both enable http and https 2015-11-03 14:53:26 +08:00
astaxie
58ed1436cc Merge pull request #1409 from superhacker777/patch-2
XSRFFormHtml() should also generate XSRF token.
2015-10-28 15:54:07 +08:00
Mikhail Devyatov
5d18a7466c XSRFFormHtml() should also generate XSRF token. 2015-10-27 20:16:47 +03:00
astaxie
912abe3272 fix #1388 2015-10-12 21:26:18 +08:00
astaxie
4ba50e5df5 fix #1385 2015-10-12 20:50:58 +08:00
astaxie
332fa44231 Merge pull request #1384 from pjoe/update_err_fix
Fix dbBase.Update not returning error on failure
2015-10-12 20:43:22 +08:00
Pelle Johnsen
174e758d19 Fix dbBase.Update not returning error 2015-09-28 14:07:35 +02:00
JessonChan
1f2f0b30f4 mem zip file refactor and test 2015-09-22 22:02:56 +08:00
Pelle Johnsen
cfcce4f5dc Fix handling of rel(fk) to model with string pk 2015-09-22 12:23:51 +02:00
JessonChan
1abf85ed2a simplify the switch code 2015-09-22 15:18:24 +08:00
JessonChan
d4f3dfd527 return when find static path 2015-09-22 14:15:41 +08:00
JessonChan
6ad215a9bb mem zip file var refactor 2015-09-22 14:11:02 +08:00
JessonChan
9c17f73489 code refactor 2015-09-22 13:48:34 +08:00
JessonChan
4995f91547 code refactor 2015-09-22 13:46:20 +08:00
JessonChan
936cb735e1 file extensions bug fixed 2015-09-22 13:27:35 +08:00
JessonChan
f708ce0299 当有设置的压缩类型时,丢弃默认类型(css,js) 2015-09-22 12:24:52 +08:00
JessonChan
dc38b324e0 code bug fixed 2015-09-22 12:19:31 +08:00
JessonChan
b9fb3a62f5 static file name default lower case 2015-09-22 11:59:48 +08:00
astaxie
95ef4c7136 server index.html in beego with ServeContent 2015-09-21 23:56:24 +08:00
astaxie
eb85e8e328 path.Clean can't clean window separate .."
"
2015-09-20 19:59:30 +08:00
astaxie
e26720496f remove the dupl 2015-09-19 20:05:57 +08:00
astaxie
8af8936ee0 Merge pull request #1368 from JessonChan/fargo
error bug fixed and clean code
2015-09-19 15:10:22 +08:00
JessonChan
07a424581d // beego.Run("localhost") 2015-09-19 05:53:28 +08:00
JessonChan
69bee9ef3c // beego.Run("localhost") 2015-09-19 05:52:52 +08:00
JessonChan
caf3714495 revert exceptMethod 2015-09-19 05:41:10 +08:00
JessonChan
983bac986a runFunction camel name 2015-09-18 18:34:07 +08:00
JessonChan
56032c67af runFunction camel name 2015-09-18 18:31:06 +08:00
JessonChan
40cb8e0cf1 use reflect to ensure all methods been except 2015-09-18 18:18:12 +08:00
JessonChan
0ac690d2c8 method name refactor 2015-09-18 17:59:28 +08:00
JessonChan
cc5abc6b30 default atoi func to handle exception 2015-09-18 17:03:00 +08:00
astaxie
cb0400dcd4 file add the config for Perm 2015-09-18 12:12:02 +08:00
astaxie
fda28fa2ff fix the conv test case 2015-09-18 12:11:48 +08:00
JessonChan
2a96f33543 more clean code 2015-09-18 10:36:16 +08:00
JessonChan
8df2cca627 add comment 2015-09-18 10:32:21 +08:00
JessonChan
ead635e62f default exception handler 2015-09-18 10:31:10 +08:00
astaxie
4823a0f114 remove the dead code 2015-09-17 23:47:26 +08:00
astaxie
e665a7dd32 Merge pull request #1367 from dvwallin/develop
added a check to parser to not panic (in develop)
2015-09-17 23:41:59 +08:00
astaxie
6e24b78b62 fix the wrong response 2015-09-17 23:27:34 +08:00
David V. Wallin
edbad60782 Merge branch 'develop' of github.com:dvwallin/beego into develop 2015-09-17 17:07:06 +02:00
astaxie
bb6062857b fix the error refactor 2015-09-17 23:05:45 +08:00
astaxie
0d100fef7d Merge pull request #1364 from JessonChan/fargo
error and hook refactor
2015-09-17 23:02:32 +08:00
astaxie
eac09e6fb6 Merge pull request #1349 from ElvizLai/patch-4
Update tree.go
2015-09-17 23:01:32 +08:00
astaxie
3df0fa462d golint tidb 2015-09-17 23:00:05 +08:00
astaxie
dfbb1b5ee5 Merge pull request #1366 from ngaut/master
Add support for TiDB
2015-09-17 21:25:12 +08:00
ngaut
09b7457ac6 orm_test: Skip relation test 2015-09-17 17:05:40 +08:00
ngaut
c841a77ad6 Orm: Add tidb for query builder 2015-09-17 17:04:23 +08:00
ngaut
c73e0395ed Orm: Support TiDB 2015-09-17 17:04:23 +08:00
JessonChan
de20960458 error map refactor 2015-09-17 10:36:29 +08:00
JessonChan
bb776cc4cb error map refactor 2015-09-17 10:33:12 +08:00
JessonChan
cce8d1e934 refactor hooks function code 2015-09-17 10:31:53 +08:00
astaxie
c6448727de golint utils 2015-09-14 23:35:13 +08:00
astaxie
5015614fdc golint pagination 2015-09-14 23:17:33 +08:00
astaxie
7b81617a95 golint captcha 2015-09-14 23:13:51 +08:00
astaxie
2389bc72f9 golint validation 2015-09-13 00:13:19 +08:00
astaxie
1d200da472 golint toolbox 2015-09-12 23:28:24 +08:00
astaxie
be7accc94c golint testing 2015-09-12 23:19:18 +08:00
astaxie
a289b08e64 golint swagger 2015-09-12 23:15:23 +08:00
astaxie
172894efe8 golint session 2015-09-12 22:53:55 +08:00
astaxie
ea2039c1dc golint plugins 2015-09-12 22:03:45 +08:00
astaxie
68ec133aa8 golint orm 2015-09-12 21:46:43 +08:00
astaxie
542e143e55 golint migration 2015-09-11 23:16:05 +08:00
astaxie
0a5fa04062 remove i18n.go 2015-09-11 23:09:37 +08:00
astaxie
34877c52a9 golint logs 2015-09-11 23:08:24 +08:00
astaxie
657995092a golint httplib 2015-09-11 22:28:28 +08:00
David V. Wallin
f6d4629103 added a check to parser to not panic 2015-09-10 11:35:57 +02:00
astaxie
65fb7ce391 golint grace 2015-09-10 16:35:40 +08:00
astaxie
01a5e54264 delete example from the source code 2015-09-10 15:40:46 +08:00
astaxie
ff5b09fc19 golint context 2015-09-10 15:31:09 +08:00
astaxie
bdd6a6ae40 golint config 2015-09-10 14:53:19 +08:00
astaxie
d7aaf2ebeb golint cache package 2015-09-09 00:15:03 +08:00
astaxie
62e528ca4c golint tree.go 2015-09-08 23:49:24 +08:00
astaxie
bcb1db256d golint templatefunc 2015-09-08 23:41:41 +08:00
astaxie
44bd3beb5e golint happy with template 2015-09-08 23:29:58 +08:00
astaxie
8615f875f8 make golint happy staticfile.go 2015-09-08 22:07:44 +08:00
astaxie
b2048e8653 make router test passed 2015-09-08 22:05:38 +08:00
astaxie
c11740b647 make golint happy router.go 2015-09-08 22:01:13 +08:00
astaxie
21fffc446b make golint happy parser.go 2015-09-08 21:45:45 +08:00
astaxie
67b36d7c48 make golint happy 2015-09-08 21:41:38 +08:00
astaxie
61570ac2f7 make golint happy with controller.go 2015-09-08 10:43:42 +08:00
astaxie
f28a941e26 make golint happy and also make the config readable 2015-09-07 23:19:42 +08:00
astaxie
152127c2af make golint happy 2015-09-07 21:38:53 +08:00
astaxie
919675e793 update the comments 2015-09-07 19:29:52 +08:00
astaxie
fe9c52fb69 optimize init admin 2015-09-07 19:27:53 +08:00
astaxie
284dfc0843 move the template related fun to template.go 2015-09-07 19:21:55 +08:00
astaxie
85d8ec5ca6 optimize the beego structure 2015-09-07 19:18:04 +08:00
astaxie
eb3479b753 optimize the app structure 2015-09-06 23:00:42 +08:00
Yongzheng Lai
a2a6ec954b Update tree.go
go fmt
2015-09-06 22:13:58 +08:00
astaxie
45b72b0674 Merge pull request #1334 from ElvizLai/patch-2
Update beego.go
2015-09-06 22:12:13 +08:00
astaxie
9e969957de Merge pull request #1348 from sidbusy/develop
allows custom the TableName of Session
2015-09-06 21:22:05 +08:00
astaxie
7b0f3a83dc Merge pull request #1351 from leekchan/cache
Fix a wrong test name & update a outdated information in README
2015-09-06 18:46:59 +08:00
Kyoung-chan Lee
fe1ec1675f Fix a wrong url (http 404). 2015-09-06 17:22:33 +09:00
Kyoung-chan Lee
4ad743fc8b Update a outdated information in README. 2015-09-06 17:20:18 +09:00
Kyoung-chan Lee
06ec3a931d Fix a wrong test name. 2015-09-06 17:13:55 +09:00
Yongzheng Lai
1377d16559 Update tree_test.go 2015-09-06 12:17:16 +08:00
Yongzheng Lai
ddd9bf1305 Update tree.go 2015-09-06 12:16:05 +08:00
Yongzheng Lai
508a57be1e Update tree_test.go 2015-09-06 12:07:12 +08:00
Yongzheng Lai
5ad999a3d1 Update tree.go
fix routers for:
```
/topic/:id/?:auth
/topic/:id/?:auth:int
```
2015-09-06 12:01:50 +08:00
sidbusy
f55bbbdff4 allows custom the TableName of Session 2015-09-05 10:31:31 +08:00
astaxie
34aa9002bb fix the httplib test case timeout 2015-09-04 23:03:10 +08:00
astaxie
f9fe89fff0 fix the file rotate test case issues 2015-09-04 22:33:03 +08:00
astaxie
9ab7466d5c fix the cappital 2015-09-04 22:20:55 +08:00
astaxie
2e75c04ffb Merge pull request #1345 from f0r/develop
为querySeter添加GroupBy方法
2015-09-04 21:48:47 +08:00
astaxie
9038cdfaae Merge pull request #1343 from onealtang/oneal-dev
always use server's locale to parse date
2015-09-04 21:32:18 +08:00
f0r
a074df9c2e 为querySeter添加GroupBy方法 2015-09-03 00:45:09 +08:00
onealtang
adca455804 always use server's locale to parse date
When parsing the date without time, it's always using UTC date, which is
unexpected. If we want to use UTC date, it's recommend to set the
server's timezone as UTC, and keep the code flexible.
2015-09-02 15:50:40 +08:00
Yongzheng Lai
9fd571830d Update beego.go
Maybe the `Hard Coding` should have a higher priority
2015-09-01 17:52:44 +08:00
astaxie
dd4cbdda66 update the gitignore 2015-08-31 11:58:11 +08:00
astaxie
ad6547936e fix the http: multiple response.WriteHeader calls 2015-08-28 23:08:00 +08:00
astaxie
306effa300 Merge pull request #1329 from ElvizLai/patch-1
Update error.go
2015-08-28 22:33:20 +08:00
Yongzheng Lai
c516819c56 Update error.go
this caused `http: multiple response.WriteHeader calls` when using method `CustomAbort` or `Abort` when status is already in errMap like 404.
2015-08-28 16:54:49 +08:00
astaxie
4202fe8fe0 Merge pull request #941 from lei-cao/develop
Added JWT plugin
2015-08-27 22:57:04 +08:00
astaxie
0c5f4b48d4 Merge pull request #1276 from pjoe/orm_distinct
Fix issue #1274: Add QuerySeter.Distinct()
2015-08-27 22:54:39 +08:00
astaxie
7aa893612e Merge pull request #1308 from zhangshuai/master
httplib请求参数支持[]string
2015-08-27 22:50:44 +08:00
astaxie
cfaae5ab8c Merge pull request #1326 from hvnsweeting/patch-1
fix typo
2015-08-27 22:49:38 +08:00
Viet Hung Nguyen
cbb6591bdb fix typo 2015-08-26 15:57:28 +07:00
Pelle Johnsen
0c33673197 Revert spaces > tabs change 2015-08-24 09:41:10 +02:00
Shuai
862ea226e5 优化设置参数 2015-08-24 00:16:56 +08:00
astaxie
437349f776 Merge pull request #1247 from Skycrab/develop
fix example/chat i/o timeout
2015-08-23 22:18:38 +08:00
astaxie
bc1f0ac6fd Merge pull request #1298 from wulove/develop
全局变量AutoRender为false时,run时不再编译模版;针对开发模式下,每个请求渲染模版时支持单独编译当前请求相关模版
2015-08-23 22:13:15 +08:00
astaxie
db2b1ee54f Merge pull request #1318 from tabalt/patch-1
fixed mux1 to mux
2015-08-21 10:57:42 +08:00
tabalt
99b1c5c54b fixed mux1 to mux 2015-08-21 10:53:59 +08:00
wulove
38ddb61199 files is []string, use len(files)==0 2015-08-21 10:32:53 +08:00
astaxie
d9e4836715 Merge pull request #1305 from Hepri/develop
Added MapGet template func
2015-08-20 22:33:07 +08:00
Sergey Shcherbina
0e3fe64c69 Added TestMapGet 2015-08-20 19:04:43 +05:00
astaxie
4081311a37 Merge pull request #1309 from smallfish/develop
Update router.go, add Flush for responseWriter
2015-08-19 15:25:24 +08:00
陈小玉
506f54a080 Update router.go, add Flush for responseWriter 2015-08-19 15:23:50 +08:00
Shuai
ff92f22d84 删除Param中的断言 2015-08-18 23:19:24 +08:00
Shuai
860006bfda httplib请求参数支持[]string 2015-08-18 19:28:17 +08:00
astaxie
9107fd8898 remove the default timeout setting 2015-08-17 22:33:28 +08:00
Hepri
d91840779a Update templatefunc.go 2015-08-17 01:18:29 +05:00
Sergey Shcherbina
d4e15c0bd0 Added MapGet template func 2015-08-17 00:08:02 +05:00
wulove
877b5c233e 增加编译模版函数BuildTemplate可变参数,使之支持单个或多个模版的编译,同时针对开发模式,每个请求只编译当前请求相关模版
增加编译模版函数BuildTemplate可变参数,使之支持单个或多个模版的编译,同时针对开发模式,每个请求只编译当前请求相关模版,不再每次请求都编译全部模版
2015-08-06 10:09:34 +08:00
wulove
57fdc308e3 AutoRender为空时,不再编译模版
AutoRender为空,Controller.Render()不再执行,故无需编译模版
2015-08-06 09:36:43 +08:00
astaxie
4857e38471 Merge pull request #1284 from wallclockbuilder/develop
Fix #1269 extract godoc to own file.
2015-07-28 11:57:27 +08:00
astaxie
42fab96cd4 Merge pull request #1285 from JessonChan/beego_develop
typo fixed
2015-07-28 11:56:45 +08:00
JessonChan
b26ef5b2e5 typo fixed
registor==>register
innner ==> inner
2015-07-27 08:44:58 +08:00
Mawuli Adzoe
b622d5d369 Fix #1269 extract documentation
Fix #1271 Add description from docs on beego.me to README
and also add same description to godoc
2015-07-26 17:06:55 +00:00
Pelle Johnsen
19d82ab62c Fix #1274: Add QuerySeter.Distinct() 2015-07-22 18:12:57 +02:00
astaxie
9775e3e3a4 Merge pull request #1265 from fugr/develop
set DoRotate fname like xx.2013-01-01.2.log
2015-07-17 01:56:48 +08:00
astaxie
160d82d1d2 Merge pull request #1267 from wallclockbuilder/develop
Fix for #1256. Indent the code sample lines properly.
2015-07-17 01:50:09 +08:00
Mawueli Kofi Adzoe
45d693e6d6 Add quick start example from website to README 2015-07-16 04:32:07 +00:00
Mawuli Adzoe
0564956fd6 Fix for #1256. Indent the code sample lines properly. 2015-07-15 12:04:18 +00:00
Hubery
59b903d557 set DoRotate fname like xx.2013-01-01.2.log
fix fname,by extension to identify the file type on mac and windows.
2015-07-15 17:00:48 +08:00
Artem Nistratov
5612f61a93 fix #671 2015-07-08 17:42:00 +03:00
astaxie
3becd2e0d8 Merge pull request #1249 from wallclockbuilder/patch-1
Fix #1237
2015-07-08 12:38:48 +08:00
skycrab
8c0ad5ef88 fix example/chat i/o timeout 2015-07-06 21:12:03 +08:00
astaxie
079993b9f7 fix #1245 2015-07-06 13:54:14 +08:00
astaxie
c15aaad85b Merge pull request #1244 from simman/develop
Update validators.go
2015-07-04 20:48:47 +08:00
SimMan
06b25deab2 Update validators.go
Support virtual operators paragraph 170!
2015-07-04 17:55:01 +08:00
Mawueli Kofi Adzoe
002302818d Fix #1237
Package description uses same text as the README.
2015-07-01 04:17:53 +00:00
astaxie
a89f14d80d Merge pull request #1227 from oiooj/develop
fix FilterHandler crash issue
2015-06-19 11:43:15 +08:00
MrLee.Kun
87e8bcc9be fix FilterHandler crash issue
Filter Handler will crash with error assignment to entry in nil map , params from function Tree.Match() maybe nil.
2015-06-19 11:19:35 +08:00
MrLee.Kun
31e5edbdcf Merge pull request #2 from astaxie/develop
pull from stable
2015-06-19 11:09:11 +08:00
astaxie
f7f390dfec fix #1221 2015-06-16 14:53:38 +08:00
astaxie
8f7246e17b change to version 1.5.0 2015-06-15 23:49:13 +08:00
astaxie
c8f6e0f156 remove the hardcode in runtime.Caller 2015-06-15 20:53:49 +08:00
astaxie
0207caab6f keep the shortname for logs info/warn/debug 2015-06-15 20:44:14 +08:00
astaxie
d629c1d3d0 change the comments 2015-06-15 20:22:05 +08:00
astaxie
817650aa33 keep the short name for logs 2015-06-15 20:20:37 +08:00
astaxie
ba1232dfaf filter should be always the same 2015-06-14 18:35:46 +08:00
astaxie
64d4f6518b fix #1213 2015-06-14 18:10:10 +08:00
astaxie
9f05db8475 Merge pull request #1212 from astaxie/revert-1211-revert-1210-develop
Revert "Revert "fix multiple filters execute issue""
2015-06-14 01:14:42 +08:00
astaxie
b275d7c6f5 Revert "Revert "fix multiple filters execute issue"" 2015-06-14 01:14:33 +08:00
astaxie
73770fbe22 Merge pull request #1211 from astaxie/revert-1210-develop
Revert "fix multiple filters execute issue"
2015-06-14 01:13:42 +08:00
astaxie
fc11169ee3 Revert "fix multiple filters execute issue" 2015-06-14 01:13:34 +08:00
astaxie
b54589fa9d Merge pull request #1210 from oiooj/develop
fix multiple filters execute issue
2015-06-14 01:08:51 +08:00
MrLee.Kun
2af0c569a5 The last filterFunc with returnOnOutput=ture won't be executed
ex:
	beego.InsertFilter("/*", beego.BeforeExec, FilterLoginCheck1,false)
	beego.InsertFilter("/*", beego.BeforeExec, FilterLoginCheck2)

In function  FilterLoginCheck1 , I'll write data via ResponseWriter, and w.started = true
FilterLoginCheck2 won't be executed, it should be.
2015-06-14 01:02:41 +08:00
MrLee.Kun
27b7a8f743 Merge pull request #1 from astaxie/develop
Develop
2015-06-14 00:35:38 +08:00
astaxie
c143a6ec19 fix #1090 add Getfiles to support mulit file upload 2015-06-13 16:20:26 +08:00
astaxie
e619d83990 fix the filter router issues 2015-06-13 12:47:01 +08:00
astaxie
27b452cd95 Merge branch 'develop' of https://github.com/astaxie/beego into develop 2015-06-13 11:15:44 +08:00
astaxie
b776e43962 merge bat/httplib to httplib 2015-06-13 11:15:13 +08:00
astaxie
cb89cd577d Merge pull request #1201 from kongjian/develop
support eq&ne for orm
2015-06-13 10:54:47 +08:00
astaxie
6b777f0c5e Merge pull request #1207 from oiooj/develop
Don't overwrite the params from function  ValidRouter
2015-06-13 09:16:07 +08:00
MrLee.Kun
491238ce7d Don't overwrite the params from function ValidRouter
just add new params to context.Input.Params
2015-06-13 01:04:46 +08:00
astaxie
d9bb1a3592 logs support elasticsearch adapter 2015-06-13 00:25:48 +08:00
astaxie
9c6775c22c log default use synchro, and support async 2015-06-13 00:25:21 +08:00
astaxie
4d70b22f96 Merge pull request #1157 from ziyel/master
Let filter function get more params info from ctx.Input.Params
2015-06-11 14:38:19 +08:00
ziyel
d943d16d52 gofmt 2015-06-10 21:26:04 +08:00
空见
bbb6f31f16 support eq&ne for orm 2015-06-09 10:18:21 +08:00
astaxie
364cacf659 record the critical logs in Prod 2015-06-08 22:00:28 +08:00
astaxie
21586586ba Merge pull request #1198 from kongjian/develop
remove space after int()& add sort for commentsRouter file
2015-06-08 20:20:40 +08:00
空见
e1d7bc8826 remove space after int()& add sort for commentsRouter file 2015-06-08 17:25:46 +08:00
astaxie
499ee09d4b Merge pull request #1194 from zieckey/GetMulti
Add GetMulti method for Cache interface
2015-06-08 08:36:20 +08:00
weizili.build17
970f0b460c Add GetMulti method for Cache interface 2015-06-07 21:33:01 +08:00
astaxie
9280683935 Merge pull request #1193 from zieckey/auth
Execute AUTH command when the "password" is configured
2015-06-07 20:34:32 +08:00
weizili.laptop
a58c8180e8 Execute AUTH command when the "password" is configured 2015-06-07 16:26:23 +08:00
astaxie
b9852df51c Merge pull request #1190 from xboston/patch-1
fix session table
2015-06-04 22:09:26 +08:00
Nikolay Kirsh
8e71d31dbe fix session table 2015-06-04 18:40:10 +05:00
astaxie
db06e954b5 fix the session memcache bug 2015-05-28 12:04:19 +08:00
astaxie
3abd01799d split into small files 2015-05-27 23:46:45 +08:00
astaxie
ae37689314 fix #1176 grace support windows 2015-05-27 23:22:05 +08:00
astaxie
40974365e6 Merge branch 'develop' of https://github.com/astaxie/beego into develop 2015-05-25 09:10:59 +08:00
astaxie
edbaa080f1 update the string 2015-05-25 09:10:38 +08:00
astaxie
d56491ab3a sync beeApp.Server to graceful 2015-05-25 09:10:38 +08:00
astaxie
9fd7acf663 fix #1152 2015-05-25 09:10:37 +08:00
astaxie
2dca48f26e fix sesseion redis db error 2015-05-25 09:10:37 +08:00
astaxie
4138fe0217 beego suppot graceful restart application 2015-05-25 09:10:37 +08:00
astaxie
245762f7d9 add apk mime 2015-05-25 09:10:37 +08:00
astaxie
18bdec951d fix #1143 2015-05-25 09:10:37 +08:00
mlgd
9252301fa0 Fix save config ini file 2015-05-25 09:10:37 +08:00
cr7pt0gr4ph7
1053b63bbc Improve documentation of filter.go. 2015-05-25 09:10:37 +08:00
JessonChan
3bd6caae0a set default timeout 2015-05-25 09:10:37 +08:00
JessonChan
d8734cf58d set default timeout 2015-05-25 09:10:37 +08:00
JessonChan
51161361db more fixed 2015-05-25 09:10:37 +08:00
JessonChan
6da0cdb9e2 no need lock here 2015-05-25 09:10:37 +08:00
JessonChan
9f070c622b no need defer here 2015-05-25 09:10:37 +08:00
JessonChan
738e22e389 zero timeout means wait until resp 2015-05-25 09:10:37 +08:00
JessonChan
69fc22f0df typo fixed 2015-05-25 09:10:37 +08:00
JessonChan
4cd7177ece typo fixed 2015-05-25 09:10:37 +08:00
JessonChan
8e618192c2 better code and fixed 2015-05-25 09:10:37 +08:00
JessonChan
3415a5b091 better go style 2015-05-25 09:10:37 +08:00
Wyatt Fang
dfe055c47c remove useless comments 2015-05-25 09:10:36 +08:00
Wyatt Fang
74b22649c8 remove the double isStruct/isStructPtr check 2015-05-25 09:10:36 +08:00
Wyatt Fang
4255630564 add Recursively validation 2015-05-25 09:10:36 +08:00
astaxie
7e3b5e5307 remove unreached code 2015-05-25 09:10:36 +08:00
Trần Văn Thanh
0222b8d693 fixed: when RelatedSel have multi string/relation, it only get last string 2015-05-25 09:10:36 +08:00
wuranbo
23268b788a *feature) 增加logcalldepth接口,使得能简单再次封装log系列函数。 2015-05-25 09:10:36 +08:00
astaxie
ee4fd60e4d no output the dump 2015-05-25 09:10:36 +08:00
astaxie
4414659df4 fix the init struct 2015-05-25 09:10:36 +08:00
astaxie
68ccd8e5a4 fix the dump has no body 2015-05-25 09:10:36 +08:00
astaxie
6f802b0a05 fix the params 2015-05-25 09:10:36 +08:00
astaxie
743628a946 add DumpRequest 2015-05-25 09:10:36 +08:00
astaxie
d90ce15707 httplib support gzip 2015-05-25 09:10:36 +08:00
astaxie
23457ed2a0 add sethost 2015-05-25 09:10:36 +08:00
peeped
d7791ba837 Update validators.go
//176 中国联通
//177 中国电信
//145 中国联通
//147 中国移动
//149 中国电信
2015-05-25 09:10:36 +08:00
Lionel Lee
676595213f fix a comment error. 2015-05-25 09:10:36 +08:00
astaxie
d446b5b011 improve the defaultval 2015-05-25 09:10:36 +08:00
astaxie
2ba12ad1e1 config read and set support Runmode 2015-05-25 09:10:35 +08:00
astaxie
8cc57e2fc8 fix #1112 2015-05-25 09:10:35 +08:00
Yongzheng Lai
322b208566 Update session.go
remove = in if statement
2015-05-25 09:10:35 +08:00
Yongzheng Lai
fd610d6777 Update session.go
move expire in line 154 to 247, because it will cause session_cookie not writen to explorer
2015-05-25 09:10:35 +08:00
astaxie
1148359570 session cookie support IE 2015-05-25 09:10:35 +08:00
peeped
55b1d6a897 Update validators.go
edit mobile regular expression ; add 184 Section No.
2015-05-25 09:10:35 +08:00
astaxie
c4c9a50c42 fix #1081 2015-05-25 09:10:35 +08:00
Yongzheng Lai
a311d712a5 Update output.go 2015-05-25 09:10:35 +08:00
Yongzheng Lai
bb5351bb9f Update output.go
fix cookie not work in IE
2015-05-25 09:10:35 +08:00
astaxie
26130a5df6 fix #1073 2015-05-25 09:10:35 +08:00
pylemon
2c9363d29b add tests to ensure bool value require test always return true. 2015-05-25 09:10:35 +08:00
pylemon
91886a4547 bugfix: if a form field type is bool, valid Required should always return true instead of return its value. 2015-05-25 09:10:35 +08:00
Donal Byrne
a7e60c93dc Set ErrorsMap to nil in Validation.Clear function 2015-05-25 09:10:35 +08:00
toalexjin
5b1705b2d6 Do not check log level in writerMsg() because the check is already done outside. 2015-05-25 09:10:35 +08:00
Donal Byrne
34940d00c0 Remove unnecessary optional group flag '?' since has to match one of comma or end of string 2015-05-25 09:10:35 +08:00
Donal Byrne
1a6ea693b5 Added to input.go: AcceptHtml, AcceptsXml and AcceptsJson functions which check the header agains a regex for simpler mult-content-type handling. 2015-05-25 09:10:35 +08:00
toalexjin
2e51c124f1 For enhancing performance, check log level before fmt.Sprintf() 2015-05-25 09:10:35 +08:00
astaxie
1d8afdc9c9 gofmt -s & go_vet 2015-05-25 09:10:34 +08:00
supiyun
1592e9c04d 验证码reload问题
当页面放置一段时间,验证码将从缓存中失效。当用户再来刷新验证码将出现验证码404。对于reload操作应该直接生成验证码。
2015-05-25 09:10:34 +08:00
Hubery
bf6b0d3e1f add JsonBody 2015-05-25 09:10:34 +08:00
astaxie
af71289c25 Merge pull request #1171 from astaxie/add-license
add missed LICENSE of captcha
2015-05-25 09:09:21 +08:00
Liu Peng
b1efae6ff8 add missed LICENSE of captcha 2015-05-24 23:59:39 +08:00
astaxie
92f3de4027 update the string 2015-05-20 11:09:30 +08:00
astaxie
185089299c sync beeApp.Server to graceful 2015-05-20 11:07:23 +08:00
astaxie
59c1e74e13 Merge pull request #1158 from mlgd/master
Fix save config ini file
2015-05-18 22:38:59 +08:00
ziyel
9bb9855153 Let filter function get more params info from ctx.Input.Params 2015-05-18 14:42:18 +08:00
astaxie
519602a553 fix #1152 2015-05-15 15:04:08 +08:00
astaxie
740a526105 fix sesseion redis db error 2015-05-13 21:20:50 +08:00
astaxie
98289cd8de beego suppot graceful restart application 2015-05-13 21:17:47 +08:00
astaxie
56e2143630 add apk mime 2015-05-09 14:54:30 +08:00
astaxie
c0cfb5277c Merge pull request #1127 from vanthanh2305/RelatedSel-multi-string/relation
RelatedSel multi string/relation
2015-05-07 23:12:29 +08:00
astaxie
b29700c3c3 Merge pull request #1131 from JessonChan/develop
httplib more fixed
2015-05-07 22:59:41 +08:00
astaxie
47be2fadb5 fix #1143 2015-05-05 21:36:31 +08:00
mlgd
1d72629334 Fix save config ini file 2015-05-04 15:54:03 +02:00
astaxie
b4880c5e1d Merge pull request #1140 from cr7pt0gr4ph7/doc-pull-request
Improve documentation of filter.go.
2015-05-04 09:47:25 +08:00
cr7pt0gr4ph7
c0bb5b9237 Improve documentation of filter.go. 2015-05-03 23:21:32 +02:00
astaxie
1e1068e81c Merge pull request #1132 from dafang/master
Recursively validations
2015-04-28 11:53:45 +08:00
JessonChan
6c3e274b6e set default timeout 2015-04-26 16:10:18 +08:00
JessonChan
f56bdb6284 set default timeout 2015-04-26 16:08:25 +08:00
JessonChan
d8fa118727 more fixed 2015-04-26 15:42:10 +08:00
JessonChan
0afd04ec6f no need lock here 2015-04-26 15:24:04 +08:00
JessonChan
973306b28d no need defer here 2015-04-26 02:19:38 +08:00
JessonChan
da8c3c3910 zero timeout means wait until resp 2015-04-26 02:17:46 +08:00
JessonChan
0c1bb6409a typo fixed 2015-04-26 02:06:19 +08:00
JessonChan
cddb4fdb60 typo fixed 2015-04-26 02:05:50 +08:00
JessonChan
e1d20aea5d better code and fixed 2015-04-26 02:04:34 +08:00
JessonChan
4498a02c15 better go style 2015-04-26 01:23:18 +08:00
Wyatt Fang
5534258e22 remove useless comments 2015-04-24 11:17:12 +08:00
Wyatt Fang
73650e1f2b remove the double isStruct/isStructPtr check 2015-04-24 11:14:49 +08:00
Wyatt Fang
d0e7dd686b add Recursively validation 2015-04-24 10:58:46 +08:00
astaxie
dc58ec8316 remove unreached code 2015-04-19 15:40:23 +08:00
Trần Văn Thanh
6d72fc63ab fixed: when RelatedSel have multi string/relation, it only get last string 2015-04-15 17:41:41 +07:00
astaxie
dd4afac5dc Merge pull request #1125 from wuranbo/dev_track
*feature) add BeeLogger.GetLogFuncCallDepth make simple wrapper log method aviable.
2015-04-13 12:49:51 +08:00
wuranbo
e229a4762f *feature) 增加logcalldepth接口,使得能简单再次封装log系列函数。 2015-04-13 12:17:44 +08:00
astaxie
ecb27f34e6 no output the dump 2015-04-09 00:18:02 +08:00
astaxie
d55997e520 fix the init struct 2015-04-09 00:12:41 +08:00
astaxie
44c8534477 fix the dump has no body 2015-04-09 00:11:25 +08:00
astaxie
44a39a6b3e fix the params 2015-04-08 23:00:08 +08:00
astaxie
cc5ca458ab add DumpRequest 2015-04-08 22:58:37 +08:00
astaxie
6f6b412709 httplib support gzip 2015-04-08 21:45:00 +08:00
astaxie
642a69de02 add sethost 2015-04-08 20:12:10 +08:00
astaxie
466f3c49c1 Merge pull request #1120 from peeped/develop
Update validators.go
2015-04-07 18:48:44 +08:00
peeped
d1c9cb2281 Update validators.go
//176 中国联通
//177 中国电信
//145 中国联通
//147 中国移动
//149 中国电信
2015-04-07 17:48:51 +08:00
astaxie
9c9ffa202a Merge pull request #1119 from lionel0806/develop
fix a comment error.
2015-04-07 11:12:54 +08:00
Lionel Lee
56dfe418dd fix a comment error. 2015-04-07 10:35:18 +08:00
astaxie
7caeb91f9b improve the defaultval 2015-04-05 23:23:35 +08:00
astaxie
47848fa77b config read and set support Runmode 2015-04-05 23:21:13 +08:00
astaxie
e0e8b98622 fix #1112 2015-04-05 23:12:29 +08:00
astaxie
5c84ada389 Merge pull request #1106 from peeped/develop
Update validators.go
2015-04-04 20:46:43 +08:00
astaxie
ac6203b81b Merge pull request #1114 from ElvizLai/patch-2
Patch 2
2015-04-04 13:03:44 +08:00
Yongzheng Lai
5e1e618d0f Update session.go
remove = in if statement
2015-04-04 00:44:22 +08:00
Yongzheng Lai
a5124a1d45 Update session.go
move expire in line 154 to 247, because it will cause session_cookie not writen to explorer
2015-04-03 17:41:09 +08:00
astaxie
e675594e46 session cookie support IE 2015-04-02 14:02:39 +08:00
astaxie
d02e32fa51 Merge pull request #1103 from ElvizLai/patch-1
Update output.go
2015-04-02 13:35:08 +08:00
peeped
8a82e25e85 Update validators.go
edit mobile regular expression ; add 184 Section No.
2015-04-02 12:07:12 +08:00
astaxie
49c0f8906f fix #1081 2015-04-01 23:31:40 +08:00
Yongzheng Lai
9261c80509 Update output.go 2015-03-31 12:36:39 +08:00
Yongzheng Lai
217e24815b Update output.go
fix cookie not work in IE
2015-03-31 12:30:47 +08:00
astaxie
840fd3b64f Merge pull request #1083 from supiyun/patch-1
验证码reload问题
2015-03-30 21:40:57 +08:00
astaxie
eedaea2fea fix #1073 2015-03-30 20:35:57 +08:00
astaxie
a002f78443 Merge pull request #1097 from pylemon/develop
form required validate for bool field bugfix
2015-03-27 23:04:07 +08:00
astaxie
cdf9ff401f Merge pull request #1096 from byrnedo/develop
Set ErrorsMap to nil in Validation.Clear function
2015-03-27 14:46:45 +08:00
pylemon
caa260f053 add tests to ensure bool value require test always return true. 2015-03-27 13:43:20 +08:00
pylemon
5fa55ca2d3 bugfix: if a form field type is bool, valid Required should always return true instead of return its value. 2015-03-27 13:30:59 +08:00
Donal Byrne
260b5b1951 Set ErrorsMap to nil in Validation.Clear function 2015-03-26 20:23:00 +01:00
astaxie
54ae4bc25b Merge pull request #1094 from toalexjin/check_log_level
For enhancing performance, check log level before fmt.Sprintf()
2015-03-26 21:51:23 +08:00
astaxie
162bee1b43 Merge pull request #1095 from byrnedo/develop
Added AcceptHtml/Json/Xml function to input
2015-03-26 21:50:41 +08:00
Donal Byrne
533b00ae56 Merge branch 'master' into develop 2015-03-26 08:40:28 +01:00
toalexjin
d3cdebbee2 Do not check log level in writerMsg() because the check is already done outside. 2015-03-26 14:40:12 +08:00
Donal Byrne
06b5c7f644 Remove unnecessary optional group flag '?' since has to match one of comma or end of string 2015-03-25 14:54:39 +01:00
Donal Byrne
185ee872c4 Added to input.go: AcceptHtml, AcceptsXml and AcceptsJson functions which check the header agains a regex for simpler mult-content-type handling. 2015-03-25 14:47:20 +01:00
toalexjin
74e0af4a9a For enhancing performance, check log level before fmt.Sprintf() 2015-03-25 15:14:57 +08:00
astaxie
8aa9455900 gofmt -s & go_vet 2015-03-19 22:29:01 -07:00
supiyun
2d26f7df2f 验证码reload问题
当页面放置一段时间,验证码将从缓存中失效。当用户再来刷新验证码将出现验证码404。对于reload操作应该直接生成验证码。
2015-03-16 17:40:55 +08:00
astaxie
3d6408cfc2 Merge pull request #1070 from fugr/patch-5
add JsonBody
2015-03-13 23:16:18 +08:00
Hubery
223f57bb4c add JsonBody 2015-03-06 14:12:24 +08:00
astaxie
c4aa33fb1b Merge pull request #1052 from dockercn/develop
Fix the wrong parameter bug in ledis session support cause build failure
2015-03-01 13:58:21 +08:00
Meaglith Ma
20cc5b261e Reform the ledis_session.go 2015-03-01 12:59:34 +08:00
Meaglith Ma
7ec2a077d9 Fix the wrong parameter bug in ledis session. 2015-03-01 12:03:03 +08:00
Meaglith Ma
9f70561f21 Merge remote-tracking branch 'upstream/master' into develop 2015-03-01 11:47:02 +08:00
astaxie
1c9898dee5 Merge branch 'develop' 2015-02-27 22:52:42 +08:00
astaxie
2cf7c6a58a change the jQuery URL 2015-02-27 22:51:20 +08:00
astaxie
2cee46ab2b change the jQuery URL 2015-02-27 22:50:25 +08:00
astaxie
020bfbcc9c Merge branch 'develop' 2015-02-27 22:47:59 +08:00
astaxie
3f8252bffd change the version from 1.4.2 to 1.4.3 2015-02-27 22:47:21 +08:00
astaxie
6d313aa15f fix #985 2015-02-27 22:37:41 +08:00
astaxie
2a4e2d4a71 delete the group route, because we already has namespace 2015-02-27 22:37:07 +08:00
astaxie
f96a6285bf fix #978 2015-02-27 22:21:58 +08:00
astaxie
e938876c4a fix the cycle import 2015-02-27 00:12:10 +08:00
astaxie
6e9d2dc965 add more error functions 2015-02-26 23:49:24 +08:00
astaxie
3aceaf8838 error support controller 2015-02-26 23:34:43 +08:00
astaxie
71b9854f48 Merge pull request #1044 from fuxiaohei/develop
code style simplify
2015-02-23 22:25:34 +08:00
astaxie
f59ccd3a35 Merge pull request #1043 from Hepri/develop
Added support to parse slices of ints and strings in ParseForm func
2015-02-23 21:58:32 +08:00
fuxiaohei
181a7c35fe code simplify for package middleware 2015-02-23 11:50:45 +08:00
fuxiaohei
2ed272aeb2 code simplify for package middleware 2015-02-23 11:50:13 +08:00
fuxiaohei
77c1109134 code simplify for package logs 2015-02-23 11:42:46 +08:00
fuxiaohei
29d4823866 code simplify for package httplib 2015-02-23 11:30:59 +08:00
fuxiaohei
24cf06d288 code style simplify for context package 2015-02-23 11:15:55 +08:00
Sergey Shcherbina
0c31c2d689 Added support to parse slices of ints and strings in ParseForm func 2015-02-22 22:13:06 +05:00
astaxie
f988f035e5 redis provider for session and cache support select db 2015-02-16 21:56:32 +08:00
astaxie
1b4158c15b Merge pull request #1039 from astaxie/revert-1000-group_by_queryseter
Revert "Add GroupBy to QuerySeter"
2015-02-14 20:40:52 +08:00
astaxie
433e8f2ce3 Revert "Add GroupBy to QuerySeter" 2015-02-14 20:40:43 +08:00
astaxie
22ba7fdce4 Merge pull request #1000 from pdf/group_by_queryseter
Add GroupBy to QuerySeter
2015-02-14 20:33:06 +08:00
astaxie
2a0f87e810 Merge pull request #1010 from BlackLee/master
add compare_not/not_nil methods for template
2015-02-14 20:31:18 +08:00
astaxie
19db4b67f6 Merge pull request #1025 from kongjian/develop
Update task tpl
2015-02-14 20:29:28 +08:00
空见
b1baf4503d beego task list update for task spec list and task run url error 2015-02-04 18:07:31 +08:00
astaxie
d536f5b8dc Merge pull request #1021 from kmulvey/readme-typo
typos in the readme
2015-02-03 09:07:00 +08:00
Kevin Mulvey
1cc1d57f55 development 2015-02-02 09:33:59 -05:00
Kevin Mulvey
73370ade90 modular 2015-02-02 09:33:27 -05:00
astaxie
0d3b7dcd07 Merge pull request #911 from supar/add-column-default-attribute
Add attribute default to the column on create or alter commands. Skip co...
2015-01-16 10:40:11 -08:00
astaxie
d7fe5ef435 Merge pull request #1004 from fugr/patch-2
Transaction
2015-01-13 11:19:03 -08:00
Hubery
8bd902814f Transaction
err处理写反了
2015-01-13 11:09:43 +08:00
astaxie
378356a65e Merge pull request #1001 from johndeng/develop
Fixed the status code issue at error handler.
2015-01-12 09:54:26 -08:00
John
30871e2617 Fixed the status issue at error handler. 2015-01-10 17:35:35 +08:00
Peter Fern
3731088b4a Add GroupBy to QuerySeter
Adds support for GroupBy to QuerySeter SELECT operations.
2015-01-10 15:26:41 +11:00
astaxie
d46833c6d8 Merge pull request #997 from dockercn/master
增加session模块中的ledisdb的动态配置
2015-01-09 13:58:13 +08:00
Black.Lee
18659e16ba add compare_not/not_nil methods for template 2015-01-05 16:38:57 +08:00
astaxie
5d8187d005 Merge pull request #977 from athurg/patch-1
Fix RequestURI nil caused template parse failed
2014-12-25 11:40:26 +08:00
Athurg Gooth
d961ae4cd8 Fix RequestURI nil caused template parse failed
Sometime RequestURI is not set, e.g. running after a front proxy server.

We should always follow the document's directive, to use Request.URL instead of RequestURI.

Refer: http://golang.org/pkg/net/http/#Request
2014-12-25 11:23:04 +08:00
astaxie
0e1a0049d1 Merge pull request #971 from athurg/get_request_params_with_default
Support default value for controller’s params get
2014-12-19 16:03:10 +08:00
astaxie
0c933643e2 improve the empty router 2014-12-19 15:33:51 +08:00
Jianbo Feng
d2c5daa5ee Update comments for controller's GetXXX functions 2014-12-19 15:28:18 +08:00
astaxie
d3ab157915 fix the cache test 2014-12-19 14:40:16 +08:00
astaxie
75d28d49c5 Merge pull request #965 from shuoli84/develop
Fix subdomain, add test, space and comment fix
2014-12-19 13:22:36 +08:00
astaxie
76bb4827d0 Merge pull request #953 from kristen1980/patch-2
Allow absolute path for filesystem cache
2014-12-18 21:24:17 +08:00
astaxie
3caba06189 Merge pull request #967 from athurg/support_all_type_on_urlfor
Add all type support for UrlFor’s params
2014-12-18 21:14:44 +08:00
shuo li
572508ddd8 Clean json config. Fix DefaultStrings 2014-12-17 17:02:46 +08:00
Jianbo Feng
e34f8479bb Add all type support for UrlFor’s params 2014-12-17 15:52:48 +08:00
Jianbo Feng
daf85f06f8 Support default value for controller’s params get 2014-12-17 15:23:11 +08:00
shuo li
22671c524e Fix subdomain, add test, space and comment fix 2014-12-17 12:06:53 +08:00
astaxie
ab99d5f1e2 Merge pull request #957 from athurg/patch-2
Fix paginator attributes cannot be modified bug
2014-12-11 19:59:50 +08:00
Athurg Gooth
c52f634d9c Fix paginator attributes cannot be modified bug
We can only use SetPaginator to create a pagination.

After that, we always need to modify something, like the totalNum, perPageNum.

These change should be seen in the view.

So we should give the view a pointer than a object.
2014-12-11 16:42:50 +08:00
astaxie
9c665afc04 improve the error tips 2014-12-08 14:57:45 +08:00
kristen1980
77ed151243 Allow absolute path for filesystem cache
Gives more flexibility by making it an absolute path. A relative path can easily be created by the user.
2014-12-07 10:00:35 -07:00
Chen Liang
29d98731c6 add sess_ledis select db config 2014-11-25 14:41:51 -08:00
Chen Liang
934dd2e8d2 Merge branch 'master' of https://github.com/astaxie/beego 2014-11-25 14:27:13 -08:00
astaxie
e65d87974a Merge pull request #940 from hilyjiang/develop
make Content-Type header more human-readable
2014-11-24 23:26:15 +08:00
Lei Cao
647e6ae1c4 Added JWT plugin 2014-11-24 23:21:03 +08:00
Hily Jiang
db04c3cbb4 make Content-Type header more human-readable 2014-11-24 23:12:09 +08:00
astaxie
802aa16136 Merge pull request #935 from mnhkahn/master
beego1.4.2,beego.AppConfig.Strings与老版本代码不兼容问题
2014-11-24 21:47:12 +08:00
astaxie
f2df07f630 Merge pull request #933 from rbastic/develop
Reword message about reloading packages..
2014-11-24 13:18:05 +08:00
Ryan Bastic
dc89f844f3 Reword message about reloading packages.. 2014-11-23 18:22:45 +01:00
astaxie
b80cdef20f Merge pull request #932 from DeanThompson/master
count log file lines
2014-11-23 23:57:27 +08:00
astaxie
98dcee0643 Merge pull request #926 from xuewuhen/master
SubDomains function bugfixed
2014-11-23 22:57:40 +08:00
astaxie
0ad75cb5fa Merge pull request #928 from lei-cao/develop
Return the response directly if it's a options PreflightHeader request
2014-11-21 23:22:59 +08:00
DeanThompson
6a9d04c269 count log file lines 2014-11-21 18:12:39 +08:00
Lei Cao
93ca11f83d Return the response directly if it's a options PreflightHeader request 2014-11-21 01:35:30 +08:00
git
d0b43ef4f5 beego.AppConfig.Strings bug 2014-11-20 16:35:04 +08:00
xuewuhen
c9bb9d6a09 SubDomains function bugfixed 2014-11-18 22:54:48 +08:00
astaxie
f96245786a fix #912 2014-11-08 15:10:47 +08:00
supar
1a1b0c14b9 Add attribute default to the column on create or alter commands. Skip columns which are keys and date or time data type 2014-11-06 17:43:53 +03:00
astaxie
07c628c7e9 fix the commentsRouter init sequence 2014-11-06 17:30:50 +08:00
astaxie
1e92d17605 fix the repeat commentsRouters 2014-11-06 16:25:47 +08:00
astaxie
bb795847da fix the not exist config file application 2014-11-06 11:12:00 +08:00
astaxie
54ba307f7f change this to short name 2014-11-05 22:40:31 +08:00
astaxie
950ff91d87 hotfix for parsefiel 2014-11-05 22:23:54 +08:00
astaxie
b43401b9f6 Merge pull request #907 from astaxie/develop
1.4.1 released
2014-11-04 22:39:03 +08:00
astaxie
fe50269b3f change 1.4.1 to 1.4.2 2014-11-04 22:38:40 +08:00
astaxie
000033e2a7 update the test case 2014-11-04 22:07:38 +08:00
astaxie
15242d89ce simple the session init 2014-11-04 19:08:06 +08:00
astaxie
76522d43af simple the session 2014-11-04 19:07:49 +08:00
astaxie
52df1234bd Merge branch 'develop' of https://github.com/astaxie/beego into develop 2014-11-04 19:04:43 +08:00
astaxie
fc6b9ce009 fix #620 simple the sessionID generate 2014-11-04 19:04:26 +08:00
astaxie
b9fdd67519 add test case fot date & stringbool 2014-11-04 16:39:17 +08:00
astaxie
7743eecfd4 support #761
type Test struct {
    Date    time.Time    `form:"Date, 2006-01-02"`
    Save    bool            `form:"Save"`
}
2014-11-04 16:19:46 +08:00
astaxie
c4d8e4a244 fix #759 2014-11-04 15:29:33 +08:00
astaxie
9d4ec508bb parse for github.com replace the . to _ 2014-11-04 10:19:30 +08:00
astaxie
8b747f54bc fix #770 2014-11-03 23:33:11 +08:00
astaxie
a2428af8a7 compatibility for warn & info function add one more depth 2014-11-03 16:48:45 +08:00
astaxie
90a7ce5c6a split the file for logs 2014-11-03 16:45:42 +08:00
astaxie
ef3c7c127b fix the variable 2014-11-03 16:44:05 +08:00
astaxie
88caf1ed70 if read the log.go then calldepth add 1 2014-11-03 16:43:07 +08:00
astaxie
304beaf89f update the log call deep 2014-11-03 16:40:08 +08:00
astaxie
2288ac868c remove the deep Caller 2014-11-03 16:34:36 +08:00
astaxie
8d797a4a5e file the static filter 2014-11-03 16:14:40 +08:00
astaxie
10db97b193 add some tips for the admin server start 2014-11-03 15:08:51 +08:00
astaxie
716962672f fix #751
add config ListenTCP4

when user want to listen on the TCP4, because now almost use the ipv4.
but default lister on the ipv6
2014-11-03 15:06:25 +08:00
astaxie
90cff5f042 fix #824 2014-11-02 21:01:51 +08:00
astaxie
da127bbc22 fix #855 #859 2014-10-31 16:31:23 +08:00
astaxie
945b1da3a8 fix the gofmt 2014-10-31 15:48:57 +08:00
astaxie
94c84b846f fix the init logger 2014-10-31 09:02:16 +08:00
astaxie
db43892fe6 improve the Put #896 2014-10-31 00:28:51 +08:00
astaxie
71149218d1 fix the log level 2014-10-30 17:43:32 +08:00
astaxie
1636a7271c Revert "fix the log test"
This reverts commit ddbfc25e56.
2014-10-30 16:57:55 +08:00
astaxie
68c3bdfdd4 Revert "logs:default support fileline"
This reverts commit 1f26852610.
2014-10-30 16:57:48 +08:00
astaxie
ecd0a5487e fix the import cycle not allowed 2014-10-30 16:12:54 +08:00
astaxie
fda841208d fix #893 2014-10-30 16:05:48 +08:00
astaxie
57e62e5e57 update the file upload to io.Pipe 2014-10-30 11:16:09 +08:00
astaxie
824e3f8f5b fix the only file upload param 2014-10-29 16:00:08 +08:00
astaxie
1822dd95ac Merge pull request #892 from dockercn/master
Add a beego session backend using LedisDB
2014-10-29 14:18:20 +08:00
astaxie
ddbfc25e56 fix the log test 2014-10-28 19:34:11 +08:00
astaxie
1f26852610 logs:default support fileline 2014-10-28 19:33:14 +08:00
Meaglith Ma
0188fb3711 Merge pull request #1 from chliang2030598/master
add session store in ledis
2014-10-27 06:02:19 +00:00
Chen Liang
0bcd828d73 add session store in ledis 2014-10-26 22:56:00 -07:00
astaxie
e11a27f1d1 Merge pull request #888 from astaxie/revert-887-add-column-default-attribute
Revert "Add column default attribute"
2014-10-26 10:41:34 +08:00
astaxie
90caeb4cf7 Revert "Add column default attribute" 2014-10-26 10:41:22 +08:00
astaxie
6c9249034d Merge pull request #887 from supar/add-column-default-attribute
Add column default attribute
2014-10-26 10:28:56 +08:00
astaxie
14114018ea config ini support include 2014-10-24 19:03:27 +08:00
supar
6f5162461e Add column DEFAULT attribute. Do not add if field is key or in
relations.
2014-10-24 14:51:35 +04:00
supar
c34c514bba Skip add DEFAULT if the field is in relations (rel or reverse) 2014-10-24 14:37:46 +04:00
astaxie
8ac2b9bf66 Merge branch 'master' into develop 2014-10-24 15:10:11 +08:00
astaxie
2a85c79ce5 Merge pull request #881 from astaxie/revert-870-add-column-default-attribute
Revert "Add column default attribute"
2014-10-24 14:58:27 +08:00
astaxie
767083bd56 Revert "Add column default attribute" 2014-10-24 14:58:17 +08:00
astaxie
1a79513293 Merge branch 'master' into develop 2014-10-24 14:50:53 +08:00
astaxie
c6cb1f92e8 Merge pull request #870 from supar/add-column-default-attribute
Add column default attribute
2014-10-24 14:49:53 +08:00
astaxie
9c0aad06c5 Merge pull request #880 from chenghuama/patch-3
Update ini.go
2014-10-24 14:15:49 +08:00
chenghua
180c6aafac Update ini.go
支持BOM格式的ini文件
2014-10-24 13:45:00 +08:00
astaxie
710f5b6234 fix the test fun for pull request 873 2014-10-20 22:23:29 +08:00
astaxie
dbf944adce Merge pull request #873 from WithGJR/develop
add new feature to 'renderform' function, user could add HTML id and class now
2014-10-20 22:03:52 +08:00
WithGJR
6c9ff81fc1 fix: if user didn't set id or class, then it won't be displayed in HTML code 2014-10-20 18:59:46 +08:00
astaxie
ec6383c07d Merge pull request #858 from bsingr/develop
Allow to use fastcgi via standard io.
2014-10-20 18:30:10 +08:00
astaxie
76db5cded4 fix the init mime 2014-10-20 18:21:17 +08:00
WithGJR
1b3e7de463 add new feature to 'renderform' function, user could add HTML id and class now 2014-10-20 17:49:16 +08:00
supar
ab28edaf25 Fix comma in the switch, fix wronf function name 2014-10-17 13:02:18 +04:00
supar
04431a7a15 Fix function name fmt.Stprintf -> fmt.Sprintf 2014-10-17 12:59:24 +04:00
supar
b00c42b3df Fix undefind variable fieldType 2014-10-17 12:56:44 +04:00
supar
4cae7af3f9 Add attribute DEFAULT '' to the CREAT, ALTER constructors 2014-10-17 12:53:59 +04:00
supar
e4988b714e Add property colDefault to fieldInfo object, set its true if there is
orm configuration default `orm:"default(1)"`
2014-10-17 12:27:53 +04:00
astaxie
24489df63d Merge pull request #867 from WithGJR/develop
fix router bug: when the request is PUT or DELETE, router can't find the...
2014-10-16 23:07:20 +08:00
astaxie
fb8e9ae1a3 Merge pull request #868 from reterVision/patch-2
Use SETEX command to set session
2014-10-16 21:42:23 +08:00
Brandon Gao
1eb9aef687 Use SETEX command to set session
In order to be compatible with older version Redis, use `SETEX` command instead of `SET x y EX 360`.
2014-10-16 20:16:17 +08:00
WithGJR
efc14a1e8d fix router bug with more better way 2014-10-16 18:58:12 +08:00
WithGJR
fa1281002e fix router bug: when the request is PUT or DELETE, router can't find the actual route and will throw 404 page to user 2014-10-16 18:26:01 +08:00
Jens Bissinger
812950b60d Allow to use fastcgi via standard io. 2014-10-13 13:47:44 +02:00
astaxie
f9e991b538 Merge pull request #853 from tossp/email
支持发送邮件内嵌附件
2014-10-12 11:02:53 +08:00
TossPig
fc07419938 Update mail.go 2014-10-11 00:42:01 +08:00
TossPig
d69eee23f0 添加错误返回
不知道英文区的人能否看懂Cnglish。。。
2014-10-11 00:38:31 +08:00
TossPig
41de7c7db6 fix
修改一个错误。
看到text/template包的写法,和你的想法是一致的。
2014-10-11 00:02:36 +08:00
TossPig
6a33647f30 修改参数类型
为了保持向后兼容,
2014-10-10 23:40:02 +08:00
TossPig
e5134873be 支持发送邮件内嵌附件
为*Email.AttachFile和Email.Attach增加了一个参数"id".
当id不为空时,设置头部信息Content-Disposition为inline,并添加Content-ID头的值为id
2014-10-10 14:40:07 +08:00
astaxie
8d20ea04b0 Merge pull request #852 from pabdavis/statistics-json
[Proposal] Ability to get statistics data unformatted
2014-10-10 10:59:30 +08:00
Bill Davis
5c1e8e42b9 Reworked implementation to not return encoded json 2014-10-09 17:07:28 -04:00
Bill Davis
ca3e7568a1 Add ability to get statistics in json format 2014-10-09 16:32:56 -04:00
astaxie
2823167848 Merge pull request #849 from pabdavis/runmode-env
Support run mode set by environment variable
2014-10-10 00:50:16 +08:00
Bill Davis
a27f5c0dc0 Remove dependency of third party lib 2014-10-09 09:17:10 -04:00
astaxie
8af0475251 fix #833 2014-10-09 18:47:22 +08:00
astaxie
9c07332cfc Update README.md 2014-10-09 09:34:22 +08:00
Bill Davis
a06e0f27ad Support run mode set by env var BEEGO_RUNMODE 2014-10-08 15:00:07 -04:00
astaxie
a760e46f98 Merge pull request #837 from bsingr/develop
Insert pagination utilities from beego/wetalk. Refs #835.
2014-10-08 23:00:46 +08:00
Jens Bissinger
262665f4e5 Remove PaginationController interface and pass context instead. Refs #835. 2014-10-08 16:01:42 +02:00
Jens Bissinger
0b3763cc67 Cleanup pagination documentation. Refs #835. 2014-10-08 16:00:00 +02:00
astaxie
c147f26cd1 Merge pull request #847 from pabdavis/multifilter-fix2
Changes to handle multi filters on execution pt
2014-10-08 21:24:28 +08:00
Bill Davis
1ba7847913 Changing check from nil to len based on slice 2014-10-08 09:21:34 -04:00
astaxie
52df979aca update the godocs 2014-10-08 14:02:57 +08:00
Bill Davis
b6f789c497 Changes to handle multi filters on execution pt 2014-10-07 16:35:30 -04:00
Jens Bissinger
fa6cbc08d9 Document usage of utils/pagination. Refs #835. 2014-10-07 11:23:08 +02:00
Jens Bissinger
c4f8f45da4 Move pagination to utils/pagination. Refs #837, #835. 2014-10-06 11:37:08 +02:00
Jens Bissinger
6fca4a8218 Insert pagination utilities from beego/wetalk. Refs #835. 2014-10-02 11:40:46 +02:00
astaxie
aae89576c6 fix #814 2014-10-01 22:31:44 +08:00
astaxie
a907a86476 fix #814 2014-10-01 22:28:49 +08:00
astaxie
8716185de8 fix #794 2014-10-01 22:10:33 +08:00
astaxie
31e6133413 beego: improve static file index.html simple code 2014-10-01 08:57:10 +08:00
astaxie
3a5de83ec2 beego: support router case sensitive 2014-09-28 22:10:43 +08:00
astaxie
f5f3395560 update the isdir 2014-09-24 14:48:08 +08:00
astaxie
8164367762 beego: flash add success & Set 2014-09-23 23:54:38 +08:00
astaxie
e1475b72b9 Merge pull request #826 from SnailKnows/patch-2
Update beego.go
2014-09-23 00:31:21 +08:00
astaxie
f267ee8a12 fix the same name controller for UrlFor 2014-09-23 00:26:07 +08:00
astaxie
7e060e6e5c fix the static file dir 2014-09-23 00:03:47 +08:00
astaxie
727d2f9ea1 fix not found when has mulit static dir
robot &robots
2014-09-22 23:44:50 +08:00
SnailKnows
67c0c232a1 Update beego.go 2014-09-20 18:56:46 +08:00
astaxie
6c62198b59 remove the go style 2014-09-15 23:01:12 +08:00
astaxie
e48e1ddaa9 Merge pull request #812 from ZhengYang/develop
More SQL keywords added and code cleanup
2014-09-11 20:48:18 +08:00
ZhengYang
1f9281c830 minor code refactor 2014-09-11 15:17:48 +08:00
ZhengYang
ccab9a7044 add more sql keywords 2014-09-11 13:48:39 +08:00
astaxie
9013f5c6c7 Merge pull request #808 from ZhengYang/develop
more complete support for sql language
2014-09-09 14:21:49 +08:00
Zheng Yang
29b7ff84e1 more complete support for sql language 2014-09-09 14:17:12 +08:00
astaxie
fb0cc55822 update the orm read me 2014-09-09 11:55:28 +08:00
astaxie
0820e21738 Merge pull request #804 from ZhengYang/develop
QueryBuilder for building SQL queries quickly
2014-09-08 19:24:39 +08:00
Zheng Yang
38eb29fa7b err msg spell correction 2014-09-08 18:41:42 +08:00
Zheng Yang
cca0a3f76d name correction: QueryBuilder instead of QueryWriter 2014-09-08 18:31:32 +08:00
Zheng Yang
f9a9b5a905 new query builder based on driver 2014-09-08 17:56:55 +08:00
Zheng Yang
c667895ce5 added new querybuilder 2014-09-08 17:47:15 +08:00
Zheng Yang
b2cdabb8a0 added query builder for orm 2014-09-08 17:37:01 +08:00
astaxie
647a47517d httplib: fix the header function for User-Agent 2014-09-05 23:21:41 +08:00
astaxie
f7cd1479ba beego: improve the log debug for running server 2014-09-05 17:04:02 +08:00
astaxie
fcc359af11 beego: fix the Upper for the _method value 2014-09-04 22:13:03 +08:00
astaxie
08b3e4191e Merge branch 'master' into develop 2014-09-04 21:58:45 +08:00
astaxie
4f4f7ce257 beego: fix the router for *.* with other regexp 2014-09-04 21:58:17 +08:00
astaxie
d06e02474f Merge pull request #795 from mvpmvh/context_params
Context params
2014-09-04 09:11:35 +08:00
Michael Hatch
4d65330ca1 changing my package namespace to astaxie 2014-09-03 19:47:09 -05:00
astaxie
2dfe1fc61c Merge pull request #792 from haowang1013/develop
fixed uninitialized return error if StartAndGC fails
2014-09-03 23:21:17 +08:00
Wang Hao
29b60d6058 fixed uninitialized return error if StartAndGC fails 2014-09-03 22:43:06 +08:00
astaxie
6eee223352 beego: fix the Upper for the _method value 2014-09-03 09:25:34 +08:00
astaxie
0692f92890 Merge branch 'develop' of https://github.com/astaxie/beego into develop 2014-09-02 14:42:02 +08:00
astaxie
41adcf9966 change the version 1.4.0 to 1.4.1 2014-09-02 14:41:14 +08:00
astaxie
e6b42a4070 Merge pull request #787 from francoishill/patch-21
Proposal for adding a ":" for stack trace printout
2014-08-31 08:52:32 +08:00
Francois
bc4780091b Proposal for adding a ":" for stack trace printout
Mainly useful for Sublime users with goto anything.
2014-08-30 21:27:21 +02:00
astaxie
d8614e80e7 beego: update the Url to Path 2014-08-30 22:22:23 +08:00
astaxie
c83a2a0925 modify the comments 2014-08-28 10:21:32 +08:00
astaxie
50a21d60c1 apiauth add more comments & improve 2014-08-28 10:05:02 +08:00
astaxie
5a087b28d2 aws api auth plugins 2014-08-28 00:25:50 +08:00
astaxie
9b40271878 fix the less ` 2014-08-27 15:53:08 +08:00
astaxie
770dc702f0 Merge pull request #782 from francoishill/patch-19
Extra field if username is empty
2014-08-27 15:36:07 +08:00
astaxie
e146100a23 Merge pull request #783 from francoishill/patch-20
Typo in the printout of some level's prefixes
2014-08-27 15:35:31 +08:00
Francois
2d94f7797b Type in the printout of each level's prefix 2014-08-26 14:03:03 +02:00
Francois
61ce608847 Update smtp.go 2014-08-26 12:47:05 +02:00
astaxie
2fe559701c fix the import 2014-08-26 15:43:18 +08:00
astaxie
37fe175c26 Merge pull request #776 from devYu/master
udpate ini.go
2014-08-26 14:43:20 +08:00
astaxie
fcc9d8c45f Merge pull request #778 from francoishill/patch-15
Update file.go
2014-08-26 14:42:52 +08:00
astaxie
e51a9d6481 Merge pull request #779 from francoishill/patch-17
Print error if occurred in WriteMsg
2014-08-26 14:42:05 +08:00
astaxie
e9a1daa3ee Merge pull request #780 from francoishill/patch-18
Allow mail with self-signed certificates
2014-08-26 14:41:36 +08:00
Francois
44ea260db1 Allow mail with self-signed certificates
For more information, refer to https://groups.google.com/forum/#!topic/golang-nuts/c9zEiH6ixyw
2014-08-26 06:52:18 +02:00
Francois
1d1ad69954 Print error if occurred in WriteMsg 2014-08-26 06:37:35 +02:00
Francois
59773dfabe Update file.go
New pull request for "Panic sometimes occurs at time 00h00 on windows, then the app crashes."
2014-08-26 06:25:59 +02:00
xianyu
ccb61f0416 gofmt
Signed-off-by: devYu <devysq@gmail.com>
2014-08-25 21:31:53 +08:00
老虞
14629c214b 优化GetData
1. 去掉重复的ToLower
2. getData内部统一ToLower
3.调整getData中对空字符串判断位置
====
4. 待确定:在getData中是否有必要进行lock操作
2014-08-25 20:14:14 +08:00
astaxie
a3888cef7f fix the comments for the \d 2014-08-25 19:48:02 +08:00
astaxie
f6a1a6c9bf Merge pull request #773 from lei-cao/develop
Added data table admin ui
2014-08-25 07:32:07 +08:00
Lei Cao
38ee43701d remove http: 2014-08-25 01:40:23 +08:00
Lei Cao
421b796f1a Added data table admin ui 2014-08-25 01:37:11 +08:00
Michael Hatch
db51ddab96 GetInt(), GetInt8(), GetInt16(), GetInt32(), GetInt64() and Example tests 2014-08-23 20:24:29 -05:00
Michael Hatch
baf2c63d5c Merge branch 'astaxie-master' 2014-08-23 10:09:37 -05:00
astaxie
771179a3c6 Merge pull request #769 from JessonChan/develop
improve and typo fixed
2014-08-23 09:46:43 +08:00
JessonChan
c07b1d881b typo fixed 2014-08-23 07:07:12 +08:00
JessonChan
d8f2b05e08 improve the code and delete NO NEED URL CHECK 2014-08-23 07:02:47 +08:00
JessonChan
7b2fe824d5 typo fixed 2014-08-23 06:48:40 +08:00
JessonChan
02301caac1 modify desc 2014-08-23 06:47:42 +08:00
astaxie
98c2307763 Merge pull request #767 from JessonChan/develop
bug fixed
2014-08-22 22:02:40 +08:00
JessonChan
485c2e865c bug fixed 2014-08-22 17:43:05 +08:00
JessonChan
b390667374 Merge remote-tracking branch 'upstream/develop' into develop
Conflicts:
	httplib/httplib.go
2014-08-22 17:39:57 +08:00
jessonchan
f684de2385 fixed bug-request dump too early 2014-08-22 17:12:46 +08:00
astaxie
35b4022ee0 httplib: set the default proto 2014-08-22 17:03:56 +08:00
astaxie
77294a5881 utils: fix the SliceIntersect 2014-08-22 16:50:07 +08:00
jessonchan
7b39bd7042 refactor 2014-08-22 16:43:42 +08:00
astaxie
01e4084587 toolbox: fix the go routine asleep 2014-08-22 13:56:36 +08:00
astaxie
bf429a3a20 Merge pull request #762 from pdf/pointer_field_support
Add support for basic type pointer fields
2014-08-22 13:41:58 +08:00
astaxie
f8ff79d77d Merge pull request #764 from smallfish/master
Update README
2014-08-22 13:41:01 +08:00
陈小玉
e9487d3571 Update README 2014-08-22 13:32:54 +08:00
Peter Fern
d7c3727f96 Add support for basic type pointer fields
Allows models like:

```
type User struct {
	Id    int64
	Name  string
	Email *string `orm:"null"`
}
```

This helps a lot when doing JSON marshalling/unmarshalling.

Pointer fields should always be declared with the NULL orm tag for sanity, this
probably requires documentation.
2014-08-22 14:25:32 +10:00
astaxie
03eb1fc104 toolbox: add notify when add & delete task 2014-08-21 15:56:41 +08:00
astaxie
0a967875da Merge pull request #757 from smallfish/develop
Add new function SetBasicAuth, and update README
2014-08-21 09:01:45 +08:00
陈小玉
6ae8bc1a16 Update README 2014-08-21 00:08:08 +08:00
陈小玉
e70537f8b3 Update README 2014-08-21 00:03:03 +08:00
smallfish
9a583323a8 Add SetBasicAuth function for HTTP Auth 2014-08-20 23:36:58 +08:00
astaxie
ff9c8d94e6 Merge pull request #753 from smallfish/develop
format comments
2014-08-20 16:40:26 +08:00
astaxie
7f977a0c8c beego: change the colour 2014-08-20 11:54:25 +08:00
astaxie
aaabeff44f change the route info 2014-08-20 10:59:38 +08:00
smallfish
f85ac088c3 format comments 2014-08-19 16:48:30 +08:00
astaxie
26da23266a Merge branch 'master' into develop 2014-08-19 09:49:07 +08:00
astaxie
80274684e0 context: redirect should writer to response instantly 2014-08-19 09:48:21 +08:00
astaxie
be005f9774 Merge pull request #750 from smallfish/develop
Update httplib support read data from response buffer, add some testcase...
2014-08-18 21:33:02 +08:00
smallfish
c16b7be9ac rollback the ToFile func implement, and add testcase 2014-08-18 21:29:45 +08:00
smallfish
de87529387 Update httplib support read data from response buffer, add some testcases 2014-08-18 21:01:49 +08:00
astaxie
c4fa17921e comments for godocs 2014-08-18 16:44:40 +08:00
astaxie
724137e605 Merge branch 'master' into develop 2014-08-18 16:42:16 +08:00
astaxie
a144769515 update the documents & comments 2014-08-18 16:41:43 +08:00
astaxie
05089be427 Merge pull request #749 from smallfish/master
rename SetAgent and ToXML, and update some testcase
2014-08-18 15:07:11 +08:00
smallfish
7668c54d05 update testcase for httplib 2014-08-18 15:03:34 +08:00
smallfish
86752a55b6 rename SetAgent and ToXML 2014-08-18 15:03:10 +08:00
astaxie
e07d780dcf update the router info 2014-08-18 15:00:27 +08:00
astaxie
e566322643 beego: change the version from 1.4.0 to 1.3.2 2014-08-18 14:46:43 +08:00
astaxie
51ee1e77c2 beego: close the file when finish init 2014-08-18 14:42:17 +08:00
astaxie
986e91b7d6 beego: update the debug info rules 2014-08-18 14:35:43 +08:00
astaxie
8b8638c507 Merge pull request #748 from smallfish/master
Remove some unnecessary code
2014-08-17 21:36:10 +08:00
smallfish
d27c5c8daf Remove some unnecessary code 2014-08-17 21:13:29 +08:00
astaxie
86121deac4 Merge pull request #747 from francoishill/patch-12
Another change to match with logs/log.go (and RFC 5424 specs)
2014-08-16 10:10:16 +08:00
astaxie
6b02e1e9d4 Merge pull request #746 from francoishill/patch-11
To match with logs/log.go (and RFC 5424 specs)
2014-08-16 10:09:32 +08:00
astaxie
83696d95c3 Merge pull request #745 from francoishill/patch-10
Makes more sense to Use Debug instead of Info?
2014-08-16 09:40:01 +08:00
Francois
7be8114616 To match with logs/log.go (and RFC 5424 specs) 2014-08-15 21:30:59 +02:00
Francois
1dbbb89ad1 To match with logs/log.go (and RFC 5424 specs) 2014-08-15 21:12:57 +02:00
Francois
75904effd9 Makes more sense to Use Debug instead of Info? 2014-08-15 21:11:16 +02:00
astaxie
cd9e614a71 plugins: basic auth & cors 2014-08-15 17:15:20 +08:00
astaxie
c1234e7c6d fix the responseWriter 2014-08-15 15:24:46 +08:00
astaxie
b611b9dab6 change the adminui link 2014-08-15 15:19:35 +08:00
astaxie
cad3da337a toolbox: fix the program name 2014-08-15 15:17:11 +08:00
astaxie
3969cd3b40 toolbox: improve the profile 2014-08-15 15:09:59 +08:00
astaxie
f4867aad5a Merge pull request #744 from lei-cao/develop
ajax refresh gc message
2014-08-15 14:46:37 +08:00
Lei Cao
17006cfb26 ajax refresh gc message 2014-08-15 14:24:55 +08:00
astaxie
7d1b03ee5d toolbox: fix the test case 2014-08-15 00:14:30 +08:00
astaxie
84a4379f0d Merge pull request #739 from lei-cao/develop
Added the UI for Admin monitor page
2014-08-14 23:57:09 +08:00
astaxie
ab71201c96 Merge pull request #741 from smallfish/master
Update ctx.WriteString multiple buf output
2014-08-14 23:56:20 +08:00
Lei Cao
c347dd9e7b Fix the comments and deleted the println 2014-08-14 23:50:15 +08:00
smallfish
75e2611cc4 Update ctx.WriteString multiple buf output 2014-08-14 21:37:52 +08:00
Lei Cao
d314d12c77 Added the UI for Admin monitor page 2014-08-14 17:35:23 +08:00
astaxie
564c3bbeb5 migration: update the debug error 2014-08-14 13:44:05 +08:00
astaxie
31f0ac4ce3 migration: update the params orders 2014-08-14 13:41:54 +08:00
astaxie
57a9670b0a migration: reset the up state sql 2014-08-14 13:37:48 +08:00
astaxie
14cd9e51ac revert the sort map for reset 2014-08-14 11:54:15 +08:00
astaxie
886bb782a5 sort the reset 2014-08-14 11:44:10 +08:00
astaxie
d2119f715c update the migrations 2014-08-14 11:39:59 +08:00
astaxie
f98b1810ab update the reset 2014-08-14 10:56:49 +08:00
astaxie
55a7711017 migration: skip reset 2014-08-14 10:19:55 +08:00
astaxie
436edda926 Merge branch 'master' into develop 2014-08-13 20:39:14 +08:00
astaxie
1f1190fbc3 Merge pull request #738 from smallfish/master
Add CustomAbort() for Controller, support status code and body
2014-08-13 20:16:36 +08:00
smallfish
20463fa725 Add CustomAbort() for Controller, support status code and body 2014-08-13 17:26:22 +08:00
astaxie
ae37f95239 migration: delete the unique key for name 2014-08-13 16:42:16 +08:00
astaxie
da6726f3da Merge pull request #737 from ZhengYang/develop
change time format for migration module
2014-08-13 16:37:13 +08:00
Zheng Yang
32469cd69d change time format 2014-08-13 16:09:13 +08:00
astaxie
e572f45296 update the error output 2014-08-13 14:50:32 +08:00
astaxie
efcaa3d934 update the migration database time format 2014-08-13 11:16:19 +08:00
astaxie
5ecfe0c335 beego hook change the path & fix the migration bug 2014-08-13 10:43:05 +08:00
astaxie
d325a66fee update the error info 2014-08-12 16:35:59 +08:00
astaxie
fe9017c819 update the description 2014-08-12 15:50:28 +08:00
astaxie
b97279a74f update the migration 2014-08-12 15:49:30 +08:00
astaxie
6a78898bb1 beego: fix the tree for addtree & add testcase 2014-08-12 15:09:12 +08:00
astaxie
f201859fa7 beego: fix the addTree 2014-08-12 00:15:39 +08:00
astaxie
52fdfc5665 beego: fix the tree addTree for regexp 2014-08-12 00:02:27 +08:00
astaxie
8ed6d06572 fix the regexps bugs 2014-08-11 22:40:55 +08:00
astaxie
b5a2347e1d Merge pull request #733 from liulixiang1988/develop
improve the 'geturl'
2014-08-11 22:25:53 +08:00
liulixiang1988
118e07158e improve the 'geturl'
If we have a url mapping like this:
`beego.Router(“/test”, &controllers.WeightController{},
"get:GetDetails”)`
when u use `UrlFor(“WeightController.GetDetails”, “foo”, 1, “bar”, 2 `,
it should return `/test?foo=1&bar=2` rather than `/test`.
2014-08-11 22:19:59 +08:00
astaxie
7a376c32be delete forms 2014-08-11 22:13:57 +08:00
astaxie
3d74a1a436 make the getconfig public
// Getconfig throw the Runmode
// [dev]
// name = astaixe
// IsEnable = false
// [prod]
// name = slene
// IsEnable = true
//
// usage:
// GetConfig("string", "name")
// GetConfig("bool", "IsEnable")
2014-08-11 22:13:18 +08:00
astaxie
00eac0e4cb Merge pull request #729 from francoishill/patch-9
Update captcha.go
2014-08-11 21:41:22 +08:00
Francois
58ac0d5ea4 Update captcha.go
Captcha must be deleted if the user entered a "challenge" with a different length than the captcha.
2014-08-09 15:35:29 +02:00
astaxie
2773fda883 session:change the driver from beego to bradfitz 2014-08-08 16:43:39 +08:00
astaxie
99c03a2b9c fix the nil judge 2014-08-08 13:16:51 +08:00
astaxie
b1b4dbb0e4 fix the nil judge 2014-08-08 12:02:44 +08:00
astaxie
77e1f26dd4 Merge pull request #728 from nizsheanez/null_pointer_panic_improve
[orm] improve null pointer panic message
2014-08-08 09:01:51 +08:00
astaxie
2820f630c8 config: add more method
DefaultString(key string, defaultval string) string      // support
section::key type in key string when using ini and json type;
Int,Int64,Bool,Float,DIY are same.
	DefaultStrings(key string, defaultval []string) []string //get string
slice
	DefaultInt(key string, defaultval int) int
	DefaultInt64(key string, defaultval int64) int64
	DefaultBool(key string, defaultval bool) bool
	DefaultFloat(key string, defaultval float64) float64
	DIY(key string) (interface{}, error)
	GetSection(section string) (map[string]string, error)
	SaveConfigFile(filename string) error
2014-08-07 17:24:21 +08:00
astaxie
1f6c5599aa migration: version 1 2014-08-07 16:30:28 +08:00
Alexey Sharov
df8c73b23a improve null pointer panic message 2014-08-07 12:14:10 +07:00
astaxie
ea6982fcea beego: template fund when the start> len(bt) 2014-08-05 23:52:06 +08:00
astaxie
a3f40234ca Merge branch 'develop' of https://github.com/astaxie/beego into develop 2014-08-05 08:56:34 +08:00
astaxie
2c420573d4 fix #703 2014-08-05 08:56:04 +08:00
astaxie
c0d3cc6fc5 beego: fix the domain string 2014-08-05 08:55:46 +08:00
astaxie
3f7ecea089 beego: Display function move from toolbox to utils 2014-08-04 20:52:18 +08:00
astaxie
f4147058fc fix when delete the commentsRouter.go 2014-08-04 17:39:14 +08:00
astaxie
1fb24aca34 beego: commentsrouter use the workPath fix #708 2014-08-04 17:34:52 +08:00
astaxie
885c0678ff move filter wrong http method 2014-08-04 16:21:34 +08:00
astaxie
d7a5281bda session: support cookie domain 2014-08-04 16:21:06 +08:00
astaxie
474a16a7a0 beego: improve the static file server 2014-08-04 15:31:27 +08:00
astaxie
1d36b19cab Merge branch 'develop' of https://github.com/astaxie/beego into develop 2014-08-04 15:00:42 +08:00
astaxie
deed251794 Merge pull request #720 from MicroMoon/patch-1
revise the comment of SliceIntersect
2014-08-02 23:28:08 +08:00
Stan Sun
22ba252c8f fix the comment of SliceIntersect
The implementations of SliceDiff and SliceIntersect are the same.
However, the comments of them are opposite.
The former is (slice1 - slice2) while the latter is (slice2- slice1)
2014-08-02 17:54:57 +08:00
astaxie
289f050c04 cache: fix comments the return err 2014-08-02 10:12:03 +08:00
astaxie
bbd31131a4 beego:parse judge weather the commentsRouter exist 2014-08-02 10:11:45 +08:00
astaxie
008ae39ff6 Merge branch 'master' into develop 2014-08-01 17:04:22 +08:00
astaxie
0836b9e13f fix #718 2014-08-01 17:03:28 +08:00
astaxie
7a39a3c52f middleware: error page set the content-type 2014-08-01 16:46:51 +08:00
astaxie
509af636b1 Merge pull request #716 from 4eek/docfix-validations-HasErrors
Fixed docs: HasErrors is a method not a variable
2014-07-29 22:04:26 +08:00
Kevin Fourie
daf8b1101f Fixed docs: HasErrors is a method not a variable 2014-07-29 15:05:04 +02:00
astaxie
428aec1c24 Merge pull request #715 from MicroMoon/develop
revise a comment
2014-07-28 09:52:26 +08:00
stansun
a804d242d9 revise a comment
If it gets a msg from the buffer chan, it will write the message to
outputs.
2014-07-27 07:13:17 -04:00
astaxie
7ddd20340b orm: delete the old docs 2014-07-26 23:25:59 +08:00
astaxie
e7fcb824c1 utils: fix the safemap Items 2014-07-26 23:25:51 +08:00
astaxie
ee9749d640 beego:fix #685
move XsrfToken& CheckXsrfCookie to context
2014-07-24 23:12:21 +08:00
astaxie
d7090689e8 cache: change the memcache &redis driver
change the memcache to the newest
2014-07-24 22:54:56 +08:00
astaxie
52d153da87 Merge pull request #710 from francoishill/patch-8
Update smtp.go (develop branch)
2014-07-22 13:45:24 +08:00
Francois
6ce55e8884 Update smtp.go (develop branch)
For mail servers that do not require Authentication we must pass NIL for the SendMail parameter 2 (the auth parameter). Otherwise it fails to send the mail.
2014-07-22 07:21:47 +02:00
astaxie
91ee42ceeb beego:update the Abort Status 2014-07-18 15:38:29 +08:00
astaxie
d17f107fc4 beego: fix #702 auto render 2014-07-18 13:29:54 +08:00
astaxie
ae8bb8ce82 Merge pull request #701 from fuxiaohei/develop
code style simplify
2014-07-17 16:51:01 +08:00
fuxiaohei
38188098c5 fix testing fail 2014-07-17 16:48:10 +08:00
fuxiaohei
c372328f88 code style simplify 2014-07-17 16:22:52 +08:00
fuxiaohei
a6ced64441 code style simplify 2014-07-17 16:22:41 +08:00
astaxie
69094b2786 remove koding link 2014-07-17 16:05:17 +08:00
astaxie
08397fef45 Merge pull request #700 from fuxiaohei/develop
code style simplify
2014-07-17 15:58:37 +08:00
fuxiaohei
84da1c924a code style simplify 2014-07-17 15:56:06 +08:00
fuxiaohei
f733b5707a code style simplify 2014-07-17 15:49:40 +08:00
fuxiaohei
9d0798edc6 Merge branch 'develop' of https://github.com/astaxie/beego into develop 2014-07-17 15:46:28 +08:00
astaxie
1858f3073b session: fix #688 2014-07-16 23:05:38 +08:00
astaxie
e6d6419a65 beego: static file support robots.txt 2014-07-16 22:27:53 +08:00
fuxiaohei
e52386b52d code style simplify 2014-07-15 10:01:26 +08:00
fuxiaohei
024817aacb Merge branch 'develop' of https://github.com/astaxie/beego into develop 2014-07-15 09:47:49 +08:00
fuxiaohei
9d0ad3f974 code style simplify 2014-07-13 18:11:13 +08:00
astaxie
6357c88d97 Merge pull request #694 from fuxiaohei/develop
code style simplify
2014-07-13 18:10:51 +08:00
fuxiaohei
9457e61a0c code style simplify 2014-07-12 22:12:06 +08:00
astaxie
f657509a42 Merge pull request #693 from fuxiaohei/develop
code style simplify
2014-07-12 19:33:32 +08:00
fuxiaohei
20e05a3908 code style simplify 2014-07-12 16:03:14 +08:00
fuxiaohei
77c40e6f7b code style simplify 2014-07-12 15:51:47 +08:00
fuxiaohei
ea2ed90ab0 Merge remote-tracking branch 'remotes/astaxie/develop' into develop 2014-07-12 15:32:37 +08:00
astaxie
15759f60ed Merge pull request #692 from fuxiaohei/develop
code style simplify
2014-07-12 14:18:30 +08:00
fuxiaohei
0e3e22efbe merge update 2014-07-12 09:57:43 +08:00
fuxiaohei
a906bf1174 code style simplify 2014-07-12 09:52:15 +08:00
astaxie
a6379481cf Merge pull request #691 from FGM/logger-rfc5424
Issue #682: convert logs package to RFC5424 logging levels.
2014-07-11 21:35:56 +08:00
Frederic G. MARAND
7d09ac252a Issue #682: convert logs package to RFC5424 logging levels. 2014-07-11 11:15:34 +02:00
fuxiaohei
0ff058bd25 code style simplify 2014-07-11 10:01:49 +08:00
astaxie
dbe75f90d5 Merge pull request #689 from fuxiaohei/develop
code style simplify
2014-07-11 09:55:56 +08:00
astaxie
ca1fd96ea5 Merge pull request #687 from fuxiaohei/develop
code style simplify
2014-07-10 16:48:04 +08:00
fuxiaohei
0b1b121db8 code style simplify 2014-07-10 13:38:05 +08:00
fuxiaohei
8683ee7c67 code style simplify 2014-07-10 13:28:54 +08:00
fuxiaohei
007db805be code style simplify 2014-07-10 13:04:18 +08:00
astaxie
19c3a5b41c beego: improve the router debug infomation 2014-07-09 09:38:36 +08:00
astaxie
e635e274d4 Merge branch 'master' into develop 2014-07-09 08:43:37 +08:00
astaxie
46cde6e579 Merge pull request #683 from chrisport/develop
beego/context: Fix ignored Header in case SetStatus has been called before
2014-07-09 08:39:54 +08:00
Christoph Portmann
3bb4d6f013 beego/context: Fix ignored Header in case SetStatus has been called before 2014-07-08 23:24:47 +03:00
astaxie
cec151fda7 Merge pull request #674 from reterVision/master
Make redis cache timeout not trivial.
2014-07-07 09:49:54 +08:00
reterVision
b6c4e27a75 Adjust the action order in Put function. 2014-07-05 22:30:51 +08:00
reterVision
2933d1fedd Make redis cache timeout not trivial.
- Instead of using HASH for all the caches, use HASH + normal KEYs.
- HASH being used as a collection of all KEYs, this is useful when
  application wants to clear all keys.
2014-07-05 22:27:31 +08:00
astaxie
cbffcaa7a8 Merge pull request #673 from sandysong/master
修正Detect Engine错误
2014-07-04 17:58:26 +08:00
sandysong
707c951302 修正Detect Engine错误 2014-07-04 16:57:37 +08:00
astaxie
fefd8ddb5b beego: update licence& fix #669 2014-07-03 23:40:21 +08:00
astaxie
14dee37a21 beego: autorouter params 2014-07-01 16:55:23 +08:00
astaxie
17a9c3c3a9 ORM:revert default value 2014-07-01 09:30:08 +08:00
astaxie
8946f816f9 orm:change the models_test default value 2014-07-01 00:30:05 +08:00
astaxie
36ba1e49b1 beego:change to 1.3.2 2014-07-01 00:06:35 +08:00
astaxie
34936dde35 Merge branch 'master' into develop 2014-06-30 23:50:45 +08:00
astaxie
aa004ed973 beego:form render textarea 2014-06-30 23:49:55 +08:00
astaxie
53353fce56 beego:fix the :id & * mixed router 2014-06-30 23:49:11 +08:00
astaxie
f92ce9af96 Merge pull request #654 from wb14123/cmd_default
Generate default value while run ORM cmd tool
2014-06-30 21:36:10 +08:00
astaxie
8b021c8ea1 Merge pull request #664 from kioopi/renderform-textarea
Makes RenderForm use textarea-element when form type is `textarea`
2014-06-30 21:14:27 +08:00
Vangelis Tsoumenis
34572193c6 Adds html5 input types to valid intput types of RenderForm. 2014-06-30 10:38:32 +02:00
astaxie
4dde2c59ff fix the parser.go lastupdate 2014-06-30 15:57:36 +08:00
astaxie
c83c17d917 Merge pull request #660 from ljyf5593/patch-1
beego: fix #657
2014-06-30 12:06:24 +08:00
Vangelis Tsoumenis
4994d36b66 templateform.RenderForm now renders textarea
When RenderForm encounters a field with the structTag `form` value
type `textarea` it renders an actual <textarea> html tag.
2014-06-29 20:49:56 +02:00
Vangelis Tsoumenis
a991b9dcde Removes unused FormType map from templatefunc 2014-06-29 20:49:35 +02:00
Vangelis Tsoumenis
3fe9e6a28a extract func parseFormTag from templatefunc.RenderForm
Extracted a func `parseFormTag` that takes a reflect.StructField
and returns the different positional parts of the `form` structTag
with default values as documented in
http://beego.me/docs/mvc/view/view.md#renderform

This makes RenderForm shorter and makes it possible to test the
parsing separately.
2014-06-29 20:49:08 +02:00
astaxie
62e9c89010 middleware: support i18n 2014-06-27 17:53:53 +08:00
ljyf5593
ac96c2b15e beego: fix #657
路由地址不区分大小写问题
2014-06-27 11:06:29 +08:00
astaxie
0f170a80da update the comments fix #658 2014-06-25 10:39:37 +08:00
astaxie
9c5348f690 beego: autoroute 2014-06-23 15:52:30 +08:00
astaxie
90f91b10c5 beego: change to beego 1.3.1 2014-06-23 15:31:51 +08:00
astaxie
a5a6a30744 beego: fix the router rule for * 2014-06-23 15:28:53 +08:00
astaxie
1f6e689e5d beego: fix #652 2014-06-23 15:28:29 +08:00
Bin Wang
7b7a95677a Generate default value while run ORM cmd tool 2014-06-22 10:52:14 +08:00
astaxie
af4f153830 beego: update the router rule for *
* not match the empty route
2014-06-21 11:44:24 +08:00
astaxie
469f283b68 beego:fix captcha filter router 2014-06-19 20:29:36 +08:00
astaxie
085c362ffb beego:fix router expge 2014-06-18 23:32:47 +08:00
astaxie
c3a07555c4 beego:change version to 1.3.0 2014-06-18 15:15:45 +08:00
astaxie
2b8e411174 merger master httplib 2014-06-18 15:04:08 +08:00
astaxie
720a77c1f9 beego:rever docs 2014-06-18 11:15:43 +08:00
astaxie
b943b74fc5 beego:init GlobalDocApi 2014-06-18 11:09:47 +08:00
astaxie
67be7b532d beego:doc move to swagger 2014-06-18 10:36:20 +08:00
slene
8be83fe488 Merge pull request #642 from JessonChan/develop
ignore nil time
2014-06-17 15:25:03 +08:00
astaxie
cff632f553 beego: swagger EnableDocs 2014-06-16 16:05:19 +08:00
astaxie
4990d88861 Merge pull request #648 from redaready/develop
update chat example
2014-06-14 12:13:50 +08:00
redar
7075ad8a28 update chat example 2014-06-14 00:21:26 +02:00
astaxie
0e278ae358 beego:format the admin print route 2014-06-13 00:14:30 +08:00
astaxie
e38a23b30e beego:admin add print method 2014-06-13 00:08:43 +08:00
astaxie
117904be73 beego:fix the some regexp routes to different func 2014-06-12 23:08:05 +08:00
astaxie
3b807845f2 beego:addtree support regexp 2014-06-12 20:50:29 +08:00
astaxie
00b710e168 beego:namespace sub router add url to pattern 2014-06-11 23:51:19 +08:00
astaxie
e25fcffbc0 config:json add support array 2014-06-11 22:47:11 +08:00
astaxie
c13141b8bf beego:fix when user defined function equal to HTTP 2014-06-11 22:45:54 +08:00
astaxie
7a7ff735e3 Merge pull request #644 from chrisport/develop
config: fix error when json config starts with an array
2014-06-11 22:02:28 +08:00
Christoph Portmann
3b934bb910 config: fix error when json config starts with an array 2014-06-11 11:33:32 +03:00
astaxie
aa275fb5ce beego:fix #639 2014-06-11 13:26:45 +08:00
astaxie
deb553be7f beego:confgi support difference run mode section
runmode = dev
appname = doraemon
[dev]
httpport = 8880
sessionon = true

[prod]
httpport = 8888
sessionon = true

[test]
httpport = 8080
sessionon = false
2014-06-11 12:00:50 +08:00
astaxie
3db9633ebd remove websocket logic because not support handler 2014-06-11 11:12:17 +08:00
astaxie
2f8a70d548 beego: router support param has _ 2014-06-11 09:33:35 +08:00
astaxie
7c0d0900ac beego:fix static file router 2014-06-11 01:19:39 +08:00
astaxie
6809c97611 beego: improve performance 2014-06-11 01:11:32 +08:00
astaxie
675643c68d beego: run mode support test 2014-06-10 22:47:48 +08:00
JessonChan
06f4bf493d ignore nil time 2014-06-10 22:10:58 +08:00
astaxie
4786fb0948 beego:fix typo NewControllerRegister 2014-06-10 20:12:57 +08:00
astaxie
fdb5672b7a beego:delete debug information 2014-06-10 18:10:32 +08:00
astaxie
107a7a21c0 beego: dev mode print request router & pattern 2014-06-10 18:09:07 +08:00
astaxie
dbebf8df4b beego:namespace support nest
ns := NewNamespace("/v3",
		NSAutoRouter(&TestController{}),
		NSNamespace("/shop",
			NSGet("/order/:id", func(ctx *context.Context) {
				ctx.Output.Body([]byte(ctx.Input.Param(":id")))
			}),
		),
	)
2014-06-10 17:11:02 +08:00
astaxie
f7b01aab13 beego: modify the filter sequence 2014-06-10 11:02:41 +08:00
astaxie
2570f075d9 beego:change ControllerComments exported 2014-06-09 17:46:13 +08:00
astaxie
21cb8ea4a3 beego:AST code 2014-06-09 17:33:04 +08:00
astaxie
6c8a7f1382 beego: router change to method Tree 2014-06-09 10:11:37 +08:00
astaxie
e00eab7f49 beego: change to tree 2014-06-08 20:24:07 +08:00
astaxie
bfabcfcb6b beego:router tree 2014-06-08 20:24:07 +08:00
astaxie
f06ba52ede Merge pull request #633 from dlt/develop
fixed typo on constant applicationXml
2014-06-07 01:10:42 +08:00
Dalto Curvelano Jr
fcae000a79 fixed typo on constant applicationXml 2014-06-06 13:56:34 -03:00
astaxie
3e4c015982 Merge pull request #631 from curvesoft/master
cookiejar support
2014-06-04 23:02:52 +08:00
CurveSoft
d689be30e8 remove httplib_test.php 2014-06-04 22:12:37 +08:00
CurveSoft
7b110a0b73 remove httplib_test.php 2014-06-04 22:09:43 +08:00
CurveSoft
e3033b57a6 1.gofmt httplib.go httplib_test.go
2.replace test url to http://httpbin.org functions
2014-06-04 21:15:24 +08:00
CurveSoft
bd537554ea 1.gofmt httplib.go httplib_test.go
2.replace test url to http://httpbin.org functions
2014-06-04 21:04:50 +08:00
CurveSoft
ebb3b91df9 1、增加cookiejar支持
2、增加Setting结构,便于统一设置请求参数
3、增加服务端测试php脚本
2014-06-03 21:20:10 +08:00
astaxie
a65ad1a4bc fix the time test case 2014-05-31 14:28:44 +08:00
astaxie
bdc01f52a0 Merge pull request #626 from mvpmvh/michael
Michael
2014-05-31 14:25:40 +08:00
Michael
a673a85d4a added tests config/json_test that test missing key usecases. created a template function to fetch AppConfig values 2014-05-30 23:48:23 -05:00
Michael
61008fe75c udpated timezone in templatefunc_test. changed error message to be more descriptive when tests fail 2014-05-30 14:12:21 -05:00
astaxie
5dee6b7d19 beego: fix the namespace cond 2014-05-28 10:23:31 +08:00
astaxie
f6c7a6bd32 beego: improve the admin router print 2014-05-27 17:27:22 +08:00
astaxie
d2eece9a39 session: #620 make the session never read empty 2014-05-27 15:45:35 +08:00
astaxie
c3a23b28ee beego: improve the RandomCreateBytes #620
when rand.Read is failed. will use the math/rand to generate the rand
bytes
2014-05-27 15:29:43 +08:00
astaxie
9083927c6a beego: enhance the XSRFKEY from 15 to 32 #620 2014-05-27 15:00:10 +08:00
astaxie
3f7e91e6a4 beego:fix *.* router bug 2014-05-26 10:15:56 +08:00
astaxie
a2a6f47afa beego: support other config provider 2014-05-25 22:37:38 +08:00
astaxie
23229ef9ef beego: BeegoServerName & beego.Run
BeegoServerName change to beegoServer+Version
beego.Run(“:8089”)
2014-05-25 22:35:20 +08:00
astaxie
0d17d974cd beego: update namespace 2014-05-23 15:56:25 +08:00
astaxie
17104c25a2 beego: Refactoring Filter & add comments 2014-05-20 18:47:41 +08:00
astaxie
8b374d7f90 beego: add benchmark 2014-05-20 18:20:44 +08:00
astaxie
fa3234147a httplib:drone can't upload file 2014-05-20 17:34:52 +08:00
astaxie
33ad6c1370 beego: remove app funciont & fix #590
config := tls.Config{
    ClientAuth: tls.RequireAndVerifyClientCert,
    Certificates: []tls.Certificate{cert},
    ClientCAs: pool,
}
config.Rand = rand.Reader

beego.BeeApp.Server. TLSConfig = &config
2014-05-20 17:28:06 +08:00
astaxie
04290dfc68 beego: delete hotupdate 2014-05-20 16:41:39 +08:00
astaxie
03080b3ef2 beego:1.2.0 2014-05-20 15:53:41 +08:00
astaxie
3f2a712ba8 beego:change default port 2014-05-20 15:40:05 +08:00
astaxie
f215aa4810 beego: change the error tips 2014-05-20 15:34:27 +08:00
astaxie
18a02d7d60 beego:support https & http listen 2014-05-20 15:30:17 +08:00
astaxie
3f4d750dc4 utils: improve the file grep 2014-05-20 14:32:06 +08:00
astaxie
9f01aeed31 beego:remove unused code 2014-05-19 18:52:48 +08:00
astaxie
b45f0b9bf6 beego: fix #478 2014-05-17 02:56:50 +08:00
astaxie
cf04ade603 merger master 2014-05-17 02:29:41 +08:00
astaxie
92f6181616 beego: change the version to 1.2.0 2014-05-17 02:26:52 +08:00
astaxie
9270a0504a beego: admin support link 2014-05-17 02:26:52 +08:00
astaxie
1da37f6ce1 beego: controller add ServeFormatted
ServeFormatted serve Xml OR Json, depending on the value of the Accept
header
2014-05-17 02:26:52 +08:00
astaxie
ef6d9b9a94 session: support memcache interface 2014-05-17 02:26:52 +08:00
astaxie
c265786251 session:support struct.
gob.Register(v)
2014-05-17 02:26:51 +08:00
astaxie
c5c806b58e beego: XSRF support Controller level fix #610
default value is true when you Enable Global XSRF, also can control in
the prepare function to change the value.
2014-05-17 02:26:51 +08:00
astaxie
e657dcfd5f beego: support namespace
ns := beego.NewNamespace("/v1/api/")
ns.Cond(func(ctx *context.Context)bool{
	    if ctx.Input.Domain() == "www.beego.me" {
	    	return true
	    }
	    return false
	})
.Filter("before", Authenticate)
.Router("/order",	&admin.OrderController{})
.Get("/version",func (ctx *context.Context) {
	ctx.Output.Body([]byte("1.0.0"))
})
.Post("/login",func (ctx *context.Context) {
	if ctx.Query("username") == "admin" && ctx.Query("username") ==
"password" {

	}
})
.Namespace(
	NewNamespace("/shop").
		Get("/order/:id", func(ctx *context.Context) {
		ctx.Output.Body([]byte(ctx.Input.Param(":id")))
	}),
)
2014-05-17 02:26:51 +08:00
slene
2ed9b2bffd orm: add test for unexported struct field 2014-05-17 02:26:51 +08:00
astaxie
55ad951bce beego: support more router
//design model
	beego.Get(router, beego.FilterFunc)
	beego.Post(router, beego.FilterFunc)
	beego.Put(router, beego.FilterFunc)
	beego.Head(router, beego.FilterFunc)
	beego.Options(router, beego.FilterFunc)
	beego.Delete(router, beego.FilterFunc)
	beego.Handler(router, http.Handler)

//example

beego.Get("/user", func(ctx *context.Context) {
	ctx.Output.Body([]byte("Get userlist"))
})

beego.Post("/user", func(ctx *context.Context) {
	ctx.Output.Body([]byte("add userlist"))
})

beego.Delete("/user/:id", func(ctx *context.Context) {
	ctx.Output.Body([]byte([]byte(ctx.Input.Param(":id")))
})

import (
    "http"
    "github.com/gorilla/rpc"
    "github.com/gorilla/rpc/json"
)

func init() {
    s := rpc.NewServer()
    s.RegisterCodec(json.NewCodec(), "application/json")
    s.RegisterService(new(HelloService), "")
    beego.Handler("/rpc", s)
}
2014-05-17 02:26:51 +08:00
astaxie
ef815bf5fc config: fix the import issue 2014-05-17 02:26:51 +08:00
jessonchan
6082a0af3e bug fixed 2014-05-17 02:26:51 +08:00
jessonchan
be30fb7937 refator func 2014-05-17 02:26:51 +08:00
toby.zxj
f4e7d63e65 httplib support to set the protocol version for incoming requests 2014-05-17 02:26:51 +08:00
astaxie
14688f240f httplib:support file upload 2014-05-17 02:26:51 +08:00
astaxie
dce09837b9 fix the typo 2014-05-17 02:26:50 +08:00
astaxie
3b9a404138 beego: support other analisys & fix typo 2014-05-17 02:26:50 +08:00
astaxie
a6f55b59cf beego: add link in the admin console 2014-05-17 02:26:50 +08:00
astaxie
c188cbbcb4 update all files License 2014-05-17 02:26:50 +08:00
astaxie
4245521660 fix #576 2014-05-17 02:26:50 +08:00
astaxie
05e5baaa9f beego:add post test case 2014-05-17 02:26:50 +08:00
astaxie
54b92e9599 context:add Bind function
// Bind data from request.Form[key] to dest
// like
/?id=123&isok=true&ft=1.2&ol[0]=1&ol[1]=2&ul[]=str&ul[]=array&user.Name=
astaxie
// var id int  beegoInput.Bind(&id, "id")  id ==123
// var isok bool  beegoInput.Bind(&isok, "isok")  id ==true
// var ft float64  beegoInput.Bind(&ft, "ft")  ft ==1.2
// ol := make([]int, 0, 2)  beegoInput.Bind(&ol, "ol")  ol ==[1 2]
// ul := make([]string, 0, 2)  beegoInput.Bind(&ul, "ul")  ul ==[str
array]
// user struct{Name}  beegoInput.Bind(&user, "user")  user ==
{Name:"astaxie"}
2014-05-17 02:26:50 +08:00
astaxie
aa68ffecec beego: support not-empty value in router fix #555 2014-05-17 02:26:50 +08:00
Lin Luxiang
78991c81ab make Maxage work 2014-05-17 02:26:49 +08:00
Donald Zhan
348ff13857 update the error message 2014-05-17 02:26:49 +08:00
Kyle McCullough
52817fb668 allow unexported fields on model structs 2014-05-17 02:26:49 +08:00
astaxie
2c59ff1cc6 beego: admin support link 2014-05-17 02:20:48 +08:00
astaxie
6bdf0838ce beego: controller add ServeFormatted
ServeFormatted serve Xml OR Json, depending on the value of the Accept
header
2014-05-17 01:26:59 +08:00
astaxie
31a63c5d50 session: support memcache interface 2014-05-17 01:19:47 +08:00
astaxie
237aaadd65 session:support struct.
gob.Register(v)
2014-05-17 00:43:51 +08:00
astaxie
34ddcef1dc beego: XSRF support Controller level fix #610
default value is true when you Enable Global XSRF, also can control in
the prepare function to change the value.
2014-05-17 00:12:25 +08:00
astaxie
f6ce2656db beego: support namespace
ns := beego.NewNamespace("/v1/api/")
ns.Cond(func(ctx *context.Context)bool{
	    if ctx.Input.Domain() == "www.beego.me" {
	    	return true
	    }
	    return false
	})
.Filter("before", Authenticate)
.Router("/order",	&admin.OrderController{})
.Get("/version",func (ctx *context.Context) {
	ctx.Output.Body([]byte("1.0.0"))
})
.Post("/login",func (ctx *context.Context) {
	if ctx.Query("username") == "admin" && ctx.Query("username") ==
"password" {

	}
})
.Namespace(
	NewNamespace("/shop").
		Get("/order/:id", func(ctx *context.Context) {
		ctx.Output.Body([]byte(ctx.Input.Param(":id")))
	}),
)
2014-05-16 23:47:29 +08:00
slene
b647026dff orm: add test for unexported struct field 2014-05-16 13:14:15 +08:00
slene
568c0c47f0 Merge pull request #542 from kylemcc/develop
orm: allow unexported fields on model structs
2014-05-16 13:11:55 +08:00
astaxie
2629de28f2 beego: support more router
//design model
	beego.Get(router, beego.FilterFunc)
	beego.Post(router, beego.FilterFunc)
	beego.Put(router, beego.FilterFunc)
	beego.Head(router, beego.FilterFunc)
	beego.Options(router, beego.FilterFunc)
	beego.Delete(router, beego.FilterFunc)
	beego.Handler(router, http.Handler)

//example

beego.Get("/user", func(ctx *context.Context) {
	ctx.Output.Body([]byte("Get userlist"))
})

beego.Post("/user", func(ctx *context.Context) {
	ctx.Output.Body([]byte("add userlist"))
})

beego.Delete("/user/:id", func(ctx *context.Context) {
	ctx.Output.Body([]byte([]byte(ctx.Input.Param(":id")))
})

import (
    "http"
    "github.com/gorilla/rpc"
    "github.com/gorilla/rpc/json"
)

func init() {
    s := rpc.NewServer()
    s.RegisterCodec(json.NewCodec(), "application/json")
    s.RegisterService(new(HelloService), "")
    beego.Handler("/rpc", s)
}
2014-05-16 10:18:19 +08:00
astaxie
10d2c7c328 config: fix the import issue 2014-05-16 10:18:19 +08:00
astaxie
af7ac98bd6 Merge pull request #609 from JessonChan/develop
[important] bug fixed
2014-05-15 11:47:07 +08:00
jessonchan
6f78f1d4b2 bug fixed 2014-05-15 11:34:44 +08:00
astaxie
9f95fd3309 Merge pull request #608 from JessonChan/develop
refactor func
2014-05-14 20:47:01 +08:00
jessonchan
74c309cefd refator func 2014-05-14 20:08:51 +08:00
astaxie
b6d63c84ae Merge pull request #605 from francoishill/patch-6
Update app.go
2014-05-14 13:12:15 +08:00
Francois
bc2f1fb79d Update app.go 2014-05-13 17:19:50 +02:00
astaxie
29e113a48a Merge pull request #597 from tobyzxj/develop
httplib support to set the protocol version for incoming requests
2014-05-09 16:25:33 +08:00
toby.zxj
3caf1896d6 httplib support to set the protocol version for incoming requests 2014-05-09 15:48:50 +08:00
astaxie
d5d5f23756 httplib:support file upload 2014-05-08 16:58:08 +08:00
astaxie
46641ef3b6 fix the typo 2014-05-08 10:51:29 +08:00
astaxie
8ed459512f Merge pull request #591 from luosangnanka/master
Update Session package README.md
2014-05-05 16:43:53 +08:00
luosangnanka
25768f0109 Update README.md
Update the json format of session for file, redis, mysql, cookie, there are errors in these json string, such as after the param `ProviderConfig` and there is a lost of `"` in the line 61 of the `gclifetime`.
2014-05-05 16:21:50 +08:00
luosangnanka
a56f67e073 Update README.md
Update the json format of session for file, redis, mysql, there are errors in these json string, after `ProviderConfig` params.
2014-05-05 16:15:49 +08:00
luosangnanka
8164f9821d Update README.md
Update the json format of session for redis, there is an error in that json string
2014-05-05 16:13:03 +08:00
astaxie
b2a69f505c beego: support other analisys & fix typo 2014-04-28 18:07:30 +08:00
astaxie
e307bd7ba9 beego:hotfix for multipart/form-data 2014-04-15 05:05:53 +08:00
astaxie
b2bd829d39 beego: add link in the admin console 2014-04-15 05:03:20 +08:00
astaxie
f9b8617fa3 context: fix multipart/form-data 2014-04-15 05:02:50 +08:00
astaxie
6c6e4ecfbc update all files License 2014-04-12 13:18:18 +08:00
astaxie
8bcf03c652 fix #576 2014-04-11 16:08:43 +08:00
astaxie
1ea449aa3a beego:add post test case 2014-04-10 22:33:32 +08:00
astaxie
a99802b7d1 beego:query data from Form & params 2014-04-10 22:21:08 +08:00
astaxie
b212ec8dab beego:query data from Form & params 2014-04-10 22:20:46 +08:00
astaxie
3e16feb1e2 beego: fix flash errors 2014-04-10 18:16:08 +08:00
astaxie
e50cbecf80 beego: fix flash errors 2014-04-10 18:14:18 +08:00
astaxie
127b85bcaa context:add Bind function
// Bind data from request.Form[key] to dest
// like
/?id=123&isok=true&ft=1.2&ol[0]=1&ol[1]=2&ul[]=str&ul[]=array&user.Name=
astaxie
// var id int  beegoInput.Bind(&id, "id")  id ==123
// var isok bool  beegoInput.Bind(&isok, "isok")  id ==true
// var ft float64  beegoInput.Bind(&ft, "ft")  ft ==1.2
// ol := make([]int, 0, 2)  beegoInput.Bind(&ol, "ol")  ol ==[1 2]
// ul := make([]string, 0, 2)  beegoInput.Bind(&ul, "ul")  ul ==[str
array]
// user struct{Name}  beegoInput.Bind(&user, "user")  user ==
{Name:"astaxie"}
2014-04-10 00:31:16 +08:00
astaxie
89dde6cd9d Merge branch 'develop' of https://github.com/astaxie/beego into develop 2014-04-09 21:43:32 +08:00
astaxie
5a52949761 beego: support not-empty value in router fix #555 2014-04-09 21:42:57 +08:00
astaxie
a78162e9e4 Merge pull request #573 from linluxiang/master
Make the Maxage Config of cookie session work
2014-04-09 14:42:29 +08:00
astaxie
931e6162ac Merge pull request #574 from dz1984/fix/cache_test
Fix/cache test
2014-04-09 14:42:01 +08:00
Lin Luxiang
1bb876f2df make Maxage work 2014-04-09 13:18:44 +08:00
Donald Zhan
18f70e6ee4 update the error message 2014-04-09 12:39:12 +08:00
astaxie
82ca85dc65 release new version 1.1.4 2014-04-08 17:49:12 +08:00
astaxie
f9cc9e9eb3 beego: release new version 1.1.4 2014-04-08 17:45:57 +08:00
astaxie
18fee2ad9a beego: fixed serious Directory Traversal 2014-04-08 17:43:25 +08:00
astaxie
4124760706 beego: filter the static file's url 2014-04-07 14:20:30 +08:00
astaxie
3fe4f8c362 toolbox: modify the godocs 2014-04-06 01:05:20 +08:00
astaxie
5a863b45f4 beego: BeeAdminApp private 2014-04-06 01:02:10 +08:00
astaxie
3ad30d48b5 beego: fix the godoc 2014-04-06 00:53:18 +08:00
astaxie
3255a43568 beego: move staticServer to New file 2014-04-06 00:18:21 +08:00
astaxie
73d757e3f4 context: improve the formParse 2014-04-06 00:08:03 +08:00
astaxie
deb28dd873 fix session test case 2014-04-04 10:16:34 +08:00
astaxie
7f394feab5 beego: hot fix for TestBeegoInit can't parsefile 2014-04-04 10:04:36 +08:00
astaxie
8cbea70e07 beego: hot fix for TestBeegoInit can't parsefile 2014-04-04 10:04:22 +08:00
astaxie
f222f5b238 beego: hot fix for console logs & go run can't find file. 2014-04-04 09:57:57 +08:00
astaxie
3f1de576e4 fix go run hello.go & console log 2014-04-04 09:57:51 +08:00
slene
f48ca96a7e beego: fix log output when SetLogger has error 2014-04-04 09:57:45 +08:00
slene
9421a21037 beego: fix log output when SetLogger has error 2014-04-04 09:57:37 +08:00
astaxie
5c06cd090c beego: hot fix for console logs & go run can't find file. 2014-04-04 09:56:25 +08:00
astaxie
fc982feeb9 fix go run hello.go & console log 2014-04-04 09:49:57 +08:00
slene
31de651053 beego: fix log output when SetLogger has error 2014-04-04 09:49:57 +08:00
slene
f4d62d3193 beego: fix dependency of cache / session sub package 2014-04-04 08:31:22 +08:00
slene
acbdeb62e8 beego: fix log output when SetLogger has error 2014-04-04 08:22:26 +08:00
slene
d58e9e6e12 beego: move dependency module to sub package 2014-04-03 23:41:48 +08:00
astaxie
6497f29ed7 version 1.1.2 release 2014-04-03 15:56:31 +08:00
astaxie
1705b42546 beego: change version from 1.1.1 to 1.1.2 2014-04-03 15:54:37 +08:00
asta.xie
5505cc09ed beego: move init to a fund & add a new fund TestBeegoInit
support Test with everything init
2014-04-03 15:07:20 +08:00
asta.xie
12e1ab0f80 beego: setLogger return error 2014-04-02 23:45:44 +08:00
asta.xie
9c5ceb70cc Logs: modify StartLogger to private 2014-04-02 23:43:37 +08:00
asta.xie
bf0b1af64f add workPath don't chdir when go run or go test 2014-04-01 18:08:00 +08:00
asta.xie
9c959fba4d fix string 2014-03-29 14:59:55 +08:00
asta.xie
5588bfc35e support filter to get router. get runController & runMethod 2014-03-29 14:55:34 +08:00
asta.xie
2f4acf46c6 modify the template file 2014-03-27 08:49:57 +08:00
asta.xie
c7437d7590 fix Cookie for session 2014-03-26 13:51:35 +08:00
asta.xie
4f819dbd9a Add a function SetLogFuncCall to enable 2014-03-26 00:06:25 +08:00
asta.xie
3f5fee2dc6 Logs support file & filenum 2014-03-25 23:48:58 +08:00
astaxie
c7f16b5d5a Merge pull request #551 from steamonimo/develop
session provider for postgresql
2014-03-25 21:28:42 +08:00
steamonimo
8d1268c0a9 session provider for postgresql
This provider is based on the mysql provider: sess_mysql.go
2014-03-25 12:45:23 +01:00
asta.xie
c921b0aa5d fix #533 change the function name 2014-03-21 14:33:11 +08:00
asta.xie
589f97130c add w.Rotate 2014-03-21 14:33:11 +08:00
asta.xie
443aaadcce fix #533 change the function name 2014-03-21 14:24:00 +08:00
asta.xie
ff1938054a add w.Rotate 2014-03-21 14:07:03 +08:00
slene
d79c297880 rollback: set httponly default is false. 2014-03-20 09:51:25 +08:00
slene
65631e0522 fix orm test 2014-03-19 10:00:26 +08:00
slene
a879e412a1 #514 2014-03-19 09:46:09 +08:00
Kyle McCullough
4785ac14d7 allow unexported fields on model structs 2014-03-18 18:00:07 -05:00
slene
50bc1ef757 rollback: set httponly default is false. 2014-03-17 12:27:04 +08:00
slene
7bacb25725 Merge pull request #538 from admpub/patch-2
validators bug fixed
2014-03-14 15:44:05 +08:00
S.W.H
ad8418720f bug fixed 2014-03-14 14:47:52 +08:00
astaxie
b59dae6fb8 Merge pull request #537 from jfolkins/develop
(REF#519) Enhancement: Allow developer to set FlashName and FlashSeperator values
2014-03-14 14:22:56 +08:00
Jared Folkins
4951314837 added FlashName,FlashSeperator, & Tests 2014-03-13 22:34:22 -07:00
asta.xie
8188873216 omit the data init 2014-03-14 12:00:53 +08:00
astaxie
5d392b76c7 Merge pull request #531 from unphp/develop
Update router.go
2014-03-14 10:08:47 +08:00
slene
c6a34b8efd Merge branch 'develop' of github.com:astaxie/beego into develop 2014-03-13 23:32:03 +08:00
slene
95e67ba2c2 orm now support custom builtin types as model struct field or query args fix #489 2014-03-13 23:31:47 +08:00
asta.xie
439b1afb85 Merge branch 'release/1.1.1' 2014-03-12 21:25:41 +08:00
asta.xie
745e9fb0fb change version to 1.1.1 2014-03-12 21:24:23 +08:00
asta.xie
769f7c751b fix static file route 2014-03-12 21:06:20 +08:00
astaxie
a8c2deb014 Merge pull request #530 from cnphpbb/develop
Update beego.go - Slice types exist trap
2014-03-12 18:56:12 +08:00
asta.xie
624f6258ee fix read / 2014-03-12 18:29:45 +08:00
unphp
43c977ab62 Update router.go
To append a slice's value into "exceptMethod", for controller's methods shouldn't reflect to AutoRouter
2014-03-12 17:20:53 +08:00
asta.xie
6c92ca2a16 fix bug for static file like /static /static_js /static_css 2014-03-12 17:03:34 +08:00
cnphpbb
0f015d75d2 Update beego.go - Modify GroupRouters all function
Modify the file beego.go. 
Type GroupRouters all function 
Slice types exist trap bug.
2014-03-12 16:50:13 +08:00
astaxie
217c3a2e87 Merge pull request #508 from voidd/develop
Couchbase session provider
2014-03-12 16:23:41 +08:00
asta.xie
ff6120cb93 Merge branch 'develop' of https://github.com/astaxie/beego into develop
Conflicts:
	session/sess_file.go
2014-03-12 15:57:57 +08:00
slene
53aaf3b4a9 orm add ResetModelCache api for test case 2014-03-12 15:56:05 +08:00
slene
d5b5c18cf9 orm add GetDB api #433 2014-03-12 15:56:05 +08:00
slene
cacdb3228d orm add operator between #518 2014-03-12 15:56:05 +08:00
Pengfei Xue
d0949b64c6 fix issue#521, return error when init redis session 2014-03-12 15:56:05 +08:00
Kirill Zdornyy
d49984d47d Fix basic auth plugin example.
NewBasicAuthenticator requires passing a second argument for Realm.
2014-03-12 15:56:05 +08:00
Daniel Hobe
9f3af59250 add support for sql.Null* types
Change instructions for sqlite3 tests to use in memory db for much faster
2014-03-12 15:56:05 +08:00
asta.xie
57afd3d979 GetStrings action as GetString 2014-03-12 15:56:05 +08:00
asta.xie
f7430a2ce1 enhance the static file path. If user foget / path.Join will auto fix it. 2014-03-12 15:56:05 +08:00
asta.xie
7389f0507e fix #505 2014-03-12 15:56:04 +08:00
slene
ee889e9975 skip cookie args when value is nil 2014-03-12 15:56:04 +08:00
slene
d8b9db8d3e move SetSecureCookie / GetSecureCookie to *context.Context and alias in Controller 2014-03-12 15:56:04 +08:00
slene
9b498feac7 update output.Cookie 2014-03-12 15:56:04 +08:00
asta.xie
69982c62c8 path default is /
httponly default true
seuce default not set
2014-03-12 15:56:04 +08:00
asta.xie
b405e19f56 delete MaxAge cookielifeTime replace 2014-03-12 15:56:04 +08:00
slene
828235b4c1 httplib support set transport and proxy 2014-03-12 15:56:04 +08:00
slene
430a0a971f orm insert skip auto_now_add when user custom a value 2014-03-12 15:56:04 +08:00
slene
5be22a99a8 fix captcha urlPrefix 2014-03-12 15:56:04 +08:00
Pengfei Xue
5d02b18db4 register interface to gob automatically 2014-03-12 15:56:04 +08:00
Pengfei Xue
97b68bdd66 fix bug, can not remove session file 2014-03-12 15:56:04 +08:00
slene
5583fa2054 orm add ResetModelCache api for test case 2014-03-10 20:52:04 +08:00
slene
00a410ad1a orm add GetDB api #433 2014-03-10 20:50:54 +08:00
slene
6ca30386b8 orm add operator between #518 2014-03-10 20:19:29 +08:00
astaxie
03b17a2ca9 Merge pull request #522 from pengfei-xue/develop
fix issue#521, return error when init redis session
2014-03-07 16:45:34 +08:00
Pengfei Xue
9957a867cd fix issue#521, return error when init redis session 2014-03-07 16:35:34 +08:00
astaxie
f3ba41a991 Merge pull request #517 from zkirill/develop
Fix basic auth plugin example.
2014-03-03 09:58:40 +08:00
Kirill Zdornyy
4befa1bc1b Fix basic auth plugin example.
NewBasicAuthenticator requires passing a second argument for Realm.
2014-03-02 17:44:23 -08:00
slene
9e3ebc88c4 Merge pull request #513 from hobeone/develop
add support for sql.Null* types, thx hobeone
2014-02-28 12:17:58 +08:00
Daniel Hobe
6e00cfb464 add support for sql.Null* types
Change instructions for sqlite3 tests to use in memory db for much faster
2014-02-27 19:53:35 -08:00
astaxie
c358c18018 Merge pull request #511 from francoishill/patch-2
Update sess_file.go
2014-02-28 09:40:28 +08:00
Francois
adf2a590fc Update sess_file.go
Lock required to ensure the File sessions work correct.
2014-02-27 15:34:38 +02:00
astaxie
edb8bac5bc Merge pull request #510 from jfolkins/fix_sessregenid
fix: added nil check on c.CruSession to prevent crash
2014-02-27 10:34:39 +08:00
Jared Folkins
47d7ac06b7 fix: added nil check on c.CruSession to prevent crash 2014-02-26 16:44:31 -08:00
asta.xie
d05270d2ec GetStrings action as GetString 2014-02-26 15:02:58 +08:00
asta.xie
04a19685ed enhance the static file path. If user foget / path.Join will auto fix it. 2014-02-26 14:44:41 +08:00
asta.xie
62555771d0 fix #505 2014-02-24 15:55:38 +08:00
slene
9dc93cbab0 skip cookie args when value is nil 2014-02-22 14:40:18 +08:00
slene
7f5fb871de move SetSecureCookie / GetSecureCookie to *context.Context and alias in Controller 2014-02-22 11:58:53 +08:00
slene
03037170e1 update output.Cookie 2014-02-22 11:12:57 +08:00
asta.xie
002e0854ab path default is /
httponly default true
seuce default not set
2014-02-22 10:37:14 +08:00
asta.xie
2bc70f62ce delete MaxAge cookielifeTime replace 2014-02-22 01:04:47 +08:00
slene
8bf0e67b79 httplib support set transport and proxy 2014-02-20 13:53:13 +08:00
slene
b310be1fcf orm insert skip auto_now_add when user custom a value 2014-02-20 13:45:31 +08:00
slene
a54353b51c fix captcha urlPrefix 2014-02-20 13:44:34 +08:00
Ivan
04c2ba01bc Merge branch 'develop' of https://github.com/voidd/beego 2014-02-19 22:44:06 +04:00
Ivan
296bcab425 couchbase session provider 2014-02-19 15:54:16 +04:00
astaxie
060b321182 Merge pull request #497 from pengfei-xue/develop
register interface to gob automatically
2014-02-18 16:47:59 +08:00
Pengfei Xue
05a0a4b046 register interface to gob automatically 2014-02-14 17:52:57 +08:00
astaxie
8906d3e77c Merge pull request #494 from pengfei-xue/develop
fix bug, can not remove session file
2014-02-13 20:19:42 +08:00
Pengfei Xue
e822642cb0 fix bug, can not remove session file 2014-02-13 18:24:05 +08:00
astaxie
a38a4f0343 Merge pull request #492 from TimothyYe/master
Fix spelling mistake
2014-02-10 14:51:26 +08:00
Timothy
e8a22660e4 Update error.go
Fix the spelling mistake of error page.
2014-02-10 12:55:53 +08:00
asta.xie
92196c602b Merge branch 'release/release1.1.0' 2014-02-10 11:39:03 +08:00
asta.xie
76222ac8d0 change 1.0.1 to 1.1.0 2014-02-10 11:33:53 +08:00
asta.xie
a184c23603 basic auth for plugin 2014-02-10 11:31:54 +08:00
asta.xie
1b778509c9 should copy the data direct. don't need range 2014-02-08 10:42:34 +08:00
asta.xie
c4250872ca controller data inherit the context's data 2014-02-07 17:25:56 +08:00
astaxie
17dd72241b Merge pull request #491 from fuxiaohei/develop
add comments for testing, utils and validation packages
2014-02-07 16:25:05 +08:00
傅小黑
ce2984f09a add comments for testing, utils and validation packages 2014-02-07 16:07:31 +08:00
傅小黑
846d766499 Merge branch 'develop' of git://github.com/astaxie/beego 2014-02-07 15:34:01 +08:00
asta.xie
bbc71142d7 controller can controller whether render the template.
EnableReander default is true.
2014-02-07 00:38:58 +08:00
astaxie
74804bc586 Merge pull request #490 from fuxiaohei/develop
add comments for session and toolbox package
2014-02-04 06:25:18 -08:00
傅小黑
1d08a54f44 add comments for toolbox packages 2014-01-29 19:12:00 +08:00
傅小黑
682544165f add comments for session packages, part 2 2014-01-29 18:15:09 +08:00
傅小黑
3f0ec5c0ca Merge branch 'develop' of git://github.com/astaxie/beego into develop 2014-01-29 01:06:49 +08:00
傅小黑
0e2872324f add comments for session packages, part 1 2014-01-29 01:05:56 +08:00
astaxie
2fb575838d Merge pull request #474 from pengfei-xue/develop
fix bug, redis session doesnt work
2014-01-28 01:50:20 -08:00
astaxie
ab8f8d532a Merge pull request #487 from cloudaice/log-feature
fixed bug: in logs package check if platform is windows
2014-01-27 20:50:25 -08:00
cloudaice
d93f112083 fixed bug: in logs package check if platform is windows 2014-01-28 11:26:43 +08:00
slene
9384e87083 orm 1. add api: NewOrmWithDB, AddAliasWthDB; 2. RawSeter -> add api: RowsToMap, RowsToStruct; 3. RawSeter -> change api: Values, ValuesList, ValuesFlat add optional params comumns. 2014-01-27 01:48:00 +08:00
Pengfei Xue
34eff4cc1f bugfix, delete the sid if it's values is empty
* regenerate sid, if the old key doesn't exists, set the new one directly
2014-01-25 10:55:49 +08:00
slene
8296713ba4 Merge pull request #477 from kylemcc/read_or_create
Add a ReadOrCreate method:
2014-01-24 18:01:24 -08:00
Pengfei Xue
d014ccfb8e bug fix, session stored in redis cannot be deleted 2014-01-23 19:28:58 +08:00
Kyle McCullough
190039b6f8 Add a ReadOrCreate method:
m := &User{Name: "Kyle"}
// Returns a boolean indicating whether the object was created,
// the primary key of the object, or an error.
created, id, err := orm.ReadOrCreate(m, "Name")
2014-01-22 09:15:21 -06:00
astaxie
edf7982567 Merge pull request #473 from cloudaice/logs-feature
diffrent level logs display diffrent color
2014-01-21 19:03:32 -08:00
Pengfei Xue
1509a6b681 fix bug, redis session doesnt work 2014-01-21 18:48:16 +08:00
cloudaice
11e6c2829b diffrent level logs display diffrent color 2014-01-21 18:00:17 +08:00
astaxie
38f93a7ba9 Merge pull request #470 from fuxiaohei/develop
add comments for orm and middleware packages.
2014-01-17 17:44:52 -08:00
傅小黑
6b5108ef92 Merge pull request #1 from fuxiaohei/develop
merge develop
2014-01-17 07:48:39 -08:00
FuXiaoHei
828a306069 add comments for orm package, done 2014-01-17 23:28:54 +08:00
傅小黑
4c527dde65 add comments for orm packages, part 2 2014-01-17 17:25:17 +08:00
傅小黑
f5a5ebe16b add comments for orm packages, part 1 2014-01-17 17:04:15 +08:00
傅小黑
32799bc259 add comments for middleware packages, fix typo error 2014-01-17 16:03:01 +08:00
slene
91d75e8925 add readme for captcha, and enhanced performance 2014-01-17 12:07:30 +08:00
astaxie
3e40041219 Merge pull request #468 from cloudaice/patch-1
Update README.md
2014-01-16 17:28:13 -08:00
项超
7d5ee0d692 Update README.md 2014-01-17 00:17:43 +08:00
slene
91cbe1f29b add some comments for captcha 2014-01-16 21:34:59 +08:00
slene
f419c12427 add captcha util 2014-01-16 20:53:35 +08:00
astaxie
fee3c2b8f9 add Strings interface can return []string sep by ;
Example:
peers = one;Two;Three
2014-01-15 17:19:03 +08:00
astaxie
b016102d34 add coding 2014-01-15 09:40:33 +08:00
astaxie
c20e1ab1e2 Merge pull request #463 from NormanZhang/develop
Update SessionExist to close the db connection
2014-01-14 06:13:34 -08:00
Norman
dc767b65df Update SessionExist to close the db connection
close the mysql connection
2014-01-14 19:54:32 +08:00
astaxie
63f19974cd Merge pull request #460 from pengfei-xue/develop
use connection pool for redis, support auto connection
2014-01-11 06:39:20 -08:00
slene
6e9ba0ea7f fix SessionRegenerateID should release old SessionStore and release new SessionStore in router.go 2014-01-11 17:01:33 +08:00
slene
3b99f37aa1 add a empty fake config Initialize AppConfig to avoid nil pointer runtime error. 2014-01-11 14:28:11 +08:00
slene
e8f5c10488 Merge pull request #457 from luxuchu/patch-1
fix #453
2014-01-10 22:21:27 -08:00
Pengfei Xue
cb55009c8b remove mutex 2014-01-10 20:31:43 +08:00
Pengfei Xue
b64e70e7df use connection pool for redis cache 2014-01-10 18:31:15 +08:00
slene
8d79f8387b #441 fix detect timezone in mysql 2014-01-10 16:50:03 +08:00
sol lu
afadb3f6df Update beego.go 2014-01-10 13:31:08 +08:00
astaxie
844412c302 fix #453 2014-01-09 21:37:50 +08:00
astaxie
299cb9130b Merge pull request #454 from pengfei-xue/develop
support redis cache auto connection
2014-01-09 04:49:31 -08:00
Pengfei Xue
0b42e5573b align memcache operations with redis 2014-01-09 18:50:30 +08:00
Pengfei Xue
a369b15ef2 reset cache connection to nil, if err isio.EOF
* this will support auto-connection
2014-01-09 18:49:18 +08:00
astaxie
e34f8c4634 add cookie test 2014-01-08 23:24:31 +08:00
astaxie
d7f2c738c8 add attach file 2014-01-08 22:35:42 +08:00
astaxie
d06c04277f support send mail 2014-01-08 22:31:26 +08:00
astaxie
aa2fef0d36 update sessionRelease
1. mysql fix last access time not update
2. mysql & redid Release when data is empty
3. add maxlifetime distinct Gclifetime
2014-01-08 20:54:20 +08:00
slene
b766f65c26 #436 support insert multi 2014-01-06 11:31:35 +08:00
astaxie
6f3a759ba5 gmfim add lock. fix #445 2014-01-05 23:16:47 +08:00
astaxie
338124e3fb fix #443 2014-01-05 15:43:48 +08:00
astaxie
31bdb793cf make fix 2014-01-05 15:21:50 +08:00
astaxie
9cbd475701 beego support new version session 2014-01-05 14:59:39 +08:00
astaxie
481448fa90 modify session module
change a log
2014-01-05 14:48:36 +08:00
slene
95c65de97c fix #440 2014-01-04 22:30:17 +08:00
slene
ef79a2b484 fix #440 2014-01-04 00:04:15 +08:00
astaxie
20cfece1ab Merge pull request #438 from Codonaut/error_page_improvements
Error page improvements
2014-01-02 07:17:49 -08:00
Scott Merkling
c433b7029f added back a <br> 2014-01-02 09:54:15 -05:00
Scott Merkling
f5cf2876dd Improved the language on the error pages 2014-01-02 09:53:09 -05:00
astaxie
480aa521e5 fix #430 2014-01-01 20:50:06 +08:00
astaxie
d57557dc55 add AutoRouterWithPrefix 2014-01-01 17:57:57 +08:00
astaxie
803d91c077 support modules design!
// the follow code is write in modules:
// GR:=NewGroupRouters()
// GR.AddRouter("/login",&UserController,"get:Login")
// GR.AddRouter("/logout",&UserController,"get:Logout")
// GR.AddRouter("/register",&UserController,"get:Reg")
// the follow code is write in app:
// import "github.com/beego/modules/auth"
// AddRouterGroup("/admin", auth.GR)
2013-12-31 23:43:15 +08:00
astaxie
62ee48dcbf Merge branch 'develop' of https://github.com/astaxie/beego into develop 2013-12-31 20:48:46 +08:00
astaxie
1e57587fe9 support Hijacker #428 2013-12-31 20:47:48 +08:00
slene
61c0b3e286 fix db locked 2013-12-31 09:55:29 +08:00
astaxie
383a04f4c2 move initmime from beego.Run to hookfunc 2013-12-31 00:34:47 +08:00
astaxie
eea272482b Merge pull request #425 from fuxiaohei/master
add comments in logs package.
2013-12-30 07:38:51 -08:00
FuXiaoHei
94ad13c846 add comments in logs package 2013-12-30 23:32:57 +08:00
slene
412a4a04de #384 2013-12-30 23:04:13 +08:00
astaxie
e0e8fa6e2a fix #413 2013-12-30 22:51:54 +08:00
astaxie
a1e29b0b75 Merge pull request #422 from pengfei-xue/devel
simplify condition test for trailing /
2013-12-30 04:58:50 -08:00
astaxie
984b0cbf31 1. :all param default expr change from (.+) to (.*)
2. add hookfunc to support appstart hook
2013-12-30 15:06:51 +08:00
傅小黑
3118c6c23f Merge commit '7a3d05ebf3fd36ea7e534de64ad38c23367ac97f' 2013-12-30 11:37:20 +08:00
Pengfei Xue
3a08eec1f9 simplify condition test for trailing / 2013-12-30 11:29:35 +08:00
astaxie
ecfd11adb4 fix typo healthcheck url 2013-12-29 11:01:19 +08:00
astaxie
95dc670eb4 fix #416 2013-12-28 23:06:20 +08:00
astaxie
7a3d05ebf3 when pattern is /admin while the url is /admin/ should return 200. fix #416 2013-12-28 23:04:45 +08:00
傅小黑
62f54cbbee fix typo error 2013-12-28 20:14:36 +08:00
astaxie
4d7f7ffa37 Merge pull request #418 from fuxiaohei/master
add comments for httplib package.
2013-12-27 16:52:29 -08:00
傅小黑
cb876268b5 add comments for httplib package. 2013-12-27 17:11:39 +08:00
astaxie
094f2fbab8 Merge pull request #415 from fuxiaohei/master
add comments for context package.
2013-12-26 07:40:19 -08:00
傅小黑
2d77c4dc49 fix code with no need line 2013-12-26 00:44:49 +08:00
傅小黑
f535916fae add comments for context package. 2013-12-25 20:13:38 +08:00
astaxie
673993fa2b Merge pull request #412 from fuxiaohei/master
add comment in config package.
2013-12-24 07:06:02 -08:00
傅小黑
6f3803ce8c Merge remote-tracking branch 'astaxie/master' 2013-12-24 21:59:37 +08:00
傅小黑
a1f6039d82 gofmt code 2013-12-24 21:59:00 +08:00
傅小黑
0183608a59 add comments for config package. 2013-12-24 21:57:33 +08:00
astaxie
d0e2c5c67a config ini module when set section is not exist will panic! 2013-12-24 21:57:15 +08:00
傅小黑
5b1afcdb5a add timeout description for file and memory cache. 2013-12-24 21:56:48 +08:00
astaxie
cfcfeb7b99 change version from 1.0.0 to 1.0.1 2013-12-24 21:35:20 +08:00
傅小黑
053e7a6aa6 Merge remote-tracking branch 'astaxie/master' 2013-12-24 21:09:17 +08:00
astaxie
62188a37c6 Merge branch 'master' of https://github.com/astaxie/beego 2013-12-24 15:27:23 +08:00
astaxie
0b659961ba clearly the router, If user set the third params, will not follow the RESTful method 2013-12-24 15:27:00 +08:00
astaxie
37aa2dc19f Merge pull request #409 from RickyLin/master
Added LayoutSections property to Controller
2013-12-23 23:21:42 -08:00
傅小黑
ba94479efd Merge remote-tracking branch 'astaxie/master' 2013-12-24 13:05:09 +08:00
Ricky Lin
4a3902432a Added LayoutSections property to Controller
users can define 0 or multipe sections in the Layout template file so
all kinds of content such as scripts, css can go to proper sections in
the generated html file.
2013-12-24 00:13:24 +08:00
astaxie
fc19f8f183 Merge pull request #408 from jinguoli/master
convert to unix eol
2013-12-23 05:16:14 -08:00
jinguoli
8c9320725b convert to unix eol 2013-12-23 11:46:11 +08:00
astaxie
0eaa58e0ca Merge pull request #406 from wangdx/patch-2
name → Name
2013-12-22 04:09:56 -08:00
dongxu
2add87b829 name → Name
typo
2013-12-22 17:57:45 +08:00
傅小黑
ba3a9bee4c Merge remote-tracking branch 'astaxie/master' 2013-12-22 16:25:08 +08:00
astaxie
5260a60ad2 Merge pull request #405 from wangdx/patch-1
RESTFul → RESTful
2013-12-21 23:58:20 -08:00
dongxu
eb5d11c01b Update README.md
RESTFul → RESTful
2013-12-22 15:56:15 +08:00
傅小黑
f96eec6dea fix a code broken when documenting 2013-12-22 15:31:49 +08:00
astaxie
e858f903a3 Merge pull request #404 from fuxiaohei/master
add comments in cache package
2013-12-21 23:28:43 -08:00
傅小黑
4037f952ec fix a code broken when documenting 2013-12-22 15:23:43 +08:00
傅小黑
6cb3f588c7 fix comments typo in beego package/ 2013-12-22 15:09:33 +08:00
傅小黑
8b0929b4bc add comments in cache package files. 2013-12-22 13:35:02 +08:00
slene
fc339fc3e0 orm detect mysql timezone #403 2013-12-21 21:00:29 +08:00
astaxie
2c868a9557 make datePatterns hide 2013-12-21 20:44:34 +08:00
astaxie
8ba6dbb9a0 Merge pull request #402 from fuxiaohei/master
add api comments in file memzipfile.go,reload.go,router.go,template.go and templatefunc.go
2013-12-21 03:55:10 -08:00
傅小黑
ff18ae2562 add api comments in file memzipfile.go,reload.go,router.go,template.go and templatefunc.go, fix spelling error GetInitListner as GetInitListener. 2013-12-21 13:19:24 +08:00
astaxie
57781d1001 when panic show the request url 2013-12-21 01:20:35 +08:00
astaxie
419c3fc772 remove contextBuffer fix #396 2013-12-21 00:34:59 +08:00
astaxie
2ad399db05 Merge pull request #400 from fuxiaohei/master
add api comments
2013-12-20 07:23:12 -08:00
傅小黑
eb9b958309 gofmt commented go file 2013-12-20 23:15:00 +08:00
傅小黑
ce332713c4 gofmt commented go files 2013-12-20 22:35:16 +08:00
astaxie
e18b9f0321 Merge pull request #399 from Max-Liu/master
repaired the wrong IP when using in localhost (Mac os x)
2013-12-20 06:19:23 -08:00
傅小黑
b459cf2347 add api comments in file config.go, controller.go, filter.go and flash.go 2013-12-20 21:16:26 +08:00
傅小黑
933e98e4f2 add api comments in file beego.go 2013-12-20 19:36:54 +08:00
傅小黑
3f3bf299a6 add api comments in file app.go 2013-12-20 19:20:13 +08:00
Max Lau
b08a4a86c1 repaired the wrong IP when using in localhost (Mac os x)
it returns “[“ when using beego in local host(Mac os x 10.9) , it
appears that Request.remoAddr returns “[::1]:****”
2013-12-20 18:56:02 +08:00
astaxie
3f0e55de56 reverse pull request 397, it not a bug. Just should this way 2013-12-20 13:20:09 +08:00
astaxie
235d2740c7 Merge pull request #397 from pengfei-xue/devel
fix routing bug
2013-12-19 21:06:54 -08:00
Pengfei Xue
00020139c5 fix routing bug 2013-12-20 11:38:29 +08:00
slene
7aa307bd24 fix: re-parse config in windows 2013-12-20 11:21:48 +08:00
astaxie
1c434dc6f4 Merge pull request #394 from fuxiaohei/master
add api comments in file admin.go
2013-12-19 07:51:22 -08:00
傅小黑
8cc8b022ee add api comments in file admin.go 2013-12-19 23:46:06 +08:00
astaxie
05e197ffff fix #391 2013-12-19 22:02:25 +08:00
astaxie
d718d9c8ee beego 1.0 release 2013-12-19 21:09:45 +08:00
astaxie
f752c98d81 Merge branch 'master' of https://github.com/astaxie/beego 2013-12-19 19:52:52 +08:00
astaxie
7c3d1d3402 fix type HasTemplateEXt to HasTemplateExt 2013-12-19 19:52:01 +08:00
slene
764bbd9897 #390 should use filepath.Dir instead of path.Dir for. 2013-12-19 19:04:57 +08:00
astaxie
67b9c63528 Merge pull request #390 from 1fei/master
更新logs的初始化部分
2013-12-19 02:54:37 -08:00
1fei
b87e122ac4 Update smtp.go 2013-12-19 18:16:06 +08:00
1fei
dcaff38cb9 Update file.go 2013-12-19 18:15:46 +08:00
1fei
b68c814c50 Update console.go
使用json直接初始化系统变量,代码更简单,并且便于后期扩展
2013-12-19 18:15:00 +08:00
1fei
9076ce7d17 Update conn.go
使用json直接初始化相关变量,代码更简单。如果把协议的首字母改大写会更简单,但不好改谢大的协议。
2013-12-19 18:13:10 +08:00
astaxie
c9ccb9cc71 Merge pull request #389 from 1fei/master
Update httplib.go
2013-12-19 01:10:08 -08:00
1fei
0269a66940 Update httplib.go
httplib针对的是客户端的http请求,所以应该用"Cookie",而不是"Set_Cookie"
2013-12-19 16:29:46 +08:00
astaxie
e481671814 _method also must support user defined router 2013-12-19 13:07:43 +08:00
astaxie
53b2a29b44 when method is POST then to parse form 2013-12-19 12:50:47 +08:00
astaxie
cb49be7815 fix router Put and Delete method when post method with _method 2013-12-19 12:47:54 +08:00
slene
68d4c2c0d8 fix: AppPath is wrong. Move BeeLogger to config.go init. 2013-12-19 12:22:30 +08:00
astaxie
de0113ae6a add comments & change channel from 100 to 1000 2013-12-19 00:43:29 +08:00
astaxie
7242bc862e improve main login performance 2013-12-18 23:48:43 +08:00
astaxie
bc0d4ac7cb set admin default to false. default the admin console is shut down. 2013-12-18 23:23:00 +08:00
astaxie
b346617dc1 context.output now need reponsewriter 2013-12-18 22:35:52 +08:00
astaxie
b8ed790858 recycling memory buffer in context 2013-12-18 22:33:21 +08:00
astaxie
48cefc6767 improve performance change reflect to interface 2013-12-18 21:32:25 +08:00
astaxie
079a41136e when call middle.Exception should set w.WriteHeader first 2013-12-18 21:00:45 +08:00
astaxie
e01fbd497c when call abort show the err:http: multiple response.WriteHeader calls 2013-12-18 20:53:23 +08:00
astaxie
9edf3143e1 fix autorouter params 2013-12-18 10:00:52 +08:00
slene
00065f2b08 fix mime bug !! 2013-12-18 00:05:04 +08:00
astaxie
0869df5588 delete GoToFunc & add GetControllerAndAction 2013-12-17 20:39:35 +08:00
slene
54c89c0d63 Merge branch 'master' of github.com:astaxie/beego 2013-12-17 16:46:56 +08:00
slene
1c52f6834a fix bug in postgres 2013-12-17 16:46:14 +08:00
astaxie
c3bc2bedc0 add methodName to fix #380 & arrangement the router 2013-12-17 11:19:18 +08:00
astaxie
7b27b7fed0 change SopRun to a variable 2013-12-17 08:53:20 +08:00
astaxie
3a996c132d Merge pull request #383 from pengfei-xue/devel
delete write body from context.Redirect
2013-12-16 16:22:28 -08:00
Pengfei Xue
65b9011bc1 delete write body from context.Redirect 2013-12-17 08:18:01 +08:00
astaxie
b9fdbdf7b5 use StopRun to terminate the execution 2013-12-16 23:22:15 +08:00
astaxie
436f9a7468 move session init before static 2013-12-16 22:56:35 +08:00
astaxie
f8708d01bf update abort & error show & sessionRelease in defer 2013-12-16 22:54:29 +08:00
astaxie
7fd18ba639 modify in the autorouter's Render #377 2013-12-16 11:46:54 +08:00
astaxie
55f638ac78 Merge pull request #377 from vadimi/master
Panic template execution errors to show error pages accordingly
2013-12-15 19:44:54 -08:00
vadimi
31f862c526 Panic template execution errors to show error pages accordingly 2013-12-15 13:17:27 -05:00
astaxie
505fca93c3 change version from 0.9.9 to 1.0.0 RC1 2013-12-15 21:54:57 +08:00
astaxie
849dbddc5a filterfunc name 2013-12-15 21:44:58 +08:00
astaxie
d24fbe8426 add tips for listconf 2013-12-15 21:33:44 +08:00
astaxie
f841b5962b Merge pull request #375 from pengfei-xue/devel
add do_filter func to reduce duplicated code
2013-12-15 05:25:46 -08:00
astaxie
f26c19052d add listconf fix #351 2013-12-15 21:22:50 +08:00
Pengfei Xue
72af5ce582 add do_filter func to reduce duplicated code 2013-12-15 21:02:28 +08:00
astaxie
aea3c68c98 add debug print func! fix #278 2013-12-15 20:32:32 +08:00
astaxie
8368360aec Merge pull request #372 from francoishill/master
Gzip support for static files, see https://github.com/smithfox/beego
2013-12-15 00:39:18 -08:00
astaxie
a5029cc4ca Merge pull request #370 from slene/master
fix set maxlifetime, close conn
2013-12-15 00:30:37 -08:00
Francois
9995168f9a Update router.go 2013-12-14 20:35:57 +02:00
Francois
02eacb8e95 Update config.go 2013-12-14 20:34:27 +02:00
Francois
2a4459b98b Create memzipfile.go 2013-12-14 20:33:12 +02:00
slene
d48b7e0101 #369 set maxlifetime, close conn 2013-12-14 23:33:24 +08:00
astaxie
495033b977 fix #366 2013-12-13 21:25:32 +08:00
astaxie
9c164408d3 Merge pull request #365 from yaofangou/master
add convertor for cache
2013-12-12 18:43:41 -08:00
mingqi.zhou
9f2327ee57 Merge remote-tracking branch 'astaxie.beego/master' 2013-12-13 10:07:21 +08:00
mingqi.zhou
68f2a5ddc7 add convertor for cache 2013-12-13 10:00:24 +08:00
astaxie
b1374b6a08 move safemap to utils & add many helpful slice function 2013-12-12 22:40:29 +08:00
astaxie
19119e99f7 move utils to utils libs & func move to templatefunc 2013-12-12 22:25:08 +08:00
astaxie
d603a6714d add more tips for admin 2013-12-12 21:51:25 +08:00
astaxie
c8724d40d2 Merge pull request #362 from kyle-wang/master
rename some function name under /utils
2013-12-12 05:51:06 -08:00
kyle
9ff937591b rename some function name under /utils
change the function name to common english word
2013-12-12 19:30:44 +08:00
astaxie
3c92cce9f4 update httplib to support setcookie 2013-12-12 15:23:17 +08:00
astaxie
fd78ea5c4a set cookie to zero 2013-12-12 10:43:13 +08:00
astaxie
c3c49e9172 Merge pull request #360 from shxsun/master
add some func to beego/utils
2013-12-11 18:08:04 -08:00
skyblue
a43a1be0b4 add some useful func 2013-12-11 22:18:45 +08:00
slene
98d1f79ca4 Merge pull request #359 from wangkechun/patch-1
Update README.md
2013-12-11 04:52:44 -08:00
e纯
c3fcc72969 Update README.md 2013-12-11 20:50:41 +08:00
astaxie
efd285a6c4 update httplib support https 2013-12-10 22:01:50 +08:00
astaxie
3a0b2e3b95 beego config module json support get data like key:🔑:key 2013-12-10 18:09:58 +08:00
astaxie
34ba7a8e6c update file cache 2013-12-10 14:10:22 +08:00
astaxie
b733b98408 for init if doesn't have app.conf will not panic 2013-12-10 00:17:22 +08:00
astaxie
b97d9896a4 update config to change section . to :: 2013-12-09 23:54:35 +08:00
skyblue
52ebaece73 add other utils 2013-12-09 16:01:24 +08:00
astaxie
690ecb8168 Merge pull request #353 from shxsun/master
initial utils dir
2013-12-08 21:45:11 -08:00
skyblue
830ccb6660 initial utils dir 2013-12-09 13:30:19 +08:00
astaxie
4fa625dea6 default app HttpAddr should none 2013-12-07 17:22:57 +08:00
astaxie
ce8a1be8d9 change syscall package to os.Kill 2013-12-07 16:52:39 +08:00
astaxie
1ea18adce8 add default mime type to fix #341 2013-12-07 15:16:32 +08:00
astaxie
35d15b8977 fix #350 2013-12-07 14:47:20 +08:00
astaxie
48ad0202bf update some tips 2013-12-07 13:26:28 +08:00
astaxie
2220968a01 Merge pull request #347 from odiel/master
Adding template functions to generate JS and CSS tags
2013-12-06 08:08:22 -08:00
odiel
1611476288 Update template.go
Adding assets_js, assets_css template functions
2013-12-06 10:36:56 -05:00
odiel
0bdd400fe7 Update utils.go
Adding Assets functions for the template, to generate HTML tags for JS and CSS
2013-12-06 10:36:12 -05:00
astaxie
8cf34fce98 Merge pull request #344 from vadimi/master
Improve unhandled error handling in prod mode
2013-12-05 21:55:37 -08:00
vadimi
d79977977d Improve unhandled error handling in prod mode 2013-12-06 00:47:34 -05:00
astaxie
de70732cd4 typo 2013-12-06 13:46:14 +08:00
vadimi
32d9d13dc7 Restore SimpleServerError method 2013-12-06 00:44:54 -05:00
astaxie
7125bd8faa support json comments 2013-12-06 13:43:08 +08:00
astaxie
7196d6ede3 Revert "Improve unhandled error handling in prod mode"
This reverts commit c2079276eb.
2013-12-06 13:37:36 +08:00
astaxie
54ef08c039 Merge pull request #342 from vadimi/master
Improve unhandled error handling in prod mode
2013-12-05 21:31:18 -08:00
vadimi
c2079276eb Improve unhandled error handling in prod mode 2013-12-05 20:57:02 -05:00
astaxie
b6bf712195 Merge pull request #338 from FightingMan/master
miswrite a type of word
2013-12-05 03:54:21 -08:00
FightingMan
27a02082a3 miswrite a type of word 2013-12-05 19:20:08 +08:00
astaxie
39b2e07dc8 Merge pull request #336 from vadimi/master
Fixed some typos
2013-12-04 19:36:52 -08:00
vadimi
12a37f71be Fixed some typos 2013-12-04 22:27:29 -05:00
astaxie
9f3058caad Merge pull request #335 from pengfei-xue/devel
beeapi example is broken
2013-12-04 19:14:51 -08:00
Pengfei Xue
4181ea8620 beeapi example is broken 2013-12-05 10:29:04 +08:00
astaxie
cfc604b53d Merge pull request #333 from pengfei-xue/devel
panic if parse failed
2013-12-04 17:54:36 -08:00
Pengfei Xue
420e816bed panic if parse failed 2013-12-04 23:53:36 +08:00
astaxie
fb6312a303 reverse from pull 330 2013-12-04 17:03:49 +08:00
astaxie
3c91360d72 dictinct system pkg and third pkg 2013-12-03 21:37:39 +08:00
astaxie
983f20642c Merge pull request #330 from pengfei-xue/devel
panic if parse config failed
2013-12-03 04:33:08 -08:00
Pengfei Xue
12ade02f2d panic if parse config failed 2013-12-03 19:56:30 +08:00
astaxie
ec745693dc Merge pull request #327 from pengfei-xue/devel
remove duplicated config initialization
2013-12-03 00:57:27 -08:00
Pengfei Xue
9cac7504c9 fixup! fix typo, use camel notation for all keys 2013-12-03 16:37:39 +08:00
Pengfei Xue
75d09d138a fix typo, use camel notation for all keys 2013-12-03 13:23:33 +08:00
Pengfei Xue
07312e240c remove duplicated config initialization 2013-12-03 13:15:32 +08:00
astaxie
9c4414f995 Merge pull request #323 from pengfei-xue/devel
case insensitive for section and key for ini config
2013-11-28 19:29:37 -08:00
Pengfei Xue
8e7fe8bb66 case insensitive for section and key for ini config 2013-11-29 10:17:35 +08:00
astaxie
0ba36763f5 Merge pull request #322 from pengfei-xue/devel
there is no need to check if b.params is nil
2013-11-27 23:05:05 -08:00
Pengfei Xue
3fce78c7cd there is no need to check if b.params is nil 2013-11-28 13:52:24 +08:00
astaxie
a83a92cdab Merge pull request #321 from smallfish/master
update logic for check ini comments
2013-11-27 21:10:13 -08:00
smallfish
23ff7af0b7 update logic for check ini comments 2013-11-28 11:56:13 +08:00
astaxie
9cc2e7237b add httplib readme 2013-11-28 11:26:17 +08:00
astaxie
63b82c438d support section
if iniconf.String("demo.key1") != "asta" {
+		t.Fatal("get demo.key1 error")
+	}
+	if iniconf.String("demo.key2") != "xie" {
+		t.Fatal("get demo.key2 error")
+	}
2013-11-27 23:55:26 +08:00
astaxie
ba5e393e99 add flush & read all chan data 2013-11-27 17:50:10 +08:00
slene
690d77e985 orm test add extra custom JsonField 2013-11-26 21:34:40 +08:00
slene
bcc8f60677 orm add test about CustomField 2013-11-26 18:32:12 +08:00
astaxie
6f93b2bcbe fix _ "github.com/go-sql-driver/mysql" 2013-11-26 17:16:35 +08:00
astaxie
70dc9d7e14 update docs 2013-11-26 17:14:27 +08:00
astaxie
01d87591e4 session & orm register called twice for driver mysql 2013-11-26 17:12:25 +08:00
astaxie
ff1b8588e0 #313 2013-11-26 17:09:23 +08:00
astaxie
54fb49ed95 fix #315 2013-11-26 16:47:50 +08:00
astaxie
fbd1c3f8b0 Merge pull request #318 from pengfei-xue/devel
add server host:port info when starting app
2013-11-25 23:56:45 -08:00
Pengfei Xue
e823b6ea95 add server host:port info when starting app 2013-11-26 15:30:59 +08:00
astaxie
b16ef12ac0 fix test 2013-11-26 14:13:23 +08:00
astaxie
f9e732b5ce fix param to params 2013-11-26 11:16:22 +08:00
astaxie
ae2e25f4c2 fix #316 2013-11-26 11:05:49 +08:00
astaxie
7b405e9af7 fix type 2013-11-26 11:05:12 +08:00
astaxie
e09e642a83 Merge pull request #317 from pengfei-xue/master
beego.Context.Abort return immediately
2013-11-25 18:30:38 -08:00
Pengfei Xue
76c0636125 beego.Context.Abort return immediately
* add common 4XX/5XX HTTP exceptions
2013-11-26 08:46:46 +08:00
astaxie
c7a0298546 Merge pull request #314 from shavac/master
add function InsertFilter to replace AddFilter by using int const to determine filter position
2013-11-25 00:56:29 -08:00
knightmare
b4fb657efd eliminated improper comments 2013-11-25 16:15:48 +08:00
knightmare
8c3b936c60 replace filterPos to pos 2013-11-25 16:04:02 +08:00
knightmare
47fc32ba47 add func InsertFilter(pattern string, pos int, filter FilterFunc) *App to replace AddFilter
pos can be const:
    BeforeRouter = iota
    AfterStatic
    BeforeExec
    AfterExec
    FinishRouter
2013-11-25 15:59:40 +08:00
slene
e5904443d9 fix #302 2013-11-24 19:29:48 +08:00
slene
4ee6cc3022 Merge pull request #312 from bronze1man/pr-orm-querytable-nil-ptr-struct
[orm] QueryTable with nil ptr struct
2013-11-24 01:08:00 -08:00
bronze1man
ceb4aa9e25 [orm] QueryTable with nil ptr struct 2013-11-24 14:26:32 +08:00
astaxie
a0dff9148a change third repo from other to beego 2013-11-21 22:19:19 +08:00
astaxie
c94189668f Merge pull request #306 from pengfei-xue/patch-1
http.ResponseWriter doesn't implement  WriteCloser interface
2013-11-21 05:31:00 -08:00
Pengfei Xue
0122addd00 http.ResponseWriter doesn't implement WriteCloser interface
The removed code will never be executed, remove it
2013-11-21 18:39:16 +08:00
astaxie
f52faf63f7 fix #304 2013-11-21 15:59:16 +08:00
astaxie
b9fb88f537 add test for task 2013-11-20 23:53:54 +08:00
astaxie
54185df46e change admin to toolbox & support task 2013-11-20 21:18:00 +08:00
slene
16352579f3 #294 2013-11-18 13:21:19 +08:00
astaxie
c5eabcf469 add file cache, thanks to gouki 2013-11-18 11:22:06 +08:00
astaxie
b5b53b3849 add more feture in admin
1,增加QPS的限制
2,增加任务
3,增加healthcheck
2013-11-17 23:10:21 +08:00
astaxie
ea513002c5 admin filter finish to all router include static file
so if your web is need auth or release the resoure you can writer the
finish filter
2013-11-15 21:51:36 +08:00
astaxie
9776bb8a03 improve the admin module 2013-11-15 21:45:51 +08:00
astaxie
969464f8ad delete back info 2013-11-15 18:25:36 +08:00
astaxie
a9b6a0b81a improve the output fomate 2013-11-15 18:21:26 +08:00
astaxie
2758c6da14 UrlMap fix to StatisticsMap 2013-11-15 18:12:36 +08:00
astaxie
097bcb3b5b Improve monitoring management module 2013-11-15 18:08:53 +08:00
astaxie
18335194bc fix runrouter is nil 2013-11-13 21:37:17 +08:00
astaxie
6c13bdde25 support profile & statistics in another port 2013-11-13 21:11:09 +08:00
astaxie
a981dab536 fix #286
the process exit and the channel info can't flush to console
2013-11-13 21:11:08 +08:00
astaxie
6632c21d62 Merge pull request #287 from francoishill/patch-1
Update template.go
2013-11-12 16:15:53 -08:00
Francois
a5b5ae899c Update template.go
We can specify "TemplateLeft" and "TemplateRight" but they did not work as these two changes are required.
2013-11-12 20:22:42 +02:00
astaxie
ac6108a87d add more json test info 2013-11-11 21:25:03 +08:00
astaxie
2f75445520 when runmode is dev it will show warning ingo
if have a attack url, the info is
2013-11-10 23:42:07 +08:00
astaxie
43057a2fcb fix #284 2013-11-10 23:26:28 +08:00
astaxie
9446563e5b add util func to get the url fix #282
UrlFor(endpoint string, values ...string) string
2013-11-10 23:05:07 +08:00
slene
167ad203cb orm #276 2013-11-08 22:19:01 +08:00
astaxie
558738ade8 JSON CallBack类型的链接,这类出现在几乎各大Web 2.0网站中。修补这类安全问题很简单,只要在目标网页开头部分强制加一个空格即可,这样BOM头就无效了。 2013-11-08 20:54:06 +08:00
astaxie
0fb7d4babb add UrlFor function but still improve 2013-11-08 18:20:08 +08:00
astaxie
91c7635d0e fix #283 2013-11-08 18:00:07 +08:00
astaxie
2a81595c3e fix #280 2013-11-08 17:23:56 +08:00
astaxie
9e4d886a6c filter http method fix #279 2013-11-07 22:10:54 +08:00
slene
b644665952 orm set relation column name #259 2013-11-06 22:05:10 +08:00
slene
9492e4131b support reverse m2m relation 2013-11-06 21:08:12 +08:00
astaxie
2abda0954b fix #277 2013-11-06 16:51:33 +08:00
astaxie
dbf6ca2b4c fix #277 2013-11-06 16:12:10 +08:00
astaxie
bca6a33325 fix #140 2013-11-05 23:41:01 +08:00
astaxie
c8f86652a3 fix #248 2013-11-05 22:23:48 +08:00
astaxie
076bd0b440 #254 add controller func SessionRegenerateID 2013-11-05 22:07:09 +08:00
astaxie
a443a798e3 fix #254 2013-11-05 21:59:35 +08:00
astaxie
23d79b8b05 #254 add SessionHashFunc SessionHashKey SessionCookieLifeTime 2013-11-03 21:41:07 +08:00
astaxie
9ccdb31003 fix #236 2013-11-02 23:54:17 +08:00
astaxie
0adb864219 fix #270
同时支持全部小写和驼峰写法
2013-11-02 22:45:08 +08:00
slene
d39954c935 Merge branch 'master' of github.com:astaxie/beego 2013-11-02 00:52:05 +08:00
slene
89c03870c8 orm fix sqlite3 time convert 2013-11-02 00:51:53 +08:00
slene
1d44018128 orm fix for support custom field 2013-11-02 00:50:08 +08:00
astaxie
d835b0c80f fix #235 2013-11-02 00:16:10 +08:00
astaxie
bc862e526d Merge pull request #271 from shavac/master
minor fix,if path does not include ':', beego will crash of "index out of range"
2013-11-01 04:57:07 -07:00
slene
a4df6e403c fix #265 2013-11-01 18:32:03 +08:00
knightmare shava
290a9d184d minor fix,if path does not include : 2013-11-01 12:34:16 +08:00
astaxie
00abdcd0a1 Merge pull request #269 from shavac/master
improve StaticDir config file parser.
2013-10-31 20:02:53 -07:00
knightmare shava
73a2081ae7 improve StaticDir config file parser.New style is like "css:static/css js:static/js" 2013-11-01 08:23:57 +08:00
astaxie
c6167ef184 fix #260 2013-10-30 23:02:53 +08:00
astaxie
4bcbc588fc fix #260 2013-10-29 23:11:23 +08:00
astaxie
5f4fe6d868 fix #260 2013-10-29 23:05:48 +08:00
slene
7131dec3af add go1.2 template funcs eq, ge, gt, le, lt, ne to beego 2013-10-29 22:35:04 +08:00
astaxie
0ddde6fa9f fix #252 2013-10-29 22:03:43 +08:00
astaxie
5d54acba30 fix isajax 2013-10-29 15:45:45 +08:00
astaxie
c1b2e1d0ca fix #238 2013-10-28 23:30:16 +08:00
astaxie
9fc4cd8958 #238 add GetProvider 2013-10-28 23:25:30 +08:00
astaxie
742c432fd1 fix #252 2013-10-28 23:09:45 +08:00
astaxie
3ac5eec301 fix #253 2013-10-28 22:38:50 +08:00
astaxie
060631e952 fix #241#192 2013-10-28 22:19:37 +08:00
astaxie
57165f2fb5 fix #247 2013-10-28 21:44:07 +08:00
astaxie
5940fd4bbd fix build error 2013-10-21 22:08:41 +08:00
astaxie
13180c5a17 fix #249 2013-10-21 22:06:30 +08:00
slene
6ea8dd5999 fix #255 2013-10-18 17:37:34 +08:00
astaxie
2795ac6e6b update panic 2013-10-17 21:14:00 +08:00
slene
83e6079ff7 fix MinSize / MaxSize / Length should use Rune Count 2013-10-16 22:49:06 +08:00
slene
d043ebcdd3 orm support complete m2m operation api / auto load related api 2013-10-14 22:31:35 +08:00
astaxie
e11c40eee4 fix #244 2013-10-12 16:56:42 +08:00
slene
5d55ca19be orm add Exist func 2013-10-12 06:57:14 +08:00
slene
3f91dfbca3 Merge branch 'master' of github.com:astaxie/beego 2013-10-09 20:29:25 +08:00
slene
bf3830b6f0 orm add atomic set value 2013-10-09 20:28:54 +08:00
slene
278f8eb13e add ValidFormer interface, can custom valid 2013-10-09 20:26:23 +08:00
slene
658a671b79 all panic use Error 2013-10-09 11:37:16 +08:00
astaxie
bf836a2126 fix #233
thanks for the good suggestion
2013-09-30 11:30:22 +08:00
astaxie
35a136bcee fix #232 2013-09-29 15:38:28 +08:00
astaxie
aaf1490ff5 fix router 2013-09-28 23:37:05 +08:00
astaxie
a62ed10ab3 add supoort AppController
http://play.golang.org/p/MZptHZeYUx
2013-09-28 23:30:36 +08:00
astaxie
e79d756d06 #230 2013-09-28 22:23:00 +08:00
astaxie
904b37032c Merge pull request #227 from sdjc/patch-4
Update config.go
2013-09-28 07:09:59 -07:00
astaxie
8a37c30f35 fix #226 2013-09-28 21:45:52 +08:00
astaxie
c4edc13413 fix #230 2013-09-28 21:36:36 +08:00
sdjc
9ddbab59bb Update config.go 2013-09-27 08:37:17 +08:00
astaxie
1eb87c5c59 fix #225 2013-09-26 22:31:39 +08:00
astaxie
fb1439dfb9 Merge pull request #224 from smithfox/patch-1
fix #217
2013-09-26 06:09:03 -07:00
astaxie
d393c329c3 protect parts's len 2013-09-26 21:06:37 +08:00
smithfox
bed0fe2218 fix #217 2013-09-26 18:33:01 +08:00
astaxie
02c2e16253 Strengthens the session's function 2013-09-26 18:07:00 +08:00
astaxie
59a67720b4 xsrf's defaut time set to 0 & fix ts not use 2013-09-25 23:07:54 +08:00
astaxie
93e1206d60 xsrf change to randstr and cookie set to security cookie 2013-09-25 23:05:53 +08:00
astaxie
2249d745d9 session support secure set 2013-09-25 23:05:53 +08:00
astaxie
f9ed74a9b2 Merge pull request #219 from markstory/readme-fixes
Fix typos in the readme file.
2013-09-25 06:42:15 -07:00
Mark Story
65ec2db4e8 Fix typos in the readme file. 2013-09-25 09:41:11 -04:00
slene
001e33f310 fix #213 2013-09-22 19:20:40 +08:00
slene
09aca2528a orm RegisterDataBase remove default maxIdle/maxConn 2013-09-22 17:51:37 +08:00
astaxie
beecc5072e fix #209 2013-09-22 14:35:01 +08:00
astaxie
797bd98269 fix #210 2013-09-22 14:32:18 +08:00
astaxie
4a3d32dc1f support auto get session from input fix #211 2013-09-22 11:43:22 +08:00
astaxie
048be29fcd add w.started fix #208 2013-09-22 11:17:18 +08:00
astaxie
4ce584c5a6 fix #201 2013-09-22 11:12:37 +08:00
astaxie
3c1d23bc62 #207 2013-09-19 23:40:55 +08:00
astaxie
95307a3d78 miss filter * 2013-09-19 23:14:47 +08:00
astaxie
a85d91b4bd fix #206 2013-09-19 23:04:05 +08:00
slene
a616087cde orm now can specify engine for mysql. add api SetMaxIdleConns/SetMaxOpenConns(go 1.2) 2013-09-16 09:50:32 +08:00
slene
198d6320dd fix xsrf cookie path should use root 2013-09-13 22:42:15 +08:00
slene
1596aa7a34 orm support use any numeric type set QuerySeter.Limit value 2013-09-13 18:06:44 +08:00
slene
8e8d39d3cb fix memory cache Put method should set value when key exist. 2013-09-13 18:04:22 +08:00
astaxie
42958ddd41 update version from 0.9.0 to 0.9.9 2013-09-13 17:45:26 +08:00
astaxie
0476da503e improve template 2013-09-13 17:41:31 +08:00
astaxie
943fe971f1 support template 2013-09-13 13:57:40 +08:00
astaxie
9d84969bf6 fix #153
已经支持了任意定义变量的路由形式,具体的使用请参考:

func TestManyRoute(t *testing.T) {

	r, _ := http.NewRequest("GET", "/beego32-12.html", nil)
	w := httptest.NewRecorder()

	handler := NewControllerRegistor()
	handler.Add("/beego:id([0-9]+)-:page([0-9]+).html", &TestController{})
	handler.ServeHTTP(w, r)

	id := r.URL.Query().Get(":id")
	page := r.URL.Query().Get(":page")

	if id != "32" {
		t.Errorf("url param set to [%s]; want [%s]", id, "32")
	}
	if page != "12" {
		t.Errorf("url param set to [%s]; want [%s]", page, "12")
	}
}
2013-09-13 11:22:14 +08:00
slene
3745bb7279 orm.Read support specify condition fields, orm.Update and QuerySeter All/One support omit fields. 2013-09-12 19:04:39 +08:00
astaxie
55fe3ba52f update tempalte's regexp 2013-09-12 18:20:29 +08:00
astaxie
de2dd6e070 update template's testcase 2013-09-12 17:32:11 +08:00
astaxie
ffb347a2bb support nest template 2013-09-12 17:20:32 +08:00
astaxie
19862725f7 support template 2013-09-12 15:24:08 +08:00
astaxie
f502f84423 fix #189 2013-09-12 13:44:24 +08:00
slene
e788fb7239 add an DateParse function, parse datestring to time.Time use php date format 2013-09-11 23:47:01 +08:00
astaxie
72f5961dd8 delete docs move to github.com/beego/beedoc 2013-09-11 18:04:10 +08:00
astaxie
9f6b803a10 update middleware & beego's error 2013-09-11 17:00:39 +08:00
astaxie
0da2059f79 update info 2013-09-11 16:31:18 +08:00
astaxie
e904d26e08 modify middleware 2013-09-11 16:23:41 +08:00
astaxie
1ff0a31d3f add router test 2013-09-11 15:49:12 +08:00
astaxie
e7f08946d1 improve the performance 2013-09-11 15:16:09 +08:00
slene
ea9c2cebfd validation add more info to ValidationError, and put all messages tmpl to a map 2013-09-10 21:51:25 +08:00
astaxie
02a03cec33 add logs readme 2013-09-10 18:44:29 +08:00
astaxie
31fbd52462 add chat example 2013-09-10 18:38:40 +08:00
astaxie
a88750d2b3 support websocket 2013-09-10 17:56:06 +08:00
astaxie
da91565354 add iswebsocket method 2013-09-10 17:02:56 +08:00
astaxie
44f5c208b6 update example 2013-09-10 15:08:32 +08:00
astaxie
83e26fdc9b fix config bug 2013-09-10 14:47:48 +08:00
astaxie
4a329db792 Merge pull request #187 from Unknwon/master
compatiable for old version
2013-09-09 16:47:23 -07:00
Unknown
1f8022d4ad compatiable for old version 2013-09-09 16:43:48 -04:00
astaxie
63da329468 go on modify api 2013-09-10 00:17:49 +08:00
astaxie
acadea6afa update xml 2013-09-10 00:02:22 +08:00
astaxie
bd61dd9ffc change a log about new version 2013-09-10 00:00:18 +08:00
astaxie
5b9ae54441 update input 2013-09-10 00:00:17 +08:00
slene
41dd6e580d orm 1. complete QueryRow/QueryRows api 2. QuerySeter.All support *[]Type and *[]*Type 2013-09-09 22:33:41 +08:00
slene
22d2de9fc7 orm fix 1. support Limit when use QuerySeter.One 2. return Local time 2013-09-06 19:03:47 +08:00
slene
6064a7ab2a orm RawSeter readValues set nil when get NULL 2013-08-30 12:38:32 +08:00
slene
8f5ca303b5 orm fix when use uint as pk 2013-08-30 12:32:05 +08:00
astaxie
dc8f932009 update doc's link 2013-08-28 17:09:01 +08:00
astaxie
4922237847 sleep some time for send mail 2013-08-28 15:55:34 +08:00
astaxie
2424618163 delete default console & add bench test 2013-08-28 15:48:48 +08:00
astaxie
b96f7e2ef2 Merge pull request #174 from Xelom/FixBra
Changed ObejctController to ObjectController in beeapi
2013-08-27 18:54:52 -07:00
Arıl Bozoluk
cde38fbe1a Changed ObejctController to ObjectController 2013-08-27 20:05:35 +03:00
Arıl Bozoluk
56a1603e1f Changed ObejctController to ObjectController 2013-08-27 20:05:15 +03:00
astaxie
f92973794e finish logs module 2013-08-27 23:49:04 +08:00
slene
49bbca0ce3 orm Improve syncdb 2013-08-27 12:33:27 +08:00
slene
6686d9235c orm fix create index 2013-08-25 13:50:50 +08:00
slene
7c72b2dca7 orm fix syncdb 2013-08-25 11:35:12 +08:00
slene
4c061feddf orm support custom multi unique / index 2013-08-22 21:19:58 +08:00
slene
02d2990576 orm all docs wiil update to beego.me 2013-08-22 18:35:35 +08:00
slene
94f7ba8bdf orm add uint uint32 uint64 auto increment support 2013-08-22 18:35:26 +08:00
fanngyuan
7d7c9825e9 change to asta 2013-08-22 14:27:23 +08:00
astaxie
dee542df42 fix yaml 2013-08-22 13:46:22 +08:00
astaxie
f2b4c29f83 Merge pull request #168 from fanngyuan/master
添加用于测试的request,后面我会在bee工具里添加一个单元测试的例子。
2013-08-21 21:05:39 -07:00
astaxie
28652c5d21 Merge pull request #167 from zxcvdavid/patch-1
file name fixed
2013-08-21 21:05:07 -07:00
fanngyuan
b104bfeb93 remove comment 2013-08-22 11:05:54 +08:00
Demon
8af4ba8980 file name fixed
file name fixed :P
2013-08-22 09:15:45 +08:00
astaxie
87f8fb0750 finish config module support ini/json/xml/yaml 2013-08-22 00:07:33 +08:00
fanngyuan
eaffabf388 add client 2013-08-21 22:47:58 +08:00
astaxie
ac8853dfd3 move from beehttp to context 2013-08-21 17:59:31 +08:00
astaxie
d2be74a4f2 add beehttp module 2013-08-21 13:24:44 +08:00
astaxie
17a99cfa81 maybe can't delete cookie error in same browser 2013-08-21 11:31:32 +08:00
astaxie
fd677c45aa fixed 2013-08-20 14:20:38 +08:00
astaxie
769735c207 fix #166 2013-08-20 12:04:50 +08:00
slene
b114f258d6 orm update docs 2013-08-19 22:37:53 +08:00
slene
c38abf35da orm support auto create db 2013-08-19 22:37:39 +08:00
astaxie
1fedaf21ec jsonp set header to javascript 2013-08-19 21:34:34 +08:00
astaxie
0b74db64eb fix typo for templateLeft 2013-08-19 13:02:18 +08:00
astaxie
f2222ba3c6 support fastcgi 2013-08-19 11:23:53 +08:00
astaxie
3cb8a96041 support unix socket fix #151
You can set
HttpAddr="/tmp/beego.sock"
HttpPort=0
2013-08-19 11:21:02 +08:00
astaxie
4f538e7fd2 fix #163
you can set the delimiter like this

beego.TemplateLeft="{#"
beego.TemplateRight="#}"

or can set the config file like app.ini

templateleft={#
templateright=#}
2013-08-19 10:41:09 +08:00
astaxie
e02f9a9931 fix #161 2013-08-19 10:26:16 +08:00
slene
aecf4af7f2 orm update docs 2013-08-17 07:41:22 +08:00
slene
618cbf1e66 orm string type default will use varchar(255) 2013-08-16 22:24:10 +08:00
slene
c81bbf9801 orm now use a filed named Id as default auto primary key, you can ignore orm:"auto" setting 2013-08-16 21:57:39 +08:00
slene
f02b286ad4 orm make offset simple, can use any numeric type 2013-08-16 20:01:18 +08:00
astaxie
0372b817d1 ServeJson ServeJsonp ServeXml and choice 2013-08-16 15:49:16 +08:00
astaxie
a3363b0605 json change from Indent to none 2013-08-15 22:27:26 +08:00
astaxie
51e625debf Merge pull request #156 from benlovell/spelling
Fix some minor spelling mistakes and typos
2013-08-14 00:17:35 -07:00
benlovell
1977d87d55 Merge branch 'master' of https://github.com/astaxie/beego into spelling 2013-08-14 09:07:51 +02:00
benlovell
9cbefacf52 Fixes some minor spelling mistakes and typos 2013-08-14 09:06:40 +02:00
309 changed files with 45965 additions and 10727 deletions

17
.github/ISSUE_TEMPLATE vendored Normal file
View File

@@ -0,0 +1,17 @@
Please answer these questions before submitting your issue. Thanks!
1. What version of Go and beego are you using (`bee version`)?
2. What operating system and processor architecture are you using (`go env`)?
3. What did you do?
If possible, provide a recipe for reproducing the error.
A complete runnable program is good.
4. What did you expect to see?
5. What did you see instead?

5
.gitignore vendored
View File

@@ -1 +1,6 @@
.idea
.vscode
.DS_Store .DS_Store
*.swp
*.swo
beego.iml

73
.travis.yml Normal file
View File

@@ -0,0 +1,73 @@
language: go
go:
- "1.13.x"
services:
- redis-server
- mysql
- postgresql
- memcached
env:
global:
- GO_REPO_FULLNAME="github.com/astaxie/beego"
matrix:
- ORM_DRIVER=sqlite3 ORM_SOURCE=$TRAVIS_BUILD_DIR/orm_test.db
- ORM_DRIVER=postgres ORM_SOURCE="user=postgres dbname=orm_test sslmode=disable"
before_install:
# link the local repo with ${GOPATH}/src/<namespace>/<repo>
- GO_REPO_NAMESPACE=${GO_REPO_FULLNAME%/*}
# relies on GOPATH to contain only one directory...
- mkdir -p ${GOPATH}/src/${GO_REPO_NAMESPACE}
- ln -sv ${TRAVIS_BUILD_DIR} ${GOPATH}/src/${GO_REPO_FULLNAME}
- cd ${GOPATH}/src/${GO_REPO_FULLNAME}
# get and build ssdb
- git clone git://github.com/ideawu/ssdb.git
- cd ssdb
- make
- cd ..
install:
- go get github.com/lib/pq
- go get github.com/go-sql-driver/mysql
- go get github.com/mattn/go-sqlite3
- go get github.com/bradfitz/gomemcache/memcache
- go get github.com/gomodule/redigo/redis
- go get github.com/beego/x2j
- go get github.com/couchbase/go-couchbase
- go get github.com/beego/goyaml2
- go get gopkg.in/yaml.v2
- go get github.com/belogik/goes
- go get github.com/ledisdb/ledisdb
- go get github.com/ssdb/gossdb/ssdb
- go get github.com/cloudflare/golz4
- go get github.com/gogo/protobuf/proto
- go get github.com/Knetic/govaluate
- go get github.com/casbin/casbin
- go get github.com/elazarl/go-bindata-assetfs
- go get github.com/OwnLocal/goes
- go get github.com/shiena/ansicolor
- go get -u honnef.co/go/tools/cmd/staticcheck
- go get -u github.com/mdempsky/unconvert
- go get -u github.com/gordonklaus/ineffassign
- go get -u golang.org/x/lint/golint
- go get -u github.com/go-redis/redis
before_script:
- psql --version
- sh -c "if [ '$ORM_DRIVER' = 'postgres' ]; then psql -c 'create database orm_test;' -U postgres; fi"
- sh -c "if [ '$ORM_DRIVER' = 'mysql' ]; then mysql -u root -e 'create database orm_test;'; fi"
- sh -c "if [ '$ORM_DRIVER' = 'sqlite' ]; then touch $TRAVIS_BUILD_DIR/orm_test.db; fi"
- sh -c "go get github.com/golang/lint/golint; golint ./...;"
- sh -c "go list ./... | grep -v vendor | xargs go vet -v"
- mkdir -p res/var
- ./ssdb/ssdb-server ./ssdb/ssdb.conf -d
after_script:
- killall -w ssdb-server
- rm -rf ./res/var/*
script:
- go test -v ./...
- staticcheck -show-ignored -checks "-ST1017,-U1000,-ST1005,-S1034,-S1012,-SA4006,-SA6005,-SA1019,-SA1024"
- unconvert $(go list ./... | grep -v /vendor/)
- ineffassign .
- find . ! \( -path './vendor' -prune \) -type f -name '*.go' -print0 | xargs -0 gofmt -l -s
- golint ./...
addons:
postgresql: "9.6"

52
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,52 @@
# Contributing to beego
beego is an open source project.
It is the work of hundreds of contributors. We appreciate your help!
Here are instructions to get you started. They are probably not perfect,
please let us know if anything feels wrong or incomplete.
## Contribution guidelines
### Pull requests
First of all. beego follow the gitflow. So please send you pull request
to **develop** branch. We will close the pull request to master branch.
We are always happy to receive pull requests, and do our best to
review them as fast as possible. Not sure if that typo is worth a pull
request? Do it! We will appreciate it.
If your pull request is not accepted on the first try, don't be
discouraged! Sometimes we can make a mistake, please do more explaining
for us. We will appreciate it.
We're trying very hard to keep beego simple and fast. We don't want it
to do everything for everybody. This means that we might decide against
incorporating a new feature. But we will give you some advice on how to
do it in other way.
### Create issues
Any significant improvement should be documented as [a GitHub
issue](https://github.com/astaxie/beego/issues) before anybody
starts working on it.
Also when filing an issue, make sure to answer these five questions:
- What version of beego are you using (bee version)?
- What operating system and processor architecture are you using?
- What did you do?
- What did you expect to see?
- What did you see instead?
### but check existing issues and docs first!
Please take a moment to check that an issue doesn't already exist
documenting your bug report or improvement proposal. If it does, it
never hurts to add a quick "+1" or "I have this problem too". This will
help prioritize the most common problems and requests.
Also if you don't know how to use it. please make sure you have read though
the docs in http://beego.me/docs

13
LICENSE Normal file
View File

@@ -0,0 +1,13 @@
Copyright 2014 astaxie
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.

View File

@@ -1,43 +1,73 @@
## beego # Beego [![Build Status](https://travis-ci.org/astaxie/beego.svg?branch=master)](https://travis-ci.org/astaxie/beego) [![GoDoc](http://godoc.org/github.com/astaxie/beego?status.svg)](http://godoc.org/github.com/astaxie/beego) [![Foundation](https://img.shields.io/badge/Golang-Foundation-green.svg)](http://golangfoundation.org) [![Go Report Card](https://goreportcard.com/badge/github.com/astaxie/beego)](https://goreportcard.com/report/github.com/astaxie/beego)
[![Build Status](https://drone.io/github.com/astaxie/beego/status.png)](https://drone.io/github.com/astaxie/beego/latest)
beego is a Go Framework which is inspired from tornado and sinatra. beego is used for rapid development of RESTful APIs, web apps and backend services in Go.
It is inspired by Tornado, Sinatra and Flask. beego has some Go-specific features such as interfaces and struct embedding.
It is a simply & powerful web framework. ###### More info at [beego.me](http://beego.me).
more info [beego.me](http://beego.me) ## 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
#### Create file `hello.go`
```go
package main
import "github.com/astaxie/beego"
func main(){
beego.Run()
}
```
#### Build and run
go build hello.go
./hello
#### Go to [http://localhost:8080](http://localhost:8080)
Congratulations! You've just built your first **beego** app.
###### Please see [Documentation](http://beego.me/docs) for more.
###### [beego-example](https://github.com/beego-dev/beego-example)
## Features ## Features
* RESTFul support * RESTful support
* MVC architecture * MVC architecture
* Session support (store in memory, file, Redis or MySQL) * Modularity
* Cache support (store in memory, Redis or Memcache) * Auto API documents
* Global Config * Annotation router
* Intelligent routing * Namespace
* Thread-safe map * Powerful development tools
* Friendly displaying of errors * Full stack for Web & API
* Useful template functions
## Documentation ## Documentation
[English](https://github.com/astaxie/beego/tree/master/docs/en) * [English](http://beego.me/docs/intro/)
* [中文文档](http://beego.me/docs/intro/)
* [Русский](http://beego.me/docs/intro/)
[API](http://gowalker.org/github.com/astaxie/beego) ## Community
[中文文档](https://github.com/astaxie/beego/tree/master/docs/zh) * [http://beego.me/community](http://beego.me/community)
* Welcome to join us in Slack: [https://beego.slack.com](https://beego.slack.com), you can get invited from [here](https://github.com/beego/beedoc/issues/232)
* QQ Group Group ID:523992905
## License
## LICENSE beego source code is licensed under the Apache Licence, Version 2.0
beego is licensed under the Apache Licence, Version 2.0
(http://www.apache.org/licenses/LICENSE-2.0.html). (http://www.apache.org/licenses/LICENSE-2.0.html).
## Use case
- Displaying API documentation: [gowalker](https://github.com/Unknwon/gowalker)
- seocms: [seocms](https://github.com/chinakr/seocms)
- CMS: [toropress](https://github.com/insionng/toropress)

458
admin.go Normal file
View File

@@ -0,0 +1,458 @@
// 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 beego
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
"reflect"
"strconv"
"text/template"
"time"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/astaxie/beego/grace"
"github.com/astaxie/beego/logs"
"github.com/astaxie/beego/toolbox"
"github.com/astaxie/beego/utils"
)
// BeeAdminApp is the default adminApp used by admin module.
var beeAdminApp *adminApp
// FilterMonitorFunc is default monitor filter when admin module is enable.
// if this func returns, admin module records qps for this request by condition of this function logic.
// usage:
// func MyFilterMonitor(method, requestPath string, t time.Duration, pattern string, statusCode int) bool {
// if method == "POST" {
// return false
// }
// if t.Nanoseconds() < 100 {
// return false
// }
// if strings.HasPrefix(requestPath, "/astaxie") {
// return false
// }
// return true
// }
// beego.FilterMonitorFunc = MyFilterMonitor.
var FilterMonitorFunc func(string, string, time.Duration, string, int) bool
func init() {
beeAdminApp = &adminApp{
routers: make(map[string]http.HandlerFunc),
}
// keep in mind that all data should be html escaped to avoid XSS attack
beeAdminApp.Route("/", adminIndex)
beeAdminApp.Route("/qps", qpsIndex)
beeAdminApp.Route("/prof", profIndex)
beeAdminApp.Route("/healthcheck", healthcheck)
beeAdminApp.Route("/task", taskStatus)
beeAdminApp.Route("/listconf", listConf)
beeAdminApp.Route("/metrics", promhttp.Handler().ServeHTTP)
FilterMonitorFunc = func(string, string, time.Duration, string, int) bool { return true }
}
// 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)
}
// QpsIndex is the http.Handler for writing qps statistics map result info in http.ResponseWriter.
// it's registered with url pattern "/qps" in admin module.
func qpsIndex(rw http.ResponseWriter, _ *http.Request) {
data := make(map[interface{}]interface{})
data["Content"] = toolbox.StatisticsMap.GetMap()
// do html escape before display path, avoid xss
if content, ok := (data["Content"]).(M); ok {
if resultLists, ok := (content["Data"]).([][]string); ok {
for i := range resultLists {
if len(resultLists[i]) > 0 {
resultLists[i][0] = template.HTMLEscapeString(resultLists[i][0])
}
}
}
}
writeTemplate(rw, data, qpsTpl, defaultScriptsTpl)
}
// ListConf is the http.Handler of displaying all beego configuration values as key/value pair.
// it's registered with url pattern "/listconf" in admin module.
func listConf(rw http.ResponseWriter, r *http.Request) {
r.ParseForm()
command := r.Form.Get("command")
if command == "" {
rw.Write([]byte("command not support"))
return
}
data := make(map[interface{}]interface{})
switch command {
case "conf":
m := make(M)
list("BConfig", BConfig, m)
m["AppConfigPath"] = template.HTMLEscapeString(appConfigPath)
m["AppConfigProvider"] = template.HTMLEscapeString(appConfigProvider)
tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl))
tmpl = template.Must(tmpl.Parse(configTpl))
tmpl = template.Must(tmpl.Parse(defaultScriptsTpl))
data["Content"] = m
tmpl.Execute(rw, data)
case "router":
content := PrintTree()
content["Fields"] = []string{
"Router Pattern",
"Methods",
"Controller",
}
data["Content"] = content
data["Title"] = "Routers"
writeTemplate(rw, data, routerAndFilterTpl, defaultScriptsTpl)
case "filter":
var (
content = M{
"Fields": []string{
"Router Pattern",
"Filter Function",
},
}
filterTypes = []string{}
filterTypeData = make(M)
)
if BeeApp.Handlers.enableFilter {
var filterType string
for k, fr := range map[int]string{
BeforeStatic: "Before Static",
BeforeRouter: "Before Router",
BeforeExec: "Before Exec",
AfterExec: "After Exec",
FinishRouter: "Finish Router"} {
if bf := BeeApp.Handlers.filters[k]; len(bf) > 0 {
filterType = fr
filterTypes = append(filterTypes, filterType)
resultList := new([][]string)
for _, f := range bf {
var result = []string{
// void xss
template.HTMLEscapeString(f.pattern),
template.HTMLEscapeString(utils.GetFuncName(f.filterFunc)),
}
*resultList = append(*resultList, result)
}
filterTypeData[filterType] = resultList
}
}
}
content["Data"] = filterTypeData
content["Methods"] = filterTypes
data["Content"] = content
data["Title"] = "Filters"
writeTemplate(rw, data, routerAndFilterTpl, defaultScriptsTpl)
default:
rw.Write([]byte("command not support"))
}
}
func list(root string, p interface{}, m M) {
pt := reflect.TypeOf(p)
pv := reflect.ValueOf(p)
if pt.Kind() == reflect.Ptr {
pt = pt.Elem()
pv = pv.Elem()
}
for i := 0; i < pv.NumField(); i++ {
var key string
if root == "" {
key = pt.Field(i).Name
} else {
key = root + "." + pt.Field(i).Name
}
if pv.Field(i).Kind() == reflect.Struct {
list(key, pv.Field(i).Interface(), m)
} else {
m[key] = pv.Field(i).Interface()
}
}
}
// PrintTree prints all registered routers.
func PrintTree() M {
var (
content = M{}
methods = []string{}
methodsData = make(M)
)
for method, t := range BeeApp.Handlers.routers {
resultList := new([][]string)
printTree(resultList, t)
methods = append(methods, template.HTMLEscapeString(method))
methodsData[template.HTMLEscapeString(method)] = resultList
}
content["Data"] = methodsData
content["Methods"] = methods
return content
}
func printTree(resultList *[][]string, t *Tree) {
for _, tr := range t.fixrouters {
printTree(resultList, tr)
}
if t.wildcard != nil {
printTree(resultList, t.wildcard)
}
for _, l := range t.leaves {
if v, ok := l.runObject.(*ControllerInfo); ok {
if v.routerType == routerTypeBeego {
var result = []string{
template.HTMLEscapeString(v.pattern),
template.HTMLEscapeString(fmt.Sprintf("%s", v.methods)),
template.HTMLEscapeString(v.controllerType.String()),
}
*resultList = append(*resultList, result)
} else if v.routerType == routerTypeRESTFul {
var result = []string{
template.HTMLEscapeString(v.pattern),
template.HTMLEscapeString(fmt.Sprintf("%s", v.methods)),
"",
}
*resultList = append(*resultList, result)
} else if v.routerType == routerTypeHandler {
var result = []string{
template.HTMLEscapeString(v.pattern),
"",
"",
}
*resultList = append(*resultList, result)
}
}
}
}
// ProfIndex is a http.Handler for showing profile command.
// it's in url pattern "/prof" in admin module.
func profIndex(rw http.ResponseWriter, r *http.Request) {
r.ParseForm()
command := r.Form.Get("command")
if command == "" {
return
}
var (
format = r.Form.Get("format")
data = make(map[interface{}]interface{})
result bytes.Buffer
)
toolbox.ProcessInput(command, &result)
data["Content"] = template.HTMLEscapeString(result.String())
if format == "json" && command == "gc summary" {
dataJSON, err := json.Marshal(data)
if err != nil {
http.Error(rw, err.Error(), http.StatusInternalServerError)
return
}
writeJSON(rw, dataJSON)
return
}
data["Title"] = template.HTMLEscapeString(command)
defaultTpl := defaultScriptsTpl
if command == "gc summary" {
defaultTpl = gcAjaxTpl
}
writeTemplate(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) {
var (
result []string
data = make(map[interface{}]interface{})
resultList = new([][]string)
content = M{
"Fields": []string{"Name", "Message", "Status"},
}
)
for name, h := range toolbox.AdminCheckList {
if err := h.Check(); err != nil {
result = []string{
"error",
template.HTMLEscapeString(name),
template.HTMLEscapeString(err.Error()),
}
} else {
result = []string{
"success",
template.HTMLEscapeString(name),
"OK",
}
}
*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)
}
// TaskStatus is a http.Handler with running task status (task name, status and the last execution).
// it's in "/task" pattern in admin module.
func taskStatus(rw http.ResponseWriter, req *http.Request) {
data := make(map[interface{}]interface{})
// Run Task
req.ParseForm()
taskname := req.Form.Get("taskname")
if taskname != "" {
if t, ok := toolbox.AdminTaskList[taskname]; ok {
if err := t.Run(); err != nil {
data["Message"] = []string{"error", template.HTMLEscapeString(fmt.Sprintf("%s", err))}
}
data["Message"] = []string{"success", template.HTMLEscapeString(fmt.Sprintf("%s run success,Now the Status is <br>%s", taskname, t.GetStatus()))}
} else {
data["Message"] = []string{"warning", template.HTMLEscapeString(fmt.Sprintf("there's no task which named: %s", taskname))}
}
}
// List Tasks
content := make(M)
resultList := new([][]string)
var fields = []string{
"Task Name",
"Task Spec",
"Task Status",
"Last Time",
"",
}
for tname, tk := range toolbox.AdminTaskList {
result := []string{
template.HTMLEscapeString(tname),
template.HTMLEscapeString(tk.GetSpec()),
template.HTMLEscapeString(tk.GetStatus()),
template.HTMLEscapeString(tk.GetPrev().String()),
}
*resultList = append(*resultList, result)
}
content["Fields"] = fields
content["Data"] = resultList
data["Content"] = content
data["Title"] = "Tasks"
writeTemplate(rw, data, tasksTpl, defaultScriptsTpl)
}
func writeTemplate(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))
}
tmpl.Execute(rw, data)
}
// adminApp is an http.HandlerFunc map used as beeAdminApp.
type adminApp struct {
routers map[string]http.HandlerFunc
}
// Route adds http.HandlerFunc to adminApp with url pattern.
func (admin *adminApp) Route(pattern string, f http.HandlerFunc) {
admin.routers[pattern] = f
}
// Run adminApp http server.
// Its addr is defined in configuration file as adminhttpaddr and adminhttpport.
func (admin *adminApp) Run() {
if len(toolbox.AdminTaskList) > 0 {
toolbox.StartTask()
}
addr := BConfig.Listen.AdminAddr
if BConfig.Listen.AdminPort != 0 {
addr = fmt.Sprintf("%s:%d", BConfig.Listen.AdminAddr, BConfig.Listen.AdminPort)
}
for p, f := range admin.routers {
http.Handle(p, f)
}
logs.Info("Admin server Running on %s", addr)
var err error
if BConfig.Listen.Graceful {
err = grace.ListenAndServe(addr, nil)
} else {
err = http.ListenAndServe(addr, nil)
}
if err != nil {
logs.Critical("Admin ListenAndServe: ", err, fmt.Sprintf("%d", os.Getpid()))
}
}

239
admin_test.go Normal file
View File

@@ -0,0 +1,239 @@
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)
t.Log(m)
om := oldMap()
for k, v := range om {
if fmt.Sprint(m[k]) != fmt.Sprint(v) {
t.Log(k, "old-key", v, "new-key", m[k])
t.FailNow()
}
}
}
func oldMap() M {
m := make(M)
m["BConfig.AppName"] = BConfig.AppName
m["BConfig.RunMode"] = BConfig.RunMode
m["BConfig.RouterCaseSensitive"] = BConfig.RouterCaseSensitive
m["BConfig.ServerName"] = BConfig.ServerName
m["BConfig.RecoverPanic"] = BConfig.RecoverPanic
m["BConfig.CopyRequestBody"] = BConfig.CopyRequestBody
m["BConfig.EnableGzip"] = BConfig.EnableGzip
m["BConfig.MaxMemory"] = BConfig.MaxMemory
m["BConfig.EnableErrorsShow"] = BConfig.EnableErrorsShow
m["BConfig.Listen.Graceful"] = BConfig.Listen.Graceful
m["BConfig.Listen.ServerTimeOut"] = BConfig.Listen.ServerTimeOut
m["BConfig.Listen.ListenTCP4"] = BConfig.Listen.ListenTCP4
m["BConfig.Listen.EnableHTTP"] = BConfig.Listen.EnableHTTP
m["BConfig.Listen.HTTPAddr"] = BConfig.Listen.HTTPAddr
m["BConfig.Listen.HTTPPort"] = BConfig.Listen.HTTPPort
m["BConfig.Listen.EnableHTTPS"] = BConfig.Listen.EnableHTTPS
m["BConfig.Listen.HTTPSAddr"] = BConfig.Listen.HTTPSAddr
m["BConfig.Listen.HTTPSPort"] = BConfig.Listen.HTTPSPort
m["BConfig.Listen.HTTPSCertFile"] = BConfig.Listen.HTTPSCertFile
m["BConfig.Listen.HTTPSKeyFile"] = BConfig.Listen.HTTPSKeyFile
m["BConfig.Listen.EnableAdmin"] = BConfig.Listen.EnableAdmin
m["BConfig.Listen.AdminAddr"] = BConfig.Listen.AdminAddr
m["BConfig.Listen.AdminPort"] = BConfig.Listen.AdminPort
m["BConfig.Listen.EnableFcgi"] = BConfig.Listen.EnableFcgi
m["BConfig.Listen.EnableStdIo"] = BConfig.Listen.EnableStdIo
m["BConfig.WebConfig.AutoRender"] = BConfig.WebConfig.AutoRender
m["BConfig.WebConfig.EnableDocs"] = BConfig.WebConfig.EnableDocs
m["BConfig.WebConfig.FlashName"] = BConfig.WebConfig.FlashName
m["BConfig.WebConfig.FlashSeparator"] = BConfig.WebConfig.FlashSeparator
m["BConfig.WebConfig.DirectoryIndex"] = BConfig.WebConfig.DirectoryIndex
m["BConfig.WebConfig.StaticDir"] = BConfig.WebConfig.StaticDir
m["BConfig.WebConfig.StaticExtensionsToGzip"] = BConfig.WebConfig.StaticExtensionsToGzip
m["BConfig.WebConfig.StaticCacheFileSize"] = BConfig.WebConfig.StaticCacheFileSize
m["BConfig.WebConfig.StaticCacheFileNum"] = BConfig.WebConfig.StaticCacheFileNum
m["BConfig.WebConfig.TemplateLeft"] = BConfig.WebConfig.TemplateLeft
m["BConfig.WebConfig.TemplateRight"] = BConfig.WebConfig.TemplateRight
m["BConfig.WebConfig.ViewsPath"] = BConfig.WebConfig.ViewsPath
m["BConfig.WebConfig.EnableXSRF"] = BConfig.WebConfig.EnableXSRF
m["BConfig.WebConfig.XSRFExpire"] = BConfig.WebConfig.XSRFExpire
m["BConfig.WebConfig.Session.SessionOn"] = BConfig.WebConfig.Session.SessionOn
m["BConfig.WebConfig.Session.SessionProvider"] = BConfig.WebConfig.Session.SessionProvider
m["BConfig.WebConfig.Session.SessionName"] = BConfig.WebConfig.Session.SessionName
m["BConfig.WebConfig.Session.SessionGCMaxLifetime"] = BConfig.WebConfig.Session.SessionGCMaxLifetime
m["BConfig.WebConfig.Session.SessionProviderConfig"] = BConfig.WebConfig.Session.SessionProviderConfig
m["BConfig.WebConfig.Session.SessionCookieLifeTime"] = BConfig.WebConfig.Session.SessionCookieLifeTime
m["BConfig.WebConfig.Session.SessionAutoSetCookie"] = BConfig.WebConfig.Session.SessionAutoSetCookie
m["BConfig.WebConfig.Session.SessionDomain"] = BConfig.WebConfig.Session.SessionDomain
m["BConfig.WebConfig.Session.SessionDisableHTTPOnly"] = BConfig.WebConfig.Session.SessionDisableHTTPOnly
m["BConfig.Log.AccessLogs"] = BConfig.Log.AccessLogs
m["BConfig.Log.EnableStaticLogs"] = BConfig.Log.EnableStaticLogs
m["BConfig.Log.AccessLogsFormat"] = BConfig.Log.AccessLogsFormat
m["BConfig.Log.FileLineNum"] = BConfig.Log.FileLineNum
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)
}
}

356
adminui.go Normal file

File diff suppressed because one or more lines are too long

496
app.go Normal file
View File

@@ -0,0 +1,496 @@
// 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 beego
import (
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
"net"
"net/http"
"net/http/fcgi"
"os"
"path"
"strings"
"time"
"github.com/astaxie/beego/grace"
"github.com/astaxie/beego/logs"
"github.com/astaxie/beego/utils"
"golang.org/x/crypto/acme/autocert"
)
var (
// BeeApp is an application instance
BeeApp *App
)
func init() {
// create beego application
BeeApp = NewApp()
}
// App defines beego application with a new PatternServeMux.
type App struct {
Handlers *ControllerRegister
Server *http.Server
}
// NewApp returns a new beego application.
func NewApp() *App {
cr := NewControllerRegister()
app := &App{Handlers: cr, Server: &http.Server{}}
return app
}
// MiddleWare function for http.Handler
type MiddleWare func(http.Handler) http.Handler
// Run beego application.
func (app *App) Run(mws ...MiddleWare) {
addr := BConfig.Listen.HTTPAddr
if BConfig.Listen.HTTPPort != 0 {
addr = fmt.Sprintf("%s:%d", BConfig.Listen.HTTPAddr, BConfig.Listen.HTTPPort)
}
var (
err error
l net.Listener
endRunning = make(chan bool, 1)
)
// run cgi server
if BConfig.Listen.EnableFcgi {
if BConfig.Listen.EnableStdIo {
if err = fcgi.Serve(nil, app.Handlers); err == nil { // standard I/O
logs.Info("Use FCGI via standard I/O")
} else {
logs.Critical("Cannot use FCGI via standard I/O", err)
}
return
}
if BConfig.Listen.HTTPPort == 0 {
// remove the Socket file before start
if utils.FileExists(addr) {
os.Remove(addr)
}
l, err = net.Listen("unix", addr)
} else {
l, err = net.Listen("tcp", addr)
}
if err != nil {
logs.Critical("Listen: ", err)
}
if err = fcgi.Serve(l, app.Handlers); err != nil {
logs.Critical("fcgi.Serve: ", err)
}
return
}
app.Server.Handler = app.Handlers
for i := len(mws) - 1; i >= 0; i-- {
if mws[i] == nil {
continue
}
app.Server.Handler = mws[i](app.Server.Handler)
}
app.Server.ReadTimeout = time.Duration(BConfig.Listen.ServerTimeOut) * time.Second
app.Server.WriteTimeout = time.Duration(BConfig.Listen.ServerTimeOut) * time.Second
app.Server.ErrorLog = logs.GetLogger("HTTP")
// run graceful mode
if BConfig.Listen.Graceful {
httpsAddr := BConfig.Listen.HTTPSAddr
app.Server.Addr = httpsAddr
if BConfig.Listen.EnableHTTPS || BConfig.Listen.EnableMutualHTTPS {
go func() {
time.Sleep(1000 * time.Microsecond)
if BConfig.Listen.HTTPSPort != 0 {
httpsAddr = fmt.Sprintf("%s:%d", BConfig.Listen.HTTPSAddr, BConfig.Listen.HTTPSPort)
app.Server.Addr = httpsAddr
}
server := grace.NewServer(httpsAddr, app.Server.Handler)
server.Server.ReadTimeout = app.Server.ReadTimeout
server.Server.WriteTimeout = app.Server.WriteTimeout
if BConfig.Listen.EnableMutualHTTPS {
if err := server.ListenAndServeMutualTLS(BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile, BConfig.Listen.TrustCaFile); err != nil {
logs.Critical("ListenAndServeTLS: ", err, fmt.Sprintf("%d", os.Getpid()))
time.Sleep(100 * time.Microsecond)
}
} else {
if BConfig.Listen.AutoTLS {
m := autocert.Manager{
Prompt: autocert.AcceptTOS,
HostPolicy: autocert.HostWhitelist(BConfig.Listen.Domains...),
Cache: autocert.DirCache(BConfig.Listen.TLSCacheDir),
}
app.Server.TLSConfig = &tls.Config{GetCertificate: m.GetCertificate}
BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile = "", ""
}
if err := server.ListenAndServeTLS(BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile); err != nil {
logs.Critical("ListenAndServeTLS: ", err, fmt.Sprintf("%d", os.Getpid()))
time.Sleep(100 * time.Microsecond)
}
}
endRunning <- true
}()
}
if BConfig.Listen.EnableHTTP {
go func() {
server := grace.NewServer(addr, app.Server.Handler)
server.Server.ReadTimeout = app.Server.ReadTimeout
server.Server.WriteTimeout = app.Server.WriteTimeout
if BConfig.Listen.ListenTCP4 {
server.Network = "tcp4"
}
if err := server.ListenAndServe(); err != nil {
logs.Critical("ListenAndServe: ", err, fmt.Sprintf("%d", os.Getpid()))
time.Sleep(100 * time.Microsecond)
}
endRunning <- true
}()
}
<-endRunning
return
}
// run normal mode
if BConfig.Listen.EnableHTTPS || BConfig.Listen.EnableMutualHTTPS {
go func() {
time.Sleep(1000 * time.Microsecond)
if BConfig.Listen.HTTPSPort != 0 {
app.Server.Addr = fmt.Sprintf("%s:%d", BConfig.Listen.HTTPSAddr, BConfig.Listen.HTTPSPort)
} else if BConfig.Listen.EnableHTTP {
logs.Info("Start https server error, conflict with http. Please reset https port")
return
}
logs.Info("https server Running on https://%s", app.Server.Addr)
if BConfig.Listen.AutoTLS {
m := autocert.Manager{
Prompt: autocert.AcceptTOS,
HostPolicy: autocert.HostWhitelist(BConfig.Listen.Domains...),
Cache: autocert.DirCache(BConfig.Listen.TLSCacheDir),
}
app.Server.TLSConfig = &tls.Config{GetCertificate: m.GetCertificate}
BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile = "", ""
} else if BConfig.Listen.EnableMutualHTTPS {
pool := x509.NewCertPool()
data, err := ioutil.ReadFile(BConfig.Listen.TrustCaFile)
if err != nil {
logs.Info("MutualHTTPS should provide TrustCaFile")
return
}
pool.AppendCertsFromPEM(data)
app.Server.TLSConfig = &tls.Config{
ClientCAs: pool,
ClientAuth: BConfig.Listen.ClientAuth,
}
}
if err := app.Server.ListenAndServeTLS(BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile); err != nil {
logs.Critical("ListenAndServeTLS: ", err)
time.Sleep(100 * time.Microsecond)
endRunning <- true
}
}()
}
if BConfig.Listen.EnableHTTP {
go func() {
app.Server.Addr = addr
logs.Info("http server Running on http://%s", app.Server.Addr)
if BConfig.Listen.ListenTCP4 {
ln, err := net.Listen("tcp4", app.Server.Addr)
if err != nil {
logs.Critical("ListenAndServe: ", err)
time.Sleep(100 * time.Microsecond)
endRunning <- true
return
}
if err = app.Server.Serve(ln); err != nil {
logs.Critical("ListenAndServe: ", err)
time.Sleep(100 * time.Microsecond)
endRunning <- true
return
}
} else {
if err := app.Server.ListenAndServe(); err != nil {
logs.Critical("ListenAndServe: ", err)
time.Sleep(100 * time.Microsecond)
endRunning <- true
}
}
}()
}
<-endRunning
}
// Router adds a patterned controller handler to BeeApp.
// it's an alias method of App.Router.
// usage:
// simple router
// beego.Router("/admin", &admin.UserController{})
// beego.Router("/admin/index", &admin.ArticleController{})
//
// regex router
//
// beego.Router("/api/:id([0-9]+)", &controllers.RController{})
//
// custom rules
// beego.Router("/api/list",&RestController{},"*:ListFood")
// beego.Router("/api/create",&RestController{},"post:CreateFood")
// beego.Router("/api/update",&RestController{},"put:UpdateFood")
// beego.Router("/api/delete",&RestController{},"delete:DeleteFood")
func Router(rootpath string, c ControllerInterface, mappingMethods ...string) *App {
BeeApp.Handlers.Add(rootpath, c, mappingMethods...)
return BeeApp
}
// UnregisterFixedRoute unregisters the route with the specified fixedRoute. It is particularly useful
// in web applications that inherit most routes from a base webapp via the underscore
// import, and aim to overwrite only certain paths.
// The method parameter can be empty or "*" for all HTTP methods, or a particular
// method type (e.g. "GET" or "POST") for selective removal.
//
// Usage (replace "GET" with "*" for all methods):
// beego.UnregisterFixedRoute("/yourpreviouspath", "GET")
// beego.Router("/yourpreviouspath", yourControllerAddress, "get:GetNewPage")
func UnregisterFixedRoute(fixedRoute string, method string) *App {
subPaths := splitPath(fixedRoute)
if method == "" || method == "*" {
for m := range HTTPMETHOD {
if _, ok := BeeApp.Handlers.routers[m]; !ok {
continue
}
if BeeApp.Handlers.routers[m].prefix == strings.Trim(fixedRoute, "/ ") {
findAndRemoveSingleTree(BeeApp.Handlers.routers[m])
continue
}
findAndRemoveTree(subPaths, BeeApp.Handlers.routers[m], m)
}
return BeeApp
}
// Single HTTP method
um := strings.ToUpper(method)
if _, ok := BeeApp.Handlers.routers[um]; ok {
if BeeApp.Handlers.routers[um].prefix == strings.Trim(fixedRoute, "/ ") {
findAndRemoveSingleTree(BeeApp.Handlers.routers[um])
return BeeApp
}
findAndRemoveTree(subPaths, BeeApp.Handlers.routers[um], um)
}
return BeeApp
}
func findAndRemoveTree(paths []string, entryPointTree *Tree, method string) {
for i := range entryPointTree.fixrouters {
if entryPointTree.fixrouters[i].prefix == paths[0] {
if len(paths) == 1 {
if len(entryPointTree.fixrouters[i].fixrouters) > 0 {
// If the route had children subtrees, remove just the functional leaf,
// to allow children to function as before
if len(entryPointTree.fixrouters[i].leaves) > 0 {
entryPointTree.fixrouters[i].leaves[0] = nil
entryPointTree.fixrouters[i].leaves = entryPointTree.fixrouters[i].leaves[1:]
}
} else {
// Remove the *Tree from the fixrouters slice
entryPointTree.fixrouters[i] = nil
if i == len(entryPointTree.fixrouters)-1 {
entryPointTree.fixrouters = entryPointTree.fixrouters[:i]
} else {
entryPointTree.fixrouters = append(entryPointTree.fixrouters[:i], entryPointTree.fixrouters[i+1:len(entryPointTree.fixrouters)]...)
}
}
return
}
findAndRemoveTree(paths[1:], entryPointTree.fixrouters[i], method)
}
}
}
func findAndRemoveSingleTree(entryPointTree *Tree) {
if entryPointTree == nil {
return
}
if len(entryPointTree.fixrouters) > 0 {
// If the route had children subtrees, remove just the functional leaf,
// to allow children to function as before
if len(entryPointTree.leaves) > 0 {
entryPointTree.leaves[0] = nil
entryPointTree.leaves = entryPointTree.leaves[1:]
}
}
}
// Include will generate router file in the router/xxx.go from the controller's comments
// usage:
// beego.Include(&BankAccount{}, &OrderController{},&RefundController{},&ReceiptController{})
// type BankAccount struct{
// beego.Controller
// }
//
// register the function
// func (b *BankAccount)Mapping(){
// b.Mapping("ShowAccount" , b.ShowAccount)
// b.Mapping("ModifyAccount", b.ModifyAccount)
//}
//
// //@router /account/:id [get]
// func (b *BankAccount) ShowAccount(){
// //logic
// }
//
//
// //@router /account/:id [post]
// func (b *BankAccount) ModifyAccount(){
// //logic
// }
//
// the comments @router url methodlist
// url support all the function Router's pattern
// methodlist [get post head put delete options *]
func Include(cList ...ControllerInterface) *App {
BeeApp.Handlers.Include(cList...)
return BeeApp
}
// RESTRouter adds a restful controller handler to BeeApp.
// its' controller implements beego.ControllerInterface and
// defines a param "pattern/:objectId" to visit each resource.
func RESTRouter(rootpath string, c ControllerInterface) *App {
Router(rootpath, c)
Router(path.Join(rootpath, ":objectId"), c)
return BeeApp
}
// AutoRouter adds defined controller handler to BeeApp.
// it's same to App.AutoRouter.
// if beego.AddAuto(&MainContorlller{}) and MainController has methods List and Page,
// visit the url /main/list to exec List function or /main/page to exec Page function.
func AutoRouter(c ControllerInterface) *App {
BeeApp.Handlers.AddAuto(c)
return BeeApp
}
// AutoPrefix adds controller handler to BeeApp with prefix.
// it's same to App.AutoRouterWithPrefix.
// if beego.AutoPrefix("/admin",&MainContorlller{}) and MainController has methods List and Page,
// visit the url /admin/main/list to exec List function or /admin/main/page to exec Page function.
func AutoPrefix(prefix string, c ControllerInterface) *App {
BeeApp.Handlers.AddAutoPrefix(prefix, c)
return BeeApp
}
// Get used to register router for Get method
// usage:
// beego.Get("/", func(ctx *context.Context){
// ctx.Output.Body("hello world")
// })
func Get(rootpath string, f FilterFunc) *App {
BeeApp.Handlers.Get(rootpath, f)
return BeeApp
}
// Post used to register router for Post method
// usage:
// beego.Post("/api", func(ctx *context.Context){
// ctx.Output.Body("hello world")
// })
func Post(rootpath string, f FilterFunc) *App {
BeeApp.Handlers.Post(rootpath, f)
return BeeApp
}
// Delete used to register router for Delete method
// usage:
// beego.Delete("/api", func(ctx *context.Context){
// ctx.Output.Body("hello world")
// })
func Delete(rootpath string, f FilterFunc) *App {
BeeApp.Handlers.Delete(rootpath, f)
return BeeApp
}
// Put used to register router for Put method
// usage:
// beego.Put("/api", func(ctx *context.Context){
// ctx.Output.Body("hello world")
// })
func Put(rootpath string, f FilterFunc) *App {
BeeApp.Handlers.Put(rootpath, f)
return BeeApp
}
// Head used to register router for Head method
// usage:
// beego.Head("/api", func(ctx *context.Context){
// ctx.Output.Body("hello world")
// })
func Head(rootpath string, f FilterFunc) *App {
BeeApp.Handlers.Head(rootpath, f)
return BeeApp
}
// Options used to register router for Options method
// usage:
// beego.Options("/api", func(ctx *context.Context){
// ctx.Output.Body("hello world")
// })
func Options(rootpath string, f FilterFunc) *App {
BeeApp.Handlers.Options(rootpath, f)
return BeeApp
}
// Patch used to register router for Patch method
// usage:
// beego.Patch("/api", func(ctx *context.Context){
// ctx.Output.Body("hello world")
// })
func Patch(rootpath string, f FilterFunc) *App {
BeeApp.Handlers.Patch(rootpath, f)
return BeeApp
}
// Any used to register router for all methods
// usage:
// beego.Any("/api", func(ctx *context.Context){
// ctx.Output.Body("hello world")
// })
func Any(rootpath string, f FilterFunc) *App {
BeeApp.Handlers.Any(rootpath, f)
return BeeApp
}
// Handler used to register a Handler router
// usage:
// beego.Handler("/api", http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) {
// fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
// }))
func Handler(rootpath string, h http.Handler, options ...interface{}) *App {
BeeApp.Handlers.Handler(rootpath, h, options...)
return BeeApp
}
// InsertFilter adds a FilterFunc with pattern condition and action constant.
// The pos means action constant including
// beego.BeforeStatic, beego.BeforeRouter, beego.BeforeExec, beego.AfterExec and beego.FinishRouter.
// The bool params is for setting the returnOnOutput value (false allows multiple filters to execute)
func InsertFilter(pattern string, pos int, filter FilterFunc, params ...bool) *App {
BeeApp.Handlers.InsertFilter(pattern, pos, filter, params...)
return BeeApp
}

385
beego.go
View File

@@ -1,304 +1,123 @@
// 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 beego package beego
import ( import (
"fmt"
"github.com/astaxie/beego/session"
"html/template"
"net"
"net/http"
"net/http/fcgi"
"os" "os"
"path" "path/filepath"
"runtime" "strconv"
"time" "strings"
) )
const VERSION = "0.9.0" const (
// VERSION represent beego web framework version.
VERSION = "1.12.3"
// DEV is for develop
DEV = "dev"
// PROD is for production
PROD = "prod"
)
// M is Map shortcut
type M map[string]interface{}
// Hook function to run
type hookfunc func() error
var ( var (
BeeApp *App hooks = make([]hookfunc, 0) //hook function slice to store the hookfunc
AppName string
AppPath string
AppConfigPath string
StaticDir map[string]string
TemplateCache map[string]*template.Template
HttpAddr string
HttpPort int
RecoverPanic bool
AutoRender bool
PprofOn bool
ViewsPath string
RunMode string //"dev" or "prod"
AppConfig *Config
//related to session
GlobalSessions *session.Manager //GlobalSessions
SessionOn bool // wheather auto start session,default is false
SessionProvider string // default session provider memory mysql redis
SessionName string // sessionName cookie's name
SessionGCMaxLifetime int64 // session's gc maxlifetime
SessionSavePath string // session savepath if use mysql/redis/file this set to the connectinfo
UseFcgi bool
MaxMemory int64
EnableGzip bool // enable gzip
DirectoryIndex bool //ebable DirectoryIndex default is false
EnbaleHotUpdate bool //enable HotUpdate default is false
HttpServerTimeOut int64 //set httpserver timeout
ErrorsShow bool //set weather show errors
XSRFKEY string //set XSRF
EnableXSRF bool
XSRFExpire int
CopyRequestBody bool //When in raw application, You want to the reqeustbody
) )
func init() { // AddAPPStartHook is used to register the hookfunc
os.Chdir(path.Dir(os.Args[0])) // The hookfuncs will run in beego.Run()
BeeApp = NewApp() // such as initiating session , starting middleware , building template, starting admin control and so on.
AppPath, _ = os.Getwd() func AddAPPStartHook(hf ...hookfunc) {
StaticDir = make(map[string]string) hooks = append(hooks, hf...)
TemplateCache = make(map[string]*template.Template)
HttpAddr = ""
HttpPort = 8080
AppName = "beego"
RunMode = "dev" //default runmod
AutoRender = true
RecoverPanic = true
PprofOn = false
ViewsPath = "views"
SessionOn = false
SessionProvider = "memory"
SessionName = "beegosessionID"
SessionGCMaxLifetime = 3600
SessionSavePath = ""
UseFcgi = false
MaxMemory = 1 << 26 //64MB
EnableGzip = false
StaticDir["/static"] = "static"
AppConfigPath = path.Join(AppPath, "conf", "app.conf")
HttpServerTimeOut = 0
ErrorsShow = true
XSRFKEY = "beegoxsrf"
XSRFExpire = 60
ParseConfig()
runtime.GOMAXPROCS(runtime.NumCPU())
} }
type App struct { // Run beego application.
Handlers *ControllerRegistor // beego.Run() default run on HttpPort
} // beego.Run("localhost")
// beego.Run(":8089")
// beego.Run("127.0.0.1:8089")
func Run(params ...string) {
// New returns a new PatternServeMux. initBeforeHTTPRun()
func NewApp() *App {
cr := NewControllerRegistor()
app := &App{Handlers: cr}
return app
}
func (app *App) Run() { if len(params) > 0 && params[0] != "" {
addr := fmt.Sprintf("%s:%d", HttpAddr, HttpPort) strs := strings.Split(params[0], ":")
var ( if len(strs) > 0 && strs[0] != "" {
err error BConfig.Listen.HTTPAddr = strs[0]
l net.Listener
)
if UseFcgi {
l, err = net.Listen("tcp", addr)
if err != nil {
BeeLogger.Fatal("Listen: ", err)
} }
err = fcgi.Serve(l, app.Handlers) if len(strs) > 1 && strs[1] != "" {
} else { BConfig.Listen.HTTPPort, _ = strconv.Atoi(strs[1])
if EnbaleHotUpdate {
server := &http.Server{
Handler: app.Handlers,
ReadTimeout: time.Duration(HttpServerTimeOut) * time.Second,
WriteTimeout: time.Duration(HttpServerTimeOut) * time.Second,
}
laddr, err := net.ResolveTCPAddr("tcp", addr)
if nil != err {
BeeLogger.Fatal("ResolveTCPAddr:", err)
}
l, err = GetInitListner(laddr)
theStoppable = newStoppable(l)
err = server.Serve(theStoppable)
theStoppable.wg.Wait()
CloseSelf()
} else {
s := &http.Server{
Addr: addr,
Handler: app.Handlers,
ReadTimeout: time.Duration(HttpServerTimeOut) * time.Second,
WriteTimeout: time.Duration(HttpServerTimeOut) * time.Second,
}
err = s.ListenAndServe()
} }
BConfig.Listen.Domains = params
} }
if err != nil {
BeeLogger.Fatal("ListenAndServe: ", err)
}
}
func (app *App) Router(path string, c ControllerInterface, mappingMethods ...string) *App {
app.Handlers.Add(path, c, mappingMethods...)
return app
}
func (app *App) AutoRouter(c ControllerInterface) *App {
app.Handlers.AddAuto(c)
return app
}
func (app *App) Filter(filter http.HandlerFunc) *App {
app.Handlers.Filter(filter)
return app
}
func (app *App) FilterParam(param string, filter http.HandlerFunc) *App {
app.Handlers.FilterParam(param, filter)
return app
}
func (app *App) FilterPrefixPath(path string, filter http.HandlerFunc) *App {
app.Handlers.FilterPrefixPath(path, filter)
return app
}
func (app *App) FilterAfter(filter http.HandlerFunc) *App {
app.Handlers.FilterAfter(filter)
return app
}
func (app *App) FilterParamAfter(param string, filter http.HandlerFunc) *App {
app.Handlers.FilterParamAfter(param, filter)
return app
}
func (app *App) FilterPrefixPathAfter(path string, filter http.HandlerFunc) *App {
app.Handlers.FilterPrefixPathAfter(path, filter)
return app
}
func (app *App) SetViewsPath(path string) *App {
ViewsPath = path
return app
}
func (app *App) SetStaticPath(url string, path string) *App {
StaticDir[url] = path
return app
}
func (app *App) DelStaticPath(url string) *App {
delete(StaticDir, url)
return app
}
func (app *App) ErrorLog(ctx *Context) {
BeeLogger.Printf("[ERR] host: '%s', request: '%s %s', proto: '%s', ua: '%s', remote: '%s'\n", ctx.Request.Host, ctx.Request.Method, ctx.Request.URL.Path, ctx.Request.Proto, ctx.Request.UserAgent(), ctx.Request.RemoteAddr)
}
func (app *App) AccessLog(ctx *Context) {
BeeLogger.Printf("[ACC] host: '%s', request: '%s %s', proto: '%s', ua: '%s', remote: '%s'\n", ctx.Request.Host, ctx.Request.Method, ctx.Request.URL.Path, ctx.Request.Proto, ctx.Request.UserAgent(), ctx.Request.RemoteAddr)
}
func RegisterController(path string, c ControllerInterface) *App {
BeeApp.Router(path, c)
return BeeApp
}
func Router(rootpath string, c ControllerInterface, mappingMethods ...string) *App {
BeeApp.Router(rootpath, c, mappingMethods...)
return BeeApp
}
func RESTRouter(rootpath string, c ControllerInterface) *App {
Router(rootpath, c)
Router(path.Join(rootpath, ":objectId"), c)
return BeeApp
}
func AutoRouter(c ControllerInterface) *App {
BeeApp.AutoRouter(c)
return BeeApp
}
func RouterHandler(path string, c http.Handler) *App {
BeeApp.Handlers.AddHandler(path, c)
return BeeApp
}
func Errorhandler(err string, h http.HandlerFunc) *App {
ErrorMaps[err] = h
return BeeApp
}
func SetViewsPath(path string) *App {
BeeApp.SetViewsPath(path)
return BeeApp
}
func SetStaticPath(url string, path string) *App {
StaticDir[url] = path
return BeeApp
}
func DelStaticPath(url string) *App {
delete(StaticDir, url)
return BeeApp
}
func Filter(filter http.HandlerFunc) *App {
BeeApp.Filter(filter)
return BeeApp
}
func FilterParam(param string, filter http.HandlerFunc) *App {
BeeApp.FilterParam(param, filter)
return BeeApp
}
func FilterPrefixPath(path string, filter http.HandlerFunc) *App {
BeeApp.FilterPrefixPath(path, filter)
return BeeApp
}
func FilterAfter(filter http.HandlerFunc) *App {
BeeApp.FilterAfter(filter)
return BeeApp
}
func FilterParamAfter(param string, filter http.HandlerFunc) *App {
BeeApp.FilterParamAfter(param, filter)
return BeeApp
}
func FilterPrefixPathAfter(path string, filter http.HandlerFunc) *App {
BeeApp.FilterPrefixPathAfter(path, filter)
return BeeApp
}
func Run() {
if AppConfigPath != path.Join(AppPath, "conf", "app.conf") {
err := ParseConfig()
if err != nil {
if RunMode == "dev" {
Warn(err)
}
}
}
if PprofOn {
BeeApp.Router(`/debug/pprof`, &ProfController{})
BeeApp.Router(`/debug/pprof/:pp([\w]+)`, &ProfController{})
}
if SessionOn {
GlobalSessions, _ = session.NewManager(SessionProvider, SessionName, SessionGCMaxLifetime, SessionSavePath)
go GlobalSessions.GC()
}
err := BuildTemplate(ViewsPath)
if err != nil {
if RunMode == "dev" {
Warn(err)
}
}
registerErrorHander()
BeeApp.Run() BeeApp.Run()
} }
// RunWithMiddleWares Run beego application with middlewares.
func RunWithMiddleWares(addr string, mws ...MiddleWare) {
initBeforeHTTPRun()
strs := strings.Split(addr, ":")
if len(strs) > 0 && strs[0] != "" {
BConfig.Listen.HTTPAddr = strs[0]
BConfig.Listen.Domains = []string{strs[0]}
}
if len(strs) > 1 && strs[1] != "" {
BConfig.Listen.HTTPPort, _ = strconv.Atoi(strs[1])
}
BeeApp.Run(mws...)
}
func initBeforeHTTPRun() {
//init hooks
AddAPPStartHook(
registerMime,
registerDefaultErrorHandler,
registerSession,
registerTemplate,
registerAdmin,
registerGzip,
)
for _, hk := range hooks {
if err := hk(); err != nil {
panic(err)
}
}
}
// TestBeegoInit is for test package init
func TestBeegoInit(ap string) {
path := filepath.Join(ap, "conf", "app.conf")
os.Chdir(ap)
InitBeegoBeforeTest(path)
}
// InitBeegoBeforeTest is for test package init
func InitBeegoBeforeTest(appConfigPath string) {
if err := LoadAppConfig(appConfigProvider, appConfigPath); err != nil {
panic(err)
}
BConfig.RunMode = "test"
initBeforeHTTPRun()
}

27
build_info.go Normal file
View File

@@ -0,0 +1,27 @@
// Copyright 2020 astaxie
//
// 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 beego
var (
BuildVersion string
BuildGitRevision string
BuildStatus string
BuildTag string
BuildTime string
GoVersion string
GitBranch string
)

133
cache.go
View File

@@ -1,133 +0,0 @@
package beego
import (
"errors"
"fmt"
"strconv"
"sync"
"time"
)
var (
DefaultEvery int = 60 // 1 minute
)
type BeeItem struct {
val interface{}
Lastaccess time.Time
expired int
}
func (itm *BeeItem) Access() interface{} {
itm.Lastaccess = time.Now()
return itm.val
}
type BeeCache struct {
lock sync.RWMutex
dur time.Duration
items map[string]*BeeItem
Every int // Run an expiration check Every seconds
}
// NewDefaultCache returns a new FileCache with sane defaults.
func NewBeeCache() *BeeCache {
cache := BeeCache{dur: time.Since(time.Now()),
Every: DefaultEvery}
return &cache
}
func (bc *BeeCache) Get(name string) interface{} {
bc.lock.RLock()
defer bc.lock.RUnlock()
itm, ok := bc.items[name]
if !ok {
return nil
}
return itm.Access()
}
func (bc *BeeCache) Put(name string, value interface{}, expired int) error {
bc.lock.Lock()
defer bc.lock.Unlock()
t := BeeItem{val: value, Lastaccess: time.Now(), expired: expired}
if _, ok := bc.items[name]; ok {
return errors.New("the key is exist")
} else {
bc.items[name] = &t
}
return nil
}
func (bc *BeeCache) Delete(name string) (ok bool, err error) {
bc.lock.Lock()
defer bc.lock.Unlock()
if _, ok = bc.items[name]; !ok {
return
}
delete(bc.items, name)
_, valid := bc.items[name]
if valid {
ok = false
}
return
}
// Return all of the item in a BeeCache
func (bc *BeeCache) Items() map[string]*BeeItem {
return bc.items
}
func (bc *BeeCache) IsExist(name string) bool {
bc.lock.RLock()
defer bc.lock.RUnlock()
_, ok := bc.items[name]
return ok
}
// Start activates the file cache; it will
func (bc *BeeCache) Start() error {
dur, err := time.ParseDuration(fmt.Sprintf("%ds", bc.Every))
if err != nil {
return err
}
bc.dur = dur
bc.items = make(map[string]*BeeItem, 0)
go bc.vaccuum()
return nil
}
func (bc *BeeCache) vaccuum() {
if bc.Every < 1 {
return
}
for {
<-time.After(time.Duration(bc.dur))
if bc.items == nil {
return
}
for name, _ := range bc.items {
bc.item_expired(name)
}
}
}
// item_expired returns true if an item is expired.
func (bc *BeeCache) item_expired(name string) bool {
bc.lock.Lock()
defer bc.lock.Unlock()
itm, ok := bc.items[name]
if !ok {
return true
}
dur := time.Now().Sub(itm.Lastaccess)
sec, err := strconv.Atoi(fmt.Sprintf("%0.0f", dur.Seconds()))
if err != nil {
delete(bc.items, name)
return true
} else if sec >= itm.expired {
delete(bc.items, name)
return true
}
return false
}

8
cache/README.md vendored
View File

@@ -22,11 +22,11 @@ First you must import it
Then init a Cache (example with memory adapter) Then init a Cache (example with memory adapter)
bm, err := NewCache("memory", `{"interval":60}`) bm, err := cache.NewCache("memory", `{"interval":60}`)
Use it like this: Use it like this:
bm.Put("astaxie", 1, 10) bm.Put("astaxie", 1, 10 * time.Second)
bm.Get("astaxie") bm.Get("astaxie")
bm.IsExist("astaxie") bm.IsExist("astaxie")
bm.Delete("astaxie") bm.Delete("astaxie")
@@ -43,7 +43,7 @@ interval means the gc time. The cache will check at each time interval, whether
## Memcache adapter ## Memcache adapter
memory adapter use the vitess's [Memcache](http://code.google.com/p/vitess/go/memcache) client. Memcache adapter use the [gomemcache](http://github.com/bradfitz/gomemcache) client.
Configure like this: Configure like this:
@@ -52,7 +52,7 @@ Configure like this:
## Redis adapter ## Redis adapter
Redis adapter use the [redigo](http://github.com/garyburd/redigo/redis) client. Redis adapter use the [redigo](http://github.com/gomodule/redigo) client.
Configure like this: Configure like this:

82
cache/cache.go vendored
View File

@@ -1,41 +1,103 @@
// 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 cache provide a Cache interface and some implement engine
// Usage:
//
// import(
// "github.com/astaxie/beego/cache"
// )
//
// bm, err := cache.NewCache("memory", `{"interval":60}`)
//
// Use it like this:
//
// bm.Put("astaxie", 1, 10 * time.Second)
// bm.Get("astaxie")
// bm.IsExist("astaxie")
// bm.Delete("astaxie")
//
// more docs http://beego.me/docs/module/cache.md
package cache package cache
import ( import (
"fmt" "fmt"
"time"
) )
// Cache interface contains all behaviors for cache adapter.
// usage:
// cache.Register("file",cache.NewFileCache) // this operation is run in init method of file.go.
// c,err := cache.NewCache("file","{....}")
// c.Put("key",value, 3600 * time.Second)
// v := c.Get("key")
//
// c.Incr("counter") // now is 1
// c.Incr("counter") // now is 2
// count := c.Get("counter").(int)
type Cache interface { type Cache interface {
// get cached value by key.
Get(key string) interface{} Get(key string) interface{}
Put(key string, val interface{}, timeout int64) error // GetMulti is a batch version of Get.
GetMulti(keys []string) []interface{}
// set cached value with key and expire time.
Put(key string, val interface{}, timeout time.Duration) error
// delete cached value by key.
Delete(key string) error Delete(key string) error
// increase cached int value by key, as a counter.
Incr(key string) error Incr(key string) error
// decrease cached int value by key, as a counter.
Decr(key string) error Decr(key string) error
// check if cached value exists or not.
IsExist(key string) bool IsExist(key string) bool
// clear all cache.
ClearAll() error ClearAll() error
// start gc routine based on config string settings.
StartAndGC(config string) error StartAndGC(config string) error
} }
var adapters = make(map[string]Cache) // Instance is a function create a new Cache Instance
type Instance func() Cache
var adapters = make(map[string]Instance)
// Register makes a cache adapter available by the adapter name. // Register makes a cache adapter available by the adapter name.
// If Register is called twice with the same name or if driver is nil, // If Register is called twice with the same name or if driver is nil,
// it panics. // it panics.
func Register(name string, adapter Cache) { func Register(name string, adapter Instance) {
if adapter == nil { if adapter == nil {
panic("cache: Register adapter is nil") panic("cache: Register adapter is nil")
} }
if _, dup := adapters[name]; dup { if _, ok := adapters[name]; ok {
panic("cache: Register called twice for adapter " + name) panic("cache: Register called twice for adapter " + name)
} }
adapters[name] = adapter adapters[name] = adapter
} }
// config need to be correct JSON as string: {"interval":360} // NewCache Create a new cache driver by adapter name and config string.
func NewCache(adapterName, config string) (Cache, error) { // config need to be correct JSON as string: {"interval":360}.
adapter, ok := adapters[adapterName] // it will start gc automatically.
func NewCache(adapterName, config string) (adapter Cache, err error) {
instanceFunc, ok := adapters[adapterName]
if !ok { if !ok {
return nil, fmt.Errorf("cache: unknown adaptername %q (forgotten import?)", adapterName) err = fmt.Errorf("cache: unknown adapter name %q (forgot to import?)", adapterName)
return
} }
adapter.StartAndGC(config) adapter = instanceFunc()
return adapter, nil err = adapter.StartAndGC(config)
if err != nil {
adapter = nil
}
return
} }

146
cache/cache_test.go vendored
View File

@@ -1,16 +1,55 @@
// 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 cache package cache
import ( import (
"os"
"sync"
"testing" "testing"
"time" "time"
) )
func Test_cache(t *testing.T) { func TestCacheIncr(t *testing.T) {
bm, err := NewCache("memory", `{"interval":20}`) bm, err := NewCache("memory", `{"interval":20}`)
if err != nil { if err != nil {
t.Error("init err") t.Error("init err")
} }
if err = bm.Put("astaxie", 1, 10); err != nil { //timeoutDuration := 10 * time.Second
bm.Put("edwardhey", 0, time.Second*20)
wg := sync.WaitGroup{}
wg.Add(10)
for i := 0; i < 10; i++ {
go func() {
defer wg.Done()
bm.Incr("edwardhey")
}()
}
wg.Wait()
if bm.Get("edwardhey").(int) != 10 {
t.Error("Incr err")
}
}
func TestCache(t *testing.T) {
bm, err := NewCache("memory", `{"interval":20}`)
if err != nil {
t.Error("init err")
}
timeoutDuration := 10 * time.Second
if err = bm.Put("astaxie", 1, timeoutDuration); err != nil {
t.Error("set Error", err) t.Error("set Error", err)
} }
if !bm.IsExist("astaxie") { if !bm.IsExist("astaxie") {
@@ -27,7 +66,7 @@ func Test_cache(t *testing.T) {
t.Error("check err") t.Error("check err")
} }
if err = bm.Put("astaxie", 1, 10); err != nil { if err = bm.Put("astaxie", 1, timeoutDuration); err != nil {
t.Error("set Error", err) t.Error("set Error", err)
} }
@@ -40,7 +79,7 @@ func Test_cache(t *testing.T) {
} }
if err = bm.Decr("astaxie"); err != nil { if err = bm.Decr("astaxie"); err != nil {
t.Error("Incr Error", err) t.Error("Decr Error", err)
} }
if v := bm.Get("astaxie"); v.(int) != 1 { if v := bm.Get("astaxie"); v.(int) != 1 {
@@ -50,4 +89,103 @@ func Test_cache(t *testing.T) {
if bm.IsExist("astaxie") { if bm.IsExist("astaxie") {
t.Error("delete err") t.Error("delete err")
} }
//test GetMulti
if err = bm.Put("astaxie", "author", timeoutDuration); err != nil {
t.Error("set Error", err)
}
if !bm.IsExist("astaxie") {
t.Error("check err")
}
if v := bm.Get("astaxie"); v.(string) != "author" {
t.Error("get err")
}
if err = bm.Put("astaxie1", "author1", timeoutDuration); err != nil {
t.Error("set Error", err)
}
if !bm.IsExist("astaxie1") {
t.Error("check err")
}
vv := bm.GetMulti([]string{"astaxie", "astaxie1"})
if len(vv) != 2 {
t.Error("GetMulti ERROR")
}
if vv[0].(string) != "author" {
t.Error("GetMulti ERROR")
}
if vv[1].(string) != "author1" {
t.Error("GetMulti ERROR")
}
}
func TestFileCache(t *testing.T) {
bm, err := NewCache("file", `{"CachePath":"cache","FileSuffix":".bin","DirectoryLevel":"2","EmbedExpiry":"0"}`)
if err != nil {
t.Error("init err")
}
timeoutDuration := 10 * time.Second
if err = bm.Put("astaxie", 1, timeoutDuration); err != nil {
t.Error("set Error", err)
}
if !bm.IsExist("astaxie") {
t.Error("check err")
}
if v := bm.Get("astaxie"); v.(int) != 1 {
t.Error("get err")
}
if err = bm.Incr("astaxie"); err != nil {
t.Error("Incr Error", err)
}
if v := bm.Get("astaxie"); v.(int) != 2 {
t.Error("get err")
}
if err = bm.Decr("astaxie"); err != nil {
t.Error("Decr Error", err)
}
if v := bm.Get("astaxie"); v.(int) != 1 {
t.Error("get err")
}
bm.Delete("astaxie")
if bm.IsExist("astaxie") {
t.Error("delete err")
}
//test string
if err = bm.Put("astaxie", "author", timeoutDuration); err != nil {
t.Error("set Error", err)
}
if !bm.IsExist("astaxie") {
t.Error("check err")
}
if v := bm.Get("astaxie"); v.(string) != "author" {
t.Error("get err")
}
//test GetMulti
if err = bm.Put("astaxie1", "author1", timeoutDuration); err != nil {
t.Error("set Error", err)
}
if !bm.IsExist("astaxie1") {
t.Error("check err")
}
vv := bm.GetMulti([]string{"astaxie", "astaxie1"})
if len(vv) != 2 {
t.Error("GetMulti ERROR")
}
if vv[0].(string) != "author" {
t.Error("GetMulti ERROR")
}
if vv[1].(string) != "author1" {
t.Error("GetMulti ERROR")
}
os.RemoveAll("cache")
} }

100
cache/conv.go vendored Normal file
View File

@@ -0,0 +1,100 @@
// 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 cache
import (
"fmt"
"strconv"
)
// GetString convert interface to string.
func GetString(v interface{}) string {
switch result := v.(type) {
case string:
return result
case []byte:
return string(result)
default:
if v != nil {
return fmt.Sprint(result)
}
}
return ""
}
// GetInt convert interface to int.
func GetInt(v interface{}) int {
switch result := v.(type) {
case int:
return result
case int32:
return int(result)
case int64:
return int(result)
default:
if d := GetString(v); d != "" {
value, _ := strconv.Atoi(d)
return value
}
}
return 0
}
// GetInt64 convert interface to int64.
func GetInt64(v interface{}) int64 {
switch result := v.(type) {
case int:
return int64(result)
case int32:
return int64(result)
case int64:
return result
default:
if d := GetString(v); d != "" {
value, _ := strconv.ParseInt(d, 10, 64)
return value
}
}
return 0
}
// GetFloat64 convert interface to float64.
func GetFloat64(v interface{}) float64 {
switch result := v.(type) {
case float64:
return result
default:
if d := GetString(v); d != "" {
value, _ := strconv.ParseFloat(d, 64)
return value
}
}
return 0
}
// GetBool convert interface to bool.
func GetBool(v interface{}) bool {
switch result := v.(type) {
case bool:
return result
default:
if d := GetString(v); d != "" {
value, _ := strconv.ParseBool(d)
return value
}
}
return false
}

143
cache/conv_test.go vendored Normal file
View File

@@ -0,0 +1,143 @@
// 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 cache
import (
"testing"
)
func TestGetString(t *testing.T) {
var t1 = "test1"
if "test1" != GetString(t1) {
t.Error("get string from string error")
}
var t2 = []byte("test2")
if "test2" != GetString(t2) {
t.Error("get string from byte array error")
}
var t3 = 1
if "1" != GetString(t3) {
t.Error("get string from int error")
}
var t4 int64 = 1
if "1" != GetString(t4) {
t.Error("get string from int64 error")
}
var t5 = 1.1
if "1.1" != GetString(t5) {
t.Error("get string from float64 error")
}
if "" != GetString(nil) {
t.Error("get string from nil error")
}
}
func TestGetInt(t *testing.T) {
var t1 = 1
if 1 != GetInt(t1) {
t.Error("get int from int error")
}
var t2 int32 = 32
if 32 != GetInt(t2) {
t.Error("get int from int32 error")
}
var t3 int64 = 64
if 64 != GetInt(t3) {
t.Error("get int from int64 error")
}
var t4 = "128"
if 128 != GetInt(t4) {
t.Error("get int from num string error")
}
if 0 != GetInt(nil) {
t.Error("get int from nil error")
}
}
func TestGetInt64(t *testing.T) {
var i int64 = 1
var t1 = 1
if i != GetInt64(t1) {
t.Error("get int64 from int error")
}
var t2 int32 = 1
if i != GetInt64(t2) {
t.Error("get int64 from int32 error")
}
var t3 int64 = 1
if i != GetInt64(t3) {
t.Error("get int64 from int64 error")
}
var t4 = "1"
if i != GetInt64(t4) {
t.Error("get int64 from num string error")
}
if 0 != GetInt64(nil) {
t.Error("get int64 from nil")
}
}
func TestGetFloat64(t *testing.T) {
var f = 1.11
var t1 float32 = 1.11
if f != GetFloat64(t1) {
t.Error("get float64 from float32 error")
}
var t2 = 1.11
if f != GetFloat64(t2) {
t.Error("get float64 from float64 error")
}
var t3 = "1.11"
if f != GetFloat64(t3) {
t.Error("get float64 from string error")
}
var f2 float64 = 1
var t4 = 1
if f2 != GetFloat64(t4) {
t.Error("get float64 from int error")
}
if 0 != GetFloat64(nil) {
t.Error("get float64 from nil error")
}
}
func TestGetBool(t *testing.T) {
var t1 = true
if !GetBool(t1) {
t.Error("get bool from bool error")
}
var t2 = "true"
if !GetBool(t2) {
t.Error("get bool from string error")
}
if GetBool(nil) {
t.Error("get bool from nil error")
}
}
func byteArrayEquals(a []byte, b []byte) bool {
if len(a) != len(b) {
return false
}
for i, v := range a {
if v != b[i] {
return false
}
}
return true
}

258
cache/file.go vendored Normal file
View File

@@ -0,0 +1,258 @@
// 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 cache
import (
"bytes"
"crypto/md5"
"encoding/gob"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"reflect"
"strconv"
"time"
)
// FileCacheItem is basic unit of file cache adapter.
// it contains data and expire time.
type FileCacheItem struct {
Data interface{}
Lastaccess time.Time
Expired time.Time
}
// FileCache Config
var (
FileCachePath = "cache" // cache directory
FileCacheFileSuffix = ".bin" // cache file suffix
FileCacheDirectoryLevel = 2 // cache file deep level if auto generated cache files.
FileCacheEmbedExpiry time.Duration // cache expire time, default is no expire forever.
)
// FileCache is cache adapter for file storage.
type FileCache struct {
CachePath string
FileSuffix string
DirectoryLevel int
EmbedExpiry int
}
// NewFileCache Create new file cache with no config.
// the level and expiry need set in method StartAndGC as config string.
func NewFileCache() Cache {
// return &FileCache{CachePath:FileCachePath, FileSuffix:FileCacheFileSuffix}
return &FileCache{}
}
// StartAndGC will start and begin gc for file cache.
// the config need to be like {CachePath:"/cache","FileSuffix":".bin","DirectoryLevel":"2","EmbedExpiry":"0"}
func (fc *FileCache) StartAndGC(config string) error {
cfg := make(map[string]string)
err := json.Unmarshal([]byte(config), &cfg)
if err != nil {
return err
}
if _, ok := cfg["CachePath"]; !ok {
cfg["CachePath"] = FileCachePath
}
if _, ok := cfg["FileSuffix"]; !ok {
cfg["FileSuffix"] = FileCacheFileSuffix
}
if _, ok := cfg["DirectoryLevel"]; !ok {
cfg["DirectoryLevel"] = strconv.Itoa(FileCacheDirectoryLevel)
}
if _, ok := cfg["EmbedExpiry"]; !ok {
cfg["EmbedExpiry"] = strconv.FormatInt(int64(FileCacheEmbedExpiry.Seconds()), 10)
}
fc.CachePath = cfg["CachePath"]
fc.FileSuffix = cfg["FileSuffix"]
fc.DirectoryLevel, _ = strconv.Atoi(cfg["DirectoryLevel"])
fc.EmbedExpiry, _ = strconv.Atoi(cfg["EmbedExpiry"])
fc.Init()
return nil
}
// Init will make new dir for file cache if not exist.
func (fc *FileCache) Init() {
if ok, _ := exists(fc.CachePath); !ok { // todo : error handle
_ = os.MkdirAll(fc.CachePath, os.ModePerm) // todo : error handle
}
}
// get cached file name. it's md5 encoded.
func (fc *FileCache) getCacheFileName(key string) string {
m := md5.New()
io.WriteString(m, key)
keyMd5 := hex.EncodeToString(m.Sum(nil))
cachePath := fc.CachePath
switch fc.DirectoryLevel {
case 2:
cachePath = filepath.Join(cachePath, keyMd5[0:2], keyMd5[2:4])
case 1:
cachePath = filepath.Join(cachePath, keyMd5[0:2])
}
if ok, _ := exists(cachePath); !ok { // todo : error handle
_ = os.MkdirAll(cachePath, os.ModePerm) // todo : error handle
}
return filepath.Join(cachePath, fmt.Sprintf("%s%s", keyMd5, fc.FileSuffix))
}
// Get value from file cache.
// if non-exist or expired, return empty string.
func (fc *FileCache) Get(key string) interface{} {
fileData, err := FileGetContents(fc.getCacheFileName(key))
if err != nil {
return ""
}
var to FileCacheItem
GobDecode(fileData, &to)
if to.Expired.Before(time.Now()) {
return ""
}
return to.Data
}
// GetMulti gets values from file cache.
// if non-exist or expired, return empty string.
func (fc *FileCache) GetMulti(keys []string) []interface{} {
var rc []interface{}
for _, key := range keys {
rc = append(rc, fc.Get(key))
}
return rc
}
// Put value into file cache.
// timeout means how long to keep this file, unit of ms.
// if timeout equals fc.EmbedExpiry(default is 0), cache this item forever.
func (fc *FileCache) Put(key string, val interface{}, timeout time.Duration) error {
gob.Register(val)
item := FileCacheItem{Data: val}
if timeout == time.Duration(fc.EmbedExpiry) {
item.Expired = time.Now().Add((86400 * 365 * 10) * time.Second) // ten years
} else {
item.Expired = time.Now().Add(timeout)
}
item.Lastaccess = time.Now()
data, err := GobEncode(item)
if err != nil {
return err
}
return FilePutContents(fc.getCacheFileName(key), data)
}
// Delete file cache value.
func (fc *FileCache) Delete(key string) error {
filename := fc.getCacheFileName(key)
if ok, _ := exists(filename); ok {
return os.Remove(filename)
}
return nil
}
// Incr will increase cached int value.
// fc value is saving forever unless Delete.
func (fc *FileCache) Incr(key string) error {
data := fc.Get(key)
var incr int
if reflect.TypeOf(data).Name() != "int" {
incr = 0
} else {
incr = data.(int) + 1
}
fc.Put(key, incr, time.Duration(fc.EmbedExpiry))
return nil
}
// Decr will decrease cached int value.
func (fc *FileCache) Decr(key string) error {
data := fc.Get(key)
var decr int
if reflect.TypeOf(data).Name() != "int" || data.(int)-1 <= 0 {
decr = 0
} else {
decr = data.(int) - 1
}
fc.Put(key, decr, time.Duration(fc.EmbedExpiry))
return nil
}
// IsExist check value is exist.
func (fc *FileCache) IsExist(key string) bool {
ret, _ := exists(fc.getCacheFileName(key))
return ret
}
// ClearAll will clean cached files.
// not implemented.
func (fc *FileCache) ClearAll() error {
return nil
}
// check file exist.
func exists(path string) (bool, error) {
_, err := os.Stat(path)
if err == nil {
return true, nil
}
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
// FileGetContents Get bytes to file.
// if non-exist, create this file.
func FileGetContents(filename string) (data []byte, e error) {
return ioutil.ReadFile(filename)
}
// FilePutContents Put bytes to file.
// if non-exist, create this file.
func FilePutContents(filename string, content []byte) error {
return ioutil.WriteFile(filename, content, os.ModePerm)
}
// GobEncode Gob encodes file cache item.
func GobEncode(data interface{}) ([]byte, error) {
buf := bytes.NewBuffer(nil)
enc := gob.NewEncoder(buf)
err := enc.Encode(data)
if err != nil {
return nil, err
}
return buf.Bytes(), err
}
// GobDecode Gob decodes file cache item.
func GobDecode(data []byte, to *FileCacheItem) error {
buf := bytes.NewBuffer(data)
dec := gob.NewDecoder(buf)
return dec.Decode(&to)
}
func init() {
Register("file", NewFileCache)
}

114
cache/memcache.go vendored
View File

@@ -1,114 +0,0 @@
package cache
import (
"code.google.com/p/vitess/go/memcache"
"encoding/json"
"errors"
)
type MemcacheCache struct {
c *memcache.Connection
conninfo string
}
func NewMemCache() *MemcacheCache {
return &MemcacheCache{}
}
func (rc *MemcacheCache) Get(key string) interface{} {
if rc.c == nil {
rc.c = rc.connectInit()
}
v, err := rc.c.Get(key)
if err != nil {
return nil
}
var contain interface{}
if len(v) > 0 {
contain = string(v[0].Value)
} else {
contain = nil
}
return contain
}
func (rc *MemcacheCache) Put(key string, val interface{}, timeout int64) error {
if rc.c == nil {
rc.c = rc.connectInit()
}
v, ok := val.(string)
if !ok {
return errors.New("val must string")
}
stored, err := rc.c.Set(key, 0, uint64(timeout), []byte(v))
if err == nil && stored == false {
return errors.New("stored fail")
}
return err
}
func (rc *MemcacheCache) Delete(key string) error {
if rc.c == nil {
rc.c = rc.connectInit()
}
_, err := rc.c.Delete(key)
return err
}
func (rc *MemcacheCache) Incr(key string) error {
return errors.New("not support in memcache")
}
func (rc *MemcacheCache) Decr(key string) error {
return errors.New("not support in memcache")
}
func (rc *MemcacheCache) IsExist(key string) bool {
if rc.c == nil {
rc.c = rc.connectInit()
}
v, err := rc.c.Get(key)
if err != nil {
return false
}
if len(v) == 0 {
return false
} else {
return true
}
return true
}
func (rc *MemcacheCache) ClearAll() error {
if rc.c == nil {
rc.c = rc.connectInit()
}
err := rc.c.FlushAll()
return err
}
func (rc *MemcacheCache) StartAndGC(config string) error {
var cf map[string]string
json.Unmarshal([]byte(config), &cf)
if _, ok := cf["conn"]; !ok {
return errors.New("config has no conn key")
}
rc.conninfo = cf["conn"]
rc.c = rc.connectInit()
if rc.c == nil {
return errors.New("dial tcp conn error")
}
return nil
}
func (rc *MemcacheCache) connectInit() *memcache.Connection {
c, err := memcache.Connect(rc.conninfo)
if err != nil {
return nil
}
return c
}
func init() {
Register("memcache", NewMemCache())
}

188
cache/memcache/memcache.go vendored Normal file
View File

@@ -0,0 +1,188 @@
// 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 memcache for cache provider
//
// depend on github.com/bradfitz/gomemcache/memcache
//
// go install github.com/bradfitz/gomemcache/memcache
//
// Usage:
// import(
// _ "github.com/astaxie/beego/cache/memcache"
// "github.com/astaxie/beego/cache"
// )
//
// bm, err := cache.NewCache("memcache", `{"conn":"127.0.0.1:11211"}`)
//
// more docs http://beego.me/docs/module/cache.md
package memcache
import (
"encoding/json"
"errors"
"strings"
"time"
"github.com/astaxie/beego/cache"
"github.com/bradfitz/gomemcache/memcache"
)
// Cache Memcache adapter.
type Cache struct {
conn *memcache.Client
conninfo []string
}
// NewMemCache create new memcache adapter.
func NewMemCache() cache.Cache {
return &Cache{}
}
// Get get value from memcache.
func (rc *Cache) Get(key string) interface{} {
if rc.conn == nil {
if err := rc.connectInit(); err != nil {
return err
}
}
if item, err := rc.conn.Get(key); err == nil {
return item.Value
}
return nil
}
// GetMulti get value from memcache.
func (rc *Cache) GetMulti(keys []string) []interface{} {
size := len(keys)
var rv []interface{}
if rc.conn == nil {
if err := rc.connectInit(); err != nil {
for i := 0; i < size; i++ {
rv = append(rv, err)
}
return rv
}
}
mv, err := rc.conn.GetMulti(keys)
if err == nil {
for _, v := range mv {
rv = append(rv, v.Value)
}
return rv
}
for i := 0; i < size; i++ {
rv = append(rv, err)
}
return rv
}
// Put put value to memcache.
func (rc *Cache) Put(key string, val interface{}, timeout time.Duration) error {
if rc.conn == nil {
if err := rc.connectInit(); err != nil {
return err
}
}
item := memcache.Item{Key: key, Expiration: int32(timeout / time.Second)}
if v, ok := val.([]byte); ok {
item.Value = v
} else if str, ok := val.(string); ok {
item.Value = []byte(str)
} else {
return errors.New("val only support string and []byte")
}
return rc.conn.Set(&item)
}
// Delete delete value in memcache.
func (rc *Cache) Delete(key string) error {
if rc.conn == nil {
if err := rc.connectInit(); err != nil {
return err
}
}
return rc.conn.Delete(key)
}
// Incr increase counter.
func (rc *Cache) Incr(key string) error {
if rc.conn == nil {
if err := rc.connectInit(); err != nil {
return err
}
}
_, err := rc.conn.Increment(key, 1)
return err
}
// Decr decrease counter.
func (rc *Cache) Decr(key string) error {
if rc.conn == nil {
if err := rc.connectInit(); err != nil {
return err
}
}
_, err := rc.conn.Decrement(key, 1)
return err
}
// IsExist check value exists in memcache.
func (rc *Cache) IsExist(key string) bool {
if rc.conn == nil {
if err := rc.connectInit(); err != nil {
return false
}
}
_, err := rc.conn.Get(key)
return err == nil
}
// ClearAll clear all cached in memcache.
func (rc *Cache) ClearAll() error {
if rc.conn == nil {
if err := rc.connectInit(); err != nil {
return err
}
}
return rc.conn.FlushAll()
}
// StartAndGC start memcache adapter.
// config string is like {"conn":"connection info"}.
// if connecting error, return.
func (rc *Cache) StartAndGC(config string) error {
var cf map[string]string
json.Unmarshal([]byte(config), &cf)
if _, ok := cf["conn"]; !ok {
return errors.New("config has no conn key")
}
rc.conninfo = strings.Split(cf["conn"], ";")
if rc.conn == nil {
if err := rc.connectInit(); err != nil {
return err
}
}
return nil
}
// connect to memcache and keep the connection.
func (rc *Cache) connectInit() error {
rc.conn = memcache.New(rc.conninfo...)
return nil
}
func init() {
cache.Register("memcache", NewMemCache)
}

108
cache/memcache/memcache_test.go vendored Normal file
View File

@@ -0,0 +1,108 @@
// 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 memcache
import (
_ "github.com/bradfitz/gomemcache/memcache"
"strconv"
"testing"
"time"
"github.com/astaxie/beego/cache"
)
func TestMemcacheCache(t *testing.T) {
bm, err := cache.NewCache("memcache", `{"conn": "127.0.0.1:11211"}`)
if err != nil {
t.Error("init err")
}
timeoutDuration := 10 * time.Second
if err = bm.Put("astaxie", "1", timeoutDuration); err != nil {
t.Error("set Error", err)
}
if !bm.IsExist("astaxie") {
t.Error("check err")
}
time.Sleep(11 * time.Second)
if bm.IsExist("astaxie") {
t.Error("check err")
}
if err = bm.Put("astaxie", "1", timeoutDuration); err != nil {
t.Error("set Error", err)
}
if v, err := strconv.Atoi(string(bm.Get("astaxie").([]byte))); err != nil || v != 1 {
t.Error("get err")
}
if err = bm.Incr("astaxie"); err != nil {
t.Error("Incr Error", err)
}
if v, err := strconv.Atoi(string(bm.Get("astaxie").([]byte))); err != nil || v != 2 {
t.Error("get err")
}
if err = bm.Decr("astaxie"); err != nil {
t.Error("Decr Error", err)
}
if v, err := strconv.Atoi(string(bm.Get("astaxie").([]byte))); err != nil || v != 1 {
t.Error("get err")
}
bm.Delete("astaxie")
if bm.IsExist("astaxie") {
t.Error("delete err")
}
//test string
if err = bm.Put("astaxie", "author", timeoutDuration); err != nil {
t.Error("set Error", err)
}
if !bm.IsExist("astaxie") {
t.Error("check err")
}
if v := bm.Get("astaxie").([]byte); string(v) != "author" {
t.Error("get err")
}
//test GetMulti
if err = bm.Put("astaxie1", "author1", timeoutDuration); err != nil {
t.Error("set Error", err)
}
if !bm.IsExist("astaxie1") {
t.Error("check err")
}
vv := bm.GetMulti([]string{"astaxie", "astaxie1"})
if len(vv) != 2 {
t.Error("GetMulti ERROR")
}
if string(vv[0].([]byte)) != "author" && string(vv[0].([]byte)) != "author1" {
t.Error("GetMulti ERROR")
}
if string(vv[1].([]byte)) != "author1" && string(vv[1].([]byte)) != "author" {
t.Error("GetMulti ERROR")
}
// test clear all
if err = bm.ClearAll(); err != nil {
t.Error("clear all err")
}
}

229
cache/memory.go vendored
View File

@@ -1,135 +1,170 @@
// 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 cache package cache
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
"sync" "sync"
"time" "time"
) )
var ( var (
DefaultEvery int = 60 // 1 minute // DefaultEvery means the clock time of recycling the expired cache items in memory.
DefaultEvery = 60 // 1 minute
) )
// MemoryItem store memory cache item.
type MemoryItem struct { type MemoryItem struct {
val interface{} val interface{}
Lastaccess time.Time createdTime time.Time
expired int64 lifespan time.Duration
} }
func (mi *MemoryItem) isExpire() bool {
// 0 means forever
if mi.lifespan == 0 {
return false
}
return time.Now().Sub(mi.createdTime) > mi.lifespan
}
// MemoryCache is Memory cache adapter.
// it contains a RW locker for safe map storage.
type MemoryCache struct { type MemoryCache struct {
lock sync.RWMutex sync.RWMutex
dur time.Duration dur time.Duration
items map[string]*MemoryItem items map[string]*MemoryItem
Every int // Run an expiration check Every seconds Every int // run an expiration check Every clock time
} }
// NewDefaultCache returns a new FileCache with sane defaults. // NewMemoryCache returns a new MemoryCache.
func NewMemoryCache() *MemoryCache { func NewMemoryCache() Cache {
cache := MemoryCache{items: make(map[string]*MemoryItem)} cache := MemoryCache{items: make(map[string]*MemoryItem)}
return &cache return &cache
} }
// Get cache from memory.
// if non-existed or expired, return nil.
func (bc *MemoryCache) Get(name string) interface{} { func (bc *MemoryCache) Get(name string) interface{} {
bc.lock.RLock() bc.RLock()
defer bc.lock.RUnlock() defer bc.RUnlock()
itm, ok := bc.items[name] if itm, ok := bc.items[name]; ok {
if !ok { if itm.isExpire() {
return nil return nil
} }
if (time.Now().Unix() - itm.Lastaccess.Unix()) > itm.expired { return itm.val
go bc.Delete(name)
return nil
}
return itm.val
}
func (bc *MemoryCache) Put(name string, value interface{}, expired int64) error {
bc.lock.Lock()
defer bc.lock.Unlock()
t := MemoryItem{
val: value,
Lastaccess: time.Now(),
expired: expired,
}
if _, ok := bc.items[name]; ok {
return errors.New("the key is exist")
} else {
bc.items[name] = &t
} }
return nil return nil
} }
// GetMulti gets caches from memory.
// if non-existed or expired, return nil.
func (bc *MemoryCache) GetMulti(names []string) []interface{} {
var rc []interface{}
for _, name := range names {
rc = append(rc, bc.Get(name))
}
return rc
}
// Put cache to memory.
// if lifespan is 0, it will be forever till restart.
func (bc *MemoryCache) Put(name string, value interface{}, lifespan time.Duration) error {
bc.Lock()
defer bc.Unlock()
bc.items[name] = &MemoryItem{
val: value,
createdTime: time.Now(),
lifespan: lifespan,
}
return nil
}
// Delete cache in memory.
func (bc *MemoryCache) Delete(name string) error { func (bc *MemoryCache) Delete(name string) error {
bc.lock.Lock() bc.Lock()
defer bc.lock.Unlock() defer bc.Unlock()
if _, ok := bc.items[name]; !ok { if _, ok := bc.items[name]; !ok {
return errors.New("key not exist") return errors.New("key not exist")
} }
delete(bc.items, name) delete(bc.items, name)
_, valid := bc.items[name] if _, ok := bc.items[name]; ok {
if valid {
return errors.New("delete key error") return errors.New("delete key error")
} }
return nil return nil
} }
// Incr increase cache counter in memory.
// it supports int,int32,int64,uint,uint32,uint64.
func (bc *MemoryCache) Incr(key string) error { func (bc *MemoryCache) Incr(key string) error {
bc.lock.RLock() bc.Lock()
defer bc.lock.RUnlock() defer bc.Unlock()
itm, ok := bc.items[key] itm, ok := bc.items[key]
if !ok { if !ok {
return errors.New("key not exist") return errors.New("key not exist")
} }
switch itm.val.(type) { switch val := itm.val.(type) {
case int: case int:
itm.val = itm.val.(int) + 1 itm.val = val + 1
case int64:
itm.val = itm.val.(int64) + 1
case int32: case int32:
itm.val = itm.val.(int32) + 1 itm.val = val + 1
case int64:
itm.val = val + 1
case uint: case uint:
itm.val = itm.val.(uint) + 1 itm.val = val + 1
case uint32: case uint32:
itm.val = itm.val.(uint32) + 1 itm.val = val + 1
case uint64: case uint64:
itm.val = itm.val.(uint64) + 1 itm.val = val + 1
default: default:
return errors.New("item val is not int int64 int32") return errors.New("item val is not (u)int (u)int32 (u)int64")
} }
return nil return nil
} }
// Decr decrease counter in memory.
func (bc *MemoryCache) Decr(key string) error { func (bc *MemoryCache) Decr(key string) error {
bc.lock.RLock() bc.Lock()
defer bc.lock.RUnlock() defer bc.Unlock()
itm, ok := bc.items[key] itm, ok := bc.items[key]
if !ok { if !ok {
return errors.New("key not exist") return errors.New("key not exist")
} }
switch itm.val.(type) { switch val := itm.val.(type) {
case int: case int:
itm.val = itm.val.(int) - 1 itm.val = val - 1
case int64: case int64:
itm.val = itm.val.(int64) - 1 itm.val = val - 1
case int32: case int32:
itm.val = itm.val.(int32) - 1 itm.val = val - 1
case uint: case uint:
if itm.val.(uint) > 0 { if val > 0 {
itm.val = itm.val.(uint) - 1 itm.val = val - 1
} else { } else {
return errors.New("item val is less than 0") return errors.New("item val is less than 0")
} }
case uint32: case uint32:
if itm.val.(uint32) > 0 { if val > 0 {
itm.val = itm.val.(uint32) - 1 itm.val = val - 1
} else { } else {
return errors.New("item val is less than 0") return errors.New("item val is less than 0")
} }
case uint64: case uint64:
if itm.val.(uint64) > 0 { if val > 0 {
itm.val = itm.val.(uint64) - 1 itm.val = val - 1
} else { } else {
return errors.New("item val is less than 0") return errors.New("item val is less than 0")
} }
@@ -139,21 +174,25 @@ func (bc *MemoryCache) Decr(key string) error {
return nil return nil
} }
// IsExist check cache exist in memory.
func (bc *MemoryCache) IsExist(name string) bool { func (bc *MemoryCache) IsExist(name string) bool {
bc.lock.RLock() bc.RLock()
defer bc.lock.RUnlock() defer bc.RUnlock()
_, ok := bc.items[name] if v, ok := bc.items[name]; ok {
return ok return !v.isExpire()
}
return false
} }
// ClearAll will delete all cache in memory.
func (bc *MemoryCache) ClearAll() error { func (bc *MemoryCache) ClearAll() error {
bc.lock.Lock() bc.Lock()
defer bc.lock.Unlock() defer bc.Unlock()
bc.items = make(map[string]*MemoryItem) bc.items = make(map[string]*MemoryItem)
return nil return nil
} }
// Start activates the file cache; it will // StartAndGC start memory cache. it will check expiration in every clock time.
func (bc *MemoryCache) StartAndGC(config string) error { func (bc *MemoryCache) StartAndGC(config string) error {
var cf map[string]int var cf map[string]int
json.Unmarshal([]byte(config), &cf) json.Unmarshal([]byte(config), &cf)
@@ -161,47 +200,57 @@ func (bc *MemoryCache) StartAndGC(config string) error {
cf = make(map[string]int) cf = make(map[string]int)
cf["interval"] = DefaultEvery cf["interval"] = DefaultEvery
} }
dur, err := time.ParseDuration(fmt.Sprintf("%ds", cf["interval"])) dur := time.Duration(cf["interval"]) * time.Second
if err != nil {
return err
}
bc.Every = cf["interval"] bc.Every = cf["interval"]
bc.dur = dur bc.dur = dur
go bc.vaccuum() go bc.vacuum()
return nil return nil
} }
func (bc *MemoryCache) vaccuum() { // check expiration.
if bc.Every < 1 { func (bc *MemoryCache) vacuum() {
bc.RLock()
every := bc.Every
bc.RUnlock()
if every < 1 {
return return
} }
for { for {
<-time.After(bc.dur) <-time.After(bc.dur)
bc.RLock()
if bc.items == nil { if bc.items == nil {
bc.RUnlock()
return return
} }
for name, _ := range bc.items { bc.RUnlock()
bc.item_expired(name) if keys := bc.expiredKeys(); len(keys) != 0 {
bc.clearItems(keys)
} }
} }
} }
// item_expired returns true if an item is expired. // expiredKeys returns key list which are expired.
func (bc *MemoryCache) item_expired(name string) bool { func (bc *MemoryCache) expiredKeys() (keys []string) {
bc.lock.Lock() bc.RLock()
defer bc.lock.Unlock() defer bc.RUnlock()
itm, ok := bc.items[name] for key, itm := range bc.items {
if !ok { if itm.isExpire() {
return true keys = append(keys, key)
}
} }
sec := time.Now().Unix() - itm.Lastaccess.Unix() return
if sec >= itm.expired { }
delete(bc.items, name)
return true // clearItems removes all the items which key in keys.
func (bc *MemoryCache) clearItems(keys []string) {
bc.Lock()
defer bc.Unlock()
for _, key := range keys {
delete(bc.items, key)
} }
return false
} }
func init() { func init() {
Register("memory", NewMemoryCache()) Register("memory", NewMemoryCache)
} }

119
cache/redis.go vendored
View File

@@ -1,119 +0,0 @@
package cache
import (
"encoding/json"
"errors"
"github.com/garyburd/redigo/redis"
)
var (
DefaultKey string = "beecacheRedis"
)
type RedisCache struct {
c redis.Conn
conninfo string
key string
}
func NewRedisCache() *RedisCache {
return &RedisCache{key: DefaultKey}
}
func (rc *RedisCache) Get(key string) interface{} {
if rc.c == nil {
rc.c = rc.connectInit()
}
v, err := rc.c.Do("HGET", rc.key, key)
if err != nil {
return nil
}
return v
}
func (rc *RedisCache) Put(key string, val interface{}, timeout int64) error {
if rc.c == nil {
rc.c = rc.connectInit()
}
_, err := rc.c.Do("HSET", rc.key, key, val)
return err
}
func (rc *RedisCache) Delete(key string) error {
if rc.c == nil {
rc.c = rc.connectInit()
}
_, err := rc.c.Do("HDEL", rc.key, key)
return err
}
func (rc *RedisCache) IsExist(key string) bool {
if rc.c == nil {
rc.c = rc.connectInit()
}
v, err := redis.Bool(rc.c.Do("HEXISTS", rc.key, key))
if err != nil {
return false
}
return v
}
func (rc *RedisCache) Incr(key string) error {
if rc.c == nil {
rc.c = rc.connectInit()
}
_, err := redis.Bool(rc.c.Do("HINCRBY", rc.key, key, 1))
if err != nil {
return err
}
return nil
}
func (rc *RedisCache) Decr(key string) error {
if rc.c == nil {
rc.c = rc.connectInit()
}
_, err := redis.Bool(rc.c.Do("HINCRBY", rc.key, key, -1))
if err != nil {
return err
}
return nil
}
func (rc *RedisCache) ClearAll() error {
if rc.c == nil {
rc.c = rc.connectInit()
}
_, err := rc.c.Do("DEL", rc.key)
return err
}
func (rc *RedisCache) StartAndGC(config string) error {
var cf map[string]string
json.Unmarshal([]byte(config), &cf)
if _, ok := cf["key"]; !ok {
cf["key"] = DefaultKey
}
if _, ok := cf["conn"]; !ok {
return errors.New("config has no conn key")
}
rc.key = cf["key"]
rc.conninfo = cf["conn"]
rc.c = rc.connectInit()
if rc.c == nil {
return errors.New("dial tcp conn error")
}
return nil
}
func (rc *RedisCache) connectInit() redis.Conn {
c, err := redis.Dial("tcp", rc.conninfo)
if err != nil {
return nil
}
return c
}
func init() {
Register("redis", NewRedisCache())
}

273
cache/redis/redis.go vendored Normal file
View File

@@ -0,0 +1,273 @@
// 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 redis for cache provider
//
// depend on github.com/gomodule/redigo/redis
//
// go install github.com/gomodule/redigo/redis
//
// Usage:
// import(
// _ "github.com/astaxie/beego/cache/redis"
// "github.com/astaxie/beego/cache"
// )
//
// bm, err := cache.NewCache("redis", `{"conn":"127.0.0.1:11211"}`)
//
// more docs http://beego.me/docs/module/cache.md
package redis
import (
"encoding/json"
"errors"
"fmt"
"strconv"
"time"
"github.com/gomodule/redigo/redis"
"strings"
"github.com/astaxie/beego/cache"
)
var (
// DefaultKey the collection name of redis for cache adapter.
DefaultKey = "beecacheRedis"
)
// Cache is Redis cache adapter.
type Cache struct {
p *redis.Pool // redis connection pool
conninfo string
dbNum int
key string
password string
maxIdle int
//the timeout to a value less than the redis server's timeout.
timeout time.Duration
}
// NewRedisCache create new redis cache with default collection name.
func NewRedisCache() cache.Cache {
return &Cache{key: DefaultKey}
}
// actually do the redis cmds, args[0] must be the key name.
func (rc *Cache) do(commandName string, args ...interface{}) (reply interface{}, err error) {
if len(args) < 1 {
return nil, errors.New("missing required arguments")
}
args[0] = rc.associate(args[0])
c := rc.p.Get()
defer c.Close()
return c.Do(commandName, args...)
}
// associate with config key.
func (rc *Cache) associate(originKey interface{}) string {
return fmt.Sprintf("%s:%s", rc.key, originKey)
}
// Get cache from redis.
func (rc *Cache) Get(key string) interface{} {
if v, err := rc.do("GET", key); err == nil {
return v
}
return nil
}
// GetMulti get cache from redis.
func (rc *Cache) GetMulti(keys []string) []interface{} {
c := rc.p.Get()
defer c.Close()
var args []interface{}
for _, key := range keys {
args = append(args, rc.associate(key))
}
values, err := redis.Values(c.Do("MGET", args...))
if err != nil {
return nil
}
return values
}
// Put put cache to redis.
func (rc *Cache) Put(key string, val interface{}, timeout time.Duration) error {
_, err := rc.do("SETEX", key, int64(timeout/time.Second), val)
return err
}
// Delete delete cache in redis.
func (rc *Cache) Delete(key string) error {
_, err := rc.do("DEL", key)
return err
}
// IsExist check cache's existence in redis.
func (rc *Cache) IsExist(key string) bool {
v, err := redis.Bool(rc.do("EXISTS", key))
if err != nil {
return false
}
return v
}
// Incr increase counter in redis.
func (rc *Cache) Incr(key string) error {
_, err := redis.Bool(rc.do("INCRBY", key, 1))
return err
}
// Decr decrease counter in redis.
func (rc *Cache) Decr(key string) error {
_, err := redis.Bool(rc.do("INCRBY", key, -1))
return err
}
// ClearAll clean all cache in redis. delete this redis collection.
func (rc *Cache) ClearAll() error {
cachedKeys, err := rc.Scan(rc.key + ":*")
if err != nil {
return err
}
c := rc.p.Get()
defer c.Close()
for _, str := range cachedKeys {
if _, err = c.Do("DEL", str); err != nil {
return err
}
}
return err
}
// Scan scan all keys matching the pattern. a better choice than `keys`
func (rc *Cache) Scan(pattern string) (keys []string, err error) {
c := rc.p.Get()
defer c.Close()
var (
cursor uint64 = 0 // start
result []interface{}
list []string
)
for {
result, err = redis.Values(c.Do("SCAN", cursor, "MATCH", pattern, "COUNT", 1024))
if err != nil {
return
}
list, err = redis.Strings(result[1], nil)
if err != nil {
return
}
keys = append(keys, list...)
cursor, err = redis.Uint64(result[0], nil)
if err != nil {
return
}
if cursor == 0 { // over
return
}
}
}
// StartAndGC start redis cache adapter.
// config is like {"key":"collection key","conn":"connection info","dbNum":"0"}
// the cache item in redis are stored forever,
// so no gc operation.
func (rc *Cache) StartAndGC(config string) error {
var cf map[string]string
json.Unmarshal([]byte(config), &cf)
if _, ok := cf["key"]; !ok {
cf["key"] = DefaultKey
}
if _, ok := cf["conn"]; !ok {
return errors.New("config has no conn key")
}
// Format redis://<password>@<host>:<port>
cf["conn"] = strings.Replace(cf["conn"], "redis://", "", 1)
if i := strings.Index(cf["conn"], "@"); i > -1 {
cf["password"] = cf["conn"][0:i]
cf["conn"] = cf["conn"][i+1:]
}
if _, ok := cf["dbNum"]; !ok {
cf["dbNum"] = "0"
}
if _, ok := cf["password"]; !ok {
cf["password"] = ""
}
if _, ok := cf["maxIdle"]; !ok {
cf["maxIdle"] = "3"
}
if _, ok := cf["timeout"]; !ok {
cf["timeout"] = "180s"
}
rc.key = cf["key"]
rc.conninfo = cf["conn"]
rc.dbNum, _ = strconv.Atoi(cf["dbNum"])
rc.password = cf["password"]
rc.maxIdle, _ = strconv.Atoi(cf["maxIdle"])
if v, err := time.ParseDuration(cf["timeout"]); err == nil {
rc.timeout = v
} else {
rc.timeout = 180 * time.Second
}
rc.connectInit()
c := rc.p.Get()
defer c.Close()
return c.Err()
}
// connect to redis.
func (rc *Cache) connectInit() {
dialFunc := func() (c redis.Conn, err error) {
c, err = redis.Dial("tcp", rc.conninfo)
if err != nil {
return nil, err
}
if rc.password != "" {
if _, err := c.Do("AUTH", rc.password); err != nil {
c.Close()
return nil, err
}
}
_, selecterr := c.Do("SELECT", rc.dbNum)
if selecterr != nil {
c.Close()
return nil, selecterr
}
return
}
// initialize a new pool
rc.p = &redis.Pool{
MaxIdle: rc.maxIdle,
IdleTimeout: rc.timeout,
Dial: dialFunc,
}
}
func init() {
cache.Register("redis", NewRedisCache)
}

144
cache/redis/redis_test.go vendored Normal file
View File

@@ -0,0 +1,144 @@
// 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 redis
import (
"fmt"
"testing"
"time"
"github.com/astaxie/beego/cache"
"github.com/gomodule/redigo/redis"
)
func TestRedisCache(t *testing.T) {
bm, err := cache.NewCache("redis", `{"conn": "127.0.0.1:6379"}`)
if err != nil {
t.Error("init err")
}
timeoutDuration := 10 * time.Second
if err = bm.Put("astaxie", 1, timeoutDuration); err != nil {
t.Error("set Error", err)
}
if !bm.IsExist("astaxie") {
t.Error("check err")
}
time.Sleep(11 * time.Second)
if bm.IsExist("astaxie") {
t.Error("check err")
}
if err = bm.Put("astaxie", 1, timeoutDuration); err != nil {
t.Error("set Error", err)
}
if v, _ := redis.Int(bm.Get("astaxie"), err); v != 1 {
t.Error("get err")
}
if err = bm.Incr("astaxie"); err != nil {
t.Error("Incr Error", err)
}
if v, _ := redis.Int(bm.Get("astaxie"), err); v != 2 {
t.Error("get err")
}
if err = bm.Decr("astaxie"); err != nil {
t.Error("Decr Error", err)
}
if v, _ := redis.Int(bm.Get("astaxie"), err); v != 1 {
t.Error("get err")
}
bm.Delete("astaxie")
if bm.IsExist("astaxie") {
t.Error("delete err")
}
//test string
if err = bm.Put("astaxie", "author", timeoutDuration); err != nil {
t.Error("set Error", err)
}
if !bm.IsExist("astaxie") {
t.Error("check err")
}
if v, _ := redis.String(bm.Get("astaxie"), err); v != "author" {
t.Error("get err")
}
//test GetMulti
if err = bm.Put("astaxie1", "author1", timeoutDuration); err != nil {
t.Error("set Error", err)
}
if !bm.IsExist("astaxie1") {
t.Error("check err")
}
vv := bm.GetMulti([]string{"astaxie", "astaxie1"})
if len(vv) != 2 {
t.Error("GetMulti ERROR")
}
if v, _ := redis.String(vv[0], nil); v != "author" {
t.Error("GetMulti ERROR")
}
if v, _ := redis.String(vv[1], nil); v != "author1" {
t.Error("GetMulti ERROR")
}
// test clear all
if err = bm.ClearAll(); err != nil {
t.Error("clear all err")
}
}
func TestCache_Scan(t *testing.T) {
timeoutDuration := 10 * time.Second
// init
bm, err := cache.NewCache("redis", `{"conn": "127.0.0.1:6379"}`)
if err != nil {
t.Error("init err")
}
// insert all
for i := 0; i < 10000; i++ {
if err = bm.Put(fmt.Sprintf("astaxie%d", i), fmt.Sprintf("author%d", i), timeoutDuration); err != nil {
t.Error("set Error", err)
}
}
// scan all for the first time
keys, err := bm.(*Cache).Scan(DefaultKey + ":*")
if err != nil {
t.Error("scan Error", err)
}
if len(keys) != 10000 {
t.Error("scan all err")
}
// clear all
if err = bm.ClearAll(); err != nil {
t.Error("clear all err")
}
// scan all for the second time
keys, err = bm.(*Cache).Scan(DefaultKey + ":*")
if err != nil {
t.Error("scan Error", err)
}
if len(keys) != 0 {
t.Error("scan all err")
}
}

231
cache/ssdb/ssdb.go vendored Normal file
View File

@@ -0,0 +1,231 @@
package ssdb
import (
"encoding/json"
"errors"
"strconv"
"strings"
"time"
"github.com/ssdb/gossdb/ssdb"
"github.com/astaxie/beego/cache"
)
// Cache SSDB adapter
type Cache struct {
conn *ssdb.Client
conninfo []string
}
//NewSsdbCache create new ssdb adapter.
func NewSsdbCache() cache.Cache {
return &Cache{}
}
// Get get value from memcache.
func (rc *Cache) Get(key string) interface{} {
if rc.conn == nil {
if err := rc.connectInit(); err != nil {
return nil
}
}
value, err := rc.conn.Get(key)
if err == nil {
return value
}
return nil
}
// GetMulti get value from memcache.
func (rc *Cache) GetMulti(keys []string) []interface{} {
size := len(keys)
var values []interface{}
if rc.conn == nil {
if err := rc.connectInit(); err != nil {
for i := 0; i < size; i++ {
values = append(values, err)
}
return values
}
}
res, err := rc.conn.Do("multi_get", keys)
resSize := len(res)
if err == nil {
for i := 1; i < resSize; i += 2 {
values = append(values, res[i+1])
}
return values
}
for i := 0; i < size; i++ {
values = append(values, err)
}
return values
}
// DelMulti get value from memcache.
func (rc *Cache) DelMulti(keys []string) error {
if rc.conn == nil {
if err := rc.connectInit(); err != nil {
return err
}
}
_, err := rc.conn.Do("multi_del", keys)
return err
}
// Put put value to memcache. only support string.
func (rc *Cache) Put(key string, value interface{}, timeout time.Duration) error {
if rc.conn == nil {
if err := rc.connectInit(); err != nil {
return err
}
}
v, ok := value.(string)
if !ok {
return errors.New("value must string")
}
var resp []string
var err error
ttl := int(timeout / time.Second)
if ttl < 0 {
resp, err = rc.conn.Do("set", key, v)
} else {
resp, err = rc.conn.Do("setx", key, v, ttl)
}
if err != nil {
return err
}
if len(resp) == 2 && resp[0] == "ok" {
return nil
}
return errors.New("bad response")
}
// Delete delete value in memcache.
func (rc *Cache) Delete(key string) error {
if rc.conn == nil {
if err := rc.connectInit(); err != nil {
return err
}
}
_, err := rc.conn.Del(key)
return err
}
// Incr increase counter.
func (rc *Cache) Incr(key string) error {
if rc.conn == nil {
if err := rc.connectInit(); err != nil {
return err
}
}
_, err := rc.conn.Do("incr", key, 1)
return err
}
// Decr decrease counter.
func (rc *Cache) Decr(key string) error {
if rc.conn == nil {
if err := rc.connectInit(); err != nil {
return err
}
}
_, err := rc.conn.Do("incr", key, -1)
return err
}
// IsExist check value exists in memcache.
func (rc *Cache) IsExist(key string) bool {
if rc.conn == nil {
if err := rc.connectInit(); err != nil {
return false
}
}
resp, err := rc.conn.Do("exists", key)
if err != nil {
return false
}
if len(resp) == 2 && resp[1] == "1" {
return true
}
return false
}
// ClearAll clear all cached in memcache.
func (rc *Cache) ClearAll() error {
if rc.conn == nil {
if err := rc.connectInit(); err != nil {
return err
}
}
keyStart, keyEnd, limit := "", "", 50
resp, err := rc.Scan(keyStart, keyEnd, limit)
for err == nil {
size := len(resp)
if size == 1 {
return nil
}
keys := []string{}
for i := 1; i < size; i += 2 {
keys = append(keys, resp[i])
}
_, e := rc.conn.Do("multi_del", keys)
if e != nil {
return e
}
keyStart = resp[size-2]
resp, err = rc.Scan(keyStart, keyEnd, limit)
}
return err
}
// Scan key all cached in ssdb.
func (rc *Cache) Scan(keyStart string, keyEnd string, limit int) ([]string, error) {
if rc.conn == nil {
if err := rc.connectInit(); err != nil {
return nil, err
}
}
resp, err := rc.conn.Do("scan", keyStart, keyEnd, limit)
if err != nil {
return nil, err
}
return resp, nil
}
// StartAndGC start memcache adapter.
// config string is like {"conn":"connection info"}.
// if connecting error, return.
func (rc *Cache) StartAndGC(config string) error {
var cf map[string]string
json.Unmarshal([]byte(config), &cf)
if _, ok := cf["conn"]; !ok {
return errors.New("config has no conn key")
}
rc.conninfo = strings.Split(cf["conn"], ";")
if rc.conn == nil {
if err := rc.connectInit(); err != nil {
return err
}
}
return nil
}
// connect to memcache and keep the connection.
func (rc *Cache) connectInit() error {
conninfoArray := strings.Split(rc.conninfo[0], ":")
host := conninfoArray[0]
port, e := strconv.Atoi(conninfoArray[1])
if e != nil {
return e
}
var err error
rc.conn, err = ssdb.Connect(host, port)
return err
}
func init() {
cache.Register("ssdb", NewSsdbCache)
}

104
cache/ssdb/ssdb_test.go vendored Normal file
View File

@@ -0,0 +1,104 @@
package ssdb
import (
"strconv"
"testing"
"time"
"github.com/astaxie/beego/cache"
)
func TestSsdbcacheCache(t *testing.T) {
ssdb, err := cache.NewCache("ssdb", `{"conn": "127.0.0.1:8888"}`)
if err != nil {
t.Error("init err")
}
// test put and exist
if ssdb.IsExist("ssdb") {
t.Error("check err")
}
timeoutDuration := 10 * time.Second
//timeoutDuration := -10*time.Second if timeoutDuration is negtive,it means permanent
if err = ssdb.Put("ssdb", "ssdb", timeoutDuration); err != nil {
t.Error("set Error", err)
}
if !ssdb.IsExist("ssdb") {
t.Error("check err")
}
// Get test done
if err = ssdb.Put("ssdb", "ssdb", timeoutDuration); err != nil {
t.Error("set Error", err)
}
if v := ssdb.Get("ssdb"); v != "ssdb" {
t.Error("get Error")
}
//inc/dec test done
if err = ssdb.Put("ssdb", "2", timeoutDuration); err != nil {
t.Error("set Error", err)
}
if err = ssdb.Incr("ssdb"); err != nil {
t.Error("incr Error", err)
}
if v, err := strconv.Atoi(ssdb.Get("ssdb").(string)); err != nil || v != 3 {
t.Error("get err")
}
if err = ssdb.Decr("ssdb"); err != nil {
t.Error("decr error")
}
// test del
if err = ssdb.Put("ssdb", "3", timeoutDuration); err != nil {
t.Error("set Error", err)
}
if v, err := strconv.Atoi(ssdb.Get("ssdb").(string)); err != nil || v != 3 {
t.Error("get err")
}
if err := ssdb.Delete("ssdb"); err == nil {
if ssdb.IsExist("ssdb") {
t.Error("delete err")
}
}
//test string
if err = ssdb.Put("ssdb", "ssdb", -10*time.Second); err != nil {
t.Error("set Error", err)
}
if !ssdb.IsExist("ssdb") {
t.Error("check err")
}
if v := ssdb.Get("ssdb").(string); v != "ssdb" {
t.Error("get err")
}
//test GetMulti done
if err = ssdb.Put("ssdb1", "ssdb1", -10*time.Second); err != nil {
t.Error("set Error", err)
}
if !ssdb.IsExist("ssdb1") {
t.Error("check err")
}
vv := ssdb.GetMulti([]string{"ssdb", "ssdb1"})
if len(vv) != 2 {
t.Error("getmulti error")
}
if vv[0].(string) != "ssdb" {
t.Error("getmulti error")
}
if vv[1].(string) != "ssdb1" {
t.Error("getmulti error")
}
// test clear all done
if err = ssdb.ClearAll(); err != nil {
t.Error("clear all err")
}
if ssdb.IsExist("ssdb") || ssdb.IsExist("ssdb1") {
t.Error("check err")
}
}

700
config.go
View File

@@ -1,203 +1,533 @@
// 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 beego package beego
import ( import (
"bufio" "crypto/tls"
"bytes" "fmt"
"errors" "net/http"
"io"
"os" "os"
"strconv" "path/filepath"
"reflect"
"runtime"
"strings" "strings"
"sync"
"unicode" "github.com/astaxie/beego/config"
"github.com/astaxie/beego/context"
"github.com/astaxie/beego/logs"
"github.com/astaxie/beego/session"
"github.com/astaxie/beego/utils"
) )
var ( // Config is the main struct for BConfig
bComment = []byte{'#'}
bEmpty = []byte{}
bEqual = []byte{'='}
bDQuote = []byte{'"'}
)
// A Config represents the configuration.
type Config struct { type Config struct {
filename string AppName string //Application name
comment map[int][]string // id: []{comment, key...}; id 1 is for main comment. RunMode string //Running Mode: dev | prod
data map[string]string // key: value RouterCaseSensitive bool
offset map[string]int64 // key: offset; for editing. ServerName string
sync.RWMutex RecoverPanic bool
RecoverFunc func(*context.Context)
CopyRequestBody bool
EnableGzip bool
MaxMemory int64
EnableErrorsShow bool
EnableErrorsRender bool
Listen Listen
WebConfig WebConfig
Log LogConfig
} }
// ParseFile creates a new Config and parses the file configuration from the // Listen holds for http and https related config
// named file. type Listen struct {
func LoadConfig(name string) (*Config, error) { Graceful bool // Graceful means use graceful module to start the server
file, err := os.Open(name) ServerTimeOut int64
ListenTCP4 bool
EnableHTTP bool
HTTPAddr string
HTTPPort int
AutoTLS bool
Domains []string
TLSCacheDir string
EnableHTTPS bool
EnableMutualHTTPS bool
HTTPSAddr string
HTTPSPort int
HTTPSCertFile string
HTTPSKeyFile string
TrustCaFile string
ClientAuth tls.ClientAuthType
EnableAdmin bool
AdminAddr string
AdminPort int
EnableFcgi bool
EnableStdIo bool // EnableStdIo works with EnableFcgi Use FCGI via standard I/O
}
// WebConfig holds web related config
type WebConfig struct {
AutoRender bool
EnableDocs bool
FlashName string
FlashSeparator string
DirectoryIndex bool
StaticDir map[string]string
StaticExtensionsToGzip []string
StaticCacheFileSize int
StaticCacheFileNum int
TemplateLeft string
TemplateRight string
ViewsPath string
EnableXSRF bool
XSRFKey string
XSRFExpire int
Session SessionConfig
}
// SessionConfig holds session related config
type SessionConfig struct {
SessionOn bool
SessionProvider string
SessionName string
SessionGCMaxLifetime int64
SessionProviderConfig string
SessionCookieLifeTime int
SessionAutoSetCookie bool
SessionDomain string
SessionDisableHTTPOnly bool // used to allow for cross domain cookies/javascript cookies.
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
type LogConfig struct {
AccessLogs bool
EnableStaticLogs bool //log static files requests default: false
AccessLogsFormat string //access log format: JSON_FORMAT, APACHE_FORMAT or empty string
FileLineNum bool
Outputs map[string]string // Store Adaptor : config
}
var (
// BConfig is the default config for Application
BConfig *Config
// AppConfig is the instance of Config, store the config information from file
AppConfig *beegoAppConfig
// AppPath is the absolute path to the app
AppPath string
// GlobalSessions is the instance for the session manager
GlobalSessions *session.Manager
// appConfigPath is the path to the config files
appConfigPath string
// appConfigProvider is the provider for the config, default is ini
appConfigProvider = "ini"
// WorkPath is the absolute path to project root directory
WorkPath string
)
func init() {
BConfig = newBConfig()
var err error
if AppPath, err = filepath.Abs(filepath.Dir(os.Args[0])); err != nil {
panic(err)
}
WorkPath, err = os.Getwd()
if err != nil {
panic(err)
}
var filename = "app.conf"
if os.Getenv("BEEGO_RUNMODE") != "" {
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) {
AppConfig = &beegoAppConfig{innerConfig: config.NewFakeConfig()}
return
}
}
if err = parseConfig(appConfigPath); err != nil {
panic(err)
}
}
func recoverPanic(ctx *context.Context) {
if err := recover(); err != nil {
if err == ErrAbort {
return
}
if !BConfig.RecoverPanic {
panic(err)
}
if BConfig.EnableErrorsShow {
if _, ok := ErrorMaps[fmt.Sprint(err)]; ok {
exception(fmt.Sprint(err), ctx)
return
}
}
var stack string
logs.Critical("the request url is ", ctx.Input.URL())
logs.Critical("Handler crashed with error", err)
for i := 1; ; i++ {
_, file, line, ok := runtime.Caller(i)
if !ok {
break
}
logs.Critical(fmt.Sprintf("%s:%d", file, line))
stack = stack + fmt.Sprintln(fmt.Sprintf("%s:%d", file, line))
}
if BConfig.RunMode == DEV && BConfig.EnableErrorsRender {
showErr(err, ctx, stack)
}
if ctx.Output.Status != 0 {
ctx.ResponseWriter.WriteHeader(ctx.Output.Status)
} else {
ctx.ResponseWriter.WriteHeader(500)
}
}
}
func newBConfig() *Config {
return &Config{
AppName: "beego",
RunMode: PROD,
RouterCaseSensitive: true,
ServerName: "beegoServer:" + VERSION,
RecoverPanic: true,
RecoverFunc: recoverPanic,
CopyRequestBody: false,
EnableGzip: false,
MaxMemory: 1 << 26, //64MB
EnableErrorsShow: true,
EnableErrorsRender: true,
Listen: Listen{
Graceful: false,
ServerTimeOut: 0,
ListenTCP4: false,
EnableHTTP: true,
AutoTLS: false,
Domains: []string{},
TLSCacheDir: ".",
HTTPAddr: "",
HTTPPort: 8080,
EnableHTTPS: false,
HTTPSAddr: "",
HTTPSPort: 10443,
HTTPSCertFile: "",
HTTPSKeyFile: "",
EnableAdmin: false,
AdminAddr: "",
AdminPort: 8088,
EnableFcgi: false,
EnableStdIo: false,
ClientAuth: tls.RequireAndVerifyClientCert,
},
WebConfig: WebConfig{
AutoRender: true,
EnableDocs: false,
FlashName: "BEEGO_FLASH",
FlashSeparator: "BEEGOFLASH",
DirectoryIndex: false,
StaticDir: map[string]string{"/static": "static"},
StaticExtensionsToGzip: []string{".css", ".js"},
StaticCacheFileSize: 1024 * 100,
StaticCacheFileNum: 1000,
TemplateLeft: "{{",
TemplateRight: "}}",
ViewsPath: "views",
EnableXSRF: false,
XSRFKey: "beegoxsrf",
XSRFExpire: 0,
Session: SessionConfig{
SessionOn: false,
SessionProvider: "memory",
SessionName: "beegosessionID",
SessionGCMaxLifetime: 3600,
SessionProviderConfig: "",
SessionDisableHTTPOnly: false,
SessionCookieLifeTime: 0, //set cookie default is the browser life
SessionAutoSetCookie: true,
SessionDomain: "",
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{
AccessLogs: false,
EnableStaticLogs: false,
AccessLogsFormat: "APACHE_FORMAT",
FileLineNum: true,
Outputs: map[string]string{"console": ""},
},
}
}
// now only support ini, next will support json.
func parseConfig(appConfigPath string) (err error) {
AppConfig, err = newAppConfig(appConfigProvider, appConfigPath)
if err != nil {
return err
}
return assignConfig(AppConfig)
}
func assignConfig(ac config.Configer) error {
for _, i := range []interface{}{BConfig, &BConfig.Listen, &BConfig.WebConfig, &BConfig.Log, &BConfig.WebConfig.Session} {
assignSingleConfig(i, ac)
}
// set the run mode first
if envRunMode := os.Getenv("BEEGO_RUNMODE"); envRunMode != "" {
BConfig.RunMode = envRunMode
} else if runMode := ac.String("RunMode"); runMode != "" {
BConfig.RunMode = runMode
}
if sd := ac.String("StaticDir"); sd != "" {
BConfig.WebConfig.StaticDir = map[string]string{}
sds := strings.Fields(sd)
for _, v := range sds {
if url2fsmap := strings.SplitN(v, ":", 2); len(url2fsmap) == 2 {
BConfig.WebConfig.StaticDir["/"+strings.Trim(url2fsmap[0], "/")] = url2fsmap[1]
} else {
BConfig.WebConfig.StaticDir["/"+strings.Trim(url2fsmap[0], "/")] = url2fsmap[0]
}
}
}
if sgz := ac.String("StaticExtensionsToGzip"); sgz != "" {
extensions := strings.Split(sgz, ",")
fileExts := []string{}
for _, ext := range extensions {
ext = strings.TrimSpace(ext)
if ext == "" {
continue
}
if !strings.HasPrefix(ext, ".") {
ext = "." + ext
}
fileExts = append(fileExts, ext)
}
if len(fileExts) > 0 {
BConfig.WebConfig.StaticExtensionsToGzip = fileExts
}
}
if sfs, err := ac.Int("StaticCacheFileSize"); err == nil {
BConfig.WebConfig.StaticCacheFileSize = sfs
}
if sfn, err := ac.Int("StaticCacheFileNum"); err == nil {
BConfig.WebConfig.StaticCacheFileNum = sfn
}
if lo := ac.String("LogOutputs"); lo != "" {
// if lo is not nil or empty
// means user has set his own LogOutputs
// clear the default setting to BConfig.Log.Outputs
BConfig.Log.Outputs = make(map[string]string)
los := strings.Split(lo, ";")
for _, v := range los {
if logType2Config := strings.SplitN(v, ",", 2); len(logType2Config) == 2 {
BConfig.Log.Outputs[logType2Config[0]] = logType2Config[1]
} else {
continue
}
}
}
//init log
logs.Reset()
for adaptor, config := range BConfig.Log.Outputs {
err := logs.SetLogger(adaptor, config)
if err != nil {
fmt.Fprintln(os.Stderr, fmt.Sprintf("%s with the config %q got err:%s", adaptor, config, err.Error()))
}
}
logs.SetLogFuncCall(BConfig.Log.FileLineNum)
return nil
}
func assignSingleConfig(p interface{}, ac config.Configer) {
pt := reflect.TypeOf(p)
if pt.Kind() != reflect.Ptr {
return
}
pt = pt.Elem()
if pt.Kind() != reflect.Struct {
return
}
pv := reflect.ValueOf(p).Elem()
for i := 0; i < pt.NumField(); i++ {
pf := pv.Field(i)
if !pf.CanSet() {
continue
}
name := pt.Field(i).Name
switch pf.Kind() {
case reflect.String:
pf.SetString(ac.DefaultString(name, pf.String()))
case reflect.Int, reflect.Int64:
pf.SetInt(ac.DefaultInt64(name, pf.Int()))
case reflect.Bool:
pf.SetBool(ac.DefaultBool(name, pf.Bool()))
case reflect.Struct:
default:
//do nothing here
}
}
}
// LoadAppConfig allow developer to apply a config file
func LoadAppConfig(adapterName, configPath string) error {
absConfigPath, err := filepath.Abs(configPath)
if err != nil {
return err
}
if !utils.FileExists(absConfigPath) {
return fmt.Errorf("the target config file: %s don't exist", configPath)
}
appConfigPath = absConfigPath
appConfigProvider = adapterName
return parseConfig(appConfigPath)
}
type beegoAppConfig struct {
innerConfig config.Configer
}
func newAppConfig(appConfigProvider, appConfigPath string) (*beegoAppConfig, error) {
ac, err := config.NewConfig(appConfigProvider, appConfigPath)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &beegoAppConfig{ac}, nil
cfg := &Config{
file.Name(),
make(map[int][]string),
make(map[string]string),
make(map[string]int64),
sync.RWMutex{},
}
cfg.Lock()
defer cfg.Unlock()
defer file.Close()
var comment bytes.Buffer
buf := bufio.NewReader(file)
for nComment, off := 0, int64(1); ; {
line, _, err := buf.ReadLine()
if err == io.EOF {
break
}
if bytes.Equal(line, bEmpty) {
continue
}
off += int64(len(line))
if bytes.HasPrefix(line, bComment) {
line = bytes.TrimLeft(line, "#")
line = bytes.TrimLeftFunc(line, unicode.IsSpace)
comment.Write(line)
comment.WriteByte('\n')
continue
}
if comment.Len() != 0 {
cfg.comment[nComment] = []string{comment.String()}
comment.Reset()
nComment++
}
val := bytes.SplitN(line, bEqual, 2)
if bytes.HasPrefix([]byte(strings.TrimSpace(string(val[1]))), bDQuote) {
val[1] = bytes.Trim([]byte(strings.TrimSpace(string(val[1]))), `"`)
}
key := strings.TrimSpace(string(val[0]))
cfg.comment[nComment-1] = append(cfg.comment[nComment-1], key)
cfg.data[key] = strings.TrimSpace(string(val[1]))
cfg.offset[key] = off
}
return cfg, nil
} }
// Bool returns the boolean value for a given key. func (b *beegoAppConfig) Set(key, val string) error {
func (c *Config) Bool(key string) (bool, error) { if err := b.innerConfig.Set(BConfig.RunMode+"::"+key, val); err != nil {
return strconv.ParseBool(c.data[key]) return b.innerConfig.Set(key, val)
}
// Int returns the integer value for a given key.
func (c *Config) Int(key string) (int, error) {
return strconv.Atoi(c.data[key])
}
func (c *Config) Int64(key string) (int64, error) {
return strconv.ParseInt(c.data[key], 10, 64)
}
// Float returns the float value for a given key.
func (c *Config) Float(key string) (float64, error) {
return strconv.ParseFloat(c.data[key], 64)
}
// String returns the string value for a given key.
func (c *Config) String(key string) string {
return c.data[key]
}
// WriteValue writes a new value for key.
func (c *Config) SetValue(key, value string) error {
c.Lock()
defer c.Unlock()
if _, found := c.data[key]; !found {
return errors.New("key not found: " + key)
}
c.data[key] = value
return nil
}
func ParseConfig() (err error) {
AppConfig, err = LoadConfig(AppConfigPath)
if err != nil {
return err
} else {
HttpAddr = AppConfig.String("httpaddr")
if v, err := AppConfig.Int("httpport"); err == nil {
HttpPort = v
}
if maxmemory, err := AppConfig.Int64("maxmemory"); err == nil {
MaxMemory = maxmemory
}
AppName = AppConfig.String("appname")
if runmode := AppConfig.String("runmode"); runmode != "" {
RunMode = runmode
}
if autorender, err := AppConfig.Bool("autorender"); err == nil {
AutoRender = autorender
}
if autorecover, err := AppConfig.Bool("autorecover"); err == nil {
RecoverPanic = autorecover
}
if pprofon, err := AppConfig.Bool("pprofon"); err == nil {
PprofOn = pprofon
}
if views := AppConfig.String("viewspath"); views != "" {
ViewsPath = views
}
if sessionon, err := AppConfig.Bool("sessionon"); err == nil {
SessionOn = sessionon
}
if sessProvider := AppConfig.String("sessionprovider"); sessProvider != "" {
SessionProvider = sessProvider
}
if sessName := AppConfig.String("sessionname"); sessName != "" {
SessionName = sessName
}
if sesssavepath := AppConfig.String("sessionsavepath"); sesssavepath != "" {
SessionSavePath = sesssavepath
}
if sessMaxLifeTime, err := AppConfig.Int("sessiongcmaxlifetime"); err == nil && sessMaxLifeTime != 0 {
int64val, _ := strconv.ParseInt(strconv.Itoa(sessMaxLifeTime), 10, 64)
SessionGCMaxLifetime = int64val
}
if usefcgi, err := AppConfig.Bool("usefcgi"); err == nil {
UseFcgi = usefcgi
}
if enablegzip, err := AppConfig.Bool("enablegzip"); err == nil {
EnableGzip = enablegzip
}
if directoryindex, err := AppConfig.Bool("directoryindex"); err == nil {
DirectoryIndex = directoryindex
}
if hotupdate, err := AppConfig.Bool("hotupdate"); err == nil {
EnbaleHotUpdate = hotupdate
}
if timeout, err := AppConfig.Int64("httpservertimeout"); err == nil {
HttpServerTimeOut = timeout
}
if errorsshow, err := AppConfig.Bool("errorsshow"); err == nil {
ErrorsShow = errorsshow
}
if copyrequestbody, err := AppConfig.Bool("copyrequestbody"); err == nil {
CopyRequestBody = copyrequestbody
}
if xsrfkey := AppConfig.String("xsrfkey"); xsrfkey != "" {
XSRFKEY = xsrfkey
}
if enablexsrf, err := AppConfig.Bool("enablexsrf"); err == nil {
EnableXSRF = enablexsrf
}
if expire, err := AppConfig.Int("xsrfexpire"); err == nil {
XSRFExpire = expire
}
} }
return nil return nil
} }
func (b *beegoAppConfig) String(key string) string {
if v := b.innerConfig.String(BConfig.RunMode + "::" + key); v != "" {
return v
}
return b.innerConfig.String(key)
}
func (b *beegoAppConfig) Strings(key string) []string {
if v := b.innerConfig.Strings(BConfig.RunMode + "::" + key); len(v) > 0 {
return v
}
return b.innerConfig.Strings(key)
}
func (b *beegoAppConfig) Int(key string) (int, error) {
if v, err := b.innerConfig.Int(BConfig.RunMode + "::" + key); err == nil {
return v, nil
}
return b.innerConfig.Int(key)
}
func (b *beegoAppConfig) Int64(key string) (int64, error) {
if v, err := b.innerConfig.Int64(BConfig.RunMode + "::" + key); err == nil {
return v, nil
}
return b.innerConfig.Int64(key)
}
func (b *beegoAppConfig) Bool(key string) (bool, error) {
if v, err := b.innerConfig.Bool(BConfig.RunMode + "::" + key); err == nil {
return v, nil
}
return b.innerConfig.Bool(key)
}
func (b *beegoAppConfig) Float(key string) (float64, error) {
if v, err := b.innerConfig.Float(BConfig.RunMode + "::" + key); err == nil {
return v, nil
}
return b.innerConfig.Float(key)
}
func (b *beegoAppConfig) DefaultString(key string, defaultVal string) string {
if v := b.String(key); v != "" {
return v
}
return defaultVal
}
func (b *beegoAppConfig) DefaultStrings(key string, defaultVal []string) []string {
if v := b.Strings(key); len(v) != 0 {
return v
}
return defaultVal
}
func (b *beegoAppConfig) DefaultInt(key string, defaultVal int) int {
if v, err := b.Int(key); err == nil {
return v
}
return defaultVal
}
func (b *beegoAppConfig) DefaultInt64(key string, defaultVal int64) int64 {
if v, err := b.Int64(key); err == nil {
return v
}
return defaultVal
}
func (b *beegoAppConfig) DefaultBool(key string, defaultVal bool) bool {
if v, err := b.Bool(key); err == nil {
return v
}
return defaultVal
}
func (b *beegoAppConfig) DefaultFloat(key string, defaultVal float64) float64 {
if v, err := b.Float(key); err == nil {
return v
}
return defaultVal
}
func (b *beegoAppConfig) DIY(key string) (interface{}, error) {
return b.innerConfig.DIY(key)
}
func (b *beegoAppConfig) GetSection(section string) (map[string]string, error) {
return b.innerConfig.GetSection(section)
}
func (b *beegoAppConfig) SaveConfigFile(filename string) error {
return b.innerConfig.SaveConfigFile(filename)
}

242
config/config.go Normal file
View File

@@ -0,0 +1,242 @@
// 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 config is used to parse config.
// Usage:
// import "github.com/astaxie/beego/config"
//Examples.
//
// cnf, err := config.NewConfig("ini", "config.conf")
//
// cnf APIS:
//
// cnf.Set(key, val string) error
// cnf.String(key string) string
// cnf.Strings(key string) []string
// cnf.Int(key string) (int, error)
// cnf.Int64(key string) (int64, error)
// cnf.Bool(key string) (bool, error)
// cnf.Float(key string) (float64, error)
// cnf.DefaultString(key string, defaultVal string) string
// cnf.DefaultStrings(key string, defaultVal []string) []string
// cnf.DefaultInt(key string, defaultVal int) int
// cnf.DefaultInt64(key string, defaultVal int64) int64
// cnf.DefaultBool(key string, defaultVal bool) bool
// cnf.DefaultFloat(key string, defaultVal float64) float64
// cnf.DIY(key string) (interface{}, error)
// cnf.GetSection(section string) (map[string]string, error)
// cnf.SaveConfigFile(filename string) error
//More docs http://beego.me/docs/module/config.md
package config
import (
"fmt"
"os"
"reflect"
"time"
)
// Configer defines how to get and set value from configuration raw data.
type Configer interface {
Set(key, val string) error //support section::key type in given key when using ini type.
String(key string) string //support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same.
Strings(key string) []string //get string slice
Int(key string) (int, error)
Int64(key string) (int64, error)
Bool(key string) (bool, error)
Float(key string) (float64, error)
DefaultString(key string, defaultVal string) string // support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same.
DefaultStrings(key string, defaultVal []string) []string //get string slice
DefaultInt(key string, defaultVal int) int
DefaultInt64(key string, defaultVal int64) int64
DefaultBool(key string, defaultVal bool) bool
DefaultFloat(key string, defaultVal float64) float64
DIY(key string) (interface{}, error)
GetSection(section string) (map[string]string, error)
SaveConfigFile(filename string) error
}
// Config is the adapter interface for parsing config file to get raw data to Configer.
type Config interface {
Parse(key string) (Configer, error)
ParseData(data []byte) (Configer, error)
}
var adapters = make(map[string]Config)
// Register makes a config adapter available by the adapter name.
// If Register is called twice with the same name or if driver is nil,
// it panics.
func Register(name string, adapter Config) {
if adapter == nil {
panic("config: Register adapter is nil")
}
if _, ok := adapters[name]; ok {
panic("config: Register called twice for adapter " + name)
}
adapters[name] = adapter
}
// NewConfig adapterName is ini/json/xml/yaml.
// filename is the config file path.
func NewConfig(adapterName, filename string) (Configer, error) {
adapter, ok := adapters[adapterName]
if !ok {
return nil, fmt.Errorf("config: unknown adaptername %q (forgotten import?)", adapterName)
}
return adapter.Parse(filename)
}
// NewConfigData adapterName is ini/json/xml/yaml.
// data is the config data.
func NewConfigData(adapterName string, data []byte) (Configer, error) {
adapter, ok := adapters[adapterName]
if !ok {
return nil, fmt.Errorf("config: unknown adaptername %q (forgotten import?)", adapterName)
}
return adapter.ParseData(data)
}
// ExpandValueEnvForMap convert all string value with environment variable.
func ExpandValueEnvForMap(m map[string]interface{}) map[string]interface{} {
for k, v := range m {
switch value := v.(type) {
case string:
m[k] = ExpandValueEnv(value)
case map[string]interface{}:
m[k] = ExpandValueEnvForMap(value)
case map[string]string:
for k2, v2 := range value {
value[k2] = ExpandValueEnv(v2)
}
m[k] = value
}
}
return m
}
// ExpandValueEnv returns value of convert with environment variable.
//
// Return environment variable if value start with "${" and end with "}".
// Return default value if environment variable is empty or not exist.
//
// It accept value formats "${env}" , "${env||}}" , "${env||defaultValue}" , "defaultvalue".
// Examples:
// v1 := config.ExpandValueEnv("${GOPATH}") // return the GOPATH environment variable.
// v2 := config.ExpandValueEnv("${GOAsta||/usr/local/go}") // return the default value "/usr/local/go/".
// v3 := config.ExpandValueEnv("Astaxie") // return the value "Astaxie".
func ExpandValueEnv(value string) (realValue string) {
realValue = value
vLen := len(value)
// 3 = ${}
if vLen < 3 {
return
}
// Need start with "${" and end with "}", then return.
if value[0] != '$' || value[1] != '{' || value[vLen-1] != '}' {
return
}
key := ""
defaultV := ""
// value start with "${"
for i := 2; i < vLen; i++ {
if value[i] == '|' && (i+1 < vLen && value[i+1] == '|') {
key = value[2:i]
defaultV = value[i+2 : vLen-1] // other string is default value.
break
} else if value[i] == '}' {
key = value[2:i]
break
}
}
realValue = os.Getenv(key)
if realValue == "" {
realValue = defaultV
}
return
}
// ParseBool returns the boolean value represented by the string.
//
// It accepts 1, 1.0, t, T, TRUE, true, True, YES, yes, Yes,Y, y, ON, on, On,
// 0, 0.0, f, F, FALSE, false, False, NO, no, No, N,n, OFF, off, Off.
// Any other value returns an error.
func ParseBool(val interface{}) (value bool, err error) {
if val != nil {
switch v := val.(type) {
case bool:
return v, nil
case string:
switch v {
case "1", "t", "T", "true", "TRUE", "True", "YES", "yes", "Yes", "Y", "y", "ON", "on", "On":
return true, nil
case "0", "f", "F", "false", "FALSE", "False", "NO", "no", "No", "N", "n", "OFF", "off", "Off":
return false, nil
}
case int8, int32, int64:
strV := fmt.Sprintf("%d", v)
if strV == "1" {
return true, nil
} else if strV == "0" {
return false, nil
}
case float64:
if v == 1.0 {
return true, nil
} else if v == 0.0 {
return false, nil
}
}
return false, fmt.Errorf("parsing %q: invalid syntax", val)
}
return false, fmt.Errorf("parsing <nil>: invalid syntax")
}
// ToString converts values of any type to string.
func ToString(x interface{}) string {
switch y := x.(type) {
// Handle dates with special logic
// This needs to come above the fmt.Stringer
// test since time.Time's have a .String()
// method
case time.Time:
return y.Format("A Monday")
// Handle type string
case string:
return y
// Handle type with .String() method
case fmt.Stringer:
return y.String()
// Handle type with .Error() method
case error:
return y.Error()
}
// Handle named string type
if v := reflect.ValueOf(x); v.Kind() == reflect.String {
return v.String()
}
// Fallback to fmt package for anything else like numeric types
return fmt.Sprint(x)
}

55
config/config_test.go Normal file
View File

@@ -0,0 +1,55 @@
// Copyright 2016 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 config
import (
"os"
"testing"
)
func TestExpandValueEnv(t *testing.T) {
testCases := []struct {
item string
want string
}{
{"", ""},
{"$", "$"},
{"{", "{"},
{"{}", "{}"},
{"${}", ""},
{"${|}", ""},
{"${}", ""},
{"${{}}", ""},
{"${{||}}", "}"},
{"${pwd||}", ""},
{"${pwd||}", ""},
{"${pwd||}", ""},
{"${pwd||}}", "}"},
{"${pwd||{{||}}}", "{{||}}"},
{"${GOPATH}", os.Getenv("GOPATH")},
{"${GOPATH||}", os.Getenv("GOPATH")},
{"${GOPATH||root}", os.Getenv("GOPATH")},
{"${GOPATH_NOT||root}", "root"},
{"${GOPATH_NOT||||root}", "||root"},
}
for _, c := range testCases {
if got := ExpandValueEnv(c.item); got != c.want {
t.Errorf("expand value error, item %q want %q, got %q", c.item, c.want, got)
}
}
}

87
config/env/env.go vendored Normal file
View File

@@ -0,0 +1,87 @@
// Copyright 2014 beego Author. All Rights Reserved.
// Copyright 2017 Faissal Elamraoui. 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 env is used to parse environment.
package env
import (
"fmt"
"os"
"strings"
"github.com/astaxie/beego/utils"
)
var env *utils.BeeMap
func init() {
env = utils.NewBeeMap()
for _, e := range os.Environ() {
splits := strings.Split(e, "=")
env.Set(splits[0], os.Getenv(splits[0]))
}
}
// Get returns a value by key.
// If the key does not exist, the default value will be returned.
func Get(key string, defVal string) string {
if val := env.Get(key); val != nil {
return val.(string)
}
return defVal
}
// MustGet returns a value by key.
// If the key does not exist, it will return an error.
func MustGet(key string) (string, error) {
if val := env.Get(key); val != nil {
return val.(string), nil
}
return "", fmt.Errorf("no env variable with %s", key)
}
// Set sets a value in the ENV copy.
// This does not affect the child process environment.
func Set(key string, value string) {
env.Set(key, value)
}
// MustSet sets a value in the ENV copy and the child process environment.
// It returns an error in case the set operation failed.
func MustSet(key string, value string) error {
err := os.Setenv(key, value)
if err != nil {
return err
}
env.Set(key, value)
return nil
}
// GetAll returns all keys/values in the current child process environment.
func GetAll() map[string]string {
items := env.Items()
envs := make(map[string]string, env.Count())
for key, val := range items {
switch key := key.(type) {
case string:
switch val := val.(type) {
case string:
envs[key] = val
}
}
}
return envs
}

75
config/env/env_test.go vendored Normal file
View File

@@ -0,0 +1,75 @@
// Copyright 2014 beego Author. All Rights Reserved.
// Copyright 2017 Faissal Elamraoui. 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 env
import (
"os"
"testing"
)
func TestEnvGet(t *testing.T) {
gopath := Get("GOPATH", "")
if gopath != os.Getenv("GOPATH") {
t.Error("expected GOPATH not empty.")
}
noExistVar := Get("NOEXISTVAR", "foo")
if noExistVar != "foo" {
t.Errorf("expected NOEXISTVAR to equal foo, got %s.", noExistVar)
}
}
func TestEnvMustGet(t *testing.T) {
gopath, err := MustGet("GOPATH")
if err != nil {
t.Error(err)
}
if gopath != os.Getenv("GOPATH") {
t.Errorf("expected GOPATH to be the same, got %s.", gopath)
}
_, err = MustGet("NOEXISTVAR")
if err == nil {
t.Error("expected error to be non-nil")
}
}
func TestEnvSet(t *testing.T) {
Set("MYVAR", "foo")
myVar := Get("MYVAR", "bar")
if myVar != "foo" {
t.Errorf("expected MYVAR to equal foo, got %s.", myVar)
}
}
func TestEnvMustSet(t *testing.T) {
err := MustSet("FOO", "bar")
if err != nil {
t.Error(err)
}
fooVar := os.Getenv("FOO")
if fooVar != "bar" {
t.Errorf("expected FOO variable to equal bar, got %s.", fooVar)
}
}
func TestEnvGetAll(t *testing.T) {
envMap := GetAll()
if len(envMap) == 0 {
t.Error("expected environment not empty.")
}
}

134
config/fake.go Normal file
View File

@@ -0,0 +1,134 @@
// 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 config
import (
"errors"
"strconv"
"strings"
)
type fakeConfigContainer struct {
data map[string]string
}
func (c *fakeConfigContainer) getData(key string) string {
return c.data[strings.ToLower(key)]
}
func (c *fakeConfigContainer) Set(key, val string) error {
c.data[strings.ToLower(key)] = val
return nil
}
func (c *fakeConfigContainer) String(key string) string {
return c.getData(key)
}
func (c *fakeConfigContainer) DefaultString(key string, defaultval string) string {
v := c.String(key)
if v == "" {
return defaultval
}
return v
}
func (c *fakeConfigContainer) Strings(key string) []string {
v := c.String(key)
if v == "" {
return nil
}
return strings.Split(v, ";")
}
func (c *fakeConfigContainer) DefaultStrings(key string, defaultval []string) []string {
v := c.Strings(key)
if v == nil {
return defaultval
}
return v
}
func (c *fakeConfigContainer) Int(key string) (int, error) {
return strconv.Atoi(c.getData(key))
}
func (c *fakeConfigContainer) DefaultInt(key string, defaultval int) int {
v, err := c.Int(key)
if err != nil {
return defaultval
}
return v
}
func (c *fakeConfigContainer) Int64(key string) (int64, error) {
return strconv.ParseInt(c.getData(key), 10, 64)
}
func (c *fakeConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
v, err := c.Int64(key)
if err != nil {
return defaultval
}
return v
}
func (c *fakeConfigContainer) Bool(key string) (bool, error) {
return ParseBool(c.getData(key))
}
func (c *fakeConfigContainer) DefaultBool(key string, defaultval bool) bool {
v, err := c.Bool(key)
if err != nil {
return defaultval
}
return v
}
func (c *fakeConfigContainer) Float(key string) (float64, error) {
return strconv.ParseFloat(c.getData(key), 64)
}
func (c *fakeConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
v, err := c.Float(key)
if err != nil {
return defaultval
}
return v
}
func (c *fakeConfigContainer) DIY(key string) (interface{}, error) {
if v, ok := c.data[strings.ToLower(key)]; ok {
return v, nil
}
return nil, errors.New("key not find")
}
func (c *fakeConfigContainer) GetSection(section string) (map[string]string, error) {
return nil, errors.New("not implement in the fakeConfigContainer")
}
func (c *fakeConfigContainer) SaveConfigFile(filename string) error {
return errors.New("not implement in the fakeConfigContainer")
}
var _ Configer = new(fakeConfigContainer)
// NewFakeConfig return a fake Configer
func NewFakeConfig() Configer {
return &fakeConfigContainer{
data: make(map[string]string),
}
}

504
config/ini.go Normal file
View File

@@ -0,0 +1,504 @@
// 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 config
import (
"bufio"
"bytes"
"errors"
"io"
"io/ioutil"
"os"
"os/user"
"path/filepath"
"strconv"
"strings"
"sync"
)
var (
defaultSection = "default" // default section means if some ini items not in a section, make them in default section,
bNumComment = []byte{'#'} // number signal
bSemComment = []byte{';'} // semicolon signal
bEmpty = []byte{}
bEqual = []byte{'='} // equal signal
bDQuote = []byte{'"'} // quote signal
sectionStart = []byte{'['} // section start signal
sectionEnd = []byte{']'} // section end signal
lineBreak = "\n"
)
// IniConfig implements Config to parse ini file.
type IniConfig struct {
}
// Parse creates a new Config and parses the file configuration from the named file.
func (ini *IniConfig) Parse(name string) (Configer, error) {
return ini.parseFile(name)
}
func (ini *IniConfig) parseFile(name string) (*IniConfigContainer, error) {
data, err := ioutil.ReadFile(name)
if err != nil {
return nil, err
}
return ini.parseData(filepath.Dir(name), data)
}
func (ini *IniConfig) parseData(dir string, data []byte) (*IniConfigContainer, error) {
cfg := &IniConfigContainer{
data: make(map[string]map[string]string),
sectionComment: make(map[string]string),
keyComment: make(map[string]string),
RWMutex: sync.RWMutex{},
}
cfg.Lock()
defer cfg.Unlock()
var comment bytes.Buffer
buf := bufio.NewReader(bytes.NewBuffer(data))
// check the BOM
head, err := buf.Peek(3)
if err == nil && head[0] == 239 && head[1] == 187 && head[2] == 191 {
for i := 1; i <= 3; i++ {
buf.ReadByte()
}
}
section := defaultSection
tmpBuf := bytes.NewBuffer(nil)
for {
tmpBuf.Reset()
shouldBreak := false
for {
tmp, isPrefix, err := buf.ReadLine()
if err == io.EOF {
shouldBreak = true
break
}
//It might be a good idea to throw a error on all unknonw errors?
if _, ok := err.(*os.PathError); ok {
return nil, err
}
tmpBuf.Write(tmp)
if isPrefix {
continue
}
if !isPrefix {
break
}
}
if shouldBreak {
break
}
line := tmpBuf.Bytes()
line = bytes.TrimSpace(line)
if bytes.Equal(line, bEmpty) {
continue
}
var bComment []byte
switch {
case bytes.HasPrefix(line, bNumComment):
bComment = bNumComment
case bytes.HasPrefix(line, bSemComment):
bComment = bSemComment
}
if bComment != nil {
line = bytes.TrimLeft(line, string(bComment))
// Need append to a new line if multi-line comments.
if comment.Len() > 0 {
comment.WriteByte('\n')
}
comment.Write(line)
continue
}
if bytes.HasPrefix(line, sectionStart) && bytes.HasSuffix(line, sectionEnd) {
section = strings.ToLower(string(line[1 : len(line)-1])) // section name case insensitive
if comment.Len() > 0 {
cfg.sectionComment[section] = comment.String()
comment.Reset()
}
if _, ok := cfg.data[section]; !ok {
cfg.data[section] = make(map[string]string)
}
continue
}
if _, ok := cfg.data[section]; !ok {
cfg.data[section] = make(map[string]string)
}
keyValue := bytes.SplitN(line, bEqual, 2)
key := string(bytes.TrimSpace(keyValue[0])) // key name case insensitive
key = strings.ToLower(key)
// handle include "other.conf"
if len(keyValue) == 1 && strings.HasPrefix(key, "include") {
includefiles := strings.Fields(key)
if includefiles[0] == "include" && len(includefiles) == 2 {
otherfile := strings.Trim(includefiles[1], "\"")
if !filepath.IsAbs(otherfile) {
otherfile = filepath.Join(dir, otherfile)
}
i, err := ini.parseFile(otherfile)
if err != nil {
return nil, err
}
for sec, dt := range i.data {
if _, ok := cfg.data[sec]; !ok {
cfg.data[sec] = make(map[string]string)
}
for k, v := range dt {
cfg.data[sec][k] = v
}
}
for sec, comm := range i.sectionComment {
cfg.sectionComment[sec] = comm
}
for k, comm := range i.keyComment {
cfg.keyComment[k] = comm
}
continue
}
}
if len(keyValue) != 2 {
return nil, errors.New("read the content error: \"" + string(line) + "\", should key = val")
}
val := bytes.TrimSpace(keyValue[1])
if bytes.HasPrefix(val, bDQuote) {
val = bytes.Trim(val, `"`)
}
cfg.data[section][key] = ExpandValueEnv(string(val))
if comment.Len() > 0 {
cfg.keyComment[section+"."+key] = comment.String()
comment.Reset()
}
}
return cfg, nil
}
// ParseData parse ini the data
// When include other.conf,other.conf is either absolute directory
// or under beego in default temporary directory(/tmp/beego[-username]).
func (ini *IniConfig) ParseData(data []byte) (Configer, error) {
dir := "beego"
currentUser, err := user.Current()
if err == nil {
dir = "beego-" + currentUser.Username
}
dir = filepath.Join(os.TempDir(), dir)
if err = os.MkdirAll(dir, os.ModePerm); err != nil {
return nil, err
}
return ini.parseData(dir, data)
}
// IniConfigContainer A Config represents the ini configuration.
// When set and get value, support key as section:name type.
type IniConfigContainer struct {
data map[string]map[string]string // section=> key:val
sectionComment map[string]string // section : comment
keyComment map[string]string // id: []{comment, key...}; id 1 is for main comment.
sync.RWMutex
}
// Bool returns the boolean value for a given key.
func (c *IniConfigContainer) Bool(key string) (bool, error) {
return ParseBool(c.getdata(key))
}
// DefaultBool returns the boolean value for a given key.
// if err != nil return defaultval
func (c *IniConfigContainer) DefaultBool(key string, defaultval bool) bool {
v, err := c.Bool(key)
if err != nil {
return defaultval
}
return v
}
// Int returns the integer value for a given key.
func (c *IniConfigContainer) Int(key string) (int, error) {
return strconv.Atoi(c.getdata(key))
}
// DefaultInt returns the integer value for a given key.
// if err != nil return defaultval
func (c *IniConfigContainer) DefaultInt(key string, defaultval int) int {
v, err := c.Int(key)
if err != nil {
return defaultval
}
return v
}
// Int64 returns the int64 value for a given key.
func (c *IniConfigContainer) Int64(key string) (int64, error) {
return strconv.ParseInt(c.getdata(key), 10, 64)
}
// DefaultInt64 returns the int64 value for a given key.
// if err != nil return defaultval
func (c *IniConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
v, err := c.Int64(key)
if err != nil {
return defaultval
}
return v
}
// Float returns the float value for a given key.
func (c *IniConfigContainer) Float(key string) (float64, error) {
return strconv.ParseFloat(c.getdata(key), 64)
}
// DefaultFloat returns the float64 value for a given key.
// if err != nil return defaultval
func (c *IniConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
v, err := c.Float(key)
if err != nil {
return defaultval
}
return v
}
// String returns the string value for a given key.
func (c *IniConfigContainer) String(key string) string {
return c.getdata(key)
}
// DefaultString returns the string value for a given key.
// if err != nil return defaultval
func (c *IniConfigContainer) DefaultString(key string, defaultval string) string {
v := c.String(key)
if v == "" {
return defaultval
}
return v
}
// Strings returns the []string value for a given key.
// Return nil if config value does not exist or is empty.
func (c *IniConfigContainer) Strings(key string) []string {
v := c.String(key)
if v == "" {
return nil
}
return strings.Split(v, ";")
}
// DefaultStrings returns the []string value for a given key.
// if err != nil return defaultval
func (c *IniConfigContainer) DefaultStrings(key string, defaultval []string) []string {
v := c.Strings(key)
if v == nil {
return defaultval
}
return v
}
// GetSection returns map for the given section
func (c *IniConfigContainer) GetSection(section string) (map[string]string, error) {
if v, ok := c.data[section]; ok {
return v, nil
}
return nil, errors.New("not exist section")
}
// SaveConfigFile save the config into file.
//
// BUG(env): The environment variable config item will be saved with real value in SaveConfigFile Function.
func (c *IniConfigContainer) SaveConfigFile(filename string) (err error) {
// Write configuration file by filename.
f, err := os.Create(filename)
if err != nil {
return err
}
defer f.Close()
// Get section or key comments. Fixed #1607
getCommentStr := func(section, key string) string {
var (
comment string
ok bool
)
if len(key) == 0 {
comment, ok = c.sectionComment[section]
} else {
comment, ok = c.keyComment[section+"."+key]
}
if ok {
// Empty comment
if len(comment) == 0 || len(strings.TrimSpace(comment)) == 0 {
return string(bNumComment)
}
prefix := string(bNumComment)
// Add the line head character "#"
return prefix + strings.Replace(comment, lineBreak, lineBreak+prefix, -1)
}
return ""
}
buf := bytes.NewBuffer(nil)
// Save default section at first place
if dt, ok := c.data[defaultSection]; ok {
for key, val := range dt {
if key != " " {
// Write key comments.
if v := getCommentStr(defaultSection, key); len(v) > 0 {
if _, err = buf.WriteString(v + lineBreak); err != nil {
return err
}
}
// Write key and value.
if _, err = buf.WriteString(key + string(bEqual) + val + lineBreak); err != nil {
return err
}
}
}
// Put a line between sections.
if _, err = buf.WriteString(lineBreak); err != nil {
return err
}
}
// Save named sections
for section, dt := range c.data {
if section != defaultSection {
// Write section comments.
if v := getCommentStr(section, ""); len(v) > 0 {
if _, err = buf.WriteString(v + lineBreak); err != nil {
return err
}
}
// Write section name.
if _, err = buf.WriteString(string(sectionStart) + section + string(sectionEnd) + lineBreak); err != nil {
return err
}
for key, val := range dt {
if key != " " {
// Write key comments.
if v := getCommentStr(section, key); len(v) > 0 {
if _, err = buf.WriteString(v + lineBreak); err != nil {
return err
}
}
// Write key and value.
if _, err = buf.WriteString(key + string(bEqual) + val + lineBreak); err != nil {
return err
}
}
}
// Put a line between sections.
if _, err = buf.WriteString(lineBreak); err != nil {
return err
}
}
}
_, err = buf.WriteTo(f)
return err
}
// Set writes a new value for key.
// if write to one section, the key need be "section::key".
// if the section is not existed, it panics.
func (c *IniConfigContainer) Set(key, value string) error {
c.Lock()
defer c.Unlock()
if len(key) == 0 {
return errors.New("key is empty")
}
var (
section, k string
sectionKey = strings.Split(strings.ToLower(key), "::")
)
if len(sectionKey) >= 2 {
section = sectionKey[0]
k = sectionKey[1]
} else {
section = defaultSection
k = sectionKey[0]
}
if _, ok := c.data[section]; !ok {
c.data[section] = make(map[string]string)
}
c.data[section][k] = value
return nil
}
// DIY returns the raw value by a given key.
func (c *IniConfigContainer) DIY(key string) (v interface{}, err error) {
if v, ok := c.data[strings.ToLower(key)]; ok {
return v, nil
}
return v, errors.New("key not find")
}
// section.key or key
func (c *IniConfigContainer) getdata(key string) string {
if len(key) == 0 {
return ""
}
c.RLock()
defer c.RUnlock()
var (
section, k string
sectionKey = strings.Split(strings.ToLower(key), "::")
)
if len(sectionKey) >= 2 {
section = sectionKey[0]
k = sectionKey[1]
} else {
section = defaultSection
k = sectionKey[0]
}
if v, ok := c.data[section]; ok {
if vv, ok := v[k]; ok {
return vv
}
}
return ""
}
func init() {
Register("ini", &IniConfig{})
}

190
config/ini_test.go Normal file
View File

@@ -0,0 +1,190 @@
// 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 config
import (
"fmt"
"io/ioutil"
"os"
"strings"
"testing"
)
func TestIni(t *testing.T) {
var (
inicontext = `
;comment one
#comment two
appname = beeapi
httpport = 8080
mysqlport = 3600
PI = 3.1415976
runmode = "dev"
autorender = false
copyrequestbody = true
session= on
cookieon= off
newreg = OFF
needlogin = ON
enableSession = Y
enableCookie = N
flag = 1
path1 = ${GOPATH}
path2 = ${GOPATH||/home/go}
[demo]
key1="asta"
key2 = "xie"
CaseInsensitive = true
peers = one;two;three
password = ${GOPATH}
`
keyValue = map[string]interface{}{
"appname": "beeapi",
"httpport": 8080,
"mysqlport": int64(3600),
"pi": 3.1415976,
"runmode": "dev",
"autorender": false,
"copyrequestbody": true,
"session": true,
"cookieon": false,
"newreg": false,
"needlogin": true,
"enableSession": true,
"enableCookie": false,
"flag": true,
"path1": os.Getenv("GOPATH"),
"path2": os.Getenv("GOPATH"),
"demo::key1": "asta",
"demo::key2": "xie",
"demo::CaseInsensitive": true,
"demo::peers": []string{"one", "two", "three"},
"demo::password": os.Getenv("GOPATH"),
"null": "",
"demo2::key1": "",
"error": "",
"emptystrings": []string{},
}
)
f, err := os.Create("testini.conf")
if err != nil {
t.Fatal(err)
}
_, err = f.WriteString(inicontext)
if err != nil {
f.Close()
t.Fatal(err)
}
f.Close()
defer os.Remove("testini.conf")
iniconf, err := NewConfig("ini", "testini.conf")
if err != nil {
t.Fatal(err)
}
for k, v := range keyValue {
var err error
var value interface{}
switch v.(type) {
case int:
value, err = iniconf.Int(k)
case int64:
value, err = iniconf.Int64(k)
case float64:
value, err = iniconf.Float(k)
case bool:
value, err = iniconf.Bool(k)
case []string:
value = iniconf.Strings(k)
case string:
value = iniconf.String(k)
default:
value, err = iniconf.DIY(k)
}
if err != nil {
t.Fatalf("get key %q value fail,err %s", k, err)
} else if fmt.Sprintf("%v", v) != fmt.Sprintf("%v", value) {
t.Fatalf("get key %q value, want %v got %v .", k, v, value)
}
}
if err = iniconf.Set("name", "astaxie"); err != nil {
t.Fatal(err)
}
if iniconf.String("name") != "astaxie" {
t.Fatal("get name error")
}
}
func TestIniSave(t *testing.T) {
const (
inicontext = `
app = app
;comment one
#comment two
# comment three
appname = beeapi
httpport = 8080
# DB Info
# enable db
[dbinfo]
# db type name
# support mysql,sqlserver
name = mysql
`
saveResult = `
app=app
#comment one
#comment two
# comment three
appname=beeapi
httpport=8080
# DB Info
# enable db
[dbinfo]
# db type name
# support mysql,sqlserver
name=mysql
`
)
cfg, err := NewConfigData("ini", []byte(inicontext))
if err != nil {
t.Fatal(err)
}
name := "newIniConfig.ini"
if err := cfg.SaveConfigFile(name); err != nil {
t.Fatal(err)
}
defer os.Remove(name)
if data, err := ioutil.ReadFile(name); err != nil {
t.Fatal(err)
} else {
cfgData := string(data)
datas := strings.Split(saveResult, "\n")
for _, line := range datas {
if !strings.Contains(cfgData, line+"\n") {
t.Fatalf("different after save ini config file. need contains %q", line)
}
}
}
}

269
config/json.go Normal file
View File

@@ -0,0 +1,269 @@
// 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 config
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"strconv"
"strings"
"sync"
)
// JSONConfig is a json config parser and implements Config interface.
type JSONConfig struct {
}
// Parse returns a ConfigContainer with parsed json config map.
func (js *JSONConfig) Parse(filename string) (Configer, error) {
file, err := os.Open(filename)
if err != nil {
return nil, err
}
defer file.Close()
content, err := ioutil.ReadAll(file)
if err != nil {
return nil, err
}
return js.ParseData(content)
}
// ParseData returns a ConfigContainer with json string
func (js *JSONConfig) ParseData(data []byte) (Configer, error) {
x := &JSONConfigContainer{
data: make(map[string]interface{}),
}
err := json.Unmarshal(data, &x.data)
if err != nil {
var wrappingArray []interface{}
err2 := json.Unmarshal(data, &wrappingArray)
if err2 != nil {
return nil, err
}
x.data["rootArray"] = wrappingArray
}
x.data = ExpandValueEnvForMap(x.data)
return x, nil
}
// JSONConfigContainer A Config represents the json configuration.
// Only when get value, support key as section:name type.
type JSONConfigContainer struct {
data map[string]interface{}
sync.RWMutex
}
// Bool returns the boolean value for a given key.
func (c *JSONConfigContainer) Bool(key string) (bool, error) {
val := c.getData(key)
if val != nil {
return ParseBool(val)
}
return false, fmt.Errorf("not exist key: %q", key)
}
// DefaultBool return the bool value if has no error
// otherwise return the defaultval
func (c *JSONConfigContainer) DefaultBool(key string, defaultval bool) bool {
if v, err := c.Bool(key); err == nil {
return v
}
return defaultval
}
// Int returns the integer value for a given key.
func (c *JSONConfigContainer) Int(key string) (int, error) {
val := c.getData(key)
if val != nil {
if v, ok := val.(float64); ok {
return int(v), nil
} else if v, ok := val.(string); ok {
return strconv.Atoi(v)
}
return 0, errors.New("not valid value")
}
return 0, errors.New("not exist key:" + key)
}
// DefaultInt returns the integer value for a given key.
// if err != nil return defaultval
func (c *JSONConfigContainer) DefaultInt(key string, defaultval int) int {
if v, err := c.Int(key); err == nil {
return v
}
return defaultval
}
// Int64 returns the int64 value for a given key.
func (c *JSONConfigContainer) Int64(key string) (int64, error) {
val := c.getData(key)
if val != nil {
if v, ok := val.(float64); ok {
return int64(v), nil
}
return 0, errors.New("not int64 value")
}
return 0, errors.New("not exist key:" + key)
}
// DefaultInt64 returns the int64 value for a given key.
// if err != nil return defaultval
func (c *JSONConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
if v, err := c.Int64(key); err == nil {
return v
}
return defaultval
}
// Float returns the float value for a given key.
func (c *JSONConfigContainer) Float(key string) (float64, error) {
val := c.getData(key)
if val != nil {
if v, ok := val.(float64); ok {
return v, nil
}
return 0.0, errors.New("not float64 value")
}
return 0.0, errors.New("not exist key:" + key)
}
// DefaultFloat returns the float64 value for a given key.
// if err != nil return defaultval
func (c *JSONConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
if v, err := c.Float(key); err == nil {
return v
}
return defaultval
}
// String returns the string value for a given key.
func (c *JSONConfigContainer) String(key string) string {
val := c.getData(key)
if val != nil {
if v, ok := val.(string); ok {
return v
}
}
return ""
}
// DefaultString returns the string value for a given key.
// if err != nil return defaultval
func (c *JSONConfigContainer) DefaultString(key string, defaultval string) string {
// TODO FIXME should not use "" to replace non existence
if v := c.String(key); v != "" {
return v
}
return defaultval
}
// Strings returns the []string value for a given key.
func (c *JSONConfigContainer) Strings(key string) []string {
stringVal := c.String(key)
if stringVal == "" {
return nil
}
return strings.Split(c.String(key), ";")
}
// DefaultStrings returns the []string value for a given key.
// if err != nil return defaultval
func (c *JSONConfigContainer) DefaultStrings(key string, defaultval []string) []string {
if v := c.Strings(key); v != nil {
return v
}
return defaultval
}
// GetSection returns map for the given section
func (c *JSONConfigContainer) GetSection(section string) (map[string]string, error) {
if v, ok := c.data[section]; ok {
return v.(map[string]string), nil
}
return nil, errors.New("nonexist section " + section)
}
// SaveConfigFile save the config into file
func (c *JSONConfigContainer) SaveConfigFile(filename string) (err error) {
// Write configuration file by filename.
f, err := os.Create(filename)
if err != nil {
return err
}
defer f.Close()
b, err := json.MarshalIndent(c.data, "", " ")
if err != nil {
return err
}
_, err = f.Write(b)
return err
}
// Set writes a new value for key.
func (c *JSONConfigContainer) Set(key, val string) error {
c.Lock()
defer c.Unlock()
c.data[key] = val
return nil
}
// DIY returns the raw value by a given key.
func (c *JSONConfigContainer) DIY(key string) (v interface{}, err error) {
val := c.getData(key)
if val != nil {
return val, nil
}
return nil, errors.New("not exist key")
}
// section.key or key
func (c *JSONConfigContainer) getData(key string) interface{} {
if len(key) == 0 {
return nil
}
c.RLock()
defer c.RUnlock()
sectionKeys := strings.Split(key, "::")
if len(sectionKeys) >= 2 {
curValue, ok := c.data[sectionKeys[0]]
if !ok {
return nil
}
for _, key := range sectionKeys[1:] {
if v, ok := curValue.(map[string]interface{}); ok {
if curValue, ok = v[key]; !ok {
return nil
}
}
}
return curValue
}
if v, ok := c.data[key]; ok {
return v
}
return nil
}
func init() {
Register("json", &JSONConfig{})
}

222
config/json_test.go Normal file
View File

@@ -0,0 +1,222 @@
// 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 config
import (
"fmt"
"os"
"testing"
)
func TestJsonStartsWithArray(t *testing.T) {
const jsoncontextwitharray = `[
{
"url": "user",
"serviceAPI": "http://www.test.com/user"
},
{
"url": "employee",
"serviceAPI": "http://www.test.com/employee"
}
]`
f, err := os.Create("testjsonWithArray.conf")
if err != nil {
t.Fatal(err)
}
_, err = f.WriteString(jsoncontextwitharray)
if err != nil {
f.Close()
t.Fatal(err)
}
f.Close()
defer os.Remove("testjsonWithArray.conf")
jsonconf, err := NewConfig("json", "testjsonWithArray.conf")
if err != nil {
t.Fatal(err)
}
rootArray, err := jsonconf.DIY("rootArray")
if err != nil {
t.Error("array does not exist as element")
}
rootArrayCasted := rootArray.([]interface{})
if rootArrayCasted == nil {
t.Error("array from root is nil")
} else {
elem := rootArrayCasted[0].(map[string]interface{})
if elem["url"] != "user" || elem["serviceAPI"] != "http://www.test.com/user" {
t.Error("array[0] values are not valid")
}
elem2 := rootArrayCasted[1].(map[string]interface{})
if elem2["url"] != "employee" || elem2["serviceAPI"] != "http://www.test.com/employee" {
t.Error("array[1] values are not valid")
}
}
}
func TestJson(t *testing.T) {
var (
jsoncontext = `{
"appname": "beeapi",
"testnames": "foo;bar",
"httpport": 8080,
"mysqlport": 3600,
"PI": 3.1415976,
"runmode": "dev",
"autorender": false,
"copyrequestbody": true,
"session": "on",
"cookieon": "off",
"newreg": "OFF",
"needlogin": "ON",
"enableSession": "Y",
"enableCookie": "N",
"flag": 1,
"path1": "${GOPATH}",
"path2": "${GOPATH||/home/go}",
"database": {
"host": "host",
"port": "port",
"database": "database",
"username": "username",
"password": "${GOPATH}",
"conns":{
"maxconnection":12,
"autoconnect":true,
"connectioninfo":"info",
"root": "${GOPATH}"
}
}
}`
keyValue = map[string]interface{}{
"appname": "beeapi",
"testnames": []string{"foo", "bar"},
"httpport": 8080,
"mysqlport": int64(3600),
"PI": 3.1415976,
"runmode": "dev",
"autorender": false,
"copyrequestbody": true,
"session": true,
"cookieon": false,
"newreg": false,
"needlogin": true,
"enableSession": true,
"enableCookie": false,
"flag": true,
"path1": os.Getenv("GOPATH"),
"path2": os.Getenv("GOPATH"),
"database::host": "host",
"database::port": "port",
"database::database": "database",
"database::password": os.Getenv("GOPATH"),
"database::conns::maxconnection": 12,
"database::conns::autoconnect": true,
"database::conns::connectioninfo": "info",
"database::conns::root": os.Getenv("GOPATH"),
"unknown": "",
}
)
f, err := os.Create("testjson.conf")
if err != nil {
t.Fatal(err)
}
_, err = f.WriteString(jsoncontext)
if err != nil {
f.Close()
t.Fatal(err)
}
f.Close()
defer os.Remove("testjson.conf")
jsonconf, err := NewConfig("json", "testjson.conf")
if err != nil {
t.Fatal(err)
}
for k, v := range keyValue {
var err error
var value interface{}
switch v.(type) {
case int:
value, err = jsonconf.Int(k)
case int64:
value, err = jsonconf.Int64(k)
case float64:
value, err = jsonconf.Float(k)
case bool:
value, err = jsonconf.Bool(k)
case []string:
value = jsonconf.Strings(k)
case string:
value = jsonconf.String(k)
default:
value, err = jsonconf.DIY(k)
}
if err != nil {
t.Fatalf("get key %q value fatal,%v err %s", k, v, err)
} else if fmt.Sprintf("%v", v) != fmt.Sprintf("%v", value) {
t.Fatalf("get key %q value, want %v got %v .", k, v, value)
}
}
if err = jsonconf.Set("name", "astaxie"); err != nil {
t.Fatal(err)
}
if jsonconf.String("name") != "astaxie" {
t.Fatal("get name error")
}
if db, err := jsonconf.DIY("database"); err != nil {
t.Fatal(err)
} else if m, ok := db.(map[string]interface{}); !ok {
t.Log(db)
t.Fatal("db not map[string]interface{}")
} else {
if m["host"].(string) != "host" {
t.Fatal("get host err")
}
}
if _, err := jsonconf.Int("unknown"); err == nil {
t.Error("unknown keys should return an error when expecting an Int")
}
if _, err := jsonconf.Int64("unknown"); err == nil {
t.Error("unknown keys should return an error when expecting an Int64")
}
if _, err := jsonconf.Float("unknown"); err == nil {
t.Error("unknown keys should return an error when expecting a Float")
}
if _, err := jsonconf.DIY("unknown"); err == nil {
t.Error("unknown keys should return an error when expecting an interface{}")
}
if val := jsonconf.String("unknown"); val != "" {
t.Error("unknown keys should return an empty string when expecting a String")
}
if _, err := jsonconf.Bool("unknown"); err == nil {
t.Error("unknown keys should return an error when expecting a Bool")
}
if !jsonconf.DefaultBool("unknown", true) {
t.Error("unknown keys with default value wrong")
}
}

228
config/xml/xml.go Normal file
View File

@@ -0,0 +1,228 @@
// 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 xml for config provider.
//
// depend on github.com/beego/x2j.
//
// go install github.com/beego/x2j.
//
// Usage:
// import(
// _ "github.com/astaxie/beego/config/xml"
// "github.com/astaxie/beego/config"
// )
//
// cnf, err := config.NewConfig("xml", "config.xml")
//
//More docs http://beego.me/docs/module/config.md
package xml
import (
"encoding/xml"
"errors"
"fmt"
"io/ioutil"
"os"
"strconv"
"strings"
"sync"
"github.com/astaxie/beego/config"
"github.com/beego/x2j"
)
// Config is a xml config parser and implements Config interface.
// xml configurations should be included in <config></config> tag.
// only support key/value pair as <key>value</key> as each item.
type Config struct{}
// Parse returns a ConfigContainer with parsed xml config map.
func (xc *Config) Parse(filename string) (config.Configer, error) {
context, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
return xc.ParseData(context)
}
// ParseData xml data
func (xc *Config) ParseData(data []byte) (config.Configer, error) {
x := &ConfigContainer{data: make(map[string]interface{})}
d, err := x2j.DocToMap(string(data))
if err != nil {
return nil, err
}
x.data = config.ExpandValueEnvForMap(d["config"].(map[string]interface{}))
return x, nil
}
// ConfigContainer A Config represents the xml configuration.
type ConfigContainer struct {
data map[string]interface{}
sync.Mutex
}
// Bool returns the boolean value for a given key.
func (c *ConfigContainer) Bool(key string) (bool, error) {
if v := c.data[key]; v != nil {
return config.ParseBool(v)
}
return false, fmt.Errorf("not exist key: %q", key)
}
// DefaultBool return the bool value if has no error
// otherwise return the defaultval
func (c *ConfigContainer) DefaultBool(key string, defaultval bool) bool {
v, err := c.Bool(key)
if err != nil {
return defaultval
}
return v
}
// Int returns the integer value for a given key.
func (c *ConfigContainer) Int(key string) (int, error) {
return strconv.Atoi(c.data[key].(string))
}
// DefaultInt returns the integer value for a given key.
// if err != nil return defaultval
func (c *ConfigContainer) DefaultInt(key string, defaultval int) int {
v, err := c.Int(key)
if err != nil {
return defaultval
}
return v
}
// Int64 returns the int64 value for a given key.
func (c *ConfigContainer) Int64(key string) (int64, error) {
return strconv.ParseInt(c.data[key].(string), 10, 64)
}
// DefaultInt64 returns the int64 value for a given key.
// if err != nil return defaultval
func (c *ConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
v, err := c.Int64(key)
if err != nil {
return defaultval
}
return v
}
// Float returns the float value for a given key.
func (c *ConfigContainer) Float(key string) (float64, error) {
return strconv.ParseFloat(c.data[key].(string), 64)
}
// DefaultFloat returns the float64 value for a given key.
// if err != nil return defaultval
func (c *ConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
v, err := c.Float(key)
if err != nil {
return defaultval
}
return v
}
// String returns the string value for a given key.
func (c *ConfigContainer) String(key string) string {
if v, ok := c.data[key].(string); ok {
return v
}
return ""
}
// DefaultString returns the string value for a given key.
// if err != nil return defaultval
func (c *ConfigContainer) DefaultString(key string, defaultval string) string {
v := c.String(key)
if v == "" {
return defaultval
}
return v
}
// Strings returns the []string value for a given key.
func (c *ConfigContainer) Strings(key string) []string {
v := c.String(key)
if v == "" {
return nil
}
return strings.Split(v, ";")
}
// DefaultStrings returns the []string value for a given key.
// if err != nil return defaultval
func (c *ConfigContainer) DefaultStrings(key string, defaultval []string) []string {
v := c.Strings(key)
if v == nil {
return defaultval
}
return v
}
// GetSection returns map for the given section
func (c *ConfigContainer) GetSection(section string) (map[string]string, error) {
if v, ok := c.data[section].(map[string]interface{}); ok {
mapstr := make(map[string]string)
for k, val := range v {
mapstr[k] = config.ToString(val)
}
return mapstr, nil
}
return nil, fmt.Errorf("section '%s' not found", section)
}
// SaveConfigFile save the config into file
func (c *ConfigContainer) SaveConfigFile(filename string) (err error) {
// Write configuration file by filename.
f, err := os.Create(filename)
if err != nil {
return err
}
defer f.Close()
b, err := xml.MarshalIndent(c.data, " ", " ")
if err != nil {
return err
}
_, err = f.Write(b)
return err
}
// Set writes a new value for key.
func (c *ConfigContainer) Set(key, val string) error {
c.Lock()
defer c.Unlock()
c.data[key] = val
return nil
}
// DIY returns the raw value by a given key.
func (c *ConfigContainer) DIY(key string) (v interface{}, err error) {
if v, ok := c.data[key]; ok {
return v, nil
}
return nil, errors.New("not exist key")
}
func init() {
config.Register("xml", &Config{})
}

125
config/xml/xml_test.go Normal file
View File

@@ -0,0 +1,125 @@
// 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 xml
import (
"fmt"
"os"
"testing"
"github.com/astaxie/beego/config"
)
func TestXML(t *testing.T) {
var (
//xml parse should incluce in <config></config> tags
xmlcontext = `<?xml version="1.0" encoding="UTF-8"?>
<config>
<appname>beeapi</appname>
<httpport>8080</httpport>
<mysqlport>3600</mysqlport>
<PI>3.1415976</PI>
<runmode>dev</runmode>
<autorender>false</autorender>
<copyrequestbody>true</copyrequestbody>
<path1>${GOPATH}</path1>
<path2>${GOPATH||/home/go}</path2>
<mysection>
<id>1</id>
<name>MySection</name>
</mysection>
</config>
`
keyValue = map[string]interface{}{
"appname": "beeapi",
"httpport": 8080,
"mysqlport": int64(3600),
"PI": 3.1415976,
"runmode": "dev",
"autorender": false,
"copyrequestbody": true,
"path1": os.Getenv("GOPATH"),
"path2": os.Getenv("GOPATH"),
"error": "",
"emptystrings": []string{},
}
)
f, err := os.Create("testxml.conf")
if err != nil {
t.Fatal(err)
}
_, err = f.WriteString(xmlcontext)
if err != nil {
f.Close()
t.Fatal(err)
}
f.Close()
defer os.Remove("testxml.conf")
xmlconf, err := config.NewConfig("xml", "testxml.conf")
if err != nil {
t.Fatal(err)
}
var xmlsection map[string]string
xmlsection, err = xmlconf.GetSection("mysection")
if err != nil {
t.Fatal(err)
}
if len(xmlsection) == 0 {
t.Error("section should not be empty")
}
for k, v := range keyValue {
var (
value interface{}
err error
)
switch v.(type) {
case int:
value, err = xmlconf.Int(k)
case int64:
value, err = xmlconf.Int64(k)
case float64:
value, err = xmlconf.Float(k)
case bool:
value, err = xmlconf.Bool(k)
case []string:
value = xmlconf.Strings(k)
case string:
value = xmlconf.String(k)
default:
value, err = xmlconf.DIY(k)
}
if err != nil {
t.Errorf("get key %q value fatal,%v err %s", k, v, err)
} else if fmt.Sprintf("%v", v) != fmt.Sprintf("%v", value) {
t.Errorf("get key %q value, want %v got %v .", k, v, value)
}
}
if err = xmlconf.Set("name", "astaxie"); err != nil {
t.Fatal(err)
}
if xmlconf.String("name") != "astaxie" {
t.Fatal("get name error")
}
}

316
config/yaml/yaml.go Normal file
View File

@@ -0,0 +1,316 @@
// 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 yaml for config provider
//
// depend on github.com/beego/goyaml2
//
// go install github.com/beego/goyaml2
//
// Usage:
// import(
// _ "github.com/astaxie/beego/config/yaml"
// "github.com/astaxie/beego/config"
// )
//
// cnf, err := config.NewConfig("yaml", "config.yaml")
//
//More docs http://beego.me/docs/module/config.md
package yaml
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"log"
"os"
"strings"
"sync"
"github.com/astaxie/beego/config"
"github.com/beego/goyaml2"
)
// Config is a yaml config parser and implements Config interface.
type Config struct{}
// Parse returns a ConfigContainer with parsed yaml config map.
func (yaml *Config) Parse(filename string) (y config.Configer, err error) {
cnf, err := ReadYmlReader(filename)
if err != nil {
return
}
y = &ConfigContainer{
data: cnf,
}
return
}
// ParseData parse yaml data
func (yaml *Config) ParseData(data []byte) (config.Configer, error) {
cnf, err := parseYML(data)
if err != nil {
return nil, err
}
return &ConfigContainer{
data: cnf,
}, nil
}
// ReadYmlReader Read yaml file to map.
// if json like, use json package, unless goyaml2 package.
func ReadYmlReader(path string) (cnf map[string]interface{}, err error) {
buf, err := ioutil.ReadFile(path)
if err != nil {
return
}
return parseYML(buf)
}
// parseYML parse yaml formatted []byte to map.
func parseYML(buf []byte) (cnf map[string]interface{}, err error) {
if len(buf) < 3 {
return
}
if string(buf[0:1]) == "{" {
log.Println("Look like a Json, try json umarshal")
err = json.Unmarshal(buf, &cnf)
if err == nil {
log.Println("It is Json Map")
return
}
}
data, err := goyaml2.Read(bytes.NewReader(buf))
if err != nil {
log.Println("Goyaml2 ERR>", string(buf), err)
return
}
if data == nil {
log.Println("Goyaml2 output nil? Pls report bug\n" + string(buf))
return
}
cnf, ok := data.(map[string]interface{})
if !ok {
log.Println("Not a Map? >> ", string(buf), data)
cnf = nil
}
cnf = config.ExpandValueEnvForMap(cnf)
return
}
// ConfigContainer A Config represents the yaml configuration.
type ConfigContainer struct {
data map[string]interface{}
sync.RWMutex
}
// Bool returns the boolean value for a given key.
func (c *ConfigContainer) Bool(key string) (bool, error) {
v, err := c.getData(key)
if err != nil {
return false, err
}
return config.ParseBool(v)
}
// DefaultBool return the bool value if has no error
// otherwise return the defaultval
func (c *ConfigContainer) DefaultBool(key string, defaultval bool) bool {
v, err := c.Bool(key)
if err != nil {
return defaultval
}
return v
}
// Int returns the integer value for a given key.
func (c *ConfigContainer) Int(key string) (int, error) {
if v, err := c.getData(key); err != nil {
return 0, err
} else if vv, ok := v.(int); ok {
return vv, nil
} else if vv, ok := v.(int64); ok {
return int(vv), nil
}
return 0, errors.New("not int value")
}
// DefaultInt returns the integer value for a given key.
// if err != nil return defaultval
func (c *ConfigContainer) DefaultInt(key string, defaultval int) int {
v, err := c.Int(key)
if err != nil {
return defaultval
}
return v
}
// Int64 returns the int64 value for a given key.
func (c *ConfigContainer) Int64(key string) (int64, error) {
if v, err := c.getData(key); err != nil {
return 0, err
} else if vv, ok := v.(int64); ok {
return vv, nil
}
return 0, errors.New("not bool value")
}
// DefaultInt64 returns the int64 value for a given key.
// if err != nil return defaultval
func (c *ConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
v, err := c.Int64(key)
if err != nil {
return defaultval
}
return v
}
// Float returns the float value for a given key.
func (c *ConfigContainer) Float(key string) (float64, error) {
if v, err := c.getData(key); err != nil {
return 0.0, err
} else if vv, ok := v.(float64); ok {
return vv, nil
} else if vv, ok := v.(int); ok {
return float64(vv), nil
} else if vv, ok := v.(int64); ok {
return float64(vv), nil
}
return 0.0, errors.New("not float64 value")
}
// DefaultFloat returns the float64 value for a given key.
// if err != nil return defaultval
func (c *ConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
v, err := c.Float(key)
if err != nil {
return defaultval
}
return v
}
// String returns the string value for a given key.
func (c *ConfigContainer) String(key string) string {
if v, err := c.getData(key); err == nil {
if vv, ok := v.(string); ok {
return vv
}
}
return ""
}
// DefaultString returns the string value for a given key.
// if err != nil return defaultval
func (c *ConfigContainer) DefaultString(key string, defaultval string) string {
v := c.String(key)
if v == "" {
return defaultval
}
return v
}
// Strings returns the []string value for a given key.
func (c *ConfigContainer) Strings(key string) []string {
v := c.String(key)
if v == "" {
return nil
}
return strings.Split(v, ";")
}
// DefaultStrings returns the []string value for a given key.
// if err != nil return defaultval
func (c *ConfigContainer) DefaultStrings(key string, defaultval []string) []string {
v := c.Strings(key)
if v == nil {
return defaultval
}
return v
}
// GetSection returns map for the given section
func (c *ConfigContainer) GetSection(section string) (map[string]string, error) {
if v, ok := c.data[section]; ok {
return v.(map[string]string), nil
}
return nil, errors.New("not exist section")
}
// SaveConfigFile save the config into file
func (c *ConfigContainer) SaveConfigFile(filename string) (err error) {
// Write configuration file by filename.
f, err := os.Create(filename)
if err != nil {
return err
}
defer f.Close()
err = goyaml2.Write(f, c.data)
return err
}
// Set writes a new value for key.
func (c *ConfigContainer) Set(key, val string) error {
c.Lock()
defer c.Unlock()
c.data[key] = val
return nil
}
// DIY returns the raw value by a given key.
func (c *ConfigContainer) DIY(key string) (v interface{}, err error) {
return c.getData(key)
}
func (c *ConfigContainer) getData(key string) (interface{}, error) {
if len(key) == 0 {
return nil, errors.New("key is empty")
}
c.RLock()
defer c.RUnlock()
keys := strings.Split(key, ".")
tmpData := c.data
for idx, k := range keys {
if v, ok := tmpData[k]; ok {
switch v.(type) {
case map[string]interface{}:
{
tmpData = v.(map[string]interface{})
if idx == len(keys)-1 {
return tmpData, nil
}
}
default:
{
return v, nil
}
}
}
}
return nil, fmt.Errorf("not exist key %q", key)
}
func init() {
config.Register("yaml", &Config{})
}

115
config/yaml/yaml_test.go Normal file
View File

@@ -0,0 +1,115 @@
// 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 yaml
import (
"fmt"
"os"
"testing"
"github.com/astaxie/beego/config"
)
func TestYaml(t *testing.T) {
var (
yamlcontext = `
"appname": beeapi
"httpport": 8080
"mysqlport": 3600
"PI": 3.1415976
"runmode": dev
"autorender": false
"copyrequestbody": true
"PATH": GOPATH
"path1": ${GOPATH}
"path2": ${GOPATH||/home/go}
"empty": ""
`
keyValue = map[string]interface{}{
"appname": "beeapi",
"httpport": 8080,
"mysqlport": int64(3600),
"PI": 3.1415976,
"runmode": "dev",
"autorender": false,
"copyrequestbody": true,
"PATH": "GOPATH",
"path1": os.Getenv("GOPATH"),
"path2": os.Getenv("GOPATH"),
"error": "",
"emptystrings": []string{},
}
)
f, err := os.Create("testyaml.conf")
if err != nil {
t.Fatal(err)
}
_, err = f.WriteString(yamlcontext)
if err != nil {
f.Close()
t.Fatal(err)
}
f.Close()
defer os.Remove("testyaml.conf")
yamlconf, err := config.NewConfig("yaml", "testyaml.conf")
if err != nil {
t.Fatal(err)
}
if yamlconf.String("appname") != "beeapi" {
t.Fatal("appname not equal to beeapi")
}
for k, v := range keyValue {
var (
value interface{}
err error
)
switch v.(type) {
case int:
value, err = yamlconf.Int(k)
case int64:
value, err = yamlconf.Int64(k)
case float64:
value, err = yamlconf.Float(k)
case bool:
value, err = yamlconf.Bool(k)
case []string:
value = yamlconf.Strings(k)
case string:
value = yamlconf.String(k)
default:
value, err = yamlconf.DIY(k)
}
if err != nil {
t.Errorf("get key %q value fatal,%v err %s", k, v, err)
} else if fmt.Sprintf("%v", v) != fmt.Sprintf("%v", value) {
t.Errorf("get key %q value, want %v got %v .", k, v, value)
}
}
if err = yamlconf.Set("name", "astaxie"); err != nil {
t.Fatal(err)
}
if yamlconf.String("name") != "astaxie" {
t.Fatal("get name error")
}
}

146
config_test.go Normal file
View File

@@ -0,0 +1,146 @@
// 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 beego
import (
"encoding/json"
"reflect"
"testing"
"github.com/astaxie/beego/config"
)
func TestDefaults(t *testing.T) {
if BConfig.WebConfig.FlashName != "BEEGO_FLASH" {
t.Errorf("FlashName was not set to default.")
}
if BConfig.WebConfig.FlashSeparator != "BEEGOFLASH" {
t.Errorf("FlashName was not set to default.")
}
}
func TestAssignConfig_01(t *testing.T) {
_BConfig := &Config{}
_BConfig.AppName = "beego_test"
jcf := &config.JSONConfig{}
ac, _ := jcf.ParseData([]byte(`{"AppName":"beego_json"}`))
assignSingleConfig(_BConfig, ac)
if _BConfig.AppName != "beego_json" {
t.Log(_BConfig)
t.FailNow()
}
}
func TestAssignConfig_02(t *testing.T) {
_BConfig := &Config{}
bs, _ := json.Marshal(newBConfig())
jsonMap := M{}
json.Unmarshal(bs, &jsonMap)
configMap := M{}
for k, v := range jsonMap {
if reflect.TypeOf(v).Kind() == reflect.Map {
for k1, v1 := range v.(M) {
if reflect.TypeOf(v1).Kind() == reflect.Map {
for k2, v2 := range v1.(M) {
configMap[k2] = v2
}
} else {
configMap[k1] = v1
}
}
} else {
configMap[k] = v
}
}
configMap["MaxMemory"] = 1024
configMap["Graceful"] = true
configMap["XSRFExpire"] = 32
configMap["SessionProviderConfig"] = "file"
configMap["FileLineNum"] = true
jcf := &config.JSONConfig{}
bs, _ = json.Marshal(configMap)
ac, _ := jcf.ParseData(bs)
for _, i := range []interface{}{_BConfig, &_BConfig.Listen, &_BConfig.WebConfig, &_BConfig.Log, &_BConfig.WebConfig.Session} {
assignSingleConfig(i, ac)
}
if _BConfig.MaxMemory != 1024 {
t.Log(_BConfig.MaxMemory)
t.FailNow()
}
if !_BConfig.Listen.Graceful {
t.Log(_BConfig.Listen.Graceful)
t.FailNow()
}
if _BConfig.WebConfig.XSRFExpire != 32 {
t.Log(_BConfig.WebConfig.XSRFExpire)
t.FailNow()
}
if _BConfig.WebConfig.Session.SessionProviderConfig != "file" {
t.Log(_BConfig.WebConfig.Session.SessionProviderConfig)
t.FailNow()
}
if !_BConfig.Log.FileLineNum {
t.Log(_BConfig.Log.FileLineNum)
t.FailNow()
}
}
func TestAssignConfig_03(t *testing.T) {
jcf := &config.JSONConfig{}
ac, _ := jcf.ParseData([]byte(`{"AppName":"beego"}`))
ac.Set("AppName", "test_app")
ac.Set("RunMode", "online")
ac.Set("StaticDir", "download:down download2:down2")
ac.Set("StaticExtensionsToGzip", ".css,.js,.html,.jpg,.png")
ac.Set("StaticCacheFileSize", "87456")
ac.Set("StaticCacheFileNum", "1254")
assignConfig(ac)
t.Logf("%#v", BConfig)
if BConfig.AppName != "test_app" {
t.FailNow()
}
if BConfig.RunMode != "online" {
t.FailNow()
}
if BConfig.WebConfig.StaticDir["/download"] != "down" {
t.FailNow()
}
if BConfig.WebConfig.StaticDir["/download2"] != "down2" {
t.FailNow()
}
if BConfig.WebConfig.StaticCacheFileSize != 87456 {
t.FailNow()
}
if BConfig.WebConfig.StaticCacheFileNum != 1254 {
t.FailNow()
}
if len(BConfig.WebConfig.StaticExtensionsToGzip) != 5 {
t.FailNow()
}
}

View File

@@ -1,119 +0,0 @@
package beego
import (
"bytes"
"fmt"
"mime"
"net/http"
"strings"
)
type Context struct {
ResponseWriter http.ResponseWriter
Request *http.Request
RequestBody []byte
Params map[string]string
}
func (ctx *Context) WriteString(content string) {
ctx.ResponseWriter.Write([]byte(content))
}
func (ctx *Context) Abort(status int, body string) {
ctx.ResponseWriter.WriteHeader(status)
ctx.ResponseWriter.Write([]byte(body))
}
func (ctx *Context) Redirect(status int, url_ string) {
ctx.ResponseWriter.Header().Set("Location", url_)
ctx.ResponseWriter.WriteHeader(status)
}
func (ctx *Context) NotModified() {
ctx.ResponseWriter.WriteHeader(304)
}
func (ctx *Context) NotFound(message string) {
ctx.ResponseWriter.WriteHeader(404)
ctx.ResponseWriter.Write([]byte(message))
}
//Sets the content type by extension, as defined in the mime package.
//For example, ctx.ContentType("json") sets the content-type to "application/json"
func (ctx *Context) ContentType(ext string) {
if !strings.HasPrefix(ext, ".") {
ext = "." + ext
}
ctype := mime.TypeByExtension(ext)
if ctype != "" {
ctx.ResponseWriter.Header().Set("Content-Type", ctype)
}
}
func (ctx *Context) SetHeader(hdr string, val string, unique bool) {
if unique {
ctx.ResponseWriter.Header().Set(hdr, val)
} else {
ctx.ResponseWriter.Header().Add(hdr, val)
}
}
//Sets a cookie -- duration is the amount of time in seconds. 0 = forever
//params:
//string name
//string value
//int64 expire = 0
//string $path
//string $domain
//bool $secure = false
//bool $httponly = false
func (ctx *Context) SetCookie(name string, value string, others ...interface{}) {
var b bytes.Buffer
fmt.Fprintf(&b, "%s=%s", sanitizeName(name), sanitizeValue(value))
if len(others) > 0 {
switch others[0].(type) {
case int:
fmt.Fprintf(&b, "; Max-Age=%d", others[0].(int))
case int64:
fmt.Fprintf(&b, "; Max-Age=%d", others[0].(int64))
case int32:
fmt.Fprintf(&b, "; Max-Age=%d", others[0].(int32))
}
} else {
fmt.Fprintf(&b, "; Max-Age=0")
}
if len(others) > 1 {
fmt.Fprintf(&b, "; Path=%s", sanitizeValue(others[1].(string)))
}
if len(others) > 2 {
fmt.Fprintf(&b, "; Domain=%s", sanitizeValue(others[2].(string)))
}
if len(others) > 3 {
fmt.Fprintf(&b, "; Secure")
}
if len(others) > 4 {
fmt.Fprintf(&b, "; HttpOnly")
}
ctx.SetHeader("Set-Cookie", b.String(), false)
}
var cookieNameSanitizer = strings.NewReplacer("\n", "-", "\r", "-")
func sanitizeName(n string) string {
return cookieNameSanitizer.Replace(n)
}
var cookieValueSanitizer = strings.NewReplacer("\n", " ", "\r", " ", ";", " ")
func sanitizeValue(v string) string {
return cookieValueSanitizer.Replace(v)
}
func (ctx *Context) GetCookie(key string) string {
keycookie, err := ctx.Request.Cookie(key)
if err != nil {
return ""
}
return keycookie.Value
}

232
context/acceptencoder.go Normal file
View File

@@ -0,0 +1,232 @@
// Copyright 2015 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 context
import (
"bytes"
"compress/flate"
"compress/gzip"
"compress/zlib"
"io"
"net/http"
"os"
"strconv"
"strings"
"sync"
)
var (
//Default size==20B same as nginx
defaultGzipMinLength = 20
//Content will only be compressed if content length is either unknown or greater than gzipMinLength.
gzipMinLength = defaultGzipMinLength
//The compression level used for deflate compression. (0-9).
gzipCompressLevel int
//List of HTTP methods to compress. If not set, only GET requests are compressed.
includedMethods map[string]bool
getMethodOnly bool
)
// InitGzip init the gzipcompress
func InitGzip(minLength, compressLevel int, methods []string) {
if minLength >= 0 {
gzipMinLength = minLength
}
gzipCompressLevel = compressLevel
if gzipCompressLevel < flate.NoCompression || gzipCompressLevel > flate.BestCompression {
gzipCompressLevel = flate.BestSpeed
}
getMethodOnly = (len(methods) == 0) || (len(methods) == 1 && strings.ToUpper(methods[0]) == "GET")
includedMethods = make(map[string]bool, len(methods))
for _, v := range methods {
includedMethods[strings.ToUpper(v)] = true
}
}
type resetWriter interface {
io.Writer
Reset(w io.Writer)
}
type nopResetWriter struct {
io.Writer
}
func (n nopResetWriter) Reset(w io.Writer) {
//do nothing
}
type acceptEncoder struct {
name string
levelEncode func(int) resetWriter
customCompressLevelPool *sync.Pool
bestCompressionPool *sync.Pool
}
func (ac acceptEncoder) encode(wr io.Writer, level int) resetWriter {
if ac.customCompressLevelPool == nil || ac.bestCompressionPool == nil {
return nopResetWriter{wr}
}
var rwr resetWriter
switch level {
case flate.BestSpeed:
rwr = ac.customCompressLevelPool.Get().(resetWriter)
case flate.BestCompression:
rwr = ac.bestCompressionPool.Get().(resetWriter)
default:
rwr = ac.levelEncode(level)
}
rwr.Reset(wr)
return rwr
}
func (ac acceptEncoder) put(wr resetWriter, level int) {
if ac.customCompressLevelPool == nil || ac.bestCompressionPool == nil {
return
}
wr.Reset(nil)
//notice
//compressionLevel==BestCompression DOES NOT MATTER
//sync.Pool will not memory leak
switch level {
case gzipCompressLevel:
ac.customCompressLevelPool.Put(wr)
case flate.BestCompression:
ac.bestCompressionPool.Put(wr)
}
}
var (
noneCompressEncoder = acceptEncoder{"", nil, nil, nil}
gzipCompressEncoder = acceptEncoder{
name: "gzip",
levelEncode: func(level int) resetWriter { wr, _ := gzip.NewWriterLevel(nil, level); return wr },
customCompressLevelPool: &sync.Pool{New: func() interface{} { wr, _ := gzip.NewWriterLevel(nil, gzipCompressLevel); return wr }},
bestCompressionPool: &sync.Pool{New: func() interface{} { wr, _ := gzip.NewWriterLevel(nil, flate.BestCompression); return wr }},
}
//according to the sec :http://tools.ietf.org/html/rfc2616#section-3.5 ,the deflate compress in http is zlib indeed
//deflate
//The "zlib" format defined in RFC 1950 [31] in combination with
//the "deflate" compression mechanism described in RFC 1951 [29].
deflateCompressEncoder = acceptEncoder{
name: "deflate",
levelEncode: func(level int) resetWriter { wr, _ := zlib.NewWriterLevel(nil, level); return wr },
customCompressLevelPool: &sync.Pool{New: func() interface{} { wr, _ := zlib.NewWriterLevel(nil, gzipCompressLevel); return wr }},
bestCompressionPool: &sync.Pool{New: func() interface{} { wr, _ := zlib.NewWriterLevel(nil, flate.BestCompression); return wr }},
}
)
var (
encoderMap = map[string]acceptEncoder{ // all the other compress methods will ignore
"gzip": gzipCompressEncoder,
"deflate": deflateCompressEncoder,
"*": gzipCompressEncoder, // * means any compress will accept,we prefer gzip
"identity": noneCompressEncoder, // identity means none-compress
}
)
// WriteFile reads from file and writes to writer by the specific encoding(gzip/deflate)
func WriteFile(encoding string, writer io.Writer, file *os.File) (bool, string, error) {
return writeLevel(encoding, writer, file, flate.BestCompression)
}
// WriteBody reads writes content to writer by the specific encoding(gzip/deflate)
func WriteBody(encoding string, writer io.Writer, content []byte) (bool, string, error) {
if encoding == "" || len(content) < gzipMinLength {
_, err := writer.Write(content)
return false, "", err
}
return writeLevel(encoding, writer, bytes.NewReader(content), gzipCompressLevel)
}
// writeLevel reads from reader,writes to writer by specific encoding and compress level
// the compress level is defined by deflate package
func writeLevel(encoding string, writer io.Writer, reader io.Reader, level int) (bool, string, error) {
var outputWriter resetWriter
var err error
var ce = noneCompressEncoder
if cf, ok := encoderMap[encoding]; ok {
ce = cf
}
encoding = ce.name
outputWriter = ce.encode(writer, level)
defer ce.put(outputWriter, level)
_, err = io.Copy(outputWriter, reader)
if err != nil {
return false, "", err
}
switch outputWriter.(type) {
case io.WriteCloser:
outputWriter.(io.WriteCloser).Close()
}
return encoding != "", encoding, nil
}
// ParseEncoding will extract the right encoding for response
// the Accept-Encoding's sec is here:
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3
func ParseEncoding(r *http.Request) string {
if r == nil {
return ""
}
if (getMethodOnly && r.Method == "GET") || includedMethods[r.Method] {
return parseEncoding(r)
}
return ""
}
type q struct {
name string
value float64
}
func parseEncoding(r *http.Request) string {
acceptEncoding := r.Header.Get("Accept-Encoding")
if acceptEncoding == "" {
return ""
}
var lastQ q
for _, v := range strings.Split(acceptEncoding, ",") {
v = strings.TrimSpace(v)
if v == "" {
continue
}
vs := strings.Split(v, ";")
var cf acceptEncoder
var ok bool
if cf, ok = encoderMap[vs[0]]; !ok {
continue
}
if len(vs) == 1 {
return cf.name
}
if len(vs) == 2 {
f, _ := strconv.ParseFloat(strings.Replace(vs[1], "q=", "", -1), 64)
if f == 0 {
continue
}
if f > lastQ.value {
lastQ = q{cf.name, f}
}
}
}
return lastQ.name
}

View File

@@ -0,0 +1,59 @@
// Copyright 2015 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 context
import (
"net/http"
"testing"
)
func Test_ExtractEncoding(t *testing.T) {
if parseEncoding(&http.Request{Header: map[string][]string{"Accept-Encoding": {"gzip,deflate"}}}) != "gzip" {
t.Fail()
}
if parseEncoding(&http.Request{Header: map[string][]string{"Accept-Encoding": {"deflate,gzip"}}}) != "deflate" {
t.Fail()
}
if parseEncoding(&http.Request{Header: map[string][]string{"Accept-Encoding": {"gzip;q=.5,deflate"}}}) != "deflate" {
t.Fail()
}
if parseEncoding(&http.Request{Header: map[string][]string{"Accept-Encoding": {"gzip;q=.5,deflate;q=0.3"}}}) != "gzip" {
t.Fail()
}
if parseEncoding(&http.Request{Header: map[string][]string{"Accept-Encoding": {"gzip;q=0,deflate"}}}) != "deflate" {
t.Fail()
}
if parseEncoding(&http.Request{Header: map[string][]string{"Accept-Encoding": {"deflate;q=0.5,gzip;q=0.5,identity"}}}) != "" {
t.Fail()
}
if parseEncoding(&http.Request{Header: map[string][]string{"Accept-Encoding": {"*"}}}) != "gzip" {
t.Fail()
}
if parseEncoding(&http.Request{Header: map[string][]string{"Accept-Encoding": {"x,gzip,deflate"}}}) != "gzip" {
t.Fail()
}
if parseEncoding(&http.Request{Header: map[string][]string{"Accept-Encoding": {"gzip,x,deflate"}}}) != "gzip" {
t.Fail()
}
if parseEncoding(&http.Request{Header: map[string][]string{"Accept-Encoding": {"gzip;q=0.5,x,deflate"}}}) != "deflate" {
t.Fail()
}
if parseEncoding(&http.Request{Header: map[string][]string{"Accept-Encoding": {"x"}}}) != "" {
t.Fail()
}
if parseEncoding(&http.Request{Header: map[string][]string{"Accept-Encoding": {"gzip;q=0.5,x;q=0.8"}}}) != "gzip" {
t.Fail()
}
}

263
context/context.go Normal file
View File

@@ -0,0 +1,263 @@
// 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 context provide the context utils
// Usage:
//
// import "github.com/astaxie/beego/context"
//
// ctx := context.Context{Request:req,ResponseWriter:rw}
//
// more docs http://beego.me/docs/module/context.md
package context
import (
"bufio"
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"errors"
"fmt"
"net"
"net/http"
"strconv"
"strings"
"time"
"github.com/astaxie/beego/utils"
)
//commonly used mime-types
const (
ApplicationJSON = "application/json"
ApplicationXML = "application/xml"
ApplicationYAML = "application/x-yaml"
TextXML = "text/xml"
)
// NewContext return the Context with Input and Output
func NewContext() *Context {
return &Context{
Input: NewInput(),
Output: NewOutput(),
}
}
// Context Http request context struct including BeegoInput, BeegoOutput, http.Request and http.ResponseWriter.
// BeegoInput and BeegoOutput provides some api to operate request and response more easily.
type Context struct {
Input *BeegoInput
Output *BeegoOutput
Request *http.Request
ResponseWriter *Response
_xsrfToken string
}
// Reset init Context, BeegoInput and BeegoOutput
func (ctx *Context) Reset(rw http.ResponseWriter, r *http.Request) {
ctx.Request = r
if ctx.ResponseWriter == nil {
ctx.ResponseWriter = &Response{}
}
ctx.ResponseWriter.reset(rw)
ctx.Input.Reset(ctx)
ctx.Output.Reset(ctx)
ctx._xsrfToken = ""
}
// Redirect does redirection to localurl with http header status code.
func (ctx *Context) Redirect(status int, localurl string) {
http.Redirect(ctx.ResponseWriter, ctx.Request, localurl, status)
}
// Abort stops this request.
// if beego.ErrorMaps exists, panic body.
func (ctx *Context) Abort(status int, body string) {
ctx.Output.SetStatus(status)
panic(body)
}
// WriteString Write string to response body.
// it sends response body.
func (ctx *Context) WriteString(content string) {
ctx.ResponseWriter.Write([]byte(content))
}
// GetCookie Get cookie from request by a given key.
// It's alias of BeegoInput.Cookie.
func (ctx *Context) GetCookie(key string) string {
return ctx.Input.Cookie(key)
}
// SetCookie Set cookie for response.
// It's alias of BeegoOutput.Cookie.
func (ctx *Context) SetCookie(name string, value string, others ...interface{}) {
ctx.Output.Cookie(name, value, others...)
}
// GetSecureCookie Get secure cookie from request by a given key.
func (ctx *Context) GetSecureCookie(Secret, key string) (string, bool) {
val := ctx.Input.Cookie(key)
if val == "" {
return "", false
}
parts := strings.SplitN(val, "|", 3)
if len(parts) != 3 {
return "", false
}
vs := parts[0]
timestamp := parts[1]
sig := parts[2]
h := hmac.New(sha256.New, []byte(Secret))
fmt.Fprintf(h, "%s%s", vs, timestamp)
if fmt.Sprintf("%02x", h.Sum(nil)) != sig {
return "", false
}
res, _ := base64.URLEncoding.DecodeString(vs)
return string(res), true
}
// SetSecureCookie Set Secure cookie for response.
func (ctx *Context) SetSecureCookie(Secret, name, value string, others ...interface{}) {
vs := base64.URLEncoding.EncodeToString([]byte(value))
timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
h := hmac.New(sha256.New, []byte(Secret))
fmt.Fprintf(h, "%s%s", vs, timestamp)
sig := fmt.Sprintf("%02x", h.Sum(nil))
cookie := strings.Join([]string{vs, timestamp, sig}, "|")
ctx.Output.Cookie(name, cookie, others...)
}
// XSRFToken creates a xsrf token string and returns.
func (ctx *Context) XSRFToken(key string, expire int64) string {
if ctx._xsrfToken == "" {
token, ok := ctx.GetSecureCookie(key, "_xsrf")
if !ok {
token = string(utils.RandomCreateBytes(32))
ctx.SetSecureCookie(key, "_xsrf", token, expire, "", "", true, true)
}
ctx._xsrfToken = token
}
return ctx._xsrfToken
}
// CheckXSRFCookie checks xsrf token in this request is valid or not.
// the token can provided in request header "X-Xsrftoken" and "X-CsrfToken"
// or in form field value named as "_xsrf".
func (ctx *Context) CheckXSRFCookie() bool {
token := ctx.Input.Query("_xsrf")
if token == "" {
token = ctx.Request.Header.Get("X-Xsrftoken")
}
if token == "" {
token = ctx.Request.Header.Get("X-Csrftoken")
}
if token == "" {
ctx.Abort(422, "422")
return false
}
if ctx._xsrfToken != token {
ctx.Abort(417, "417")
return false
}
return true
}
// RenderMethodResult renders the return value of a controller method to the output
func (ctx *Context) RenderMethodResult(result interface{}) {
if result != nil {
renderer, ok := result.(Renderer)
if !ok {
err, ok := result.(error)
if ok {
renderer = errorRenderer(err)
} else {
renderer = jsonRenderer(result)
}
}
renderer.Render(ctx)
}
}
//Response is a wrapper for the http.ResponseWriter
//started set to true if response was written to then don't execute other handler
type Response struct {
http.ResponseWriter
Started bool
Status int
Elapsed time.Duration
}
func (r *Response) reset(rw http.ResponseWriter) {
r.ResponseWriter = rw
r.Status = 0
r.Started = false
}
// Write writes the data to the connection as part of an HTTP reply,
// and sets `started` to true.
// started means the response has sent out.
func (r *Response) Write(p []byte) (int, error) {
r.Started = true
return r.ResponseWriter.Write(p)
}
// WriteHeader sends an HTTP response header with status code,
// and sets `started` to true.
func (r *Response) WriteHeader(code int) {
if r.Status > 0 {
//prevent multiple response.WriteHeader calls
return
}
r.Status = code
r.Started = true
r.ResponseWriter.WriteHeader(code)
}
// Hijack hijacker for http
func (r *Response) Hijack() (net.Conn, *bufio.ReadWriter, error) {
hj, ok := r.ResponseWriter.(http.Hijacker)
if !ok {
return nil, nil, errors.New("webserver doesn't support hijacking")
}
return hj.Hijack()
}
// Flush http.Flusher
func (r *Response) Flush() {
if f, ok := r.ResponseWriter.(http.Flusher); ok {
f.Flush()
}
}
// CloseNotify http.CloseNotifier
func (r *Response) CloseNotify() <-chan bool {
if cn, ok := r.ResponseWriter.(http.CloseNotifier); ok {
return cn.CloseNotify()
}
return nil
}
// Pusher http.Pusher
func (r *Response) Pusher() (pusher http.Pusher) {
if pusher, ok := r.ResponseWriter.(http.Pusher); ok {
return pusher
}
return nil
}

54
context/context_test.go Normal file
View File

@@ -0,0 +1,54 @@
// Copyright 2016 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 context
import (
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
func TestXsrfReset_01(t *testing.T) {
r := &http.Request{}
c := NewContext()
c.Request = r
c.ResponseWriter = &Response{}
c.ResponseWriter.reset(httptest.NewRecorder())
c.Output.Reset(c)
c.Input.Reset(c)
c.XSRFToken("key", 16)
if c._xsrfToken == "" {
t.FailNow()
}
token := c._xsrfToken
c.Reset(&Response{ResponseWriter: httptest.NewRecorder()}, r)
if c._xsrfToken != "" {
t.FailNow()
}
c.XSRFToken("key", 16)
if c._xsrfToken == "" {
t.FailNow()
}
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"))
}

689
context/input.go Normal file
View File

@@ -0,0 +1,689 @@
// 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 context
import (
"bytes"
"compress/gzip"
"errors"
"io"
"io/ioutil"
"net"
"net/http"
"net/url"
"reflect"
"regexp"
"strconv"
"strings"
"sync"
"github.com/astaxie/beego/session"
)
// Regexes for checking the accept headers
// TODO make sure these are correct
var (
acceptsHTMLRegex = regexp.MustCompile(`(text/html|application/xhtml\+xml)(?:,|$)`)
acceptsXMLRegex = regexp.MustCompile(`(application/xml|text/xml)(?:,|$)`)
acceptsJSONRegex = regexp.MustCompile(`(application/json)(?:,|$)`)
acceptsYAMLRegex = regexp.MustCompile(`(application/x-yaml)(?:,|$)`)
maxParam = 50
)
// BeegoInput operates the http request header, data, cookie and body.
// it also contains router params and current session.
type BeegoInput struct {
Context *Context
CruSession session.Store
pnames []string
pvalues []string
data map[interface{}]interface{} // store some values in this context when calling context in filter or controller.
dataLock sync.RWMutex
RequestBody []byte
RunMethod string
RunController reflect.Type
}
// NewInput return BeegoInput generated by Context.
func NewInput() *BeegoInput {
return &BeegoInput{
pnames: make([]string, 0, maxParam),
pvalues: make([]string, 0, maxParam),
data: make(map[interface{}]interface{}),
}
}
// Reset init the BeegoInput
func (input *BeegoInput) Reset(ctx *Context) {
input.Context = ctx
input.CruSession = nil
input.pnames = input.pnames[:0]
input.pvalues = input.pvalues[:0]
input.dataLock.Lock()
input.data = nil
input.dataLock.Unlock()
input.RequestBody = []byte{}
}
// Protocol returns request protocol name, such as HTTP/1.1 .
func (input *BeegoInput) Protocol() string {
return input.Context.Request.Proto
}
// URI returns full request url with query string, fragment.
func (input *BeegoInput) URI() string {
return input.Context.Request.RequestURI
}
// URL returns request url path (without query string, fragment).
func (input *BeegoInput) URL() string {
return input.Context.Request.URL.EscapedPath()
}
// Site returns base site url as scheme://domain type.
func (input *BeegoInput) Site() string {
return input.Scheme() + "://" + input.Domain()
}
// Scheme returns request scheme as "http" or "https".
func (input *BeegoInput) Scheme() string {
if scheme := input.Header("X-Forwarded-Proto"); scheme != "" {
return scheme
}
if input.Context.Request.URL.Scheme != "" {
return input.Context.Request.URL.Scheme
}
if input.Context.Request.TLS == nil {
return "http"
}
return "https"
}
// Domain returns host name.
// Alias of Host method.
func (input *BeegoInput) Domain() string {
return input.Host()
}
// Host returns host name.
// if no host info in request, return localhost.
func (input *BeegoInput) Host() string {
if input.Context.Request.Host != "" {
if hostPart, _, err := net.SplitHostPort(input.Context.Request.Host); err == nil {
return hostPart
}
return input.Context.Request.Host
}
return "localhost"
}
// Method returns http request method.
func (input *BeegoInput) Method() string {
return input.Context.Request.Method
}
// Is returns boolean of this request is on given method, such as Is("POST").
func (input *BeegoInput) Is(method string) bool {
return input.Method() == method
}
// IsGet Is this a GET method request?
func (input *BeegoInput) IsGet() bool {
return input.Is("GET")
}
// IsPost Is this a POST method request?
func (input *BeegoInput) IsPost() bool {
return input.Is("POST")
}
// IsHead Is this a Head method request?
func (input *BeegoInput) IsHead() bool {
return input.Is("HEAD")
}
// IsOptions Is this a OPTIONS method request?
func (input *BeegoInput) IsOptions() bool {
return input.Is("OPTIONS")
}
// IsPut Is this a PUT method request?
func (input *BeegoInput) IsPut() bool {
return input.Is("PUT")
}
// IsDelete Is this a DELETE method request?
func (input *BeegoInput) IsDelete() bool {
return input.Is("DELETE")
}
// IsPatch Is this a PATCH method request?
func (input *BeegoInput) IsPatch() bool {
return input.Is("PATCH")
}
// IsAjax returns boolean of this request is generated by ajax.
func (input *BeegoInput) IsAjax() bool {
return input.Header("X-Requested-With") == "XMLHttpRequest"
}
// IsSecure returns boolean of this request is in https.
func (input *BeegoInput) IsSecure() bool {
return input.Scheme() == "https"
}
// IsWebsocket returns boolean of this request is in webSocket.
func (input *BeegoInput) IsWebsocket() bool {
return input.Header("Upgrade") == "websocket"
}
// IsUpload returns boolean of whether file uploads in this request or not..
func (input *BeegoInput) IsUpload() bool {
return strings.Contains(input.Header("Content-Type"), "multipart/form-data")
}
// AcceptsHTML Checks if request accepts html response
func (input *BeegoInput) AcceptsHTML() bool {
return acceptsHTMLRegex.MatchString(input.Header("Accept"))
}
// AcceptsXML Checks if request accepts xml response
func (input *BeegoInput) AcceptsXML() bool {
return acceptsXMLRegex.MatchString(input.Header("Accept"))
}
// AcceptsJSON Checks if request accepts json response
func (input *BeegoInput) AcceptsJSON() bool {
return acceptsJSONRegex.MatchString(input.Header("Accept"))
}
// AcceptsYAML Checks if request accepts json response
func (input *BeegoInput) AcceptsYAML() bool {
return acceptsYAMLRegex.MatchString(input.Header("Accept"))
}
// IP returns request client ip.
// if in proxy, return first proxy id.
// if error, return RemoteAddr.
func (input *BeegoInput) IP() string {
ips := input.Proxy()
if len(ips) > 0 && ips[0] != "" {
rip, _, err := net.SplitHostPort(ips[0])
if err != nil {
rip = ips[0]
}
return rip
}
if ip, _, err := net.SplitHostPort(input.Context.Request.RemoteAddr); err == nil {
return ip
}
return input.Context.Request.RemoteAddr
}
// Proxy returns proxy client ips slice.
func (input *BeegoInput) Proxy() []string {
if ips := input.Header("X-Forwarded-For"); ips != "" {
return strings.Split(ips, ",")
}
return []string{}
}
// Referer returns http referer header.
func (input *BeegoInput) Referer() string {
return input.Header("Referer")
}
// Refer returns http referer header.
func (input *BeegoInput) Refer() string {
return input.Referer()
}
// SubDomains returns sub domain string.
// if aa.bb.domain.com, returns aa.bb .
func (input *BeegoInput) SubDomains() string {
parts := strings.Split(input.Host(), ".")
if len(parts) >= 3 {
return strings.Join(parts[:len(parts)-2], ".")
}
return ""
}
// Port returns request client port.
// when error or empty, return 80.
func (input *BeegoInput) Port() int {
if _, portPart, err := net.SplitHostPort(input.Context.Request.Host); err == nil {
port, _ := strconv.Atoi(portPart)
return port
}
return 80
}
// UserAgent returns request client user agent string.
func (input *BeegoInput) UserAgent() string {
return input.Header("User-Agent")
}
// ParamsLen return the length of the params
func (input *BeegoInput) ParamsLen() int {
return len(input.pnames)
}
// Param returns router param by a given key.
func (input *BeegoInput) Param(key string) string {
for i, v := range input.pnames {
if v == key && i <= len(input.pvalues) {
// we cannot use url.PathEscape(input.pvalues[i])
// for example, if the value is /a/b
// after url.PathEscape(input.pvalues[i]), the value is %2Fa%2Fb
// However, the value is used in ControllerRegister.ServeHTTP
// and split by "/", so function crash...
return input.pvalues[i]
}
}
return ""
}
// Params returns the map[key]value.
func (input *BeegoInput) Params() map[string]string {
m := make(map[string]string)
for i, v := range input.pnames {
if i <= len(input.pvalues) {
m[v] = input.pvalues[i]
}
}
return m
}
// SetParam will set the param with key and value
func (input *BeegoInput) SetParam(key, val string) {
// check if already exists
for i, v := range input.pnames {
if v == key && i <= len(input.pvalues) {
input.pvalues[i] = val
return
}
}
input.pvalues = append(input.pvalues, val)
input.pnames = append(input.pnames, key)
}
// ResetParams clears any of the input's Params
// This function is used to clear parameters so they may be reset between filter
// passes.
func (input *BeegoInput) ResetParams() {
input.pnames = input.pnames[:0]
input.pvalues = input.pvalues[:0]
}
// Query returns input data item string by a given string.
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)
}
// Header returns request header item string by a given string.
// if non-existed, return empty string.
func (input *BeegoInput) Header(key string) string {
return input.Context.Request.Header.Get(key)
}
// Cookie returns request cookie item string by a given key.
// if non-existed, return empty string.
func (input *BeegoInput) Cookie(key string) string {
ck, err := input.Context.Request.Cookie(key)
if err != nil {
return ""
}
return ck.Value
}
// Session returns current session item value by a given key.
// if non-existed, return nil.
func (input *BeegoInput) Session(key interface{}) interface{} {
return input.CruSession.Get(key)
}
// CopyBody returns the raw request body data as bytes.
func (input *BeegoInput) CopyBody(MaxMemory int64) []byte {
if input.Context.Request.Body == nil {
return []byte{}
}
var requestbody []byte
safe := &io.LimitedReader{R: input.Context.Request.Body, N: MaxMemory}
if input.Header("Content-Encoding") == "gzip" {
reader, err := gzip.NewReader(safe)
if err != nil {
return nil
}
requestbody, _ = ioutil.ReadAll(reader)
} else {
requestbody, _ = ioutil.ReadAll(safe)
}
input.Context.Request.Body.Close()
bf := bytes.NewBuffer(requestbody)
input.Context.Request.Body = http.MaxBytesReader(input.Context.ResponseWriter, ioutil.NopCloser(bf), MaxMemory)
input.RequestBody = requestbody
return requestbody
}
// Data return the implicit data in the input
func (input *BeegoInput) Data() map[interface{}]interface{} {
input.dataLock.Lock()
defer input.dataLock.Unlock()
if input.data == nil {
input.data = make(map[interface{}]interface{})
}
return input.data
}
// GetData returns the stored data in this context.
func (input *BeegoInput) GetData(key interface{}) interface{} {
input.dataLock.Lock()
defer input.dataLock.Unlock()
if v, ok := input.data[key]; ok {
return v
}
return nil
}
// SetData stores data with given key in this context.
// This data are only available in this context.
func (input *BeegoInput) SetData(key, val interface{}) {
input.dataLock.Lock()
defer input.dataLock.Unlock()
if input.data == nil {
input.data = make(map[interface{}]interface{})
}
input.data[key] = val
}
// ParseFormOrMulitForm parseForm or parseMultiForm based on Content-type
func (input *BeegoInput) ParseFormOrMulitForm(maxMemory int64) error {
// Parse the body depending on the content type.
if strings.Contains(input.Header("Content-Type"), "multipart/form-data") {
if err := input.Context.Request.ParseMultipartForm(maxMemory); err != nil {
return errors.New("Error parsing request body:" + err.Error())
}
} else if err := input.Context.Request.ParseForm(); err != nil {
return errors.New("Error parsing request body:" + err.Error())
}
return nil
}
// Bind data from request.Form[key] to dest
// like /?id=123&isok=true&ft=1.2&ol[0]=1&ol[1]=2&ul[]=str&ul[]=array&user.Name=astaxie
// var id int beegoInput.Bind(&id, "id") id ==123
// var isok bool beegoInput.Bind(&isok, "isok") isok ==true
// var ft float64 beegoInput.Bind(&ft, "ft") ft ==1.2
// ol := make([]int, 0, 2) beegoInput.Bind(&ol, "ol") ol ==[1 2]
// ul := make([]string, 0, 2) beegoInput.Bind(&ul, "ul") ul ==[str array]
// user struct{Name} beegoInput.Bind(&user, "user") user == {Name:"astaxie"}
func (input *BeegoInput) Bind(dest interface{}, key string) error {
value := reflect.ValueOf(dest)
if value.Kind() != reflect.Ptr {
return errors.New("beego: non-pointer passed to Bind: " + key)
}
value = value.Elem()
if !value.CanSet() {
return errors.New("beego: non-settable variable passed to Bind: " + key)
}
typ := value.Type()
// Get real type if dest define with interface{}.
// e.g var dest interface{} dest=1.0
if value.Kind() == reflect.Interface {
typ = value.Elem().Type()
}
rv := input.bind(key, typ)
if !rv.IsValid() {
return errors.New("beego: reflect value is empty")
}
value.Set(rv)
return nil
}
func (input *BeegoInput) bind(key string, typ reflect.Type) reflect.Value {
if input.Context.Request.Form == nil {
input.Context.Request.ParseForm()
}
rv := reflect.Zero(typ)
switch typ.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
val := input.Query(key)
if len(val) == 0 {
return rv
}
rv = input.bindInt(val, typ)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
val := input.Query(key)
if len(val) == 0 {
return rv
}
rv = input.bindUint(val, typ)
case reflect.Float32, reflect.Float64:
val := input.Query(key)
if len(val) == 0 {
return rv
}
rv = input.bindFloat(val, typ)
case reflect.String:
val := input.Query(key)
if len(val) == 0 {
return rv
}
rv = input.bindString(val, typ)
case reflect.Bool:
val := input.Query(key)
if len(val) == 0 {
return rv
}
rv = input.bindBool(val, typ)
case reflect.Slice:
rv = input.bindSlice(&input.Context.Request.Form, key, typ)
case reflect.Struct:
rv = input.bindStruct(&input.Context.Request.Form, key, typ)
case reflect.Ptr:
rv = input.bindPoint(key, typ)
case reflect.Map:
rv = input.bindMap(&input.Context.Request.Form, key, typ)
}
return rv
}
func (input *BeegoInput) bindValue(val string, typ reflect.Type) reflect.Value {
rv := reflect.Zero(typ)
switch typ.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
rv = input.bindInt(val, typ)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
rv = input.bindUint(val, typ)
case reflect.Float32, reflect.Float64:
rv = input.bindFloat(val, typ)
case reflect.String:
rv = input.bindString(val, typ)
case reflect.Bool:
rv = input.bindBool(val, typ)
case reflect.Slice:
rv = input.bindSlice(&url.Values{"": {val}}, "", typ)
case reflect.Struct:
rv = input.bindStruct(&url.Values{"": {val}}, "", typ)
case reflect.Ptr:
rv = input.bindPoint(val, typ)
case reflect.Map:
rv = input.bindMap(&url.Values{"": {val}}, "", typ)
}
return rv
}
func (input *BeegoInput) bindInt(val string, typ reflect.Type) reflect.Value {
intValue, err := strconv.ParseInt(val, 10, 64)
if err != nil {
return reflect.Zero(typ)
}
pValue := reflect.New(typ)
pValue.Elem().SetInt(intValue)
return pValue.Elem()
}
func (input *BeegoInput) bindUint(val string, typ reflect.Type) reflect.Value {
uintValue, err := strconv.ParseUint(val, 10, 64)
if err != nil {
return reflect.Zero(typ)
}
pValue := reflect.New(typ)
pValue.Elem().SetUint(uintValue)
return pValue.Elem()
}
func (input *BeegoInput) bindFloat(val string, typ reflect.Type) reflect.Value {
floatValue, err := strconv.ParseFloat(val, 64)
if err != nil {
return reflect.Zero(typ)
}
pValue := reflect.New(typ)
pValue.Elem().SetFloat(floatValue)
return pValue.Elem()
}
func (input *BeegoInput) bindString(val string, typ reflect.Type) reflect.Value {
return reflect.ValueOf(val)
}
func (input *BeegoInput) bindBool(val string, typ reflect.Type) reflect.Value {
val = strings.TrimSpace(strings.ToLower(val))
switch val {
case "true", "on", "1":
return reflect.ValueOf(true)
}
return reflect.ValueOf(false)
}
type sliceValue struct {
index int // Index extracted from brackets. If -1, no index was provided.
value reflect.Value // the bound value for this slice element.
}
func (input *BeegoInput) bindSlice(params *url.Values, key string, typ reflect.Type) reflect.Value {
maxIndex := -1
numNoIndex := 0
sliceValues := []sliceValue{}
for reqKey, vals := range *params {
if !strings.HasPrefix(reqKey, key+"[") {
continue
}
// Extract the index, and the index where a sub-key starts. (e.g. field[0].subkey)
index := -1
leftBracket, rightBracket := len(key), strings.Index(reqKey[len(key):], "]")+len(key)
if rightBracket > leftBracket+1 {
index, _ = strconv.Atoi(reqKey[leftBracket+1 : rightBracket])
}
subKeyIndex := rightBracket + 1
// Handle the indexed case.
if index > -1 {
if index > maxIndex {
maxIndex = index
}
sliceValues = append(sliceValues, sliceValue{
index: index,
value: input.bind(reqKey[:subKeyIndex], typ.Elem()),
})
continue
}
// It's an un-indexed element. (e.g. element[])
numNoIndex += len(vals)
for _, val := range vals {
// Unindexed values can only be direct-bound.
sliceValues = append(sliceValues, sliceValue{
index: -1,
value: input.bindValue(val, typ.Elem()),
})
}
}
resultArray := reflect.MakeSlice(typ, maxIndex+1, maxIndex+1+numNoIndex)
for _, sv := range sliceValues {
if sv.index != -1 {
resultArray.Index(sv.index).Set(sv.value)
} else {
resultArray = reflect.Append(resultArray, sv.value)
}
}
return resultArray
}
func (input *BeegoInput) bindStruct(params *url.Values, key string, typ reflect.Type) reflect.Value {
result := reflect.New(typ).Elem()
fieldValues := make(map[string]reflect.Value)
for reqKey, val := range *params {
var fieldName string
if strings.HasPrefix(reqKey, key+".") {
fieldName = reqKey[len(key)+1:]
} else if strings.HasPrefix(reqKey, key+"[") && reqKey[len(reqKey)-1] == ']' {
fieldName = reqKey[len(key)+1 : len(reqKey)-1]
} else {
continue
}
if _, ok := fieldValues[fieldName]; !ok {
// Time to bind this field. Get it and make sure we can set it.
fieldValue := result.FieldByName(fieldName)
if !fieldValue.IsValid() {
continue
}
if !fieldValue.CanSet() {
continue
}
boundVal := input.bindValue(val[0], fieldValue.Type())
fieldValue.Set(boundVal)
fieldValues[fieldName] = boundVal
}
}
return result
}
func (input *BeegoInput) bindPoint(key string, typ reflect.Type) reflect.Value {
return input.bind(key, typ.Elem()).Addr()
}
func (input *BeegoInput) bindMap(params *url.Values, key string, typ reflect.Type) reflect.Value {
var (
result = reflect.MakeMap(typ)
keyType = typ.Key()
valueType = typ.Elem()
)
for paramName, values := range *params {
if !strings.HasPrefix(paramName, key+"[") || paramName[len(paramName)-1] != ']' {
continue
}
key := paramName[len(key)+1 : len(paramName)-1]
result.SetMapIndex(input.bindValue(key, keyType), input.bindValue(values[0], valueType))
}
return result
}

217
context/input_test.go Normal file
View File

@@ -0,0 +1,217 @@
// 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 context
import (
"net/http"
"net/http/httptest"
"reflect"
"testing"
)
func TestBind(t *testing.T) {
type testItem struct {
field string
empty interface{}
want interface{}
}
type Human struct {
ID int
Nick string
Pwd string
Ms bool
}
cases := []struct {
request string
valueGp []testItem
}{
{"/?p=str", []testItem{{"p", interface{}(""), interface{}("str")}}},
{"/?p=", []testItem{{"p", "", ""}}},
{"/?p=str", []testItem{{"p", "", "str"}}},
{"/?p=123", []testItem{{"p", 0, 123}}},
{"/?p=123", []testItem{{"p", uint(0), uint(123)}}},
{"/?p=1.0", []testItem{{"p", 0.0, 1.0}}},
{"/?p=1", []testItem{{"p", false, true}}},
{"/?p=true", []testItem{{"p", false, true}}},
{"/?p=ON", []testItem{{"p", false, true}}},
{"/?p=on", []testItem{{"p", false, true}}},
{"/?p=1", []testItem{{"p", false, true}}},
{"/?p=2", []testItem{{"p", false, false}}},
{"/?p=false", []testItem{{"p", false, false}}},
{"/?p[a]=1&p[b]=2&p[c]=3", []testItem{{"p", map[string]int{}, map[string]int{"a": 1, "b": 2, "c": 3}}}},
{"/?p[a]=v1&p[b]=v2&p[c]=v3", []testItem{{"p", map[string]string{}, map[string]string{"a": "v1", "b": "v2", "c": "v3"}}}},
{"/?p[]=8&p[]=9&p[]=10", []testItem{{"p", []int{}, []int{8, 9, 10}}}},
{"/?p[0]=8&p[1]=9&p[2]=10", []testItem{{"p", []int{}, []int{8, 9, 10}}}},
{"/?p[0]=8&p[1]=9&p[2]=10&p[5]=14", []testItem{{"p", []int{}, []int{8, 9, 10, 0, 0, 14}}}},
{"/?p[0]=8.0&p[1]=9.0&p[2]=10.0", []testItem{{"p", []float64{}, []float64{8.0, 9.0, 10.0}}}},
{"/?p[]=10&p[]=9&p[]=8", []testItem{{"p", []string{}, []string{"10", "9", "8"}}}},
{"/?p[0]=8&p[1]=9&p[2]=10", []testItem{{"p", []string{}, []string{"8", "9", "10"}}}},
{"/?p[0]=true&p[1]=false&p[2]=true&p[5]=1&p[6]=ON&p[7]=other", []testItem{{"p", []bool{}, []bool{true, false, true, false, false, true, true, false}}}},
{"/?human.Nick=astaxie", []testItem{{"human", Human{}, Human{Nick: "astaxie"}}}},
{"/?human.ID=888&human.Nick=astaxie&human.Ms=true&human[Pwd]=pass", []testItem{{"human", Human{}, Human{ID: 888, Nick: "astaxie", Ms: true, Pwd: "pass"}}}},
{"/?human[0].ID=888&human[0].Nick=astaxie&human[0].Ms=true&human[0][Pwd]=pass01&human[1].ID=999&human[1].Nick=ysqi&human[1].Ms=On&human[1].Pwd=pass02",
[]testItem{{"human", []Human{}, []Human{
{ID: 888, Nick: "astaxie", Ms: true, Pwd: "pass01"},
{ID: 999, Nick: "ysqi", Ms: true, Pwd: "pass02"},
}}}},
{
"/?id=123&isok=true&ft=1.2&ol[0]=1&ol[1]=2&ul[]=str&ul[]=array&human.Nick=astaxie",
[]testItem{
{"id", 0, 123},
{"isok", false, true},
{"ft", 0.0, 1.2},
{"ol", []int{}, []int{1, 2}},
{"ul", []string{}, []string{"str", "array"}},
{"human", Human{}, Human{Nick: "astaxie"}},
},
},
}
for _, c := range cases {
r, _ := http.NewRequest("GET", c.request, nil)
beegoInput := NewInput()
beegoInput.Context = NewContext()
beegoInput.Context.Reset(httptest.NewRecorder(), r)
for _, item := range c.valueGp {
got := item.empty
err := beegoInput.Bind(&got, item.field)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(got, item.want) {
t.Fatalf("Bind %q error,should be:\n%#v \ngot:\n%#v", item.field, item.want, got)
}
}
}
}
func TestSubDomain(t *testing.T) {
r, _ := http.NewRequest("GET", "http://www.example.com/?id=123&isok=true&ft=1.2&ol[0]=1&ol[1]=2&ul[]=str&ul[]=array&user.Name=astaxie", nil)
beegoInput := NewInput()
beegoInput.Context = NewContext()
beegoInput.Context.Reset(httptest.NewRecorder(), r)
subdomain := beegoInput.SubDomains()
if subdomain != "www" {
t.Fatal("Subdomain parse error, got" + subdomain)
}
r, _ = http.NewRequest("GET", "http://localhost/", nil)
beegoInput.Context.Request = r
if beegoInput.SubDomains() != "" {
t.Fatal("Subdomain parse error, should be empty, got " + beegoInput.SubDomains())
}
r, _ = http.NewRequest("GET", "http://aa.bb.example.com/", nil)
beegoInput.Context.Request = r
if beegoInput.SubDomains() != "aa.bb" {
t.Fatal("Subdomain parse error, got " + beegoInput.SubDomains())
}
/* TODO Fix this
r, _ = http.NewRequest("GET", "http://127.0.0.1/", nil)
beegoInput.Context.Request = r
if beegoInput.SubDomains() != "" {
t.Fatal("Subdomain parse error, got " + beegoInput.SubDomains())
}
*/
r, _ = http.NewRequest("GET", "http://example.com/", nil)
beegoInput.Context.Request = r
if beegoInput.SubDomains() != "" {
t.Fatal("Subdomain parse error, got " + beegoInput.SubDomains())
}
r, _ = http.NewRequest("GET", "http://aa.bb.cc.dd.example.com/", nil)
beegoInput.Context.Request = r
if beegoInput.SubDomains() != "aa.bb.cc.dd" {
t.Fatal("Subdomain parse error, got " + beegoInput.SubDomains())
}
}
func TestParams(t *testing.T) {
inp := NewInput()
inp.SetParam("p1", "val1_ver1")
inp.SetParam("p2", "val2_ver1")
inp.SetParam("p3", "val3_ver1")
if l := inp.ParamsLen(); l != 3 {
t.Fatalf("Input.ParamsLen wrong value: %d, expected %d", l, 3)
}
if val := inp.Param("p1"); val != "val1_ver1" {
t.Fatalf("Input.Param wrong value: %s, expected %s", val, "val1_ver1")
}
if val := inp.Param("p3"); val != "val3_ver1" {
t.Fatalf("Input.Param wrong value: %s, expected %s", val, "val3_ver1")
}
vals := inp.Params()
expected := map[string]string{
"p1": "val1_ver1",
"p2": "val2_ver1",
"p3": "val3_ver1",
}
if !reflect.DeepEqual(vals, expected) {
t.Fatalf("Input.Params wrong value: %s, expected %s", vals, expected)
}
// overwriting existing params
inp.SetParam("p1", "val1_ver2")
inp.SetParam("p2", "val2_ver2")
expected = map[string]string{
"p1": "val1_ver2",
"p2": "val2_ver2",
"p3": "val3_ver1",
}
vals = inp.Params()
if !reflect.DeepEqual(vals, expected) {
t.Fatalf("Input.Params wrong value: %s, expected %s", vals, expected)
}
if l := inp.ParamsLen(); l != 3 {
t.Fatalf("Input.ParamsLen wrong value: %d, expected %d", l, 3)
}
if val := inp.Param("p1"); val != "val1_ver2" {
t.Fatalf("Input.Param wrong value: %s, expected %s", val, "val1_ver2")
}
if val := inp.Param("p2"); val != "val2_ver2" {
t.Fatalf("Input.Param wrong value: %s, expected %s", val, "val1_ver2")
}
}
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")
}
})
}

408
context/output.go Normal file
View File

@@ -0,0 +1,408 @@
// 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 context
import (
"bytes"
"encoding/json"
"encoding/xml"
"errors"
"fmt"
"html/template"
"io"
"mime"
"net/http"
"net/url"
"os"
"path/filepath"
"strconv"
"strings"
"time"
yaml "gopkg.in/yaml.v2"
)
// BeegoOutput does work for sending response header.
type BeegoOutput struct {
Context *Context
Status int
EnableGzip bool
}
// NewOutput returns new BeegoOutput.
// it contains nothing now.
func NewOutput() *BeegoOutput {
return &BeegoOutput{}
}
// Reset init BeegoOutput
func (output *BeegoOutput) Reset(ctx *Context) {
output.Context = ctx
output.Status = 0
}
// Header sets response header item string via given key.
func (output *BeegoOutput) Header(key, val string) {
output.Context.ResponseWriter.Header().Set(key, val)
}
// Body sets response body content.
// if EnableGzip, compress content string.
// it sends out response body directly.
func (output *BeegoOutput) Body(content []byte) error {
var encoding string
var buf = &bytes.Buffer{}
if output.EnableGzip {
encoding = ParseEncoding(output.Context.Request)
}
if b, n, _ := WriteBody(encoding, buf, content); b {
output.Header("Content-Encoding", n)
output.Header("Content-Length", strconv.Itoa(buf.Len()))
} else {
output.Header("Content-Length", strconv.Itoa(len(content)))
}
// Write status code if it has been set manually
// Set it to 0 afterwards to prevent "multiple response.WriteHeader calls"
if output.Status != 0 {
output.Context.ResponseWriter.WriteHeader(output.Status)
output.Status = 0
} else {
output.Context.ResponseWriter.Started = true
}
io.Copy(output.Context.ResponseWriter, buf)
return nil
}
// Cookie sets cookie value via given key.
// others are ordered as cookie's max age time, path,domain, secure and httponly.
func (output *BeegoOutput) Cookie(name string, value string, others ...interface{}) {
var b bytes.Buffer
fmt.Fprintf(&b, "%s=%s", sanitizeName(name), sanitizeValue(value))
//fix cookie not work in IE
if len(others) > 0 {
var maxAge int64
switch v := others[0].(type) {
case int:
maxAge = int64(v)
case int32:
maxAge = int64(v)
case int64:
maxAge = v
}
switch {
case maxAge > 0:
fmt.Fprintf(&b, "; Expires=%s; Max-Age=%d", time.Now().Add(time.Duration(maxAge)*time.Second).UTC().Format(time.RFC1123), maxAge)
case maxAge < 0:
fmt.Fprintf(&b, "; Max-Age=0")
}
}
// the settings below
// Path, Domain, Secure, HttpOnly
// can use nil skip set
// default "/"
if len(others) > 1 {
if v, ok := others[1].(string); ok && len(v) > 0 {
fmt.Fprintf(&b, "; Path=%s", sanitizeValue(v))
}
} else {
fmt.Fprintf(&b, "; Path=%s", "/")
}
// default empty
if len(others) > 2 {
if v, ok := others[2].(string); ok && len(v) > 0 {
fmt.Fprintf(&b, "; Domain=%s", sanitizeValue(v))
}
}
// default empty
if len(others) > 3 {
var secure bool
switch v := others[3].(type) {
case bool:
secure = v
default:
if others[3] != nil {
secure = true
}
}
if secure {
fmt.Fprintf(&b, "; Secure")
}
}
// default false. for session cookie default true
if len(others) > 4 {
if v, ok := others[4].(bool); ok && v {
fmt.Fprintf(&b, "; HttpOnly")
}
}
output.Context.ResponseWriter.Header().Add("Set-Cookie", b.String())
}
var cookieNameSanitizer = strings.NewReplacer("\n", "-", "\r", "-")
func sanitizeName(n string) string {
return cookieNameSanitizer.Replace(n)
}
var cookieValueSanitizer = strings.NewReplacer("\n", " ", "\r", " ", ";", " ")
func sanitizeValue(v string) string {
return cookieValueSanitizer.Replace(v)
}
func jsonRenderer(value interface{}) Renderer {
return rendererFunc(func(ctx *Context) {
ctx.Output.JSON(value, false, false)
})
}
func errorRenderer(err error) Renderer {
return rendererFunc(func(ctx *Context) {
ctx.Output.SetStatus(500)
ctx.Output.Body([]byte(err.Error()))
})
}
// JSON writes json to response body.
// if encoding is true, it converts utf-8 to \u0000 type.
func (output *BeegoOutput) JSON(data interface{}, hasIndent bool, encoding bool) error {
output.Header("Content-Type", "application/json; charset=utf-8")
var content []byte
var err error
if hasIndent {
content, err = json.MarshalIndent(data, "", " ")
} else {
content, err = json.Marshal(data)
}
if err != nil {
http.Error(output.Context.ResponseWriter, err.Error(), http.StatusInternalServerError)
return err
}
if encoding {
content = []byte(stringsToJSON(string(content)))
}
return output.Body(content)
}
// YAML writes yaml to response body.
func (output *BeegoOutput) YAML(data interface{}) error {
output.Header("Content-Type", "application/x-yaml; charset=utf-8")
var content []byte
var err error
content, err = yaml.Marshal(data)
if err != nil {
http.Error(output.Context.ResponseWriter, err.Error(), http.StatusInternalServerError)
return err
}
return output.Body(content)
}
// JSONP writes jsonp to response body.
func (output *BeegoOutput) JSONP(data interface{}, hasIndent bool) error {
output.Header("Content-Type", "application/javascript; charset=utf-8")
var content []byte
var err error
if hasIndent {
content, err = json.MarshalIndent(data, "", " ")
} else {
content, err = json.Marshal(data)
}
if err != nil {
http.Error(output.Context.ResponseWriter, err.Error(), http.StatusInternalServerError)
return err
}
callback := output.Context.Input.Query("callback")
if callback == "" {
return errors.New(`"callback" parameter required`)
}
callback = template.JSEscapeString(callback)
callbackContent := bytes.NewBufferString(" if(window." + callback + ")" + callback)
callbackContent.WriteString("(")
callbackContent.Write(content)
callbackContent.WriteString(");\r\n")
return output.Body(callbackContent.Bytes())
}
// XML writes xml string to response body.
func (output *BeegoOutput) XML(data interface{}, hasIndent bool) error {
output.Header("Content-Type", "application/xml; charset=utf-8")
var content []byte
var err error
if hasIndent {
content, err = xml.MarshalIndent(data, "", " ")
} else {
content, err = xml.Marshal(data)
}
if err != nil {
http.Error(output.Context.ResponseWriter, err.Error(), http.StatusInternalServerError)
return err
}
return output.Body(content)
}
// ServeFormatted serve YAML, XML OR JSON, depending on the value of the Accept header
func (output *BeegoOutput) ServeFormatted(data interface{}, hasIndent bool, hasEncode ...bool) {
accept := output.Context.Input.Header("Accept")
switch accept {
case ApplicationYAML:
output.YAML(data)
case ApplicationXML, TextXML:
output.XML(data, hasIndent)
default:
output.JSON(data, hasIndent, len(hasEncode) > 0 && hasEncode[0])
}
}
// Download forces response for download file.
// it prepares the download response header automatically.
func (output *BeegoOutput) Download(file string, filename ...string) {
// check get file error, file not found or other error.
if _, err := os.Stat(file); err != nil {
http.ServeFile(output.Context.ResponseWriter, output.Context.Request, file)
return
}
var fName string
if len(filename) > 0 && filename[0] != "" {
fName = filename[0]
} else {
fName = filepath.Base(file)
}
//https://tools.ietf.org/html/rfc6266#section-4.3
fn := url.PathEscape(fName)
if fName == fn {
fn = "filename=" + fn
} else {
/**
The parameters "filename" and "filename*" differ only in that
"filename*" uses the encoding defined in [RFC5987], allowing the use
of characters not present in the ISO-8859-1 character set
([ISO-8859-1]).
*/
fn = "filename=" + fName + "; filename*=utf-8''" + fn
}
output.Header("Content-Disposition", "attachment; "+fn)
output.Header("Content-Description", "File Transfer")
output.Header("Content-Type", "application/octet-stream")
output.Header("Content-Transfer-Encoding", "binary")
output.Header("Expires", "0")
output.Header("Cache-Control", "must-revalidate")
output.Header("Pragma", "public")
http.ServeFile(output.Context.ResponseWriter, output.Context.Request, file)
}
// ContentType sets the content type from ext string.
// MIME type is given in mime package.
func (output *BeegoOutput) ContentType(ext string) {
if !strings.HasPrefix(ext, ".") {
ext = "." + ext
}
ctype := mime.TypeByExtension(ext)
if ctype != "" {
output.Header("Content-Type", ctype)
}
}
// SetStatus sets response status code.
// It writes response header directly.
func (output *BeegoOutput) SetStatus(status int) {
output.Status = status
}
// IsCachable returns boolean of this request is cached.
// HTTP 304 means cached.
func (output *BeegoOutput) IsCachable() bool {
return output.Status >= 200 && output.Status < 300 || output.Status == 304
}
// IsEmpty returns boolean of this request is empty.
// HTTP 201204 and 304 means empty.
func (output *BeegoOutput) IsEmpty() bool {
return output.Status == 201 || output.Status == 204 || output.Status == 304
}
// IsOk returns boolean of this request runs well.
// HTTP 200 means ok.
func (output *BeegoOutput) IsOk() bool {
return output.Status == 200
}
// IsSuccessful returns boolean of this request runs successfully.
// HTTP 2xx means ok.
func (output *BeegoOutput) IsSuccessful() bool {
return output.Status >= 200 && output.Status < 300
}
// IsRedirect returns boolean of this request is redirection header.
// HTTP 301,302,307 means redirection.
func (output *BeegoOutput) IsRedirect() bool {
return output.Status == 301 || output.Status == 302 || output.Status == 303 || output.Status == 307
}
// IsForbidden returns boolean of this request is forbidden.
// HTTP 403 means forbidden.
func (output *BeegoOutput) IsForbidden() bool {
return output.Status == 403
}
// IsNotFound returns boolean of this request is not found.
// HTTP 404 means not found.
func (output *BeegoOutput) IsNotFound() bool {
return output.Status == 404
}
// IsClientError returns boolean of this request client sends error data.
// HTTP 4xx means client error.
func (output *BeegoOutput) IsClientError() bool {
return output.Status >= 400 && output.Status < 500
}
// IsServerError returns boolean of this server handler errors.
// HTTP 5xx means server internal error.
func (output *BeegoOutput) IsServerError() bool {
return output.Status >= 500 && output.Status < 600
}
func stringsToJSON(str string) string {
var jsons bytes.Buffer
for _, r := range str {
rint := int(r)
if rint < 128 {
jsons.WriteRune(r)
} else {
jsons.WriteString("\\u")
if rint < 0x100 {
jsons.WriteString("00")
} else if rint < 0x1000 {
jsons.WriteString("0")
}
jsons.WriteString(strconv.FormatInt(int64(rint), 16))
}
}
return jsons.String()
}
// Session sets session item value with given key.
func (output *BeegoOutput) Session(name interface{}, value interface{}) {
output.Context.Input.CruSession.Set(name, value)
}

78
context/param/conv.go Normal file
View File

@@ -0,0 +1,78 @@
package param
import (
"fmt"
"reflect"
beecontext "github.com/astaxie/beego/context"
"github.com/astaxie/beego/logs"
)
// ConvertParams converts http method params to values that will be passed to the method controller as arguments
func ConvertParams(methodParams []*MethodParam, methodType reflect.Type, ctx *beecontext.Context) (result []reflect.Value) {
result = make([]reflect.Value, 0, len(methodParams))
for i := 0; i < len(methodParams); i++ {
reflectValue := convertParam(methodParams[i], methodType.In(i), ctx)
result = append(result, reflectValue)
}
return
}
func convertParam(param *MethodParam, paramType reflect.Type, ctx *beecontext.Context) (result reflect.Value) {
paramValue := getParamValue(param, ctx)
if paramValue == "" {
if param.required {
ctx.Abort(400, fmt.Sprintf("Missing parameter %s", param.name))
} else {
paramValue = param.defaultValue
}
}
reflectValue, err := parseValue(param, paramValue, paramType)
if err != nil {
logs.Debug(fmt.Sprintf("Error converting param %s to type %s. Value: %v, Error: %s", param.name, paramType, paramValue, err))
ctx.Abort(400, fmt.Sprintf("Invalid parameter %s. Can not convert %v to type %s", param.name, paramValue, paramType))
}
return reflectValue
}
func getParamValue(param *MethodParam, ctx *beecontext.Context) string {
switch param.in {
case body:
return string(ctx.Input.RequestBody)
case header:
return ctx.Input.Header(param.name)
case path:
return ctx.Input.Query(":" + param.name)
default:
return ctx.Input.Query(param.name)
}
}
func parseValue(param *MethodParam, paramValue string, paramType reflect.Type) (result reflect.Value, err error) {
if paramValue == "" {
return reflect.Zero(paramType), nil
}
parser := getParser(param, paramType)
value, err := parser.parse(paramValue, paramType)
if err != nil {
return result, err
}
return safeConvert(reflect.ValueOf(value), paramType)
}
func safeConvert(value reflect.Value, t reflect.Type) (result reflect.Value, err error) {
defer func() {
if r := recover(); r != nil {
var ok bool
err, ok = r.(error)
if !ok {
err = fmt.Errorf("%v", r)
}
}
}()
result = value.Convert(t)
return
}

View File

@@ -0,0 +1,69 @@
package param
import (
"fmt"
"strings"
)
//MethodParam keeps param information to be auto passed to controller methods
type MethodParam struct {
name string
in paramType
required bool
defaultValue string
}
type paramType byte
const (
param paramType = iota
path
body
header
)
//New creates a new MethodParam with name and specific options
func New(name string, opts ...MethodParamOption) *MethodParam {
return newParam(name, nil, opts)
}
func newParam(name string, parser paramParser, opts []MethodParamOption) (param *MethodParam) {
param = &MethodParam{name: name}
for _, option := range opts {
option(param)
}
return
}
//Make creates an array of MethodParmas or an empty array
func Make(list ...*MethodParam) []*MethodParam {
if len(list) > 0 {
return list
}
return nil
}
func (mp *MethodParam) String() string {
options := []string{}
result := "param.New(\"" + mp.name + "\""
if mp.required {
options = append(options, "param.IsRequired")
}
switch mp.in {
case path:
options = append(options, "param.InPath")
case body:
options = append(options, "param.InBody")
case header:
options = append(options, "param.InHeader")
}
if mp.defaultValue != "" {
options = append(options, fmt.Sprintf(`param.Default("%s")`, mp.defaultValue))
}
if len(options) > 0 {
result += ", "
}
result += strings.Join(options, ", ")
result += ")"
return result
}

37
context/param/options.go Normal file
View File

@@ -0,0 +1,37 @@
package param
import (
"fmt"
)
// MethodParamOption defines a func which apply options on a MethodParam
type MethodParamOption func(*MethodParam)
// IsRequired indicates that this param is required and can not be omitted from the http request
var IsRequired MethodParamOption = func(p *MethodParam) {
p.required = true
}
// InHeader indicates that this param is passed via an http header
var InHeader MethodParamOption = func(p *MethodParam) {
p.in = header
}
// InPath indicates that this param is part of the URL path
var InPath MethodParamOption = func(p *MethodParam) {
p.in = path
}
// InBody indicates that this param is passed as an http request body
var InBody MethodParamOption = func(p *MethodParam) {
p.in = body
}
// Default provides a default value for the http param
func Default(defaultValue interface{}) MethodParamOption {
return func(p *MethodParam) {
if defaultValue != nil {
p.defaultValue = fmt.Sprint(defaultValue)
}
}
}

149
context/param/parsers.go Normal file
View File

@@ -0,0 +1,149 @@
package param
import (
"encoding/json"
"reflect"
"strconv"
"strings"
"time"
)
type paramParser interface {
parse(value string, toType reflect.Type) (interface{}, error)
}
func getParser(param *MethodParam, t reflect.Type) paramParser {
switch t.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return intParser{}
case reflect.Slice:
if t.Elem().Kind() == reflect.Uint8 { //treat []byte as string
return stringParser{}
}
if param.in == body {
return jsonParser{}
}
elemParser := getParser(param, t.Elem())
if elemParser == (jsonParser{}) {
return elemParser
}
return sliceParser(elemParser)
case reflect.Bool:
return boolParser{}
case reflect.String:
return stringParser{}
case reflect.Float32, reflect.Float64:
return floatParser{}
case reflect.Ptr:
elemParser := getParser(param, t.Elem())
if elemParser == (jsonParser{}) {
return elemParser
}
return ptrParser(elemParser)
default:
if t.PkgPath() == "time" && t.Name() == "Time" {
return timeParser{}
}
return jsonParser{}
}
}
type parserFunc func(value string, toType reflect.Type) (interface{}, error)
func (f parserFunc) parse(value string, toType reflect.Type) (interface{}, error) {
return f(value, toType)
}
type boolParser struct {
}
func (p boolParser) parse(value string, toType reflect.Type) (interface{}, error) {
return strconv.ParseBool(value)
}
type stringParser struct {
}
func (p stringParser) parse(value string, toType reflect.Type) (interface{}, error) {
return value, nil
}
type intParser struct {
}
func (p intParser) parse(value string, toType reflect.Type) (interface{}, error) {
return strconv.Atoi(value)
}
type floatParser struct {
}
func (p floatParser) parse(value string, toType reflect.Type) (interface{}, error) {
if toType.Kind() == reflect.Float32 {
res, err := strconv.ParseFloat(value, 32)
if err != nil {
return nil, err
}
return float32(res), nil
}
return strconv.ParseFloat(value, 64)
}
type timeParser struct {
}
func (p timeParser) parse(value string, toType reflect.Type) (result interface{}, err error) {
result, err = time.Parse(time.RFC3339, value)
if err != nil {
result, err = time.Parse("2006-01-02", value)
}
return
}
type jsonParser struct {
}
func (p jsonParser) parse(value string, toType reflect.Type) (interface{}, error) {
pResult := reflect.New(toType)
v := pResult.Interface()
err := json.Unmarshal([]byte(value), v)
if err != nil {
return nil, err
}
return pResult.Elem().Interface(), nil
}
func sliceParser(elemParser paramParser) paramParser {
return parserFunc(func(value string, toType reflect.Type) (interface{}, error) {
values := strings.Split(value, ",")
result := reflect.MakeSlice(toType, 0, len(values))
elemType := toType.Elem()
for _, v := range values {
parsedValue, err := elemParser.parse(v, elemType)
if err != nil {
return nil, err
}
result = reflect.Append(result, reflect.ValueOf(parsedValue))
}
return result.Interface(), nil
})
}
func ptrParser(elemParser paramParser) paramParser {
return parserFunc(func(value string, toType reflect.Type) (interface{}, error) {
parsedValue, err := elemParser.parse(value, toType.Elem())
if err != nil {
return nil, err
}
newValPtr := reflect.New(toType.Elem())
newVal := reflect.Indirect(newValPtr)
convertedVal, err := safeConvert(reflect.ValueOf(parsedValue), toType.Elem())
if err != nil {
return nil, err
}
newVal.Set(convertedVal)
return newValPtr.Interface(), nil
})
}

View File

@@ -0,0 +1,86 @@
package param
import (
"reflect"
"testing"
"time"
)
type testDefinition struct {
strValue string
expectedValue interface{}
expectedParser paramParser
}
func Test_Parsers(t *testing.T) {
//ints
checkParser(testDefinition{"1", 1, intParser{}}, t)
checkParser(testDefinition{"-1", int64(-1), intParser{}}, t)
checkParser(testDefinition{"1", uint64(1), intParser{}}, t)
//floats
checkParser(testDefinition{"1.0", float32(1.0), floatParser{}}, t)
checkParser(testDefinition{"-1.0", float64(-1.0), floatParser{}}, t)
//strings
checkParser(testDefinition{"AB", "AB", stringParser{}}, t)
checkParser(testDefinition{"AB", []byte{65, 66}, stringParser{}}, t)
//bools
checkParser(testDefinition{"true", true, boolParser{}}, t)
checkParser(testDefinition{"0", false, boolParser{}}, t)
//timeParser
checkParser(testDefinition{"2017-05-30T13:54:53Z", time.Date(2017, 5, 30, 13, 54, 53, 0, time.UTC), timeParser{}}, t)
checkParser(testDefinition{"2017-05-30", time.Date(2017, 5, 30, 0, 0, 0, 0, time.UTC), timeParser{}}, t)
//json
checkParser(testDefinition{`{"X": 5, "Y":"Z"}`, struct {
X int
Y string
}{5, "Z"}, jsonParser{}}, t)
//slice in query is parsed as comma delimited
checkParser(testDefinition{`1,2`, []int{1, 2}, sliceParser(intParser{})}, t)
//slice in body is parsed as json
checkParser(testDefinition{`["a","b"]`, []string{"a", "b"}, jsonParser{}}, t, MethodParam{in: body})
//pointers
var someInt = 1
checkParser(testDefinition{`1`, &someInt, ptrParser(intParser{})}, t)
var someStruct = struct{ X int }{5}
checkParser(testDefinition{`{"X": 5}`, &someStruct, jsonParser{}}, t)
}
func checkParser(def testDefinition, t *testing.T, methodParam ...MethodParam) {
toType := reflect.TypeOf(def.expectedValue)
var mp MethodParam
if len(methodParam) == 0 {
mp = MethodParam{}
} else {
mp = methodParam[0]
}
parser := getParser(&mp, toType)
if reflect.TypeOf(parser) != reflect.TypeOf(def.expectedParser) {
t.Errorf("Invalid parser for value %v. Expected: %v, actual: %v", def.strValue, reflect.TypeOf(def.expectedParser).Name(), reflect.TypeOf(parser).Name())
return
}
result, err := parser.parse(def.strValue, toType)
if err != nil {
t.Errorf("Parsing error for value %v. Expected result: %v, error: %v", def.strValue, def.expectedValue, err)
return
}
convResult, err := safeConvert(reflect.ValueOf(result), toType)
if err != nil {
t.Errorf("Conversion error for %v. from value: %v, toType: %v, error: %v", def.strValue, result, toType, err)
return
}
if !reflect.DeepEqual(convResult.Interface(), def.expectedValue) {
t.Errorf("Parsing error for value %v. Expected result: %v, actual: %v", def.strValue, def.expectedValue, result)
}
}

12
context/renderer.go Normal file
View File

@@ -0,0 +1,12 @@
package context
// Renderer defines an http response renderer
type Renderer interface {
Render(ctx *Context)
}
type rendererFunc func(ctx *Context)
func (f rendererFunc) Render(ctx *Context) {
f(ctx)
}

27
context/response.go Normal file
View File

@@ -0,0 +1,27 @@
package context
import (
"strconv"
"net/http"
)
const (
//BadRequest indicates http error 400
BadRequest StatusCode = http.StatusBadRequest
//NotFound indicates http error 404
NotFound StatusCode = http.StatusNotFound
)
// StatusCode sets the http response status code
type StatusCode int
func (s StatusCode) Error() string {
return strconv.Itoa(int(s))
}
// Render sets the http status code
func (s StatusCode) Render(ctx *Context) {
ctx.Output.SetStatus(int(s))
}

View File

@@ -1,45 +1,122 @@
// 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 beego package beego
import ( import (
"bytes" "bytes"
"compress/flate"
"compress/gzip"
"crypto/hmac"
"crypto/sha1"
"encoding/base64"
"encoding/json"
"encoding/xml"
"errors" "errors"
"fmt" "fmt"
"github.com/astaxie/beego/session"
"html/template" "html/template"
"io" "io"
"io/ioutil"
"mime/multipart" "mime/multipart"
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
"path" "reflect"
"strconv" "strconv"
"strings" "strings"
"time"
"github.com/astaxie/beego/context"
"github.com/astaxie/beego/context/param"
"github.com/astaxie/beego/session"
) )
type Controller struct { var (
Ctx *Context // ErrAbort custom error when user stop request handler manually.
Data map[interface{}]interface{} ErrAbort = errors.New("user stop run")
ChildName string // GlobalControllerRouter store comments with controller. pkgpath+controller:comments
TplNames string GlobalControllerRouter = make(map[string][]ControllerComments)
Layout string )
TplExt string
_xsrf_token string // ControllerFilter store the filter for controller
gotofunc string type ControllerFilter struct {
CruSession session.SessionStore Pattern string
XSRFExpire int Pos int
Filter FilterFunc
ReturnOnOutput bool
ResetParams bool
} }
// ControllerFilterComments store the comment for controller level filter
type ControllerFilterComments struct {
Pattern string
Pos int
Filter string // NOQA
ReturnOnOutput bool
ResetParams bool
}
// ControllerImportComments store the import comment for controller needed
type ControllerImportComments struct {
ImportPath string
ImportAlias string
}
// ControllerComments store the comment for the controller method
type ControllerComments struct {
Method string
Router string
Filters []*ControllerFilter
ImportComments []*ControllerImportComments
FilterComments []*ControllerFilterComments
AllowHTTPMethods []string
Params []map[string]string
MethodParams []*param.MethodParam
}
// ControllerCommentsSlice implements the sort interface
type ControllerCommentsSlice []ControllerComments
func (p ControllerCommentsSlice) Len() int { return len(p) }
func (p ControllerCommentsSlice) Less(i, j int) bool { return p[i].Router < p[j].Router }
func (p ControllerCommentsSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
// Controller defines some basic http request handler operations, such as
// http context, template and view, session and xsrf.
type Controller struct {
// context data
Ctx *context.Context
Data map[interface{}]interface{}
// route controller info
controllerName string
actionName string
methodMapping map[string]func() //method:routertree
AppController interface{}
// template data
TplName string
ViewPath string
Layout string
LayoutSections map[string]string // the key is the section name and the value is the template name
TplPrefix string
TplExt string
EnableRender bool
// xsrf data
_xsrfToken string
XSRFExpire int
EnableXSRF bool
// session
CruSession session.Store
}
// ControllerInterface is an interface to uniform all controller handler.
type ControllerInterface interface { type ControllerInterface interface {
Init(ct *Context, cn string) Init(ct *context.Context, controllerName, actionName string, app interface{})
Prepare() Prepare()
Get() Get()
Post() Post()
@@ -48,257 +125,474 @@ type ControllerInterface interface {
Head() Head()
Patch() Patch()
Options() Options()
Trace()
Finish() Finish()
Render() error Render() error
XSRFToken() string
CheckXSRFCookie() bool
HandlerFunc(fn string) bool
URLMapping()
} }
func (c *Controller) Init(ctx *Context, cn string) { // Init generates default values of controller operations.
c.Data = make(map[interface{}]interface{}) func (c *Controller) Init(ctx *context.Context, controllerName, actionName string, app interface{}) {
c.Layout = "" c.Layout = ""
c.TplNames = "" c.TplName = ""
c.ChildName = cn c.controllerName = controllerName
c.actionName = actionName
c.Ctx = ctx c.Ctx = ctx
c.TplExt = "tpl" c.TplExt = "tpl"
c.AppController = app
c.EnableRender = true
c.EnableXSRF = true
c.Data = ctx.Input.Data()
c.methodMapping = make(map[string]func())
} }
func (c *Controller) Prepare() { // Prepare runs after Init before request function execution.
func (c *Controller) Prepare() {}
} // Finish runs after request function execution.
func (c *Controller) Finish() {}
func (c *Controller) Finish() {
}
func (c *Controller) Destructor() {
if c.CruSession != nil {
c.CruSession.SessionRelease()
}
}
// Get adds a request function to handle GET request.
func (c *Controller) Get() { func (c *Controller) Get() {
http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", http.StatusMethodNotAllowed)
} }
// Post adds a request function to handle POST request.
func (c *Controller) Post() { func (c *Controller) Post() {
http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", http.StatusMethodNotAllowed)
} }
// Delete adds a request function to handle DELETE request.
func (c *Controller) Delete() { func (c *Controller) Delete() {
http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", http.StatusMethodNotAllowed)
} }
// Put adds a request function to handle PUT request.
func (c *Controller) Put() { func (c *Controller) Put() {
http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", http.StatusMethodNotAllowed)
} }
// Head adds a request function to handle HEAD request.
func (c *Controller) Head() { func (c *Controller) Head() {
http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", http.StatusMethodNotAllowed)
} }
// Patch adds a request function to handle PATCH request.
func (c *Controller) Patch() { func (c *Controller) Patch() {
http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", http.StatusMethodNotAllowed)
} }
// Options adds a request function to handle OPTIONS request.
func (c *Controller) Options() { func (c *Controller) Options() {
http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", http.StatusMethodNotAllowed)
} }
func (c *Controller) Render() error { // Trace adds a request function to handle Trace request.
rb, err := c.RenderBytes() // this method SHOULD NOT be overridden.
// https://tools.ietf.org/html/rfc7231#section-4.3.8
// The TRACE method requests a remote, application-level loop-back of
// the request message. The final recipient of the request SHOULD
// reflect the message received, excluding some fields described below,
// back to the client as the message body of a 200 (OK) response with a
// Content-Type of "message/http" (Section 8.3.1 of [RFC7230]).
func (c *Controller) Trace() {
ts := func(h http.Header) (hs string) {
for k, v := range h {
hs += fmt.Sprintf("\r\n%s: %s", k, v)
}
return
}
hs := fmt.Sprintf("\r\nTRACE %s %s%s\r\n", c.Ctx.Request.RequestURI, c.Ctx.Request.Proto, ts(c.Ctx.Request.Header))
c.Ctx.Output.Header("Content-Type", "message/http")
c.Ctx.Output.Header("Content-Length", fmt.Sprint(len(hs)))
c.Ctx.Output.Header("Cache-Control", "no-cache, no-store, must-revalidate")
c.Ctx.WriteString(hs)
}
// HandlerFunc call function with the name
func (c *Controller) HandlerFunc(fnname string) bool {
if v, ok := c.methodMapping[fnname]; ok {
v()
return true
}
return false
}
// URLMapping register the internal Controller router.
func (c *Controller) URLMapping() {}
// Mapping the method to function
func (c *Controller) Mapping(method string, fn func()) {
c.methodMapping[method] = fn
}
// Render sends the response with rendered template bytes as text/html type.
func (c *Controller) Render() error {
if !c.EnableRender {
return nil
}
rb, err := c.RenderBytes()
if err != nil { if err != nil {
return err return err
} else {
c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/html; charset=utf-8")
c.writeToWriter(rb)
} }
return nil
if c.Ctx.ResponseWriter.Header().Get("Content-Type") == "" {
c.Ctx.Output.Header("Content-Type", "text/html; charset=utf-8")
}
return c.Ctx.Output.Body(rb)
} }
// RenderString returns the rendered template string. Do not send out response.
func (c *Controller) RenderString() (string, error) { func (c *Controller) RenderString() (string, error) {
b, e := c.RenderBytes() b, e := c.RenderBytes()
return string(b), e return string(b), e
} }
// RenderBytes returns the bytes of rendered template string. Do not send out response.
func (c *Controller) RenderBytes() ([]byte, error) { func (c *Controller) RenderBytes() ([]byte, error) {
//if the controller has set layout, then first get the tplname's content set the content to the layout buf, err := c.renderTemplate()
if c.Layout != "" { // if the controller has set layout, then first get the tplName's content set the content to the layout
if c.TplNames == "" { if err == nil && c.Layout != "" {
c.TplNames = c.ChildName + "/" + strings.ToLower(c.Ctx.Request.Method) + "." + c.TplExt c.Data["LayoutContent"] = template.HTML(buf.String())
}
if RunMode == "dev" {
BuildTemplate(ViewsPath)
}
subdir := path.Dir(c.TplNames)
_, file := path.Split(c.TplNames)
newbytes := bytes.NewBufferString("")
if _, ok := BeeTemplates[subdir]; !ok {
panic("can't find templatefile in the path:" + c.TplNames)
return []byte{}, errors.New("can't find templatefile in the path:" + c.TplNames)
}
BeeTemplates[subdir].ExecuteTemplate(newbytes, file, c.Data)
tplcontent, _ := ioutil.ReadAll(newbytes)
c.Data["LayoutContent"] = template.HTML(string(tplcontent))
subdir = path.Dir(c.Layout)
_, file = path.Split(c.Layout)
ibytes := bytes.NewBufferString("")
err := BeeTemplates[subdir].ExecuteTemplate(ibytes, file, c.Data)
if err != nil {
Trace("template Execute err:", err)
}
icontent, _ := ioutil.ReadAll(ibytes)
return icontent, nil
} else {
if c.TplNames == "" {
c.TplNames = c.ChildName + "/" + strings.ToLower(c.Ctx.Request.Method) + "." + c.TplExt
}
if RunMode == "dev" {
BuildTemplate(ViewsPath)
}
subdir := path.Dir(c.TplNames)
_, file := path.Split(c.TplNames)
ibytes := bytes.NewBufferString("")
if _, ok := BeeTemplates[subdir]; !ok {
panic("can't find templatefile in the path:" + c.TplNames)
return []byte{}, errors.New("can't find templatefile in the path:" + c.TplNames)
}
err := BeeTemplates[subdir].ExecuteTemplate(ibytes, file, c.Data)
if err != nil {
Trace("template Execute err:", err)
}
icontent, _ := ioutil.ReadAll(ibytes)
return icontent, nil
}
return []byte{}, nil
}
func (c *Controller) writeToWriter(rb []byte) { if c.LayoutSections != nil {
output_writer := c.Ctx.ResponseWriter.(io.Writer) for sectionName, sectionTpl := range c.LayoutSections {
if EnableGzip == true && c.Ctx.Request.Header.Get("Accept-Encoding") != "" { if sectionTpl == "" {
splitted := strings.SplitN(c.Ctx.Request.Header.Get("Accept-Encoding"), ",", -1) c.Data[sectionName] = ""
encodings := make([]string, len(splitted)) continue
}
for i, val := range splitted { buf.Reset()
encodings[i] = strings.TrimSpace(val) err = ExecuteViewPathTemplate(&buf, sectionTpl, c.viewPath(), c.Data)
} if err != nil {
for _, val := range encodings { return nil, err
if val == "gzip" { }
c.Ctx.ResponseWriter.Header().Set("Content-Encoding", "gzip") c.Data[sectionName] = template.HTML(buf.String())
output_writer, _ = gzip.NewWriterLevel(c.Ctx.ResponseWriter, gzip.BestSpeed)
break
} else if val == "deflate" {
c.Ctx.ResponseWriter.Header().Set("Content-Encoding", "deflate")
output_writer, _ = flate.NewWriter(c.Ctx.ResponseWriter, flate.BestSpeed)
break
} }
} }
} else {
c.Ctx.SetHeader("Content-Length", strconv.Itoa(len(rb)), true) buf.Reset()
} ExecuteViewPathTemplate(&buf, c.Layout, c.viewPath(), c.Data)
output_writer.Write(rb)
switch output_writer.(type) {
case *gzip.Writer:
output_writer.(*gzip.Writer).Close()
case *flate.Writer:
output_writer.(*flate.Writer).Close()
case io.WriteCloser:
output_writer.(io.WriteCloser).Close()
} }
return buf.Bytes(), err
} }
func (c *Controller) renderTemplate() (bytes.Buffer, error) {
var buf bytes.Buffer
if c.TplName == "" {
c.TplName = strings.ToLower(c.controllerName) + "/" + strings.ToLower(c.actionName) + "." + c.TplExt
}
if c.TplPrefix != "" {
c.TplName = c.TplPrefix + c.TplName
}
if BConfig.RunMode == DEV {
buildFiles := []string{c.TplName}
if c.Layout != "" {
buildFiles = append(buildFiles, c.Layout)
if c.LayoutSections != nil {
for _, sectionTpl := range c.LayoutSections {
if sectionTpl == "" {
continue
}
buildFiles = append(buildFiles, sectionTpl)
}
}
}
BuildTemplate(c.viewPath(), buildFiles...)
}
return buf, ExecuteViewPathTemplate(&buf, c.TplName, c.viewPath(), c.Data)
}
func (c *Controller) viewPath() string {
if c.ViewPath == "" {
return BConfig.WebConfig.ViewsPath
}
return c.ViewPath
}
// Redirect sends the redirection response to url with status code.
func (c *Controller) Redirect(url string, code int) { func (c *Controller) Redirect(url string, code int) {
LogAccess(c.Ctx, nil, code)
c.Ctx.Redirect(code, url) c.Ctx.Redirect(code, url)
} }
// SetData set the data depending on the accepted
func (c *Controller) SetData(data interface{}) {
accept := c.Ctx.Input.Header("Accept")
switch accept {
case context.ApplicationYAML:
c.Data["yaml"] = data
case context.ApplicationXML, context.TextXML:
c.Data["xml"] = data
default:
c.Data["json"] = data
}
}
// Abort stops controller handler and show the error data if code is defined in ErrorMap or code string.
func (c *Controller) Abort(code string) { func (c *Controller) Abort(code string) {
panic(code) status, err := strconv.Atoi(code)
}
func (c *Controller) ServeJson(encoding ...bool) {
content, err := json.MarshalIndent(c.Data["json"], "", " ")
if err != nil { if err != nil {
http.Error(c.Ctx.ResponseWriter, err.Error(), http.StatusInternalServerError) status = 200
return
} }
c.Ctx.ResponseWriter.Header().Set("Content-Type", "application/json;charset=UTF-8") c.CustomAbort(status, code)
if len(encoding) > 0 && encoding[0] == true {
content = []byte(stringsToJson(string(content)))
}
c.writeToWriter(content)
} }
func (c *Controller) ServeJsonp() { // CustomAbort stops controller handler and show the error data, it's similar Aborts, but support status code and body.
content, err := json.MarshalIndent(c.Data["jsonp"], "", " ") func (c *Controller) CustomAbort(status int, body string) {
if err != nil { // first panic from ErrorMaps, it is user defined error functions.
http.Error(c.Ctx.ResponseWriter, err.Error(), http.StatusInternalServerError) if _, ok := ErrorMaps[body]; ok {
return c.Ctx.Output.Status = status
panic(body)
} }
callback := c.Ctx.Request.Form.Get("callback") // last panic user string
if callback == "" { c.Ctx.ResponseWriter.WriteHeader(status)
http.Error(c.Ctx.ResponseWriter, `"callback" parameter required`, http.StatusInternalServerError) c.Ctx.ResponseWriter.Write([]byte(body))
return panic(ErrAbort)
}
callback_content := bytes.NewBufferString(callback)
callback_content.WriteString("(")
callback_content.Write(content)
callback_content.WriteString(");\r\n")
c.Ctx.ResponseWriter.Header().Set("Content-Type", "application/json;charset=UTF-8")
c.writeToWriter(callback_content.Bytes())
} }
func (c *Controller) ServeXml() { // StopRun makes panic of USERSTOPRUN error and go to recover function if defined.
content, err := xml.Marshal(c.Data["xml"]) func (c *Controller) StopRun() {
if err != nil { panic(ErrAbort)
http.Error(c.Ctx.ResponseWriter, err.Error(), http.StatusInternalServerError)
return
}
c.Ctx.ResponseWriter.Header().Set("Content-Type", "application/xml;charset=UTF-8")
c.writeToWriter(content)
} }
// URLFor does another controller handler in this request function.
// it goes to this controller method if endpoint is not clear.
func (c *Controller) URLFor(endpoint string, values ...interface{}) string {
if len(endpoint) == 0 {
return ""
}
if endpoint[0] == '.' {
return URLFor(reflect.Indirect(reflect.ValueOf(c.AppController)).Type().Name()+endpoint, values...)
}
return URLFor(endpoint, values...)
}
// ServeJSON sends a json response with encoding charset.
func (c *Controller) ServeJSON(encoding ...bool) {
var (
hasIndent = BConfig.RunMode != PROD
hasEncoding = len(encoding) > 0 && encoding[0]
)
c.Ctx.Output.JSON(c.Data["json"], hasIndent, hasEncoding)
}
// ServeJSONP sends a jsonp response.
func (c *Controller) ServeJSONP() {
hasIndent := BConfig.RunMode != PROD
c.Ctx.Output.JSONP(c.Data["jsonp"], hasIndent)
}
// ServeXML sends xml response.
func (c *Controller) ServeXML() {
hasIndent := BConfig.RunMode != PROD
c.Ctx.Output.XML(c.Data["xml"], hasIndent)
}
// ServeYAML sends yaml response.
func (c *Controller) ServeYAML() {
c.Ctx.Output.YAML(c.Data["yaml"])
}
// ServeFormatted serve YAML, XML OR JSON, depending on the value of the Accept header
func (c *Controller) ServeFormatted(encoding ...bool) {
hasIndent := BConfig.RunMode != PROD
hasEncoding := len(encoding) > 0 && encoding[0]
c.Ctx.Output.ServeFormatted(c.Data, hasIndent, hasEncoding)
}
// Input returns the input data map from POST or PUT request body and query string.
func (c *Controller) Input() url.Values { func (c *Controller) Input() url.Values {
ct := c.Ctx.Request.Header.Get("Content-Type") if c.Ctx.Request.Form == nil {
if strings.Contains(ct, "multipart/form-data") {
c.Ctx.Request.ParseMultipartForm(MaxMemory) //64MB
} else {
c.Ctx.Request.ParseForm() c.Ctx.Request.ParseForm()
} }
return c.Ctx.Request.Form return c.Ctx.Request.Form
} }
// ParseForm maps input data map to obj struct.
func (c *Controller) ParseForm(obj interface{}) error { func (c *Controller) ParseForm(obj interface{}) error {
return ParseForm(c.Input(), obj) return ParseForm(c.Input(), obj)
} }
func (c *Controller) GetString(key string) string { // GetString returns the input value by key string or the default value while it's present and input is blank
return c.Input().Get(key) func (c *Controller) GetString(key string, def ...string) string {
if v := c.Ctx.Input.Query(key); v != "" {
return v
}
if len(def) > 0 {
return def[0]
}
return ""
} }
func (c *Controller) GetStrings(key string) []string { // GetStrings returns the input string slice by key string or the default value while it's present and input is blank
r := c.Ctx.Request // it's designed for multi-value input field such as checkbox(input[type=checkbox]), multi-selection.
if r.Form == nil { func (c *Controller) GetStrings(key string, def ...[]string) []string {
return []string{} var defv []string
if len(def) > 0 {
defv = def[0]
} }
vs := r.Form[key]
if len(vs) > 0 { if f := c.Input(); f == nil {
return defv
} else if vs := f[key]; len(vs) > 0 {
return vs return vs
} }
return []string{}
return defv
} }
func (c *Controller) GetInt(key string) (int64, error) { // GetInt returns input as an int or the default value while it's present and input is blank
return strconv.ParseInt(c.Input().Get(key), 10, 64) func (c *Controller) GetInt(key string, def ...int) (int, error) {
strv := c.Ctx.Input.Query(key)
if len(strv) == 0 && len(def) > 0 {
return def[0], nil
}
return strconv.Atoi(strv)
} }
func (c *Controller) GetBool(key string) (bool, error) { // GetInt8 return input as an int8 or the default value while it's present and input is blank
return strconv.ParseBool(c.Input().Get(key)) func (c *Controller) GetInt8(key string, def ...int8) (int8, error) {
strv := c.Ctx.Input.Query(key)
if len(strv) == 0 && len(def) > 0 {
return def[0], nil
}
i64, err := strconv.ParseInt(strv, 10, 8)
return int8(i64), err
} }
// GetUint8 return input as an uint8 or the default value while it's present and input is blank
func (c *Controller) GetUint8(key string, def ...uint8) (uint8, error) {
strv := c.Ctx.Input.Query(key)
if len(strv) == 0 && len(def) > 0 {
return def[0], nil
}
u64, err := strconv.ParseUint(strv, 10, 8)
return uint8(u64), err
}
// GetInt16 returns input as an int16 or the default value while it's present and input is blank
func (c *Controller) GetInt16(key string, def ...int16) (int16, error) {
strv := c.Ctx.Input.Query(key)
if len(strv) == 0 && len(def) > 0 {
return def[0], nil
}
i64, err := strconv.ParseInt(strv, 10, 16)
return int16(i64), err
}
// GetUint16 returns input as an uint16 or the default value while it's present and input is blank
func (c *Controller) GetUint16(key string, def ...uint16) (uint16, error) {
strv := c.Ctx.Input.Query(key)
if len(strv) == 0 && len(def) > 0 {
return def[0], nil
}
u64, err := strconv.ParseUint(strv, 10, 16)
return uint16(u64), err
}
// GetInt32 returns input as an int32 or the default value while it's present and input is blank
func (c *Controller) GetInt32(key string, def ...int32) (int32, error) {
strv := c.Ctx.Input.Query(key)
if len(strv) == 0 && len(def) > 0 {
return def[0], nil
}
i64, err := strconv.ParseInt(strv, 10, 32)
return int32(i64), err
}
// GetUint32 returns input as an uint32 or the default value while it's present and input is blank
func (c *Controller) GetUint32(key string, def ...uint32) (uint32, error) {
strv := c.Ctx.Input.Query(key)
if len(strv) == 0 && len(def) > 0 {
return def[0], nil
}
u64, err := strconv.ParseUint(strv, 10, 32)
return uint32(u64), err
}
// GetInt64 returns input value as int64 or the default value while it's present and input is blank.
func (c *Controller) GetInt64(key string, def ...int64) (int64, error) {
strv := c.Ctx.Input.Query(key)
if len(strv) == 0 && len(def) > 0 {
return def[0], nil
}
return strconv.ParseInt(strv, 10, 64)
}
// GetUint64 returns input value as uint64 or the default value while it's present and input is blank.
func (c *Controller) GetUint64(key string, def ...uint64) (uint64, error) {
strv := c.Ctx.Input.Query(key)
if len(strv) == 0 && len(def) > 0 {
return def[0], nil
}
return strconv.ParseUint(strv, 10, 64)
}
// GetBool returns input value as bool or the default value while it's present and input is blank.
func (c *Controller) GetBool(key string, def ...bool) (bool, error) {
strv := c.Ctx.Input.Query(key)
if len(strv) == 0 && len(def) > 0 {
return def[0], nil
}
return strconv.ParseBool(strv)
}
// GetFloat returns input value as float64 or the default value while it's present and input is blank.
func (c *Controller) GetFloat(key string, def ...float64) (float64, error) {
strv := c.Ctx.Input.Query(key)
if len(strv) == 0 && len(def) > 0 {
return def[0], nil
}
return strconv.ParseFloat(strv, 64)
}
// GetFile returns the file data in file upload field named as key.
// it returns the first one of multi-uploaded files.
func (c *Controller) GetFile(key string) (multipart.File, *multipart.FileHeader, error) { func (c *Controller) GetFile(key string) (multipart.File, *multipart.FileHeader, error) {
return c.Ctx.Request.FormFile(key) return c.Ctx.Request.FormFile(key)
} }
// GetFiles return multi-upload files
// files, err:=c.GetFiles("myfiles")
// if err != nil {
// http.Error(w, err.Error(), http.StatusNoContent)
// return
// }
// for i, _ := range files {
// //for each fileheader, get a handle to the actual file
// file, err := files[i].Open()
// defer file.Close()
// if err != nil {
// http.Error(w, err.Error(), http.StatusInternalServerError)
// return
// }
// //create destination file making sure the path is writeable.
// dst, err := os.Create("upload/" + files[i].Filename)
// defer dst.Close()
// if err != nil {
// http.Error(w, err.Error(), http.StatusInternalServerError)
// return
// }
// //copy the uploaded file to the destination file
// if _, err := io.Copy(dst, file); err != nil {
// http.Error(w, err.Error(), http.StatusInternalServerError)
// return
// }
// }
func (c *Controller) GetFiles(key string) ([]*multipart.FileHeader, error) {
if files, ok := c.Ctx.Request.MultipartForm.File[key]; ok {
return files, nil
}
return nil, http.ErrMissingFile
}
// SaveToFile saves uploaded file to new path.
// it only operates the first one of mutil-upload form file field.
func (c *Controller) SaveToFile(fromfile, tofile string) error { func (c *Controller) SaveToFile(fromfile, tofile string) error {
file, _, err := c.Ctx.Request.FormFile(fromfile) file, _, err := c.Ctx.Request.FormFile(fromfile)
if err != nil { if err != nil {
@@ -314,13 +608,15 @@ func (c *Controller) SaveToFile(fromfile, tofile string) error {
return nil return nil
} }
func (c *Controller) StartSession() session.SessionStore { // StartSession starts session and load old session data info this controller.
func (c *Controller) StartSession() session.Store {
if c.CruSession == nil { if c.CruSession == nil {
c.CruSession = GlobalSessions.SessionStart(c.Ctx.ResponseWriter, c.Ctx.Request) c.CruSession = c.Ctx.Input.CruSession
} }
return c.CruSession return c.CruSession
} }
// SetSession puts value into session.
func (c *Controller) SetSession(name interface{}, value interface{}) { func (c *Controller) SetSession(name interface{}, value interface{}) {
if c.CruSession == nil { if c.CruSession == nil {
c.StartSession() c.StartSession()
@@ -328,6 +624,7 @@ func (c *Controller) SetSession(name interface{}, value interface{}) {
c.CruSession.Set(name, value) c.CruSession.Set(name, value)
} }
// GetSession gets value from session.
func (c *Controller) GetSession(name interface{}) interface{} { func (c *Controller) GetSession(name interface{}) interface{} {
if c.CruSession == nil { if c.CruSession == nil {
c.StartSession() c.StartSession()
@@ -335,6 +632,7 @@ func (c *Controller) GetSession(name interface{}) interface{} {
return c.CruSession.Get(name) return c.CruSession.Get(name)
} }
// DelSession removes value from session.
func (c *Controller) DelSession(name interface{}) { func (c *Controller) DelSession(name interface{}) {
if c.CruSession == nil { if c.CruSession == nil {
c.StartSession() c.StartSession()
@@ -342,61 +640,68 @@ func (c *Controller) DelSession(name interface{}) {
c.CruSession.Delete(name) c.CruSession.Delete(name)
} }
// SessionRegenerateID regenerates session id for this session.
// the session data have no changes.
func (c *Controller) SessionRegenerateID() (err error) {
if c.CruSession != nil {
c.CruSession.SessionRelease(c.Ctx.ResponseWriter)
}
c.CruSession, err = GlobalSessions.SessionRegenerateID(c.Ctx.ResponseWriter, c.Ctx.Request)
c.Ctx.Input.CruSession = c.CruSession
return
}
// DestroySession cleans session data and session cookie.
func (c *Controller) DestroySession() { func (c *Controller) DestroySession() {
c.Ctx.Input.CruSession.Flush()
c.Ctx.Input.CruSession = nil
GlobalSessions.SessionDestroy(c.Ctx.ResponseWriter, c.Ctx.Request) GlobalSessions.SessionDestroy(c.Ctx.ResponseWriter, c.Ctx.Request)
} }
// IsAjax returns this request is ajax or not.
func (c *Controller) IsAjax() bool { func (c *Controller) IsAjax() bool {
return (c.Ctx.Request.Header.Get("HTTP_X_REQUESTED_WITH") == "XMLHttpRequest") return c.Ctx.Input.IsAjax()
} }
func (c *Controller) XsrfToken() string { // GetSecureCookie returns decoded cookie value from encoded browser cookie values.
if c._xsrf_token == "" { func (c *Controller) GetSecureCookie(Secret, key string) (string, bool) {
token := c.Ctx.GetCookie("_xsrf") return c.Ctx.GetSecureCookie(Secret, key)
if token == "" { }
h := hmac.New(sha1.New, []byte(XSRFKEY))
fmt.Fprintf(h, "%s:%d", c.Ctx.Request.RemoteAddr, time.Now().UnixNano()) // SetSecureCookie puts value into cookie after encoded the value.
tok := fmt.Sprintf("%s:%d", h.Sum(nil), time.Now().UnixNano()) func (c *Controller) SetSecureCookie(Secret, name, value string, others ...interface{}) {
token = base64.URLEncoding.EncodeToString([]byte(tok)) c.Ctx.SetSecureCookie(Secret, name, value, others...)
expire := 0 }
if c.XSRFExpire > 0 {
expire = c.XSRFExpire // XSRFToken creates a CSRF token string and returns.
} else { func (c *Controller) XSRFToken() string {
expire = XSRFExpire if c._xsrfToken == "" {
} expire := int64(BConfig.WebConfig.XSRFExpire)
c.Ctx.SetCookie("_xsrf", token, expire) if c.XSRFExpire > 0 {
expire = int64(c.XSRFExpire)
} }
c._xsrf_token = token c._xsrfToken = c.Ctx.XSRFToken(BConfig.WebConfig.XSRFKey, expire)
} }
return c._xsrf_token return c._xsrfToken
} }
func (c *Controller) CheckXsrfCookie() bool { // CheckXSRFCookie checks xsrf token in this request is valid or not.
token := c.GetString("_xsrf") // the token can provided in request header "X-Xsrftoken" and "X-CsrfToken"
if token == "" { // or in form field value named as "_xsrf".
token = c.Ctx.Request.Header.Get("X-Xsrftoken") func (c *Controller) CheckXSRFCookie() bool {
if !c.EnableXSRF {
return true
} }
if token == "" { return c.Ctx.CheckXSRFCookie()
token = c.Ctx.Request.Header.Get("X-Csrftoken")
}
if token == "" {
c.Ctx.Abort(403, "'_xsrf' argument missing from POST")
}
if c._xsrf_token != token {
c.Ctx.Abort(403, "XSRF cookie does not match POST argument")
}
return true
} }
func (c *Controller) XsrfFormHtml() string { // XSRFFormHTML writes an input field contains xsrf token value.
return "<input type=\"hidden\" name=\"_xsrf\" value=\"" + func (c *Controller) XSRFFormHTML() string {
c._xsrf_token + "\"/>" return `<input type="hidden" name="_xsrf" value="` +
c.XSRFToken() + `" />`
} }
func (c *Controller) GoToFunc(funcname string) { // GetControllerAndAction gets the executing controller name and action name.
if funcname[0] < 65 || funcname[0] > 90 { func (c *Controller) GetControllerAndAction() (string, string) {
panic("GoToFunc should exported function") return c.controllerName, c.actionName
}
c.gotofunc = funcname
} }

182
controller_test.go Normal file
View File

@@ -0,0 +1,182 @@
// 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 beego
import (
"math"
"strconv"
"testing"
"os"
"path/filepath"
"github.com/astaxie/beego/context"
)
func TestGetInt(t *testing.T) {
i := context.NewInput()
i.SetParam("age", "40")
ctx := &context.Context{Input: i}
ctrlr := Controller{Ctx: ctx}
val, _ := ctrlr.GetInt("age")
if val != 40 {
t.Errorf("TestGetInt expect 40,get %T,%v", val, val)
}
}
func TestGetInt8(t *testing.T) {
i := context.NewInput()
i.SetParam("age", "40")
ctx := &context.Context{Input: i}
ctrlr := Controller{Ctx: ctx}
val, _ := ctrlr.GetInt8("age")
if val != 40 {
t.Errorf("TestGetInt8 expect 40,get %T,%v", val, val)
}
//Output: int8
}
func TestGetInt16(t *testing.T) {
i := context.NewInput()
i.SetParam("age", "40")
ctx := &context.Context{Input: i}
ctrlr := Controller{Ctx: ctx}
val, _ := ctrlr.GetInt16("age")
if val != 40 {
t.Errorf("TestGetInt16 expect 40,get %T,%v", val, val)
}
}
func TestGetInt32(t *testing.T) {
i := context.NewInput()
i.SetParam("age", "40")
ctx := &context.Context{Input: i}
ctrlr := Controller{Ctx: ctx}
val, _ := ctrlr.GetInt32("age")
if val != 40 {
t.Errorf("TestGetInt32 expect 40,get %T,%v", val, val)
}
}
func TestGetInt64(t *testing.T) {
i := context.NewInput()
i.SetParam("age", "40")
ctx := &context.Context{Input: i}
ctrlr := Controller{Ctx: ctx}
val, _ := ctrlr.GetInt64("age")
if val != 40 {
t.Errorf("TestGeetInt64 expect 40,get %T,%v", val, val)
}
}
func TestGetUint8(t *testing.T) {
i := context.NewInput()
i.SetParam("age", strconv.FormatUint(math.MaxUint8, 10))
ctx := &context.Context{Input: i}
ctrlr := Controller{Ctx: ctx}
val, _ := ctrlr.GetUint8("age")
if val != math.MaxUint8 {
t.Errorf("TestGetUint8 expect %v,get %T,%v", math.MaxUint8, val, val)
}
}
func TestGetUint16(t *testing.T) {
i := context.NewInput()
i.SetParam("age", strconv.FormatUint(math.MaxUint16, 10))
ctx := &context.Context{Input: i}
ctrlr := Controller{Ctx: ctx}
val, _ := ctrlr.GetUint16("age")
if val != math.MaxUint16 {
t.Errorf("TestGetUint16 expect %v,get %T,%v", math.MaxUint16, val, val)
}
}
func TestGetUint32(t *testing.T) {
i := context.NewInput()
i.SetParam("age", strconv.FormatUint(math.MaxUint32, 10))
ctx := &context.Context{Input: i}
ctrlr := Controller{Ctx: ctx}
val, _ := ctrlr.GetUint32("age")
if val != math.MaxUint32 {
t.Errorf("TestGetUint32 expect %v,get %T,%v", math.MaxUint32, val, val)
}
}
func TestGetUint64(t *testing.T) {
i := context.NewInput()
i.SetParam("age", strconv.FormatUint(math.MaxUint64, 10))
ctx := &context.Context{Input: i}
ctrlr := Controller{Ctx: ctx}
val, _ := ctrlr.GetUint64("age")
if val != math.MaxUint64 {
t.Errorf("TestGetUint64 expect %v,get %T,%v", uint64(math.MaxUint64), val, val)
}
}
func TestAdditionalViewPaths(t *testing.T) {
dir1 := tmpDir("TestAdditionalViewPaths1")
dir2 := tmpDir("TestAdditionalViewPaths2")
defer os.RemoveAll(dir1)
defer os.RemoveAll(dir2)
dir1file := "file1.tpl"
dir2file := "file2.tpl"
genFile := func(dir string, name string, content string) {
os.MkdirAll(filepath.Dir(filepath.Join(dir, name)), 0777)
if f, err := os.Create(filepath.Join(dir, name)); err != nil {
t.Fatal(err)
} else {
defer f.Close()
f.WriteString(content)
f.Close()
}
}
genFile(dir1, dir1file, `<div>{{.Content}}</div>`)
genFile(dir2, dir2file, `<html>{{.Content}}</html>`)
AddViewPath(dir1)
AddViewPath(dir2)
ctrl := Controller{
TplName: "file1.tpl",
ViewPath: dir1,
}
ctrl.Data = map[interface{}]interface{}{
"Content": "value2",
}
if result, err := ctrl.RenderString(); err != nil {
t.Fatal(err)
} else {
if result != "<div>value2</div>" {
t.Fatalf("TestAdditionalViewPaths expect %s got %s", "<div>value2</div>", result)
}
}
func() {
ctrl.TplName = "file2.tpl"
defer func() {
if r := recover(); r == nil {
t.Fatal("TestAdditionalViewPaths expected error")
}
}()
ctrl.RenderString()
}()
ctrl.TplName = "file2.tpl"
ctrl.ViewPath = dir2
ctrl.RenderString()
}

17
doc.go Normal file
View File

@@ -0,0 +1,17 @@
/*
Package beego provide a MVC framework
beego: an open-source, high-performance, modular, full-stack web framework
It is used for rapid development of RESTful APIs, web apps and backend services in Go.
beego is inspired by Tornado, Sinatra and Flask with the added benefit of some Go-specific features such as interfaces and struct embedding.
package main
import "github.com/astaxie/beego"
func main() {
beego.Run()
}
more information: http://beego.me
*/
package beego

View File

@@ -1,102 +0,0 @@
# Getting start with API application development
Go is very good for developing API applications which I think is the biggest strength compare to other dynamic languages. Beego provides powerful and quick setup tool for developing API applications, which gives you more focus on business logic.
## Quick setup
bee can setup a API application very quick by executing commands under any `$GOPATH/src`.
`bee api beeapi`
## Application directory structure
```
├── conf
│ └── app.conf
├── controllers
│ └── default.go
├── models
│ └── object.go
└── main.go
```
## Source code explanation
- app.conf has following configuration options for your API applications:
- autorender = false // Disable auto-render since API applications don't need.
- copyrequestbody = true // RESTFul applications sends raw body instead of form, so we need to read body specifically.
- main.go is for registering routers of RESTFul.
beego.RESTRouter("/object", &controllers.ObejctController{})
Match rules as follows:
<table>
<tr>
<th>URL</th> <th>HTTP Verb</th> <th>Functionality</th>
</tr>
<tr>
<td>/object</td> <td>POST</td> <td>Creating Objects</td>
</tr>
<tr>
<td>/object/objectId</td> <td>GET</td> <td>Retrieving Objects</td>
</tr>
<tr>
<td>/object/objectId</td> <td>PUT</td> <td>Updating Objects</td>
</tr>
<tr>
<td>/object</td> <td>GET</td> <td>Queries</td>
</tr>
<tr>
<td>/object/objectId</td> <td>DELETE</td> <td>Deleting Objects</td>
</tr>
</table>
- ObejctController implemented corresponding methods:
type ObejctController struct {
beego.Controller
}
func (this *ObejctController) Post(){
}
func (this *ObejctController) Get(){
}
func (this *ObejctController) Put(){
}
func (this *ObejctController) Delete(){
}
- models implemented corresponding object operation for adding, deleting, updating and getting.
## Test
- Add a new object:
curl -X POST -d '{"Score":1337,"PlayerName":"Sean Plott"}' http://127.0.0.1:8080/object
Returns a corresponding objectID:astaxie1373349756660423900
- Query a object:
`curl -X GET http://127.0.0.1:8080/object/astaxie1373349756660423900`
- Query all objects:
`curl -X GET http://127.0.0.1:8080/object`
- Update a object:
`curl -X PUT -d '{"Score":10000}'http://127.0.0.1:8080/object/astaxie1373349756660423900`
- Delete a object:
`curl -X DELETE http://127.0.0.1:8080/object/astaxie1373349756660423900`

View File

@@ -1,46 +0,0 @@
## What is hot update?
If you have used nginx, you may know that nginx supports hot update, which means you can update your nginx without stopping and restarting it. It serves old connections with old version, and accepts new connections with new version. Notice that hot compiling is different from hot update, where hot compiling is monitoring your source files and recompile them when the content changes, it requires stop and restart your applications, `bee start` is a tool for hot compiling.
## Is hot update necessary?
Some people says that hot update is not as useful as its cool name. In my opinion, this is absolutely necessary because zero-down server is our goal for our services. Even though sometimes some errors or hardware problems may occur, but it belongs to design of high availability, don't mix them up. Service update is a known issue, so we need to fix this problem.
## How Beego support hot update?
The basic principle of hot update: main process fork a process, and child process execute corresponding programs. So what happens? We know that after forked a process, main process will have all handles, data and stack, etc, but all handles are saved in `CloseOnExec`, so all copied handles will be closed when you execute it unless you clarify this, and we need child process to reuse the handle of `net.Listener`. Once a process calls exec functions, it is "dead", system replaces it with new code. The only thing it left is the process ID, which is the same number but it is a new program after executed.
Therefore, the first thing we need to do is that let child process fork main process and through `os.StartProcess` to append files that contains handle that is going to be inherited.
The second step is that we hope child process can start listening from same handle, so we can use `net.FileListener` to achieve this goal. Here we also need FD of this file, so we need to add a environment variable to set this FD before we start child process.
The final step is that we want to serve old connections with old version of application, and serve new connections with new version. So how can we know if there is any old connections? To do this, we have to record all connections, then we are able to know. Another problem is that how to let new application to accept connection? Because two versions of applications are listening to same port, they get connection request randomly, so we just close old accept function, and it will get error in `l.Accept`.
Above are three problems that we need to solve, you can see my code logic for specific implementation.
## Show time
1. Write code in your Get method:
func (this *MainController) Get() {
a, _ := this.GetInt("sleep")
time.Sleep(time.Duration(a) * time.Second)
this.Ctx.WriteString("ospid:" + strconv.Itoa(os.Getpid()))
}
2. Open two terminals:
One execute: ` ps -ef|grep <application name>`
Another one execute `curl "http://127.0.0.1:8080/?sleep=20"`
3. Hot update
`kill -HUP <PID>`
4. Open a terminal to request connection: `curl "http://127.0.0.1:8080/?sleep=0"`
As you will see, the first request will wait for 20 seconds, but it's served by old process; after hot update, the first request will print old process ID, but the second request will print new process ID.

View File

@@ -1,26 +0,0 @@
# Installation
Beego is a simple web framework, but it uses many third-party packages, so you have to install all dependency packages also.
- Before anything you do, you have to check that you installed Go in your computer, see more detail about Go installation in my book: [Chapter 1](https://github.com/Unknwon/build-web-application-with-golang_EN/blob/master/eBook/01.1.md)
- Use `go get ` to install Beego:
go get github.com/astaxie/beego
- Install bee tools for fast-develop Beego applications:
go get github.com/astaxie/bee
Good job, you're ready to Beego with powerful bee tools!
![](images/bee.png)
Beego has following dependency packages:
- Session module: [github.com/astaxie/beego/session](https://github.com/astaxie/beego/session)
- To support redis engine: [github.com/garyburd/redigo/redis](https://github.com/garyburd/redigo/redis)
- To support mysql engine: [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql)
- To support markdown as template function: [github.com/russross/blackfriday](https://github.com/russross/blackfriday)
- [Introduction](README.md)
- [Quick start](Quickstart.md)

File diff suppressed because it is too large Load Diff

View File

@@ -1,60 +0,0 @@
# Beego
Beego is a lightweight, open source, non-blocking and scalable web framework for the Go programming language. It's like tornado in Python. This web framework has already been using for building web server and tools in SNDA's CDN system. Documentation and downloads available at [http://astaxie.github.com/beego](http://astaxie.github.com/beego)
It has following main features:
- Supports MVC model, you only need to focus on logic and implementation methods.
- Supports websocket, use customized handlers to integrate sockjs.
- Supports customized router rules, including regex and semanteme.
- Session integration, supports memory, file, redis, mysql, etc.
- Automated parsing user form, you can get data very easy.
- Log level system, easy to record debugging and deployment logs.
- Use configuration file (.ini) to customized your system.
- Use built-in templates in Go, and it provides much more useful functions which are commonly used in web development.
The working principles of Beego as follows:
![](images/beego.png)
Beego is licensed under the Apache Licence, Version 2.0
(http://www.apache.org/licenses/LICENSE-2.0.html).
# Simple example
The following example prints string "Hello world" to your browser, it shows how easy to build a web application with Beego.
package main
import (
"github.com/astaxie/beego"
)
type MainController struct {
beego.Controller
}
func (this *MainController) Get() {
this.Ctx.WriteString("hello world")
}
func main() {
beego.Router("/", &MainController{})
beego.Run()
}
# Handbook
- [Purposes](Why.md)
- [Installation](Install.md)
- [Quick start](Quickstart.md)
- [Step by step](Tutorial.md)
- [Real world usage](Application.md)
- [Hot update](HotUpdate.md)
# Documentation
[Go Walker](http://gowalker.org/github.com/astaxie/beego)

View File

@@ -1,36 +0,0 @@
## Supervisord
[Supervisord](http://supervisord.org/) will make sure your web app is always up.
1. Installation
wget http://pypi.python.org/packages/2.7/s/setuptools/setuptools-0.6c11-py2.7.egg
sh setuptools-0.6c11-py2.7.egg
easy_install supervisor
echo_supervisord_conf >/etc/supervisord.conf
mkdir /etc/supervisord.conf.d
2. Configure `/etc/supervisord.conf`
[include]
files = /etc/supervisord.conf.d/*.conf
3. Add new application
cd /etc/supervisord.conf.d
vim beepkg.conf
Configuration file:
[program:beepkg]
directory = /opt/app/beepkg
command = /opt/app/beepkg/beepkg
autostart = true
startsecs = 5
user = root
redirect_stderr = true
stdout_logfile = /var/log/supervisord/beepkg.log

View File

@@ -1,19 +0,0 @@
# 一步一步跟我写博客
## 创建项目
## 数据库结构设计
## 控制器设计
## 模板设计
## 用户登陆退出
## 数据库操作

View File

@@ -1,20 +0,0 @@
# Design purposes and ideas
People may ask me why I want to build a new web framework rather than use other good ones. I know there are many excellent web frameworks on the internet and almost all of them are open source, and I have my reasons to do this.
Remember when I was writing the book about how to build web applications with Go, I just wanted to tell people what were my valuable experiences with Go in web development, especially I have been working with PHP and Python for almost ten years. At first, I didn't realize that a small web framework can give great help to web developers when they are learning to build web applications in a new programming language, and it also helps people more by studying its source code. Finally, I decided to write a open source web framework called Beego as supporting materiel for my book.
I used to use CI in PHP and tornado in Python, there are both lightweight, so they has following advantages:
1. Save time for handling general problems, I only need to care about logic part.
2. Learn more about languages by studying their source code, it's not hard to read and understand them because they are both lightweight frameworks.
3. It's quite easy to make secondary development of these frameworks for specific purposes.
Those reasons are my original intention of implementing Beego, and used two chapters in my book to introduce and design this lightweight web framework in Go.
Then I started to design logic execution of Beego. Because Go and Python have somewhat similar, I referenced some ideas from tornado to design Beego. As you can see, there is no different between Beego and tornado in RESTful processing; they both use GET, POST or some other methods to implement RESTful. I took some ideas from [https://github.com/drone/routes](https://github.com/drone/routes) at the beginning of designing routes. It uses regular expression in route rules processing, which is an excellent idea that to make up for the default Mux router function in Go. However, I have to design my own interface in order to implement RESTful and use inherited ideas in Python.
The controller is the most important part of whole MVC model, and Beego uses the interface and ideas I said above for the controller. Although I haven't decided to have to design the model part, everyone is welcome to implement data management by referencing Beedb, my another open source project. I simply adopt Go built-in template engine for the view part, but add more commonly used functions as template functions. This is how a simple web framework looks like, but I'll keep working on form processing, session handling, log recording, configuration, automated operation, etc, to build a simple but complete web framework.
- [Introduction](README.md)
- [Installation](Install.md)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

View File

@@ -1,106 +0,0 @@
# API应用开发入门
Go是非常适合用来开发API应用的而且我认为也是Go相对于其他动态语言的最大优势应用。beego在开发API应用方面提供了非常强大和快速的工具方便用户快速的建立API应用原型专心业务逻辑就行了。
## 快速建立原型
bee快速开发工具提供了一个API应用建立的工具在gopath/src下的任意目录执行如下命令就可以快速的建立一个API应用
`bee api beeapi`
## 应用的目录结构
应用的目录结构如下所示:
```
├── conf
│ └── app.conf
├── controllers
│ └── default.go
├── models
│ └── object.go
└── main.go
```
## 源码解析
- app.conf里面主要针对API的配置如下
autorender = false //API应用不需要模板渲染所以关闭自动渲染
copyrequestbody = true //RESTFul应用发送信息的时候是raw body而不是普通的form表单所以需要额外的读取body信息
- main.go文件主要针对RESTFul的路由注册
`beego.RESTRouter("/object", &controllers.ObejctController{})`
这个路由可以匹配如下的规则
<table>
<tr>
<th>URL</th> <th>HTTP Verb</th> <th>Functionality</th>
</tr>
<tr>
<td>/object</td> <td>POST</td> <td>Creating Objects</td>
</tr>
<tr>
<td>/object/objectId</td> <td>GET</td> <td>Retrieving Objects</td>
</tr>
<tr>
<td>/object/objectId</td> <td>PUT</td> <td>Updating Objects</td>
</tr>
<tr>
<td>/object</td> <td>GET</td> <td>Queries</td>
</tr>
<tr>
<td>/object/objectId</td> <td>DELETE</td> <td>Deleting Objects</td>
</tr>
</table>
- ObejctController实现了对应的方法
```
type ObejctController struct {
beego.Controller
}
func (this *ObejctController) Post(){
}
func (this *ObejctController) Get(){
}
func (this *ObejctController) Put(){
}
func (this *ObejctController) Delete(){
}
```
- models里面实现了对应操作对象的增删改取等操作
## 测试
- 添加一个对象:
`curl -X POST -d '{"Score":1337,"PlayerName":"Sean Plott"}' http://127.0.0.1:8080/object`
返回一个相应的objectID:astaxie1373349756660423900
- 查询一个对象
`curl -X GET http://127.0.0.1:8080/object/astaxie1373349756660423900`
- 查询全部的对象
`curl -X GET http://127.0.0.1:8080/object`
- 更新一个对象
`curl -X PUT -d '{"Score":10000}'http://127.0.0.1:8080/object/astaxie1373349756660423900`
- 删除一个对象
`curl -X DELETE http://127.0.0.1:8080/object/astaxie1373349756660423900`

View File

@@ -1,23 +0,0 @@
# beego案例
- 短域名服务
使用beego开发了一个类似bitly的短域名服务提供盛大内部项目使用目前一台机器32G内存、8核、centos64
redis数据库数据量在1500w多点从2012年8月份运行至今没有出现过问题
- 政府合作项目
使用beego提供系统级别服务监控继承电路板信号智能分析nginx配置提供大数据量的下载调度
- 内部监控系统
目前这个项目还在开发中主要是利用beego做两个服务一个是服务器端收集信息一个是客户端收集信息并上报给服务器端如果和服务端断开那么本地可以暂存数据防止数据丢失同时还支持类似pupput的功能支持程序自动更新(重启功能,不支持热更新)
- 日志分析系统
以前采用hadoop来分析日志的来源和省份信息发现hadoop分析这么大的数据性能不是很好延迟比较大目前采用自己的一套架构squid日志每小时分割上报每小时对日志进行分割然后进行UV、PV、省份、运营商、浏览器、数据量等的分析同时把日志进行按域名分割提供用户原始日志下载
- 下载分发系统
架构暂时不好公布我们提供文件下载的智能分发但是从文件上传到下发到每一台服务器以前采用BT的方式性能不是很好目前采用新的架构性能提升十几倍
- 基于微信的提醒助手
开源在github上
- 视频直播调度器

View File

@@ -1,45 +0,0 @@
## 热升级是什么?
热升级是什么呢了解nginx的同学都知道nginx是支持热升级的可以用老进程服务先前链接的链接使用新进程服务新的链接即在不停止服务的情况下完成系统的升级与运行参数修改。那么热升级和热编译是不同的概念热编译是通过监控文件的变化重新编译然后重启进程例如bee start就是这样的工具
## 热升级有必要吗?
很多人认为HTTP的应用有必要支持热升级吗那么我可以很负责的说非常有必要不中断服务始终是我们所追求的目标虽然很多人说可能服务器会坏掉等等这个是属于高可用的设计范畴不要搞混了这个是可预知的问题所以我们需要避免这样的升级带来的用户不可用。你还在为以前升级搞到凌晨升级而烦恼嘛那么现在就赶紧拥抱热升级吧。
## beego如何支持热升级
热升级的原理基本上就是主进程fork一个进程然后子进程exec相应的程序。那么这个过程中发生了什么呢我们知道进程fork之后会把主进程的所有句柄、数据和堆栈继承过来、但是里面所有的句柄存在一个叫做CloseOnExec也就是执行exec的时候copy的所有的句柄都被关闭了除非特别申明而我们期望的是子进程能够复用主进程的net.Listener的句柄。一个进程一旦调用exec类函数它本身就"死亡"了,系统把代码段替换成新的程序的代码,废弃原有的数据段和堆栈段,并为新程序分配新的数据段与堆栈段,唯一留下的,就是进程号,也就是说,对系统而言,还是同一个进程,不过已经是另一个程序了。
那么我们要做的第一步就是让子进程继承主进程的这个句柄我们可以通过os.StartProcess的参数来附加Files把需要继承的句柄写在里面。
第二步就是我们希望子进程能够从这个句柄启动监听还好Go里面支持net.FileListener直接从句柄来监听但是我们需要子进程知道这个FD所以在启动子进程的时候我们设置了一个环境变量设置这个FD。
第三步就是我们期望老的链接继续服务完而新的链接采用新的进程这里面有两个细节第一就是老的链接继续服务那么我们怎么知道有老链接存在所以我们必须每次接收一个链接记录一下这样我们就知道还存在没有服务完的链接第二就是怎么让老进程停止接收数据让新进程接收数据呢大家都监听在同一个端口理论上是随机来接收的所以这里我们只要关闭老的链接的接收就行这样就会使得在l.Accept的时候报错。
上面是我们需要解决的三个方面的问题,具体的实现大家可以看我实现的代码逻辑。
## 如何演示热升级
1. 编写代码在beego应用的控制器中Get方法实现大概如下
func (this *MainController) Get() {
a, _ := this.GetInt("sleep")
time.Sleep(time.Duration(a) * time.Second)
this.Ctx.WriteString("ospid:" + strconv.Itoa(os.Getpid()))
}
2. 打开两个终端
一个终端输入:` ps -ef|grep 应用名`
一个终端输入请求:`curl "http://127.0.0.1:8080/?sleep=20"`
3. 热升级
`kill -HUP 进程ID`
4. 打开一个终端输入请求:`curl "http://127.0.0.1:8080/?sleep=0"`
我们可以看到这样的结果第一个请求等待20s但是处理他的是老的进程热升级之后第一个请求还在执行最后会输出老的进程ID而第二次请求输出的是新的进程ID

View File

@@ -1,78 +0,0 @@
## 方便的http客户端
我们经常会使用Go来请求其他API应用例如你使用beego开发了一个RESTFul的API应用那么如果来请求呢当然可以使用`http.Client`来实现但是需要自己来操作很多步骤自己需要考虑很多东西所以我就基于net下的一些包实现了这个简便的http客户端工具。
该工具的主要特点:
- 链式操作
- 超时控制
- 方便的解析
- 可控的debug
## 例子
我们上次开发的RESTful应用最后我写过如何通过curl来进行测试那么下面一一对每个操作如何用httplib来操作进行展示
- 添加一个对象:
`curl -X POST -d '{"Score":1337,"PlayerName":"Sean Plott"}' http://127.0.0.1:8080/object`
返回一个相应的objectID:astaxie1373349756660423900
str,err:=beego.Post("http://127.0.0.1:8080/object").Body(`{"Score":1337,"PlayerName":"Sean Plott"}`).String()
if err != nil{
println(err)
}
- 查询一个对象
`curl -X GET http://127.0.0.1:8080/object/astaxie1373349756660423900`
var object Obeject
err:=beego.Get("http://127.0.0.1:8080/object/astaxie1373349756660423900").ToJson(&object)
if err != nil{
println(err)
}
- 查询全部的对象
`curl -X GET http://127.0.0.1:8080/object`
var objects []Object
err:=beego.Get("http://127.0.0.1:8080/object").ToJson(&objects)
if err != nil{
println(err)
}
- 更新一个对象
`curl -X PUT -d '{"Score":10000}'http://127.0.0.1:8080/object/astaxie1373349756660423900`
str,err:=beego.Put("http://127.0.0.1:8080/object/astaxie1373349756660423900").Body(`{"Score":10000}`).String()
if err != nil{
println(err)
}
- 删除一个对象
`curl -X DELETE http://127.0.0.1:8080/object/astaxie1373349756660423900`
str,er:=beego.Delete("http://127.0.0.1:8080/object/astaxie1373349756660423900").String()
if err != nil{
println(err)
}
## 开启调试模式
用户可以开启调试打印request信息默认是关闭模式
beego.Post(url).Debug(true)
## ToFile、ToXML、ToJson
上面我演示了Json的解析其实还有直接保存为文件的ToFile操作解析XML的ToXML操作
## 设置链接超时和读写超时
默认都设置为60秒用户可以通过函数来设置相应的超时时间
beego.Get(url).SetTimeout(100*time.Second,100*time.Second)
更加详细的请参考[API接口](http://gowalker.org/github.com/astaxie/beego)

View File

@@ -1,31 +0,0 @@
# 安装入门
beego虽然是一个简单的框架但是其中用到了很多第三方的包所以在你安装beego的过程中Go会自动安装其他关联的包。
- 当然第一步你需要安装Go如何安装Go请参考我的书[第一章](https://github.com/astaxie/build-web-application-with-golang/blob/master/ebook/01.1.md)
- 安装beego
go get github.com/astaxie/beego
- 安装bee工具,这个工具可以用来快速的建立beego的应用
go get github.com/astaxie/bee
这样就完成了beego的安装你就可以开始开发了,可以通过bee工具来创建beego项目
![](images/bee.png)
>beego依赖的第三方包有如下
> - session模块github.com/astaxie/beego/session
> - session模块中支持redis引擎github.com/garyburd/redigo/redis
> - session模块中支持mysql引擎github.com/go-sql-driver/mysql
- [beego介绍](README.md)
- [快速入门](Quickstart.md)

File diff suppressed because it is too large Load Diff

View File

@@ -1,54 +0,0 @@
# beego介绍
beego是一个类似tornado的Go应用框架采用了RESTFul的方式来实现应用框架是一个超轻量级的框架主要有如下的特点
- 支持MVC的方式用户只需要关注逻辑实现对应method的方法即可
- 支持websocket通过自定义Handler实现集成sockjs等方式实现
- 支持自定义路由支持各种方式的路由正则、语意均支持类似sinatra
- session集成支持memory、file、redis、mysql等存储
- 表单处理自动化解析,用户可以很方便的获取数据
- 日志分级系统,用户可以很方便的调试和应用日志记录
- 自定义配置文件支持ini格式的文本配置可以方便的在系统中调参数
- 采用了Go内置的模板集成实现了很多Web开发中常用的函数
执行过程如下所示:
![](images/beego.png)
# beego简单例子
package main
import (
"github.com/astaxie/beego"
)
type MainController struct {
beego.Controller
}
func (this *MainController) Get() {
this.Ctx.WriteString("hello world")
}
func main() {
beego.Router("/", &MainController{})
beego.Run()
}
# beego 指南
* [为什么设计beego](Why.md)
* [安装入门](Install.md)
* [快速入门](Quickstart.md)
* [一步一步开发应用](Tutorial.md)
* [beego案例](Application.md)
* [热升级](HotUpdate.md)
* [API应用开发入门](API.md)
* [HTTPLIB客户端](HttpLib.md)
# API接口
API对于我们平时开发应用非常有用用于查询一些开发的函数godoc做的非常好了
[Go Walker](http://gowalker.org/github.com/astaxie/beego)

View File

@@ -1,34 +0,0 @@
## supervisord安装
1. setuptools安装
wget http://pypi.python.org/packages/2.7/s/setuptools/setuptools-0.6c11-py2.7.egg
sh setuptools-0.6c11-py2.7.egg
easy_install supervisor
echo_supervisord_conf >/etc/supervisord.conf
mkdir /etc/supervisord.conf.d
2. 修改配置/etc/supervisord.conf
[include]
files = /etc/supervisord.conf.d/*.conf
3. 新建管理的应用
cd /etc/supervisord.conf.d
vim beepkg.conf
配置文件:
[program:beepkg]
directory = /opt/app/beepkg
command = /opt/app/beepkg/beepkg
autostart = true
startsecs = 5
user = root
redirect_stderr = true
stdout_logfile = /var/log/supervisord/beepkg.log

View File

@@ -1,19 +0,0 @@
# 一步一步跟我写博客
## 创建项目
## 数据库结构设计
## 控制器设计
## 模板设计
## 用户登陆退出
## 数据库操作

View File

@@ -1,20 +0,0 @@
# 为什么设计beego和设计的思路
很多人会问为什么有那么多框架了还要去实现一个框架呢是不是大家都有自己实现框架的情节我可以肯定的说不是我说一下为什么设计beego的初衷
还记得当初写书的时候我纯粹只是想把自己在学习Go语言中的一些体会写出来由于我以前主要从事PHP和python的Web开发所以想写一本Go如何来做Web实战的经验刚开始的时候书的目录里面根本就没有框架实现这些章节是写到后来发现其实对于Web开发者来说一个微型的框架是非常有利于大家学习一个语言和快速进行应用开发的。
我以前经常用PHP的CI框架和python的tornado框架这些框架都是非常轻量级的轻量级就有利于我们
- 第一节约我开发中一些常见问题的处理,用户只需要关注逻辑层面的东西
- 第二轻量级以至于他们的代码也是非常清晰的,我们可以通过阅读他们的源码来学习和体会这门语言的一些细节
- 第三对于项目开发者来说可以基于这些框架进行改造以适应自己的项目,从而实现二次框架的创造
所以基于上面这些的考虑我就想实现一个类似这些语言的轻量级框架所以我就在书的最后设计了两个章节来介绍和实现beego框架这就是当初写beego框架的初衷。
有了这个初衷之后我就开始设计beego的执行逻辑由于Go语言和python的思路比较接近所以我就参考了tornado的思路来设计beego你可以看到beego的RESTful处理完全和tornado的处理是一模一样的通过controller层的Get、Post等方法来实现RESTFul。刚开始的时候路由参考的是[https://github.com/drone/routes](https://github.com/drone/routes)这个的正则处理我觉得非常好弥补了Go语言默认Mux中的路由功能但是由于要采用RESTFul方式所以我自己设计了一个接口实现python中的继承思想。
整个的MVC逻辑中C是最重要的部分这一块采用了我上面说的接口方式M模块目前我还没想好怎么做但是大家可以参考我的另一个开源项目beedb来实现数据的管理V这一块目前采用了Go语言自带的模板引擎但是实现了很多方便的模板函数。这样一个简易的框架就完成了然后我就不断的完善周边的功能包括表单处理、session处理、日志处理、配置处理、自动化运行等功能。
- [beego介绍](README.md)
- [安装入门](Install.md)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Some files were not shown because too many files have changed in this diff Show More