Немного HTTP

Тема в разделе "WASM.NETWORKS", создана пользователем slavanap, 16 май 2009.

  1. slavanap

    slavanap Вячеслав

    Публикаций:
    0
    Регистрация:
    10 сен 2008
    Сообщения:
    300
    Адрес:
    Смоленск, Россия
    Какие символы заменяются на %хх при HTTP запросе?
    Знаю, что пробел - %20,
    Русские буквы - %hex-код.
    А что с остальным? Иероглифы, ?, $, &...

    Заранее спасибо.
     
  2. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    я видел, как заменялись знаки вопроса и слеши. Что еще - хз
     
  3. G13

    G13 New Member

    Публикаций:
    0
    Регистрация:
    24 мар 2006
    Сообщения:
    499
    Читайте rfc3986 (или предыдущую версию - rfc1738).

    Если вкратце, то не заменяются следующие символы (unreserved characters):
    Зарезервированные символы (reserved characters) - заменяются, если не используются по назначению.
    Всё остальное заменяется. Иероглифы сводятся к двухбайтной кодировке, либо к UTF-8 и, естественно, тоже заменяются.
     
  4. integer

    integer New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2007
    Сообщения:
    62
    http://ru.wikipedia.org/wiki/URL
     
  5. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Я прально отредактировал?
     
  6. slavanap

    slavanap Вячеслав

    Публикаций:
    0
    Регистрация:
    10 сен 2008
    Сообщения:
    300
    Адрес:
    Смоленск, Россия
    А как определить, UTF-8 (2 байта на символ - следовательно 2 процента) передано или ASCII кодировка (1 байт) ??
     
  7. slavanap

    slavanap Вячеслав

    Публикаций:
    0
    Регистрация:
    10 сен 2008
    Сообщения:
    300
    Адрес:
    Смоленск, Россия
    Нашёл кусок кода:
    Код (Text):
    1. private static String unescape(String s) {
    2.     StringBuffer sbuf = new StringBuffer () ;
    3.     int l  = s.length() ;
    4.     int ch = -1 ;
    5.     int b, sumb = 0;
    6.     for (int i = 0, more = -1 ; i < l ; i++) {
    7.       /* Get next byte b from URL segment s */
    8.       switch (ch = s.charAt(i)) {
    9.     case '%':
    10.       ch = s.charAt (++i) ;
    11.       int hb = (Character.isDigit ((char) ch)
    12.             ? ch - '0'
    13.             : 10+Character.toLowerCase((char) ch) - 'a') & 0xF ;
    14.       ch = s.charAt (++i) ;
    15.       int lb = (Character.isDigit ((char) ch)
    16.             ? ch - '0'
    17.             : 10+Character.toLowerCase ((char) ch)-'a') & 0xF ;
    18.       b = (hb << 4) | lb ;
    19.       break ;
    20.     case '+':
    21.       b = ' ' ;
    22.       break ;
    23.     default:
    24.       b = ch ;
    25.       }
    26.       /* Decode byte b as UTF-8, sumb collects incomplete chars */
    27.       if ((b & 0xc0) == 0x80) {         // 10xxxxxx (continuation byte)
    28.     sumb = (sumb << 6) | (b & 0x3f) ;   // Add 6 bits to sumb
    29.     if (--more == 0) sbuf.append((char) sumb) ; // Add char to sbuf
    30.       } else if ((b & 0x80) == 0x00) {      // 0xxxxxxx (yields 7 bits)
    31.     sbuf.append((char) b) ;         // Store in sbuf
    32.       } else if ((b & 0xe0) == 0xc0) {      // 110xxxxx (yields 5 bits)
    33.     sumb = b & 0x1f;
    34.     more = 1;               // Expect 1 more byte
    35.       } else if ((b & 0xf0) == 0xe0) {      // 1110xxxx (yields 4 bits)
    36.     sumb = b & 0x0f;
    37.     more = 2;               // Expect 2 more bytes
    38.       } else if ((b & 0xf8) == 0xf0) {      // 11110xxx (yields 3 bits)
    39.     sumb = b & 0x07;
    40.     more = 3;               // Expect 3 more bytes
    41.       } else if ((b & 0xfc) == 0xf8) {      // 111110xx (yields 2 bits)
    42.     sumb = b & 0x03;
    43.     more = 4;               // Expect 4 more bytes
    44.       } else /*if ((b & 0xfe) == 0xfc)*/ {  // 1111110x (yields 1 bit)
    45.     sumb = b & 0x01;
    46.     more = 5;               // Expect 5 more bytes
    47.       }
    48.       /* We don't test if the UTF-8 encoding is well-formed */
    49.     }
    50.     return sbuf.toString() ;
    51.   }
    Понял, что '+' = ' ', '%..' перекодируются в спецсимволы при декодировании, остальные остаются без изменения. А вот какие коды нужно распознавать как Unicode, а какие - как ASCII - непонятно. (я в java не силён.)
     
  8. slavanap

    slavanap Вячеслав

    Публикаций:
    0
    Регистрация:
    10 сен 2008
    Сообщения:
    300
    Адрес:
    Смоленск, Россия
    Вообщем, разобрался. Есть такой код перекодировки. Может, кто-нибудь проверит на оптимальность..
    Код (Text):
    1. DecodeURI proc USES EDI ESI, lpBuffer:DWORD  ; eax = length of res, enc_string ends with 0x0
    2.       MOV  EDI, lpBuffer
    3.       MOV  ESI, EDI
    4.  
    5.   @Loop:
    6.       LODSB
    7.       CMP  AL, '%'
    8.       JNE  @Save
    9.      
    10.       LODSW
    11.     ; Work with AH
    12.       CMP  AH, 'A'
    13.       JB   A1
    14.       CMP  AH, 'a'
    15.       JB   A2
    16.       ADD  AH, -('a'-10)
    17.       JMP  A3
    18.   A2: ADD  AH, -('A'-10)
    19.       JMP  A3
    20.   A1: XOR  AH, 30h
    21.   A3:
    22.     ; Work with AL
    23.       CMP  AL, 'A'
    24.       JB   B1
    25.       CMP  AL, 'a'
    26.       JB   B2
    27.       ADD  AL, -('a'-10)
    28.       JMP  B3
    29.   B2: ADD  AL, -('A'-10)
    30.       JMP  B3
    31.   B1: XOR  AL, 30h
    32.   B3:
    33.       SHL  AL, 4
    34.       OR   AL, AH
    35.   @Save:
    36.       STOSB
    37.       CMP  AL, 0
    38.       JNE  @Loop
    39.      
    40.       SUB  ESI, lpBuffer
    41.       DEC  ESI
    42.      
    43.       ADD  ESP, -(MAX_PATH*2)
    44.       MOV  EDI, ESP
    45.       INVOKE MultiByteToWideChar, CP_UTF8, 0, lpBuffer, ESI, EDI, MAX_PATH*2
    46.       INVOKE WideCharToMultiByte, 1251, 0, EDI, EAX, lpBuffer, MAX_PATH, NULL, NULL
    47.       ADD  ESP, (MAX_PATH*2)
    48.       MOV  EDI, lpBuffer
    49.       MOV  BYTE PTR [EDI+EAX], 0
    50.       RET
    51. DecodeURI Endp
     
  9. slavanap

    slavanap Вячеслав

    Публикаций:
    0
    Регистрация:
    10 сен 2008
    Сообщения:
    300
    Адрес:
    Смоленск, Россия
    P.S. Код писал сам.
     
  10. djmans

    djmans New Member

    Публикаций:
    0
    Регистрация:
    27 дек 2006
    Сообщения:
    312
    >А как определить, UTF-8 (2 байта на символ - следовательно 2 процента)
    во первых не два байта а от 2-х до 6.
    во вторых http://ru.wikipedia.org/wiki/UTF-8

    оба товоих вопроса есть в википедии, которая раскрывается по первой сылке на запросы utf-8 и url. конечно лучше зафлудить форум еше одной говнотемой. чем зайти в гуглю. и я уверен что на твой третий вопрос тоже юудет ответ в гугле по первой ссылке.
     
  11. maksim_

    maksim_ New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2009
    Сообщения:
    263
    это utf-8 от 2х до шести? вообще-то латинский алфавит кодируется 8 битами.
     
  12. djmans

    djmans New Member

    Публикаций:
    0
    Регистрация:
    27 дек 2006
    Сообщения:
    312
    >это utf-8 от 2х до шести? вообще-то латинский алфавит кодируется 8 битами.
    имелось ввиду кодированые символы, а так да верное замечение.
     
  13. slavanap

    slavanap Вячеслав

    Публикаций:
    0
    Регистрация:
    10 сен 2008
    Сообщения:
    300
    Адрес:
    Смоленск, Россия
    djmans,
    А разве по коду не видно, что я это давно понял?!
    Тем более, что флудить я не собираюсь, не собирался и не буду собираться!
    Проблема уже решена, хоть и немного корявым способом. Если кто-нибудь поможет оптимизировать преведённый выше код, скажу спасибо, если нет - тему можно закрывать.

    В коде идёт перекодировка имени файла (можно и всего URI) из URI ('%' + UTF8) в utf8.
     
  14. djmans

    djmans New Member

    Публикаций:
    0
    Регистрация:
    27 дек 2006
    Сообщения:
    312
    если ты под виндой, то попробуй MultiByteToWideChar, WideCharToMultiByte
     
  15. slavanap

    slavanap Вячеслав

    Публикаций:
    0
    Регистрация:
    10 сен 2008
    Сообщения:
    300
    Адрес:
    Смоленск, Россия
    DecodeURI proc USES EDI ESI, lpBuffer:lol: WORD ; eax = length of res, enc_string ends with 0x0
    MOV EDI, lpBuffer
    MOV ESI, EDI

    ; Избавляемся от процентов в адресе, подменяя их коды на истинные значения байтов.
    ; Может быть, есть способ короче..

    @Loop:
    LODSB
    CMP AL, '%'
    JNE @Save

    LODSW
    ; Work with AH
    CMP AH, 'A'
    JB A1
    CMP AH, 'a'
    JB A2
    ADD AH, -('a'-10)
    JMP A3
    A2: ADD AH, -('A'-10)
    JMP A3
    A1: XOR AH, 30h
    A3:
    ; Work with AL
    CMP AL, 'A'
    JB B1
    CMP AL, 'a'
    JB B2
    ADD AL, -('a'-10)
    JMP B3
    B2: ADD AL, -('A'-10)
    JMP B3
    B1: XOR AL, 30h
    B3:
    SHL AL, 4
    OR AL, AH
    @Save:
    STOSB
    CMP AL, 0
    JNE @Loop

    ; Получаем размер строки
    SUB ESI, lpBuffer
    DEC ESI

    ; Далее декодируем функциями Windows'а
    ADD ESP, -(MAX_PATH*2)
    MOV EDI, ESP
    INVOKE MultiByteToWideChar, CP_UTF8, 0, lpBuffer, ESI, EDI, MAX_PATH*2
    INVOKE WideCharToMultiByte, 1251, 0, EDI, EAX, lpBuffer, MAX_PATH, NULL, NULL
    ADD ESP, (MAX_PATH*2)
    MOV EDI, lpBuffer
    MOV BYTE PTR [EDI+EAX], 0
    RET
    DecodeURI Endp