웹페이지 운영/워드프레스

워드프레스 Error ( -32300 ) : transport error - HTTP status code was not 200 해결 방법

공무원 봉급 2022. 5. 18. 17:23

새로운 분야에 도전을 한다는 것은 항상 가슴 뛰는 일이지만 괴로운 일이기도 합니다. 요즘 워드프레스 웹서버를 구성했고, API를 이용해서 블로그 자동화를 진행중에 있습니다. 이 과정에서 배워야 하는 것도 많고, 해결해야 하는 문제들도 많이 마주치게 되었습니다.

본 페이지에서는 워드프레서 API 호출시에 "Error ( -32300 ) : transport error - HTTP status code was not 200" 에러가 발생했을 때 해결하는 방법에 대해서 기술하고자 합니다.

우선 "Error ( -32300 ) : transport error - HTTP status code was not 200" 에러를 유발하는 원인들은 상당히 많이 있습니다. 사실 위의 메시지 만으로는 디버깅이 쉽지 않은게 사실입니다.

왜냐하면 위의 메시지는 워드프레스 API 호출시에 200이 오지 않았다는 메시지만 나오기 때문에 HTTP 302 에러 때문인지 HTTP 400 에러 때문인지 문제를 좀 더 narrow down 하는데 어려움이 있습니다.

저의 경우는 HTTP 302 리다이렉션 응답과 HTTP 400 응답 오류 문제로 고생을 제법 했습니다.

 

미리 읽어두면 좋은 글

우선 제가 기존에 작성한 아래의 글을 먼저 읽어두시면 도움이 됩니다. 웹서버의 php-xml 모듈에 구성되어 있지 않아서 HTTP 400 Not Found 오류를 유발했던 문제를 해결하는 방법을 설명한 글입니다. 워드프레스 디버그 메시지를 살펴보는 방법과 API 예제가 있기 때문에 미리 읽어두시기를 권장드립니다.

2022.05.18 - [워드프레스] - 워드프레스 API "PHP의 XML 확장이 가능하지 않습니다. 호스팅 회사에게 연락하여 PHP의 XML 확장을 활성화하세요."

 

워드프레스 API "PHP의 XML 확장이 가능하지 않습니다. 호스팅 회사에게 연락하여 PHP의 XML 확장을

본 페이지에서는 워드프레스의 API로 호출시에 "PHP의 XML 확장이 가능하지 않습니다. 호스팅 회사에게 연락하여 PHP의 XML 확장을 활성화하세요."라는 에러 메시지가 발생할 경우 조치하는 방법에

worldclassproduct.tistory.com

 

필요한 배경 지식

워드프레스 API를 활용하는 방법은 여러가지가 있을 수 있습니다. PHP 스크립트로 작성해도 되고, curl 명령을 통해서도 가능하며, 파이썬 스크립트를 이용하는 방법도 있습니다. 하지만 워드프레스 디버깅을 위해서는 PHP 문법에 대한 이해가 필요합니다. 왜냐하면 워드프레스는 PHP 스크립트로 만들어졌기 때문입니다. 또한, 워드프레스의 로그를 살펴보는 방법도 알아야 합니다.

  • PHP 문법에 대한 이해
  • 워드프레스 로그 수집 방법
  • 워드프레스 API 프로토콜

 

API 쿼리 관련 워드프레스 소스 코드

우선 워드프레스 클라이언트 사이드의 소스 코드를 살펴보겠습니다.

$ vi /var/www/wordpress/wp-includes/IXR/class-IXR-client.php

vi 편집기를 열어서 살펴보면 query() 함수가 어떻게 짜여졌는지 소스 코드를 살펴볼 수 있습니다.

    function query( ...$args )
    {
        $method = array_shift($args);
        $request = new IXR_Request($method, $args);
        $length = $request->getLength();
        $xml = $request->getXml();
        $r = "\r\n";
        $request  = "POST {$this->path} HTTP/1.0$r";

        // Merged from WP #8145 - allow custom headers
        $this->headers['Host']          = $this->server;
        $this->headers['Content-Type']  = 'text/xml';
        $this->headers['User-Agent']    = $this->useragent;
        $this->headers['Content-Length']= $length;

        foreach( $this->headers as $header => $value ) {
            $request .= "{$header}: {$value}{$r}";
        }
        $request .= $r;

        $request .= $xml;

        $this->debug = true;
        // Now send the request
        if ($this->debug) {
            echo '<pre class="ixr_request">'.htmlspecialchars($request)."\n</pre>\n\n";
        }

        if ($this->timeout) {
            $fp = @fsockopen($this->server, $this->port, $errno, $errstr, $this->timeout);
        } else {
            $fp = @fsockopen($this->server, $this->port, $errno, $errstr);
        }
        if (!$fp) {
            $this->error = new IXR_Error(-32300, 'transport error - could not open socket');
            return false;
        }
        fputs($fp, $request);
        $contents = '';
        $debugContents = '';
        $gotFirstLine = false;
        $gettingHeaders = true;
        while (!feof($fp)) {
            $line = fgets($fp, 4096);
            print("return : " . $line);
            if (!$gotFirstLine) {
                // Check line for '200'
                if (strstr($line, '200') === false) {
                    $this->error = new IXR_Error(-32300, 'transport error - HTTP status code was not 200');
                    return false;
                }
                $gotFirstLine = true;
            }
            if (trim($line) == '') {
                $gettingHeaders = false;
            }
            if (!$gettingHeaders) {
            	// merged from WP #12559 - remove trim
                $contents .= $line;
            }
            if ($this->debug) {
            	$debugContents .= $line;
            }
        }
        if ($this->debug) {
            echo '<pre class="ixr_response">'.htmlspecialchars($debugContents)."\n</pre>\n\n";
        }

        // Now parse what we've got back
        $this->message = new IXR_Message($contents);
        if (!$this->message->parse()) {
            // XML error
            $this->error = new IXR_Error(-32700, 'parse error. not well formed');
            return false;
        }

        // Is the message a fault?
        if ($this->message->messageType == 'fault') {
            $this->error = new IXR_Error($this->message->faultCode, $this->message->faultString);
            return false;
        }

        // Message must be OK
        return true;
    }

 

디버그 메시지 추가

위의 소스 코드에서 저는 아래와 같이 2개의 디버그 메시지를 추가하였습니다.

$this->debug = true;

위의 코드를 추가함으로써 아래 디버그가 나오도록 했습니다.

echo '<pre class="ixr_request">'.htmlspecialchars($request)."\n</pre>\n\n";

또한 아래 코드를 추가함으로써 서버로부터 리턴되는 응답을 표시하도록 했습니다.

print("return : " . $line);

 

실행

물론 웹페이지에서 실행을 시켜도 되겠지만, 저는 로컬에서 실행시켜 보았습니다. 웹페이지에서 실행할 경우 에러가 발생시에 디버깅이 쉽지 않아서 쉘에서 실행해보시는걸 추천드립니다.

$ php api.php

 

디버그 메시지 분석

실행 결과를 살펴보면 query를 위해서 작성된 데이터를 확인할 수 있습니다. (파란색으로 강조한 부분)

<pre class="ixr_request">POST /xmlrpc.php HTTP/1.0
Host: www.webpage.com
Content-Type: text/xml
User-Agent: The Incutio XML-RPC PHP Library
Content-Length: 110

&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;methodCall&gt;
&lt;methodName&gt;system.listMethods&lt;/methodName&gt;
&lt;params&gt;
&lt;/params&gt;&lt;/methodCall&gt;
</pre>

return : HTTP/1.1 302 Found
Error ( -32300 ) : transport error - HTTP status code was not 200

또한 빨간색으로 강조한 부분을 살펴보면 302 리다이렉션 응답이 왔다는 것을 알 수 있습니다.

웹서버에 따라서 http 프로토콜로 접속을 시도할 경우 https 프로토콜로 rewrite 하는 경우가 많습니다. 즉, http 프로토콜로 접속을 시도했고 서버에서는 이것을 https 프로토콜로 리다이렉션을 시켰기 때문에 302 응답이 오는 것입니다.

 

302 리다이렉션 에러 해결 방법 (임시대책)

302 리다이렉션 에러를 해결하는 방법은 HTTP 프로토콜로 접속할 경우 HTTPS 프로토콜로 리다이렉션하는 기능을 제거해주면 됩니다.

아래의 명령을 통해서 HTTP 프로토콜 설정 파일을 살펴봅니다.

$ sudo vi /etc/apache2/sites-available/000-default.conf

설정 파일 내부의 아래 내용들을 주석처리 합니다.

<VirtualHost *:80>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
#ServerName www.example.com

ServerAdmin webmaster@localhost
DocumentRoot /var/www/wordpress

# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf

# RewriteEngine On
# RewriteCond %{HTTPS} !on
# RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R,L]
</VirtualHost>

아파치 웹서버의 설정을 변경한 이후에는 반드시 아파치 웹서비스를 재시작해줘야 합니다.

$ sudo service apache2 restart

 

302 리다이렉션 에러 해결 방법 (영구대책)

사실 HTTP 프로토콜은 HTTPS 프로토콜로 자동으로 리다이렉션 해주는게 좋습니다. 따라서 API 통신시에 HTTPS로 통신할 수 있도록 변경하는 방법도 있습니다. 파이썬으로 워드프레스에 글을 자동으로 업데이트하는 방법에 대해서는 제가 작성한 아래 글을 참고하시기 바랍니다.

 

워드프레스 API를 통한 자동 글쓰기 예제 (파이썬 버전)

블로그 자동화를 위해서는 네이버 블로그나 티스토리 블로그로는 한계가 있습니다. 하루에 발행할 수 있는 글의 개수에 제한이 있기 때문입니다. 그래서 GitHub Pages나 워드프레스로 블로그를 옮

worldclassproduct.tistory.com

 

400 에러에 의한 문제

400 에러에 의한 문제라면 아래의 글을 참고해보시는 것도 좋겠습니다.

 

워드프레스 API "PHP의 XML 확장이 가능하지 않습니다. 호스팅 회사에게 연락하여 PHP의 XML 확장을

본 페이지에서는 워드프레스의 API로 호출시에 "PHP의 XML 확장이 가능하지 않습니다. 호스팅 회사에게 연락하여 PHP의 XML 확장을 활성화하세요."라는 에러 메시지가 발생할 경우 조치하는 방법에

worldclassproduct.tistory.com

 

이상입니다.