HTTP Parser and message builder / objects in plain C Snapshot
Classes | Typedefs | Enumerations | Functions
HTTP_RESPONSE_WRITER

writer of http responss More...

Classes

struct  tagHTTP_RESPONSE_WRITER

Typedefs

typedef struct
tagHTTP_RESPONSE_WRITER 
HTTP_RESPONSE_WRITER

Enumerations

enum  HTTP_RESPONSE_WR_STATE {
  HTTP_RESPONSE_WR_STATUS_LINE, HTTP_RESPONSE_WR_CONNECTION_CLOSE, HTTP_RESPONSE_WR_CHUNKED, HTTP_RESPONSE_WR_CONTENT_LENGTH,
  HTTP_RESPONSE_WR_HEADERS, HTTP_RESPONSE_WR_EOF
}

Functions

M_INLINE void HTTP_RESPONSE_WRITER_init (HTTP_RESPONSE_WRITER *writer, HTTP_RESPONSE *response)
PARSER_STATUS HTTP_RESPONSE_WRITER_write (HTTP_RESPONSE_WRITER *writer, BF *data)

Detailed Description

writer of http responss


Typedef Documentation


Enumeration Type Documentation

Enumerator:
HTTP_RESPONSE_WR_STATUS_LINE 
HTTP_RESPONSE_WR_CONNECTION_CLOSE 
HTTP_RESPONSE_WR_CHUNKED 
HTTP_RESPONSE_WR_CONTENT_LENGTH 
HTTP_RESPONSE_WR_HEADERS 
HTTP_RESPONSE_WR_EOF 

Definition at line 409 of file http.h.


Function Documentation

M_INLINE void HTTP_RESPONSE_WRITER_init ( HTTP_RESPONSE_WRITER writer,
HTTP_RESPONSE response 
)

Definition at line 429 of file http.h.

{
  writer->response = response;
  writer->state = HTTP_RESPONSE_WR_STATUS_LINE;
}
PARSER_STATUS HTTP_RESPONSE_WRITER_write ( HTTP_RESPONSE_WRITER writer,
BF *  data 
)

Definition at line 992 of file http.c.

{ 
  HTTP_RESPONSE *resp = writer->response;
  char line_buf[40];
  int nlen;

  while(1) {
  switch( writer->state ) {
    case HTTP_RESPONSE_WR_STATUS_LINE:
      nlen = sprintf(line_buf,"HTTP/%s %d %s\r\n", http_version_to_str( resp->version ), resp->status_code, get_reason_phrase( resp->status_code ) );
      if (BF_putn( bf, line_buf, nlen) ) {
         RETURN_WRITER_MORE_DATA;
      }
      writer->state = HTTP_RESPONSE_WR_CONNECTION_CLOSE; 
    //break;
    case HTTP_RESPONSE_WR_CONNECTION_CLOSE:
      if (resp->base.flags & HTTP_MESSAGE_FLAG_CONNECTION_CLOSE ) {
        if (BF_putn( bf, S_CONNECTION_CLOSE, S_CONNECTION_CLOSE_LEN ) ) {
          RETURN_WRITER_MORE_DATA;
        } 
      }
      writer->state = HTTP_RESPONSE_WR_CHUNKED; 
    //break;
    case HTTP_RESPONSE_WR_CHUNKED:
      if (resp->base.flags & HTTP_MESSAGE_FLAG_TRANSFER_CHUNKED ) {
        if (BF_putn( bf, S_TRANSFER_CHUNKED, S_TRANSFER_CHUNKED_LEN ) ) {
          RETURN_WRITER_MORE_DATA;
        }
      }
      writer->state = HTTP_RESPONSE_WR_CONTENT_LENGTH; 
     //break;
    case HTTP_RESPONSE_WR_CONTENT_LENGTH:
      if (resp->base.flags & HTTP_MESSAGE_FLAG_HAS_CONTENT_LENGTH ) {
        nlen = sprintf(line_buf,"Content-Length: %d\r\n", resp->base.content_length );
        if (BF_putn( bf, line_buf, nlen) ) {
          RETURN_WRITER_MORE_DATA;
        }
      }
      writer->state = HTTP_RESPONSE_WR_HEADERS; 
      writer->header_position = DLISTUNR_get_first( &resp->base.header_values );
      writer->state_header = 0;
     //break;
    case HTTP_RESPONSE_WR_HEADERS:
      if ( ! DLISTUNR_is_eof( &resp->base.header_values, writer->header_position)) {
        STRINGPAIR *header = (STRINGPAIR *) DLISTUNR_at(&resp->base.header_values, writer->header_position);
        switch(writer->state_header) {
            case 0:
                if (BF_putn( bf, header->key, strlen(header->key))) {
                  RETURN_WRITER_MORE_DATA;
                }
                writer->state_header = 1;
              //break;
                
            case 1:
                if (BF_putn( bf, ": ", 2)) {
                  RETURN_WRITER_MORE_DATA;
                }
                writer->state_header = 2;
              //break;

            case 2:
                if (BF_putn( bf, header->value, strlen(header->value))) {
                  RETURN_WRITER_MORE_DATA;
                }
                writer->state_header = 3;
              //break;

            case 3:
                if (BF_putn( bf, "\r\n", 2)) {
                  RETURN_WRITER_MORE_DATA;
                }
                writer->header_position = DLISTUNR_next(writer->header_position);
                writer->state_header = 0;
                break;
           }
      } else {
         writer->state = HTTP_RESPONSE_WR_EOF;
         goto wr_eof;
        
      }
      break;
    case HTTP_RESPONSE_WR_EOF:
wr_eof:    
      if (BF_putn( bf, "\r\n", 2)) {
          RETURN_WRITER_MORE_DATA;
      }
      return PARSER_STATUS_COMPLETED; 
    }
  }

}