HTTP Request in TCP
net
파이썬으로 개발된 OCR 서버와 TCP로 이미지 데이터를 http 형식으로 전송하는 방법을 알아내기 위해, Node.js 의 내장 모듈 net 을 사용했다.
Http Request
Host: localhost:3000
User-Agent: WithMe_TCP/1.0
Accept: */*
Content-Length: 1043
Content-Type: multipart/form-data; boundary=------------------------d599bfa08c4b3286
--------------------------d599bfa08c4b3286
Content-Disposition: form-data; name="file"; filename="icon.png"
Content-Type: image/png
[Binary Data]
--------------------------d599bfa08c4b3286--
Client Code
import net from 'net';
import fs from 'fs';
const options = {
host: 'localhost',
path: '/ocr',
port: 3000,
method: 'POST',
image: '../ocr/testData/icon.png'
};
(async() => {
const serverSocket = net.connect(options.port, options.host, async () => {
serverSocket.on("data", (b) => {
console.log(b.toString());
});
serverSocket.on('error', (e) => {console.log(e)})
const Image = await ReadImage(options.image);
const Boundary = '------------------------d599bfa08c4b3286';
const Body = [
`--${Boundary}`,
`Content-Disposition: form-data; name="file"; filename="${options.image.split('/').pop()}"`,
`Content-Type: image/${Image.extension}`,
'',
Image.data.toString('binary'),
`--${Boundary}--`,
''
]
const Header = [
`${options.method} ${options.path} HTTP/1.1`,
`Host: ${options.host}${(options.port!=80)?':'+options.port:''}`,
'User-Agent: WithMe_TCP/1.0',
'Accept: */*',
`Content-Length: ${Buffer.from(Body.join('\r\n'), 'binary').byteLength}`,
`Content-Type: multipart/form-data; boundary=${Boundary}`,
'',
''
]
let BinHeader = new Uint8Array(Buffer.from(Header.join('\r\n'), 'binary').byteLength);
let BinBody = new Uint8Array(Buffer.from(Body.join('\r\n'), 'binary').byteLength);
Buffer.from(Header.join('\r\n'), 'binary').forEach((v, idx) => {
BinHeader.set([v], idx)
})
Buffer.from(Body.join('\r\n'), 'binary').forEach((v, idx) => {
BinBody.set([v], idx);
})
console.log(BinHeader);
console.log(BinBody);
fs.writeFileSync('./http', Header.join('\r\n') + Body.join('\r\n'), 'binary');
serverSocket.write(BinHeader);
serverSocket.write(BinBody);
});
})();
function ReadImage(location: string): Promise<{data: Buffer, extension: undefined | string}> {
return new Promise(resolve => {
const data = fs.readFileSync(location);
console.log(data.slice(0, 8),data.length);
const extension = location.split('.').pop();
return resolve({data: data, extension: extension})
})
}
설명
http는 Content-Type에 따라 Body의 구조가 다르다
MIME 에 따라 json, binary 등 많은 형식이 있다. 위 코드에서는 이미지 데이터를 전송하기 위해 multipart/form-data 를 사용했다.
boundary
multipart 라는 이름에서 보이듯이, Body가 여러개의 파트로 나누어져 있고 이를 분리하는 역할을 하는 것이 boundary 이다.
시작은 "--BoundaryString" 로 시작하며, 데이터의 맨 마지막에 "--BoundaryString--" 의 형식으로 끝이 난다.
curl
http request를 콘솔에서 보내주는 도구인데, --trace 옵션을 통하여 서버로 전송되는 모든 데이터를 하나하나 뜯어볼 수 있어 도움이 많이 되었다.
--trace file
--trace-ascii file
위 명령어를 통해 파일에 저장가능
BinaryData
Nodejs의 문제인지는 모르겠지만, socket.write의 인자는 string | Uint8Array 를 처리할 수 있다.
그런데 string을 넘겨주니 서버에서 받는 데이터에 변조가 일어나 정상적인 처리가 불가능했다.
파일 인코딩도 바꿔보며 테스트 한 결과 Binary 형식에서 문자열로 변경하는 중에 일어나는 문제로 보여 직접 Binary데이터를 Uint8Array 형태로 변환해 주었다.
Author And Source
이 문제에 관하여(HTTP Request in TCP), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@heavyrisem/HTTP-Request-in-TCP저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)