/globus_gass_transfer-7.2/library/globus_gass_transfer_http.c
# · C · 6483 lines · 5093 code · 648 blank · 742 comment · 716 complexity · de1586f4ef60c82a9264f1084549746c MD5 · raw file
Large files are truncated click here to view the full file
- /*
- * 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
- /**
- * @file globus_gass_transfer_http.c http/https Protocol Module Implementation
- *
- * This module implements the http and https URL schemes for the GASS transfer
- * library
- *
- * CVS Information:
- * $Source: /home/globdev/CVS/globus-packages/gass/transfer/source/library/globus_gass_transfer_http.c,v $
- * $Date: 2009/11/11 19:48:37 $
- * $Revision: 1.48 $
- * $Author: bester $
- */
- #endif
- #include "globus_i_gass_transfer.h"
- #include "globus_io.h"
- #include "globus_l_gass_transfer_http.h"
- #include <stdlib.h>
- #include <ctype.h>
- #include <string.h>
- #ifndef TARGET_ARCH_WIN32
- #include <strings.h>
- #endif
- #include "version.h"
- #ifndef GLOBUS_DONT_DOCUMENT_INTERNAL
- /*
- #define DEBUG_GASS_TRANSFER
- */
- typedef struct
- {
- globus_gass_transfer_http_listener_proto_t * l_proto;
- globus_gass_transfer_request_t request;
- }
- globus_l_gass_transfer_failed_kickout_closure_t;
- #if defined(DEBUG_GASS_TRANSFER)
- static char * globus_l_gass_transfer_http_debug_level="";
- /* Debug Levels */
- /* 1: Major entry points to the library are displayed */
- /* 2: Calls into the gass transfer proto API are displayed */
- /* 3: Callbacks are displayed */
- /* 4: Callback Registration is displayed */
- /* 5: Error returns from lower-level calls */
- /* 6: Protocol dumps */
- /* 9: Thread safety */
- #define debug_printf(level,fmt) \
- if(strchr(globus_l_gass_transfer_http_debug_level, (#level)[0])) \
- {\
- printf fmt;\
- }
- #undef globus_l_gass_transfer_http_lock
- #undef globus_l_gass_transfer_http_unlock
- static int globus_l_gass_lock_line=0;
- static int globus_l_gass_lock_tmp=0;
- #define MYNAME(x) static char * myname=#x
- #define globus_l_gass_transfer_http_lock() \
- printf(strchr(globus_l_gass_transfer_http_debug_level,'9') ? "Thread [%d] acquiring mutex at %s:%d\n" : "", \
- (int) globus_thread_self(), \
- __FILE__, \
- __LINE__), \
- fflush(stdout), \
- globus_l_gass_lock_tmp = \
- globus_mutex_lock(&globus_l_gass_transfer_http_mutex), \
- globus_l_gass_lock_line=__LINE__, \
- globus_l_gass_lock_tmp
- #define globus_l_gass_transfer_http_unlock() \
- printf(strchr(globus_l_gass_transfer_http_debug_level, '9') ? "Thread [%d] releasing mutex at %s:%d\n" : "", \
- (int) globus_thread_self(), \
- __FILE__, \
- __LINE__), \
- fflush(stdout), \
- globus_l_gass_lock_line = 0, \
- globus_mutex_unlock(&globus_l_gass_transfer_http_mutex)
- #else
- #define debug_printf(level, fmt)
- #define MYNAME(x)
- #endif
- static
- void
- globus_l_gass_transfer_http_accept_failed_kickout(
- void * arg);
- static volatile int globus_l_gass_transfer_http_closing;
- #if !defined(GLOBUS_GASS_TRANSFER_HTTP_PARSER_TEST)
- int
- globus_l_gass_transfer_http_activate(void)
- {
- OM_uint32 maj_stat;
- OM_uint32 min_stat;
- gss_name_t name;
- gss_cred_id_t globus_l_gass_transfer_http_credential =
- GSS_C_NO_CREDENTIAL;
- gss_buffer_desc name_buffer;
- MYNAME(globus_l_gass_transfer_http_activate);
-
- globus_l_gass_transfer_http_closing = 0;
- name_buffer.value = GLOBUS_NULL;
- name_buffer.length = 0;
- # if defined(DEBUG_GASS_TRANSFER)
- {
- globus_l_gass_transfer_http_debug_level =
- globus_module_getenv("GLOBUS_GASS_TRANSFER_HTTP_DEBUG_LEVEL");
- if(globus_l_gass_transfer_http_debug_level == GLOBUS_NULL)
- {
- globus_l_gass_transfer_http_debug_level = "";
- }
- }
- # endif
-
- debug_printf(1, (_GTSL("Entering %s()\n"),myname));
- globus_module_activate(GLOBUS_COMMON_MODULE);
- globus_module_activate(GLOBUS_GSI_GSS_ASSIST_MODULE);
- globus_module_activate(GLOBUS_IO_MODULE);
- globus_mutex_init(&globus_l_gass_transfer_http_mutex,
- GLOBUS_NULL);
- globus_cond_init(&globus_l_gass_transfer_http_cond,
- GLOBUS_NULL);
- maj_stat = globus_gss_assist_acquire_cred(
- &min_stat,
- GSS_C_BOTH,
- &globus_l_gass_transfer_http_credential);
- if (maj_stat != GSS_S_COMPLETE)
- {
- goto error_exit;
- }
- maj_stat = gss_inquire_cred(
- &min_stat,
- globus_l_gass_transfer_http_credential,
- &name,
- GLOBUS_NULL,
- GLOBUS_NULL,
- GLOBUS_NULL);
- if (maj_stat != GSS_S_COMPLETE)
- {
- goto error_exit;
- }
- maj_stat = gss_display_name(
- &min_stat,
- name,
- &name_buffer,
- GLOBUS_NULL);
- if (maj_stat != GSS_S_COMPLETE)
- {
- goto error_exit;
- }
- maj_stat = gss_release_name(
- &min_stat,
- &name);
- if (maj_stat != GSS_S_COMPLETE)
- {
- goto error_exit;
- }
-
- globus_l_gass_transfer_http_subject_name = name_buffer.value;
- if (globus_l_gass_transfer_http_credential != GSS_C_NO_CREDENTIAL)
- {
- gss_release_cred(&min_stat, &globus_l_gass_transfer_http_credential);
- }
- debug_printf(1, (_GTSL("Exiting %s()\n"),myname));
-
- return GLOBUS_SUCCESS;
- error_exit:
- if (globus_l_gass_transfer_http_credential != GSS_C_NO_CREDENTIAL)
- {
- gss_release_cred(&min_stat, &globus_l_gass_transfer_http_credential);
- }
- debug_printf(1, (_GTSL("Exiting %s()\n"),myname));
- return GLOBUS_FAILURE;
- }
- int
- globus_l_gass_transfer_http_deactivate(void)
- {
- MYNAME(globus_l_gass_transfer_http_deactivate);
- debug_printf(1, (_GTSL("Entering %s()\n"),myname));
- globus_l_gass_transfer_http_lock();
- while(globus_l_gass_transfer_http_closing > 0)
- {
- globus_l_gass_transfer_http_wait();
- }
- globus_l_gass_transfer_http_unlock();
- globus_module_deactivate(GLOBUS_IO_MODULE);
- globus_module_deactivate(GLOBUS_GSI_GSS_ASSIST_MODULE);
- globus_mutex_destroy(&globus_l_gass_transfer_http_mutex);
- globus_cond_destroy(&globus_l_gass_transfer_http_cond);
- globus_free(globus_l_gass_transfer_http_subject_name);
- globus_module_deactivate(GLOBUS_COMMON_MODULE);
- debug_printf(1, (_GTSL("Exiting %s()\n"),myname));
- return GLOBUS_SUCCESS;
- }
- globus_module_descriptor_t globus_i_gass_transfer_http_module =
- {
- "globus_i_gass_transfer_http",
- globus_l_gass_transfer_http_activate,
- globus_l_gass_transfer_http_deactivate,
- GLOBUS_NULL,
- GLOBUS_NULL,
- &local_version
- };
- /* Protocol Descriptor, which is registered with the GASS system */
- globus_gass_transfer_proto_descriptor_t
- globus_i_gass_transfer_http_descriptor =
- {
- "http",
- /* client-side support */
- globus_l_gass_transfer_http_new_requestattr,
- globus_l_gass_transfer_http_new_request,
- /* server-side support */
- globus_l_gass_transfer_http_new_listenerattr /* new_listenerattr */,
- globus_l_gass_transfer_http_new_listener /* new_listener */
- };
- globus_gass_transfer_proto_descriptor_t
- globus_i_gass_transfer_https_descriptor =
- {
- "https",
- /* client-side support */
- globus_l_gass_transfer_http_new_requestattr,
- globus_l_gass_transfer_http_new_request,
- /* server-side support */
- globus_l_gass_transfer_http_new_listenerattr /* new_listenerattr */,
- globus_l_gass_transfer_http_new_listener /* new_listener */
- };
- /*
- * Function: globus_l_gass_transfer_http_send()
- *
- * Description: Send a byte array to an HTTP server
- *
- * Parameters:
- *
- * Returns:
- */
- 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)
- {
- globus_result_t result;
- globus_gass_transfer_http_request_proto_t * new_proto;
- globus_reltime_t delay_time;
- MYNAME(globus_l_gass_transfer_http_send);
-
- debug_printf(1, (_GTSL("Entering %s()\n"),myname));
- globus_l_gass_transfer_http_lock();
- new_proto = (globus_gass_transfer_http_request_proto_t *) proto;
- new_proto->last_data = last_data;
- /* We can only process a send if the proto is in the "idle" state */
- globus_assert(new_proto->state == GLOBUS_GASS_TRANSFER_HTTP_STATE_IDLE);
- /* state change to "pending" */
- new_proto->state = GLOBUS_GASS_TRANSFER_HTTP_STATE_PENDING;
- /* Update the buffers to point to those supplied by the user */
- new_proto->user_buffer = buffer;
- new_proto->user_buflen = buffer_length;
- /* If a a failure occurred, callback with the failure bit set,
- * and close the handle
- */
- if(new_proto->failure_occurred)
- {
- goto fail_exit;
- }
- /* Register the send of the data */
- if(new_proto->chunked)
- {
- globus_size_t num_iovecs;
- /* send chunk header and footer as an iovec array */
- sprintf((char *) new_proto->iov[0].iov_base,
- "%lx%s",
- (long) new_proto->user_buflen,
- CRLF);
- new_proto->iov[0].iov_len = strlen((char *) new_proto->iov[0].iov_base);
- new_proto->iov[1].iov_base = (void *) new_proto->user_buffer;
- new_proto->iov[1].iov_len = new_proto->user_buflen;
- new_proto->iov[2].iov_base = CRLF;
- new_proto->iov[2].iov_len = 2;
- if(last_data && new_proto->user_buflen != 0)
- {
- /* last data, need to append a zero-length chunk to
- * indicate this
- */
- num_iovecs = 4;
- }
- else if(last_data && new_proto->user_buflen == 0)
- {
- /* last data, with a zero-length chunk from the user */
- new_proto->iov[1].iov_base = CRLF;
- new_proto->iov[1].iov_len = 2;
- num_iovecs = 2;
- }
- else
- {
- /* normal chunk */
- num_iovecs = 3;
- }
- debug_printf(4, (_GTSL("%s(): Registering writev\n"), myname));
- result = globus_io_register_writev(
- &new_proto->handle,
- new_proto->iov,
- num_iovecs /* 3 iovecs header, body, final CRLF */,
- globus_l_gass_transfer_http_writev_callback,
- new_proto);
- }
- else
- {
- /* send data raw */
- debug_printf(4, (_GTSL("%s(): Registering writev\n"), myname));
- result = globus_io_register_write(
- &new_proto->handle,
- new_proto->user_buffer,
- new_proto->user_buflen,
- globus_l_gass_transfer_http_write_callback,
- new_proto);
- }
- if(result == GLOBUS_SUCCESS)
- {
- /*
- * Registration succeeded. Callback to GASS occurs when I/O
- * completes.
- */
- globus_l_gass_transfer_http_unlock();
- debug_printf(1, (_GTSL("exiting %s()\n"),myname));
- return;
- }
- fail_exit:
- /* Registration failed, close up handle and signal failure to GASS */
- result = globus_l_gass_transfer_http_register_close(new_proto);
- if (result != GLOBUS_SUCCESS)
- {
- globus_l_gass_transfer_http_close(new_proto);
- }
- GlobusTimeReltimeSet(delay_time, 0, 0);
- debug_printf(4, (_GTSL("%s(): Registering oneshot\n"), myname));
- globus_callback_register_oneshot(
- GLOBUS_NULL,
- &delay_time,
- globus_l_gass_transfer_http_callback_send_callback,
- (void *) new_proto);
- globus_l_gass_transfer_http_unlock();
- debug_printf(1, (_GTSL("exiting %s()\n"),myname));
- }
- /* globus_l_gass_transfer_http_send() */
- /*
- * Function: globus_l_gass_transfer_http_receive()
- *
- * Description: Schedule the next block of data from the http server
- * to end up in the provided byte array
- *
- * Parameters:
- *
- * Returns:
- */
- 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)
- {
- globus_gass_transfer_http_request_proto_t * new_proto;
- globus_reltime_t delay_time;
- MYNAME(globus_l_gass_transfer_http_receive);
-
- debug_printf(1, (_GTSL("Entering %s()\n"),myname));
-
- globus_l_gass_transfer_http_lock();
- new_proto = (globus_gass_transfer_http_request_proto_t *) proto;
- /* We can only process a receive if the proto is in the "idle" state */
- globus_assert(new_proto->state == GLOBUS_GASS_TRANSFER_HTTP_STATE_IDLE);
- /* state change to "pending" */
- new_proto->state = GLOBUS_GASS_TRANSFER_HTTP_STATE_PENDING;
- /* Update the buffers to point to those supplied by the user */
- new_proto->user_buffer = buffer;
- new_proto->user_buflen = buffer_length;
- new_proto->user_offset = 0;
- new_proto->user_waitlen = wait_for_length;
- new_proto->oneshot_registered = GLOBUS_TRUE;
- GlobusTimeReltimeSet(delay_time, 0, 0);
- debug_printf(4, (_GTSL("%s(): Registering oneshot\n"), myname));
- globus_callback_register_oneshot(
- GLOBUS_NULL,
- &delay_time,
- globus_l_gass_transfer_http_callback_read_buffered_callback,
- (void *) new_proto);
- globus_l_gass_transfer_http_unlock();
- debug_printf(1, (_GTSL("exiting %s()\n"),myname));
- }
- /* globus_l_gass_transfer_http_receive() */
- /*
- * Function: globus_l_gass_transfer_http_fail()
- *
- * Description: Cause the given request to fail for client-caused reasons
- *
- * Parameters:
- *
- * Returns:
- */
- static
- void
- globus_l_gass_transfer_http_fail(
- globus_gass_transfer_request_proto_t * proto,
- globus_gass_transfer_request_t request)
- {
- globus_gass_transfer_http_request_proto_t * new_proto;
- globus_bool_t signalled;
- globus_result_t result;
- MYNAME(globus_l_gass_transfer_http_fail);
- debug_printf(1, (_GTSL("entering %s()\n"),myname));
- new_proto = (globus_gass_transfer_http_request_proto_t *) proto;
- globus_l_gass_transfer_http_lock();
- signalled = GLOBUS_FALSE;
- while(!signalled)
- {
- switch(new_proto->state)
- {
- case GLOBUS_GASS_TRANSFER_HTTP_STATE_PENDING:
- if(new_proto->oneshot_registered == GLOBUS_TRUE)
- {
- new_proto->failure_occurred = GLOBUS_TRUE;
- signalled = GLOBUS_TRUE;
- break;
- }
- else if(new_proto->oneshot_active)
- {
- new_proto->failure_occurred = GLOBUS_TRUE;
- while(new_proto->state ==
- GLOBUS_GASS_TRANSFER_HTTP_STATE_PENDING)
- {
- globus_l_gass_transfer_http_wait();
- }
- break;
- }
- case GLOBUS_GASS_TRANSFER_HTTP_STATE_CONNECTING:
- case GLOBUS_GASS_TRANSFER_HTTP_STATE_IDLE:
- /* We will transition to the closing state, signalling the failure,
- * and registering the close (which will transition us to the
- * done state).
- */
- signalled = GLOBUS_TRUE;
- new_proto->failure_occurred = GLOBUS_TRUE;
- result = globus_l_gass_transfer_http_register_close(new_proto);
- if (result != GLOBUS_SUCCESS)
- {
- globus_l_gass_transfer_http_close(new_proto);
- }
- break;
- case GLOBUS_GASS_TRANSFER_HTTP_STATE_CLOSING:
- case GLOBUS_GASS_TRANSFER_HTTP_STATE_DONE:
- case GLOBUS_GASS_TRANSFER_HTTP_STATE_REQUESTING:
- case GLOBUS_GASS_TRANSFER_HTTP_STATE_RESPONDING:
- case GLOBUS_GASS_TRANSFER_HTTP_STATE_REFERRED:
- case GLOBUS_GASS_TRANSFER_HTTP_STATE_DENIED:
- signalled = GLOBUS_TRUE;
- new_proto->failure_occurred = GLOBUS_TRUE;
- break;
- }
- }
- globus_l_gass_transfer_http_unlock();
- debug_printf(1, (_GTSL("Exiting %s()\n"),myname));
- }
- /* globus_l_gass_transfer_http_fail() */
- 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)
- {
- globus_gass_transfer_http_request_proto_t * proto;
- MYNAME(globus_l_gass_transfer_http_write_callback);
- debug_printf(3, (_GTSL("Entering %s()\n"),myname));
- proto = (globus_gass_transfer_http_request_proto_t *) callback_arg;
- globus_l_gass_transfer_http_lock();
- if(result != GLOBUS_SUCCESS ||
- proto->failure_occurred ||
- proto->parse_error)
- {
- proto->last_data = GLOBUS_TRUE;
- }
- if(proto->last_data)
- {
- proto->user_offset = nbytes;
- if((proto->type == GLOBUS_GASS_TRANSFER_REQUEST_TYPE_PUT ||
- proto->type == GLOBUS_GASS_TRANSFER_REQUEST_TYPE_APPEND) &&
- (!proto->failure_occurred && !proto->parse_error))
- {
- if(proto->got_response)
- {
- globus_byte_t * buffer;
- globus_size_t offset;
- globus_gass_transfer_request_t request = proto->request;
- int failed = proto->failure_occurred;
- proto->failure_occurred = GLOBUS_TRUE;
- buffer = proto->user_buffer;
- offset = proto->user_offset;
- result = globus_l_gass_transfer_http_register_close(proto);
- if (result != GLOBUS_SUCCESS)
- {
- globus_l_gass_transfer_http_close(proto);
- }
- globus_l_gass_transfer_http_unlock();
- globus_gass_transfer_proto_send_complete(request,
- buffer,
- offset,
- failed,
- GLOBUS_TRUE);
- debug_printf(3, (_GTSL("Exiting %s()\n"),myname));
- return;
- }
- else
- {
- /* the callback to read the response is registered at
- * the beginning of the send, so we do nothing here,
- * and wait for the response
- */
- proto->waiting_for_response = GLOBUS_TRUE;
- globus_l_gass_transfer_http_unlock();
- debug_printf(3, (_GTSL("Exiting %s()\n"),myname));
- return;
- }
- }
- else
- {
- globus_gass_transfer_request_t request;
- globus_byte_t * buf;
- globus_size_t nbytes_sent;
- globus_bool_t fail;
- request = proto->request;
- buf = proto->user_buffer;
- nbytes_sent = proto->user_offset;
- fail = proto->failure_occurred;
-
-
- /* need to register the close, and callback to the user */
- result = globus_l_gass_transfer_http_register_close(proto);
- if (result != GLOBUS_SUCCESS)
- {
- globus_l_gass_transfer_http_close(proto);
- }
-
- globus_l_gass_transfer_http_unlock();
- globus_gass_transfer_proto_send_complete(
- request,
- buf,
- nbytes_sent,
- fail,
- GLOBUS_TRUE);
- debug_printf(3, (_GTSL("Exiting %s()\n"),myname));
- return;
- }
- }
- else
- {
- globus_gass_transfer_request_t request;
- globus_byte_t * buf;
- globus_bool_t fail;
- globus_bool_t last_data;
-
- proto->state = GLOBUS_GASS_TRANSFER_HTTP_STATE_IDLE;
- request = proto->request;
- buf = proto->user_buffer;
- fail = proto->failure_occurred;
- last_data = proto->last_data;
-
- globus_l_gass_transfer_http_unlock();
- globus_gass_transfer_proto_send_complete(request,
- buf,
- nbytes,
- fail,
- last_data);
- }
- debug_printf(3, (_GTSL("Exiting %s()\n"),myname));
- return;
- }
- /* globus_l_gass_transfer_http_write_callback() */
- 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)
- {
- globus_gass_transfer_http_request_proto_t * proto;
- MYNAME(globus_l_gass_transfer_http_writev_callback);
- debug_printf(3, (_GTSL("Entering %s()\n"),myname));
- proto = (globus_gass_transfer_http_request_proto_t *) callback_arg;
- globus_l_gass_transfer_http_lock();
- if(result != GLOBUS_SUCCESS ||
- proto->failure_occurred ||
- proto->parse_error)
- {
- proto->last_data = GLOBUS_TRUE;
- }
- if(proto->last_data)
- {
- proto->user_offset = nbytes - iov[0].iov_len - iov[2].iov_len;
- if((proto->type == GLOBUS_GASS_TRANSFER_REQUEST_TYPE_PUT ||
- proto->type == GLOBUS_GASS_TRANSFER_REQUEST_TYPE_APPEND) &&
- (!proto->failure_occurred && !proto->parse_error))
- {
- if(proto->got_response)
- {
- globus_byte_t * buffer;
- globus_size_t offset;
- int failed = proto->failure_occurred;
- globus_gass_transfer_request_t request = proto->request;
- buffer = proto->user_buffer;
- offset = proto->user_offset;
- result = globus_l_gass_transfer_http_register_close(proto);
- if (result != GLOBUS_SUCCESS)
- {
- globus_l_gass_transfer_http_close(proto);
- }
- globus_l_gass_transfer_http_unlock();
- globus_gass_transfer_proto_send_complete(request,
- buffer,
- offset,
- failed,
- GLOBUS_TRUE);
- debug_printf(3, (_GTSL("Exiting %s()\n"),myname));
- return;
- }
- else
- {
- /* the callback to read the response is registered at
- * the beginning of the send, so we do nothing here,
- * and wait for the response
- */
- proto->waiting_for_response = GLOBUS_TRUE;
- globus_l_gass_transfer_http_unlock();
- debug_printf(3, (_GTSL("Exiting %s()\n"),myname));
- return;
- }
- }
- else
- {
- globus_gass_transfer_request_t request;
- globus_byte_t *buf;
- globus_size_t nbytes_sent;
- globus_bool_t fail;
- request = proto->request;
- buf = proto->user_buffer;
- nbytes_sent = proto->user_offset;
- fail = proto->failure_occurred;
- /* need to register the close, and callback to the user */
- result = globus_l_gass_transfer_http_register_close(proto);
- if (result != GLOBUS_SUCCESS)
- {
- globus_l_gass_transfer_http_close(proto);
- }
- globus_l_gass_transfer_http_unlock();
- globus_gass_transfer_proto_send_complete(
- request,
- buf,
- nbytes_sent,
- fail,
- GLOBUS_TRUE);
- debug_printf(3, (_GTSL("Exiting %s()\n"),myname));
- return;
- }
- }
- else
- {
- globus_gass_transfer_request_t request;
- globus_byte_t *buf;
- globus_size_t nbytes_sent;
- globus_bool_t fail;
-
- request = proto->request;
- buf = proto->user_buffer;
- nbytes_sent = nbytes - iov[0].iov_len - iov[2].iov_len,
- fail = proto->failure_occurred;
- proto->state = GLOBUS_GASS_TRANSFER_HTTP_STATE_IDLE;
- globus_l_gass_transfer_http_unlock();
- globus_gass_transfer_proto_send_complete(request,
- buf,
- nbytes_sent,
- fail,
- GLOBUS_FALSE);
- debug_printf(3, (_GTSL("Exiting %s()\n"),myname));
- return;
- }
- }
- /* globus_l_gass_transfer_http_writev_callback() */
- /*
- * Function: globus_l_gass_transfer_http_read_callack()
- *
- * Description: Callback when the read of from the connection to the active
- * buffer has completed or failed.
- *
- * Parameters:
- *
- * Returns:
- */
- 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)
- {
- globus_object_t * err = GLOBUS_NULL;
- globus_gass_transfer_http_request_proto_t * proto;
- globus_gass_transfer_request_t request;
- globus_bool_t last_data = GLOBUS_FALSE;
- globus_bool_t failure = GLOBUS_FALSE;
- globus_size_t offset = 0;
-
- MYNAME(globus_l_gass_transfer_http_read_callback);
-
- debug_printf(3, (_GTSL("Entering %s()\n"),myname));
-
- proto = (globus_gass_transfer_http_request_proto_t *) callback_arg;
- if(result != GLOBUS_SUCCESS)
- {
- char * tmpstr;
- err = globus_error_get(result);
- tmpstr = globus_object_printable_to_string(err);
- debug_printf(5, (_GTSL("%s(): Error: %s\n"), myname, tmpstr));
- globus_libc_free(tmpstr);
- }
- globus_l_gass_transfer_http_lock();
- proto->user_offset += nbytes;
- proto->handled += nbytes;
- if(nbytes > proto->user_waitlen)
- {
- proto->user_waitlen = 0;
- }
- else
- {
- proto->user_waitlen -= nbytes;
- }
- if(proto->chunked)
- {
- proto->chunk_left -= nbytes;
- }
- if(result != GLOBUS_SUCCESS &&
- globus_io_eof(err))
- {
- proto->eof_read = GLOBUS_TRUE;
- }
- else if(result != GLOBUS_SUCCESS ||
- proto->failure_occurred ||
- proto->parse_error)
- {
- proto->recv_state = GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_ERROR;
- }
- if(proto->recv_state == GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_UNTIL_EOF &&
- proto->eof_read == GLOBUS_TRUE)
- {
- proto->recv_state = GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_EOF;
- }
- else if(proto->recv_state ==
- GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_UNTIL_LENGTH &&
- proto->handled == proto->length)
- {
- proto->recv_state = GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_EOF;
- }
- else if(proto->recv_state ==
- GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_UNTIL_LENGTH &&
- proto->eof_read == GLOBUS_TRUE &&
- proto->handled < proto->length)
- {
- proto->recv_state = GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_ERROR;
- }
- else if(nbytes==0 && proto->eof_read)
- {
- proto->failure_occurred = GLOBUS_TRUE;
- proto->recv_state = GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_ERROR;
- }
- if((proto->type == GLOBUS_GASS_TRANSFER_REQUEST_TYPE_PUT ||
- proto->type == GLOBUS_GASS_TRANSFER_REQUEST_TYPE_APPEND) &&
- proto->recv_state == GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_EOF)
- {
- char * response;
- globus_size_t response_len=0;
- globus_size_t offset;
- response_len += 1;
- response_len += strlen(GLOBUS_L_GENERIC_RESPONSE);
- response_len += 3;
- response_len += strlen(GLOBUS_L_OK);
- response_len += 2;
- response = globus_malloc(response_len);
- proto->state = GLOBUS_GASS_TRANSFER_HTTP_STATE_RESPONDING;
- offset = sprintf(response,
- GLOBUS_L_GENERIC_RESPONSE,
- 0,
- 200,
- GLOBUS_L_OK);
- offset += sprintf(response + offset,
- CRLF);
- debug_printf(4,(_GTSL("%s(): Registering write\n"),myname));
- globus_io_register_write(&proto->handle,
- (globus_byte_t *) response,
- strlen(response),
- globus_l_gass_transfer_http_write_response,
- proto);
- }
- /* Register the socket for closing if we're done reading from it */
- else if(proto->recv_state == GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_EOF ||
- proto->recv_state == GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_ERROR)
- {
- failure = proto->failure_occurred;
- buf = proto->user_buffer;
- offset = proto->user_offset;
- request = proto->request;
- last_data = GLOBUS_TRUE;
- if(proto->state != GLOBUS_GASS_TRANSFER_HTTP_STATE_CLOSING)
- {
- result = globus_l_gass_transfer_http_register_close(proto);
- if (result != GLOBUS_SUCCESS)
- {
- globus_l_gass_transfer_http_close(proto);
- }
- }
- globus_l_gass_transfer_http_unlock();
- debug_printf(2, (_GTSL("calling globus_gass_transfer_proto_receive_complete()")));
- globus_gass_transfer_proto_receive_complete(request,
- buf,
- offset,
- failure,
- last_data);
- goto out;
- }
- if(proto->user_waitlen == 0 ||
- proto->recv_state == GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_EOF ||
- proto->recv_state == GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_ERROR)
- {
- /*
- * Received the required minimum of data from connection, an
- * error, or the end-of file, signal this to GASS
- */
- if(proto->state == GLOBUS_GASS_TRANSFER_HTTP_STATE_PENDING)
- {
- proto->state = GLOBUS_GASS_TRANSFER_HTTP_STATE_IDLE;
- }
- if(proto->recv_state == GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_EOF ||
- proto->recv_state == GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_ERROR)
- {
- last_data = GLOBUS_TRUE;
- }
- failure = proto->failure_occurred;
- buf = proto->user_buffer;
- offset = proto->user_offset;
- request = proto->request;
- globus_l_gass_transfer_http_unlock();
- debug_printf(2, (_GTSL("calling globus_gass_transfer_proto_receive_complete()")));
- globus_gass_transfer_proto_receive_complete(request,
- buf,
- offset,
- failure,
- last_data);
- }
- else
- {
- result = globus_l_gass_transfer_http_register_read(proto);
- globus_l_gass_transfer_http_unlock();
- }
- out:
- if(err)
- {
- globus_object_free(err);
- }
- debug_printf(3, (_GTSL("Exiting %s()\n"),myname));
- return;
- }
- /* globus_l_gass_transfer_http_read_callback() */
- /*
- * Function: globus_l_gass_transfer_http_read_buffered_callack()
- *
- * Description: Callback when the read of from the http to the
- * response buffer has completed or failed.
- *
- * Parameters:
- *
- * Returns:
- */
- 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)
- {
- globus_object_t * err = GLOBUS_NULL;
- globus_gass_transfer_http_request_proto_t * proto;
- MYNAME(globus_l_gass_transfer_http_read_buffered_callback);
- debug_printf(3, (_GTSL("Entering %s()\n"),myname));
- proto = (globus_gass_transfer_http_request_proto_t *) callback_arg;
- if(result != GLOBUS_SUCCESS)
- {
- char * tmpstr;
- err = globus_error_get(result);
- tmpstr = globus_object_printable_to_string(err);
- debug_printf(5, (_GTSL("%s(): %s\n"), myname, tmpstr));
- globus_libc_free(tmpstr);
- }
- globus_l_gass_transfer_http_lock();
- proto->response_offset += nbytes;
- if(result != GLOBUS_SUCCESS &&
- globus_io_eof(err))
- {
- proto->eof_read = GLOBUS_TRUE;
- }
- else if(result != GLOBUS_SUCCESS)
- {
- proto->recv_state = GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_ERROR;
- }
- /*
- * Copy the document from the response buffer to the user-supplied
- * buffer, translating end-of-line if necessary, and handling any
- * chunk header/footer information
- */
- globus_l_gass_transfer_http_handle_chunk(proto);
- if(proto->failure_occurred)
- {
- proto->recv_state = GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_ERROR;
- }
- /* successful read for server, send response */
- if((proto->type == GLOBUS_GASS_TRANSFER_REQUEST_TYPE_PUT ||
- proto->type == GLOBUS_GASS_TRANSFER_REQUEST_TYPE_APPEND) &&
- proto->recv_state == GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_EOF &&
- proto->recv_state != GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_ERROR)
- {
- char * response;
- globus_size_t response_len=0;
- globus_size_t offset;
- response_len += 1;
- response_len += strlen(GLOBUS_L_GENERIC_RESPONSE);
- response_len += 3;
- response_len += strlen(GLOBUS_L_OK);
- response_len += 2;
- response = globus_malloc(response_len);
- proto->state = GLOBUS_GASS_TRANSFER_HTTP_STATE_RESPONDING;
- offset = sprintf(response,
- GLOBUS_L_GENERIC_RESPONSE,
- 0,
- 200,
- GLOBUS_L_OK);
- offset += sprintf(response + offset,
- CRLF);
- debug_printf(4,(_GTSL("%s(): Registering write\n"),myname));
- globus_io_register_write(&proto->handle,
- (globus_byte_t *) response,
- strlen(response),
- globus_l_gass_transfer_http_write_response,
- proto);
- }
- /* Register the socket for closing if we're done reading from it */
- else if(proto->recv_state == GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_EOF ||
- proto->recv_state == GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_ERROR)
- {
- if(proto->state != GLOBUS_GASS_TRANSFER_HTTP_STATE_CLOSING)
- {
- result = globus_l_gass_transfer_http_register_close(proto);
- if (result != GLOBUS_SUCCESS)
- {
- globus_l_gass_transfer_http_close(proto);
- }
- }
- }
- if(proto->user_waitlen == 0 ||
- proto->recv_state == GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_EOF ||
- proto->recv_state == GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_ERROR)
- {
- globus_gass_transfer_request_t request;
- globus_bool_t last_data = GLOBUS_FALSE;
- globus_bool_t failure ;
- globus_byte_t * buf;
- globus_size_t offset;
- /*
- * Received the required minimum of data from connection, an
- * error, or the end-of file, signal this to GASS
- */
- if(proto->state == GLOBUS_GASS_TRANSFER_HTTP_STATE_PENDING)
- {
- proto->state = GLOBUS_GASS_TRANSFER_HTTP_STATE_IDLE;
- }
- if(proto->recv_state == GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_EOF ||
- proto->recv_state == GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_ERROR)
- {
- last_data = GLOBUS_TRUE;
- }
- if(err)
- {
- globus_object_free(err);
- err = GLOBUS_NULL;
- }
- proto->oneshot_active = GLOBUS_FALSE;
- failure = proto->failure_occurred;
- buf = proto->user_buffer;
- offset = proto->user_offset;
- request = proto->request;
- globus_l_gass_transfer_http_signal();
- globus_l_gass_transfer_http_unlock();
- debug_printf(2, (_GTSL("calling globus_gass_transfer_proto_receive_complete()\n")));
- globus_gass_transfer_proto_receive_complete(request,
- buf,
- offset,
- failure,
- last_data);
- debug_printf(3, (_GTSL("Exiting %s()\n"),myname));
- return;
- }
- else
- {
- result = globus_l_gass_transfer_http_register_read(proto);
- }
- if(result != GLOBUS_SUCCESS)
- {
- goto error_exit;
- }
- proto->oneshot_active = GLOBUS_FALSE;
- globus_l_gass_transfer_http_unlock();
- if(err)
- {
- globus_object_free(err);
- }
- debug_printf(3, (_GTSL("Exiting %s()\n"),myname));
- return;
- error_exit:
- proto->state = GLOBUS_GASS_TRANSFER_HTTP_STATE_CLOSING;
- proto->failure_occurred = GLOBUS_TRUE;
- proto->oneshot_active = GLOBUS_FALSE;
- proto->oneshot_active = GLOBUS_FALSE;
-
- result = globus_l_gass_transfer_http_register_close(proto);
- if(err)
- {
- globus_object_free(err);
- }
- {
- globus_gass_transfer_request_t request;
- globus_byte_t *buf;
- globus_size_t offset;
- request = proto->request;
- buf = proto->user_buffer;
- offset = proto->user_offset;
- /* register close failed, act as though it was closed */
- if (result != GLOBUS_SUCCESS)
- {
- globus_l_gass_transfer_http_close(proto);
- }
- globus_l_gass_transfer_http_unlock();
- debug_printf(2, (_GTSL("calling globus_gass_transfer_proto_receive_complete()")));
- globus_gass_transfer_proto_receive_complete(request,
- buf,
- offset,
- GLOBUS_TRUE,
- GLOBUS_TRUE);
- }
- debug_printf(3, (_GTSL("Exiting %s()\n"),myname));
- return;
- }
- /* globus_l_gass_transfer_http_read_buffered_callback() */
- /*
- * Function: globus_l_gass_transfer_http_close_callback()
- *
- * Description: Called upon completion of close()ing the file handle,
- * Will free the proto instance if the client has called
- * the "done" function
- *
- *
- * Parameters:
- *
- * Returns:
- */
- static
- void
- globus_l_gass_transfer_http_close_callback(
- void * callback_arg,
- globus_io_handle_t * handle,
- globus_result_t result)
- {
- globus_gass_transfer_http_request_proto_t * proto;
- MYNAME(globus_l_gass_transfer_http_close_callback);
- debug_printf(3, (_GTSL("Entering %s()\n"),myname));
- proto = (globus_gass_transfer_http_request_proto_t *) callback_arg;
- globus_l_gass_transfer_http_lock();
- globus_l_gass_transfer_http_close(proto);
- globus_l_gass_transfer_http_unlock();
- }
- /* globus_l_gass_transfer_http_close_callback() */
- /*
- * Function: globus_l_gass_transfer_http_close()
- *
- * Description: must be called with the mutex locked
- *
- *
- * Parameters:
- *
- * Returns:
- */
- static
- void
- globus_l_gass_transfer_http_close(
- globus_gass_transfer_http_request_proto_t * proto)
- {
- proto->state = GLOBUS_GASS_TRANSFER_HTTP_STATE_DONE;
- if(proto->destroy_called)
- {
- globus_l_gass_transfer_http_proto_destroy(proto);
- }
- globus_l_gass_transfer_http_closing--;
- globus_l_gass_transfer_http_signal();
- }
- /* globus_l_gass_transfer_http_close() */
- /*
- * Function: globus_l_gass_transfer_http_register_close()
- *
- * Description: must be called with the mutex locked
- *
- *
- * Parameters:
- *
- * Returns:
- */
- static
- globus_result_t
- globus_l_gass_transfer_http_register_close(
- globus_gass_transfer_http_request_proto_t * proto)
- {
- globus_result_t result;
- MYNAME(globus_l_gass_transfer_http_register_close);
-
- proto->state = GLOBUS_GASS_TRANSFER_HTTP_STATE_CLOSING;
- globus_l_gass_transfer_http_closing++;
-
- debug_printf(4,(_GTSL("%s(): registering close on %p\n"), myname, &proto->handle));
- result = globus_io_register_close(
- &proto->handle,
- globus_l_gass_transfer_http_close_callback,
- proto);
- return result;
- }
- /* globus_l_gass_transfer_http_register_close() */
- /*
- * Function: globus_l_gass_transfer_http_listener_close_callback()
- *
- * Description:
- *
- * Parameters:
- *
- * Returns:
- */
- static
- void
- globus_l_gass_transfer_http_listener_close_callback(
- void * callback_arg,
- globus_io_handle_t * handle,
- globus_result_t result)
- {
- globus_gass_transfer_http_listener_proto_t *
- proto;
- MYNAME(globus_l_gass_transfer_http_listener_close_callback);
- debug_printf(3, (_GTSL("Entering %s()\n"),myname));
- proto = (globus_gass_transfer_http_listener_proto_t *) callback_arg;
- globus_l_gass_transfer_http_lock();
- globus_l_gass_transfer_http_listener_close(proto);
- globus_l_gass_transfer_http_unlock();
- debug_printf(3, (_GTSL("Exiting %s()\n"),myname));
- }
- /* globus_l_gass_transfer_http_listener_close_callback() */
- /*
- * Function: globus_l_gass_transfer_http_listener_close()
- *
- * Description: must be called with the mutex locked
- *
- * Parameters:
- *
- * Returns:
- */
- static
- void
- globus_l_gass_transfer_http_listener_close(
- globus_gass_transfer_http_listener_proto_t * proto)
- {
- proto->state = GLOBUS_GASS_TRANSFER_HTTP_LISTENER_CLOSED;
- if(proto->destroy_called)
- {
- globus_l_gass_transfer_http_listener_proto_destroy(proto);
- }
- globus_l_gass_transfer_http_closing--;
- globus_l_gass_transfer_http_signal();
- }
- /* globus_l_gass_transfer_http_listener_close() */
- static
- void
- globus_l_gass_transfer_http_register_listener_close(
- globus_gass_transfer_http_listener_proto_t * proto)
- {
- globus_result_t result;
- MYNAME(globus_l_gass_transfer_http_register_listener_close);
- globus_l_gass_transfer_http_closing++;
- debug_printf(4,(_GTSL("%s(): registering close on %p\n"), myname, &proto->handle));
- result = globus_io_register_close(
- &proto->handle,
- globus_l_gass_transfer_http_listener_close_callback,
- proto);
- globus_assert(result == GLOBUS_SUCCESS);
- if(result != GLOBUS_SUCCESS)
- {
- globus_l_gass_transfer_http_listener_close(proto);
- }
- }
- /* globus_l_gass_transfer_http_register_listener_close() */
-
- /*
- * Function: globus_l_gass_transfer_http_listener_proto_destroy()
- *
- * Description:
- *
- * Parameters:
- *
- * Returns:
- */
- static
- void
- globus_l_gass_transfer_http_listener_proto_destroy(
- globus_gass_transfer_http_listener_proto_t *
- proto)
- {
- globus_free(proto);
- }
- /* globus_l_gass_transfer_http_listener_proto_destroy() */
- /*
- * Function: globus_l_gass_transfer_http_destroy()
- *
- * Description:
- *
- * Parameters:
- *
- * Returns:
- */
- static
- void
- globus_l_gass_transfer_http_destroy(
- globus_gass_transfer_request_proto_t * proto,
- globus_gass_transfer_request_t request)
- {
- globus_gass_transfer_http_request_proto_t * new_proto;
- MYNAME(globus_l_gass_transfer_http_destroy);
- debug_printf(1, (_GTSL("entering %s()\n"),myname));
- new_proto = (globus_gass_transfer_http_request_proto_t *) proto;
- globus_l_gass_transfer_http_lock();
- if(new_proto->state == GLOBUS_GASS_TRANSFER_HTTP_STATE_CLOSING ||
- new_proto->state == GLOBUS_GASS_TRANSFER_HTTP_STATE_REFERRED ||
- new_proto->state == GLOBUS_GASS_TRANSFER_HTTP_STATE_RESPONDING ||
- new_proto->state == GLOBUS_GASS_TRANSFER_HTTP_STATE_DENIED)
- {
- new_proto->destroy_called=GLOBUS_TRUE;
- }
- else if(new_proto->state == GLOBUS_GASS_TRANSFER_HTTP_STATE_DONE)
- {
- globus_l_gass_transfer_http_proto_destroy(new_proto);
- }
- globus_l_gass_transfer_http_unlock();
- debug_printf(1, (_GTSL("exiting %s()\n"),myname));
- }
- /* globus_l_gass_transfer_http_destroy() */
- /*
- * Function: globus_l_gass_transfer_http_listener_destroy()
- *
- * Description:
- *
- * Parameters:
- *
- * Returns:
- */
- static
- void
- globus_l_gass_transfer_http_listener_destroy(
- globus_gass_transfer_listener_proto_t * proto,
- globus_gass_transfer_listener_t listener)
- {
- globus_gass_transfer_http_listener_proto_t *new_proto;
- MYNAME(globus_l_gass_transfer_http_listener_destroy);
- debug_printf(1, (_GTSL("entering %s()\n"),myname));
- new_proto = (globus_gass_transfer_http_listener_proto_t *) proto;
- globus_l_gass_transfer_http_lock();
- if(new_proto->state != GLOBUS_GASS_TRANSFER_HTTP_LISTENER_CLOSED)
- {
- new_proto->destroy_called=GLOBUS_TRUE;
- }
- else
- {
- globus_l_gass_transfer_http_listener_proto_destroy(new_proto);
- }
- globus_l_gass_transfer_http_unlock();
- debug_printf(1, (_GTSL("exiting %s()\n"),myname));
- }
- /* globus_l_gass_transfer_http_listener_destroy() */
- /*
- * Function: globus_l_gass_transfer_http_listen()
- *
- * Description:
- *
- * Parameters:
- *
- * Returns:
- */
- static
- void
- globus_l_gass_transfer_http_listen(
- globus_gass_transfer_listener_proto_t * proto,
- globus_gass_transfer_listener_t listener)
- {
- globus_gass_transfer_http_listener_proto_t *new_proto;
- globus_result_t result;
- globus_reltime_t delay_time;
- MYNAME(globus_l_gass_transfer_http_listen);
- debug_printf(1, (_GTSL("entering %s()\n"),myname));
- new_proto = (globus_gass_transfer_http_listener_proto_t *) proto;
- globus_l_gass_transfer_http_lock();
- debug_printf(4,(_GTSL("%s(): registering listen on %p\n"),
- myname,
- &new_proto->handle));
- result = globus_io_tcp_register_listen(
- &new_proto->handle,
- globus_l_gass_transfer_http_listen_callback,
- (void *) new_proto);
- if(result != GLOBUS_SUCCESS)
- {
- GlobusTimeReltimeSet(delay_time, 0, 0);
- debug_printf(4,(_GTSL("%s(): registering oneshot because listen failed\n"),
- myname));
- globus_callback_register_oneshot(
- GLOBUS_NULL,
- &delay_time,
- globus_l_gass_transfer_http_callback_listen_callback,
- (void *) new_proto);
-
- }
- else
- {
- new_proto->state = GLOBUS_GASS_TRANSFER_HTTP_LISTENER_LISTENING;
- }
- globus_l_gass_transfer_http_unlock();
- debug_printf(1, (_GTSL("exiting %s()\n"),myname));
- }
- /* globus_l_gass_transfer_http_listen() */
- static
- void
- globus_l_gass_transfer_http_listen_callback(
- void * callback_arg,
- globus_io_handle_t * handle,
- globus_result_t result)
- {
- globus_gass_transfer_http_listener_proto_t *proto;
- globus_gass_transfer_listener_t listener;
- MYNAME(globus_l_gass_transfer_http_listen_callback);
-
- debug_printf(3, (_GTSL("Entering %s()\n"),myname));
- proto = (globus_gass_transfer_http_listener_proto_t *) callback_arg;
- globus_l_gass_transfer_http_lock();
- switch(proto->state)
- {
- case GLOBUS_GASS_TRANSFER_HTTP_LISTENER_LISTENING:
- proto->state = GLOBUS_GASS_TRANSFER_HTTP_LISTENER_READY;
- break;
- case GLOBUS_GASS_TRANSFER_HTTP_LISTENER_CLOSING1:
- case GLOBUS_GASS_TRANSFER_HTTP_LISTENER_CLOSED:
- break;
- case GLOBUS_GASS_TRANSFER_HTTP_LISTENER_STARTING:
- case GLOBUS_GASS_TRANSFER_HTTP_LISTENER_ACCEPTING:
- case GLOBUS_GASS_TRANSFER_HTTP_LISTENER_READY:
- case GLOBUS_GASS_TRANSFER_HTTP_LISTENER_CLOSING2:
- globus_assert(proto->state != GLOBUS_GASS_TRANSFER_HTTP_LISTENER_STARTING);
- globus_assert(proto->state != GLOBUS_GASS_TRANSFER_HTTP_LISTENER_ACCEPTING);
- globus_assert(proto->state != GLOBUS_GASS_TRANSFER_HTTP_LISTENER_READY);
- globus_assert(proto->state != GLOBUS_GASS_TRANSFER_HTTP_LISTENER_CLOSING2);
- }
- listener = proto->listener;
- globus_l_gass_transfer_http_unlock();
- debug_printf(2, (_GTSL("calling globus_gass_transfer_proto_listener_ready()")));
- globus_gass_transfer_proto_listener_ready(listener);
- debug_printf(3, (_GTSL("Exiting %s()\n"),myname));
- }
- /* globus_l_gass_transfer_http_listen_callback() */
- static
- void
- globus_l_gass_transfer_http_accept_callback(
- void * callback_arg,
- globus_io_handle_t * handle,
- globus_result_t result)
- {
- globus_gass_transfer_http_listener_proto_t *l;
- MYNAME(globus_l_gass_transfer_http_accept_callback);
-
- debug_printf(3, (_GTSL("Entering %s()\n"),myname));
- globus_l_gass_transfer_http_lock();
- fflush(stdout);
- l = (globus_gass_transfer_http_listener_proto_t *) callback_arg;
- switch(l->state)
- {
- case GLOBUS_GASS_TRANSFER_HTTP_LISTENER_ACCEPTING:
- l->request->response_buffer = globus_malloc(GLOBUS_L_GASS_RESPONSE_LEN *
- sizeof(globus_byte_t));
- l->request->response_buflen = GLOBUS_L_GASS_RESPONSE_LEN;
- l->request->response_offset = 0;
- l->request->parsed_offset = 0;
- if(result != GLOBUS_SUCCESS)
- {
- globus_l_gass_transfer_http_unlock();
- globus_l_gass_transfer_http_request_callback(
- l,
- &l->request->handle,
- result,
- l->request->response_buffer,
- 0);
- debug_printf(3, (_GTSL("Exiting globus_l_gass_transfer_http_accept_callback()\n")));
- return;
- }
- else
- {
- debug_printf(4, (_GTSL("%s(): Registering read on %p\n"),
- myname,
- &l->request->handle));
- globus_io_register_read(&l->request->handle,
- l->request->response_buffer,
- l->request->response_buflen,
- 1,
- globus_l_gass_transfer_http_request_callback,
- l);
- }
- break;
- case GLOBUS_GASS_TRANSFER_HTTP_LISTENER_CLOSING2:
- case GLOBUS_GASS_TRANSFER_HTTP_LISTENER_CLOSED:
- globus_l_gass_transfer_http_unlock();
- globus_gass_transfer_proto_new_listener_request(l->listener,
- l->request->request,
- GLOBUS_NULL);
- globus_l_gass_transfer_http_lock();
- /* should destroy the proto->request here? */
- break;
- case GLOBUS_GASS_TRANSFER_HTTP_LISTENER_STARTING:
- case GLOBUS_GASS_TRANSFER_HTTP_LISTENER_LISTENING:
- case GLOBUS_GASS_TRANSFER_HTTP_LISTENER_READY:
- case GLOBUS_GASS_TRANSFER_HTTP_LISTENER_CLOSING1:
- globus_assert(l->state != GLOBUS_GASS_TRANSFER_HTTP_LISTENER_STARTING);
- globus_assert(l->state != GLOBUS_GASS_TRANSFER_HTTP_LISTENER_LISTENING);
- globus_assert(l->state != GLOBUS_GASS_TRANSFER_HTTP_LISTENER_READY);
- globus_assert(l->state != GLOBUS_GASS_TRANSFER_HTTP_LISTENER_CLOSING1);
- }
- globus_l_gass_transfer_http_unlock();
- debug_printf(3, (_GTSL("Exiting %s()\n"), myname));
- }
- /* globus_l_gass_transfer_http_accept_callback() */
- static
- void
- globus_l_gass_transfer_http_request_refer(
- globus_gass_transfer_request_proto_t * rproto,
- globus_gass_transfer_request_t request)
- {
- globus_gass_transfer_http_request_proto_t * proto;
- globus_gass_transfer_referral_t referral;
- int rc;
- char * referral_string;
- globus_size_t referral_count;
- globus_size_t body_count=0; /* :) */
- globus_size_t offset;
- globus_size_t x;
- globus_size_t i;
- globus_size_t digits = 0;
- MYNAME(globus_l_gass_transfer_http_request_refer);
-
- globus_l_gass_transfer_http_lock();
- proto = (globus_gass_transfer_http_request_proto_t *) rproto;
- rc = globus_gass_transfer_request_get_referral(request,
- &referral);
- /* HTTP/1.1 302 Document Moved CRLF
- * Location: referral.url[0] CRLF
- * Content-Length: $body_count CRLF
- * Content-Type: text/html CRLF
- * CRLF
- * <html><head><title>300 Multiple Choices</title></head><body>
- * <a href="<referral.url[1]>">referral.url[1]</a><br>
- * ..
- * <a href="<referral.url[i]>">referral.url[i]</a><br>
- * </body></html>
- */
- referral_count = 1;
- referral_count += strlen(GLOBUS_L_REFER_RESPONSE);
- referral_count += strlen(GLOBUS_L_LOCATION_HEADER);
- referral_count += 2;
- referral_count += strlen(GLOBUS_L_CONTENT_LENGTH_HEADER);
- referral_count += strlen(GLOBUS_L_HTML_HEADER);
- referral_count += strlen(referral.url[0]);
- body_count += strlen(GLOBUS_L_HTML_REFERRAL_BODY_HEAD);
- body_count += strlen(GLOBUS_L_HTML_REFERRAL_BODY_TAIL);
- for(i = 0 ; i < referral.count; i++)
- {
- body_count += strlen(GLOBUS_L_HTML_HREF);
- body_count += strlen(referral.url[i]);
- body_count += strlen(referral.url[i]);
- }
- /* count the number of decimal digits in the body */
- x=body_count;
- do
- {
- digits++;
- x /= 10;
- } while(x > 0);
- referral_count += digits;
- referral_string = globus_malloc(referral_count + body_count);
- offset = sprintf(referral_string,
- GLOBUS_L_REFER_RESPONSE);
- offset += sprintf(referral_string + offset,
- GLOBUS_L_LOCATION_HEADER,
- referral.url[0]);
- offset += sprintf(referral_string + offset,
- GLOBUS_L_HTML_HEADER);
- offset += sprintf(referral_string + offset,
- GLOBUS_L_CONTENT_LENGTH_HEADER,
- (long) body_count);
- offset += sprintf(referral_string + offset,
- CRLF);
- offset += sprintf(referral_string + offset,
- GLOBUS_L_HTML_REFERRAL_BODY_HEAD);
- for(i = 0 ; i < referral.count; i++)
- {
- offset += sprintf(referral_string + offset,
- GLOBUS_L_HTML_HREF,
- referral.url[i],
- referral.url[i]);
- }
- offset += sprintf(referral_string + offset,
- GLOBUS_L_HTML_REFERRAL_BODY_TAIL);
- proto->state = GLOBUS_GASS_TRANSFER_HTTP_STATE_REFERRED;
- globus_gass_transfer_referral_destroy(&referral);
- debug_printf(4, (_GTSL("%s(): Registering write on %p\n"),
- myname,
- &proto->handle));
- globus_io_register_write(&proto->handle,
- (globus_byte_t *) referral_string,
- strlen(referral_string),
- globus_l_gass_transfer_http_write_response,
- proto);
- globus_l_gass_transfer_http_unlock();
- }
- /* globus_l_gass_transfer_http_request_refer() */
- static
- void
- globus_l_gass_transfer_http_request_deny(
- globus_gass_transfer_request_proto_t * rproto,
- globus_gass_transfer_request_t request)
- {
- globus_gass_transfer_http_request_proto_t * proto;
- char * deny_string;
- globus_size_t deny_count;
- globus_size_t body_count=0; /* :) */
- globus_size_t offset;
- globus_size_t x;
- globus_size_t digits = 0;
- int reason;
- char * message;
- MYNAME(globus_l_gass_transfer_http_request_deny);
-
- globus_l_gass_transfer_http_lock();
- proto = (globus_gass_transfer_http_request_proto_t *) rproto;
- reason = globus_gass_transfer_request_get_denial_reason(request);
- if(reason < 400 ||
- reason >= 600)
- {
- reason = 500;
- message = globus_libc_strdup(GLOBUS_L_…