Privet 是雲端服務使用的 Cloud Device Local Discovery API。本文件內容分為以下章節:
1. 引言
雲端連線裝置有許多優點。只要使用線上轉換服務,即使裝置未連上網路,也能使用主機工作佇列,並可隨時隨地存取。然而,由於許多使用者都可存取許多雲端裝置,因此我們需要提供一種方法,以根據位置尋找最近的裝置。Privet 通訊協定的目的是將雲端裝置的彈性與適當的本機探索機制繫結在一起,方便在新環境中輕鬆探索裝置。
這個通訊協定的目標如下:- 在本機搜尋雲端裝置
- 透過雲端服務註冊雲端裝置
- 將已註冊的裝置與雲端代表建立關聯
- 啟用離線功能
- 簡化導入方式,讓小裝置能輕鬆使用
Privet 通訊協定由 2 個主要部分組成:探索與 API。Discovery 是用於尋找區域網路中的裝置,而 API 可用來取得裝置的相關資訊並執行某些動作。在本文件中,裝置是指導入 Privet 通訊協定的雲端連線裝置。
2. Discovery
Discovery 是採用零配置 (mDNS 和 DNS-SD) 的通訊協定。裝置「必須」導入 IPv4 連結本機位址。裝置「必須」遵循 mDNS 和 DNS-SD 規格。
- http://www.rfc-editor.org/rfc/rfc3927.txt (IPv4 Link-local)
- http://www.rfc-editor.org/rfc/rfc4862.txt (IPv6 Link-local)
- http://www.rfc-editor.org/rfc/rfc6762.txt (mDNS)
- http://www.rfc-editor.org/rfc/rfc6763.txt (DNS-SD)
裝置必須依照上述規格執行名稱衝突解析。
2.1. 服務類型
DNS 服務探索會針對服務類型使用下列格式:_applicationprotocol._transportprotocol。針對 Privet 通訊協定,DNS-SD 的服務類型應為:_privet._TCP
裝置也可以實作其他服務類型。建議您為裝置實作的所有服務類型使用相同的服務執行個體名稱。舉例來說,印表機可以實作「Printer XYZ._privet._TCP」和「Printer XYZ._printer._TCP」服務。可簡化使用者的設定。不過,Privet 用戶端只會搜尋「quot;_privet._TCP"」。
除了主要服務類型以外,裝置也「必須」透過相應的子類型宣傳 PTR 記錄 (請參閱 DNS-SD 規格:「&7t1」)。選擇性執行個體列舉 (子類型))。格式如下: _<subtype>._sub._privet._TCP
目前唯一支援的裝置子類型是印表機。因此,所有印表機均「必須」宣傳兩項 PTR 記錄:
- _privet._helpcenter.local。
- _printer._sub._privet._TCP.local。
2.2. TXT 記錄
「DNS 服務探索」定義了在 TXT 記錄中新增服務選用資訊的欄位。TXT 記錄包含鍵/值組合。每個鍵/值組合則會從長度位元組開始,後面接著最多 255 個位元組的文字。鍵是第一個「=」字元之前的文字,值是第一個「=」字元之後的文字。根據規格,記錄中沒有任何值,在此情況下,就不會有「=」字元或「=」字元後面的文字。(請參閱 DNS-SD 規格:"6.1. DNS TXT 記錄的一般格式規則](DNS DNS 記錄格式和 &602.DNS-SD TXT 記錄大小” (建議長度)。
Privet 要求裝置在 TXT 記錄中傳送下列鍵/值組合。鍵/值字串不區分大小寫,例如「quot;CS=online"」和「quot;cs=online」。TXT 記錄中的資訊必須與透過 /info API 存取的資訊相同 (請參閱 4.1. API 部分)。
建議將 TXT 記錄大小保持在 512 個位元組以下。
2.2.1. txt
TXT 結構版本。txtvers 必須是 TXT 結構的第一個記錄。目前唯一支援的版本為 1。
txtvers=1
2.2.2. 數量
提供使用者可理解的裝置名稱。例如:
ty=Google Cloud Ready Printer Model XYZ
2.2.3. 記事 (選填)
提供使用者可理解的裝置名稱。例如:
note=1st floor lobby printer
注意:此為選用鍵,可能會略過。不過如有設定,使用者「必須」能修改這個值。註冊裝置時,「必須」使用相同的說明。
2.2.4。網址
此裝置連上的伺服器網址 (包括通訊協定)。例如:
url=https://www.google.com/cloudprint
2.2.5. 類型
裝置支援的裝置子類型清單 (以半形逗號分隔)。格式為:"type=_subtype1,_subtype2"。目前唯一支援的裝置子類型為 printer。
type=printer
列出的每個子類型應使用對應的 PTR 記錄進行宣傳。每個支援的服務子類型都應有對應的項目。服務子類型名稱 (<subtype>._sub._privet._TCP) 應與這裡的裝置類型相同。
2.2.6. ID
裝置 ID。如果裝置尚未註冊,您應該會看到這組金鑰,但值應為空白。例如:
id=11111111-2222-3333-4444-555555555555 id=
2.2.7. cs
指出裝置目前的連線狀態。這個規格中定義了四個可能的值。
- 「online」是指裝置目前已連結至雲端。
- 「離線」表示裝置位於區域網路上,但無法與伺服器通訊。
- 「連線中」表示裝置正在執行啟動程序,而且尚未完全上線。
- 「尚未設定」表示裝置的網際網路存取權尚未設定。這個值目前並未使用,但在日後的規格版本中可能很有用。
- cs=online
- cs=離線
- cs=connecting
如果裝置已透過雲端註冊,裝置啟動時應檢查伺服器的連線狀態,以偵測連線狀態 (例如呼叫 Cloud API 以取得裝置設定)。裝置可以透過通知管道 (例如 XMPP) 連線狀態報告這個值。裝置啟動時,未註冊的裝置可能會連線偵測網域的連線狀態,例如偵測雲端列印裝置的 www.google.com。
3. 公告事項
裝置啟動、關機或狀態變更時,裝置「必須」遵循 mDNS 規格中所述的公告步驟。應至少傳送對應公告兩次 (間隔至少一秒)。
3.1. 啟動
在裝置啟動時,必須「按照 mDNS 規格所述執行探測和公告步驟。在這種情況下,您必須傳送 SRV、PTR 和 TXT 記錄。因此,建議您盡可能將所有記錄分成一個 DNS 回應。如果沒有,則建議您採用以下順序:SRV、PTR、TXT 記錄。
3.2. 關機
裝置關閉時,應盡可能傳送「goodbye 封包」 (TTL)0 (如 mDNS 說明文件中所述)。
3.3. 更新
當 TXT 中所述的資訊有所變更時,裝置「必須」傳送更新公告。在此情況下,系統只會傳送新的 TXT 記錄。舉例來說,裝置註冊完成後,「必須」傳送包含新裝置 ID 的更新公告。
4. API
找到雲端裝置後,即可透過區域網路直接在裝置上啟用用戶端通訊功能。所有 API 均採用 HTTP 1.1。資料格式為 JSON 格式。API 要求可以是 GET 或 POST 要求。
每個要求都「必須是」有效的 X-Privet-Token" 標頭。「只有」要求可以擁有空白的「X-Privet-Token」標頭。這是 /privet/info 要求 (請注意,標頭「必須」存在)。如果缺少「X-Privet-Token」標頭,裝置「必須」回應下列 HTTP 400 錯誤:
HTTP/1.1 400 Missing X-Privet-Token header.
如果「X-Privet-Token」為空白或無效,裝置「必須」傳回「無效 X-Privet-Token 錯誤」;(invalid_x_privet_token,詳情請參閱「錯誤」一節)。唯一的例外是 /info API。如要進一步瞭解這項作業完成的原因,以及符記的產生方式,請參閱附錄 A:XSSI 和 XSRF 的攻擊與預防功能。
如果要求的 API 不存在或不受支援,裝置「必須」傳回 HTTP 404 錯誤。
4.1. API 適用性
在公開任何 API (包括 /info API) 之前,裝置「必須」與伺服器聯絡,以檢查本機設定。重新啟動時,「必須」保留本機設定。如果伺服器無法使用,則應使用最後已知的本機設定。如果裝置尚未註冊,則應採用預設設定。
雲端列印印表機「必須」按照下列步驟操作,才能註冊、接收及更新本機設定。
4.1.1. 註冊
裝置註冊時,「必須」指定「local_settings」參數,如下所示:
{ "current": { "local_discovery": true, "access_token_enabled": true, "printer/local_printing_enabled": true, "printer/conversion_printing_enabled": true, "xmpp_timeout_value": 300 } }可以調整下列設定:
值名稱 | 值類型 | 說明 |
---|---|---|
區域探索 | 布林值 | 指出是否允許本機探索功能。如果設為「false」,則必須停用所有本機 API (包括 /info) 和 DNS-SD 探索。根據預設,新註冊的裝置應傳送「true」。 |
啟用存取權杖 | 布林值 (選填) | 指出是否應在區域網路上公開 /accesstoken API。根據預設,這個值應為「true」。 |
印表機/local_printing_enabled | 布林值 (選填) | 指出是否應在本機區域公開本機本機列印功能 (/printer/createjob、/printer/submitdoc、/printer/jobstate)。根據預設,這個值應為「true」。 |
印表機/轉換_列印_已啟用 | 布林值 (選填) | 表示本機列印是否要將工作傳送至伺服器進行轉換。只有在已啟用本機列印功能時,您才需要使用這個選項。 |
xmpp_timeout_value | int (選填) | 表示 XMPP 管道連線偵測 (ping) 之間的秒數。根據預設,這個值必須是 300 (5 分鐘) 或以上。 |
重要事項:如果沒有任何選用值,表示裝置完全不支援對應的功能。
4.1.2. 啟動
裝置啟動時,應與伺服器聯絡,確認可在本機網路上公開哪些 API。如果印表機是連線至雲端列印服務,則應呼叫:
/cloudprint/printer?printerid=<printer_id>或
/cloudprint/list
/preferences/printer 的優先順序高於 /patch/list,但兩者皆有效。
這個 API 會傳回目前的裝置參數,包括本機 API 的設定。伺服器傳送的格式如下:
"local_settings": { "current": { "local_discovery": true, "access_token_enabled": true, "printer/local_printing_enabled": true, "printer/conversion_printing_enabled": true, "xmpp_timeout_value": 300 }, "pending": { "local_discovery": true, "access_token_enabled": true, "printer/local_printing_enabled": false, "printer/conversion_printing_enabled": false, "xmpp_timeout_value": 500 } }
"current" 物件代表目前有效的設定。
"pending" 物件代表應套用至裝置的設定 (此物件可能遺失)。
當裝置看到「待處理」設定時,「必須」更新其狀態 (詳情請見下方)。
4.1.3. 更新
如果如果需要更新設定,系統會將 XMPP 通知傳送到裝置上。通知的格式如下:
<device_id>/update_settings
收到這類通知後,裝置「必須」查詢伺服器來取得最新的設定。 雲端列印裝置「必須」使用:
/cloudprint/printer?printerid=<printer_id>
當裝置從啟動時,或在通知中收到「/pending/printer API」區段時,「必須」更新內部狀態,以便記住新設定。必須「呼叫伺服器 API」確認新設定。如果是雲端印表機,裝置「必須」呼叫 /ecomm/update API,並使用註冊程序中的 "local_settings" 參數。
重新連線至 XMPP 管道時,裝置「必須」呼叫 /ecomm/printer API,檢查本機設定自上次以來是否變更。
4.1.3.1。本機設定待處理
"local_settings" 裝置用來呼叫伺服器 API 的參數「必須」包含「quot;pending"」區段。
4.1.3.2. 本機設定 (目前)
只有裝置可以變更「本機設定」的「目前」部分。 其他人都會變更「待處理」部分,然後等待裝置將變更套用到「目前」部分。
4.1.4. 離線
如果啟動期間無法與伺服器連線,裝置在通知後「必須」使用最後已知的本機設定。
4.1.5。從服務中刪除裝置
如果裝置已從服務中刪除 (例如 GCP),系統會向裝置傳送 XMPP 通知。通知的格式如下:
<device_id>/delete
收到這類通知後,裝置「必須」前往伺服器查看狀態。雲端列印裝置「必須」使用:
/cloudprint/printer?printerid=<printer_id>
裝置「必須」收到成功的 HTTP 答案,且成功=成功:沒有裝置/印表機的說明。這表示裝置已從伺服器中移除,裝置「必須」清除憑證,並前往預設的原廠設定模式。
每當裝置收到回覆,指出裝置因 /ecomm/printer API 而遭到刪除 (啟動、更新設定通知、每日連線偵測 (ping),裝置「必須」刪除憑證,並進入預設模式。
4.2. /privet/info API
info API 為 MANDATORY,且「必須」在每個裝置上實作。這是「/privet/info」的 HTTP GET 要求:網址:GET /privet/info HTTP/1.1
Info API 會傳回所支援的裝置和功能基本資訊。這個 API 「不得」變更裝置狀態或執行任何動作,因為容易遭受 XSRF 攻擊。 只有 ONLY API 才能使用空白的「X-Privet-Token」標頭。用戶端應呼叫 /privet/info API,並加上「X-Privet-Token」的標頭,並將標頭設為 X-Privet-Token: ""
探索時,Info API 「必須」傳回與 TXT 記錄中的資料一致。
4.2.1. 輸入
/privet/info API 不含任何輸入參數。
4.2.2. Return 鍵
/privet/info API 會傳回關於裝置和支援功能的基本資訊。
[TXT] 欄代表 DNS-SD TXT 記錄中的對應欄位。
值名稱 | 值類型 | 說明 | TXT |
---|---|---|---|
version | string | 支援的最高 API 版本 (major.minor),目前為 1.0 | |
名稱 | string | 使用者可理解的裝置名稱。 | ty |
說明 | string | (選用) 裝置說明。可由使用者修改。 | 記事 |
url | string | 這部裝置所通訊伺服器的網址。網址「必須」包含通訊協定規格,例如:https://www.google.com/patch。 | url |
類型 | 字串清單 | 支援的裝置類型清單。 | 類型 |
id | string | 裝置 ID;如果裝置尚未註冊,則為空白。 | id |
device_state [裝置狀態] | string | 裝置狀態。 「閒置」是指裝置已準備就緒 「處理中」表示裝置忙碌中,且功能可能受限一段時間 已停止表示裝置無法運作,且需要使用者介入 | |
連線狀態 | string | 伺服器連線狀態 (base_url)
線上 - 可用連線 離線 - 沒有連線 連線 - 執行啟動步驟 未設定 - 尚未設定連線 已註冊的裝置可依據通知管道的狀態 (例如 XMPP 連線狀態) 回報連線狀態。 | cs |
製造商 | string | 裝置製造商名稱 | |
模式 | string | 裝置型號 | |
序號 | string | 裝置專屬 ID。在這個規格中,這必須是 UUID。(GCP 1.1 規格)
(選用) 強烈建議您在任何地方使用相同的序號 ID,以便不同用戶端可識別相同的裝置。舉例來說,實作 IPP 的印表機可在「printer-device-id」欄位中使用這組序號。 | |
韌體 | string | 裝置韌體版本 | |
運作時間 | int | 裝置啟動的秒數。 | |
setup_url | string | (選填) 含有設定操作說明的網頁網址 (包括通訊協定) | |
support_url | string | (選填) 含有支援服務網址的網頁網址 (包括通訊協定) 和常見問題資訊 | |
update_url | string | (選填) 含有更新韌體操作說明的網頁網址 (包括通訊協定) | |
x-privet-token | string | 必須傳遞至所有 API 的 X-Privet-Token 標頭值,以避免 XSSI 和 XSRF 攻擊。詳情請參閱 6.1。 | |
api | API 說明 | 支援的 API 清單 (如下所述) | |
semantic_state (語意狀態) | JSON | (選用) 裝置的語意狀態,採 CloudDeviceState 格式。 |
api - 包含本機網路可用 API 清單的 JSON 清單。請注意,並非所有 API 都透過區域網路提供。舉例來說,新的連接裝置應僅支援 /register API:
"api": [ "/privet/register", ]裝置註冊完成後,裝置就「必須」停止支援 /register API。裝置也應向服務確認,以提供可透過區域網路公開的 API。例如:
"api": [ "/privet/accesstoken", "/privet/capabilities", "/privet/printer/submitdoc", ]
目前可使用下列 API:
- /privet/enroll:透過區域網路註冊裝置的 API。(詳情請參閱 /privet/register API)。成功在雲端註冊裝置後,就必須先隱藏這個 API。
- /privet/accesstoken - 向裝置要求存取權杖的 API (詳情請參閱 /privet/accesstoken API)。
- /privet/capabilities - 用於擷取裝置功能的 API (詳情請參閱「/privet/capabilities API」)。
- /privet/printer/* - 特定裝置類型「printer」的 API,詳情請參閱印表機專用 API。
{ "version": "1.0", "name": "Gene’s printer", "description": "Printer connected through Chrome connector", "url": "https://www.google.com/cloudprint", "type": [ "printer" ], "id": "11111111-2222-3333-4444-555555555555", "device_state": "idle", "connection_state": "online", "manufacturer": "Google", "model": "Google Chrome", "serial_number": "1111-22222-33333-4444", "firmware": "24.0.1312.52", "uptime": 600, "setup_url": "http://support.google.com/cloudprint/answer/1686197/?hl=en", "support_url": "http://support.google.com/cloudprint/?hl=en", "update_url": "http://support.google.com/cloudprint/?hl=en", "x-privet-token": "AIp06DjQd80yMoGYuGmT_VDAApuBZbInsQ:1358377509659", "api": [ "/privet/accesstoken", "/privet/capabilities", "/privet/printer/submitdoc", ] }以下是輸出墨水的印表機「/privet/info」回應範例 (請注意 semantic_state 欄位):
{ "version": "1.0", "name": "Gene’s printer", "description": "Printer connected through Chrome connector", "url": "https://www.google.com/cloudprint", "type": [ "printer" ], "id": "11111111-2222-3333-4444-555555555555", "device_state": "stopped", "connection_state": "online", "manufacturer": "Google", "model": "Google Chrome", "serial_number": "1111-22222-33333-4444", "firmware": "24.0.1312.52", "uptime": 600, "setup_url": "http://support.google.com/cloudprint/answer/1686197/?hl=en", "support_url": "http://support.google.com/cloudprint/?hl=en", "update_url": "http://support.google.com/cloudprint/?hl=en", "x-privet-token": "AIp06DjQd80yMoGYuGmT_VDAApuBZbInsQ:1358377509659", "api": [ "/privet/accesstoken", "/privet/capabilities", "/privet/printer/submitdoc", ], "semantic_state": { "version": "1.0", "printer": { "state": "STOPPED", "marker_state": { "item": [ { "vendor_id": "ink", "state": "EXHAUSTED", "level_percent": 0 } ] } } } }
4.2.3. 錯誤
如果缺少 X-Privet-Token 標頭,/privet/info API 「必須」傳回錯誤。「必須」是 HTTP 400 錯誤:
HTTP/1.1 400 Missing X-Privet-Token header.
4.3. /privet/註冊 API
/privet/register API 為「選用」。這是 HTTP POST 要求,/privet/register API 必須檢查有效的 X-Privet-Token 標頭。裝置「必須」在「/privet/register」中導入這個 API:
POST /privet/register?action=start&user=user@domain.com HTTP/1.1 POST /privet/register?action=complete&user=user@domain.com HTTP/1.1
裝置目前必須允許匿名註冊,才應該公開 /privet/register API。例如:
- 如果裝置處於開啟狀態 (或按一下裝置上的特殊按鈕),但尚未註冊,則應顯示 /privet/register API,允許本機網路的使用者聲明印表機的擁有權。
- 註冊完成後,裝置應停止公開 /privet/register API,以免區域網路的其他使用者收回裝置。
- 部分裝置可能採用不同的註冊方式,且完全不公開 /privet/register API (例如 Chrome 雲端列印連接器)。
註冊程序包含 3 個步驟 (請參閱「雲端列印」的匿名註冊)。
- 啟動匿名註冊程序。
- 用戶端會呼叫 /privet/register API,以啟動這項程序。裝置可能會等待使用者確認。
- 取得聲明憑證。
用戶端會輪詢裝置,以便確認裝置何時可以繼續執行。裝置準備就緒後,會向伺服器傳送請求,擷取註冊權杖和註冊網址。已收到的權杖和網址「必須」傳回用戶端。在這個步驟中,如果裝置收到另一個用於初始化的呼叫,則應完成以下動作:
- 如果這同位使用者開始註冊,請將所有先前的資料 (如果有的話) 捨棄,並開始進行新的註冊程序。
- 如果不同的使用者 - 傳回 device_繁忙錯誤和 30 秒逾時。
完成註冊程序。
在用戶端認領裝置後,用戶端應通知裝置完成註冊。註冊程序完成後,裝置應傳送更新公告,包括新取得的裝置 ID。
注意:裝置處理 /privet/register API 呼叫時,可能不會同時處理其他 /privet/register API 呼叫。裝置「必須」傳回 device_繁忙的錯誤和 30 秒逾時。
我們強烈建議使用者在裝置上確認註冊。如果已實作,裝置收到「/privet/register?action=start API 呼叫」後,「必須」等候使用者確認。用戶端會呼叫 /privet/register?action=getClaimToken API,確認使用者何時確認是否可用,以及憑證附加資訊可用。如果使用者取消裝置上的註冊 (例如按下「取消」按鈕),則「必須」傳回 user_cancel 錯誤。如果使用者未在特定時間範圍內確認註冊,就「必須」傳回確認_錯誤。詳情請參閱預設部分。
4.3.1. 輸入
/privet/register API 包含下列輸入參數:名稱 | 值 |
---|---|
動作 | 可以是下列任一項目:
開始 - 開始註冊程序 getClaimToken - 擷取裝置的聲明憑證 取消 - 取消註冊程序 完成 - 完成註冊程序 |
使用者 | 領取這部裝置的使用者電子郵件地址。 |
裝置「必須」檢查所有動作的電子郵件地址 (開始、getClaimToken、取消、完成) 是否相符。
4.3.2. Return 鍵
/privet/register API 會傳回下列資料:值名稱 | 值類型 | 說明 |
---|---|---|
動作 | string | 與輸入參數相同。 |
使用者 | 字串 (選填) | 與輸入參數中的使用者相同 (如果輸入內容中省略的話)。 |
驗證權杖 | 字串 (選填) | 註冊權杖 (「comClaimToken」的必填回覆、「start」、「complete」或「cancel」的「省略」)。 |
claim_url | 字串 (選填) | 註冊網址 (「getClaimToken」的必填回應;「comtstart」、「quot;complete"」、「&cancel;」「取消」)使用雲端印表機時,伺服器必須是從伺服器接收到的「complete_ invitations_url」。 |
Auto_claim_url | 字串 (選填) | 註冊網址 (「getClaimToken」的必填回應;「comtstart」、「quot;complete"」、「&cancel;」「取消」)使用雲端印表機時,伺服器必須是從伺服器接收的「quo_ invitations_url」。 |
device_id | 字串 (選填) | {0/} |
裝置「必須」在註冊完成後傳回 /privet/info API 回應中的裝置 ID。
範例 1:
{ "action": "start", "user": "user@domain.com", }
範例 2:
{ "action": "getClaimToken", "user": "user@domain.com", "token": "AAA111222333444555666777", "claim_url": "https://domain.com/SoMeUrL", }
範例 3:
{ "action": "complete", "user": "user@domain.com", "device_id": "11111111-2222-3333-4444-555555555555", }
4.3.3. 錯誤
/privet/register API 可能會傳回下列錯誤 (詳情請參閱「錯誤」一節):錯誤 | 說明 |
---|---|
裝置忙碌 | 裝置忙碌中,無法執行要求的動作。請於逾時後重試。 |
pending_user_action | 為因應 "getClaimToken"; 這個錯誤,代表裝置仍處於待使用者確認的狀態,因此逾時後應重試。 |
user_cancel | 使用者明確取消了註冊程序。 |
確認時間 | 使用者確認逾時, |
無效操作 | 系統會呼叫無效動作。例如,如果用戶端在呼叫 action=start 和 action=getClaimToken 之前呼叫 action=complete。 |
無效參數 | 要求中指定的參數無效。(為避免日後相容性,請放心忽略不明參數)。舉例來說,如果用戶端呼叫 action=unknown 或 user=,則會傳回此值。 |
device_config_error | 裝置端的日期/時間 (或其他某些設定) 有誤。使用者必須前往裝置內部網站及調整裝置設定。 |
離線 | 裝置目前處於離線狀態,無法與伺服器通訊。 |
server_error | 註冊過程中發生伺服器錯誤。 |
無效_權杖_權杖 | X-Privet-Token 在要求中無效或空白。 |
成功完成註冊後,裝置「必須」停止公開 /privet/register API。如果裝置未公開 /privet/register API,則「必須」傳回 HTTP 404 錯誤。因此,如果裝置已註冊,這個 API 必須呼叫 404。如果缺少 X-Privet-Token 標頭,則裝置「必須」傳回 HTTP 400 錯誤。
4.4. /privet/accesstoken API
/privet/accesstoken API 為選用項目。這是 HTTP GET 要求。/privet/accesstoken API 必須檢查有效的「X-Privet-Token"」標頭。裝置「必須」在「/privet/accesstoken" 網址」中導入這個 API:GET /privet/accesstoken HTTP/1.1
裝置收到 /accesstoken API 呼叫時,應呼叫伺服器來擷取指定使用者的存取權杖,並將權杖傳回用戶端。接著,用戶端會透過存取權杖透過雲端存取這部裝置。
Google 雲端列印裝置「必須」呼叫下列 API:
/cloudprint/proximitytoken並傳遞本機 API 的「printeridoutlinelt;printer_id>"」和「user"」參數。如果成功,伺服器回應會包含以下物件:
"proximity_token": { "user": "user@domain.com", "token": "AAA111222333444555666777", "expires_in": 600 }雲端列印裝置「必須」在回應中回應本機 /privet/accesstoken API 呼叫,並將「quot; nearby_token"」物件的值傳送。如果裝置可以傳送「所有」參數 (包括此規格中未提及的參數),這種方式會更有利於未來發展。
4.4.1. 輸入
/privet/accesstoken API 包含下列輸入參數:名稱 | 值 |
---|---|
使用者 | 要使用這個存取權杖的使用者的電子郵件。在要求中可能為空白。 |
4.4.2. Return 鍵
/privet/accesstoken API 會傳回下列資料:值名稱 | 值類型 | 說明 |
---|---|---|
驗證權杖 | string | 伺服器傳回的存取權杖 |
使用者 | string | 與輸入參數相同。 |
到期 | int | 這個權杖過期前的秒數。已從伺服器接收並傳回這個回應。 |
示例:
{ "token": "AAA111222333444555666777", "user": "user@domain.com", "expires_in": 600 }
4.4.3. 錯誤
/privet/accesstoken API 可能會傳回下列錯誤 (詳情請參閱「錯誤」一節):錯誤 | 說明 |
---|---|
離線 | 裝置目前處於離線狀態,無法與伺服器通訊。 |
access_denied | 權限不足。存取遭拒。伺服器明確拒絕要求時,裝置應傳回這個錯誤。 |
無效參數 | 要求中指定的參數無效。(為避免日後相容性,請放心忽略不明參數)。例如,如果用戶端名為 /accesstoken?user= 或 /accesstoken。 |
server_error | 伺服器錯誤。 |
無效_權杖_權杖 | X-Privet-Token 在要求中無效或空白。 |
如果裝置未公開 /privet/accesstoken API,則「必須」傳回 HTTP 404 錯誤。如果缺少 X-Privet-Token 標頭,則裝置「必須」傳回 HTTP 400 錯誤。
4.5. /privet/功能 API
/privet/capabilities API 為「選用」。這是 HTTP GET 要求。/privet/capabilities API 必須檢查有效的「X-Privet-Token"」標頭。裝置「必須」在「/privet/功能」中導入這個 API;網址:GET /privet/capabilities HTTP/1.1當裝置收到 /功能 API 呼叫時,如果裝置可執行,則應與伺服器聯絡以取得更新功能。舉例來說,如果印表機支援透過雲端列印服務,將列印工作 (在本機接收) 發布至本身,則應該會傳回 Cloud 雲端列印服務傳回的功能。在此情況下,雲端列印在將工作傳送至印表機前可能執行的新增功能,可能會改變原始印表機功能。最常見的情況是支援的文件類型清單。如果印表機處於離線狀態,應傳回支援的文件類型。不過,如果印表機已在線上註冊,並已註冊雲端列印功能,則應用程式只能傳回「*/*」做為支援的類型。在這種情況下,雲端列印服務會執行必要的轉換。如果是離線列印,印表機「必須」支援至少「圖片/pwg 光柵」格式。
4.5.1. 輸入
/privet/capabilities API 包含下列輸入參數:名稱 | 值 |
---|---|
離線 | (選用) 只能設為「離線=1」。在這種情況下,裝置應傳回離線使用功能 (如果與「線上」功能不同)。 |
4.5.2. Return 鍵
/privet/capabilities API 會以 Cloud 裝置說明 (CDD) JSON 格式傳回裝置功能 (詳情請參閱 CDD 文件)。印表機至少「必須」傳回支援的類型清單。舉例來說,目前可連上網路的 CloudReady 印表機可能會傳回類似下方的內容 (至少):{ "version": "1.0", "printer": { "supported_content_type": [ { "content_type": "application/pdf", "min_version": "1.4" }, { "content_type": "image/pwg-raster" }, { "content_type": "image/jpeg" }, { "content_type": "*/*" } ] } }當伺服器與伺服器中斷連線後,可能會傳回:
{ "version": "1.0", "printer": { "supported_content_type": [ { "content_type": "application/pdf", "min_version": "1.4" }, { "content_type": "image/pwg-raster" }, { "content_type": "image/jpeg" } ] } }
注意:印表機會以順序表示支援的內容類型優先順序。舉例來說,在上面的範例中,印表機會指定使用「application/pdf」的形式,而非「image/pwg-raster"」和「image/jpeg」。用戶端應盡可能優先處理印表機的優先順序 (詳情請參閱 CDD 文件)。
4.5.3. 錯誤
/privet/capabilities API 可能會傳回下列錯誤 (詳情請參閱「錯誤」一節):錯誤 | 說明 |
---|---|
無效_權杖_權杖 | X-Privet-Token 在要求中無效或空白。 |
如果裝置未公開 /privet/capabilities API,則「必須」傳回 HTTP 404 錯誤。如果缺少 X-Privet-Token 標頭,則裝置「必須」傳回 HTTP 400 錯誤。
4.6. 錯誤
從上述 API 傳回下列格式的錯誤:值名稱 | 值類型 | 說明 |
---|---|---|
錯誤 | string | 錯誤類型 (依 API 定義) |
說明 | 字串 (選填) | 使用者可理解的錯誤說明。 |
server_api | 字串 (選填) | 如果伺服器發生錯誤,這個欄位會包含失敗的伺服器伺服器 API。 |
server_code [伺服器代碼] | int (選填) | 如果發生伺服器錯誤,這個欄位會包含伺服器傳回的錯誤代碼。 |
server_http_code | int (選填) | 如果是伺服器 HTTP 錯誤,這個欄位會包含傳回的 HTTP 錯誤代碼伺服器。 |
timeout | int (選填) | 用戶端重試前的秒數 (僅適用於可復原的錯誤)。用戶端「必須」將這個值中的實際逾時隨機設為 + 20% 的值。 |
如果缺少 X-Privet-Token 標頭,所有 API 都「必須」傳回 HTTP 400 錯誤。
HTTP/1.1 400 缺少 X-Privet-Token 標頭。
範例 1:
{ "error": "server_error", "description": "Service unavailable", "server_api": "/submit", "server_http_code": 503 }
範例 2:
{ "error": "printer_busy", "description": "Printer is currently printing other job", "timeout": 15 }
5. 印表機 API
這個通訊協定支援的裝置類型之一是印表機。支援這個類型的裝置可能會實作印表機專用的特定功能。在理想情況下,列印成雲端列印的印表機會通過雲端列印伺服器:
![](https://developers.google.cn/cloud-print/images/privet_image07.jpg?authuser=6&hl=zh-tw)
在某些情況下,用戶端可能需要在本機傳送文件。如果用戶端沒有 Google ID,或是無法與 Google 雲端列印伺服器通訊,可能會需要用到這個值。在這種情況下,列印工作會在本機傳送至印表機。印表機會使用雲端列印服務將工作排入佇列和轉換。透過雲端提交列印工作後,該印表機會將工作重新張貼到雲端列印服務,然後再提出申請。如此一來,您就可以在服務條款 (轉換) 和列印工作管理/追蹤方面享有靈活的使用者體驗。
![](https://developers.google.cn/cloud-print/images/privet_image08.jpg?authuser=6&hl=zh-tw)
由於雲端列印服務導入了轉換功能,因此印表機應「支援」所有支援的內容類型清單格式 (&*t*/*")。
{ "version": "1.0", "printer": { "supported_content_type": [ { "content_type": "image/pwg-raster" }, { "content_type": "*/*" } ] } }
在某些情況下,您需要一個完全離線的解決方案。由於印表機支援有限的輸入格式,因此用戶端必須將文件轉換為幾種原生支援的印表機格式。
![](https://developers.google.cn/cloud-print/images/privet_image04.jpg?authuser=6&hl=zh-tw)
這份規格要求所有印表機至少支援 PWG 光柵 (「image/pwg-raster&」) 格式。印表機可能支援其他格式 (例如 JPEG),且用戶端支援這種格式。印表機「必須」透過 /capabilities API 公開支援的類型,例如:
{ "version": "1.0", "printer": { "supported_content_type": [ { "content_type": "image/pwg-raster" }, { "content_type": "image/jpeg" } ] } }用戶端可以透過兩種方式透過區域網路進行列印。
簡易列印 - 用戶端透過區域網路將文件傳送至 /submitdoc API,但未指定「job_id」參數。您提交的文件將使用預設的列印票證設定列印,且無須使用列印工作狀態。如果印表機「只」支援這種列印類型,則「必須」在 /privet /info API 回應中宣傳 ONLY/submitdoc API。
"api": [ "/privet/accesstoken", "/privet/capabilities", "/privet/printer/submitdoc", ]
進階列印 - 用戶端必須先在要求中呼叫具有有效 CJT 工作票券的 /privet/printer/createjob API,才能在印表機上建立列印工作。印表機「必須」將列印票券儲存在記憶體中,並將 job_id 傳回用戶端。接著,用戶端會呼叫 /printer/submitdoc API,並指定先前收到的 job_id。屆時印表機會開始列印。用戶端會呼叫 /privet/printer/jobstate API,對印表機進行輪詢。
在多用戶端環境中,無法保證 API 的呼叫方式。其中一個用戶端可呼叫另一個用戶端的 /createjob->/submitdoc 呼叫之間的 /createjob。為減少可能的死結問題,並增加可用性,我們建議您在印表機上至少保留 3 至 5 個待處理列印工作(至少 3 到 5 個):
- /createjob 會擷取佇列中的第一個可用位置。
- 工作 (佇列中) 的生命週期為至少 5 分鐘。
- 如果佇列中的所有位置都已被擷取,則系統會移除最舊且非列印的工作,並放到新工作。
- 如果裝置上已有列印工作 (簡易或進階列印),/submitdoc 會傳回忙碌,並建議逾時,以重試這項列印工作。
- 如果 /submitdoc 參照已從佇列中移除的工作 (因為遭到取代或逾時),印表機應傳回 invalid_print_job 錯誤,而用戶端會從 /createjob 步驟重試程序。用戶端「必須」等待最多 5 秒的隨機逾時時間,然後再試一次。
如果記憶體限制導致裝置無法儲存多個待處理工作,您可以排入 1 個列印工作的佇列。但仍應使用與上述相同的通訊協定。工作完成或失敗後,如果發生錯誤,印表機應儲存工作狀態的相關資訊至少 5 分鐘。儲存已完成工作狀態的佇列大小不得小於 10。如果需要更多工作狀態,系統可能會在 5 分鐘逾時前,將佇列中最舊的的狀態移除。
注意:目前用戶端會輪詢工作狀態。日後,如果列印工作狀態有所變更,印表機可能會要求傳送 TXT DNS 通知。
5.1. /privet/printer/createjob API
/privet/printer/createjob API 為「選用」(請參閱上方的簡易列印)。這是 HTTP POST 要求,/privet/printer/createjob API 必須檢查有效的「X-Privet-Token"」標頭。 裝置「必須」在「/privet/printer/createjob」中導入這個 API:url
POST /privet/printer/createjob HTTP/1.1收到 /privet/printer/createjob API 呼叫時,印表機「必須」建立新的列印工作 ID、將收到的列印票證儲存為 CJT 格式,並將列印工作 ID 傳回用戶端。
5.1.1. 輸入
/privet/printer/createjob API 的網址中沒有輸入參數。要求主體應包含 CJT 格式的列印工作票券資料。5.1.2. Return 鍵
/privet/printer/createjob API 會傳回下列資料:值名稱 | 值類型 | 說明 |
---|---|---|
job_id | string | 新建立的列印工作 ID。 |
到期 | int | 這項列印工作的有效秒數。 |
示例:
{ "job_id": "123", "expires_in": 600 }
5.1.3. 錯誤
/privet/printer/createjob API 可能會傳回下列錯誤 (詳情請參閱「錯誤」一節):錯誤 | 說明 |
---|---|
無效的票券 | 提交的列印票證無效。 |
印表機忙碌 | 印表機忙碌中,目前無法處理 /建立工作。請於逾時後重試。 |
印表機錯誤 | 印表機處於錯誤狀態,需要使用者互動才能修正。 說明應包含更詳細的說明 (例如「紙匣 1 中的卡紙」)。 |
無效_權杖_權杖 | X-Privet-Token 在要求中無效或空白。 |
如果裝置未顯示 /privet/printer/createjob,則「必須」傳回 HTTP 404 錯誤。如果缺少 X-Privet-Token 標頭,則裝置「必須」傳回 HTTP 400 錯誤。
5.2. /privet/printer/submitdoc API
您必須啟用 /privet/printer/submitdoc API,才能透過區域網路 (離線或發布至雲端列印) 列印列印。這是 HTTP POST 要求,/privet/printer/submitdoc API 必須檢查有效的「X-Privet-Token"」標頭。裝置「必須」在 /privet/printer/submitdoc" 網址中導入這個 API:印表機 如果無法開始列印,則「必須」傳回錯誤 print_繁忙錯誤和建議的逾時期間,讓用戶端等待並再試一次。如果印表機無法保存內部緩衝區中的所有資料,則應該使用 TCP 機制來減緩資料轉移速度,直到輸出部分文件為止,讓部分緩衝區再次可用。(例如,印表機可在 TCP 層上設定 windowsize=0,讓用戶端等待)。
將文件提交到印表機可能需要耗費大量時間。列印期間,用戶端應能查看印表機和工作的狀態 (進階列印)。為此,印表機「必須」允許用戶端在處理 /privet/printer/submitdoc API 呼叫時呼叫/privet/info 和 /privet/printer/jobstate API。所有用戶端均建議啟動新的執行緒來執行 /privet/printer/submitdoc API 呼叫,以便主要執行緒使用 /privet/info 和 /privet/printer/jobstate API 檢查印表機和工作狀態。
注意:強烈建議您在本機列印工作完成或取消作業後,以便在日後指定版本的規格中,將工作最終狀態回報給 /patch/提交介面,以方便會計和使用者體驗。含有「printerid」、「printer」和「contentType」參數,以及「PrintJobState」格式 (則為 PrintJobState 格式) 參數,以及「Cloud Job 工作格式」參數)。請注意,提供的 PrintJobState 實際上必須是最終,亦即其類型必須為 DONE 或 ABORTED,且必須提供 ABORTED 的理由 (詳情請參閱 JobState)。另請注意,/apt/submit 介面並未回報使用 /ecomm/submit 介面回報本機列印工作,因為該區段旨在說明該介面的主要用途:提交列印工作以及在「quot;content"」參數中提供的文件來列印。
5.2.1. 輸入
/privet/printer/submitdoc API 含有以下輸入參數:名稱 | 值 |
---|---|
job_id | (選用) 列印工作 ID。如果使用簡易列印大小寫,可能會省略這個屬性 (請參閱上方說明)。必須與印表機傳回的型號相符。 |
<使用者名稱> | (選用) 使用者可理解的使用者名稱。以上資訊並非必要,只應用於列印工作註解。如果工作是轉貼到雲端列印服務,這個字串應附加至雲端列印工作。 |
client_name | (選用) 發出這個要求的用戶端應用程式名稱。僅供顯示之用。如果工作是轉貼到雲端列印服務,這個字串應附加至雲端列印工作。 |
工作名稱 | (選用) 要記錄的列印工作名稱。如果工作是轉貼到雲端列印服務,這個字串應附加至雲端列印工作。 |
離線 | (選用) 只能設為「離線=1」。在這種情況下,印表機應試著只在離線列印 (不要重新發布至雲端列印伺服器)。 |
要求主體應包含列印的有效文件。"Content-Length" 應加入正確的要求長度。"Content-Type"標頭應設為文件 MIME 類型,且與 CDD 中的其中一個類型相符 (除非 CDD 指定「*/*"」)。
我們強烈建議用戶端為這項要求提供有效的使用者名稱 (或電子郵件)、用戶端名稱和工作名稱。這些欄位只會用於使用者介面,以改善使用者體驗。
5.2.2. Return 鍵
/privet/printer/submitdoc API 會傳回下列資料:值名稱 | 值類型 | 說明 |
---|---|---|
job_id | string | 要求中所指定新建立的列印工作 (簡單列印) 或 job_id (進階列印) 的 ID。 |
到期 | int | 這項列印工作的有效秒數。 |
job_type | string | 所提交文件的內容類型。 |
job_size | int 64 位元 | 列印資料的大小 (以位元組為單位)。 |
工作名稱 | string | (選用) 與輸入內容相同的工作名稱 (如果有的話)。 |
示例:
{ "job_id": "123", "expires_in": 500, "job_type": "application/pdf", "job_size": 123456, "job_name": "My PDF document" }
5.2.3. 錯誤
/privet/printer/submitdoc API 可能會傳回下列錯誤 (詳情請參閱「錯誤」一節):錯誤 | 說明 |
---|---|
無效的職缺 | 要求中指定了無效/過期的工作 ID。逾時後重試。 |
無效的文件類型 | 印表機不支援文件 MIME-type。 |
無效的文件 | 提交的文件無效。 |
document_too_large | 文件超過許可大小上限。 |
印表機忙碌 | 印表機忙碌中,目前無法處理文件。請於逾時後重試。 |
印表機錯誤 | 印表機處於錯誤狀態,需要使用者互動才能修正。 說明應包含更詳細的說明 (例如「紙匣 1 中的卡紙」)。 |
無效參數 | 要求中指定的參數無效。(為避免日後發生相容性問題,請放心忽略未知的參數)。 |
user_cancel | 使用者明確取消了裝置的列印程序。 |
server_error | 無法將文件發布至雲端列印。 |
無效_權杖_權杖 | X-Privet-Token 在要求中無效或空白。 |
如果裝置未顯示 /privet/printer/submitdoc,它「必須」傳回 HTTP 404 錯誤。如果缺少 X-Privet-Token 標頭,則裝置「必須」傳回 HTTP 400 錯誤。
注意:由於附加了大型酬載,/privet/printer/submitdoc API 可能需要在印表機端進行特殊處理。在某些情況下 (視印表機 HTTP 伺服器實作和平台而定),印表機可能會在傳回 HTTP 錯誤前關閉通訊端。此外,印表機會傳回 503 錯誤,而非 Privet 錯誤。印表機「必須」盡可能傳回 Privet。但是,每個實作 Privet 規格的客戶都應能處理通訊端關閉 (無 HTTP 錯誤) 和 /privet/printer/submitdoc API 的 503 HTTP 錯誤案例。在這種情況下,用戶端 SHOULD 會將此視為 Privet 的「printer_忙碌」;並將「逾時」設為 15 秒。為避免無限重試,用戶端可在重試次數達到一定次數後停止重試 (例如 3 次)。
5.3. /privet/printer/jobstate API
/privet/printer/jobstate API 為「選用」(請參閱上方的簡易輸出)。這是 HTTP GET 要求。/privet/printer/jobstate API 必須檢查有效的「X-Privet-Token"」標頭。裝置「必須」在「/privet/printer/jobstate" url」中實作這個 API:GET /privet/printer/jobstate HTTP/1.1收到 /privet/printer/jobstate API 呼叫時,印表機應傳回要求的列印工作或 Invalid_print_job 錯誤的狀態。
5.3.1. 輸入
/privet/printer/jobstate API 使用下列輸入參數:名稱 | 值 |
---|---|
job_id | 列印工作狀態的列印工作 ID。 |
5.3.2. Return 鍵
/privet/printer/jobstate API 會傳回下列資料:值名稱 | 值類型 | 說明 |
---|---|---|
job_id | string | 用於列印狀態資訊的列印工作 ID。 |
州 | string | draft - 已在裝置上建立列印工作 (尚未收到 /privet/printer/submitdoc 呼叫)。 已排入佇列 - 已收到列印工作並排入佇列,但列印尚未開始。 in_progress - 列印工作正在進行列印。 已停止 - 列印工作已暫停,但可以手動或自動重新啟動。 complete:列印工作已完成。 已中止 - 列印工作失敗。 |
說明 | string | (選用) 使用者可理解的列印工作狀態說明。包含 state< stoped 或 bborted 時,應提供額外資訊。semantic_state 欄位通常會為客戶提供更實用且有意義的說明。 |
到期 | int | 這項列印工作的有效秒數。 |
job_type | string | (選用) 所提交文件的內容類型。 |
job_size | int 64 位元 | (選用) 列印資料的大小 (以位元組為單位)。 |
工作名稱 | string | (選用) 與輸入內容相同的工作名稱 (如果有的話)。 |
server_job_id (伺服器工作 ID) | string | (選用) 從伺服器傳回的工作 ID (如果工作已發布至雲端列印服務)。離線列印時隱藏。 |
semantic_state (語意狀態) | JSON | (選用) 採用 PrintJobState 格式的工作的語意狀態。 |
範例 (透過雲端列印報告列印):
{ "job_id": "123", "state": "in_progress", "expires_in": 100, "job_type": "application/pdf", "job_size": 123456, "job_name": "My PDF document", "server_job_id": "1111-2222-3333-4444" }
示例 (離線列印錯誤):
{ "job_id": "123", "state": "stopped", "description": "Out of paper", "expires_in": 100, "job_type": "application/pdf", "job_size": 123456, "job_name": "My PDF document" }
範例 (使用者取消列印工作):
{ "job_id": "123", "state": "aborted", "description": "User action", "expires_in": 100, "job_type": "application/pdf", "job_size": 123456, "job_name": "My PDF document", "semantic_state": { "version": "1.0", "state": { "type": "ABORTED", "user_action_cause": {"action_code": "CANCELLED"} }, "pages_printed": 7 } }
範例 (列印工作因紙張而停止)。請注意裝置狀態的參照。用戶端必須呼叫 /privet/info API,才能取得裝置狀態的相關詳細資料:
{ "job_id": "123", "state": "stopped", "description": "Out of paper", "expires_in": 100, "job_type": "application/pdf", "job_size": "123456", "job_name": "My PDF document", "semantic_state": { "version": "1.0", "state": { "type": "STOPPED", "device_state_cause": {"error_code": "INPUT_TRAY"} }, "pages_printed": 7 } }
5.3.3. 錯誤
/privet/printer/jobstate API 會傳回下列錯誤 (詳情請參閱「錯誤」一節):錯誤 | 說明 |
---|---|
無效的職缺 | 要求中指定了無效/過期的工作 ID。 |
server_error | 無法取得列印工作狀態 (用於發布至雲端列印的列印工作) 失敗。 |
無效_權杖_權杖 | X-Privet-Token 在要求中無效或空白。 |
如果裝置不公開 /privet/printer/jobstate,則「必須」傳回 HTTP 404 錯誤。如果缺少 X-Privet-Token 標頭,則裝置「必須」傳回 HTTP 400 錯誤。
6. 附錄
6.1. 預設行為和設定
本節說明所有與「所有 Privet 相容」裝置的預設行為。- 立即可用的裝置僅支援 /privet/info 和 /privet/register API。所有其他 API (例如 /privet/accesstoken、本機列印) 應停用。
- 註冊時必須和裝置互動。
- 使用者「必須」在裝置上執行實體操作 (例如按下按鈕),確認他們可以存取裝置。
- 使用者執行上述動作後,印表機應傳送 /ecomm/register 要求。除非採取動作,否則請勿傳送這項要求 (請參閱「序列圖 1」)。
- 如果裝置正在處理 /privet/register 要求 (例如等待上述動作),則必須拒絕所有其他 /privet/register 要求。在這種情況下,裝置「必須」傳回 device_繁忙的錯誤。
- 裝置應在 60 秒內逾時,任何未收到上述實體動作的 /register 要求。在這種情況下,裝置「必須」傳回 confirm_timeout 錯誤。
- 選用:非必要與非必要,可改善使用者體驗:
- 印表機可能會閃爍或其畫面,指出使用者必須採取動作確認註冊。
- 印表機螢幕上可能會顯示「已為使用者註冊「abc@def.com」的 Google 雲端列印工作 - 按下「確定」繼續」,其中「abc@def.com」是 /register API 呼叫中的使用者參數。這有助於使用者清楚瞭解下列事項:
- 確認使用者的註冊要求
- (如果對方沒有觸發請求的話)。
- 除了透過印表機確認實際操作 (例如「按下確定的按鈕」後,印表機可能也會為使用者提供用於取消要求的按鈕 (例如「按下 [取消] 可拒絕」)。如果使用者未在 60 秒的逾時期限前觸發註冊要求,「取消」就能取消要求。在此情況下,裝置「必須」傳回 user_cancel 錯誤。
- 擁有權轉移:
- 裝置可能會從 Cloud 服務中明確刪除。
- 如果裝置成功執行,但因 /家常/印表機 (針對 GCP) 呼叫而沒有裝置說明,則裝置必須「立即可用」模式還原。
- 如果裝置的憑證已失效 (因伺服器「無效的憑證」而失效),則「必須」還原為預設 (立即可用的) 模式。
- 本機恢復原廠設定「必須」清除裝置憑證並設為預設狀態。
- 選用:裝置可能會提供選單項目來清除憑證,並將其設為預設模式。
- 支援 XMPP 通知的裝置「必須」包含連線伺服器的功能。您「必須」透過「local_settings」設定控制連線偵測 (ping) 逾時。
- 裝置可明確地連線偵測伺服器 (GCP 的 /patch/printer API 以及 XMPP 連線偵測) 頻率不超過一天 (24 小時),以確保伺服器為同步狀態。建議在 24 至 32 小時內將隨機隨機檢查檢查期。
- 選用:建議您為雲端列印裝置採用這項設定,但我們不建議採取手動方式 (按鈕),讓使用者能從裝置啟動新的列印工作檢查。部分印表機已有這種金鑰。
- 選用,企業印表機可以選擇完全停用本機探索功能。在這種情況下,裝置「必須」在伺服器上更新這些本機設定。新的本機設定「必須」留空 (可將「quot;local_discovery"」設為「false」,代表您可以透過 GCP Service 重新啟用)。
6.1.2 預設註冊圖表
![](https://developers.google.cn/cloud-print/images/privet_image06.png?authuser=6&hl=zh-tw)
6.2. XSSI 和 XSRF 攻擊與預防功能
本節說明裝置上的 XSSI 和 XSRF 攻擊可能如何及受到保護 (包括符記產生技術)。如要瞭解詳情,請前往下列網址: http:// %}security.blogspot.com/2011/05/website-security-for-webmasters.html
一般而言,如果網站使用 Cookie 驗證機制,就可能導致 XSSI 和 XSRF 攻擊。雖然 Google 不會將 Cookie 與 Google 雲端列印服務搭配使用,但仍可能造成這類攻擊。區域網路存取權的設計隱含信任要求。
6.2.1. 特小西
惡意網站可能會猜測 Privet 相容裝置的 IP 位址和通訊埠號碼,並試圖利用「quot;srcoutlinelt;api name>"」在 Privet API 中呼叫 Privet API:<script type="text/javascript" src="http://192.168.1.42:8080/privet/info"></script>如未提供防護,惡意網站可以執行 API 呼叫並存取結果。
為了避免這種攻擊,「所有 Privet API」呼叫「必須」包含要求中的「X-Privet-Token"」標頭。"srcoutlinelt;api>"指令碼標記無法新增標頭,因此有效防範這類攻擊。
6.2.2. XSRF
http://en.wikipedia.org/wiki/ Cross-site_request_forgery惡意網站可能會猜測 Privet 相容裝置的 IP 位址和通訊埠號碼,並嘗試利用 <iframe>、表單或其他跨網站載入機制呼叫 Privet API。攻擊者將無法存取要求的結果,但如果要求會執行動作 (例如列印),可能會觸發該要求。
為避免這種攻擊,我們需要下列防護措施:
- 將 /privet/info API 保持開啟至 XSRF
- /privet/info API 「不得」在裝置上執行任何動作
- 使用 /privet/info API 接收 x-privet-token
- 所有其他 API 都必須「在」X-Privet-Token" 標頭中檢查有效的 x-privet-token。
- x-privet-token 應該只有 24 小時有效。
即使攻擊者能夠執行 /privet/info API,也無法讀取回應中的 x-privet-token,因此無法呼叫任何其他 API。
強烈建議您使用以下演算法產生 XSRF 權杖:
XSRF_token = base64( SHA1(device_secret + DELIMITER + issue_timecounter) + DELIMITER + issue_timecounter )
XSRF 權杖產生元素:
- DELIMITER 是一種特殊字元,通常是「:」
- issue_timecounter 是從事件開始(或時間戳記的紀元)或裝置啟動時間 (適用於 CPU 計數器) 算起的秒數。issue_timecounter 會在裝置啟動時運往中,持續增加 (請參閱下方的權杖驗證)。
- SHA1 - 使用 SHA1 演算法的雜湊函式
- base64 - base64 編碼
- device_secret - 裝置專屬的密鑰。每次重新啟動時「必須」更新裝置密鑰。
產生裝置密鑰的建議做法:
- 每次重新啟動時產生新的 UUID
- 每次重新啟動時產生 64 位元隨機數字
裝置不必儲存其核發的所有 XSRF 權杖。當裝置需要驗證 XSRF 權杖是否有效時,則應將權杖進行 Base64 解碼。從下半部取得 issue_timecounter (明文),並嘗試產生 device_secret + DELIMITER + issue_timecounter 的 SHA1 雜湊,其中 issue_timecounter 來自權杖。如果新產生的 SHA1 與權杖中的 SHA1 相符,裝置就必須檢查在 time_timecounter 是否在目前時間計數器的有效期限 (24 小時) 內。為此,裝置會採用目前時間計數器 (例如 CPU 計數器),然後減去 issue_timecounter。結果結果「必須」是權杖核發後秒數。
重要事項:如要實作 XSRF 保護措施,建議您使用這個方式。Privet 規格的用戶端不得試圖解讀 XSRF 權杖,而是應視為黑箱。圖 6.2.3 說明瞭導入 X-Privet-Token 並驗證一般要求的建議方式。
6.2.3 X-Privet 權杖產生與驗證序列圖
![](https://developers.google.cn/cloud-print/images/privet_image03.png?authuser=6&hl=zh-tw)
6.3. 工作流程圖
本節將說明不同情況下的工作流程。6.3.1. 立即可用的印表機工作流程
![](https://developers.google.cn/cloud-print/images/privet_image01.png?authuser=6&hl=zh-tw)
6.3.2. 已註冊的印表機啟動狀態
![](https://developers.google.cn/cloud-print/images/privet_image02.png?authuser=6&hl=zh-tw)
6.3.3 XMPP 通知處理工作流程
![](https://developers.google.cn/cloud-print/images/privet_image05.png?authuser=6&hl=zh-tw)
6.3.4. 檢查印表機設定工作流程
![](https://developers.google.cn/cloud-print/images/privet_image00.png?authuser=6&hl=zh-tw)