summaryrefslogtreecommitdiff
path: root/lib/soap/sender.ts
diff options
context:
space:
mode:
Diffstat (limited to 'lib/soap/sender.ts')
-rw-r--r--lib/soap/sender.ts88
1 files changed, 57 insertions, 31 deletions
diff --git a/lib/soap/sender.ts b/lib/soap/sender.ts
index 3728429b..1dfc8730 100644
--- a/lib/soap/sender.ts
+++ b/lib/soap/sender.ts
@@ -35,6 +35,9 @@ export interface SoapSendResult {
responseText?: string;
statusCode?: number;
headers?: Record<string, string>;
+ endpoint?: string;
+ requestXml?: string;
+ requestHeaders?: Record<string, string>;
}
// 기본 환경변수에서 인증 정보 가져오기
@@ -111,34 +114,46 @@ export async function sendSoapXml(
console.log('📤 SOAP XML 전송 시작');
console.log('🔍 전송 XML (첫 500자):', xmlData.substring(0, 500));
+ // 요청 헤더 및 fetch 옵션을 사전에 구성
+ const requestHeaders: Record<string, string> = {
+ 'Content-Type': 'text/xml; charset=utf-8',
+ 'SOAPAction': config.soapAction || 'http://sap.com/xi/WebService/soap1.1',
+ };
+
+ // Basic Authentication 헤더 추가
+ if (authConfig.username && authConfig.password) {
+ const credentials = Buffer.from(`${authConfig.username}:${authConfig.password}`).toString('base64');
+ requestHeaders['Authorization'] = `Basic ${credentials}`;
+ console.log('🔐 Basic Authentication 헤더 추가 완료');
+ } else {
+ console.warn('⚠️ SOAP 인증 정보가 설정되지 않았습니다.');
+ }
+
+ const fetchOptions: RequestInit = {
+ method: 'POST',
+ headers: requestHeaders,
+ body: xmlData,
+ };
+
+ // Body 루트 요소(p1:MT_...)에 기본 네임스페이스를 부여하여 하위 무접두사 요소들도 동일 네임스페이스로 인식되도록 처리
+ const envelopeObj = soapEnvelope as Record<string, any>;
+ const bodyObj = envelopeObj['soap:Envelope']?.['soap:Body'] as Record<string, any> | undefined;
+ if (bodyObj && typeof bodyObj === 'object') {
+ const rootKeys = Object.keys(bodyObj);
+ if (rootKeys.length > 0) {
+ const rootKey = rootKeys[0];
+ if (bodyObj[rootKey] && typeof bodyObj[rootKey] === 'object') {
+ bodyObj[rootKey]['@_xmlns'] = namespace;
+ }
+ }
+ }
+
const result = await withSoapLogging(
logInfo.direction,
logInfo.system,
logInfo.interface,
xmlData,
async () => {
- // 헤더 설정
- const headers: Record<string, string> = {
- 'Content-Type': 'text/xml; charset=utf-8',
- 'SOAPAction': config.soapAction || 'http://sap.com/xi/WebService/soap1.1',
- };
-
- // Basic Authentication 헤더 추가
- if (authConfig.username && authConfig.password) {
- const credentials = Buffer.from(`${authConfig.username}:${authConfig.password}`).toString('base64');
- headers['Authorization'] = `Basic ${credentials}`;
- console.log('🔐 Basic Authentication 헤더 추가 완료');
- } else {
- console.warn('⚠️ SOAP 인증 정보가 설정되지 않았습니다.');
- }
-
- // fetch 옵션 설정
- const fetchOptions: RequestInit = {
- method: 'POST',
- headers,
- body: xmlData,
- };
-
// 타임아웃 설정
if (config.timeout) {
const controller = new AbortController();
@@ -171,14 +186,22 @@ export async function sendSoapXml(
console.log('📥 SOAP 응답 수신:', response.status, response.statusText);
console.log('🔍 응답 XML (첫 500자):', responseText.substring(0, 500));
- // HTTP 상태 코드 확인
- if (!response.ok) {
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
- }
-
- // SOAP Fault 검사
- if (responseText.includes('soap:Fault') || responseText.includes('SOAP:Fault')) {
- throw new Error(`SOAP Fault: ${responseText}`);
+ // HTTP 상태 코드가 비정상이거나 SOAP Fault 포함 시 실패로 처리하되 본문을 그대로 반환
+ if (!response.ok || responseText.includes('soap:Fault') || responseText.includes('SOAP:Fault')) {
+ const responseHeaders: Record<string, string> = {};
+ response.headers.forEach((value, key) => {
+ responseHeaders[key] = value;
+ });
+ return {
+ success: false,
+ message: !response.ok ? `HTTP ${response.status}: ${response.statusText}` : 'SOAP Fault',
+ responseText,
+ statusCode: response.status,
+ headers: responseHeaders,
+ endpoint: config.endpoint,
+ requestXml: xmlData,
+ requestHeaders
+ };
}
// 응답 헤더 수집
@@ -192,7 +215,10 @@ export async function sendSoapXml(
message: '전송 성공',
responseText,
statusCode: response.status,
- headers: responseHeaders
+ headers: responseHeaders,
+ endpoint: config.endpoint,
+ requestXml: xmlData,
+ requestHeaders
};
} catch (error) {