Privet은 클라우드 서비스에서 사용하는 클라우드 기기 로컬 검색 API입니다. 이 문서는 다음 섹션으로 구성됩니다.
- 소개: Privet 소개
- 디스커버리: 로컬 디스커버리 메커니즘
- 공지사항: 지역 검색 공지사항
- API: 일반 클라우드 기기를 위한 비공개 API
- Printer API: 프린터에서 사용하는 Privet API
- 부록: 보충 다이어그램
1. 소개
클라우드 연결 기기에는 많은 이점이 있습니다. 온라인 변환 서비스를 사용하고, 기기가 오프라인 상태일 때 작업 대기열을 호스팅하며, 전 세계 어디에서나 액세스할 수 있습니다. 하지만 특정 사용자가 액세스할 수 있는 클라우드 기기가 많으므로 위치에 따라 가장 가까운 기기를 찾는 방법을 제공해야 합니다. Privet 프로토콜의 목적은 클라우드 기기의 유연성을 적절한 로컬 검색 메커니즘과 결합하여 새 환경에서 기기를 쉽게 검색할 수 있도록 하는 것입니다.
이 프로토콜의 목표는 다음과 같습니다.- 클라우드 기기를 로컬에서 검색 가능하게 만들기
- 클라우드 서비스에 클라우드 기기 등록
- 등록된 기기를 클라우드 표현과 연결
- 오프라인 기능 지원
- 소형 기기에서 활용할 수 있도록 구현을 간소화
Privet 프로토콜은 검색과 API라는 두 가지 주요 부분으로 구성됩니다. 검색은 로컬 네트워크에서 기기를 찾는 데 사용되고 API는 기기에 관한 정보를 가져오고 일부 작업을 실행하는 데 사용됩니다. 이 문서에서 기기는 Privet 프로토콜을 구현하는 클라우드 연결 기기를 의미합니다.
2. 디스커버리
검색은 무설정 네트워킹 기반 (mDNS + DNS-SD) 프로토콜입니다. 기기는 IPv4 링크-로컬 주소 지정을 구현해야 합니다(MUST). 기기는 mDNS 및 DNS-SD 사양을 준수해야 합니다(MUST).
- http://www.rfc-editor.org/rfc/rfc3927.txt (IPv4 링크 로컬)
- http://www.rfc-editor.org/rfc/rfc4862.txt (IPv6 링크 로컬)
- http://www.rfc-editor.org/rfc/rfc6762.txt (mDNS)
- http://www.rfc-editor.org/rfc/rfc6763.txt (DNS-SD)
기기는 위의 사양에 따라 이름 충돌 해결을 실행해야 합니다(MUST).
2.1. 서비스 유형
DNS 서비스 검색은 서비스 유형에 다음 형식을 사용합니다. _applicationprotocol._transportprotocol Privet 프로토콜의 경우 DNS-SD의 서비스 유형은 _privet._tcp여야 합니다.
기기는 다른 서비스 유형도 구현할 수 있습니다. 기기에서 구현한 모든 서비스 유형에 동일한 서비스 인스턴스 이름을 사용하는 것이 좋습니다. 예를 들어 프린터는 'Printer XYZ._privet._tcp' 및 'Printer XYZ._printer._tcp' 서비스를 구현할 수 있습니다. 사용자의 설정을 간소화합니다. 하지만 Privet 클라이언트는 '_privet._tcp'만 찾습니다.
기기는 기본 서비스 유형 외에도 해당 하위 유형의 PTR 레코드를 광고해야 합니다(MUST) (DNS-SD 사양: '7.1. 선택적 인스턴스 열거 (하위 유형)'을 참고하세요. 형식은 다음을 따라야 합니다. _<subtype>._sub._privet._tcp
현재 지원되는 유일한 기기 하위 유형은 프린터입니다. 따라서 모든 프린터는 다음 두 PTR 레코드를 광고해야 합니다(MUST).
- _privet._tcp.local.
- _printer._sub._privet._tcp.local.
2.2. TXT 레코드
DNS 서비스 검색은 TXT 레코드에 서비스에 관한 선택적 정보를 추가할 필드를 정의합니다. TXT 레코드는 키/값 쌍으로 구성됩니다. 각 키/값 쌍은 길이 바이트로 시작하고 최대 255바이트의 텍스트가 이어집니다. 키는 첫 번째 '=' 문자 앞의 텍스트이고 값은 첫 번째 '=' 문자 뒤의 텍스트부터 끝까지입니다. 사양에서는 레코드에 값이 없는 경우를 허용합니다. 이 경우 '=' 문자가 없거나 '=' 문자 뒤에 텍스트가 없습니다. (DNS-SD 사양의 '6.1. DNS TXT 레코드 형식은 'DNS TXT 레코드의 일반 형식 규칙'을, DNS-SD TXT 레코드 크기'를 참고하세요(권장 길이).
Privet에서는 기기가 TXT 레코드에서 다음 키/값 쌍을 전송해야 합니다. 키/값 문자열은 대소문자를 구분하지 않습니다. 예를 들어 'CS=online'과 'cs=ONLINE'은 동일합니다. TXT 레코드의 정보는 /info API를 통해 액세스할 수 있는 정보와 동일해야 합니다(MUST)(4.1. API 섹션)을 참고하세요.
TXT 레코드 크기는 512바이트 미만으로 유지하는 것이 좋습니다.
2.2.1. txtvers
TXT 구조의 버전입니다. txtvers는 TXT 구조의 첫 번째 레코드여야 합니다(MUST). 현재 지원되는 버전은 1뿐입니다.
txtvers=1
2.2.2. ty
사용자가 읽을 수 있는 기기 이름을 제공합니다. 예를 들면 다음과 같습니다.
ty=Google Cloud Ready Printer Model XYZ
2.2.3. 참고 (선택사항)
사용자가 읽을 수 있는 기기 이름을 제공합니다. 예를 들면 다음과 같습니다.
note=1st floor lobby printer
참고: 이 키는 선택사항이므로 건너뛰어도 됩니다. 하지만 값이 있는 경우 사용자가 이 값을 수정할 수 있어야 합니다(SHOULD). 기기를 등록할 때 동일한 설명을 사용해야 합니다(MUST).
2.2.4. url
이 기기가 연결된 서버 URL입니다 (프로토콜 포함). 예를 들면 다음과 같습니다.
url=https://www.google.com/cloudprint
2.2.5. type
이 기기에서 지원하는 기기 하위 유형을 쉼표로 구분한 목록입니다. 형식은 'type=_subtype1,_subtype2'입니다. 현재 지원되는 유일한 기기 하위 유형은 프린터입니다.
type=printer
나열된 각 하위 유형은 해당 PTR 레코드를 사용하여 광고해야 합니다. 지원되는 각 서비스 하위 유형에는 해당하는 항목이 하나 있어야 합니다. 서비스 하위 유형 이름(<subtype>._sub._privet._tcp)은 여기서 기기 유형과 같아야 합니다.
2.2.6. id
기기 ID입니다. 기기가 아직 등록되지 않은 경우 이 키는 있어야 하지만 값은 비어 있어야 합니다. 예를 들면 다음과 같습니다.
id=11111111-2222-3333-4444-555555555555 id=
2.2.7. cs
기기의 현재 연결 상태를 나타냅니다. 이 사양에는 네 가지 가능한 값이 정의되어 있습니다.
- 'online'은 기기가 현재 클라우드에 연결되어 있음을 나타냅니다.
- '오프라인'은 기기가 로컬 네트워크에서 사용할 수 있지만 서버와 통신할 수 없음을 나타냅니다.
- '연결 중'은 기기가 시작 시퀀스를 실행 중이며 아직 완전히 온라인 상태가 아님을 나타냅니다.
- 'not-configured'는 기기의 인터넷 액세스가 아직 구성되지 않았음을 나타냅니다. 이 값은 현재 사용되지 않지만 향후 사양 버전에서 유용할 수 있습니다.
- cs=online
- cs=offline
- cs=connecting
기기가 클라우드에 등록된 경우 시작 시 서버와의 연결을 확인하여 연결 상태를 감지해야 합니다 (예: 기기 설정을 가져오기 위해 클라우드 API 호출). 기기는 알림 채널 (예: XMPP) 연결 상태를 사용하여 이 값을 보고할 수 있습니다. 시작 시 등록되지 않은 기기는 연결 상태를 감지하기 위해 도메인을 핑할 수 있습니다 (예: 클라우드 프린트 기기의 경우 www.google.com을 핑).
3. 공지사항
기기 시작, 종료 또는 상태 변경 시 기기는 mDNS 사양에 설명된 대로 알림 단계를 실행해야 합니다(MUST). 이러한 알림을 최소 1초 간격으로 두 번 이상 전송해야 합니다(SHOULD).
3.1. 시작
기기 시작 시 mDNS 사양에 설명된 대로 프로브 및 알림 단계를 실행해야 합니다(MUST). 이 경우 SRV, PTR, TXT 레코드를 전송해야 합니다. 가능하면 모든 레코드를 하나의 DNS 응답으로 그룹화하는 것이 좋습니다. 그렇지 않은 경우 SRV, PTR, TXT 레코드 순서가 권장됩니다.
3.2. 종료
기기 종료 시 TTL=0인 'goodbye packet'을 전송하여 관심 있는 모든 당사자에게 이를 알리려고 시도해야 합니다(mDNS 문서에 설명됨)(SHOULD).
3.3. 업데이트
TXT에 설명된 정보가 변경된 경우 기기는 업데이트 공지를 전송해야 합니다(MUST). 이 경우 새 TXT 레코드만 전송하면 됩니다. 예를 들어 기기가 등록된 후에는 새 기기 ID를 포함하는 업데이트 공지를 전송해야 합니다(MUST).
4. API
클라우드 기기가 검색되면 로컬 네트워크를 통해 기기와 직접 클라이언트 통신이 사용 설정됩니다. 모든 API는 HTTP 1.1 기반입니다. 데이터 형식은 JSON 기반입니다. API 요청은 GET 또는 POST 요청일 수 있습니다.
각 요청에는 유효한 'X-Privet-Token' 헤더가 포함되어야 합니다(MUST). 'X-Privet-Token' 헤더가 비어 있도록 허용되는 유일한 요청은 /privet/info 요청입니다 (헤더는 여전히 있어야 함). 'X-Privet-Token' 헤더가 누락된 경우 기기는 다음 HTTP 400 오류로 응답해야 합니다(MUST).
HTTP/1.1 400 Missing X-Privet-Token header.
'X-Privet-Token' 헤더가 비어 있거나 유효하지 않으면 기기는 '잘못된 X-Privet-Token 오류'(invalid_x_privet_token, 자세한 내용은 오류 섹션 참고)로 응답해야 합니다(MUST). 유일한 예외는 /info API입니다. 이 작업이 실행되는 이유와 토큰 생성 방법에 관한 자세한 내용은 부록 A: XSSI 및 XSRF 공격과 방지를 참고하세요.
요청된 API가 없거나 지원되지 않는 경우 기기는 HTTP 404 오류를 반환해야 합니다(MUST).
4.1. API 사용 가능 여부
어떤 API(예: /info API)가 노출되기 전에 기기는 서버에 연락하여 로컬 설정을 확인해야 합니다(MUST). 로컬 설정은 다시 시작 간에 보존되어야 합니다(MUST). 서버를 사용할 수 없는 경우 마지막으로 확인된 로컬 설정을 사용해야 합니다. 기기가 아직 등록되지 않은 경우 기본 설정을 따라야 합니다.
클라우드 프린트 기기는 아래 단계에 따라 로컬 설정을 등록하고 수신하고 업데이트해야 합니다(MUST).
4.1.1. 등록
기기가 등록될 때 다음과 같이 'local_settings' 매개변수를 지정해야 합니다(MUST).
{ "current": { "local_discovery": true, "access_token_enabled": true, "printer/local_printing_enabled": true, "printer/conversion_printing_enabled": true, "xmpp_timeout_value": 300 } }
값 이름 | 값 유형 | 설명 |
---|---|---|
local_discovery | 부울 | 로컬 검색 기능이 허용되는지 여부를 나타냅니다. 'false'인 경우 모든 로컬 API(/info 포함)와 DNS-SD 검색을 사용 중지해야 합니다. 기본적으로 새로 등록하는 기기는 'true'를 전달해야 합니다. |
access_token_enabled | 불리언 (선택사항) | /accesstoken API가 로컬 네트워크에 노출되어야 하는지 나타냅니다. 기본적으로 'true'여야 합니다. |
printer/local_printing_enabled | 불리언 (선택사항) | 로컬 인쇄 기능 (/printer/createjob, /printer/submitdoc, /printer/jobstate)이 로컬 네트워크에 노출되어야 하는지 나타냅니다. 기본적으로 'true'여야 합니다. |
printer/conversion_printing_enabled | 불리언 (선택사항) | 로컬 인쇄에서 변환을 위해 서버에 작업을 전송할 수 있는지 나타냅니다. 로컬 인쇄가 사용 설정된 경우에만 의미가 있습니다. |
xmpp_timeout_value | int (선택사항) | XMPP 채널 핑 사이의 시간(초)을 나타냅니다. 기본적으로 300(5분) 이상이어야 합니다(MUST). |
중요: 선택적 값이 없으면 기기에서 해당 기능을 완전히 지원하지 않음을 나타냅니다.
4.1.2. 시작
기기 시작 시 서버에 연락하여 로컬 네트워크에 노출할 수 있는 API를 확인해야 합니다. 클라우드 프린트에 연결된 프린터의 경우 다음을 호출해야 합니다.
/cloudprint/printer?printerid=<printer_id>
/cloudprint/list
/cloudprint/list보다 /cloudprint/printer가 선호되지만 둘 다 작동합니다.
이 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' 객체는 기기에 적용해야 하는 설정을 나타냅니다 (이 객체가 누락될 수 있음).
기기에서 '대기 중' 설정을 확인하면 상태를 업데이트해야 합니다(MUST)(아래 참고).
4.1.3. 업데이트
설정 업데이트가 필요한 경우 XMPP 알림이 기기로 전송됩니다. 알림은 다음 형식으로 표시됩니다.
<device_id>/update_settings
이러한 알림을 수신하면 기기는 서버에 쿼리하여 최신 설정을 가져와야 합니다(MUST). 클라우드 프린트 기기는 다음을 사용해야 합니다(MUST).
/cloudprint/printer?printerid=<printer_id>
기기가 시작 시 또는 알림으로 인해 /cloudprint/printer API의 결과로 '대기 중' 섹션을 확인하면 새 설정을 기억하도록 내부 상태를 업데이트해야 합니다 (MUST). 새 설정을 확인하기 위해 서버 API를 호출해야 합니다(MUST). 클라우드 프린터의 경우 기기는 등록 시와 마찬가지로 /cloudprint/update API를 호출하고 'local_settings' 매개변수를 사용해야 합니다(MUST).
XMPP 채널에 다시 연결할 때 기기는 /cloudprint/printer API를 호출하여 마지막 연결 이후 로컬 설정이 변경되었는지 확인해야 합니다(MUST).
4.1.3.1. 로컬 설정 대기 중
기기에서 서버 API를 호출하는 데 사용하는 'local_settings' 매개변수에는 'pending' 섹션이 포함되면 안 됩니다(MUST NEVER).
4.1.3.2. Local Settings Current(현재 지역 설정)
기기만 'local_settings'의 'current' 섹션을 변경할 수 있습니다. 나머지 모든 사용자는 '대기 중' 섹션을 변경하고 변경사항이 기기에 의해 '현재' 섹션에 전파될 때까지 기다립니다.
4.1.4. 오프라인
시작 중에 서버에 연결할 수 없는 경우 알림 후 기기는 마지막으로 알려진 로컬 설정을 사용해야 합니다(MUST).
4.1.5. 서비스에서 기기 삭제
기기가 서비스 (예: GCP)에서 삭제된 경우 XMPP 알림이 기기로 전송됩니다. 알림은 다음 형식으로 표시됩니다.
<device_id>/delete
이러한 알림을 수신하면 기기는 서버로 이동하여 상태를 확인해야 합니다(MUST). 클라우드 프린트 기기는 다음을 사용해야 합니다(MUST).
/cloudprint/printer?printerid=<printer_id>
기기는 success=false이고 기기/프린터 설명이 없는 성공적인 HTTP 응답을 수신해야 합니다(MUST). 기기가 서버에서 삭제되었음을 의미하며, 기기는 사용자 인증 정보를 삭제하고 기본 공장 설정 모드로 전환해야 합니다(MUST).
기기가 /cloudprint/printer API(시작, 업데이트 설정 알림, 일일 핑)의 결과로 삭제되었음을 나타내는 응답을 수신할 때마다 사용자 인증 정보를 삭제하고 기본 모드로 전환해야 합니다(MUST).
4.2. /privet/info API
정보 API는 필수이며(MANDATORY) 모든 기기에서 구현해야 합니다(MUST). '/privet/info' URL에 대한 HTTP GET 요청입니다(GET /privet/info HTTP/1.1).
info API는 기기와 지원되는 기능에 관한 기본 정보를 반환합니다. 이 API는 XSRF 공격에 취약하므로 기기 상태를 변경하거나 작업을 실행하면 안 됩니다(MUST NOT). 이 API만 빈 'X-Privet-Token' 헤더를 사용할 수 있습니다. 클라이언트는 'X-Privet-Token' 헤더가 X-Privet-Token: ''으로 설정된 /privet/info API를 호출해야 합니다.
정보 API는 검색 중에 TXT 레코드에서 사용할 수 있는 데이터와 일치하는 데이터를 반환해야 합니다(MUST).
4.2.1. 입력
/privet/info API에는 입력 매개변수가 없습니다.
4.2.2. 리턴
/privet/info API는 기기 및 지원되는 기능에 관한 기본 정보를 반환합니다.
TXT 열은 DNS-SD TXT 레코드의 해당 필드를 나타냅니다.
값 이름 | 값 유형 | 설명 | TXT |
---|---|---|---|
version | 문자열 | 지원되는 API의 최고 버전 (major.minor), 현재 1.0 | |
이름 | 문자열 | 사람이 읽을 수 있는 기기 이름입니다. | ty |
설명 | 문자열 | (선택사항) 기기 설명입니다. 사용자가 수정할 수 있어야 합니다(SHOULD). | 메모 |
URL | 문자열 | 이 기기가 통신하는 서버의 URL입니다. URL에는 프로토콜 사양이 포함되어야 합니다(MUST). 예: https://www.google.com/cloudprint | URL |
유형 | 문자열 목록 | 지원되는 기기 유형 목록입니다. | 유형 |
id | 문자열 | 기기 ID입니다. 기기가 아직 등록되지 않은 경우 비어 있습니다. | id |
device_state | 문자열 | 기기 상태입니다. idle은 기기가 준비되었음을 의미합니다. processing은 기기가 사용 중이며 한동안 기능이 제한될 수 있음을 의미합니다. stopped은 기기가 작동하지 않으며 사용자 개입이 필요함을 의미합니다. | |
connection_state | 문자열 | 서버 (base_url) 연결 상태
online - 연결 가능 offline - 연결 없음 connecting - 시작 단계 실행 중 not-configured - 아직 연결이 구성되지 않음 등록된 기기는 알림 채널 상태 (예: XMPP 연결 상태)에 따라 연결 상태를 보고할 수 있습니다. | cs |
제조업체 | 문자열 | 기기 제조업체 이름 | |
모델 | 문자열 | 기기의 모델 | |
serial_number | 문자열 | 고유 기기 식별자입니다. 이 사양에서 이는 UUID여야 합니다(MUST). (GCP 1.1 사양)
(선택사항) 여러 클라이언트가 동일한 기기를 식별할 수 있도록 모든 곳에서 동일한 일련번호 ID를 사용할 것을 적극 권장합니다. 예를 들어 IPP를 구현하는 프린터는 'printer-device-id' 필드에서 이 일련번호 ID를 사용할 수 있습니다. | |
펌웨어 | 문자열 | 기기 펌웨어 버전 | |
uptime | int | 기기 부팅 후 경과된 시간(초)입니다. | |
setup_url | 문자열 | (선택사항) 설정 안내가 있는 페이지의 URL (프로토콜 포함) | |
support_url | 문자열 | (선택사항) 지원, FAQ 정보가 포함된 페이지의 URL (프로토콜 포함) | |
update_url | 문자열 | (선택사항) 펌웨어 업데이트 안내가 있는 페이지의 URL (프로토콜 포함) | |
x-privet-token | 문자열 | XSSI 및 XSRF 공격을 방지하기 위해 모든 API에 전달해야 하는 X-Privet-Token 헤더의 값입니다. 자세한 내용은 6.1. 을 참고하세요. | |
api | API 설명 | 지원되는 API 목록 (아래 설명) | |
semantic_state | JSON | (선택사항) CloudDeviceState 형식의 기기 시맨틱 상태입니다. |
api - 로컬 네트워크를 통해 사용할 수 있는 API 목록을 포함하는 JSON 목록입니다. 일부 API는 로컬 네트워크에서 동시에 사용할 수 없을 수 있습니다. 예를 들어 새로 연결된 기기는 /register API만 지원해야 합니다.
"api": [ "/privet/register", ]
"api": [ "/privet/accesstoken", "/privet/capabilities", "/privet/printer/submitdoc", ]
현재 사용할 수 있는 API는 다음과 같습니다.
- /privet/register - 로컬 네트워크를 통한 기기 등록 API 자세한 내용은 /privet/register API를 참고하세요. 이 API는 기기가 클라우드에 성공적으로 등록되면 숨겨야 합니다(MUST).
- /privet/accesstoken - 기기에서 액세스 토큰을 요청하는 API입니다 (자세한 내용은 /privet/accesstoken API 참고).
- /privet/capabilities - 기기 기능을 가져오는 API입니다 (자세한 내용은 /privet/capabilities API 참고).
- /privet/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", ] }
{ "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. 오류
/privet/info API는 X-Privet-Token 헤더가 누락된 경우에만 오류를 반환해야 합니다(ONLY). HTTP 400 오류여야 합니다(MUST).
HTTP/1.1 400 Missing X-Privet-Token header.
4.3. /privet/register API
/privet/register API는 선택사항입니다(OPTIONAL). HTTP POST 요청입니다. /privet/register API는 유효한 X-Privet-Token 헤더가 있는지 확인해야 합니다(MUST). 기기는 '/privet/register' URL에서 이 API를 구현해야 합니다(MUST).
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단계로 구성됩니다 (Cloud Print의 익명 등록 참고).
- 익명 등록 프로세스를 시작합니다.
- 클라이언트는 /privet/register API를 호출하여 이 프로세스를 시작합니다. 이때 기기는 사용자 확인을 기다릴 수 있습니다.
- 클레임 토큰을 가져옵니다.
클라이언트는 기기가 계속할 준비가 되었는지 확인하기 위해 폴링합니다. 기기가 준비되면 서버에 등록 토큰과 등록 URL을 가져오라는 요청을 보냅니다. 수신된 토큰과 URL은 클라이언트에 반환해야 합니다(SHOULD). 이 단계에서 기기가 등록을 초기화하는 다른 전화를 수신하는 경우 다음을 충족해야 합니다.
- 등록을 시작한 사용자가 동일한 경우 이전 데이터를 모두 삭제하고 새 등록 프로세스를 시작합니다.
- 다른 사용자인 경우 device_busy 오류와 30초 제한 시간을 반환합니다.
등록 절차를 완료합니다.
클라이언트가 기기를 소유한 후 클라이언트는 기기에 등록을 완료하도록 알려야 합니다. 등록 프로세스가 완료되면 기기는 새로 획득한 기기 ID를 포함한 업데이트 공지를 전송해야 합니다.
참고: 기기에서 /privet/register API 호출을 처리하는 동안 다른 /privet/register API 호출은 동시에 처리할 수 없습니다. 기기는 device_busy 오류와 30초 제한 시간을 반환해야 합니다(MUST).
기기 등록 시 사용자 확인을 적극 권장합니다(HIGHLY recommended). 구현된 경우 기기는 /privet/register?action=start API 호출을 수신한 후 사용자 확인을 기다려야 합니다(MUST). 클라이언트는 /privet/register?action=getClaimToken API를 호출하여 사용자 확인이 완료되고 클레임 토큰을 사용할 수 있는 시점을 확인합니다. 사용자가 기기에서 등록을 취소하면(예: 취소 버튼을 누름) user_cancel 오류가 반환되어야 합니다(MUST). 사용자가 특정 기간 내에 등록을 확인하지 않은 경우 confirmation_timeout 오류가 반환되어야 합니다(MUST). 자세한 내용은 기본값 섹션을 참고하세요.
4.3.1. 입력
/privet/register API에는 다음과 같은 입력 매개변수가 있습니다.이름 | 값 |
---|---|
action | 다음 중 하나일 수 있습니다.
start - 등록 프로세스를 시작합니다. getClaimToken - 기기의 클레임 토큰을 가져옵니다. cancel - 등록 프로세스를 취소합니다. complete - 등록 프로세스를 완료합니다. |
사용자 | 이 기기를 소유할 사용자의 이메일입니다. |
기기는 모든 작업(시작, getClaimToken, 취소, 완료)의 이메일 주소가 일치하는지 확인해야 합니다(MUST).
4.3.2. 리턴
/privet/register API는 다음 데이터를 반환합니다.값 이름 | 값 유형 | 설명 |
---|---|---|
action | 문자열 | 입력 매개변수와 동일한 작업입니다. |
사용자 | 문자열 (선택사항) | 입력 매개변수와 동일한 사용자입니다 (입력에서 생략된 경우 누락될 수 있음). |
토큰 | 문자열 (선택사항) | 등록 토큰('getClaimToken' 응답에 필수, 'start', 'complete', 'cancel'에는 생략됨). |
claim_url | 문자열 (선택사항) | 등록 URL('getClaimToken' 응답에 필수, 'start', 'complete', 'cancel'에는 생략됨) 클라우드 프린터의 경우 서버에서 수신한 'complete_invite_url'이어야 합니다. |
automated_claim_url | 문자열 (선택사항) | 등록 URL('getClaimToken' 응답에 필수, 'start', 'complete', 'cancel'에는 생략됨) 클라우드 프린터의 경우 서버에서 수신한 'automated_invite_url'이어야 합니다. |
device_id | 문자열 (선택사항) | 새 기기 ID입니다. 'start' 응답에서는 생략되며 'complete'에서는 필수입니다. |
기기는 등록이 완료된 후에만 /privet/info API 응답에서 기기 ID를 반환해야 합니다(MUST).
예시 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는 다음 오류를 반환할 수 있습니다 (자세한 내용은 오류 섹션 참고).오류 | 설명 |
---|---|
device_busy | 기기가 사용 중이므로 요청된 작업을 수행할 수 없습니다. 시간이 초과된 후 다시 시도합니다. |
pending_user_action | 'getClaimToken'에 대한 응답에서 이 오류는 기기가 아직 사용자 확인을 기다리고 있음을 나타내며, 'getClaimToken' 요청은 제한 시간 후 다시 시도해야 합니다. |
user_cancel | 사용자가 기기에서 등록 프로세스를 명시적으로 취소했습니다. |
confirmation_timeout | 사용자 확인 시간이 초과됩니다. |
invalid_action | 잘못된 작업이 호출됩니다. 예를 들어 클라이언트가 action=start 및 action=getClaimToken을 호출하기 전에 action=complete를 호출한 경우입니다. |
invalid_params | 요청에 지정된 매개변수가 잘못되었습니다. (알 수 없는 매개변수는 향후 호환성을 위해 안전하게 무시해야 합니다.) 예를 들어 클라이언트가 action=unknown 또는 user=를 호출한 경우 이를 반환합니다. |
device_config_error | 기기 측의 날짜/시간 (또는 기타 설정)이 잘못되었습니다. 사용자가 기기 내부 웹사이트로 이동하여 기기 설정을 구성해야 합니다. |
오프라인 | 현재 기기가 오프라인 상태이므로 서버와 통신할 수 없습니다. |
server_error | 등록 프로세스 중에 서버 오류가 발생했습니다. |
invalid_x_privet_token | 요청에서 X-Privet-Token이 잘못되었거나 비어 있습니다. |
등록이 성공적으로 완료된 후 기기는 /privet/register API 노출을 중지해야 합니다(MUST). 기기가 /privet/register API를 노출하지 않는 경우 HTTP 404 오류를 반환해야 합니다(MUST). 따라서 기기가 이미 등록된 경우 이 API를 호출하면 404를 반환해야 합니다(MUST). X-Privet-Token 헤더가 누락된 경우 기기는 HTTP 400 오류를 반환해야 합니다(MUST).
4.4. /privet/accesstoken API
/privet/accesstoken API는 선택사항입니다. HTTP GET 요청입니다. /privet/accesstoken API는 유효한 'X-Privet-Token' 헤더를 확인해야 합니다(MUST). 기기는 '/privet/accesstoken' URL에서 이 API를 구현해야 합니다(MUST).GET /privet/accesstoken HTTP/1.1
기기가 /accesstoken API 호출을 수신하면 서버를 호출하여 지정된 사용자의 액세스 토큰을 가져오고 토큰을 클라이언트에 반환해야 합니다. 그러면 클라이언트가 액세스 토큰을 사용하여 클라우드를 통해 이 기기에 액세스합니다.
클라우드 프린트 기기는 다음 API를 호출해야 합니다(MUST).
/cloudprint/proximitytoken
"proximity_token": { "user": "user@domain.com", "token": "AAA111222333444555666777", "expires_in": 600 }
4.4.1. 입력
/privet/accesstoken API에는 다음과 같은 입력 매개변수가 있습니다.이름 | 값 |
---|---|
사용자 | 이 액세스 토큰을 사용하려고 한 사용자의 이메일입니다. 요청에서 비어 있을 수 있습니다. |
4.4.2. 리턴
/privet/accesstoken API는 다음 데이터를 반환합니다.값 이름 | 값 유형 | 설명 |
---|---|---|
token | 문자열 | 서버에서 반환된 액세스 토큰 |
사용자 | 문자열 | 입력 매개변수와 동일한 사용자입니다. |
expires_in | int | 이 토큰이 만료되기까지 남은 시간(초)입니다. 서버에서 수신되어 이 응답에 전달됩니다. |
예:
{ "token": "AAA111222333444555666777", "user": "user@domain.com", "expires_in": 600 }
4.4.3. 오류
/privet/accesstoken API는 다음 오류를 반환할 수 있습니다 (자세한 내용은 오류 섹션 참고).오류 | 설명 |
---|---|
오프라인 | 기기가 현재 오프라인 상태이므로 서버와 통신할 수 없습니다. |
access_denied | 권한이 부족합니다. 액세스가 거부되었습니다. 요청이 서버에 의해 명시적으로 거부된 경우 기기는 이 오류를 반환해야 합니다. |
invalid_params | 요청에 지정된 매개변수가 잘못되었습니다. (알 수 없는 매개변수는 향후 호환성을 위해 안전하게 무시해야 합니다.) 예를 들어 클라이언트가 /accesstoken?user= 또는 /accesstoken을 호출한 경우 |
server_error | 서버 오류입니다. |
invalid_x_privet_token | 요청에서 X-Privet-Token이 잘못되었거나 비어 있습니다. |
기기가 /privet/accesstoken API를 노출하지 않는 경우 HTTP 404 오류를 반환해야 합니다(MUST). X-Privet-Token 헤더가 누락된 경우 기기는 HTTP 400 오류를 반환해야 합니다(MUST).
4.5. /privet/capabilities API
/privet/capabilities API는 선택사항입니다(OPTIONAL). HTTP GET 요청입니다. /privet/capabilities API는 유효한 'X-Privet-Token' 헤더를 확인해야 합니다(MUST). 기기는 '/privet/capabilities' URL에서 이 API를 구현해야 합니다(MUST).GET /privet/capabilities HTTP/1.1
4.5.1. 입력
/privet/capabilities API에는 다음과 같은 입력 매개변수가 있습니다.이름 | 값 |
---|---|
오프라인 | (선택사항) 'offline=1'만 가능합니다. 이 경우 기기는 오프라인 사용 기능을 반환해야 합니다('온라인' 기능과 다른 경우). |
4.5.2. 리턴
/privet/capabilities API는 클라우드 기기 설명 (CDD) JSON 형식으로 기기 기능을 반환합니다 (자세한 내용은 CDD 문서를 참고하세요). 프린터는 최소한 지원되는 유형 목록을 여기에 반환해야 합니다(MUST). 예를 들어 현재 온라인 상태인 클라우드 지원 프린터는 다음과 같은 결과를 반환할 수 있습니다 (최소한).{ "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" } ] } }
참고: 프린터는 순서를 사용하여 지원되는 콘텐츠 유형 우선순위를 표현합니다. 예를 들어 위의 샘플에서 프린터는 'image/pwg-raster' 및 'image/jpeg'보다 'application/pdf' 데이터를 선호한다고 지정합니다. 클라이언트는 가능한 경우 프린터 우선순위를 존중해야 합니다(자세한 내용은 CDD 문서 참고).
4.5.3. 오류
/privet/capabilities API는 다음 오류를 반환할 수 있습니다 (자세한 내용은 오류 섹션 참고).오류 | 설명 |
---|---|
invalid_x_privet_token | 요청에서 X-Privet-Token이 잘못되었거나 비어 있습니다. |
기기가 /privet/capabilities API를 노출하지 않는 경우 HTTP 404 오류를 반환해야 합니다(MUST). X-Privet-Token 헤더가 누락된 경우 기기는 HTTP 400 오류를 반환해야 합니다(MUST).
4.6. 오류
오류는 위의 API에서 다음 형식으로 반환됩니다.값 이름 | 값 유형 | 설명 |
---|---|---|
오류 | 문자열 | 오류 유형 (API별로 정의됨) |
설명 | 문자열 (선택사항) | 사람이 읽을 수 있는 오류 설명입니다. |
server_api | 문자열 (선택사항) | 서버 오류의 경우 이 필드에는 실패한 서버 API가 포함됩니다. |
server_code | int (선택사항) | 서버 오류의 경우 이 필드에는 서버가 반환한 오류 코드가 포함됩니다. |
server_http_code | int (선택사항) | 서버 HTTP 오류의 경우 이 필드에는 서버에서 반환된 HTTP 오류 코드가 포함됩니다. |
제한 시간 | int (선택사항) | 클라이언트가 다시 시도하기 전에 기다리는 시간(초)(복구 가능한 오류에만 해당). 클라이언트는 이 값에서 실제 제한 시간을 +20%인 값으로 무작위로 지정해야 합니다(MUST). |
X-Privet-Token 헤더가 누락된 경우 모든 API는 HTTP 400 오류를 반환해야 합니다(MUST).
HTTP/1.1 400 Missing X-Privet-Token header.
예시 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. Printer API
이 프로토콜이 지원하는 기기 유형 중 하나는 프린터 유형입니다. 이 유형을 지원하는 기기는 프린터에 특화된 일부 기능을 구현할 수 있습니다(MAY). 클라우드 지원 프린터로 인쇄하는 경우 클라우드 프린트 서버를 통해 인쇄하는 것이 좋습니다.

경우에 따라 클라이언트가 문서를 로컬로 전송해야 할 수 있습니다. 클라이언트에 Google ID가 없거나 클라우드 프린트 서버와 통신할 수 없는 경우 필요할 수 있습니다. 이 경우 인쇄 작업이 프린터에 로컬로 제출됩니다. 그러면 프린터에서 작업 대기열 및 변환에 클라우드 프린트 서비스를 사용합니다. 프린터는 로컬로 제출된 작업을 클라우드 프린트 서비스에 다시 게시한 다음 클라우드를 통해 제출되었으므로 요청합니다. 이 프로세스를 통해 서비스 (변환) 및 인쇄 작업 관리/추적 측면에서 유연한 사용자 환경을 제공할 수 있습니다.

Cloud Print 서비스는 변환을 구현하므로 프린터는 지원되는 콘텐츠 유형 목록에 모든 입력 형식('*/*')을 지원한다고 광고해야 합니다(SHOULD).
{ "version": "1.0", "printer": { "supported_content_type": [ { "content_type": "image/pwg-raster" }, { "content_type": "*/*" } ] } }
완전한 오프라인 솔루션이 필요한 경우도 있습니다. 프린터는 제한된 수의 입력 형식을 지원하므로 클라이언트는 문서를 기본적으로 지원되는 프린터 형식으로 변환해야 합니다.

이 사양에서는 모든 프린터가 오프라인 인쇄 사례에 대해 최소한 PWG 래스터('image/pwg-raster') 형식을 지원해야 합니다(REQUIRES). 프린터는 다른 형식 (예: JPEG)을 지원할 수 있으며 클라이언트가 이를 지원하는 경우 해당 형식으로 문서를 전송할 수 있습니다. 프린터는 /capabilities API를 통해 지원되는 유형을 노출해야 합니다(MUST). 예를 들면 다음과 같습니다.
{ "version": "1.0", "printer": { "supported_content_type": [ { "content_type": "image/pwg-raster" }, { "content_type": "image/jpeg" } ] } }
간단한 인쇄 - 클라이언트가 로컬 네트워크를 통해 /submitdoc API로 문서를 전송합니다(job_id 매개변수를 지정하지 않음). 제출된 문서는 기본 인쇄 티켓 설정을 사용하여 인쇄되며 인쇄 작업 상태는 필요하지 않습니다. 프린터가 이 유형의 인쇄만 지원하는 경우 /privet /info API 응답에서/submitdoc API만 광고해야 합니다(MUST).
"api": [ "/privet/accesstoken", "/privet/capabilities", "/privet/printer/submitdoc", ]
고급 인쇄 - 클라이언트는 먼저 요청에 유효한 CJT 작업 티켓을 사용하여 /privet/printer/createjob API를 호출하여 프린터에서 인쇄 작업을 만들어야 합니다. 프린터는 인쇄 티켓을 메모리에 저장하고 job_id를 클라이언트에 반환해야 합니다(MUST). 그러면 클라이언트가 /printer/submitdoc API를 호출하고 이전에 수신한 job_id를 지정합니다. 이때 프린터에서 인쇄를 시작합니다. 클라이언트는 /privet/printer/jobstate API를 호출하여 인쇄 작업 상태를 폴링합니다.
멀티 클라이언트 환경에서는 이 API가 호출되는 방식을 보장할 수 없습니다. 한 클라이언트가 다른 클라이언트의/createjob->/submitdoc 호출 사이에 /createjob을 호출할 수 있습니다. 가능한 교착 상태를 없애고 사용성을 개선하려면 프린터에 대기 중인 인쇄 작업의 작은 대기열 (최소 3~5개)이 있는 것이 좋습니다.
- /createjob은 대기열에서 사용 가능한 첫 번째 자리를 차지합니다.
- 작업 수명 (대기열)은 5분 이상입니다.
- 대기열의 모든 자리가 채워져 있으면 인쇄되지 않은 가장 오래된 작업이 삭제되고 새 작업이 그 자리에 배치됩니다.
- 현재 기기에서 인쇄 중인 인쇄 작업이 있는 경우 (간단한 인쇄 또는 고급 인쇄) /submitdoc은 상태 busy를 반환하고 이 인쇄 작업을 다시 시도하도록 제한 시간을 제안해야 합니다.
- /submitdoc이 교체 또는 시간 초과로 인해 대기열에서 삭제된 작업을 참조하는 경우 프린터는 invalid_print_job 오류를 반환해야 하며 클라이언트는 /createjob 단계부터 프로세스를 다시 시도합니다. 클라이언트는 재시도하기 전에 최대 5초의 무작위 시간 초과 기간을 기다려야 합니다(MUST).
메모리 제약으로 인해 기기에 여러 대기 중인 작업을 저장할 수 없는 경우 인쇄 작업 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' 헤더를 확인해야 합니다(MUST). 기기는 '/privet/printer/createjob' URL에서 이 API를 구현해야 합니다(MUST).
POST /privet/printer/createjob HTTP/1.1
5.1.1. 입력
/privet/printer/createjob API에 URL의 입력 매개변수가 없습니다. 요청 본문에는 CJT 형식의 인쇄 작업 티켓 데이터가 포함되어야 합니다.5.1.2. 리턴
/privet/printer/createjob API는 다음 데이터를 반환합니다.값 이름 | 값 유형 | 설명 |
---|---|---|
job_id | 문자열 | 새로 생성된 인쇄 작업의 ID입니다. |
expires_in | int | 이 인쇄 작업이 유효한 시간(초)입니다. |
예:
{ "job_id": "123", "expires_in": 600 }
5.1.3. 오류
/privet/printer/createjob API는 다음 오류를 반환할 수 있습니다 (자세한 내용은 오류 섹션 참고).오류 | 설명 |
---|---|
invalid_ticket | 제출된 인쇄 티켓이 잘못되었습니다. |
printer_busy | 프린터가 사용 중이므로 현재 /createjob을 처리할 수 없습니다. 시간이 초과된 후 다시 시도합니다. |
printer_error | 프린터가 오류 상태이며 이를 수정하려면 사용자 상호작용이 필요합니다. 설명에는 자세한 설명 (예: '트레이 1에서 용지 걸림')이 포함되어야 합니다. |
invalid_x_privet_token | 요청에서 X-Privet-Token이 잘못되었거나 비어 있습니다. |
기기가 /privet/printer/createjob을 노출하지 않는 경우 HTTP 404 오류를 반환해야 합니다(MUST). X-Privet-Token 헤더가 누락된 경우 기기는 HTTP 400 오류를 반환해야 합니다(MUST).
5.2. /privet/printer/submitdoc API
/privet/printer/submitdoc API는 로컬 네트워크를 통한 인쇄(오프라인 또는 Cloud Print에 다시 게시)를 구현해야 합니다(REQUIRED). HTTP POST 요청입니다. /privet/printer/submitdoc API는 유효한 'X-Privet-Token' 헤더를 확인해야 합니다(MUST). 기기는 '/privet/printer/submitdoc' URL에서 이 API를 구현해야 합니다(MUST).POST /privet/printer/submitdoc HTTP/1.1
프린터가 내부 버퍼에 모든 데이터를 저장할 수 없는 경우 문서의 일부를 인쇄하여 버퍼의 일부를 다시 사용할 수 있게 될 때까지 TCP 메커니즘을 사용하여 데이터 전송 속도를 늦춰야 합니다(SHOULD). (예를 들어 프린터가 TCP 레이어에서 windowsize=0을 설정하여 클라이언트가 대기하도록 할 수 있습니다.)
프린터에 문서를 제출하는 데 상당한 시간이 걸릴 수 있습니다. 클라이언트는 인쇄가 진행되는 동안 프린터와 작업의 상태 (고급 인쇄)를 확인할 수 있어야 합니다. 이렇게 하려면 프린터는 /privet/printer/submitdoc API 호출을 처리하는 동안 클라이언트가/privet/info 및 /privet/printer/jobstate API를 호출하도록 허용해야 합니다(MUST). 모든 클라이언트는 기본 스레드가 /privet/info 및/privet /printer/jobstate API를 사용하여 프린터 및 작업 상태를 확인할 수 있도록 새 스레드를 시작하여 /privet/printer/submitdoc API 호출을 실행하는 것이 좋습니다.
참고: 로컬 인쇄 작업이 완료되거나 중단되면 회계 및 사용자 환경 목적으로 작업의 최종 상태를 /cloudprint/submit 인터페이스에 보고하는 것이 적극 권장되며 (향후 이 사양의 버전에서 필수) 'printerid', 'title', 'contentType', 'final_semantic_state' (PrintJobState 형식) 매개변수는 필수이며 'tag' (반복 매개변수) 및 'ticket' (CloudJobTicket 형식의 작업 티켓) 매개변수는 선택사항입니다. 제공된 PrintJobState가 실제로 최종 상태여야 합니다. 즉, 유형이 DONE 또는 ABORTED여야 하며 ABORTED인 경우 원인이 제공되어야 합니다 (자세한 내용은 JobState 참고). 또한 로컬 인쇄 작업을 보고하기 위해 /cloudprint/submit 인터페이스를 사용하는 것은 사양에 언급되어 있지 않습니다. 이 섹션은 인터페이스의 기본 사용 사례인 'content' 매개변수에 제공된 인쇄할 문서를 사용하여 인쇄 작업을 제출하는 것을 설명하기 위한 것이기 때문입니다.
5.2.1. 입력
/privet/printer/submitdoc API에는 다음과 같은 입력 매개변수가 있습니다.이름 | 값 |
---|---|
job_id | (선택사항) 인쇄 작업 ID입니다. 간단한 인쇄 사례의 경우 생략할 수 있습니다(위 참고). 프린터에서 반환된 값과 일치해야 합니다. |
user_name | (선택사항) 사람이 읽을 수 있는 사용자 이름입니다. 이는 확정된 값이 아니며 인쇄 작업 주석에만 사용해야 합니다. 작업이 클라우드 프린트 서비스에 다시 게시되는 경우 이 문자열이 클라우드 프린트 작업에 연결되어야 합니다. |
client_name | (선택사항) 이 요청을 실행하는 클라이언트 애플리케이션의 이름입니다. 표시용으로만 사용하세요. 작업이 클라우드 프린트 서비스에 다시 게시되는 경우 이 문자열이 클라우드 프린트 작업에 연결되어야 합니다. |
job_name | (선택사항) 기록할 인쇄 작업의 이름입니다. 작업이 클라우드 프린트 서비스에 다시 게시되는 경우 이 문자열이 클라우드 프린트 작업에 연결되어야 합니다. |
오프라인 | (선택사항) 'offline=1'만 가능합니다. 이 경우 프린터는 오프라인 인쇄만 시도해야 합니다 (클라우드 프린트 서버에 다시 게시하지 않음). |
요청 본문에는 인쇄할 유효한 문서가 포함되어야 합니다. 'Content-Length'에는 요청의 올바른 길이가 포함되어야 합니다. 'Content-Type' 헤더는 문서 MIME 유형으로 설정되어야 하며 CDD의 유형 중 하나와 일치해야 합니다 (CDD에서 '*/*'를 지정하지 않는 한).
클라이언트는 이 요청과 함께 유효한 사용자 이름(또는 이메일), 클라이언트 이름, 작업 이름을 제공할 것을 적극 권장합니다(HIGHLY recommended). 이러한 필드는 사용자 환경을 개선하기 위해 UI에서만 사용됩니다.
5.2.2. 리턴
/privet/printer/submitdoc API는 다음 데이터를 반환합니다.값 이름 | 값 유형 | 설명 |
---|---|---|
job_id | 문자열 | 새로 생성된 인쇄 작업 (간단한 인쇄) 또는 요청에 지정된 job_id (고급 인쇄)의 ID입니다. |
expires_in | int | 이 인쇄 작업이 유효한 시간(초)입니다. |
job_type | 문자열 | 제출된 문서의 콘텐츠 유형입니다. |
job_size | int 64비트 | 인쇄 데이터의 크기(바이트)입니다. |
job_name | 문자열 | (선택사항) 입력의 작업 이름과 동일합니다 (있는 경우). |
예:
{ "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는 다음 오류를 반환할 수 있습니다 (자세한 내용은 오류 섹션 참고).오류 | 설명 |
---|---|
invalid_print_job | 요청에 잘못되었거나 만료된 작업 ID가 지정되었습니다. 시간 제한 후 다시 시도합니다. |
invalid_document_type | 문서 MIME 유형이 프린터에서 지원되지 않습니다. |
invalid_document | 제출된 서류가 잘못되었습니다. |
document_too_large | 문서가 허용된 최대 크기를 초과합니다. |
printer_busy | 프린터가 사용 중이므로 현재 문서를 처리할 수 없습니다. 시간이 초과된 후 다시 시도합니다. |
printer_error | 프린터가 오류 상태이며 이를 수정하려면 사용자 상호작용이 필요합니다. 설명에는 자세한 설명 (예: '트레이 1에서 용지 걸림')이 포함되어야 합니다. |
invalid_params | 요청에 지정된 매개변수가 잘못되었습니다. (알 수 없는 매개변수는 향후 호환성을 위해 안전하게 무시해야 함) |
user_cancel | 사용자가 기기에서 인쇄 프로세스를 명시적으로 취소했습니다. |
server_error | 클라우드 프린트에 문서를 게시하지 못했습니다. |
invalid_x_privet_token | 요청에서 X-Privet-Token이 잘못되었거나 비어 있습니다. |
기기가 /privet/printer/submitdoc을 노출하지 않으면 HTTP 404 오류를 반환해야 합니다(MUST). X-Privet-Token 헤더가 누락된 경우 기기는 HTTP 400 오류를 반환해야 합니다(MUST).
참고: /privet/printer/submitdoc API에는 첨부된 페이로드가 크기 때문에 프린터 측에서 특별한 처리가 필요할 수 있습니다. 경우에 따라 (프린터 HTTP 서버 구현 및 플랫폼에 따라 다름) 프린터가 HTTP 오류를 반환하기 전에 소켓을 닫을 수 있습니다. 그 외의 경우 프린터가 Privet 오류 대신 503 오류를 반환할 수 있습니다. 프린터는 최대한 Private을 반환해야 합니다(SHOULD). 하지만 Privet 사양을 구현하는 모든 클라이언트는 /privet/printer/submitdoc API의 소켓 닫기(HTTP 오류 없음) 및 503 HTTP 오류 사례를 처리할 수 있어야 합니다(SHOULD). 이 경우 클라이언트는 'timeout'이 15초로 설정된 Privet 'printer_busy' 오류로 처리해야 합니다(SHOULD). 무한 재시도를 방지하기 위해 클라이언트는 적절한 횟수 (예: 3)만큼 시도한 후 재시도를 중지할 수 있습니다.
5.3. /privet/printer/jobstate API
/privet/printer/jobstate API는 선택사항입니다 (위의 간단한 인쇄 참고). HTTP GET 요청입니다. /privet/printer/jobstate API는 유효한 'X-Privet-Token' 헤더를 확인해야 합니다(MUST). 기기는 '/privet/printer/jobstate' URL에서 이 API를 구현해야 합니다(MUST).GET /privet/printer/jobstate HTTP/1.1
5.3.1. 입력
/privet/printer/jobstate API에는 다음과 같은 입력 매개변수가 있습니다.이름 | 값 |
---|---|
job_id | 상태를 반환할 인쇄 작업 ID입니다. |
5.3.2. 리턴
/privet/printer/jobstate API는 다음 데이터를 반환합니다.값 이름 | 값 유형 | 설명 |
---|---|---|
job_id | 문자열 | 상태 정보가 있는 인쇄 작업 ID입니다. |
주 | 문자열 | draft - 기기에서 인쇄 작업이 생성되었습니다 (아직 /privet/printer/submitdoc 호출이 수신되지 않음).
queued - 인쇄 작업이 수신되어 대기열에 추가되었지만 아직 인쇄가 시작되지 않았습니다. in_progress - 인쇄 작업이 인쇄 중입니다. stopped - 인쇄 작업이 일시중지되었지만 수동 또는 자동으로 다시 시작할 수 있습니다. done - 인쇄 작업이 완료되었습니다. 중단됨 - 인쇄 작업이 실패했습니다. |
설명 | 문자열 | (선택사항) 인쇄 작업 상태에 대한 사람이 읽을 수 있는 설명입니다. state가 stopped 또는 aborted인 경우 추가 정보를 포함해야 합니다. semantic_state 필드는 일반적으로 클라이언트에 더 나은 의미 있는 설명을 제공합니다. |
expires_in | int | 이 인쇄 작업이 유효한 시간(초)입니다. |
job_type | 문자열 | (선택사항) 제출된 문서의 콘텐츠 유형입니다. |
job_size | int 64비트 | (선택사항) 인쇄 데이터의 크기(바이트)입니다. |
job_name | 문자열 | (선택사항) 입력의 작업 이름과 동일합니다 (있는 경우). |
server_job_id | 문자열 | (선택사항) 서버에서 반환된 작업의 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는 다음 오류를 반환할 수 있습니다 (자세한 내용은 오류 섹션 참고).오류 | 설명 |
---|---|
invalid_print_job | 요청에 잘못되었거나 만료된 작업 ID가 지정되었습니다. |
server_error | 클라우드 프린트에 게시된 인쇄 작업의 인쇄 작업 상태를 가져오지 못했습니다. |
invalid_x_privet_token | 요청에서 X-Privet-Token이 잘못되었거나 비어 있습니다. |
기기가 /privet/printer/jobstate를 노출하지 않으면 HTTP 404 오류를 반환해야 합니다(MUST). X-Privet-Token 헤더가 누락된 경우 기기는 HTTP 400 오류를 반환해야 합니다(MUST).
6. 부록
6.1. 기본 동작 및 설정
이 섹션에서는 모든 Privet 호환 기기에서 예상되는 기본 동작을 설명합니다.- 기본 제공 기기는 /privet/info 및 /privet/register API만 지원해야 합니다. 다른 모든 API (예: /privet/accesstoken, 로컬 인쇄)는 사용 중지해야 합니다.
- 등록에는 기기와의 물리적 상호작용이 필요합니다.
- 사용자는 기기에 대한 액세스를 확인하기 위해 기기에서 물리적 작업을 실행해야 합니다(예: 버튼 누르기)(MUST).
- 사용자가 위에 설명된 작업을 수행하면 프린터는 /cloudprint/register 요청을 전송해야 합니다. 작업이 실행된 후에 이 요청을 전송해야 합니다(시퀀스 다이어그램 1 참고).
- 기기가 /privet/register 요청을 처리하는 경우 (예: 위의 작업을 기다리는 경우) 다른 모든 /privet/register 요청을 거부해야 합니다. 이 경우 기기는 device_busy 오류를 반환해야 합니다(MUST).
- 기기는 60초 이내에 위에 언급된 실제 작업을 수신하지 않는 /register 요청을 제한 시간 초과해야 합니다. 이 경우 기기는 confirmation_timeout 오류를 반환해야 합니다(MUST).
- 선택사항: 권장되지만 필수는 아닙니다. 다음을 통해 사용자 환경을 개선할 수 있습니다.
- 사용자가 등록을 확인하기 위해 조치를 취해야 함을 나타내기 위해 프린터에서 표시등이 깜박이거나 화면이 깜박일 수 있습니다.
- 프린터 화면에 'abc@def.com 사용자의 Google 클라우드 프린트에 등록 중입니다. 계속하려면 확인을 누르세요'라는 메시지가 표시될 수 있습니다. 여기서 abc@def.com은 /register API 호출의 사용자 매개변수입니다. 이렇게 하면 사용자에게 다음 사항이 더 명확해집니다.
- 확인하는 것이 등록 요청임
- 요청을 트리거하지 않은 경우 어떤 일이 발생하는지 알 수 있습니다.
- 프린터에서 확인하는 물리적 작업 (예: '확인 버튼을 누르세요') 프린터는 사용자에게 요청을 취소하는 버튼 (예: '취소를 눌러 거부')를 표시합니다. 이렇게 하면 등록 요청을 트리거하지 않은 사용자가 60초 제한 시간 전에 요청을 취소할 수 있습니다. 이 경우 기기는 user_cancel 오류를 반환해야 합니다(MUST).
- 소유권 이전:
- 기기가 클라우드 서비스에서 명시적으로 삭제되었을 수 있습니다.
- 기기가 성공을 수신하지만 /cloudprint/printer(GCP용) 호출의 결과로 기기 설명이 없는 경우 기본(초기) 모드로 되돌려야 합니다(MUST).
- 기기의 사용자 인증 정보가 더 이상 작동하지 않는 경우(서버의 '잘못된 사용자 인증 정보' 응답으로 인해 명시적으로) 기본(초기) 모드로 되돌아가야 합니다(MUST).
- 로컬 초기화는 기기의 사용자 인증 정보를 삭제하고 기본 상태로 설정해야 합니다(MUST).
- 선택사항: 기기에서 사용자 인증 정보를 삭제하고 기본 모드로 전환하는 메뉴 항목을 제공할 수 있습니다.
- XMPP 알림을 지원하는 기기는 서버를 핑하는 기능을 포함해야 합니다(MUST). 핑 제한 시간은 서버에서 'local_settings'를 통해 제어할 수 있어야 합니다(MUST).
- 기기는 동기화되도록 하루(24시간)에 한 번 이상 명시적으로 서버를 핑(/cloudprint/printer API for GCP, XMPP 핑 외)할 수 있습니다. 24~32시간 내에 확인 창을 무작위로 지정하는 것이 좋습니다.
- 선택사항: 클라우드 프린트 기기의 경우 사용자가 기기에서 새 인쇄 작업 확인을 시작할 수 있는 수동 방법(버튼)이 있는 것이 권장되지만 필수는 아닙니다. 일부 프린터에는 이미 이 기능이 있습니다.
- 선택사항입니다. 엔터프라이즈 프린터에는 로컬 검색을 완전히 사용 중지하는 옵션이 있을 수 있습니다. 이 경우 기기는 서버에서 이러한 로컬 설정을 업데이트해야 합니다(MUST). 새 로컬 설정은 비어 있어야 합니다 (MUST). 'local_discovery'를 'false'로 설정하면 GCP 서비스에서 다시 사용 설정할 수 있습니다.
6.1.2 기본 등록 다이어그램

6.2. XSSI 및 XSRF 공격 및 방지
이 섹션에서는 기기에서 XSSI 및 XSRF 공격이 발생할 가능성과 이러한 공격으로부터 보호하는 방법 (토큰 생성 기술 포함)을 설명합니다.자세한 내용은 다음을 참고하세요. http://googleonlinesecurity.blogspot.com/2011/05/website-security-for-webmasters.html
일반적으로 사이트에서 쿠키 인증 메커니즘을 사용하는 경우 XSSI 및 XSRF 공격이 가능합니다. Google은 클라우드 프린트 서비스에서 쿠키를 사용하지 않지만 이러한 공격은 여전히 가능합니다. 로컬 네트워크 액세스는 설계상 요청을 암시적으로 신뢰합니다.
6.2.1. XSSI
악성 웹사이트가 Privet 호환 기기의 IP 주소와 포트 번호를 추측하고 <script> 태그 내에서 'src=<api name >'을 사용하여 Privet API를 호출하려고 시도할 수 있습니다.<script type="text/javascript" src="http://192.168.1.42:8080/privet/info"></script>
이러한 유형의 공격을 방지하려면 모든 Privet API 호출에 요청의 'X-Privet-Token' 헤더가 필요해야 합니다(MUST). 'src=<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는 기기에서 어떤 작업도 실행하면 안 됩니다(MUST NOT).
- /privet/info API를 사용하여 x-privet-token 수신
- 다른 모든 API는 'X-Privet-Token' 헤더에서 유효한 x-privet-token을 확인해야 합니다(MUST).
- x-privet-token은 24시간 동안만 유효해야 합니다(SHOULD).
공격자가 /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 - 기기별 비밀번호입니다. 기기 보안 비밀은 다시 시작할 때마다 업데이트해야 합니다(MUST).
기기 비밀번호를 생성하는 권장 방법:
- 다시 시작할 때마다 새 UUID 생성
- 다시 시작할 때마다 64비트 난수 생성
기기에서 발급한 모든 XSRF 토큰을 저장할 필요는 없습니다. 기기에서 유효성을 위해 XSRF 토큰을 확인해야 하는 경우 토큰을 base64로 디코딩해야 합니다. 두 번째 절반 (일반 텍스트)에서 issue_timecounter를 가져와 토큰에서 가져온 issue_timecounter를 사용하여 device_secret + DELIMITER + issue_timecounter의 SHA1 해시를 생성하려고 시도합니다. 새로 생성된 SHA1이 토큰의 SHA1과 일치하면 기기는 이제 issue_timecounter가 현재 시간 카운터의 (24시간) 유효 기간 내에 있는지 확인해야 합니다. 이렇게 하려면 기기에서 현재 시간 카운터 (예: CPU 카운터)를 가져와서 여기에서 issue_timecounter를 뺍니다. 결과는 토큰 발급 이후의 시간(초)이어야 합니다(MUST).
중요: XSRF 보호를 구현하는 데 권장되는 방법입니다. Privet 사양의 클라이언트는 XSRF 토큰을 이해하려고 시도해서는 안 되며, 대신 블랙박스로 취급해야 합니다. 그림 6.2.3은 X-Privet-Token과 일반적인 요청의 확인을 구현하는 권장 방법을 보여줍니다.
6.2.3 X-Privet 토큰 생성 및 확인 시퀀스 다이어그램

6.3. 워크플로 다이어그램
이 섹션에서는 다양한 사례의 워크플로를 설명합니다.6.3.1. 프린터 초기 설정 워크플로

6.3.2. 등록된 프린터 시작

6.3.3 XMPP 알림 처리 워크플로

6.3.4. 프린터 설정 워크플로 확인
