اشکال زدایی Google Data API Clients: کاوش ترافیک از درون برنامه شما

جفری اسکادر، تیم Google Data APIs
ژوئن 2007

معرفی

گاهی اوقات هیچ جایگزینی برای دیدن آنچه از روی سیم می گذرد وجود ندارد. این امر به ویژه هنگام نوشتن نرم‌افزاری که از سرویس‌های وب مانند Google Data API استفاده می‌کند، که در آن بسیاری از عملیات شامل درخواست‌های HTTP هستند، صادق است. وقتی همه چیز شکست خورد، می توانید با دیدن بایت های ارسال شده و دریافتی واقعی، تأیید کنید که برنامه شما همان کاری را که انتظار دارید انجام می دهد. بسیاری از کتابخانه های سرویس گیرنده برای APIهای Google Data یک حالت اشکال زدایی دارند که ترافیک HTTP را نمایش می دهد. این به ویژه زمانی مفید است که به یک بسته sniffer مانند WireShark یا Fiddler دسترسی ندارید.

نمی‌توانم تعداد دفعاتی را که می‌توانم قسم بخورم که برنامه‌ام درست است، بشمارم، فقط با بررسی یک بسته بسته متوجه شدم که یک کاراکتر جدید خط جدید یا یک عنوان HTTP با نام اشتباه وجود دارد. برنامه نویسی در برابر یک وب سرویس بدون نگاه کردن به ترافیک HTTP می تواند مانند تلاش برای نخ زدن سوزن با چشمان بسته باشد.

با این حال، ممکن است در موقعیتی قرار بگیرید که یک sniffer بسته در دسترس نباشد یا برای مقابله با بسته های رمزگذاری شده کافی نباشد. هرگز نترسید - می توانید با استفاده از برخی مکانیسم های ثبت درون برنامه ای از این محدودیت عبور کنید. با استفاده از این امکانات ثبت‌نام، می‌توانید برخی، اگر نه همه، داده‌های مبادله شده را مشاهده کنید، حتی برای داده‌های HTTPS رمزگذاری‌شده یا کدهای در حال اجرا از راه دور.

برای این مقاله، من نمونه کد تشخیصی را به 3 زبان با استفاده از کتابخانه های سرویس گیرنده Google Data API برای جاوا ، دات نت و پایتون نوشته ام. در هر مثال، من ورود به سیستم یا اشکال زدایی را روشن می کنم، با استفاده از ورود به سیستم کلاینت احراز هویت می کنم، و سپس فهرستی از صفحات گسترده گوگل خود را دریافت می کنم و عناوین آنها را چاپ می کنم.

جاوا

می‌توانید از کلاس‌های java.util.logging برای تنظیم سطوح گزارش‌گیری (و در نتیجه نمایش داده‌های ترافیک) برای چند شیء کلیدی در کتابخانه مشتری استفاده کنید. در مثال زیر، من تصمیم گرفتم به سربرگ های HTTP و فعالیت های تجزیه کننده XML نگاه کنم تا نمای کاملی از آنچه در حال حرکت است را داشته باشم.

کتابخانه سرویس گیرنده Google Data Java دارای کلاس‌های جداگانه برای رسیدگی به درخواست‌های HTTP و تجزیه XML است. بنابراین، من باید دو شی Logger ایجاد کنم، یکی برای هر کلاس: com.google.gdata.client.http.HttpGDataRequest ترافیک HTTP را مدیریت می کند در حالی که com.google.gdata.util.XmlParser مسئول تجزیه XML است.

نمونه‌های لاگر فعالیت‌های HttpGDataRequest و XmlParser را ضبط می‌کنند و می‌توانید سطح جزئیات خروجی هر لاگر را کنترل کنید. برای این نمایش، من تمام رویدادهای تولید شده توسط اشیاء HttpGDataRequest و XmlParser را انتخاب کرده‌ام.

هنگامی که Logger های خود را ایجاد و پیکربندی کردم، باید به آنها بگویم وقتی رویدادی را از کلاس های خود دریافت می کنند چه کاری انجام دهند. در حال حاضر، من می خواهم تمام اطلاعات ورود به سیستم را در کنسول بنویسم، بنابراین یک ConsoleHandler ایجاد می کنم و آن را به هر دو Logger خود اضافه می کنم.

این کد نمونه من است:

import com.google.gdata.client.spreadsheet.*;
import com.google.gdata.data.spreadsheet.*;
import com.google.gdata.util.*;
import java.io.*;
import java.net.URL;
import java.util.*;
import java.util.logging.*;

public class PrintSpreadsheetsWithLogging {
   
   
public static void main(String [] args) throws AuthenticationException,
                                                   
ServiceException, IOException {
       
// Configure the logging mechanisms.
       
Logger httpLogger = Logger.getLogger("com.google.gdata.client.http.HttpGDataRequest");
        httpLogger
.setLevel(Level.ALL);
       
Logger xmlLogger = Logger.getLogger("com.google.gdata.util.XmlParser");
        xmlLogger
.setLevel(Level.ALL);
       
// Create a log handler which prints all log events to the console.
       
ConsoleHandler logHandler = new ConsoleHandler();
        logHandler
.setLevel(Level.ALL);
        httpLogger
.addHandler(logHandler);
        xmlLogger
.addHandler (logHandler);
       
       
SpreadsheetService service = new SpreadsheetService("testing-loggingExampleApp-1");
        service
.setUserCredentials(email, password);
     
       
// Get a list of your spreadsheets.
        URL metafeedUrl
= new URL("http://spreadsheets.google.com/feeds/spreadsheets/private/full ");
       
SpreadsheetFeed feed = service.getFeed(metafeedUrl, SpreadsheetFeed.class);
     
       
// Print the title of each spreadsheet.
       
List spreadsheets = feed.getEntries();
       
for (int i = 0; i < spreadsheets.size(); i++) {
         
SpreadsheetEntry entry = (SpreadsheetEntry)spreadsheets.get(i);
         
System.out.println("\t" + entry.getTitle().getPlainText());
       
}
   
}
}

هنگامی که این برنامه را اجرا می کنید، چیزی شبیه به این را در کنسول خواهید دید (من برخی از قسمت های کمتر جالب را حذف کردم):

Jun 7, 2007 10:24:50 AM ...HttpGDataRequest setPrivateHeader
FINER: Authorization: <Not Logged>
Jun 7, 2007 10:24:50 AM ...HttpGDataRequest setHeader
FINER: User-Agent: ...
...
Jun 7, 2007 10:25:20 AM ...HttpGDataRequest execute
FINE: 200 OK
Jun 7, 2007 10:25:20 AM ...HttpGDataRequest execute
FINER: Date: Thu, 07 Jun 2007 17:25:24 GMT
Jun 7, 2007 10:25:20 AM ...HttpGDataRequest execute
FINER: null: HTTP/1.1 200 OK
Jun 7, 2007 10:25:20 AM ...HttpGDataRequest execute
FINER: Content-Type: application/atom+xml; charset=UTF-8
Jun 7, 2007 10:25:20 AM ...HttpGDataRequest execute
FINER: Last-Modified: Thu, 07 Jun 2007 17:25:22 GMT
...
Jun 7, 2007 10:25:20 AM ...XmlParser startElement
FINE: Start element id
Jun 7, 2007 10:25:20 AM ...XmlParser endElement
FINE: End element id
...
Jun 7, 2007 10:25:20 AM ...XmlParser startElement
FINE: Start element title
Jun 7, 2007 10:25:20 AM ...XmlParser startElement
FINER: Attribute type='text'
Jun 7, 2007 10:25:20 AM ...XmlParser endElement
FINE: End element title
...
Jun 7, 2007 10:25:20 AM ...XmlParser endElement
FINE: End element entry
...
Jun 7, 2007 10:25:20 AM ...XmlParser endElement
FINE: End element feed

این گزارش‌ها می‌توانند بسیار بزرگ باشند، بنابراین ممکن است بخواهید در تنظیم سطوح Loggerها انتخابی‌تر باشید. همچنین می توانید به جای ConsoleHandler یک FileHandler ایجاد کنید تا به شما امکان دهد داده های گزارش را برای استفاده بعدی ذخیره کنید.

البته، اگر جاوا کیف شما نیست، می توانید دات نت را امتحان کنید.

.خالص

برای گرفتن ترافیک HTTP در کتابخانه کلاینت دات نت، می توانید کارخانه درخواست پیش فرض در کلاینت را با یک GDataLoggingRequestFactory جایگزین کنید.

درخواست های HTTP در کتابخانه دات نت توسط GDataRequestFactory که در داخل هر شیء Service قرار دارد ایجاد می شود. کارخانه‌های درخواست عادی هیچ گزارشی را انجام نمی‌دهند، اما GDataLoggingRequestFactory ، که زیرکلاس GDataRequestFactory است، دارای ورود به سیستم است. شما می‌توانید مسیر کامل فایل گزارش را با تنظیم CombinedFileName مشخص کنید.

پس از راه اندازی کارخانه درخواست خود، باید کارخانه درخواست را در شیء Service خود با تنظیم RequestFactory شیء سرویس جایگزین کنید. کد شما ممکن است چیزی شبیه به این باشد:

using System;
using Google.GData.Client;
using Google.GData.Extensions;
using Google.GData.Spreadsheets;

namespace LogginTest
{
   
class Program
   
{
       
static void Main(string[] args)
       
{
           
SpreadsheetsService service = new SpreadsheetsService("-exampleApp-1");
            service
.setUserCredentials(email, password);

           
Google.GData.Client.GDataLoggingRequestFactory factory = new GDataLoggingRequestFactory("wise", "SpreadsheetsLoggingTest");
            factory
.MethodOverride = true;
            factory
.CombinedLogFileName = "c:\\temp\\xmllog.log";
           
Console.WriteLine("Log file name:" + factory.CombinedLogFileName);
           
            service
.RequestFactory = factory;

           
SpreadsheetQuery query = new SpreadsheetQuery();
           
SpreadsheetFeed feed = service.Query(query);

           
Console.WriteLine("Your spreadsheets:");
           
foreach (SpreadsheetEntry entry in feed.Entries)
           
{
               
Console.WriteLine(entry.Title.Text);
           
}

           
Console.ReadKey();
       
}
   
}
}

فایل لاگ به دست آمده حاوی درخواست ها و پاسخ های XML است. در اینجا یک مثال کوتاه آمده است که من آن را با استفاده از tidy قالب بندی کرده ام.

<?xml version='1.0' encoding='utf-8'?>

<feed xmlns='http://www.w3.org/2005/Atom'
xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'>
  <id>
  http://spreadsheets.google.com/feeds/spreadsheets/private/full</id>
  <updated>2007-06-07T22:05: 02.674Z</updated>
  <link rel='self' type='application/atom+xml'
  href='http://spreadsheets.google.com/feeds/spreadsheets/private/full'>

  </link>
  ...
  <entry>
    <updated>2007-03-28T17:28:57.250Z</updated>
    <category scheme=' http://schemas.google.com/spreadsheets/2006'
    term='http://schemas.google.com/spreadsheets/2006#spreadsheet'>
    <title type='text'>events</title>

    <content type='text'>events</content>
    ...
  </entry>
  <entry>
    <updated>2007-05-25T22:11:08.200Z</updated>

    <category scheme=' http://schemas.google.com/spreadsheets/2006'
    term='http://schemas.google.com/spreadsheets/2006#spreadsheet'>
    </category>
    <title type='text'>UnitTest</title>
    <content type='text'>UnitTest</content>
    ...
  </entry>

  ...
</feed>

اما شاید شما واقعاً به زبان های اسکریپت نویسی علاقه دارید و ترجیح می دهید از پایتون استفاده کنید.

پایتون

برای گرفتن ترافیک HTTP در کتابخانه کلاینت پایتون، می‌توانید با روشن کردن حالت اشکال زدایی در سرویس گیرنده HTTP، ترافیک هدر HTTP را به کنسول بازتاب دهید. شیء سرویس دارای یک عضو اشکال زدایی است که می توانید آن را روی True تنظیم کنید.

تنظیم اشکال زدایی روی true، پرچم اشکال زدایی را در شیء زیرین HTTPRequest که در شیء سرویس موجود است تنظیم می کند.

در اینجا مثالی آورده شده است که وقتی لیستی از صفحات گسترده خود را درخواست می کنید، هدرهای HTTP ارسال شده از سرور صفحات گسترده را بازتاب می دهد.

#!/usr/bin/python

import gdata.spreadsheet.service

client
= gdata.spreadsheet.service.SpreadsheetsService()
client
.debug = True

client
.ClientLogin(email, password)

feed
= client.GetSpreadsheetsFeed()

for entry in feed.entry:
 
print entry.title.text

و چیزی شبیه به این را در کنسول خود خواهید دید:

reply: 'HTTP/1.1 200 OK\r\n'
header: Content-Type: application/atom+xml; charset=UTF-8
header: Last-Modified: Thu, 07 Jun 2007 18:22:35 GMT
header: Cache-Control: max-age=0, must-revalidate, private
header: Transfer-Encoding: chunked
...
header: Date: Thu, 07 Jun 2007 18:22:35 GMT
header: Server: GFE/1.3

با انجام عملیات اضافی، مانند درج یا به‌روزرسانی، داده‌های درخواست مربوطه را خواهید دید که به کنسول خود بازتاب می‌کنند.

نتیجه

این آموزش مختصر نشان می‌دهد که چگونه می‌توانید عملکرد اصلی ورود به سیستم را به یک برنامه جاوا، دات‌نت یا پایتون که از کتابخانه‌های سرویس گیرنده Google Data API استفاده می‌کند، اضافه کنید. اگر نیاز به اشکال زدایی مبادلات HTTP دارید، اما به یک بسته sniffer دسترسی ندارید، این تکنیک ها می توانند مفید باشند. من فقط با این مثال ها سطح را خراشیده ام. بسیاری از مکانیسم‌های گزارش‌گیری موجود در این زبان‌ها بسیار قدرتمندتر از آنچه در اینجا نشان داده شده است. اگر اطلاعات بیشتری در مورد ورود به سیستم یا Google Data API می‌خواهید، فهرست منابع زیر را بررسی کنید.

کتابخانه های مشتری تحت پوشش این مقاله را می توان در این صفحات یافت:

موارد مرتبط با دانش پایه:

گروه‌های بحث: ما تعداد کمی داریم، که با عرضه APIهای Google Data بیشتر در راه است. ما فعالانه گروه ها را رصد می کنیم.

اگر سوال یا پیشنهادی دارید، خوشحال می شوم از شما بشنوم. به گروه بحث بروید و شروع به ارسال کنید.