00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef GLOBUS_DONT_DOCUMENT_INTERNAL
00018
00026 #ifndef GLOBUS_L_GASS_TRANSFER_HTTP_H
00027 #define GLOBUS_L_GASS_TRANSFER_HTTP_H
00028
00029 #ifdef __cplusplus
00030 extern "C" {
00031 #endif
00032
00033
00034
00035
00036 enum
00037 {
00038 GLOBUS_L_DEFAULT_HTTP_PORT = 80,
00039 GLOBUS_L_DEFAULT_HTTPS_PORT = 443,
00040 GLOBUS_L_GASS_RESPONSE_LEN = 256
00041 };
00042
00043 typedef enum
00044 {
00045 GLOBUS_L_LINE_MODE_UNKNOWN,
00046 GLOBUS_L_LINE_MODE_CR,
00047 GLOBUS_L_LINE_MODE_LF,
00048 GLOBUS_L_LINE_MODE_CRLF
00049 } globus_gass_transfer_http_line_mode_t;
00050
00051
00052
00053
00054
00055
00056 const globus_gass_transfer_http_line_mode_t
00057 globus_l_gass_transfer_http_line_mode =
00058 #ifndef TARGET_ARCH_WIN32
00059 GLOBUS_L_LINE_MODE_LF;
00060 #else
00061 GLOBUS_L_LINE_MODE_CRLF;
00062 #endif
00063
00064
00065
00066
00067 #define GLOBUS_L_TEXT_BYTE(text) (text & 0x7f)
00068
00069 static globus_mutex_t globus_l_gass_transfer_http_mutex;
00070 static globus_cond_t globus_l_gass_transfer_http_cond;
00071
00072 #define globus_l_gass_transfer_http_lock() \
00073 globus_mutex_lock(&globus_l_gass_transfer_http_mutex) \
00074
00075 #define globus_l_gass_transfer_http_unlock() \
00076 \
00077 globus_mutex_unlock(&globus_l_gass_transfer_http_mutex)
00078 #define globus_l_gass_transfer_http_wait() \
00079 globus_cond_wait(&globus_l_gass_transfer_http_cond, \
00080 &globus_l_gass_transfer_http_mutex)
00081 #define globus_l_gass_transfer_http_signal() \
00082 globus_cond_signal(&globus_l_gass_transfer_http_cond)
00083
00084 static char * globus_l_gass_transfer_http_subject_name;
00085
00086
00087 #define CR '\015'
00088 #define LF '\012'
00089 #define CRLF "\015\012"
00090 #define CR_STRING "\015"
00091 #define LF_STRING "\012"
00092
00093
00094 #define GLOBUS_GASS_HTTP_VERSION "Globus-GASS-HTTP/1.1.0"
00095
00096 #define GLOBUS_L_APPEND_URI "/globus-bins/GASSappend?"
00097
00098 #define GLOBUS_L_GET_COMMAND "GET %s HTTP/1.1" CRLF \
00099 "Host: %s" CRLF \
00100 "Connection: close" CRLF \
00101 "User-Agent: " GLOBUS_GASS_HTTP_VERSION CRLF
00102
00103 #define GLOBUS_L_PUT_COMMAND "PUT %s HTTP/1.1" CRLF \
00104 "Host: %s" CRLF \
00105 "Connection: close" CRLF \
00106 "User-Agent: " GLOBUS_GASS_HTTP_VERSION CRLF
00107
00108 #define GLOBUS_L_APPEND_COMMAND "POST " GLOBUS_L_APPEND_URI "%s " \
00109 "HTTP/1.1" CRLF \
00110 "Host: %s" CRLF \
00111 "Connection: close" CRLF \
00112 "User-Agent: " GLOBUS_GASS_HTTP_VERSION CRLF
00113
00114 #define GLOBUS_L_REFER_RESPONSE "HTTP/1.1 302 Moved Temporarily" CRLF \
00115 "Connection: close" CRLF \
00116 "Server: " GLOBUS_GASS_HTTP_VERSION CRLF
00117
00118 #define GLOBUS_L_CONTINUE_RESPONSE "HTTP/1.1 100 Continue" CRLF
00119
00120 #define GLOBUS_L_GENERIC_RESPONSE "HTTP/1.%d %d %s" CRLF \
00121 "Connection: close" CRLF \
00122 "Server: " GLOBUS_GASS_HTTP_VERSION CRLF
00123 #define GLOBUS_L_OK "Ok"
00124
00125 #define GLOBUS_L_DENIAL_RESPONSE "HTTP/1.1 %d %s" CRLF \
00126 "Connection: close" CRLF \
00127 "Server: " GLOBUS_GASS_HTTP_VERSION CRLF
00128
00129 #define GLOBUS_L_DEFAULT_DENIAL_MESSAGE "Internal Server Error"
00130
00131 #define GLOBUS_L_CONTENT_LENGTH_HEADER "Content-Length: %ld" CRLF
00132 #define GLOBUS_L_CHUNKED_HEADER "Transfer-Encoding: chunked" CRLF
00133 #define GLOBUS_L_BINARY_HEADER "Content-Type: " \
00134 "application/octet-stream" CRLF
00135 #define GLOBUS_L_TEXT_HEADER "Content-Type: text/plain" CRLF
00136 #define GLOBUS_L_HTML_HEADER "Content-Type: text/html" CRLF
00137 #define GLOBUS_L_HTML_REFERRAL_BODY_HEAD \
00138 "<html><head><title>Document Moved</title></head><body>"
00139 #define GLOBUS_L_HTML_REFERRAL_BODY_TAIL \
00140 "</body></html>"
00141 #define GLOBUS_L_HTML_DENIAL_BODY "<html><head><title>%d %s</title></head><body>" CRLF \
00142 "<h1>%d %s</h1></body></html>" CRLF
00143 #define GLOBUS_L_HTML_HREF "<a href=\"%s\">%s</a><br>"
00144 #define GLOBUS_L_LOCATION_HEADER "Location: %s" CRLF
00145
00146 #define GLOBUS_L_DEFAULT_FAILURE_CODE 400
00147 #define GLOBUS_L_DEFAULT_FAILURE_REASON "Bad Request"
00148
00149
00150 #define GLOBUS_L_PROTOCOL_FAILURE_CODE 416
00151 #define GLOBUS_L_PROTOCOL_FAILURE_REASON "Protocol Error"
00152
00153 #define GLOBUS_L_MALLOC_FAILURE_CODE 417
00154 #define GLOBUS_L_MALLOC_FAILURE_REASON "Malloc Error"
00155
00156
00157
00158
00159 typedef enum
00160 {
00161
00162 GLOBUS_GASS_TRANSFER_HTTP_STATE_CONNECTING,
00163 GLOBUS_GASS_TRANSFER_HTTP_STATE_REQUESTING,
00164 GLOBUS_GASS_TRANSFER_HTTP_STATE_CLOSING,
00165 GLOBUS_GASS_TRANSFER_HTTP_STATE_REFERRED,
00166 GLOBUS_GASS_TRANSFER_HTTP_STATE_DENIED,
00167 GLOBUS_GASS_TRANSFER_HTTP_STATE_RESPONDING,
00168
00169 GLOBUS_GASS_TRANSFER_HTTP_STATE_IDLE,
00170 GLOBUS_GASS_TRANSFER_HTTP_STATE_DONE,
00171 GLOBUS_GASS_TRANSFER_HTTP_STATE_PENDING
00172 } globus_gass_transfer_http_state_t;
00173
00174
00175 typedef enum
00176 {
00177 GLOBUS_GASS_TRANSFER_HTTP_LISTENER_STARTING,
00178 GLOBUS_GASS_TRANSFER_HTTP_LISTENER_LISTENING,
00179 GLOBUS_GASS_TRANSFER_HTTP_LISTENER_READY,
00180 GLOBUS_GASS_TRANSFER_HTTP_LISTENER_ACCEPTING,
00181 GLOBUS_GASS_TRANSFER_HTTP_LISTENER_CLOSING1,
00182 GLOBUS_GASS_TRANSFER_HTTP_LISTENER_CLOSING2,
00183 GLOBUS_GASS_TRANSFER_HTTP_LISTENER_CLOSED
00184 } globus_gass_transfer_listener_state_t;
00185 typedef enum
00186 {
00187 GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_CHUNK_SIZE,
00188 GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_CHUNK_EXT,
00189 GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_CHUNK_END_HEADER_CR,
00190 GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_CHUNK_END_HEADER_LF,
00191 GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_CHUNK_BODY,
00192 GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_CHUNK_END_BODY_CR,
00193 GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_CHUNK_END_BODY_LF,
00194 GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_CHUNK_FOOTER,
00195 GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_UNTIL_LENGTH,
00196 GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_UNTIL_EOF,
00197 GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_EOF,
00198 GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_ERROR
00199 } globus_l_gass_transfer_http_recv_state_t;
00200
00201 typedef struct
00202 {
00203
00204 globus_gass_transfer_proto_listener_t close_listener;
00205 globus_gass_transfer_proto_listener_t listen;
00206 globus_gass_transfer_proto_accept_t accept;
00207 globus_gass_transfer_proto_listener_t destroy;
00208
00209
00210 globus_gass_transfer_listener_t listener;
00211 globus_io_handle_t handle;
00212 globus_url_scheme_t url_scheme;
00213
00214 globus_gass_transfer_listener_state_t state;
00215 globus_bool_t destroy_called;
00216
00217 struct globus_gass_transfer_http_request_proto_s * request;
00218 } globus_gass_transfer_http_listener_proto_t;
00219
00220 typedef struct globus_gass_transfer_http_request_proto_s
00221 {
00222
00223 globus_gass_transfer_proto_send_t send_buffer;
00224 globus_gass_transfer_proto_receive_t recv_buffer;
00225
00226 globus_gass_transfer_proto_func_t fail;
00227
00228 globus_gass_transfer_proto_func_t deny;
00229 globus_gass_transfer_proto_func_t refer;
00230 globus_gass_transfer_proto_func_t authorize;
00231
00232 globus_gass_transfer_proto_func_t destroy;
00233
00234
00235 globus_io_handle_t handle;
00236
00237
00238 volatile globus_bool_t oneshot_registered;
00239 volatile globus_bool_t oneshot_active;
00240
00241 volatile globus_gass_transfer_http_state_t state;
00242
00243 globus_gass_transfer_request_t request;
00244
00245 globus_bool_t failure_occurred;
00246 globus_bool_t destroy_called;
00247
00248
00249 globus_url_t proxy_url;
00250 globus_bool_t text_mode;
00251 globus_size_t block_size;
00252
00253
00254 globus_url_t url;
00255 char * url_string;
00256 globus_gass_transfer_request_type_t type;
00257
00258
00259
00260
00261
00262
00263 struct iovec iov[4];
00264
00265 globus_size_t length;
00266 globus_size_t handled;
00267 globus_bool_t chunked;
00268
00269 globus_bool_t last_data;
00270
00271 globus_bool_t client_side;
00272
00273
00274 globus_size_t chunk_left;
00275 globus_l_gass_transfer_http_recv_state_t recv_state;
00276 globus_bool_t eof_read;
00277
00278
00279 globus_byte_t * response_buffer;
00280 globus_size_t response_buflen;
00281 globus_size_t response_offset;
00282 globus_size_t parsed_offset;
00283 int code;
00284 char * reason;
00285 globus_bool_t parse_error;
00286
00287
00288 int major;
00289 int minor;
00290
00291 globus_list_t * headers;
00292
00293
00294 globus_gass_transfer_http_line_mode_t line_mode;
00295
00296
00297
00298
00299 globus_byte_t * user_buffer;
00300 globus_size_t user_buflen;
00301 globus_size_t user_offset;
00302 globus_size_t user_waitlen;
00303
00304 globus_gass_transfer_authorization_t authorization_mode;
00305 char * authorized_subject;
00306 char * connected_subject;
00307
00308
00309 char * uri;
00310 char * method;
00311 globus_bool_t proxy_connect;
00312 globus_bool_t got_response;
00313 globus_bool_t waiting_for_response;
00314 } globus_gass_transfer_http_request_proto_t;
00315
00316
00317
00318
00319 #if !defined(GLOBUS_GASS_TRANSFER_HTTP_PARSER_TEST)
00320 static
00321 void
00322 globus_l_gass_transfer_http_send(
00323 globus_gass_transfer_request_proto_t * proto,
00324 globus_gass_transfer_request_t request,
00325 globus_byte_t * buffer,
00326 globus_size_t buffer_length,
00327 globus_bool_t last_data);
00328
00329 static
00330 void
00331 globus_l_gass_transfer_http_receive(
00332 globus_gass_transfer_request_proto_t * proto,
00333 globus_gass_transfer_request_t request,
00334 globus_byte_t * buffer,
00335 globus_size_t buffer_length,
00336 globus_size_t wait_for_length);
00337
00338 static
00339 void
00340 globus_l_gass_transfer_http_writev_callback(
00341 void * callback_arg,
00342 globus_io_handle_t * handle,
00343 globus_result_t result,
00344 struct iovec * iov,
00345 globus_size_t iovcnt,
00346 globus_size_t nbytes);
00347
00348 static
00349 void
00350 globus_l_gass_transfer_http_write_callback(
00351 void * callback_arg,
00352 globus_io_handle_t * handle,
00353 globus_result_t result,
00354 globus_byte_t * buf,
00355 globus_size_t nbytes);
00356
00357 static
00358 void
00359 globus_l_gass_transfer_http_write_response(
00360 void * arg,
00361 globus_io_handle_t * handle,
00362 globus_result_t result,
00363 globus_byte_t * buf,
00364 globus_size_t nbytes);
00365
00366 static
00367 void
00368 globus_l_gass_transfer_http_proto_destroy(
00369 globus_gass_transfer_http_request_proto_t * proto);
00370
00371 static
00372 void
00373 globus_l_gass_transfer_http_read_callback(
00374 void * callback_arg,
00375 globus_io_handle_t * handle,
00376 globus_result_t result,
00377 globus_byte_t * buf,
00378 globus_size_t nbytes);
00379
00380 static
00381 void
00382 globus_l_gass_transfer_http_read_buffered_callback(
00383 void * callback_arg,
00384 globus_io_handle_t * handle,
00385 globus_result_t result,
00386 globus_byte_t * buf,
00387 globus_size_t nbytes);
00388
00389 static
00390 void
00391 globus_l_gass_transfer_http_callback_read_buffered_callback(
00392 void * arg);
00393
00394 static
00395 void
00396 globus_l_gass_transfer_http_callback_ready_callback(
00397 void * arg);
00398 void
00399 globus_l_gass_transfer_http_copy_text_buffer(
00400 globus_byte_t * output,
00401 globus_byte_t * input,
00402 globus_gass_transfer_http_line_mode_t * line_mode,
00403 globus_size_t input_max_to_copy,
00404 globus_size_t output_max_to_copy,
00405 globus_size_t * input_copied,
00406 globus_size_t * output_copied);
00407
00408 static
00409 void
00410 globus_l_gass_transfer_http_fail(
00411 globus_gass_transfer_request_proto_t * proto,
00412 globus_gass_transfer_request_t request);
00413
00414 static
00415 void
00416 globus_l_gass_transfer_http_close_callback(
00417 void * callback_arg,
00418 globus_io_handle_t * handle,
00419 globus_result_t result);
00420
00421 static
00422 void
00423 globus_l_gass_transfer_http_accept_callback(
00424 void * callback_arg,
00425 globus_io_handle_t * handle,
00426 globus_result_t result);
00427
00428
00429 static
00430 void
00431 globus_l_gass_transfer_http_destroy(
00432 globus_gass_transfer_request_proto_t * proto,
00433 globus_gass_transfer_request_t request);
00434
00435 static
00436 void
00437 globus_l_gass_transfer_http_new_request(
00438 globus_gass_transfer_request_t request,
00439 globus_gass_transfer_requestattr_t * attr);
00440
00441 static
00442 globus_object_t *
00443 globus_l_gass_transfer_http_new_requestattr(
00444 char * url_scheme);
00445
00446 static
00447 globus_object_t *
00448 globus_l_gass_transfer_http_new_listenerattr(
00449 char * url_scheme);
00450
00451 static
00452 void
00453 globus_l_gass_transfer_http_close_listener(
00454 globus_gass_transfer_listener_proto_t * proto,
00455 globus_gass_transfer_listener_t listener);
00456
00457 static
00458 void
00459 globus_l_gass_transfer_http_listen(
00460 globus_gass_transfer_listener_proto_t * proto,
00461 globus_gass_transfer_listener_t listener);
00462
00463 static
00464 void
00465 globus_l_gass_transfer_http_accept(
00466 globus_gass_transfer_listener_proto_t * proto,
00467 globus_gass_transfer_listener_t listener,
00468 globus_gass_transfer_request_t request,
00469 globus_gass_transfer_requestattr_t * attr);
00470
00471 static
00472 globus_bool_t
00473 globus_l_gass_transfer_http_authorization_callback(
00474 void * arg,
00475 globus_io_handle_t * handle,
00476 globus_result_t result,
00477 char * identity,
00478 gss_ctx_id_t context_handle);
00479
00480 static
00481 void
00482 globus_l_gass_transfer_http_listener_destroy(
00483 globus_gass_transfer_listener_proto_t * proto,
00484 globus_gass_transfer_listener_t listener);
00485
00486 static
00487 int
00488 globus_l_gass_transfer_http_new_listener(
00489 globus_gass_transfer_listener_t listener,
00490 globus_gass_transfer_listenerattr_t * attr,
00491 char * scheme,
00492 char ** base_url,
00493 globus_gass_transfer_listener_proto_t ** proto);
00494
00495 static
00496 void
00497 globus_l_gass_transfer_http_connect_callback(
00498 void * arg,
00499 globus_io_handle_t * handle,
00500 globus_result_t result);
00501
00502 static
00503 void
00504 globus_l_gass_transfer_http_command_callback(
00505 void * arg,
00506 globus_io_handle_t * handle,
00507 globus_result_t result,
00508 globus_byte_t * buf,
00509 globus_size_t nbytes);
00510
00511 static
00512 void
00513 globus_l_gass_transfer_http_response_callback(
00514 void * arg,
00515 globus_io_handle_t * handle,
00516 globus_result_t result,
00517 globus_byte_t * buf,
00518 globus_size_t nbytes);
00519
00520 static
00521 void
00522 globus_l_gass_transfer_http_listener_proto_destroy(
00523 globus_gass_transfer_http_listener_proto_t *
00524 proto);
00525 static
00526 void
00527 globus_l_gass_transfer_http_callback_listen_callback(
00528 void * arg);
00529
00530 static
00531 void
00532 globus_l_gass_transfer_http_listen_callback(
00533 void * callback_arg,
00534 globus_io_handle_t * handle,
00535 globus_result_t result);
00536 #endif
00537
00538 static
00539 globus_bool_t
00540 globus_l_gass_transfer_http_find_crlf(
00541 globus_byte_t * bytes,
00542 globus_size_t len,
00543 globus_size_t * crlf_offset);
00544
00545 static
00546 globus_bool_t
00547 globus_l_gass_transfer_http_parse_headers(
00548 globus_gass_transfer_http_request_proto_t * proto);
00549
00550 static
00551 globus_bool_t
00552 globus_l_gass_transfer_http_parse_one_header(
00553 globus_gass_transfer_http_request_proto_t * proto,
00554 globus_bool_t * last_header);
00555
00556 static
00557 globus_bool_t
00558 globus_l_gass_transfer_http_parse_status_line(
00559 globus_gass_transfer_http_request_proto_t * proto);
00560
00561 static
00562 globus_bool_t
00563 islws(
00564 char byte);
00565
00566 static
00567 globus_bool_t
00568 ischar(
00569 char byte);
00570
00571 static
00572 globus_bool_t
00573 istspecial(
00574 char byte);
00575
00576 static
00577 void
00578 globus_l_gass_transfer_http_callback_send_callback(
00579 void * arg);
00580
00581 static
00582 void
00583 globus_l_gass_transfer_http_request_callback(
00584 void * arg,
00585 globus_io_handle_t * handle,
00586 globus_result_t result,
00587 globus_byte_t * buf,
00588 globus_size_t nbytes);
00589
00590 static
00591 globus_result_t
00592 globus_l_gass_transfer_http_register_read(
00593 globus_gass_transfer_http_request_proto_t * proto);
00594
00595 static
00596 char *
00597 globus_l_gass_transfer_http_construct_request(
00598 globus_gass_transfer_http_request_proto_t * proto);
00599
00600 static
00601 globus_bool_t
00602 globus_l_gass_transfer_http_handle_chunk(
00603 globus_gass_transfer_http_request_proto_t * proto);
00604
00605 static
00606 globus_bool_t
00607 globus_l_gass_transfer_http_parse_response(
00608 globus_gass_transfer_http_request_proto_t * proto);
00609
00610 static
00611 globus_bool_t
00612 globus_l_gass_transfer_http_parse_request(
00613 globus_gass_transfer_http_request_proto_t * proto);
00614
00615 static
00616 globus_bool_t
00617 globus_l_gass_transfer_http_parse_request_line(
00618 globus_gass_transfer_http_request_proto_t * proto);
00619
00620 static
00621 void
00622 globus_l_gass_transfer_http_extract_referral(
00623 globus_gass_transfer_http_request_proto_t * proto,
00624 char *** referral,
00625 globus_size_t * referral_count);
00626
00627 static
00628 void
00629 globus_l_gass_transfer_http_callback_denied(
00630 void * arg);
00631
00632 static
00633 void
00634 globus_l_gass_transfer_http_close(
00635 globus_gass_transfer_http_request_proto_t * proto);
00636
00637 static
00638 globus_result_t
00639 globus_l_gass_transfer_http_register_close(
00640 globus_gass_transfer_http_request_proto_t * proto);
00641
00642 static
00643 void
00644 globus_l_gass_transfer_http_listener_close(
00645 globus_gass_transfer_http_listener_proto_t * proto);
00646
00647 #ifdef __cplusplus
00648 }
00649 #endif
00650
00651 #endif
00652
00653 #endif