錯誤資訊傳回流程(以SQL錯誤為例)
Client | Server | |||
1 | ------- | Data Piggyback(11) Cursor Close All(69) 或 03 5e | -----> | 具體語句 |
2 | <----- | Marker(0C) | ------- | 傳回Marker |
3 | <----- | Marker(0C) | ------- | 傳回Marker |
4 | ------- | Marker(0C) | -----> | Request Marker |
5 | <----- | Data Error(17) 02 | ------- | 錯誤資訊 |
錯誤請求涉及的包有Marker包(PacketType 0x0C)和Data Error(DataType 0x06 DataID 0x17 CallID 0x02)包
錯誤請求發出後,服務端會傳回兩個Marker(2,3),然後用戶端會主動通過一個Marker(4)請求去擷取錯誤資訊(5)
Marker包不是data包,他的的dataflag是0C,是以頭部是
0x00,0x0b,0x00,0x00,0x0c,0x00,0x00,0x00
從目前看似乎Marker包長度固定為0b
除去頭部固定的8個位元組後,剩下三個位元組是Marker的具體内容
傳回的第一個Marker
01 00 01 或者01 00 03
Attention
Marker Type: Data Marker - 1 Data Bytes (0x01)
Marker Data Byte: 0x00
Marker Data Byte: 0x03 或者 0x01
傳回的第二個Marker
01 00 02
Attention
Marker Type: Data Marker - 1 Data Bytes (0x01)
Marker Data Byte: 0x00
Marker Data Byte: 0x02
請求Marker
01 00 02
Attention
Marker Type: Data Marker - 1 Data Bytes (0x01)
Marker Data Byte: 0x00
Marker Data Byte: 0x02
錯誤資訊傳回
此包根據服務端,用戶端不同有很多變化,且不能通用
64bitOCIclient to 12c 錯誤傳回
此包此包為Data包,DataID=17 CALLID=02
包含兩個部分,前一個部分固定長度為155位元組,表示内部錯誤資訊,後一部分是前序一個長度位元組的錯誤字元串,和語言及編碼設定有關
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL90TQNdXQq1UMo1WZwx2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL4gTM2IDM1MjMwETNwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
.....
64bitOCIclient to 11g 錯誤傳回
此包此包為Data包,DataID=04 CALLID=05
包含兩個部分,前一個部分固定長度為68位元組,表示内部錯誤資訊,後一部分與12c版本相同是前序長度的錯誤字元串,和語言及編碼設定有關
注意與12c一樣,綠色部分的錯誤編碼要和藍色字元串中的錯誤編碼相同,才能顯示字元串中的資訊,否則顯示預設資訊
TNS312版本錯誤傳回
如果将版本改為312,傳回錯誤又不相同,
此包此包為Data包,DataID=17 CALLID=02
綠色部分的錯誤編碼要和藍色字元串中的錯誤編碼相同,才能顯示字元串中的資訊,否則顯示預設資訊
代碼示例
功能:在接收指令處如果滿足禁止條件,則傳回權限不足,效果如圖
首先在接收指令處如果滿足禁止條件,則傳回兩個marker
if(command:match("forbidden")) then
--set a flag indicate error happen
ngx.ctx.responseError=true
print("forbidden matched...")
--return marker1
reqsock:send(string.char(0x00,0x0b,0x00,0x00,0x0c,0x00,0x00,0x00,0x01,0x00,0x01))
--return marker2
reqsock:send(string.char(0x00,0x0b,0x00,0x00,0x0c,0x00,0x00,0x00,0x01,0x00,0x02))
goto continue
end
當代理收到marker時,傳回具體錯誤,需要根據各種條件進行判斷
--process req marker, if flag true then return error
if(data:byte(3)==12 and ngx.ctx.responseError) then
print("return error message")
--11g
if(tnsVersion==314 and oracleVersion.major==11) then
reqsock:send(string.char(
0x00, 0x75, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x00, 0x00, 0x04, 0x05, 0x00, 0x00, 0x00, 0x05,
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x04, 0x00,
0x00, 0x00, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x28, 0x4f, 0x52, 0x41,
0x2d, 0x30, 0x30, 0x39, 0x34, 0x32, 0x3a, 0x20,
0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x6f, 0x72,
0x20, 0x76, 0x69, 0x65, 0x77, 0x20, 0x64, 0x6f,
0x65, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x65,
0x78, 0x69, 0x73, 0x74, 0x0a))
end
--12c
if(tnsVersion==314 and oracleVersion.major==12) then
reqsock:send(string.char(
0x00, 0xb4, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x00, 0x00, 0x17, 0x02, 0x04, 0x00, 0x04, 0x33,
0x35, 0x38, 0x34, 0x04, 0x01, 0x00, 0x00, 0x00,
0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07,
0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x40, 0xbb, 0x3d, 0x24, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
0x04, 0x00, 0x00, 0x18, 0x4f, 0x52, 0x41, 0x2d,
0x30, 0x31, 0x30, 0x33, 0x31, 0x3a, 0x20, 0xe6,
0x9d, 0x83, 0xe9, 0x99, 0x90, 0xe4, 0xb8, 0x8d,
0xe8, 0xb6, 0xb3, 0x0a))
end
if(tnsVersion==312) then
reqsock:send(string.char(
0x00, 0xb4, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x00, 0x00, 0x17, 0x02, 0x04, 0x00, 0x04, 0x32,
0x37, 0x30, 0x30, 0x04, 0x05, 0x00, 0x00, 0x00,
0x56, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07,
0x04, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x0e,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x60, 0xe6, 0xe9, 0x0f, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
0x04, 0x00, 0x00, 0x18, 0x4f, 0x52, 0x41, 0x2d,
0x30, 0x31, 0x30, 0x33, 0x31, 0x3a, 0x20, 0xe6,
0x9d, 0x83, 0xe9, 0x99, 0x90, 0xe4, 0xb8, 0x8d,
0xe8, 0xb6, 0xb3, 0x0a))
end
ngx.ctx.responseError=nil
goto continue
end