HTTP Logger Protocol, version 2

The http-logger is a noninteractive tool used to log interactions between Opera and the web servers it accesses.

This is a draft which has never been implemented.

BNF

Following is the grammar of the service, "http-logger":

  PROTOCOL ::= (COMMAND | EVENT)* ;


  ##
  # Commands (messages from debugger to debugging host)
  #

  COMMAND ::= SET-LOG-MODE
            | GET-LOG-MODE
            | GET-RESPONSE-BODY
            ;

  SET-LOG-MODE ::= "<set-log-mode>" LOG-MODE-TYPE "</set-log-mode>" ;

  GET-RESPONSE-BODY ::= "<get-response-body>"
                          REQUEST-ID
                          ENCODING?
                          DECODING?
                        "</get-response-body>"
                        ;

  GET-LOG-MODE ::= "<get-log-mode />" ;

  ###
  # Events (messages from debugging host to debugger)
  #

  EVENT ::= REQUEST
          | RESPONSE-HEADER
          | RESPONSE-BODY
          | LOG-MODE
          ;

  REQUEST ::= "<request>"
                REQUEST-ID
                WINDOW-ID
                RUNTIME-ID # this is perhaps not necessary if we have frame path
                FRAME-PATH
                TIME
                METHOD
                URL
                PARSED-HEADERS
              "</request>" ;

  # The RESPONSE does not have it's own id, but refers to the generating REQUEST-ID

  RESPONSE-HEADER ::= "<response-header>"
                        REQUEST-ID
                        TIME
                        MIME-TYPE
                        ENCODING
                        STATUS
                        RAW-HEADER
                        PARSED-HEADERS
                      "</response-header>" ;

  # TODO: How should an event stream (e.g. server sent events) be represented? How about a really slow connection or big file?
  
  RESPONSE-BODY ::= "<response-body>"
                      REQUEST-ID
                      TIME
                      BODY?
                    "</response-body>" ;
  
  LOG-MODE ::= "<log-mode>" LOG-MODE-TYPE "</log-mode>" ;

  ##
  # Other data types
  #

  BODY ::= "<body>"
             ENCODING
             DECODING
             BODY-DATA
           "</body>";

  # REQUEST-ID is an identifier for the request; it is not necessarily unique across
  # time, as it is just the memory address of the request object. 

  REQUEST-ID ::= "<request-id>" UNSIGNED "</request-id>" ;

  # Timestamp of the message, in milliseconds since 1970-01-01 00:00 UTC
  # (be sure not to rely on the time being correct - this is client time, and
  # may be wildly different than the host time)

  TIME ::= "<time>" FLOAT "</time>" ;

  # Header of the request/response, i.e. the HTTP data up until the first
  # occurence of CR+LF+CR+LF, inclusive.

  RAW-HEADER ::= "<raw-header>" TEXT "</raw-header>" ;
  
  PARSED-HEADERS ::= "<parsed-headers>" HEADER* "</parsed-headers>" ;

  HEADER ::= "<header>"
               HEADER-NAME
               HEADER-VALUE 
             "</header>" ;

  HEADER-NAME ::= "<header-name>" TEXT "</header-name>" ;

  HEADER-VALUE ::= "<header-value>" TEXT "</header-value>" ;

  ENCODING ::= "<encoding>" ENCODING-TYPE "</encoding>" ;

  DECODING ::= "<decoding>" DECODING-TYPE "</decoding>" ;
  
  BODY-DATA ::= "<body-data>" TEXT "</body-data>" ;

  FLOAT ::= [0-9]+ "." [0-9]+ ;

  # TODO: These names does not really reflect what is going on. At the very
  #       least they need an explanation.

  LOG-MODE-TYPE ::= "profiling" | "logging" ;

  # DECODING-TYPE is either 
  #   "none", meaning raw data, or
  #   "used-by-opera", which is how Opera ended up decoding it
  # TODO: How will Opera tell the client which encoding it actually used?

  DECODING-TYPE ::= TEXT ;

  ENCODING-TYPE ::= "none" | "base64" ;

  FRAME-PATH ::= TEXT ;

  MIME-TYPE ::= TEXT ;

  STATUS ::= UNSIGNED ;
  
  METHOD ::= TEXT ;
  
  URL ::= TEXT ;

  ###
  # From ecmascript-debugger-protocol.html
  #

  # The window ID is shared across scope. Notably, it's the same as in the ecmascript debugger.
  # INTERNAL: The value is from Window::id

  WINDOW-ID ::= "<window-id>" UNSIGNED "</window-id>" ;

  UNSIGNED ::= [0-9]+ ;
  
  RUNTIME-ID ::= UNSIGNED ; 

  TEXT ::= textual-data ;