Docstoc

Win32 API– '

Document Sample
Win32 API–            ' Powered By Docstoc
					                          ‫תרגול – יום רביעי‬
                                                       ‫שרת ‪ HTTP‬פשוט (5 שעות)‬
    ‫במסגרת תרגיל זה תכתבו שרת ‪ HTTP‬אמיתי שאפשר להתחבר אליו באמצעות ‪ Internet Explorer‬או‬
    ‫‪ Firefox‬ולצפות בדפים. עכב מגבלות הזמן, השרת יהיה מצומצם ביכולותיו וידע להגיש רק דפים סטיים‬
  ‫שנמצאים בספריה על המחשב שלכם. כמו כל שרת ראוי לשמו הוא ירוץ כ-‪ service‬ב-‪ .Windows‬תיאור‬
                                              ‫פשוט של פרוטוקול ‪ HTTP‬ניתן למצוא בנספח לתרגיל.‬

                                                                               ‫מימוש השרת‬
  ‫השרת יהיה תוכנת ‪ command line‬ויהיה כתוב בשפת ‪( C‬או ++‪ C‬למי שמכיר ורוצה). הוא יפתח ‪socket‬‬
‫על פורט 0808 ויאזין לחיבורים נכנסים. עבור כל חיבור נכנס, הוא יקרא את תוכן הבקשה, יפענח אותה בכדי‬
     ‫להבין מה הקובץ הנדרש וישלח את תוכן הקובץ ללקוח. במידה והשרת לא ימצא את הקובץ הנדרש, הוא‬
   ‫יחזיר ללקוח קוד שגיאה 404 (‪ .)Not Found‬במידה והשרת לא יצליח לפענח את הבקשה, הוא יחזיר קוד‬
                                                                 ‫שגיאה 004 (‪.)Invalid Request‬‬

    ‫השרת יאפשר גישה לקבצים שיושבים תחת הספריה "‪ "files‬בספרייה בה נמצא ה-‪ EXE‬של השרת, כך‬
              ‫שגישה באמצעות דפדפן ל-‪ http://localhost:8080/somefile.txt‬תחזיר את תוכן הקובץ‬
                                                                         ‫‪.files/somefile.txt‬‬

  ‫השרת יטפל רק בבקשות ‪ GET‬ויחזיר שגיאה 004 (‪ )Invalid Request‬עבור בקשות מסוג אחר (‪POST‬‬
     ‫וכו'). אין צורך להתייחס ל-‪ headers‬ששולח הלקוח, כל המידע הנדרש לצורך התרגיל נמצא בשורה‬
                                                                     ‫הראשונה של הבקשה.‬

     ‫עבור כל בקשה, השרת ידפיס את ה-‪ method‬שהגיעה בבקשה, ה-‪ url‬שהתבקש, את הססטוס שהחוחזר‬
                                                                           ‫ושגיאות שקרו.‬

       ‫השרת צריך לקבוע את ערך הכותר ‪ Content-Type‬בתשובה בהתאם לסיומת המבוקשת של הקובץ:‬

                                                        ‫‪Content-Type‬‬               ‫סיומות‬
                                                              ‫‪text/html‬‬         ‫‪htm, html‬‬
                                                           ‫‪image/jpeg‬‬                 ‫‪jpg‬‬
                                                            ‫‪image/png‬‬                 ‫‪png‬‬
                                                             ‫‪image/gif‬‬                 ‫‪gif‬‬
                                                             ‫‪text/plain‬‬                ‫‪txt‬‬
                                                                ‫‪text/css‬‬               ‫‪css‬‬
                                                             ‫‪text/plain‬‬               ‫אחר‬

   ‫השרת צריך לדעת לפעול בשני מצבים – הן כתוכנה רגילה והן כ-‪( service‬בעיקר כי זה כאב ראש רציני‬
           ‫ביותר לדבג ‪-service‬ים). הקביעה של המצב תתבצע ע"י בחינת פרמטר ה-‪ argv‬של ה-‪.main‬‬

  ‫אם מפעילים את השרת עם הפרמטר ‪ ,--service‬הוא יפעיל את המנגנונים הנדרשים לתקשורת‬          ‫‪‬‬
                                                  ‫מול ה-‪.Service Control Manager‬‬
  ‫כאשר במצב ‪ ,Service‬השרת צריך לדעת לטפל באופן נכון בבקשות ‪ Start, Pause, Resume‬ו-‬       ‫‪‬‬
       ‫‪( Stop‬שימו לב שהדוגמא שהוצגה לכם בשיעור לא כוללת תמיכה ב-‪ Pause/Resume‬ואתם‬
                                                     ‫צריכים למצוא דרך לממש זאת לבד).‬
        ‫אם מפעילים אותו עם הפרמטר ‪ ,--standalone‬הוא פשוט יתחיל לרוץ ולהאזין לבקשות.‬      ‫‪‬‬

      ‫לבדיקת השרת שלכם אתם יכולים לשים את ה-‪ Winsock FAQ‬שנמצא בספריית ‪ more‬של הרצאת‬
    ‫‪ Winsock‬בתיקיית ה-‪ files‬שלכם ולנסות לקרוא את האתר דרך השרת שלכם. התמונות להיות מוצגות‬
                                                               ‫ומרבית הלינקים אמורים לעבוד.‬

                                                                                     ‫הערות‬
    ‫בסיום שליחת התוכן ללקוח, השרת צריך לסגור את הקשר. שימו לב שאתם סוגרים אותו בצורה‬     ‫‪‬‬
  ‫מסודרת עם ‪-read ,shutdown‬ים ו-‪ ,closesocket‬אחרת חלק מהמידע ששלחתם עלול לא להגיע‬
                                                                                ‫ללקוח.‬
   ‫לצורך פשטות אתם יכולים להניח שהבקשה לא תהיה גדולה מ-‪ 2K‬ולקרוא אותה בבת אחת לתוך‬       ‫‪‬‬
                                                          ‫‪ buffer‬שהקצאתם מבעוד מועד.‬
    ‫אתם לא יכולים להניח דבר לגבי גודל הקובץ שאתם שולחים כתשובה ולכן אסור לכם לטעון את‬    ‫‪‬‬
  ‫הקובץ לזכרון. השתמשו ב-‪ CreateFile‬בכדי לפתוח את הקובץ, ב-‪ GetFileSize‬בכדי לקבל את‬
        ‫הגודל שלו עבור כותר ה-"‪ "Content-Length‬וב-‪ ReadFile‬בכדי לקרוא את תוכן הקובץ‬
                 ‫בחתיכות ולשלוח אותו ללקוח. אל תשכחו לסגור את הקובץ עם ‪.CloseHandle‬‬
 ‫בניגוד לשרת אמיתי, השרת שלכם יוכל לטפל בבקשה אחת בלבד בזמן נתון. אין צורך להתעסק עם‬     ‫‪‬‬
                                                                           ‫‪-thread‬ים.‬
‫שימו לב שגם אם בקשה מסויימת נכשלת ואתם מחזירים סטטוס שגיאה, השרת צריך להמשיך לרוץ.‬       ‫‪‬‬
   ‫כאשר אתם מחזירים סטטוס שגיאה ללקוח, מעבר לקוד הסטטוס ותיאור הסטטוס שמופיע בשורת‬       ‫‪‬‬
                          ‫התשובה הראשונה, תשלחו גם תוכן שמתאר את השגיאה יותר בפירוט.‬
                                                              ‫להלן דוגמא לתשובה כזאת:‬

         ‫‪HTTP/1.1 404 NOT FOUND‬‬
         ‫03 :‪Content-Length‬‬
         ‫‪Content-Type: text/plain‬‬

         ‫!'‪Can't find '/files/momo.txt‬‬




‫בהצלחה !‬
                                                           ‫נספח – פרוטוקול ‪HTTP‬‬
                       ‫לצורכי פשטות התיאור שלהלן אינו מלא ומכיל רק את מה שנדרש לביצוע התרגיל.‬

   ‫‪( Hypertext Transfer Protocol‬ראשי תיבות: ‪ )HTTP‬הוא פרוטוקול תקשורת שנועד להעברת דפי‬
         ‫‪ HTML‬ואובייקטים שהם מכילים (כגון תמונות) ברשת האינטרנט. הפרוטוקול פועל בשכבת ה-‬
                                                           ‫‪ ,Application‬מעל פרוטוקול ‪.TCP‬‬

   ‫בתקשורת ‪ HTTP‬משתתפים שרת (שאתם הולכים לכתוב) ולקוח (לרוב דפדפן כגון ‪ IE‬או ‪.)Firefox‬‬
  ‫הדפדפן יוזם את התקשורת ע"י יצירת קשר ‪ TCP‬מול השרת ושליחת בקשה שמכילה את כתובת הקובץ‬
  ‫המבוקש (למשל, דף ‪ .)HTML‬השרת מפענח את הבקשה ושולח ללקוח תשובה, שמכילה אינדיקציה על‬
           ‫ההצלחה או הכישלון של פעולה וכן את תוכן הקובץ. בסיום השליחה, השרת מנתק את הקשר.‬

                                                              ‫בקשה – ‪HTTP Request‬‬
                           ‫כאשר אנחנו מבקשים מהדפדפן שלנו להגיש לנו את התוכן שנמצא בכתובת‬
                    ‫‪ ,http://en.wikipedia.org/wiki/HTTP‬נשלחת בקשה לשרת שנראית בערך כך:‬

        ‫1.1/‪GET /wiki/HTTP HTTP‬‬
        ‫‪Host: en.wikipedia.org‬‬
        ‫0.5/‪User-Agent: Mozilla‬‬
        ‫:‪Accept‬‬
        ‫8.0=‪text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q‬‬
        ‫5.0=‪Accept-Language: en-us,en;q‬‬
        ‫‪Accept-Encoding: gzip,deflate‬‬
        ‫7.0=‪Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q‬‬
        ‫003 :‪Keep-Alive‬‬
        ‫‪Connection: keep-alive‬‬
        ‫‪If-Modified-Since: Tue, 19 Aug 2008 08:21:05 GMT‬‬


  ‫הבקשה (כמו כל דבר בצבא) מורכבת משלושה חלקים: השורה הראשונה מתארת את האובייקט שהלקוח‬
  ‫רוצה לקבל. השורות הבאות (עד להופעתה של שורה ריקה) מוסיפות מידע על הבקשה ועל הלקוח. החלק‬
                                                      ‫השלישי והאופציונאלי מכיל תוכן לבקשה.‬

                                               ‫השורות בפרוטוקול מופרדות ע"י רצף התווים "‪."\r\n‬‬

  ‫שורת הבקשה (השורה הראשונה המודגשת) מתחלקת גם היא לשלושה חלקים המופרדים ע"י רווח בודד.‬

   ‫החלק הראשון נקרא ‪ method‬ומתאר את סוג הבקשה. בקשות מסוג ‪ GET‬שמבקשות שהשרת‬               ‫‪‬‬
‫ישלח חזרה תוכן של קובץ. בקשות מסוג ‪ POST‬מאפשרות להעלות תוכן לשרת (למשל כשעושים‬
                                          ‫‪ submit‬ל-‪ )form‬וכן סוגים נוספים, נדירים יותר.‬
  ‫החלק השני של שורת הבקשה מכיל את כתובת האובייקט (הקובץ) אותו הלקוח רוצה לקבל. זהו‬        ‫‪‬‬
            ‫למעשה החלק של ה-‪ URL‬שהזנו בדפדפן שבא אחרי הפרוטוקול (‪ )http‬ושם השרת‬
                                      ‫(‪ .)en.wikipedia.org‬הכתובת תמיד מתחילה בלוסכן.‬
‫החלק השלישי של שורת הבקשה מתאר את גרסת הפרוטוקול שהלקוח תומך בו. נכון לרגע זה, כל‬         ‫‪‬‬
          ‫הדפדפנים המוכרים שולחים כאן 1.1/‪ HTTP‬ואנחנו נתעלם מערך זה לצורכי התרגיל.‬
‫הכותרים (תרגום רע למילה ‪ )headers‬מספרים דברים נוספים על הבקשה ועל הלקוח. כל כותר תופס שורה‬
    ‫אחת בדיוק (מופרדת עם "‪ "\r\n‬כמובן) ומכיל את שם הכותר ואת הערך שלו מופרדים ע"י נקודותיים.‬
           ‫לצורכי תרגיל זה אנחנו נתעלם מהכותרים לחלוטין. רצף הכותרים מסתיים תמיד בשורה ריקה.‬

‫עבור סוגים מסויימים של בקשות (כגון ‪ POST‬שמאפשרת להעלות מידע לשרת), הלקוח נדרש לספק תוכן‬
   ‫לבקשה (למשל את תוכן הקובץ שהלקוח רוצה להעלות). התוכן יגיע אחרי השורה הריקה שמסיימת את‬
‫הרצף הכותרים. בתרגיל זה אנחנו נתעלם מתוכן אפשרי בבקשה, היות והשרת שלנו לא יודע לטפל בבקשות‬
                                                                                    ‫‪.POST‬‬

                                                          ‫תשובה – ‪HTTP Response‬‬
‫כאשר שרת ה-‪ HTTP‬מבקל את הבקשה ומפענח אותה, הוא שולח ללקוח תשובה. התשובה גם היא מורכבת‬
                                                            ‫משלושה חלקים ונראית למשל כך:‬

        ‫‪HTTP/1.1 200 OK‬‬
        ‫31 :‪Content-Length‬‬
        ‫‪Content-Type: text/plain‬‬

        ‫!‪Hello, World‬‬


   ‫שורת התשובה הראשונה מתארת את סטטוס הבקשה – האם הבקשה הצליחה או נכשלה ואם נכשלה מה‬
 ‫היתה סיבת הכשלון. השורה מורכבת משלושה חלקים מופרדים ע"י רווח – החלק הראשון מתאר את גרסת‬
       ‫הפרוטוקול, החלק השני הוא הקוד המספרי של הסטטוס והחלק האחרון הוא התיאור המילולי שלו.‬

                                                                 ‫להלן מספר ססטוסים שימושיים:‬

                     ‫002 – ‪ – OK‬הבקשה הצליחה והתשובה כוללת את תוכן הקובץ הנדרש‬          ‫‪‬‬
                             ‫004 – ‪ – Bad Requeset‬השרת לא הצליח לפענח את הבקשה‬          ‫‪‬‬
                                 ‫404 – ‪ – Not Found‬השרת לא מצא את הקובץ המבוקש‬          ‫‪‬‬
         ‫005 – ‪ – Internal Server Error‬השרת נתקל בשגיאה פנימית ולא יכל לטפל בבקשה‬       ‫‪‬‬
                 ‫105 – ‪ – Not Implemented‬השרת לא יודע לטפל בסוג הבקשה שנשלחה‬            ‫‪‬‬

 ‫לאחר שורת התשובה מגיעה רשימה של כותרים הבנויים באופן דומה מאוד לכותרים של הבקשה. כל כותר‬
  ‫מופיע על שורה נפרדת ומורכב משם וערך המופרדים ע"י נקודותיים. בסוף רשימת הכותרים מגיעה שורה‬
                                                    ‫ריקה. גם כאן כל השורות מופרדות ע"י "‪."\r\n‬‬

 ‫כותר מאוד חשוב הוא ה-"‪ "Content-Length‬שמתאר את אורך הקובץ שאתם מחזירים בתשובה בבתים.‬
                  ‫כותר חשוב אחר הוא ה-"‪ "Content-Type‬שמתאר את סוג הקובץ שאתם מחזירים.‬

 ‫לאחר השורה הריקה שמציינת את סוף הכותרים מגיע תוכן התשובה – כלומר תוכן הקובץ המבוקש. אורך‬
                               ‫התוכן צריך להיות זהה לערך שנרשם בכותר ה-"‪."Content-Length‬‬

				
DOCUMENT INFO
Shared By:
Categories:
Stats:
views:38
posted:4/17/2010
language:Hebrew
pages:4
Jun Wang Jun Wang Dr
About Some of Those documents come from internet for research purpose,if you have the copyrights of one of them,tell me by mail vixychina@gmail.com.Thank you!