반응형

과제로 C++ 웹 서버를 여는 문제를 풀고 있었는데
Form 태그로 데이터를 받게 구현 했었습니다.

 

그런데 이상하게 입력한 값이 영어가 아닌 경우 자동으로 인코딩 되어 서버에 전송이 되는것으로 보였습니다.

 

UTF-8로 지정된 데이터가 아닌 다른 형식으로 바뀐 데이터가 보내지고 있었고

한글만 깨지는것이 아닌 영어를 제외한 모든 데이터가 깨지는 현상이었습니다.

_method=post&id=hello world!z&password=aA1!
이렇게 전송되었어야 할 데이터가
_method=post&id=hello+world%21z&password=aA1%21
이런식으로 인코딩되어 전송됨
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <form method="post">
        <input type="hidden" name="_method" value="post"/>
        <label for="name">닉네임 :</label>
        <input type="text" name="id" id="id" value="hello world!">
      
        <label for="password">비밀번호 :</label>
        <input type="password" name="password" id="password">
      
        <input type="submit" value="Submit">
        <!-- <button>제출</button> -->
    </form>

</body>
</html>

당시 문제가 됐었던 html 코드인데 charset을 form 태그에 넣고 utf-8로 지정을 했어도 문제가 해결되지 않았고

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

이 코드를 head태그에 넣고 해도 안되고 자바스크립트로 charset을 지정해도 안되고 form 태그 옵션인

accept-charset="utf-8"

이걸 추가 해도 안되서 좌절하고 있었습니다.

 

그래서 아무리 해도 안될것 같아 다른 방법을 찾아보다가 문득 든 생각

"규칙을 찾아서 디코딩 해보자" 였습니다.

웹에 관한 지식이 없던 상황이었지만 다행히도 규칙이 보여서 디코딩을 해보니 성공했었습니다.

 

// _method=post&id=hello+world%21z&password=aA1%21
std::string Http::decoding(const std::string& encodedString) {
    std::string decodedString;
    std::istringstream iss(encodedString);
    char c;
    int value;
    
    while (iss.get(c)) {
        if (c == '%') {
            if (iss >> std::hex >> value) {
                decodedString += static_cast<char>(value);
            }
        } else if (c == '+') {
            decodedString += ' ';
        } else {
            decodedString += c;
        }
    }
    
    return decodedString;
}

인코딩된 데이터를 보면 공백은 + 문자로 바뀌고 영어 이외의 문자는 %16진수로 변환되어 있습니다.

그래서 %문자인 경우 16진수를 10진수로 바꾼뒤 char로 바꾸고

+문자인 경우 공백으로 바꾸고

그 외의의 문자는 영문일테니 그대로 값을 복사해 주었습니다.

 

그랬더니 정상적으로 디코딩되어 원래 원하던 값이 잘 나오네요.

c++98 버전을 기준으로 과제를 풀었어야 했어서 istringstream으로 받아 get 함수를 통해 위 과정을 반복해주었습니다.

반응형
원피스는 실존하다