Privet הוא API של גילוי מכשירים מקומיים בענן המשמש את שירותי הענן. המסמך הזה מסודר בקטעים הבאים:
- מבוא: מבוא ל-Prive
- Discovery: מנגנוני הגילוי המקומי
- הודעות: הודעות גילוי מקומי
- API: ממשקי Privet API למכשירים כלליים בענן
- Printer API: ממשקי API של Privet שנמצאים בשימוש מדפסות
- נספח: תרשימים משלימים
1. מבוא
למכשירים המחוברים לענן יש יתרונות רבים. הם יכולים להשתמש בשירותי המרות מקוונים, לארח תורי משרות המארחים כאשר המכשיר לא מחובר לאינטרנט, וניתן לגשת אליהם מכל מקום בעולם. עם זאת, כאשר מכשירי ענן רבים נגישים למשתמש מסוים, עלינו לספק שיטה למציאת המכשיר הקרוב ביותר על סמך המיקום. המטרה של פרוטוקול Privet היא לחייב את המכשירים בענן לפעול לפי מנגנון הגילוי המקומי המתאים, כדי שניתן יהיה לגלות מכשירים בקלות בסביבות חדשות.
המטרות של הפרוטוקול הזה הן:- להפוך מכשירים בענן לגלויים באופן מקומי
- רישום מכשירים בענן באמצעות שירות ענן
- שיוך מכשירים רשומים לייצוג בענן
- הפעלת פונקציונליות במצב אופליין
- מפשטים את ההטמעה, כדי שמכשירים קטנים יוכלו להשתמש בה
פרוטוקול Privet מורכב משני חלקים עיקריים: גילוי ו-API. הגילוי משמש לאיתור המכשיר ברשת המקומית, וממשק ה-API משמש לקבלת מידע על המכשיר ולביצוע פעולות מסוימות. במסמך הזה, המכשיר מתייחס למכשיר מחובר בענן שמטמיע את פרוטוקול Privet.
2. גילוי
Discovery הוא פרוטוקול המבוסס על אפס (mDNS + DNS-SD). המכשיר חייב להטמיע כתובות IPv4-Local 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 Discovery מוגדר עבור סוגי השירות הבאים: _applicationprotocol._transportprotocol. במקרה של פרוטוקול Privet, סוג השירות ב-DNS-SD צריך להיות: _privet._tcp
המכשיר יכול ליישם גם סוגי שירות אחרים. מומלץ להשתמש באותו שם מופע של שירות בכל סוגי השירותים המוטמעים במכשיר. לדוגמה: מדפסת יכולה להטמיע את השירותים "מדפסת XYZ._privet._tcp" ו-"Printer XYZ._printer._tcp". היא תפשט את ההגדרה עבור המשתמש. עם זאת, לקוחות Privet יחפשו רק "_privet._tcp".
בנוסף לסוג השירות הראשי, המכשיר חייב לפרסם את רשומות ה-PTR של סוגי המשנה המתאימים (יש לעיין במפרט ה-DNS-SD: "7.1. מספור מופעים סלקטיביים (סוג משנה)"). הפורמט הנכון צריך להיות: _<subtype>._sub._privet._tcp
כרגע, סוג המשנה היחיד שנתמך הוא מדפסת. לכן כל המדפסות חייבות לפרסם שתי רשומות PTR:
- _privet._tcp.local.
- _printer._sub._privet._tcp.local.
2.2. רשומת TXT
בשירות החיפוש של DNS מוגדרים שדות להוספת מידע אופציונלי לגבי שירות ברשומות ה-TXT. רשומת TXT מורכבת מצמדים של מפתח/ערך. כל צמד של מפתח/ערך מתחיל בבייטים באורך של טקסט ואחריו עד 255 בייטים של טקסט. המפתח הוא הטקסט שלפני התו '=' הראשון והערך הוא הטקסט שאחרי התו '=' הראשון עד סוף. המפרט לא מאפשר ערך בכלל, ולכן במקרה כזה לא יופיע התו '=' או 'אין טקסט' אחרי התו '='. (עיינו במפרט של DNS-SD: "6.1. כללי עיצוב כלליים לרשומות DNS TXT&&; עבור פורמט רשומת TXT של DNS ו-"6.2. DNS-SD TXT גודל רשומה&;באורך המומלץ).
Privet מחייב את המכשיר לשלוח את זוגות המפתח/ערך הבאים ברשומת ה-TXT. מחרוזות מפתח/ערך הן לא תלויות-רישיות, לדוגמה "CS=online" &"cs=Online" הן זהות. המידע ברשומת ה-TXT חייב להיות זהה לזה שניתן להגיע באמצעות /info API (ראו 4.1. API).
מומלץ לוודא שגודל רשומת ה-TXT יהיה פחות מ-512 בייטים.
2.2.1. txtvers
הגרסה של מבנה ה-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
כתובת ה-URL של השרת שאליו המכשיר מחובר (כולל פרוטוקול). למשל:
url=https://www.google.com/cloudprint
סוג 2.2.5.
רשימה המופרדת בפסיקים של סוגי משנה של מכשירים שנתמכים במכשיר הזה. הפורמט הוא: "type=_subtype1,_subtype2". בשלב זה, סוג המשנה הנתמך היחיד של המכשיר הוא מדפסת.
type=printer
יש לפרסם כל סוג משנה שמופיע באמצעות רשומת PTR תואמת. לכל סוג משנה של שירות נתמך צריך להיות פריט תואם אחד. סוג המשנה של סוג השירות (<subtype>._sub._privet._tcp) צריך להיות שווה לסוג המכשיר כאן.
מזהה 2.2.6.
מזהה המכשיר. אם המכשיר עדיין לא רשום, המפתח הזה צריך להופיע אבל הערך צריך להיות ריק. למשל:
id=11111111-2222-3333-4444-555555555555 id=
2.2.7. cs
מציין את מצב החיבור הנוכחי של המכשיר. במפרט הזה מפורטים ארבעה ערכים אפשריים.
- "online" מציין שהמכשיר מחובר כרגע לענן.
- "Offline" מציין שהמכשיר זמין ברשת המקומית, אבל לא יכול לדבר אל השרת.
- "connecting" מציין שהמכשיר מבצע את רצף ההפעלה ועדיין לא מחובר לאינטרנט.
- "not-defined" מציין שעדיין לא הוגדרה גישת האינטרנט במכשיר. הערך הזה לא בשימוש כרגע, אבל יכול להיות שימושי בגרסאות עתידיות של המפרט.
- cs=online
- cs=Offline
- cs=connecting
אם המכשיר נרשם בענן, במהלך ההפעלה הוא צריך לבדוק קישוריות עם שרת כדי לזהות את מצב החיבור שלו (לדוגמה, קריאה ל-Cloud API כדי לקבל את הגדרות המכשיר). המכשיר עשוי להשתמש במצב החיבור של ערוץ ההתראות שלו (לדוגמה, XMPP) כדי לדווח על הערך הזה. מכשירים שאינם רשומים במהלך ההפעלה עשויים לבצע פינג של דומיין כדי לזהות את מצב החיבור שלהם (לדוגמה, פינג www.google.com למכשירים עם הדפסה בענן).
3. עדכונים
בזמן ההפעלה של המכשיר, כיבוי או שינוי המצב, המכשיר חייב לבצע את שלב ההודעה כפי שמתואר במפרט של mDNS. היא אמורה לשלוח את ההודעה המתאימה לפחות פעמיים, עם מרווח של שנייה אחת לפחות ביניהן.
3.1. הפעלה
בזמן ההפעלה של המכשיר, המכשיר חייב לבצע פעולות חיפוש והכרזה על השלבים כפי שמתואר במפרט של mDNS. במקרה כזה יש לשלוח את רשומות ה-SRV, ה-PTR וה-TXT. אם אפשר, מומלץ לקבץ את כל הרשומות בתגובת DNS אחת. אם לא, מומלץ להשתמש בהזמנה הבאה: SRV, PTR, רשומות TXT.
3.2. כיבוי
במהלך ההשבתה של המכשיר, היא אמורה לנסות להודיע על כך לכל הצדדים המתעניינים. לשם כך, שולחים "goodbye packet" באמצעות TTL=0 (כמתואר בתיעוד mDNS).
3.3. עדכון
אם אחד מהמידע שמתואר ב-TXT השתנה, המכשיר חייב לשלוח הודעת עדכון. במקרה כזה, מספיק לשלוח את רשומת ה-TXT החדשה בלבד. לדוגמה, לאחר שמכשיר נרשם, עליו לשלוח התראת עדכון עם מזהה המכשיר החדש.
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 error" (בקטע 'שגיאות' אפשר למצוא מידע על שגיאות). החריג היחיד הוא ה-API /info. רוצים לדעת למה זה קורה ואיך יוצרים אסימונים? כדאי לעיין בנספח א': התקפות XSSI והתקפות XSRF ומניעתן.
אם ממשק ה-API המבוקש אינו קיים או אינו נתמך, המכשיר חייב להחזיר שגיאת HTTP 404.
4.1. זמינות API
לפני שממשק API כלשהו נחשף (כולל /info API), המכשיר חייב לפנות לשרת כדי לבדוק את ההגדרות המקומיות. יש לשמור הגדרות מקומיות בין הפעלות מחדש. אם השרת לא זמין, מומלץ להשתמש בהגדרות המקומיות האחרונות הידועות. אם המכשיר עדיין לא נרשם, הוא צריך לפעול לפי הגדרות ברירת המחדל.
כדי לרשום, לקבל ולעדכן הגדרות מקומיות, מכשירי Cloud Print צריכים לפעול לפי השלבים שבהמשך.
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 } }אפשר לקבוע את ההגדרות הבאות:
שם הערך | סוג ערך | תיאור |
---|---|---|
local_discovery | boolean | העמודה הזו מציינת אם הפונקציונליות של גילוי מקומי מותרת. אם "false", יש להשבית את כל גילוי ה-API המקומי (כולל /info) וגילוי DNS-SD. כברירת מחדל, מכשירים חדשים שנרשמים צריכים לעבור את "true". |
access_token_Enabled | בוליאני (אופציונלי) | מציינת אם /accesstoken API צריך להיחשף ברשת המקומית. כברירת מחדל, הערך צריך להיות "true". |
מדפסת/local_printing_Enabled | בוליאני (אופציונלי) | מציין אם יש לחשוף את הפונקציונליות של הדפסה מקומית (/printer/createjob, /printer/submitdoc, /printer/jobstate) ברשת המקומית. כברירת מחדל, הערך צריך להיות "true". |
מדפסת/conversion_printing_Enabled | בוליאני (אופציונלי) | העמודה הזו מציינת אם ההדפסה המקומית עשויה לשלוח עבודה לשרת להמרה. יש היגיון רק כשההדפסה המקומית מופעלת. |
Xmpp_timeout_value | int (אופציונלי) | מציין את מספר השניות בין פינגים של ערוץ XMPP. ערך ברירת המחדל חייב להיות 300 (5 דקות) או יותר. |
חשוב: אם לא מוגדר ערך אופציונלי, המכשיר לא תומך לחלוטין בפונקציונליות התואמת.
4.1.2. הפעלה
בהפעלת המכשיר, עליו לפנות לשרת כדי לבדוק אילו ממשקי API זמינים לחשיפה ברשת המקומית. במדפסות שמחוברות ל-Cloud Print, יש להתקשר אל:
/cloudprint/printer?printerid=<printer_id>או
/cloudprint/list
/cloudprint/printer עדיפה על /cloudprint/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"Object מציין הגדרות שיש להחיל על המכשיר (ייתכן שהאובייקט חסר).
ברגע שהמכשיר רואה את הגדרות ה&המתנה; הוא חייב לעדכן את המצב שלו (ראו בהמשך).
4.1.3. עדכון
אם נדרש עדכון הגדרות, תישלח התראה XMPP למכשיר. ההתראה תופיע בפורמט הבא:
<device_id>/update_settings
בעת קבלת הודעה כזו, המכשיר חייב לשלוח שאילתה לשרת כדי לקבל את ההגדרות העדכניות ביותר. מכשירי Cloud Print חייבים להשתמש:
/cloudprint/printer?printerid=<printer_id>
ברגע שהמכשיר רואה את הקטע "Pending" כתוצאה מ-API/ //cloudprint/printer (במהלך ההפעלה או עקב ההודעה), הוא חייב לעדכן את המצב הפנימי שלו כדי לזכור את ההגדרות החדשות. עליו לקרוא ל-API של השרת כדי לאשר את ההגדרות החדשות. ב-Cloud Printers, המכשיר חייב לקרוא ל-/cloudprint/update API ולהשתמש בפרמטר "local_settings" כמו במהלך הרישום.
בהתחברות מחדש לערוץ XMPP, חובה לחבר את המכשיר ל- /cloudprint/printer API כדי לבדוק אם ההגדרות המקומיות השתנו מאז הפעם האחרונה.
4.1.3.1. הגדרות מקומיות בהמתנה
"local_settings" הפרמטר שבו המכשיר משתמש כדי לקרוא ל-API של השרת חייב להכיל את הקטע "Pending" .
4.1.3.2 הגדרות מקומיות נוכחיות
רק המכשיר יכול לשנות את הקטע "current" של ה-"local_settings". כל המשתמשים האחרים ישנו את הקטע "Pending" וממתינים עד שהשינויים יופצו בהתאם למכשיר.
4.1.4. אופליין
כשלא ניתן ליצור קשר עם השרת בזמן ההפעלה, לאחר התראה, המכשיר חייב להשתמש בהגדרות המקומיות האחרונות הידועות.
4.1.5. מחיקת מכשיר מהשירות
אם המכשיר נמחק מהשירות (למשל, GCP), תישלח אליו התראה מ-XMPP. ההתראה תהיה בפורמט הבא:
<device_id>/delete
בעת קבלת התראה כזו, המכשיר חייב לעבור לשרת כדי לבדוק את מצבו. בענן יש להשתמש במכשירים עם הדפסה:
/cloudprint/printer?printerid=<printer_id>
המכשיר חייב לקבל תגובת HTTP מוצלחת עם תיאור הצלחה=False וללא תיאור מכשיר/מדפסת. פירוש הדבר הוא שהמכשיר הוסר מהשרת, והמכשיר חייב למחוק את פרטי הכניסה שלו ולעבור להגדרות ברירת המחדל של היצרן.
בכל פעם שהמכשיר מקבל תשובה המציינת שהוא נמחק עקב ה-API /cloudprint/printer API (מצב ההפעלה, ההתראה על הגדרות העדכון, פינג יומי), הוא צריך למחוק את פרטי הכניסה ולעבור למצב ברירת המחדל.
4.2. /privet/info API
ה-API של המידע הוא MANDATOR וחובה להטמיע אותו בכל מכשיר. זוהי בקשת HTTP GET עבור "/privet/info" url: GET /privet/info HTTP/1.1
ה-API של המידע מחזיר מידע בסיסי על המכשיר והפונקציונליות שהוא תומך בו. ה-API הזה לעולם לא ישנה את סטטוס המכשיר או מבצע פעולה כלשהי, כי הוא חשוף להתקפות XSRF. זהו ה-API בלבד, שמותר להוסיף לו כותרת "X-Privet-Token". הלקוחות צריכים לקרוא ל-/privet/info API עם "X-Privet-Token" הכותרת מוגדרת ל-X-Privet-Token: ""
המידע חייב להחזיר נתונים בהתאם לנתונים הזמינים ברשומת ה-TXT במהלך הגילוי.
4.2.1. הזנת קלט
/privet/info API לא מכיל פרמטרים של קלט.
4.2.2. הלוך ושוב
/privet/info API מחזיר מידע בסיסי על המכשיר והפונקציונליות הנתמכת.
עמודת ה-TXT מציינת את השדה המתאים ברשומת ה-TXT של DNS-SD.
שם הערך | סוג ערך | תיאור | TXT |
---|---|---|---|
גרסה | string | הגרסה הגבוהה ביותר (major.minor) של API נתמכת, כרגע 1.0 | |
name | string | שם של אדם שקריא. | עניבה |
תיאור | string | (אופציונלי) תיאור המכשיר. צריך להיות ניתן לשינוי על ידי המשתמש. | הערה, פתקית |
כתובת אתר | string | כתובת ה-URL של השרת שאליו המכשיר מדבר. כתובת ה-URL חייבת לכלול את מפרט הפרוטוקול, לדוגמה: https://www.google.com/cloudprint. | כתובת אתר |
סוג | רשימת מחרוזות | רשימת סוגי המכשירים הנתמכים. | סוג |
id | string | מזהה המכשיר, ריק אם המכשיר עדיין לא רשום. | id |
device_state | string | מצב המכשיר. לא פעיל פירושו שהמכשיר מוכן עיבוד פירושו שהמכשיר עסוק וייתכן שהפונקציונליות תהיה מוגבלת למשך זמן מה הופסק והמכשיר לא פועל ונדרשת התערבות משתמש | |
סטטוס_החיבור | string | מצב החיבור לשרת (base_url)
אונליין - חיבור זמין אופליין - אין חיבור חיבור - ביצוע שלבי הפעלה לא מוגדר - החיבור עדיין לא הוגדר מכשיר רשום עשוי לדווח על מצב החיבור שלו על סמך מצב ערוץ ההתראה (למשל, מצב חיבור XMPP). | cs |
יצרן | string | שם יצרן המכשיר | |
מודל | string | דגם המכשיר | |
מספר סידורי | string | מזהה מכשיר ייחודי. המפרט הזה חייב להיות UUID. (מפרט של GCP 1.1)
(אופציונלי) מומלץ מאוד להשתמש באותו מזהה מספר סידורי בכל מקום, כדי שלקוחות שונים יוכלו לזהות את אותו מכשיר. לדוגמה, מדפסות שמשתמשות ב-IPP יכולות להשתמש במזהה המספר הסידורי בשדה "printer-device-id". | |
קושחה | string | גרסת הקושחה של המכשיר | |
זמן פעולה תקינה | int | מספר השניות מאתחול המכשיר. | |
set_url | string | (אופציונלי) כתובת ה-URL (כולל פרוטוקול) של הדף עם הוראות להגדרה | |
support_url | string | (אופציונלי) כתובת ה-URL (כולל פרוטוקול) של הדף עם תמיכה ומידע על שאלות נפוצות | |
update_url | string | (אופציונלי) כתובת URL (כולל פרוטוקול) של הדף עם הוראות לעדכון הקושחה | |
כרטיס x-privet-token | string | הערך של הכותרת X-Privet-Token שיש להעביר לכל ממשקי ה-API כדי למנוע מתקפות XSSI ו-XSRF. פרטים נוספים מופיעים ב-6.1. | |
ממשק API | תיאור של ממשקי API | רשימה של ממשקי API נתמכים (כמתואר בהמשך) | |
Semantic_state | JSON | (אופציונלי) המצב הסמנטי של המכשיר בפורמט CloudDeviceState. |
api – רשימת JSON המכילה את רשימת ממשקי ה-API שזמינים דרך הרשת המקומית. לתשומת ליבך: ייתכן שלא כל ממשקי ה-API יהיו זמינים בו-זמנית ברשת המקומית. לדוגמה, מכשיר שהתחבר לאחרונה צריך לתמוך רק ב-API /רישום:
"api": [ "/privet/register", ]לאחר רישום המכשיר, הוא אמור להפסיק לתמוך ב-/enroll API. המכשיר צריך גם לבדוק עם השירות כדי לברר אילו ממשקי API יכולים להיחשף ברשת המקומית. למשל:
"api": [ "/privet/accesstoken", "/privet/capabilities", "/privet/printer/submitdoc", ]
ממשקי ה-API הבאים זמינים בשלב הזה:
- /privet/enroll – ממשק API לרישום מכשירים ברשת המקומית. (פרטים נוספים זמינים בכתובת /privet/enroll API). API זה חייב להיות מוסתר לאחר שהמכשיר נרשם בהצלחה בענן.
- /privet/accesstoken – ממשק ה-API לבקשת אסימון גישה מהמכשיר (פרטים נוספים זמינים בכתובת /privet/accesstoken API).
- /privet/capabilities – ממשק ה-API כדי לאחזר את יכולות המכשיר (פרטים נוספים זמינים בכתובת /privet/capabilities API).
- /privet/printer/* - ממשק API ספציפי לסוג המכשיר "printer" לקבלת פרטים, יש לעיין בממשקי 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. שגיאות
/privet/info API אמור להחזיר שגיאה רק אם חסרה כותרת X-Privet-Token. זו חייבת להיות שגיאת HTTP 400:
HTTP/1.1 400 Missing X-Privet-Token header.
4.3. /privet/enroll API
/privet/enroll API הוא אופציונלי. זוהי בקשת HTTP POST. /privet/enroll API עליך לבדוק עבור כותרת X-Privet-Token חוקית. המכשיר חייב להטמיע את ה-API הזה ב-"/privet/enroll" url:
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 בלבד כשהוא מאפשר רישום אנונימי באותו רגע. למשל:
- כשהמכשיר פועל (או אחרי שלוחצים על לחצן מיוחד במכשיר) והוא עדיין לא רשום, הוא צריך לחשוף את ה-API /privet/enroll כדי לאפשר למשתמש מהרשת המקומית לתבוע בעלות על המדפסת.
- לאחר השלמת הרישום, המכשיר צריך להפסיק את חשיפת ה-API /privet/enroll כדי למנוע ממשתמש אחר ברשת המקומית להחזיר את המכשיר.
- ייתכן שלמכשירים מסוימים יש דרכים שונות לרישום מכשירים, ואסור להם לחשוף את /privet/enroll API בכלל (לדוגמה, מחבר Chrome Cloud Print).
תהליך הרישום מורכב מ-3 שלבים (הצגת הרישום האנונימי של Cloud Print).
- התחלת תהליך רישום אנונימי.
- לקוח מתחיל את התהליך הזה באמצעות קריאה ל-/privet/enroll API. בשלב זה, המכשיר עשוי להמתין לאישור משתמש.
- קבלת אסימון תביעה.
הלקוח שואל אם המכשיר מוכן להמשיך. ברגע שהמכשיר מוכן, הוא שולח בקשה לשרת כדי לאחזר את אסימון הרישום ואת כתובת האתר לרישום. האסימון והכתובת URL שהתקבלו צריכים לחזור ללקוח. בשלב הזה, אם המכשיר מקבל שיחה נוספת כדי לאתחל את הרישום, עליו לבצע את הפעולות הבאות:
- אם אותו משתמש התחיל את הרישום, יש להסיר את כל הנתונים הקודמים (אם יש כאלה) ולהתחיל תהליך רישום חדש.
- אם זהו משתמש אחר – יש להחזיר את השגיאה מכשיר_עסוק עם זמן קצוב לתפוגה של 30 שניות.
משלימים את תהליך ההרשמה.
אחרי שהלקוח תובע בעלות על המכשיר, הלקוח צריך להודיע על כך למכשיר כדי להשלים את הרישום. לאחר השלמת תהליך הרישום, המכשיר ישלח הודעת עדכון, כולל מזהה המכשיר החדש שנרכש.
הערה: כשהמכשיר מעבד קריאות ל-/privet/enroll API, אין אפשרות לעבד קריאות אחרות מסוג /privet/enroll API בו-זמנית. המכשיר חייב להחזיר את השגיאה device_עסוק והזמן הקצוב לתפוגה יסתיים תוך 30 שניות.
מומלץ מאוד לאשר את המשתמש לרישום במכשיר. אם היא מיושמת, המכשיר חייב להמתין לאישור המשתמש לאחר קבלת /privet/enroll?action=start API. הלקוח יתקשר אל /privet/enroll?action=getClaimToken API כדי לברר מתי אישור המשתמש הושלם ואם אסימון הבעלות זמין. אם המשתמש מבטל את הרישום במכשיר (לדוגמה, לוחץ על הלחצן 'ביטול'), חובה להחזיר את השגיאה user_cancel. אם המשתמש לא אישר את הרישום בפרק זמן מסוים, יש להחזיר את הודעת האישור_timeout. מידע נוסף זמין בקטע ברירות המחדל.
4.3.1. הזנת קלט
/privet/enroll API כולל את הפרמטרים הבאים של קלט:שם | ערך |
---|---|
פעולה | ניתן להשתמש באחת מהאפשרויות הבאות:
start – כדי להתחיל בתהליך הרישום getClaimToken – אחזור אחזור התלונה במכשיר cancel – לביטול תהליך הרישום complete – להשלמת תהליך הרישום |
משתמש | כתובת האימייל של המשתמש שיתבע בעלות על המכשיר. |
המכשיר חייב לוודא שכתובת האימייל מכל הפעולות (התחלה, getClaimToken, ביטול, השלמת) תואמת.
4.3.2. הלוך ושוב
/privet/enroll API מחזיר את הנתונים הבאים:שם הערך | סוג ערך | תיאור |
---|---|---|
פעולה | string | פעולה זהה לזו של פרמטר הקלט. |
משתמש | מחרוזת (אופציונלי) | משתמש זהה לזה שבפרמטר הקלט (ייתכן שהוא חסר, אם הושמט בקלט). |
אסימון | מחרוזת (אופציונלי) | אסימון רישום (חובה עבור "getClaimToken" Response, הושמט עבור "start", "complete", "cancel"). |
claim_url [כתובת_URL_לתביעת בעלות] | מחרוזת (אופציונלי) | כתובת URL לרישום (חובה עבור "getClaimToken" Response, הושמטה עבור "start", "complete", "cancel" ). עבור מדפסות ענן, הוא צריך להיות ה-"complete_welcome_url" שהתקבלו מהשרת. |
auto_claim_url | מחרוזת (אופציונלי) | כתובת URL לרישום (חובה עבור "getClaimToken" Response, הושמטה עבור "start", "complete", "cancel" ). עבור מדפסות ענן, הוא צריך להיות ה-"automated_Invitation_url"התקבל מהשרת. |
מזהה_מכשיר | מחרוזת (אופציונלי) | מזהה מכשיר חדש (הושמט עבור "start" תגובה, חובה עבור "complete"). |
המכשיר חייב להחזיר את מזהה המכשיר שלו בתגובה /privet/info API רק בסיום ההרשמה.
דוגמה 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/enroll API עשוי לחזור אחרי השגיאות (לפרטים נוספים בקטע 'שגיאות'):שגיאה | תיאור |
---|---|
מכשיר_עסוק | המכשיר עסוק ואין אפשרות לבצע את הפעולה המבוקשת. אפשר לנסות שוב אחרי שתם הזמן הקצוב לתפוגה. |
בהמתנה_user_action | בתגובה ל- "getClaimToken" השגיאה הזו מציינת שהמכשיר עדיין בהמתנה לאישור המשתמש, ו&"getClaimToken" יש לנסות לבצע את הבקשה מחדש אחרי הזמן הקצוב לתפוגה. |
user_cancel | המשתמש ביטל במפורש את תהליך הרישום במכשיר. |
Certificate_timeout | תם הזמן הקצוב לאישור המשתמש. |
ערך לא חוקי | קריאה לפעולה לא חוקית. לדוגמה, אם הלקוח נקרא action=complete לפני הקריאה ל-action=start ו-action=getClaimToken. |
לא חוקי_פרמטרים | פרמטרים לא חוקיים שצוינו בבקשה. (התעלמות מפרמטרים לא מוכרים עבור תאימות עתידית). לדוגמה, אפשר להחזיר את הערך הזה אם הלקוח נקרא action=unknown או משתמש=. |
device_config_error | התאריך/שעה (או הגדרות אחרות) שגויים בצד המכשיר. המשתמש צריך לעבור (לאתר הפנימי של המכשיר) ולקבוע את הגדרות המכשיר. |
אופליין | המכשיר לא מחובר לאינטרנט ולכן לא ניתן לדבר עם השרת. |
שגיאה_בשרת | אירעה שגיאת שרת במהלך תהליך ההרשמה. |
לא חוקי_x_privet_token | X-Prive-Token אינו חוקי או ריק בבקשה. |
לאחר שהרישום יסתיים, המכשיר חייב להפסיק לחשוף את ה-/privet/enroll API. אם המכשיר לא חושף את ה-API /privet/enroll, עליו להחזיר שגיאת 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" . המכשיר חייב להטמיע את ה-API הזה בכתובת ה-URL &privet/accesstoken" :GET /privet/accesstoken HTTP/1.1
כשהמכשיר יקבל את קריאת ה-API /accesstoken, עליו להתקשר לשרת כדי לאחזר את אסימון הגישה של המשתמש הנתון ולהחזיר את האסימון ללקוח. אחרי כן, הלקוח ישתמש באסימון הגישה כדי לגשת למכשיר הזה דרך הענן.
מכשירי Cloud Print חייבים להפעיל את ה-API הבא:
/cloudprint/proximitytokenוגם ניתן להעביר את הפרמטר "printerid=<printer_id>" ואת "user" מה-API המקומי. אם התגובה לבקשה מוצלחת, היא תכלול את האובייקט הבא:
"proximity_token": { "user": "user@domain.com", "token": "AAA111222333444555666777", "expires_in": 600 }מכשירי Cloud Print חייבים להעביר את הערך של האובייקט "proximity_token" בתגובה לקריאות מקומיות ל-/privet/accesstoken API. השיטה הזו מועילה יותר (אם המכשיר יכול להעביר את כל הפרמטרים, כולל פרמטרים שלא מתוארים במפרט הזה).
4.4.1. הזנת קלט
/privet/accesstoken API כולל את הפרמטרים הבאים של קלט:שם | ערך |
---|---|
משתמש | כתובת האימייל של המשתמש שהתכוון להשתמש באסימון הגישה הזה. הבקשה עשויה להיות ריקה בבקשה. |
4.4.2. הלוך ושוב
/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. |
שגיאה_בשרת | שגיאת שרת. |
לא חוקי_x_privet_token | X-Privet-Token לא חוקי בבקשה או ריק. |
אם המכשיר לא חושף את ה-API /privet/accesstoken, הוא חייב להחזיר שגיאת HTTP 404. אם כותרת ה-X-Privet-Token חסרה, המכשיר חייב להחזיר שגיאת HTTP 400.
4.5. /privet/capabilities API
/privet/capabilities API הוא אופציונלי. זוהי בקשה מסוג HTTP GET. /privet/capabilities API חייב לבדוק אם קיימת כותרת חוקית "X-Privet-Token" . המכשיר חייב להטמיע את ה-API הזה ב-"/privet/capabilities" url:GET /privet/capabilities HTTP/1.1כשהמכשיר מקבל קריאה דרך /capabilities API, אם המכשיר יכול, עליו לפנות לשרת כדי לקבל יכולות מעודכנות. לדוגמה, אם מדפסת תומכת בפרסום משימת הדפסה (התקבלה באופן מקומי) לעצמו דרך שירות Cloud Print, היא אמורה להחזיר יכולות ששירות Cloud Print יחזיר. במקרה כזה, הדפסה ב-Cloud Print עשויה לשנות את יכולות המדפסת המקוריות, על ידי הוספה של תכונות חדשות שהיא עשויה לבצע לפני שליחת העבודה למדפסת. המקרה הנפוץ ביותר הוא רשימה של סוגי מסמכים נתמכים. אם המדפסת לא מחוברת לאינטרנט, היא אמורה להחזיר את סוגי המסמכים שבהם היא תומכת. עם זאת, אם המדפסת מחוברת ורשומה באמצעות Cloud Print, היא חייבת להחזיר "*/*" אחד מאחד הסוגים הנתמכים. במקרה כזה, שירות Cloud Print יבצע את ההמרה הנדרשת. עבור הדפסה במצב אופליין, המדפסת חייבת לתמוך לפחות בפורמט "image/pwg-raster"
4.5.1. הזנת קלט
/privet/capabilities API מכיל את הפרמטרים הבאים של קלט:שם | ערך |
---|---|
אופליין | (אופציונלי) אפשר רק "Offline=1". במקרה כזה, המכשיר אמור להחזיר יכולות לשימוש במצב אופליין (אם הן שונות מהיכולות "online" ). |
4.5.2. הלוך ושוב
/privet/capabilities API מחזיר יכולות למכשיר בפורמט JSON של תיאור המכשיר (CDD) (לפרטים, יש לעיין במסמך CDD). לכל הפחות, מדפסות חייבות להחזיר רשימה של סוגים נתמכים כאן. לדוגמה, מדפסת המותאמת לענן שיכולה להיות אונליין כרגע עשויה להחזיר מוצר כזה (לפחות)הערה: מדפסות יכולות לזהות סדרי עדיפויות של סוגי תוכן נתמכים באמצעות סדר מסוים. לדוגמה, בדוגמאות שלמעלה, המדפסת מציינת שהיא מעדיפה &"application/pdf" נתונים על "image/pwg-raster" ו-"image/jpeg". אם זה אפשרי, הלקוחות צריכים לכבד את העדיפות של המדפסת (לפרטים, אפשר לעיין במסמך CDD).
4.5.3. שגיאות
/privet/capabilities API עשוי לחזור אחרי השגיאות הבאות (לפרטים, יש לעיין בקטע 'שגיאות):שגיאה | תיאור |
---|---|
לא חוקי_x_privet_token | X-Prive-Token אינו חוקי או ריק בבקשה. |
אם המכשיר לא חושף את ה-API /privet/capabilities, הוא צריך להחזיר שגיאת HTTP 404. אם חסרה כותרת X-Privet-Token, המכשיר חייב להחזיר שגיאת HTTP 400.
4.6. שגיאות
השגיאות מוחזרות מממשקי ה-API שלמעלה בפורמט הבא:שם הערך | סוג ערך | תיאור |
---|---|---|
error | string | סוג שגיאה (מוגדר לכל API) |
תיאור | מחרוזת (אופציונלי) | תיאור השגיאה הקריא אנושי. |
server_api | מחרוזת (אופציונלי) | במקרה של שגיאת שרת, השדה הזה מכיל את ממשק ה-API של השרת שנכשל. |
קוד שרת | int (אופציונלי) | במקרה של שגיאת שרת, השדה הזה מכיל את קוד השגיאה שהשרת החזיר. |
שרת_http_code | int (אופציונלי) | במקרה של שגיאת HTTP בשרת, השדה הזה מכיל את שרת קוד השגיאות HTTP. |
זמן קצוב לתפוגה | int (אופציונלי) | מספר השניות שהלקוח ימתין לפני שינסה שוב (לשגיאות שניתן לשחזר בלבד). הערך של הלקוח חייב להיות אקראי בפועל, מהערך הזה לערך 20% ומעלה. |
כל ממשקי ה-API חייבים להחזיר שגיאת HTTP 400 אם חסרה כותרת X-Privet-Token.
כותרת 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 למדפסת
אחד מסוגי המכשירים שבהם הפרוטוקול הזה תומך הוא מדפסת סוג. מכשירים שתומכים בסוג זה עשויים ליישם פונקציונליות מסוימת שאינה תואמת למדפסות. במצב אידיאלי, הדפסה באמצעות מדפסות המתאימות לענן תעבור דרך שרת של Cloud Print:
במקרים מסוימים, ייתכן שהלקוח יצטרך לשלוח מסמך באופן מקומי. ייתכן שדרושה ללקוח כאשר אין לו מזהה Google או שאינו יכול לדבר אל שרת Cloud Print. במקרה כזה, משימת ההדפסה תישלח באופן מקומי למדפסת. לאחר מכן, המדפסת תשתמש בשירות Cloud Print להפעלת תור משימות והמרה. המדפסת תפרסם מחדש את העבודה שנשלחה באופן מקומי לשירות Cloud Print ולאחר מכן תבקש אותה מאחר שהיא נשלחה דרך הענן. התהליך הזה יספק חוויית משתמש גמישה במונחים של תנאים והגבלות (המרה) וניהול/מעקב אחר משימות הדפסה.
מאחר שהשירות Cloud Print מטמיע המרה, יש להציג את המדפסת בבית, שתומכת בכל הפורמטים של קלט ("*/*") מתוך רשימת סוגי התוכן הנתמכים:
{ "version": "1.0", "printer": { "supported_content_type": [ { "content_type": "image/pwg-raster" }, { "content_type": "*/*" } ] } }
במקרים מסוימים רצוי פתרון לא מקוון לחלוטין. מכיוון שהמדפסות תומכות במספר מוגבל של פורמטים של קלט, הלקוח צריך להמיר את המסמכים למספר פורמטים של מדפסות שנתמכות באופן מקורי.
המפרט הזה דורש את כל המדפסות התומכות בפורמט PWG Raster ("image/pwg-raster") לפחות עבור בקשת ההדפסה במצב אופליין. מדפסת עשויה לתמוך בפורמטים אחרים (לדוגמה, JPEG) ואם לקוח תומך בה, היא עשויה לשלוח מסמכים בפורמט הזה. המדפסת חייבת לחשוף סוגים נתמכים באמצעות ה-API /capabilities, לדוגמה:
{ "version": "1.0", "printer": { "supported_content_type": [ { "content_type": "image/pwg-raster" }, { "content_type": "image/jpeg" } ] } }יש שתי דרכים שבהן לקוח יכול להתחיל להדפיס ברשת המקומית.
הדפסה פשוטה – הלקוח שולח את המסמך ברשת המקומית ל-/submitdoc API (בלי לציין את הפרמטרJob_id). המסמך שנשלח יודפס לפי הגדרות ברירת המחדל של כרטיסי ההדפסה ואין צורך בסטטוסים של משימות הדפסה. אם המדפסת תומכת רק בסוג ההדפסה הזה, היא חייבת לפרסם רק ה-API /submitdoc בתגובת /privet/info API.
"api": [ "/privet/accesstoken", "/privet/capabilities", "/privet/printer/submitdoc", ]
הדפסה מתקדמת – הלקוח צריך קודם ליצור משימת הדפסה במדפסת על ידי קריאה ל-/privet/printer/createjob באמצעות ה-API של כרטיס CJT בבקשה. המדפסת חייבת לאחסן את כרטיס ההדפסה בזיכרון ולהחזיר ללקוח את מזהה העבודה. לאחר מכן, הלקוח יתקשר ל-/printer/submitdoc API ויציין את המספר הקודם של job_id. במועד זה, המדפסת תתחיל להדפיס. הלקוח יבחן את סטטוס הסטטוס של משימת ההדפסה על ידי קריאה ל-API /privet/printer/jobstate.
בסביבת ממשק מרובה לקוחות, לא מובטח איך ה-API הזה יופעל. ייתכן שלקוח אחד יוכל להתקשר אל /createjob בין קריאות /createjob->/submitdoc של לקוח אחר. כדי למנוע מצבי חסימה אפשריים ולשפר את נוחות השימוש, מומלץ להגדיר תור קטן של משימות הדפסה במדפסת (לפחות 3-5):
- /createjob מקבל את המקום הראשון בתור.
- אורך החיים של התור (בתור) הוא לפחות 5 דקות.
- אם יימצאו כל המקומות בתור, הם יוסרו והמשימה הישנה שלא תודפס תוסר.
- אם יש משימת הדפסה כרגע במכשיר (הדפסה פשוטה או מתקדמת), /submitdoc אמורה להחזיר את הסטטוס 'עסוק' ולהציע זמן קצוב לתפוגה כדי לנסות שוב את משימת ההדפסה הזו.
- אם הערך /submitdoc מתייחס לעבודה שהוסרה מ'הבאים בתור' (עקב החלפה או זמן קצוב לתפוגה), המדפסת צריכה להחזיר שגיאה invalid_print_job והלקוח ינסה שוב את התהליך מהשלב /createjob. הלקוח חייב להמתין תקופה אקראית של זמן קצוב לתפוגה של עד 5 שניות לפני שהוא מנסה שוב.
אם הגבלות הזיכרון מונעות אחסון של משימות בהמתנה רבות במכשיר, יכול להיות שאורך תור ההדפסה יהיה ארוך. היא אמורה להמשיך לפעול לפי הפרוטוקול המופיע למעלה. אחרי שמשימות הושלמו או נכשלות בגלל שגיאה, המדפסת צריכה לשמור מידע על סטטוס המשימה למשך 5 דקות לפחות. גודל התור לאחסון הסטטוסים צריך להיות לפחות 10. אם יש סטטוסים נוספים של עבודה שצריך לשמור, ייתכן שהסטטוס הישן ביותר יוסר מהתור לפני הזמן הקצוב לתפוגה של 5 דקות.
הערה: בשלב זה, לקוחות יכולים לערוך סקר כדי לראות את סטטוס המשרה. בעתיד, ייתכן שנדרוש מהמדפסת לשלוח התראת TXT DNS כאשר כל סטטוס של משימת הדפסה ישתנה.
5.1. /privet/printer/createjob API
/privet/printer/createjob API הוא אופציונלי (ראו הדפסות פשוטות למעלה). זוהי בקשה מסוג HTTP POST. /privet/printer/createjob API חייב לבדוק אם יש כותרת "X-Privet-Token" חוקית. המכשיר חייב להטמיע את ה-API הזה בכתובת "/privet/printer/createjob" url:
POST /privet/printer/createjob HTTP/1.1כשמקבלים קריאה /privet/printer/createjob API, המדפסת חייבת ליצור מזהה משימת הדפסה חדש, לאחסן את כרטיס ההדפסה שהתקבל בפורמט CJT, ולהחזיר ללקוח את מזהה משימת ההדפסה.
5.1.1. הזנת קלט
בכתובת /privet/printer/createjob API אין פרמטרים של קלט בכתובת ה-URL. גוף הבקשה צריך לכלול את נתוני הכרטיסים למשימת ההדפסה בפורמט CJT.5.1.2. הלוך ושוב
/privet/printer/createjob API מחזיר את הנתונים הבאים:שם הערך | סוג ערך | תיאור |
---|---|---|
מזהה_משימה | string | המזהה של משימת ההדפסה החדשה. |
בתוקף עד | int | מספר השניות שמשימת ההדפסה הזו חוקית. |
דוגמה:
{ "job_id": "123", "expires_in": 600 }
5.1.3. שגיאות
/privet/printer/createjob API עשוי להחזיר את השגיאות הבאות (פרטים נוספים בקטע 'שגיאות):שגיאה | תיאור |
---|---|
כרטיס_לא חוקי | כרטיס ההדפסה ששלחת לא חוקי. |
במכשיר_מדפסת | המדפסת עמוסה ואינה יכולה לעבד /createjob. אפשר לנסות שוב אחרי שתם הזמן הקצוב לתפוגה. |
שגיאה_במדפסת | המדפסת במצב שגיאה ודורשת אינטראקציה של המשתמש כדי לתקן אותה. התיאור צריך לכלול הסבר מפורט יותר (למשל, "Paper Jam in the Tray 1" ). |
לא חוקי_x_privet_token | X-Prive-Token אינו חוקי או ריק בבקשה. |
אם המכשיר לא חושף את השגיאה /privet/printer/createjob, הוא חייב להחזיר שגיאת HTTP 404. אם חסרה כותרת X-Privet-Token, המכשיר חייב להחזיר שגיאת HTTP 400.
5.2. /privet/printer/submitdoc API
/privet/printer/submitdoc API נדרש לצורך הטמעת הדפסה ברשת מקומית (אופליין או פרסום מחדש ב-Cloud Print). זוהי בקשת HTTP POST. /privet/printer/submitdoc API חייבים לבדוק אם יש כותרת "X-Privet-Token" חוקית. המכשיר חייב ליישם את ה-API הזה בכתובת ה-URL&&privet/printer/submitdoc" כתובת URL:POST /privet/printer/submitdoc HTTP/1.1כשמקבלים את הקריאה /privet/printer/submitdoc API, המדפסת צריכה להתחיל להדפיס. אם הוא לא יכול להתחיל בהדפסה, הוא חייב להחזיר את הודעת השגיאה להפעיל_מדפסת ואת משך הזמן המומלץ ללקוח כדי להמתין לפני שינסה שוב.
אם למדפסת אין אפשרות לשמור את כל הנתונים במאגר הפנימי שלה, היא אמורה להשתמש במנגנוני TCP כדי להאט את העברת הנתונים עד שהיא תדפיס חלק מהמסמך, כך שחלק מהמאגר יהיה זמין שוב. (לדוגמה, המדפסת עשויה להגדיר windowsize=0 בשכבות TCP, מה שיגרום ללקוח להמתין).
שליחת מסמך למדפסת עשויה להימשך זמן רב. הלקוח חייב להיות מסוגל לבדוק את מצב המדפסת והמשימה (הדפסה מתקדמת) במהלך ההדפסה. לשם כך, המדפסת חייבת לאפשר ללקוח לקרוא ל-API /privet/info ול-/privet/printer/jobstate APIs במהלך עיבוד קריאות /privet/printer/submitdoc API. מומלץ לכל הלקוחות להתחיל שרשור חדש כדי להפעיל את הקריאה ל- /privet/printer/submitdoc API, כדי שהשרשור הראשי יוכל להשתמש ב- /privet/info וב- /privet/printer/jobstate APIs כדי לבדוק את מצבי המדפסות והמשימות.
הערה: עם השלמת העבודה או הפלה של משימת ההדפסה המקומית, מומלץ מאוד (וידרש בגרסה עתידית של המפרט הזה) לדווח על מצבה הסופי של המשרה לממשק /cloudprint/submit, למטרות חשבונאות וחוויית משתמש. הפרמטרים "printerid", "title", "contentType" ו-"final_semantic_state" (בפורמט PrintJobState) הם שדות חובה, והפרמטרים "tag" (פרמטר חוזר) ו-" Card" (כרטיס המשרה בפורמט CloudJobTicket). חשוב לשים לב שה-PrintJobState שצוין חייב להיות סופי, כלומר יש לבצע את הסוג שלו או לבטל אותו, ויש לספק סיבה אם הוא בוטל (פרטים נוספים זמינים בקטע JobState). לתשומת ליבך, השימוש בממשק /cloudprint/submit לדיווח של משימות הדפסה מקומיות לא מוזכר במפרט שלו, כי הסעיף הזה נועד לתאר את השימוש העיקרי בממשק: שליחת משימת הדפסה עם המסמך להדפסה בפרמטר "content".
5.2.1. הזנת קלט
/privet/printer/submitdoc API כוללים את הפרמטרים הבאים של קלט:שם | ערך |
---|---|
מזהה_משימה | (אופציונלי) מזהה משימת הדפסה. יכול להיות שהושמטו עבור אירוע הדפסה פשוט (ראו למעלה). חייב להתאים לזה שהמדפסת החזירה. |
שם משתמש | (אופציונלי) שם שהמשתמש יכול לקרוא. זה לא סופי, ויש להשתמש בו רק בשביל הערות של משימות הדפסה. אם משרה פורסמה מחדש בשירות Cloud Print, המחרוזת הזו צריכה להיות מחוברת למשימת Cloud Print. |
client_name | (אופציונלי) השם של אפליקציית הלקוח שמבצעת את הבקשה הזו. למטרות תצוגה בלבד. אם המשימה פורסמה מחדש בשירות Cloud Print, מחרוזת זו צריכה להיות מחוברת למשימת Cloud Print. |
_work_name | (אופציונלי) השם של משימת ההדפסה שיש להקליט. אם המשימה פורסמה מחדש בשירות Cloud Print, צריך לצרף את המחרוזת הזו למשימה של Cloud Print. |
אופליין | (אופציונלי) אפשר רק "Offline=1". במקרה כזה, עליך לנסות להדפיס רק במצב אופליין (אין לפרסם מחדש בשרת Cloud Print). |
גוף הבקשה צריך להכיל מסמך חוקי להדפסה. "Content-Length" צריך לכלול את האורך הנכון של הבקשה. "Content-Type" צריך להגדיר את הסוג לסוג MIME של המסמך ולהתאים לאחד מהסוגים ב-CDD (אלא אם CDD מציין "*/*").
מומלץ מאוד לספק ללקוחות שם משתמש (או כתובת אימייל) חוקי, שם לקוח ושם עבודה עם הבקשה הזו. השדות האלה משמשים רק בממשקי משתמש כדי לשפר את חוויית המשתמש.
5.2.2. הלוך ושוב
/privet/printer/submitdoc API מחזיר את הנתונים הבאים:שם הערך | סוג ערך | תיאור |
---|---|---|
מזהה_משימה | string | המזהה של משימת ההדפסה החדשה (הדפסה פשוטה) או ה-Job_id שצוינה בבקשה (הדפסה מתקדמת). |
בתוקף עד | int | מספר השניות שמשימת ההדפסה הזו חוקית. |
סוג_משימה | string | סוג התוכן של המסמך שנשלח. |
גודל_משימה | int של 64 ביט | הגודל של נתוני ההדפסה בבייטים. |
_work_name | 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 עשוי להחזיר את השגיאות הבאות (פרטים נוספים בקטע 'שגיאות):שגיאה | תיאור |
---|---|
לא חוקי_בהדפסה | בבקשה מופיע מזהה משימה לא חוקי או שפג תוקפו. יש לנסות שוב אחרי הזמן הקצוב לתפוגה. |
לא_חוקי_מסמך | המדפסת לא תומכת בסוג ה-MIME של המסמך. |
לא חוקי_מסמך | המסמך שנשלח לא חוקי. |
document_too_large | המסמך חורג מהגודל המקסימלי המותר. |
במכשיר_מדפסת | המדפסת עמוסה ואינה יכולה לעבד מסמך כעת. אפשר לנסות שוב אחרי שתם הזמן הקצוב לתפוגה. |
שגיאה_במדפסת | המדפסת במצב שגיאה ודורשת אינטראקציה של המשתמש כדי לתקן אותה. התיאור צריך לכלול הסבר מפורט יותר (למשל, "Paper Jam in the Tray 1" ). |
לא חוקי_פרמטרים | פרמטרים לא חוקיים שצוינו בבקשה. (התעלמות מפרמטרים לא ידועים לצורך תאימות עתידית) |
user_cancel | המשתמש ביטל במפורש את תהליך ההדפסה מהמכשיר. |
שגיאה_בשרת | פרסום המסמך ב-Cloud Print נכשל. |
לא חוקי_x_privet_token | X-Prive-Token אינו חוקי או ריק בבקשה. |
אם המכשיר לא חושף את השגיאה /privet/printer/submitdoc, יש להחזיר שגיאת HTTP 404. אם כותרת ה-X-Privet-Token חסרה, המכשיר חייב להחזיר שגיאת HTTP 400.
לתשומת לבך: /privet/printer/submitdoc API עשוי לדרוש טיפול מיוחד בצד המדפסת כי המטען הייעודי גדול. במקרים מסוימים (בהתאם להטמעת שרת ה-HTTP והפלטפורמה של המדפסת), ייתכן שהמדפסת תיסגר עם שקע לפני החזרה של שגיאת HTTP. בהדפסה אחרת, המדפסת עשויה להחזיר שגיאת 503 (במקום שגיאת Privet). כדאי למדפסות לנסות כמה שיותר להחזיר את Privet. עם זאת, כל לקוח שמטמיע את המפרט של Privet אמור להיות מסוגל לטפל בסגירת socket (אין שגיאת HTTP) ובתיקיות מסוג 503 HTTP עבור /privet/printer/submitdoc API. במקרה כזה, הלקוח צריך לטפל בכתובת ה-URL הזו עם השגיאה 'Prvet "printer_ למשוך" עם שגיאה של "timeout" מוגדר ל-15 שניות. כדי להימנע מניסיונות חוזרים ללא הגבלה, הלקוח עשוי להפסיק את הניסיון החוזר לאחר מספר סביר של ניסיונות (לדוגמה, 3).
5.3. /privet/printer/jobstate API
/privet/printer/jobstate API הוא אופציונלי (ראו 'הדפסה פשוטה' למעלה). זוהי בקשה מסוג HTTP GET. /privet/printer/jobstate API חייב לבדוק אם יש כותרת חוקית "X-Privet-Token" . המכשיר חייב להטמיע את ה-API הזה בכתובת "/privet/printer/jobstate" url:GET /privet/printer/jobstate HTTP/1.1כשמקבלים קריאה ל- /privet/printer/jobstate API, מדפסת אמורה להחזיר את הסטטוס של משימת ההדפסה המבוקשת או שגיאה מסוג valid_print_job.
5.3.1. הזנת קלט
/privet/printer/jobstate API כולל את הפרמטרים הבאים של קלט:שם | ערך |
---|---|
מזהה_משימה | מזהה של משימת הדפסה להחזרת הסטטוס. |
5.3.2. הלוך ושוב
/privet/printer/jobstate API מחזיר את הנתונים הבאים:שם הערך | סוג ערך | תיאור |
---|---|---|
מזהה_משימה | string | כאן מופיע הסטטוס של משימת ההדפסה. |
מדינה | string | draft - משימת ההדפסה נוצרה במכשיר (עדיין לא התקבלו /privet/printer/submitdoc.
הבאים בתור – משימת ההדפסה התקבלה וממתינה בתור, אבל ההדפסה עוד לא התחילה. in_progress – משימת ההדפסה מתבצעת. הפסקתי – משימת ההדפסה הושהתה, אבל אפשר להפעיל אותה מחדש באופן ידני או אוטומטי. סיום – משימת ההדפסה הסתיימה. בוטלה – משימת ההדפסה נכשלה. |
תיאור | string | (אופציונלי) תיאור קריא למשתמשים של סטטוס משימת ההדפסה. צריך לכלול מידע נוסף אם הפרמטר state< הופסק או בוטל. השדה semantic_state בדרך כלל מספק ללקוח תיאור טוב ומשמעותי יותר. |
בתוקף עד | int | מספר השניות שמשימת ההדפסה הזו חוקית. |
סוג_משימה | string | (אופציונלי) סוג התוכן של המסמך שנשלח. |
גודל_משימה | int של 64 ביט | (אופציונלי) גודל נתוני ההדפסה בבייטים. |
_work_name | string | (אופציונלי) אותו שם משרה שהזנת (אם יש כזה). |
Server_job_id | string | (אופציונלי) מזהה העבודה שמוחזרת מהשרת (אם העבודה פורסמה בשירות Cloud Print). הושמטו לצורך הדפסה במצב אופליין. |
Semantic_state | JSON | (אופציונלי) המצב הסמנטי של המשרה בפורמט PrintJobState. |
דוגמה (הדפסה על ידי דיווח דרך Cloud Print):
{ "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 עשוי להחזיר את השגיאות הבאות (פרטים נוספים בקטע 'שגיאות):שגיאה | תיאור |
---|---|
לא חוקי_בהדפסה | צוין בבקשה מזהה משרה לא חוקי או שפג תוקפו. |
שגיאה_בשרת | קבלת הסטטוס של משימת ההדפסה (למשימות הדפסה שפורסמו ב-Cloud Print) נכשלה. |
לא חוקי_x_privet_token | X-Prive-Token אינו חוקי או ריק בבקשה. |
אם המכשיר לא חושף את השגיאה /privet/printer/jobstate, הוא חייב להחזיר שגיאת HTTP 404. אם כותרת ה-X-Privet-Token חסרה, המכשיר חייב להחזיר שגיאת HTTP 400.
6. נספח
6.1. התנהגות והגדרות ברירת מחדל
בקטע הזה נסביר את התנהגות ברירת המחדל שאנחנו מצפים מכל המכשירים שתואמים ל-Prive.- מכשירים מחוץ לקופסה צריכים לתמוך רק בממשקי API של /privet/info ו-/privet/enroll. יש להשבית את כל ממשקי ה-API האחרים (למשל /privet/accesstoken, local Print).
- כדי להירשם, נדרשת אינטראקציה פיזית עם מכשיר.
- המשתמש חייב לבצע פעולה פיזית במכשיר (למשל, לחיצה על לחצן) כדי לאשר את רמת הגישה שלו למכשיר.
- לאחר שהמשתמש מבצע את הפעולה שצוינה למעלה, המדפסת צריכה לשלוח את הבקשה / /cloudprint/enroll. אין לשלוח את הבקשה הזו עד לאחר ביצוע הפעולה (ראו את תרשים רצף 1).
- אם המכשיר מעבד בקשה /privet/enroll (למשל, בהמתנה לפעולה שלמעלה), הוא צריך לדחות את כל הבקשות /privet/enroll האחרות. במקרה כזה, המכשיר צריך להחזיר את השגיאה 'device_עסוק'.
- הזמן הקצוב לתפוגה של המכשיר צריך להיות 'זמן פעילות /רישום', שאינו מקבל את הפעולה הפיזית שצוינה למעלה תוך 60 שניות. במקרה כזה, המכשיר חייב להחזיר את השגיאה Confirm_timeout.
- אופציונלי: מומלץ לבצע את הפעולות הבאות, אבל לא חובה:
- המדפסת עשויה להדליק נורה או את המסך כדי לציין שהמשתמש צריך לבצע פעולה מסוימת כדי לאשר את הרישום.
- ייתכן שהמדפסת מציינת במסך ש'היא רשומה ל-Google Cloud Print עבור המשתמש 'abc@def.com' - יש ללחוץ על 'אישור' כדי להמשיך', כאשר abc@def.com הוא פרמטר המשתמש מקריאה /register API. כך יהיה ברור למשתמש:
- בקשת הרישום שהוא מאשר
- מה קורה אם הוא לא הפעיל את הבקשה.
- בנוסף לפעולה פיזית לאישור מהמדפסת (למשל, 'לוחצים על הלחצן 'אישור'), יכולים להציג במדפסת גם לחצן לביטול הבקשה (למשל, 'יש ללחוץ על 'ביטול' כדי לדחות'. זה יאפשר למשתמשים שלא הפעילו את בקשת הרישום לבטל אותה לפני תום הזמן הקצוב של 60 השניות. במקרה כזה, המכשיר חייב להחזיר את השגיאה user_cancel.
- בקשות להעברת בעלות:
- יכול להיות שהמכשיר יימחק במפורש משירות הענן.
- אם המכשיר הצליח, אבל אין תיאור של המכשיר כתוצאה מהקריאה /cloudprint/printer (עבור GCP), הוא חייב לחזור למצב ברירת המחדל (מחוץ לאריזה).
- אם פרטי הכניסה של המכשיר לא פועלים יותר (באופן מפורש עקב תגובה &ote;invalid, in" השרת), הם חייבים לחזור למצב ברירת מחדל (out-box)
- איפוס להגדרות המקוריות חייב למחוק את פרטי הכניסה של המכשיר ולהגדיר אותו למצב ברירת המחדל.
- אופציונלי: המכשיר יכול לספק אפשרות בתפריט כדי לנקות את פרטי הכניסה ולהעביר אותם למצב ברירת מחדל.
- המכשירים שתומכים בהתראות XMPP חייבים לכלול את האפשרות לשלוח פינג לשרת. הזמן הקצוב לתפוגה של הפינג חייב להיות בשליטת השרת דרך "local_settings"
- המכשיר יכול לבצע פינג מפורש של השרת (/cloudprint/printer API for GCP, בנוסף לפינגים של XMPP), בתדירות גבוהה מדי פעם ביום (24 שעות) כדי לוודא שהוא מסונכרן. מומלץ להגדיר באקראי את חלון הבדיקה תוך 24 עד 32 שעות.
- אופציונלי: במכשירים שמיועדים ל-Cloud Print, מומלץ לא לבצע את הפעולה הזו באופן ידני (באמצעות לחצן) כדי לאפשר למשתמש לבצע בדיקה במשימות הדפסה חדשות במכשיר. כבר יש מדפסות מסוימות.
- אופציונלי. במדפסות ארגוניות עשויה להיות אפשרות להשבית לגמרי את הגילוי המקומי. במקרה כזה, המכשיר חייב לעדכן את ההגדרות המקומיות האלה בשרת. ההגדרות המקומיות החדשות חייבות להיות ריקות (&"local_discovery" to "false", ופירוש הדבר שניתן להפעיל אותן מחדש משירות GCP).
6.1.2 תרשים ברירת המחדל של הרישום
6.2. מתקפות ומניעה של XSSI ו-XSRF
בקטע הזה נסביר את האפשרות למתקפות XSSI ו-XSRF במכשיר ואיך להגן עליהן מפניהן (כולל שיטות ליצירת אסימונים).פרטים נוספים זמינים כאן: http://googleonlinesecurity.blogspot.com/2011/05/website-security-for-webmasters.html
בדרך כלל, מתקפות XSSI ו-XSRF אפשריות כאשר אתר משתמש במנגנונים לאימות של קובצי cookie. Google לא משתמשת בקובצי Cookie באמצעות שירות Cloud Print, אבל עדיין יש מתקפות כאלה. גישה לרשת מקומית, על סמך התכנון, סומכת באופן מפורש על בקשות.
6.2.1. XSSI
בעלי אתרים זדוניים יכולים לנחש את כתובת ה-IP ואת מספר היציאה של מכשיר התואם ל-Privet, ולנסות להתקשר ל-Pvet API כדי להשתמש ב-"src=<api name>" כחלק מ-<script> :<script type="text/javascript" src="http://192.168.1.42:8080/privet/info"></script>ללא הגנה, אתרים זדוניים יוכלו לבצע קריאות ל-API ולגשת לתוצאות שלהן.
כדי למנוע סוג זה של תקיפה, כל הקריאות ל-API של Privet חייבות לדרוש את הכותרת "X-Privet-Token" בבקשה. "src=<api>"תגי סקריפט לא יכולים להוסיף כותרות, וכך להגן ביעילות מפני התקפות כאלה.
6.2.2. XSRF
http://en.wikipedia.org/wiki/Cross-site_request_forgeryיכול להיות שאתר זדוני ינחש את כתובת ה-IP ואת מספר היציאה של מכשיר התואם ל-Privet API וינסה להתקשר ל-Prvet 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 הוא מספר השניות מאז אירוע מסוים (תקופה של חותמת זמן) או זמן ההפעלה של המכשיר (למונים של יחידת העיבוד המרכזית). בעיה_timeבר גדל כל הזמן כשהמכשיר פועל.
- SHA1 – פונקציית גיבוב (hash) באמצעות אלגוריתם SHA1
- base64 – קידוד base64
- device_Secret – סוד המכשיר. צריך לעדכן את הסוד של המכשיר בכל הפעלה מחדש.
דרכים מומלצות ליצירת סוד מכשיר:
- יצירת UUID חדש בכל הפעלה מחדש
- יצירת מספר אקראי בן 64 ביט בכל הפעלה מחדש
המכשיר אינו נדרש לאחסן את כל אסימוני ה-XSRF שהונפקו. כשהמכשיר צריך לאמת אסימון XSRF לצורך אימות, עליו לקודד את האסימון ב-644. מורידים את הפרמטר issue_timeCounter מהמחצית השנייה (cleartext), ומנסים להפיק גיבוב SHA1 של device_Secret + + issue_timecross, כאשר האסימון ן אם האלגוריתם SHA1 החדש תואם לזה שבאסימון, המכשיר צריך לבדוק עכשיו אם ה-ISSUE_timecounter נמצא בטווח התוקף של (24 שעות) ממונה הזמן הנוכחי. כדי לעשות זאת, המכשיר לוקח את מונה הזמן הנוכחי (לדוגמה, מונה CPU) ומוריד ממנו את ISSUE_timecounter. התוצאה חייבת להיות מספר השניות מאז הבעיה באסימון.
חשוב: זו הדרך המומלצת להטמיע הגנה מסוג XSRF. הלקוחות של מפרט Privet לא ינסו להבין את אסימון XSRF, אלא שהם יתייחסו אליו כאל קופסה שחורה. איור 6.2.3 ממחיש את הדרך המומלצת להטמעה של אסימון X-Prive-Token ואימות של בקשה אופיינית.