/* ** Send file to client ** ** IN: ** HTTPSRV_SESSION_STRUCT* session - session used for transmission ** HTTPSRV_STRUCT* server - server structure ** ** OUT: ** none ** ** Return Value: ** none */ void httpsrv_sendfile(HTTPSRV_STRUCT *server, HTTPSRV_SESSION_STRUCT *session) { char *ext; int length; char *buffer; buffer = session->buffer.data; ext = strrchr(session->request.path, '.'); httpsrv_process_file_type(ext, session); /* Check if file has server side includes */ if ((0 == strcasecmp(ext, ".shtml")) || (0 == strcasecmp(ext, ".shtm"))) { /* * Disable keep-alive for this session otherwise we would have to * wait for session timeout. */ session->keep_alive = 0; httpsrv_sendhdr(session, 0, 1); #if MQX_USE_IO_OLD fseek(session->response.file, session->response.len, IO_SEEK_SET); #else fseek(session->response.file, session->response.len, SEEK_SET); #endif length = fread(buffer+session->buffer.offset, 1, HTTPSRV_SES_BUF_SIZE_PRV-session->buffer.offset, session->response.file); if (length > 0) { uint32_t offset; offset = httpsrv_sendextstr(server, session, length); session->response.len += session->buffer.offset; httpsrv_ses_flush(session); session->response.len += offset; } } else { #if MQX_USE_IO_OLD httpsrv_sendhdr(session, session->response.file->SIZE, 1); fseek(session->response.file, session->response.len, IO_SEEK_SET); #else httpsrv_sendhdr(session, httpsrv_fsize(session->response.file), 1); fseek(session->response.file, session->response.len, SEEK_SET); #endif length = fread(buffer+session->buffer.offset, 1, HTTPSRV_SES_BUF_SIZE_PRV-session->buffer.offset, session->response.file); if (length > 0) { session->buffer.offset += length; httpsrv_ses_flush(session); session->response.len += length; } } if (length <= 0) { session->state = HTTPSRV_SES_END_REQ; } }
/* ** Write data to client from CGI script ** ** IN: ** HTTPSRV_CGI_RES_STRUCT* response - CGI response structure used for forming response ** ** OUT: ** none ** ** Return Value: ** uint_32 - Number of bytes written */ uint_32 HTTPSRV_cgi_write(HTTPSRV_CGI_RES_STRUCT* response) { HTTPSRV_SESSION_STRUCT* session = (HTTPSRV_SESSION_STRUCT*) response->ses_handle; uint_32 retval = 0; if (session == NULL) { return(0); } if (session->response.hdrsent == 0) { session->response.status_code = response->status_code; session->response.content_type = response->content_type; session->response.len = response->content_length; /* ** If there is no content length we have to disable keep alive. ** Otherwise we would have to wait for session timeout. */ if (session->response.len == 0) { session->keep_alive = 0; } httpsrv_sendhdr(session, response->content_length, 1); } if ((response->data != NULL) && (response->data_length)) { retval = httpsrv_write(session, response->data, response->data_length); } return(retval); }
/* ** Send error page to client ** ** IN: ** HTTPSRV_SESSION_STRUCT* session - session used for transmission ** const char* title - title of error page ** const char* text - text displayed on error page ** ** OUT: ** none ** ** Return Value: ** none */ void httpsrv_send_err_page(HTTPSRV_SESSION_STRUCT *session, const char* title, const char* text) { uint32_t length; char* page; length = snprintf(NULL, 0, ERR_PAGE_FORMAT, title, text); length++; page = _mem_alloc(length*sizeof(char)); session->response.content_type = HTTPSRV_CONTENT_TYPE_HTML; if (page != NULL) { snprintf(page, length, ERR_PAGE_FORMAT, title, text); httpsrv_sendhdr(session, strlen(page), 1); httpsrv_write(session, page, strlen(page)); httpsrv_ses_flush(session); _mem_free(page); } else { httpsrv_sendhdr(session, 0, 0); } }
/* ** Write data to client from CGI script ** ** IN: ** HTTPSRV_CGI_RES_STRUCT* response - CGI response structure used for forming response ** ** OUT: ** none ** ** Return Value: ** uint_32 - Number of bytes written */ uint32_t HTTPSRV_cgi_write(HTTPSRV_CGI_RES_STRUCT* response) { HTTPSRV_SESSION_STRUCT* session = (HTTPSRV_SESSION_STRUCT*) response->ses_handle; uint32_t retval = 0; int32_t wrote; if (session == NULL) { return(0); } if (!(session->flags & HTTPSRV_FLAG_HEADER_SENT)) { session->response.status_code = response->status_code; session->response.content_type = response->content_type; session->response.length = response->content_length; if (response->content_length < 0) { session->flags |= HTTPSRV_FLAG_IS_TRANSCODED; } /* * Ignore rest of received data in buffer (set buffer offset to zero). * We do this because otherwise any buffered but unread data would be * part of response (before header) and render it invalid. */ if (session->buffer.offset <= session->request.content_length) { session->request.content_length -= session->buffer.offset; } session->buffer.offset = 0; httpsrv_sendhdr(session, response->content_length, 1); } if (session->flags & HTTPSRV_FLAG_IS_TRANSCODED) { char length_str[sizeof("FFFFFFFF\r\n")] = {0}; /* Write length. */ snprintf(length_str, sizeof(length_str), "%x\r\n", response->data_length); wrote = httpsrv_write(session, length_str, strlen(length_str)); if (wrote < 0) { retval = 0; goto EXIT; } /* Write data. */ wrote = httpsrv_write(session, response->data, response->data_length); if (wrote < 0) { retval = 0; goto EXIT; } retval = wrote; /* Write tail. */ wrote = httpsrv_write(session, "\r\n", strlen("\r\n")); if (wrote < 0) { retval = 0; goto EXIT; } } else if ((response->data != NULL) && (response->data_length > 0)) { retval = httpsrv_write(session, response->data, response->data_length); } EXIT: session->time = RTCS_time_get(); return(retval); }
/* ** Send file to client ** ** IN: ** HTTPSRV_SESSION_STRUCT* session - session used for transmission ** HTTPSRV_STRUCT* server - server structure ** ** OUT: ** none ** ** Return Value: ** none */ void httpsrv_sendfile(HTTPSRV_STRUCT *server, HTTPSRV_SESSION_STRUCT *session) { char *ext; int expand = 0; int len; char* buf = session->buffer.data; ext = strrchr(session->request.path, '.'); if (ext != NULL) { httpsrv_process_file_type(ext+1, session); } else { session->response.content_type = HTTPSRV_CONTENT_TYPE_OCTETSTREAM; } /* Check if file has server side includes */ if ((0 == strcasecmp(ext, ".shtml")) || (0 == strcasecmp(ext, ".shtm"))) { expand = 1; /* Disable keep-alive for this session otherwise we would have to wait for session timeout */ session->keep_alive = 0; /* If there will be any expansion there's no way how to calculate correct length ** zero length prevents sending Content-Length header field. */ httpsrv_sendhdr(session, 0, 1); } else { #if MQX_USE_IO_OLD httpsrv_sendhdr(session, session->response.file->SIZE, 1); #else httpsrv_sendhdr(session, httpsrv_fsize(session->response.file), 1); #endif } if (expand) { len = fread(buf+session->buffer.offset, 1, HTTPSRV_SES_BUF_SIZE_PRV-session->buffer.offset, session->response.file); if (len > 0) { len = httpsrv_sendextstr(server, session, buf, len); if (!len) { session->state = HTTPSRV_SES_END_REQ; } else { session->response.len += len; #if MQX_USE_IO_OLD fseek(session->response.file, session->response.len, IO_SEEK_SET); #else fseek(session->response.file, session->response.len, SEEK_SET); #endif } } else { session->state = HTTPSRV_SES_END_REQ; } } else { #if MQX_USE_IO_OLD fseek(session->response.file, session->response.len, IO_SEEK_SET); #else fseek(session->response.file, session->response.len, SEEK_SET); #endif len = fread(buf+session->buffer.offset, 1, HTTPSRV_SES_BUF_SIZE_PRV-session->buffer.offset, session->response.file); if (len > 0) { session->buffer.offset += len; httpsrv_ses_flush(session); session->response.len += len; } else { session->state = HTTPSRV_SES_END_REQ; } } }
/* ** Send file to client ** ** IN: ** HTTPSRV_SESSION_STRUCT* session - session used for transmission ** HTTPSRV_STRUCT* server - server structure ** ** OUT: ** none ** ** Return Value: ** none */ void httpsrv_sendfile(HTTPSRV_STRUCT *server, HTTPSRV_SESSION_STRUCT *session) { char *ext; int expand = 0; int len; char* buf = session->buffer.data; ext = strrchr(session->request.path, '.'); if (ext != NULL) { httpsrv_process_file_type(ext+1, session); } else { session->response.content_type = HTTPSRV_CONTENT_TYPE_OCTETSTREAM; } /* Check if file has server side includes */ if ((0 == strcasecmp(ext, ".shtml")) || (0 == strcasecmp(ext, ".shtm"))) { expand = 1; /* Disable keep-alive for this session otherwise we would have to wait for session timeout */ session->keep_alive = 0; /* If there will be any expansion there's no way how to calculate correct length ** zero length prevents sending Content-Length header field. */ httpsrv_sendhdr(session, 0, 1); } else { httpsrv_sendhdr(session, session->response.file->SIZE, 1); } if (expand) { len = read(session->response.file, buf+session->buffer.offset, (HTTPSRVCFG_SES_BUFFER_SIZE & PSP_MEMORY_ALIGNMENT_MASK)-session->buffer.offset); if (len > 0) { len = httpsrv_sendextstr(server, session, buf, len); if (!len) { session->state = HTTPSRV_SES_END_REQ; } else { session->response.len += len; fseek(session->response.file, session->response.len, IO_SEEK_SET); } } else { session->state = HTTPSRV_SES_END_REQ; } } else { fseek(session->response.file, session->response.len, IO_SEEK_SET); len = read(session->response.file, buf+session->buffer.offset, (HTTPSRVCFG_SES_BUFFER_SIZE & PSP_MEMORY_ALIGNMENT_MASK)-session->buffer.offset); if (len > 0) { uint_32 retval = 0; session->buffer.offset += len; retval = httpsrv_send_buffer(session); if (retval != RTCS_ERROR) { session->response.len += len; } } else { session->state = HTTPSRV_SES_END_REQ; } } }