Loading...
Searching...
No Matches
globus_l_gass_transfer_http.h
/*
* Copyright 1999-2006 University of Chicago
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef GLOBUS_DONT_DOCUMENT_INTERNAL
#ifndef GLOBUS_L_GASS_TRANSFER_HTTP_H
#define GLOBUS_L_GASS_TRANSFER_HTTP_H
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************************************
Module Specific Constants
******************************************************************************/
enum
{
GLOBUS_L_DEFAULT_HTTP_PORT = 80,
GLOBUS_L_DEFAULT_HTTPS_PORT = 443,
GLOBUS_L_GASS_RESPONSE_LEN = 256
};
typedef enum
{
GLOBUS_L_LINE_MODE_UNKNOWN,
GLOBUS_L_LINE_MODE_CR,
GLOBUS_L_LINE_MODE_LF,
GLOBUS_L_LINE_MODE_CRLF
} globus_gass_transfer_http_line_mode_t;
/*
* Local text format to convert requests with the text_mode attribute
* set. Always LF, which is used by the C language. Conversion from LF
* ode to the local storage is up to the user (or Globus I/O library).
*/
const globus_gass_transfer_http_line_mode_t
globus_l_gass_transfer_http_line_mode =
#ifndef TARGET_ARCH_WIN32
GLOBUS_L_LINE_MODE_LF;
#else
GLOBUS_L_LINE_MODE_CRLF;
#endif
/* For 8-bit Text:
#define GLOBUS_L_TEXT_BYTE(text) (text)
*/
#define GLOBUS_L_TEXT_BYTE(text) (text & 0x7f)
static globus_mutex_t globus_l_gass_transfer_http_mutex;
static globus_cond_t globus_l_gass_transfer_http_cond;
#define globus_l_gass_transfer_http_lock() \
globus_mutex_lock(&globus_l_gass_transfer_http_mutex)/*,*/ \
/*printf("locked mutex at %s: %d\n", __FILE__, __LINE__)*/
#define globus_l_gass_transfer_http_unlock() \
/*printf("unlocking mutex at %s: %d\n", __FILE__, __LINE__), */\
globus_mutex_unlock(&globus_l_gass_transfer_http_mutex)
#define globus_l_gass_transfer_http_wait() \
globus_cond_wait(&globus_l_gass_transfer_http_cond, \
&globus_l_gass_transfer_http_mutex)
#define globus_l_gass_transfer_http_signal() \
globus_cond_signal(&globus_l_gass_transfer_http_cond)
static char * globus_l_gass_transfer_http_subject_name;
/* Some handy, common values in the HTTP protocol */
#define CR '\015'
#define LF '\012'
#define CRLF "\015\012"
#define CR_STRING "\015"
#define LF_STRING "\012"
/* Commands the client issues to the server */
#define GLOBUS_GASS_HTTP_VERSION "Globus-GASS-HTTP/1.1.0"
#define GLOBUS_L_APPEND_URI "/globus-bins/GASSappend?"
#define GLOBUS_L_GET_COMMAND "GET %s HTTP/1.1" CRLF \
"Host: %s" CRLF \
"Connection: close" CRLF \
"User-Agent: " GLOBUS_GASS_HTTP_VERSION CRLF
#define GLOBUS_L_PUT_COMMAND "PUT %s HTTP/1.1" CRLF \
"Host: %s" CRLF \
"Connection: close" CRLF \
"User-Agent: " GLOBUS_GASS_HTTP_VERSION CRLF
#define GLOBUS_L_APPEND_COMMAND "POST " GLOBUS_L_APPEND_URI "%s " \
"HTTP/1.1" CRLF \
"Host: %s" CRLF \
"Connection: close" CRLF \
"User-Agent: " GLOBUS_GASS_HTTP_VERSION CRLF
#define GLOBUS_L_REFER_RESPONSE "HTTP/1.1 302 Moved Temporarily" CRLF \
"Connection: close" CRLF \
"Server: " GLOBUS_GASS_HTTP_VERSION CRLF
#define GLOBUS_L_CONTINUE_RESPONSE "HTTP/1.1 100 Continue" CRLF
#define GLOBUS_L_GENERIC_RESPONSE "HTTP/1.%d %d %s" CRLF \
"Connection: close" CRLF \
"Server: " GLOBUS_GASS_HTTP_VERSION CRLF
#define GLOBUS_L_OK "Ok"
#define GLOBUS_L_DENIAL_RESPONSE "HTTP/1.1 %d %s" CRLF \
"Connection: close" CRLF \
"Server: " GLOBUS_GASS_HTTP_VERSION CRLF
#define GLOBUS_L_DEFAULT_DENIAL_MESSAGE "Internal Server Error"
#define GLOBUS_L_CONTENT_LENGTH_HEADER "Content-Length: %zu" CRLF
#define GLOBUS_L_CHUNKED_HEADER "Transfer-Encoding: chunked" CRLF
#define GLOBUS_L_BINARY_HEADER "Content-Type: " \
"application/octet-stream" CRLF
#define GLOBUS_L_TEXT_HEADER "Content-Type: text/plain" CRLF
#define GLOBUS_L_HTML_HEADER "Content-Type: text/html" CRLF
#define GLOBUS_L_HTML_REFERRAL_BODY_HEAD \
"<html><head><title>Document Moved</title></head><body>"
#define GLOBUS_L_HTML_REFERRAL_BODY_TAIL \
"</body></html>"
#define GLOBUS_L_HTML_DENIAL_BODY "<html><head><title>%d %s</title></head><body>" CRLF \
"<h1>%d %s</h1></body></html>" CRLF
#define GLOBUS_L_HTML_HREF "<a href=\"%s\">%s</a><br>"
#define GLOBUS_L_LOCATION_HEADER "Location: %s" CRLF
#define GLOBUS_L_DEFAULT_FAILURE_CODE 400
#define GLOBUS_L_DEFAULT_FAILURE_REASON "Bad Request"
/* The "client failure" (4xx) response codes defined in RFC 2068 end at 415 */
#define GLOBUS_L_PROTOCOL_FAILURE_CODE 416
#define GLOBUS_L_PROTOCOL_FAILURE_REASON "Protocol Error"
#define GLOBUS_L_MALLOC_FAILURE_CODE 417
#define GLOBUS_L_MALLOC_FAILURE_REASON "Malloc Error"
/******************************************************************************
Module specific Types
******************************************************************************/
typedef enum
{
/* Client-only states */
GLOBUS_GASS_TRANSFER_HTTP_STATE_CONNECTING,
GLOBUS_GASS_TRANSFER_HTTP_STATE_REQUESTING,
GLOBUS_GASS_TRANSFER_HTTP_STATE_CLOSING,
GLOBUS_GASS_TRANSFER_HTTP_STATE_REFERRED,
GLOBUS_GASS_TRANSFER_HTTP_STATE_DENIED,
GLOBUS_GASS_TRANSFER_HTTP_STATE_RESPONDING,
/* Common states */
GLOBUS_GASS_TRANSFER_HTTP_STATE_IDLE,
GLOBUS_GASS_TRANSFER_HTTP_STATE_DONE,
GLOBUS_GASS_TRANSFER_HTTP_STATE_PENDING
} globus_gass_transfer_http_state_t;
/* These mirror the GASS listener states exactly */
typedef enum
{
GLOBUS_GASS_TRANSFER_HTTP_LISTENER_STARTING,
GLOBUS_GASS_TRANSFER_HTTP_LISTENER_LISTENING,
GLOBUS_GASS_TRANSFER_HTTP_LISTENER_READY,
GLOBUS_GASS_TRANSFER_HTTP_LISTENER_ACCEPTING,
GLOBUS_GASS_TRANSFER_HTTP_LISTENER_CLOSING1,
GLOBUS_GASS_TRANSFER_HTTP_LISTENER_CLOSING2,
GLOBUS_GASS_TRANSFER_HTTP_LISTENER_CLOSED
} globus_gass_transfer_listener_state_t;
typedef enum
{
GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_CHUNK_SIZE,
GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_CHUNK_EXT,
GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_CHUNK_END_HEADER_CR,
GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_CHUNK_END_HEADER_LF,
GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_CHUNK_BODY,
GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_CHUNK_END_BODY_CR,
GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_CHUNK_END_BODY_LF,
GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_CHUNK_FOOTER,
GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_UNTIL_LENGTH,
GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_UNTIL_EOF,
GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_EOF,
GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_ERROR
} globus_l_gass_transfer_http_recv_state_t;
typedef struct
{
/* Standard "proto" elements */
globus_gass_transfer_proto_listener_t close_listener;
globus_gass_transfer_proto_listener_t listen;
globus_gass_transfer_proto_accept_t accept;
globus_gass_transfer_proto_listener_t destroy;
/* Begin internal http-specific proto state */
globus_gass_transfer_listener_t listener;
globus_io_handle_t handle;
globus_url_scheme_t url_scheme;
globus_gass_transfer_listener_state_t state;
globus_bool_t destroy_called;
struct globus_gass_transfer_http_request_proto_s * request;
} globus_gass_transfer_http_listener_proto_t;
typedef struct globus_gass_transfer_http_request_proto_s
{
/* Standard "proto" elements */
globus_gass_transfer_proto_send_t send_buffer;
globus_gass_transfer_proto_receive_t recv_buffer;
globus_gass_transfer_proto_func_t fail;
globus_gass_transfer_proto_func_t deny;
globus_gass_transfer_proto_func_t refer;
globus_gass_transfer_proto_func_t authorize;
globus_gass_transfer_proto_func_t destroy;
/* Begin internal http-specific proto state */
globus_io_handle_t handle;
/* last data for sending, and EOF on receiving */
volatile globus_bool_t oneshot_registered;
volatile globus_bool_t oneshot_active;
volatile globus_gass_transfer_http_state_t state;
globus_gass_transfer_request_t request;
globus_bool_t failure_occurred;
globus_bool_t destroy_called;
/* Flags from the request attributes */
globus_url_t proxy_url;
globus_bool_t text_mode;
globus_size_t block_size;
/* Type and name of the requested resource */
globus_url_t url;
char * url_string;
globus_gass_transfer_request_type_t type;
/*
* For the "send" case, a 4 item iovec array, containing
* the chunk header, body, and trailing CRLF, and a 0-length
* chunk + crlf
*/
struct iovec iov[4];
/* Length and transfer encoding */
globus_size_t length;
globus_size_t handled;
globus_bool_t chunked;
/* sending-side: are we handling the last data block? */
globus_bool_t last_data;
globus_bool_t client_side;
/* Amount of data from the current chunk still needs to
be given to the user */
globus_size_t chunk_left;
globus_l_gass_transfer_http_recv_state_t recv_state;
globus_bool_t eof_read;
/* Used to parse/store responses from the HTTP server */
globus_byte_t * response_buffer;
globus_size_t response_buflen;
globus_size_t response_offset;
globus_size_t parsed_offset;
int code;
char * reason;
globus_bool_t parse_error;
/* Major/minor version of the HTTP protocol we are using */
int major;
int minor;
/* HTTP headers we've received */
globus_list_t * headers;
/* Line mode of this particular file we are reading */
globus_gass_transfer_http_line_mode_t line_mode;
/*
* The buffer which was handed to the protocol module
* from GASS
*/
globus_byte_t * user_buffer;
globus_size_t user_buflen;
globus_size_t user_offset;
globus_size_t user_waitlen;
globus_gass_transfer_authorization_t authorization_mode;
char * authorized_subject;
char * connected_subject;
/* For handling requests from client */
char * uri;
char * method;
globus_bool_t proxy_connect;
globus_bool_t got_response;
globus_bool_t waiting_for_response;
} globus_gass_transfer_http_request_proto_t;
/******************************************************************************
Module specific Prototypes
******************************************************************************/
#if !defined(GLOBUS_GASS_TRANSFER_HTTP_PARSER_TEST)
static
void
globus_l_gass_transfer_http_send(
globus_gass_transfer_request_proto_t * proto,
globus_gass_transfer_request_t request,
globus_byte_t * buffer,
globus_size_t buffer_length,
globus_bool_t last_data);
static
void
globus_l_gass_transfer_http_receive(
globus_gass_transfer_request_proto_t * proto,
globus_gass_transfer_request_t request,
globus_byte_t * buffer,
globus_size_t buffer_length,
globus_size_t wait_for_length);
static
void
globus_l_gass_transfer_http_writev_callback(
void * callback_arg,
globus_io_handle_t * handle,
globus_result_t result,
struct iovec * iov,
globus_size_t iovcnt,
globus_size_t nbytes);
static
void
globus_l_gass_transfer_http_write_callback(
void * callback_arg,
globus_io_handle_t * handle,
globus_result_t result,
globus_byte_t * buf,
globus_size_t nbytes);
static
void
globus_l_gass_transfer_http_write_response(
void * arg,
globus_io_handle_t * handle,
globus_result_t result,
globus_byte_t * buf,
globus_size_t nbytes);
static
void
globus_l_gass_transfer_http_proto_destroy(
globus_gass_transfer_http_request_proto_t * proto);
static
void
globus_l_gass_transfer_http_read_callback(
void * callback_arg,
globus_io_handle_t * handle,
globus_result_t result,
globus_byte_t * buf,
globus_size_t nbytes);
static
void
globus_l_gass_transfer_http_read_buffered_callback(
void * callback_arg,
globus_io_handle_t * handle,
globus_result_t result,
globus_byte_t * buf,
globus_size_t nbytes);
static
void
globus_l_gass_transfer_http_callback_read_buffered_callback(
void * arg);
static
void
globus_l_gass_transfer_http_callback_ready_callback(
void * arg);
void
globus_l_gass_transfer_http_copy_text_buffer(
globus_byte_t * output,
globus_byte_t * input,
globus_gass_transfer_http_line_mode_t * line_mode,
globus_size_t input_max_to_copy,
globus_size_t output_max_to_copy,
globus_size_t * input_copied,
globus_size_t * output_copied);
static
void
globus_l_gass_transfer_http_fail(
globus_gass_transfer_request_proto_t * proto,
globus_gass_transfer_request_t request);
static
void
globus_l_gass_transfer_http_close_callback(
void * callback_arg,
globus_io_handle_t * handle,
globus_result_t result);
static
void
globus_l_gass_transfer_http_accept_callback(
void * callback_arg,
globus_io_handle_t * handle,
globus_result_t result);
static
void
globus_l_gass_transfer_http_destroy(
globus_gass_transfer_request_proto_t * proto,
globus_gass_transfer_request_t request);
static
void
globus_l_gass_transfer_http_new_request(
globus_gass_transfer_request_t request,
globus_gass_transfer_requestattr_t * attr);
static
globus_object_t *
globus_l_gass_transfer_http_new_requestattr(
char * url_scheme);
static
globus_object_t *
globus_l_gass_transfer_http_new_listenerattr(
char * url_scheme);
static
void
globus_l_gass_transfer_http_close_listener(
globus_gass_transfer_listener_proto_t * proto,
globus_gass_transfer_listener_t listener);
static
void
globus_l_gass_transfer_http_listen(
globus_gass_transfer_listener_proto_t * proto,
globus_gass_transfer_listener_t listener);
static
void
globus_l_gass_transfer_http_accept(
globus_gass_transfer_listener_proto_t * proto,
globus_gass_transfer_listener_t listener,
globus_gass_transfer_request_t request,
globus_gass_transfer_requestattr_t * attr);
static
globus_bool_t
globus_l_gass_transfer_http_authorization_callback(
void * arg,
globus_io_handle_t * handle,
globus_result_t result,
char * identity,
gss_ctx_id_t context_handle);
static
void
globus_l_gass_transfer_http_listener_destroy(
globus_gass_transfer_listener_proto_t * proto,
globus_gass_transfer_listener_t listener);
static
int
globus_l_gass_transfer_http_new_listener(
globus_gass_transfer_listener_t listener,
globus_gass_transfer_listenerattr_t * attr,
char * scheme,
char ** base_url,
globus_gass_transfer_listener_proto_t ** proto);
static
void
globus_l_gass_transfer_http_connect_callback(
void * arg,
globus_io_handle_t * handle,
globus_result_t result);
static
void
globus_l_gass_transfer_http_command_callback(
void * arg,
globus_io_handle_t * handle,
globus_result_t result,
globus_byte_t * buf,
globus_size_t nbytes);
static
void
globus_l_gass_transfer_http_response_callback(
void * arg,
globus_io_handle_t * handle,
globus_result_t result,
globus_byte_t * buf,
globus_size_t nbytes);
static
void
globus_l_gass_transfer_http_listener_proto_destroy(
globus_gass_transfer_http_listener_proto_t *
proto);
static
void
globus_l_gass_transfer_http_callback_listen_callback(
void * arg);
static
void
globus_l_gass_transfer_http_listen_callback(
void * callback_arg,
globus_io_handle_t * handle,
globus_result_t result);
#endif
static
globus_bool_t
globus_l_gass_transfer_http_find_crlf(
globus_byte_t * bytes,
globus_size_t len,
globus_size_t * crlf_offset);
static
globus_bool_t
globus_l_gass_transfer_http_parse_headers(
globus_gass_transfer_http_request_proto_t * proto);
static
globus_bool_t
globus_l_gass_transfer_http_parse_one_header(
globus_gass_transfer_http_request_proto_t * proto,
globus_bool_t * last_header);
static
globus_bool_t
globus_l_gass_transfer_http_parse_status_line(
globus_gass_transfer_http_request_proto_t * proto);
static
globus_bool_t
islws(
char byte);
static
globus_bool_t
ischar(
char byte);
static
globus_bool_t
istspecial(
char byte);
static
void
globus_l_gass_transfer_http_callback_send_callback(
void * arg);
static
void
globus_l_gass_transfer_http_request_callback(
void * arg,
globus_io_handle_t * handle,
globus_result_t result,
globus_byte_t * buf,
globus_size_t nbytes);
static
globus_result_t
globus_l_gass_transfer_http_register_read(
globus_gass_transfer_http_request_proto_t * proto);
static
char *
globus_l_gass_transfer_http_construct_request(
globus_gass_transfer_http_request_proto_t * proto);
static
globus_bool_t
globus_l_gass_transfer_http_handle_chunk(
globus_gass_transfer_http_request_proto_t * proto);
static
globus_bool_t
globus_l_gass_transfer_http_parse_response(
globus_gass_transfer_http_request_proto_t * proto);
static
globus_bool_t
globus_l_gass_transfer_http_parse_request(
globus_gass_transfer_http_request_proto_t * proto);
static
globus_bool_t
globus_l_gass_transfer_http_parse_request_line(
globus_gass_transfer_http_request_proto_t * proto);
static
void
globus_l_gass_transfer_http_extract_referral(
globus_gass_transfer_http_request_proto_t * proto,
char *** referral,
globus_size_t * referral_count);
static
void
globus_l_gass_transfer_http_callback_denied(
void * arg);
static
void
globus_l_gass_transfer_http_close(
globus_gass_transfer_http_request_proto_t * proto);
static
globus_result_t
globus_l_gass_transfer_http_register_close(
globus_gass_transfer_http_request_proto_t * proto);
static
void
globus_l_gass_transfer_http_listener_close(
globus_gass_transfer_http_listener_proto_t * proto);
#ifdef __cplusplus
}
#endif
#endif /* GLOBUS_L_GASS_TRANSFER_HTTP_H */
#endif /* GLOBUS_DONT_DOCUMENT_INTERNAL */
globus_gass_transfer_proto_send_t
void(* globus_gass_transfer_proto_send_t)(globus_gass_transfer_request_proto_t *proto, globus_gass_transfer_request_t request, globus_byte_t *bytes, globus_size_t bytes_length, globus_bool_t last_data)
Definition globus_gass_transfer_proto.h:123
globus_gass_transfer_proto_listener_t
void(* globus_gass_transfer_proto_listener_t)(globus_gass_transfer_listener_proto_t *proto, globus_gass_transfer_listener_t listener)
Definition globus_gass_transfer_proto.h:290
globus_gass_transfer_listener_proto_t
struct globus_gass_transfer_listener_proto_s globus_gass_transfer_listener_proto_t
Definition globus_gass_transfer_proto.h:88
globus_gass_transfer_proto_receive_t
void(* globus_gass_transfer_proto_receive_t)(globus_gass_transfer_request_proto_t *proto, globus_gass_transfer_request_t request, globus_byte_t *bytes, globus_size_t bytes_length, globus_size_t wait_for_length)
Definition globus_gass_transfer_proto.h:163
globus_gass_transfer_request_proto_t
struct globus_gass_transfer_request_proto_s globus_gass_transfer_request_proto_t
Definition globus_gass_transfer_proto.h:81
globus_gass_transfer_proto_func_t
void(* globus_gass_transfer_proto_func_t)(globus_gass_transfer_request_proto_t *proto, globus_gass_transfer_request_t request)
Definition globus_gass_transfer_proto.h:190
globus_gass_transfer_proto_accept_t
void(* globus_gass_transfer_proto_accept_t)(globus_gass_transfer_listener_proto_t *proto, globus_gass_transfer_listener_t listener, globus_gass_transfer_request_t request, globus_gass_transfer_requestattr_t *attr)
Definition globus_gass_transfer_proto.h:358
globus_gass_transfer_request_type_t
globus_gass_transfer_request_type_t
Definition globus_gass_transfer.h:146
globus_gass_transfer_request_t
Request handle.