目次↑

.. HTTP/RESTインターフェース

..1. 概要

HTTP/RESTインターフェースはCopper PDF 2.1.0からサポートされた、HTTPベースのインターフェースです。 高速・高機能なCTIPに比べて冗長なプロトコルですが、HTTPをベースとしているため、普通のウェブブラウザやHTTPクライアントライブラリを利用できる利点があります。

HTTP通信による処理速度の損失は、変換処理の開始・終了時に発生するものなので、数十ページ以上の文書の出力ではほとんど問題になりません。 数ページ程度の文書を繰り返し出力する場合は、処理速度はおおむね70%程度に低下します。

HTTP/RESTインターフェースはCTIP 2.0と同等の機能を備えており、実際にJava版のCTIP 2.0ドライバは、 CTIP, HTTP接続の両方で、同一のインターフェースを利用することができます。

このドキュメントでは、HTTP/RESTインターフェースの基本的な使用方法だけを解説します。 HTTP/RESTインターフェースの完全な仕様は、以下のアドレスで公開している仕様書を参照してください。
https://osdn.net/projects/copper/docs/cti-rest-v1

..2. アクションの実行

HTTP/RESTインターフェースにより、Copper PDFに対して何らかの動作(アクション)の実行を要求するためには、 HTTPのGETまたはPOSTメソッドでクライアントからアクセスします。 アクションの種類は、ファイルパスにより識別されます。 処理対象文書や認証情報など、必要な情報はリクエストパラメータとして送ります。 アクションとファイルパスの対応と、使用可能なリクエストパラメータの表は以下の通りです。

パス リクエストパラメータ 説明
/open rest.user
rest.password
rest.timeout
rest.httpSession
セッションの開始
/info rest.id
rest.user
rest.password
rest.uri
サーバーの情報(セッションの開始と終了を兼ねる)
/properties rest.id
"rest."で始まらないパラメータ
プロパティ設定
/resources rest.id
rest.uri
rest.mimeType
rest.encoding
rest.resource
rest.notFound
"rest."で始まらないパラメータ
リソース送信(プロパティ設定を兼ねる)
/transcode rest.id
rest.user
rest.password
rest.async
rest.requestResource
"rest."で始まらないパラメータ
rest.uri
rest.mimeType
rest.encoding
rest.resource
rest.main
rest.mainURI
ドキュメント変換処理(セッションの開始と終了、プロパティ設定、リソース送信を兼ねる)
/messages rest.id
rest.wait
メッセージ受信
/result rest.id
rest.uri
ドキュメント変換結果受信
/abort rest.id
rest.mode
ドキュメント変換処理の中断
/reset rest.id
リセット
/close rest.id
セッションの終了

例えばlocalhostの8097ポートでドキュメント変換サーバーが動作している場合、変換処理を実行するには、 http://localhost:8097/transcode にアクセスします。

HTTP/RESTインターフェースの機能をフルに活用する場合は、openによりセッションを開始し、各種操作をした後、closeによりセッションを終了することが基本となります。 ただし、transcodeアクションは簡単な変換処理であれば1回のリクエストだけで完結できるようになっています。

リクエストパラメータは、クエリパラメータで送る方法、POSTメソッドのフォームパラメータとして送る方法(application/x-www-form-urlencoded)、 そしてmultipart/form-data形式のファイルとフォームフィールドとして送る方法があります (さらに、ファイルそのものをリクエストボディとして送る方法があります。詳細は仕様書を参照してください)。

application/x-www-form-urlencoded を使用する場合、送信できるデータの最大サイズに制限があります(190KB程度)。 そのため、アプリケーション側から変換対象のドキュメントをCopper PDFに送る場合は、なるべくmultipart/form-dataの使用を推奨します。

リクエストパラメータの意味は次の表の通りです。

パラメータ名 説明
rest.user 認証のためのユーザー名です。
rest.password 認証のためのパスワードです。
rest.timeout セッションの最小持続時間(ミリ秒)です。
rest.httpSession trueを設定すると、クッキーによるHTTPセッション使用します。
rest.id セッションを識別するIDです。クッキーによるHTTPセッション使用する場合は不要です。
rest.uri infoアクションではサーバー情報の識別URI、resultアクションでは結果の識別URI、他のアクションでは次に送るデータの仮想URIを表します。
rest.mimeType 次に送るデータのMIME型です。
rest.encoding 次に送るデータのキャラクタ・エンコーディングです。
rest.resource リソースデータです。これはmaltipart/form-dataのファイルとして送ることもできます。
rest.notFound リソースデータの代わりに、このパラメータにtrueを設定すると、リソースが存在しないことを示します。
rest.async transcodeアクションは通常、変換結果をレスポンスとして返しますが、 このパラメータにtrueを設定すると変換結果をresultアクションにより得ることを前提に、非同期的にドキュメント変換処理を実行します。
rest.requestResource trueを設定すると、サーバーが必要なリソースをクライアントに要求するようになります。 クライアントはリソースの送信要求をmessagesアクションで確認する必要があります。
rest.main 変換対象のメインドキュメントです。これはmaltipart/form-dataのファイルとして送ることもできます。
rest.mainURI サーバーに変換対象のメインドキュメントを取得させる場合のURIです。
rest.wait メッセージの変化があるまでmessagesアクションのレスポンスを保留する場合の最大待ち時間(ミリ秒)です。
rest.mode 1であればなるべく有効なデータを出力して処理を中断し、2であればなるべく直ちに処理を中断します。

なお、各アクションのレスポンスの詳細は仕様書を参照してください。

..3. ウェブブラウザからのアクセス

ウェブブラウザからデータの変換を行う場合、最も簡単な方法は以下のフォームをHTMLファイルとして保存して (キャラクタ・エンコーディングはUTF-8にしてください)、ブラウザで表示し、「変換」ボタンを押すことです。 テキストエリアの内容(Hello world!)がPDF化されます。

<form action="http://localhost:8097/transcode">
  <input type="hidden" name="rest.user" value="user"/>
  <input type="hidden" name="rest.password" value="kappa"/>
  <textarea name="rest.main">
<html><body>Hello world!</body></html>
  </textarea>
  <button type="submit">変換</button>
</form>

アップロードしたファイルを変換することもできます。

<form action="http://localhost:8097/transcode" method="post"
      enctype="multipart/form-data">
  <input type="hidden" name="rest.user" value="user"/>
  <input type="hidden" name="rest.password" value="kappa"/>
  <input type="file" name="rest.main" />
  <button type="submit">変換</button>
</form>

..4. Ruby (httpclient)

※新しく開発されたRubyインターフェースか、実行環境としてJRubyを使う場合はJavaインターフェースを利用した方がより高速です。

Rubyではhttpclientモジュールを使うと簡単です。 以下のサンプルでは、ヒアドキュメントとして記述したHTMLを変換します。

require 'httpclient'

# 変換対象のHTML
data = <<DATA
<html>
<body>
RubyからCopper PDFを使う。
</body>
</html>
DATA

# POSTの準備
client = HTTPClient.new
postdata = {
  "rest.user" => "user",
  "rest.password" => "kappa",
  "rest.main" => data,
}

# 大きなデータを扱えるようにmultipart/formdataで送信(boundaryは適当な文字列)
boundary = "3w48588hfwfdwed2332hdiuj2d3jiuhd32"
puts client.post_content("http://localhost:8097/transcode", postdata,
"content-type" => "multipart/form-data, boundary=#{boundary}")

以下の例では https://copper-pdf.com/ をPDF化します。 前の例では大きなデータをPOSTするため multipart/form-data を使用しましたが、POSTするデータが小さい場合は普通のPOST(application/x-www-form-urlencoded)で構いません。 パラメータの input.include画像等の取得のためにアクセスを許可するアドレスのパターンです。

require 'httpclient'

# POSTの準備
client = HTTPClient.new
postdata = {
  "rest.user" => "user",
  "rest.password" => "kappa",
  "input.include" => "https://copper-pdf.com/**",
  "rest.mainURI" => "https://copper-pdf.com/",
}

# POSTを実行
puts client.post_content("http://localhost:8097/transcode", postdata)

..5. Python (urllib2, urllib)

※新しく開発されたPythonインターフェースか、実行環境としてJythonを使う場合はJavaインターフェースを利用した方がより高速です。

Pythonではurllib2モジュールを使うことができます。 以下のサンプルでは、三重クォートで囲った文字列リテラルとして記述したHTMLを変換します。

# -*- coding: utf_8 -*-
import urllib2

# multipart/form-dataの出力(boundaryは適当な文字列)
boundary = '3w48588hfwfdwed2332hdiuj2d3jiuhd32'
def multipart_formdata(form_dict):
    disposition = 'Content-Disposition: form-data; name="%s"'
    lines = []
    for k, v in form_dict.iteritems():
        lines.append('--' + boundary)
        lines.append(disposition % k)
        lines.append('')
        lines.append(v)
    lines.append("--" + boundary + "--")
    lines.append('')
    value = "\r\n".join(lines)
    return value

# 変換対象のHTML
data = """
<html>
<body>
PythonからCopper PDFを使う。
</body>
</html>
"""

# POSTの実行
params = {'rest.user':'user',
	'rest.password':'kappa',
	'rest.main':data}

url = 'http://localhost:8097/transcode'
req = urllib2.Request(url)
req.add_header("Content-Type",
               "multipart/form-data; boundary=" + boundary)
data = multipart_formdata(params)
f = urllib2.urlopen(req, data)

# 結果表示
print f.read()

以下の例では https://copper-pdf.com をPDF化します。 前の例では大きなデータをPOSTするため multipart/form-data を使用しましたが、POSTするデータが小さい場合は普通のPOST(application/x-www-form-urlencoded)で構いません。 こちらはurllibを使っています。 パラメータの input.include画像等の取得のためにアクセスを許可するアドレスのパターンです。

# -*- coding: utf_8 -*-
import urllib

url = 'http://localhost:8097/transcode'
params = urllib.urlencode({'rest.user':'user',
                           'rest.password':'kappa',
                           'input.include':'https://copper-pdf.com**',
                           'rest.mainURI':'https://copper-pdf.com',
                           })
f = urllib.urlopen(url, params)
print f.read()

..6. C# (.NET WebClient)

※C# / VB.NETではRESTインターフェースを使用する必要はなくなりました。 より高速で高機能な.NETドライバの使用を推奨します。

C#では.NETのWebClientを使うことができます。 以下のサンプルでは、ヒアドキュメントとして記述したHTMLを変換します。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Collections.Specialized;

namespace cti.net
{
    class Program
    {
        static void Main(string[] args)
        {
            string data = @"
<html>
<body>
C#からCopper PDFを使う。
</body>
</html>
            ";

            WebClient client = new WebClient();
            NameValueCollection par = new NameValueCollection();
            par.Add("rest.user", "user");
            par.Add("rest.password", "kappa");
            par.Add("rest.main", data);
            byte[] res = client.UploadValues("http://localhost:8097/transcode", par);
            Console.OpenStandardOutput().Write(res, 0, res.Length);
            client.Dispose();
        }
    }
}

以下の例では https://copper-pdf.com をPDF化します。 パラメータの input.include 画像等の取得のためにアクセスを許可するアドレスのパターンです。

この例では、変換結果をストリームに逐次送り出すため、メモリを節約することができ、巨大なPDFの出力にも対応できます。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Collections.Specialized;

namespace cti.net
{
    class ServerDocument
    {
        static void Main(string[] args)
        {
		    Response.ClearContent();
		    Response.ContentType = "application/pdf";
		    WebClient wc = new WebClient();
		    String uri = "http://localhost:8097/transcode" + // ローカルマシンのCopper PDF
		        "?rest.user=user" +
		        "&rest.password=kappa" +
		        "&input.include=https://copper-pdf.com/**" + // 画像等へのアクセス許可
		        "&rest.mainURI=https://copper-pdf.com/"; // 変換対象アドレス
		        
		    Stream input = wc.OpenRead(uri);
		    Stream output = Console.OpenStandardOutput();
		    byte[] buff = new byte[4096];
		    int len;
		    while ((len = input.Read(buff, 0, buff.Length)) > 0)
		        output.Write(buff, 0, len);
		
		    input.Close();
		    wc.Dispose();
        }
    }
}

..7. ASP.NET (C#, VisualBasic)

※C# / VB.NETではRESTインターフェースを使用する必要はなくなりました。 より高速で高機能な.NETドライバの使用を推奨します。

以下の例では https://copper-pdf.com/ をPDF化します。 それぞれC#とVisualBasicのプログラム例です。 パラメータの input.include 画像等の取得のためにアクセスを許可するアドレスのパターンです。

<%@ Page Language="C#" AutoEventWireup="true" %>
<%@ Import Namespace="System.Net" %>
<%@ Import Namespace="System.IO" %>
<%            
    Response.ClearContent();
	Response.ContentType = "application/pdf";
	
    // ファイル名
    String filename = "FILENAME.pdf";
    Response.AddHeader("Content-Disposition", "attachment; filename=" + filename);

    Response.ContentType = "application/pdf";
    WebClient wc = new WebClient();
    String uri = "http://localhost:8097/transcode" + // ローカルマシンのCopper PDF
        "?rest.user=user" +
        "&rest.password=kappa" +
        "&input.include=https://copper-pdf.com/**" + // 画像等へのアクセス許可
        "&rest.mainURI=https://copper-pdf.com/"; // 変換対象アドレス

    Stream input = wc.OpenRead(uri);
    Stream output = Response.OutputStream;
    byte[] buff = new byte[4096];
    int len;
    while ((len = input.Read(buff, 0, buff.Length)) > 0)
        output.Write(buff, 0, len);

    input.Close();
    wc.Dispose();
%>
<%@ Page Language="VB" %>
<%@ Import Namespace="System.Net" %>
<%@ Import Namespace="System.IO" %>
<%            
    Response.ClearContent()
    Response.ContentType = "application/pdf"
 
    ' ファイル名
    Dim filename As String = "FILENAME.pdf"
    Response.AddHeader("Content-Disposition", "attachment; filename=" + filename)

    Response.ContentType = "application/pdf"
    Dim wc As WebClient = New WebClient()
    ' ローカルマシンのCopper PDF
    Dim uri As String = "http://localhost:8097/transcode"
    uri &= "?rest.user=user"
    uri &= "&rest.password=kappa"
    ' 画像等へのアクセス許可
    uri &= "&input.include=hhttps://copper-pdf.com/**"
    ' 変換対象アドレス
    uri &= "&rest.mainURI=https://copper-pdf.com/"

    Dim input As Stream = wc.OpenRead(uri)
    Dim output As Stream = Response.OutputStream
    Dim buff(4096) As Byte
    Dim len As Integer
    len = input.Read(buff, 0, buff.Length)
    While (len > 0)
        output.Write(buff, 0, len)
        len = input.Read(buff, 0, buff.Length)
    End While
    input.Close()
    wc.Dispose()
%>

..8. 4th Dimension (Internet Commands)

4th Dimension(4D)ではInternet CommandsのTCP/IPコマンドを使うことができます。 以下のサンプルでは、BLOBに格納したHTMLを変換します。

C_TEXT($host;$user;$password;$boundary;$sourceType;$source;$beforeContent;$afterContent;$resultFile;$text)
C_LONGINT($port;$length;$err;$status;$socket;$pos)
C_BLOB($content;$buffer;$data)
C_TIME($doc)

  `Copper PDFサーバー
$host:="localhost"
$port:=8097
$user:="user"
$password:="kappa"

  `変換対象HTML
$sourceType:="text/html"
$source:="<html><head><title>サンプル</title></head><body>4DからCopper PDFを使う。</body></html>"
TEXT TO BLOB($source;$content)  `BLOBに変換

  `結果ファイル名
$resultFile:="Result.pdf"

  `通信開始
$err:=TCP_Open ($host;$port;$socket)
$err:=TCP_State ($socket;$status)

  `リクエスト送信
$boundary:=String(Random)+String(Random)+String(Random)  `マルチパートの境界(ランダムな文字列)
$beforeContent:="---"+$boundary+"\r\n"
$beforeContent:=$beforeContent+"Content-Disposition: form-data; name=\"rest.main\"; filename=\"data.html\"\r\n"
$beforeContent:=$beforeContent+"Content-Type: "+$sourceType+"\r\n\r\n"
$afterContent:="\r\n---"+$boundary+"--\r\n"
$length:=Length($beforeContent)+BLOB size($content)+Length($afterContent)

$err:=TCP_Send ($socket;"POST /transcode?rest.user="+$user+"&rest.password="+$password+" HTTP/1.0\r\n")  `keep-aliveとchunkedを使わないためHTTP/1.0で接続する
$err:=TCP_Send ($socket;"Host: "+$host+"\r\n")
$err:=TCP_Send ($socket;"Content-Length: "+String($length)+"\r\n")
$err:=TCP_Send ($socket;"Content-Type: multipart/form-data; boundary=-"+$boundary+"\r\n")
$err:=TCP_Send ($socket;"\r\n")

$err:=TCP_Send ($socket;$beforeContent)
$err:=TCP_SendBLOB ($socket;$content)
$err:=TCP_Send ($socket;$afterContent)

  `レスポンス受信
Repeat 
	SET BLOB SIZE($buffer;0)
	$err:=TCP_ReceiveBLOB ($socket;$buffer)
	$err:=TCP_State ($socket;$status)
	$bufferLen:=BLOB size($buffer)
	$dataLen:=BLOB size($data)
	INSERT IN BLOB($data;$dataLen;$bufferLen)
	COPY BLOB($buffer;$data;0;$dataLen;$bufferLen)
Until (($status=0) | ($err#0))

$err:=TCP_State ($socket;$state)
$err:=TCP_Close ($socket)

  `ヘッダの除去
$text:=BLOB to text($data;Mac C string )
$pos:=Position("\r\n\r\n";$text)
DELETE FROM BLOB($data;0;$pos+3)  `先頭から最初の空行までの間を除去する

  `ファイルの出力
$doc:=Create document($resultFile)
CLOSE DOCUMENT($doc)
BLOB TO DOCUMENT($resultFile;$data)

以下の例では http://print.cssj.jp/ をPDF化します。 パラメータの input.include 画像等の取得のためにアクセスを許可するアドレスのパターンです。

C_TEXT($host;$user;$password;$include;$uri;$query;$resultFile;$text)
C_LONGINT($port;$err;$status;$socket;$pos)
C_BLOB($content;$buffer;$data)
C_TIME($doc)

  `Copper PDFサーバー
$host:="neko"
$port:=8097
$user:="user"
$password:="localhost"

  `変換対象アドレス
$include:="hhttps://copper-pdf.com/**"
$uri:="https://copper-pdf.com/"

  `結果ファイル名
$resultFile:="Result.pdf"

  `通信開始
$err:=TCP_Open ($host;$port;$socket)
$err:=TCP_State ($socket;$status)

  `リクエスト送信
$query:="rest.user="+$user+"&rest.password="+$password+
"&input.include="+$include+"&rest.mainURI="+$uri
$err:=TCP_Send ($socket;"GET /transcode?"+$query+" HTTP/1.0\r\n")  `keep-aliveとchunkedを使わないためHTTP/1.0で接続する
$err:=TCP_Send ($socket;"Host: "+$host+"\r\n")
$err:=TCP_Send ($socket;"\r\n")

$err:=TCP_Send ($socket;$beforeContent)
$err:=TCP_SendBLOB ($socket;$content)
$err:=TCP_Send ($socket;$afterContent)

  `レスポンス受信
Repeat 
	SET BLOB SIZE($buffer;0)
	$err:=TCP_ReceiveBLOB ($socket;$buffer)
	$err:=TCP_State ($socket;$status)
	$bufferLen:=BLOB size($buffer)
	$dataLen:=BLOB size($data)
	INSERT IN BLOB($data;$dataLen;$bufferLen)
	COPY BLOB($buffer;$data;0;$dataLen;$bufferLen)
Until (($status=0) | ($err#0))

$err:=TCP_State ($socket;$state)
$err:=TCP_Close ($socket)

  `ヘッダの除去
$text:=BLOB to text($data;Mac C string )
$pos:=Position("\r\n\r\n";$text)
DELETE FROM BLOB($data;0;$pos+3)  `先頭から最初の空行までの間を除去する

  `ファイルの出力
$doc:=Create document($resultFile)
CLOSE DOCUMENT($doc)
BLOB TO DOCUMENT($resultFile;$data)

..9. その他のサンプルについて

HTTP/RESTインターフェースは、さらに多くの種類の開発環境から、様々な方法で利用することできます。 最新情報はCopper PDFのサイト(https://copper-pdf.com/)で提供しています。


目次↑
Copper PDF ©2012 Zamasoft. All rights reserved.