Closed ioseb closed 11 years ago
@revazi რა ხდება? როდის აპირებ საქმის დაწყებას? თუ მე დაგიწერო?
@ioseb დღეს დავიწყებ
@revazi
@ioseb ოკ
@revazi გვაგვიანებ უკვე.
@ioseb ვცდილობ გავერკვე და იმედია მალე გავაკეთებ
@revazi Maven პროექტი თუ გამართე?
@ioseb კიი. კოდზე ვფიქრობ
@revazi
ასე მივუდგეთ საკითხს. ზედმეტი დრო რომ არ დაიხარჯოს მე დაგისვამ შეკითხვებს და შენ დამიფიქსირე რა გესმის და როგორ გესმის და რა არ გემის:
ამ შეკითხვებიდან რომელიმეზე თუ არ გაქვს პასუხი კოდის წერაზე ფიქრი ნაადრევია.
@ioseb 1) გასაგებია public class HttpRequestLine ეს კლასი თავისი მეთდებით აკეთებს Request - ის ნაწილების ცალ-ცალკე setter & getter მეთოდების აღწერას სადაც set-პრეფიქსით დაწყებულ მეთოდებს ჩვენ უნდა გადავცეთ წინასწარ დამუშავებული Request-ის ნაწილები მაგ. Path, Query, MethodType... 2) ამის უკეთ განმარტება მჭირდება ალბათ. 3) მოთხოვნის სტრიქონებში კანონქომიერება ის არის რომ მოთხოვნის ტიპი გამოყოფილია მოთხოვნისგან space-ით შემდეგ მოთხოვნაა ყველგან და შემდეგ ისევ space-ით გამოყოფილი HTTP-ის ვერსია თუმცა "\r\nGET /test HTTP/1.1\r\n\r\n" ამაზე ორი სიტყვით მითხარი. 4) წავიკითხე და გავიგე რომ მოთხოვნის სტრიქონის შემდეგ შაბლონს იყენებს request-line = method SP request-target SP HTTP-version CRLF
@revazi
ალგორითმი მარტივად რომ ვთქვათ ასეთია:
throw new HttpRequestException(HttpStatus.Code.UNSUPPORTED_METHOD)
(ეს ბოლო @vaxop - ს ტასკია, ანუ ექსეპშენი)throw new HttpRequestException(HttpStatus.Code.HTTP_VERSION_NOT_SUPPORTED)
გასაგებია ეს ყველაფერი?
@revazi
დასაწყისისთვის გთავაზობ ასეთ რამეს:
package edu.cst.webserver.http;
import junit.framework.Assert;
import org.junit.Test;
public class HttpRequestLineParserTest {
private static final String HTTP_VERSION = "HTTP/1.1";
@Test
public void testRequestLine0() {
HttpRequestLineParser parser = HttpRequestLineParser.newInstance();
String requestLineString = "GET /test HTTP/1.1\\r\\n";
HttpRequestLine requestLine = parser.parse(requestLineString);
Assert.assertEquals(HttpMethod.METHOD_GET, requestLine.getMethodName());
Assert.assertEquals("/test", requestLine.getPath());
Assert.assertEquals(HTTP_VERSION, requestLine.getHttpVersion());
}
}
რომელიც გაშვების შემდეგ თავისთავად ცხადია ტესტირების შეცდომებს გამოიწვევს. შეეცადე .parse() მეთოდი მიიყვანო იქამდე რომ მხოლოდ ეს ერთი ტესტი გაიაროს. როდესაც ამას მიაღწევ დაამატე ახალი ტესტები ჩემს პირველ პოსტში მოყვანილი ყველა მოთხოვნის სტრიქონისთვის და გატესტე სხვადასხვა ნაწილები.
@reflooding @demonno მიეხმარეთ უნიტ ტესტინგში.
@revazi
ეს ამოცანა რომ გავამარტივოთ:
ესე გასაგებია?
კონფიგურაციის კლასის გამოყენება ძალიან მარტივია
მაგალითისთვის რომ შევამოწმოთ მხარდაჭერილია თუ არა GET მეთოდი , უნდა დავწეროთ შემდეგი :
ServerConfig config = ServerConfig.getInstance();
config.isSupportedMethod("GET");
დადებითი პასუხის შემტხვევაში დაგვიბრუნდება ბულის ტიპის მნიშვნელობა true , უარყოფითის შემთხვევაში ბულის ტიპის მნიშვნელობა false
@ioseb გასაგებია. წავყვები ყველაფერს რაც დამიწერე და გავაკეთებ
@revazi ვნახე შენი კომიტი. ჯერ ძალიან ნედლია მაგრამ სტილისტური შენიშვნა მაქვს. გამხსნელი ფიგურული ფრჩხილები აიტანე იმავე ხაზზე სადაც იწყება ბლოკი. სხვების კოდსაც შეხედე.
არასწორია:
if (condition)
{
// code here...
}
სწორია:
if (condition) {
// code here...
}
@ioseb გავითვალისწინებ, შევასწორებ და ამაღამ კოდსაც დავამატებ კიდევ.
@revazi აქ კომენტარები რომ დაგიწერე არ გამოგრჩეს: https://github.com/reflooding/serv-cst/commit/cb8052f81ee7b7aaa8494e89fc4b3c5e0c4dbb64
@ioseb ვნახე და მივხედავ
@revazi არის რამე პროგრესი?
@ioseb HttpRequestLineParser() - ში მიმითითე რა უნდა გავაკეთო.
@revazi მეტი რა უნდა მიგითოთ? ამ თიქეთში უამრავი რამე დავწერე და კოდში კომენტარებიც დაგიწერე. კონკრეტულად რა გაინტერესებს?
@revazi თუ არ გამოგდის და არ გცალია თქვი და სხვას გადავულოცავ ამ დავალებას. არ არის ეს საქმე როდესაც მოლოდინი მაქვს რომ გააკეთებ რაღაცას დღეების მანძილზე არ ჩანხარ და ისეთ კოდს ტოვებ რეპოში რომელიც არათუ არ მუშაობს, არც კი კომპილირდება. ელ.ფოსტა ხშირად გადაამოწმე და მოწერილს უპასუხე.
@ioseb ვცდილობ რომ გავარჩიო და ვცდილობ გავერკვე regex-ის გამოყენებაში java-ში. private HttpRequestLineParser() { } ამაზე მაინტერესებდა parse - მეთოდის დასრულების მერე როგორ უნდა გამომეყენებინა.
@revazi არ გეწყინოს მაგრამ ან მეკაიფები ან არ კითხულობ რას ვწერ. ამონარიდები პირველი პოსტიდან:
აი ასეთია გამოყენება:
HttpRequestLineParser parser = HttpRequestLineParser.newInstance();
HttpRequestLine requestLine = parser.parse("GET /path/to/resource?param=value HTTP/1.1");
ალგორითმი მარტივად რომ ვთქვათ ასეთია:
throw new HttpRequestException(HttpStatus.Code.UNSUPPORTED_METHOD)
(ეს ბოლო @vaxop - ს ტასკია, ანუ ექსეპშენი)throw new HttpRequestException(HttpStatus.Code.HTTP_VERSION_NOT_SUPPORTED)
გასაგებია ეს ყველაფერი?
ის რეგულარული გამოსახულება რაც მანდ დაგჭირდება თავი ბოლო ეს არის:
String[] tokens = requestLine.trim().split("\\s+");
თუმცა ვისურვებდი რომ ცოტა უფრო კრეატიული ყოფილიყავი და რეგულარული გამოსახულების გარეშე დაგეძლია ეს ამოცანა. დანარჩენი რაც კოდის კომენტარებში დავწერე ისიც გადაიკითხე.
არაფერი არსებითი გასარკვევი არ გაქვს. და იმის ნაცვლად რომ დრო ხარჯო და შეგვაფერხო უმჯობესი იქნება თუ:
@ioseb ok Sorry.
HTTP - ს რაც შეეხება ვერ ვნახე isSupportedMethod მსგავსი მეთოდი HTTP - ის ვერსიისთვის
@revazi "Sorry" არ მიიღება. თუ ვერ ნახე:
if (!httpMethod.equals("HTTP/1.1")) {
// rest of code here...
}
სადაც httpMethod
არის შენი ცვლადი.
ასე ვერ იზამდი?
ვიზამდი მაგრამ მეგონა რომ სხვას უნდა დაეწერა.
@revazi თავს იმართლებ და თან ძალიან არაეფექტურად :D :D :D საქმეს მიხედე, თუ არ გცალია თქვი. რომ "გეგონა" ვერ თქვი მერე? ან ვისზეც გეგონა რატომ არ შეახსენე?
@ioseb ოხ არ ვიმართლებ თავს. სხვის კოდებში ხელები არ აფათუროთო და რაღაცები და მგონია რომ მარტო ჩემათ რაც არის ნათქვამი იმაში უნდა ვწერო.
@revazi
საქმეს მივხედოთ, ვფერხდებით აშკარად.
@ioseb ხო. ახლა გასაგებია
@revazi დაგიმატე დავალება და შენვე ჩაამატე #19
@ioseb დავამატე და ტესტებიც დავუწერე. Recipients of an invalid request-line SHOULD respond with either a 400 (Bad Request) error შეკითხვა: შევამოწმო URI Whitespace-ებზე?
@revazi ძალიან კარგი. არა, URI შენ არ უნდა შეამოწმო მაგაზე(ჯერ). ანუ როდესაც იმ სტრიქონს გახლიჩავ უნდა მიიღო 3 ნაწილი. თუ მეტი/ან ნაკლები მიიღე თავისთავად არასწორია უკვე. იმ შემთხვევაში თუ მაინც 3 ნაწილი მიიღე და პირველი ორი ნაწილი სწორია, მესამე ნაწილი არ გამოვა სწორი და შეცდომაა(ანუ exception უნდა ისროლო) და თუ სამივე ნაწილი სწორია ესე იგი ყველაფერი კარგად არის.
@revazi
Recipients of an invalid request-line SHOULD respond with either a 400 (Bad Request) error
ამ შემთხვევაში შენ უბრალოდ აკეთებ ასეთ რამეს:
throw new HttpRequestException(HttpStatus.Code.BAD_REQUEST)
მეტი არაფერი გევალება.
ეგ მიწერია მაშინ როცა request-line_ის space-ებით გამოყოფილი ნაწილების რაოდენობა არ უდრის 3ს. parts = requestLineString.split("\s+"); if (parts.length != 3){ throw new HttpRequestException(HttpStatus.Code.BAD_REQUEST); }
შესაბამისად აღარ არის საჭირო URI - ს შემოწმება. გარდა ამისა მნიშვნელოვანი რაოდენობის უნიტ ტესტები გაქვს დასაწერი(იხ. დისკუსიის პირველი პოსტი) და გამოვავლნეთ ხარვეზებს როგორმე.
On Sunday, March 3, 2013 at 7:41 PM, Revaz wrote:
ეგ მიწერია მაშინ როცა request-line_ის space-ებით გამოყოფილი ნაწილების რაოდენობა არ უდრის 3ს. parts = requestLineString.split("\s+"); if (parts.length != 3){ throw new HttpRequestException(HttpStatus.Code.BAD_REQUEST); }
— Reply to this email directly or view it on GitHub (https://github.com/reflooding/serv-cst/issues/8#issuecomment-14348641).
ახლა ვიწყებ ტესტებზე მუშაობას უბრალოდ ერთი რაც მინდოდა კიდევ HttpRequestLine requestLine = parser.parse("GET /path/to/resource?param=value HTTP/1.1"); <<< ამაზე მიწერს incompetible types და parse მეთოდიდან String-ი არ უნდა დავაბრუნო. როგორ დავაბრუნო parse მეთდიდან HttpRequestLine ტიპის ობიექტი?
@revazi სტრიქონი არ უნდა დააბურნო.
HttpRequestLine requestLine = new HttpRequestLine();
requestLine.setHttpVersion(httpVersion);
requestLine.setQueryString(queryString);
requestLine.setFragment(fragment);
requestLine.setPath(path);
requestLine.setMethod(HttpMethod.getHttpMethodByname(methodName));
return requestLine;
სადაც: httpVersion
, path
, queryString
, fragment
, methodName
შენი ცვლადებია. ამ ცვლადებიდან:
methodName
მეთოდის სახელია რომელიც უკვე უნდა გქონდეს მოთხოვნის სტრიქონის დახლეჩვის მერე;httpVersion
ასევე ბოლო ნაწილი;path
, queryString
, fragment
უნდა მოიპოვო შესაბამისი ალგორითმით.როდესაც უკვე გაქვს URI სტრიქონი უნდა გააკეთო ასე:
path
. ან თუ კითხვის ნიშანი არ გვხვდება მთლიანად არის path
queryString
queryString
- ში გხვდება # სიმბოლო ნიშნავს რომ მაგ სიმბოლოს მერე რაც არის არის fragment
makes sense?
აქედან მარტო ეს მინდოდა: HttpRequestLine requestLine = new HttpRequestLine(); requestLine. setHttpVersion(httpVersion); requestLine.setQueryString(queryString); requestLine.setFragment(fragment); requestLine.setPath(path); requestLine.setMethod(HttpMethod.getHttpMethodByname(methodName));
return requestLine;
დანარჩენი ვეცადე ისე გამეკეთებინა და რაღაც კოდი უკვე დავწერე. ვვარაუდობდი ასე მაგრამ ვერ გავავწყვიტე set-მეთოდების ამბავი. ახლა გასაგებია.
ოკეი, ველოდები რეზულტატს.
we don't have Httpmethod.getHttpMethodByname();
yes we have. https://github.com/reflooding/serv-cst/blob/master/src/main/java/edu/cst/webserver/http/HttpMethod.java
it's name is: getMethodByName()
. source is available and please do not be so lazy and look sometimes inside others work.
On Sunday, March 3, 2013 at 8:14 PM, Revaz wrote:
we don't have
Httpmethod.getHttpMethodByname();— Reply to this email directly or view it on GitHub (https://github.com/reflooding/serv-cst/issues/8#issuecomment-14349157).
ჩავიხედე რა უხ.
ნუ ღელავ და საქმეს მიხედე :P თუ ჩაიხედე რატომ ვერ იპოვე?
On Sunday, March 3, 2013 at 8:18 PM, Revaz wrote:
ჩავიხედე რა უხ.
— Reply to this email directly or view it on GitHub (https://github.com/reflooding/serv-cst/issues/8#issuecomment-14349229).
რავიცი ნორმალურად არ ჩავიხედე. My fault.
კარგია :D შედეგი დაიდოს ხარისხიანი!
ცოტაც მაცადე Boss
მთავარია დამანახეთ რომ მუშაობთ, სხვაგან მე არსად არ მეჩქარება.
On Sunday, March 3, 2013 at 8:22 PM, Revaz wrote:
ცოტაც მაცადე Boss
— Reply to this email directly or view it on GitHub (https://github.com/reflooding/serv-cst/issues/8#issuecomment-14349316).
მიღებული HTTP მოთხოვნის საწყისი სტრიქონის(Request Line: იხ. http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-21#section-3.1.1) წაკითხვა.
სავარაუდო ტესტები:
ყველა ზემოთ ჩამოთვლილი მოთხოვნის სტრიქონის წაკითხვის შემდეგ უნდა შეიქმნას შემდეგი კლასის ობიექტი:
საწყისი სტრიქონის წაკითხვის დროს, მეთოდის ამოკითხვის დასრულების შემდეგ:
HttpMethod.getMethodByName(methodName);
იხ. #2პარსერის კლასი რომელმაც უნდა დააბრუნოს ზემოთ ნაჩვენები კლასის ობიექტი:
გამოყენების ნიმუში: