/// <summary> /// Session处理轮回 /// </summary> public void Processing() { int nRet = 0; string strError = ""; try { byte[] baPackage = null; int nLen = 0; byte[] baResponsePackage = null; for (; ; ) { _activateTime = DateTime.Now; // 接收前端请求 nRet = RecvTcpPackage(out baPackage, out nLen, out strError); if (nRet == -1) goto ERROR_NOT_LOG; // 分析请求包 BerTree tree1 = new BerTree(); int nTotlen = 0; tree1.m_RootNode.BuildPartTree(baPackage, 0, baPackage.Length, out nTotlen); BerNode root = tree1.GetAPDuRoot(); switch (root.m_uTag) { case BerTree.z3950_initRequest: { InitRequestInfo info = null; string strDebugInfo = ""; nRet = Decode_InitRequest( root, out info, out strDebugInfo, out strError); if (nRet == -1) goto ERROR1; // 可以用groupid来表示字符集信息 InitResponseInfo response_info = new InitResponseInfo(); // 判断info中的信息,决定是否接受Init请求。 if (String.IsNullOrEmpty(info.m_strID) == true) { // 如果定义了允许匿名登录 if (String.IsNullOrEmpty(this._service.AnonymousUserName) == false) { info.m_strID = this._service.AnonymousUserName; info.m_strPassword = this._service.AnonymousPassword; } else { response_info.m_nResult = 0; this._bInitialized = false; SetInitResponseUserInfo(response_info, "", // string strOID, 0, // long lErrorCode, "不允许匿名登录"); goto DO_RESPONSE; } } // 进行登录 // return: // -1 error // 0 登录未成功 // 1 登录成功 nRet = DoLogin(info.m_strGroupID, info.m_strID, info.m_strPassword, out strError); if (nRet == -1 || nRet == 0) { response_info.m_nResult = 0; this._bInitialized = false; SetInitResponseUserInfo(response_info, "", // string strOID, 0, // long lErrorCode, strError); } else { response_info.m_nResult = 1; this._bInitialized = true; } DO_RESPONSE: // 填充response_info的其它结构 response_info.m_strReferenceId = info.m_strReferenceId; // .m_strID; BUG!!! 2007/11/2 if (info.m_lPreferredMessageSize != 0) this._lPreferredMessageSize = info.m_lPreferredMessageSize; // 极限 if (this._lPreferredMessageSize > MaxPreferredMessageSize) this._lPreferredMessageSize = MaxPreferredMessageSize; response_info.m_lPreferredMessageSize = this._lPreferredMessageSize; if (info.m_lExceptionalRecordSize != 0) this._lExceptionalRecordSize = info.m_lExceptionalRecordSize; // 极限 if (this._lExceptionalRecordSize > MaxExceptionalRecordSize) this._lExceptionalRecordSize = MaxExceptionalRecordSize; response_info.m_lExceptionalRecordSize = this._lExceptionalRecordSize; response_info.m_strImplementationId = "Digital Platform"; response_info.m_strImplementationName = "dp2ZServer"; response_info.m_strImplementationVersion = "1.0"; if (info.m_charNego != null) { /* option * search (0), present (1), delSet (2), resourceReport (3), triggerResourceCtrl (4), resourceCtrl (5), accessCtrl (6), scan (7), sort (8), -- (9) (reserved) extendedServices (10), level-1Segmentation (11), level-2Segmentation (12), concurrentOperations (13), namedResultSets (14) 15 Encapsulation Z39.50-1995 Amendment 3: Z39.50 Encapsulation 16 resultCount parameter in Sort Response See Note 8 Z39.50-1995 Amendment 1: Add resultCount parameter to Sort Response 17 Negotiation Model See Note 9 Model for Z39.50 Negotiation During Initialization 18 Duplicate Detection See Note 1 Z39.50 Duplicate Detection Service 19 Query type 104 * } */ response_info.m_strOptions = "yynnnnnnnnnnnnn"; if (info.m_charNego.EncodingLevelOID == CharsetNeogatiation.Utf8OID) { BerTree.SetBit(ref response_info.m_strOptions, 17, true); response_info.m_charNego = info.m_charNego; this._searchTermEncoding = Encoding.UTF8; if (info.m_charNego.RecordsInSelectedCharsets != -1) { response_info.m_charNego.RecordsInSelectedCharsets = info.m_charNego.RecordsInSelectedCharsets; // 依从前端的请求 if (response_info.m_charNego.RecordsInSelectedCharsets == 1) this._marcRecordEncoding = Encoding.UTF8; } } } else { response_info.m_strOptions = "yynnnnnnnnnnnnn"; } BerTree tree = new BerTree(); nRet = Encode_InitialResponse(response_info, out baResponsePackage); if (nRet == -1) goto ERROR1; } break; case BerTree.z3950_searchRequest: { SearchRequestInfo info = null; // 解码Search请求包 nRet = Decode_SearchRequest( root, out info, out strError); if (nRet == -1) goto ERROR1; if (_bInitialized == false) goto ERROR_NOT_LOG; // 编码Search响应包 nRet = Encode_SearchResponse(info, out baResponsePackage, out strError); if (nRet == -1) goto ERROR1; } break; case BerTree.z3950_presentRequest: { PresentRequestInfo info = null; // 解码Search请求包 nRet = Decode_PresentRequest( root, out info, out strError); if (nRet == -1) goto ERROR1; if (_bInitialized == false) goto ERROR_NOT_LOG; // 编码Present响应包 nRet = Encode_PresentResponse(info, out baResponsePackage); if (nRet == -1) goto ERROR1; } break; default: break; } // 发出响应包 // return: // -1 出错 // 0 正确发出 // 1 发出前,发现流中有未读入的数据 nRet = SendTcpPackage(baResponsePackage, baResponsePackage.Length, out strError); if (nRet == -1) goto ERROR_NOT_LOG; } } catch (ThreadInterruptedException) { // string dummy = e.Message; // Needed for to remove compile warning } catch (Exception x) { /* if(m_clientSocket.Connected) { // SendData("421 Service not available, closing transmission channel\r\n"); // m_pSMTP_Server.WriteErrorLog(x.Message); } else { } * */ strError = "Session Processing()俘获异常: " + ExceptionUtil.GetDebugText(x); goto ERROR1; } finally { _service.RemoveSession(this.SessionID); this.CloseSocket(); } return; ERROR1: // 将strError写入日志 this._service.Log.WriteEntry(strError, EventLogEntryType.Error); return; ERROR_NOT_LOG: // 不写入日志 return; }
void SetInitResponseUserInfo(InitResponseInfo response_info, string strOID, long lErrorCode, string strErrorMessage) { if (response_info.UserInfoField == null) response_info.UserInfoField = new External(); response_info.UserInfoField.m_strDirectRefenerce = strOID; response_info.UserInfoField.m_lIndirectReference = lErrorCode; if (String.IsNullOrEmpty(strErrorMessage) == false) { response_info.UserInfoField.m_octectAligned = Encoding.UTF8.GetBytes(strErrorMessage); } }
// 2007/7/18 // build a z39.50 Init response public static int Encode_InitialResponse(InitResponseInfo info, out byte[] baPackage) { baPackage = null; BerNode root = null; BerTree tree = new BerTree(); root = tree.m_RootNode.NewChildConstructedNode(BerTree.z3950_initResponse, BerNode.ASN1_CONTEXT); if (String.IsNullOrEmpty(info.m_strReferenceId) == false) { root.NewChildCharNode(BerTree.z3950_ReferenceId, BerNode.ASN1_CONTEXT, Encoding.UTF8.GetBytes(info.m_strReferenceId)); } root.NewChildBitstringNode(BerTree.z3950_ProtocolVersion, // 3 BerNode.ASN1_CONTEXT, "yy"); /* option search (0), present (1), delSet (2), resourceReport (3), triggerResourceCtrl (4), resourceCtrl (5), accessCtrl (6), scan (7), sort (8), -- (9) (reserved) extendedServices (10), level-1Segmentation (11), level-2Segmentation (12), concurrentOperations (13), namedResultSets (14) 15 Encapsulation Z39.50-1995 Amendment 3: Z39.50 Encapsulation 16 resultCount parameter in Sort Response See Note 8 Z39.50-1995 Amendment 1: Add resultCount parameter to Sort Response 17 Negotiation Model See Note 9 Model for Z39.50 Negotiation During Initialization 18 Duplicate Detection See Note 1 Z39.50 Duplicate Detection Service 19 Query type 104 */ root.NewChildBitstringNode(BerTree.z3950_Options, // 4 BerNode.ASN1_CONTEXT, info.m_strOptions); // "110000000000001" root.NewChildIntegerNode(BerTree.z3950_PreferredMessageSize, // 5 BerNode.ASN1_CONTEXT, BitConverter.GetBytes((long)info.m_lPreferredMessageSize)); root.NewChildIntegerNode(BerTree.z3950_ExceptionalRecordSize, // 6 BerNode.ASN1_CONTEXT, BitConverter.GetBytes((long)info.m_lExceptionalRecordSize)); // 2007/11/7 原来这个事项曾经位置不对,现在调整到这里 // bool root.NewChildIntegerNode(BerTree.z3950_result, // 12 BerNode.ASN1_CONTEXT, BitConverter.GetBytes((long)info.m_nResult)); root.NewChildCharNode(BerTree.z3950_ImplementationId, // 110 BerNode.ASN1_CONTEXT, Encoding.UTF8.GetBytes(info.m_strImplementationId)); root.NewChildCharNode(BerTree.z3950_ImplementationName, // 111 BerNode.ASN1_CONTEXT, Encoding.UTF8.GetBytes(info.m_strImplementationName)); root.NewChildCharNode(BerTree.z3950_ImplementationVersion, // 112 BerNode.ASN1_CONTEXT, Encoding.UTF8.GetBytes(info.m_strImplementationVersion)); // "3" // userInformationField if (info.UserInfoField != null) { BerNode nodeUserInfoRoot = root.NewChildConstructedNode(BerTree.z3950_UserInformationField, // 11 BerNode.ASN1_CONTEXT); info.UserInfoField.Build(nodeUserInfoRoot); } if (info.m_charNego != null) { info.m_charNego.EncodeResponse(root); } baPackage = null; root.EncodeBERPackage(ref baPackage); return 0; }