globus_gass_transfer  8.13
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
globus_l_gass_transfer_http.h
1 
2 #ifndef GLOBUS_DONT_DOCUMENT_INTERNAL
3 
11 #ifndef GLOBUS_L_GASS_TRANSFER_HTTP_H
12 #define GLOBUS_L_GASS_TRANSFER_HTTP_H
13 
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17 
18 /******************************************************************************
19  Module Specific Constants
20 ******************************************************************************/
21 enum
22 {
23  GLOBUS_L_DEFAULT_HTTP_PORT = 80,
24  GLOBUS_L_DEFAULT_HTTPS_PORT = 443,
25  GLOBUS_L_GASS_RESPONSE_LEN = 256
26 };
27 
28 typedef enum
29 {
30  GLOBUS_L_LINE_MODE_UNKNOWN,
31  GLOBUS_L_LINE_MODE_CR,
32  GLOBUS_L_LINE_MODE_LF,
33  GLOBUS_L_LINE_MODE_CRLF
34 } globus_gass_transfer_http_line_mode_t;
35 
36 /*
37  * Local text format to convert requests with the text_mode attribute
38  * set. Always LF, which is used by the C language. Conversion from LF
39  * ode to the local storage is up to the user (or Globus I/O library).
40  */
41 const globus_gass_transfer_http_line_mode_t
42 globus_l_gass_transfer_http_line_mode =
43 #ifndef TARGET_ARCH_WIN32
44  GLOBUS_L_LINE_MODE_LF;
45 #else
46  GLOBUS_L_LINE_MODE_CRLF;
47 #endif
48 
49 /* For 8-bit Text:
50 #define GLOBUS_L_TEXT_BYTE(text) (text)
51 */
52 #define GLOBUS_L_TEXT_BYTE(text) (text & 0x7f)
53 
54 static globus_mutex_t globus_l_gass_transfer_http_mutex;
55 static globus_cond_t globus_l_gass_transfer_http_cond;
56 
57 #define globus_l_gass_transfer_http_lock() \
58  globus_mutex_lock(&globus_l_gass_transfer_http_mutex)/*,*/ \
59  /*printf("locked mutex at %s: %d\n", __FILE__, __LINE__)*/
60 #define globus_l_gass_transfer_http_unlock() \
61  /*printf("unlocking mutex at %s: %d\n", __FILE__, __LINE__), */\
62  globus_mutex_unlock(&globus_l_gass_transfer_http_mutex)
63 #define globus_l_gass_transfer_http_wait() \
64  globus_cond_wait(&globus_l_gass_transfer_http_cond, \
65  &globus_l_gass_transfer_http_mutex)
66 #define globus_l_gass_transfer_http_signal() \
67  globus_cond_signal(&globus_l_gass_transfer_http_cond)
68 
69 static char * globus_l_gass_transfer_http_subject_name;
70 
71 /* Some handy, common values in the HTTP protocol */
72 #define CR '\015'
73 #define LF '\012'
74 #define CRLF "\015\012"
75 #define CR_STRING "\015"
76 #define LF_STRING "\012"
77 
78 /* Commands the client issues to the server */
79 #define GLOBUS_GASS_HTTP_VERSION "Globus-GASS-HTTP/1.1.0"
80 
81 #define GLOBUS_L_APPEND_URI "/globus-bins/GASSappend?"
82 
83 #define GLOBUS_L_GET_COMMAND "GET %s HTTP/1.1" CRLF \
84  "Host: %s" CRLF \
85  "Connection: close" CRLF \
86  "User-Agent: " GLOBUS_GASS_HTTP_VERSION CRLF
87 
88 #define GLOBUS_L_PUT_COMMAND "PUT %s HTTP/1.1" CRLF \
89  "Host: %s" CRLF \
90  "Connection: close" CRLF \
91  "User-Agent: " GLOBUS_GASS_HTTP_VERSION CRLF
92 
93 #define GLOBUS_L_APPEND_COMMAND "POST " GLOBUS_L_APPEND_URI "%s " \
94  "HTTP/1.1" CRLF \
95  "Host: %s" CRLF \
96  "Connection: close" CRLF \
97  "User-Agent: " GLOBUS_GASS_HTTP_VERSION CRLF
98 
99 #define GLOBUS_L_REFER_RESPONSE "HTTP/1.1 302 Moved Temporarily" CRLF \
100  "Connection: close" CRLF \
101  "Server: " GLOBUS_GASS_HTTP_VERSION CRLF
102 
103 #define GLOBUS_L_CONTINUE_RESPONSE "HTTP/1.1 100 Continue" CRLF
104 
105 #define GLOBUS_L_GENERIC_RESPONSE "HTTP/1.%d %d %s" CRLF \
106  "Connection: close" CRLF \
107  "Server: " GLOBUS_GASS_HTTP_VERSION CRLF
108 #define GLOBUS_L_OK "Ok"
109 
110 #define GLOBUS_L_DENIAL_RESPONSE "HTTP/1.1 %d %s" CRLF \
111  "Connection: close" CRLF \
112  "Server: " GLOBUS_GASS_HTTP_VERSION CRLF
113 
114 #define GLOBUS_L_DEFAULT_DENIAL_MESSAGE "Internal Server Error"
115 
116 #define GLOBUS_L_CONTENT_LENGTH_HEADER "Content-Length: %ld" CRLF
117 #define GLOBUS_L_CHUNKED_HEADER "Transfer-Encoding: chunked" CRLF
118 #define GLOBUS_L_BINARY_HEADER "Content-Type: " \
119  "application/octet-stream" CRLF
120 #define GLOBUS_L_TEXT_HEADER "Content-Type: text/plain" CRLF
121 #define GLOBUS_L_HTML_HEADER "Content-Type: text/html" CRLF
122 #define GLOBUS_L_HTML_REFERRAL_BODY_HEAD \
123  "<html><head><title>Document Moved</title></head><body>"
124 #define GLOBUS_L_HTML_REFERRAL_BODY_TAIL \
125  "</body></html>"
126 #define GLOBUS_L_HTML_DENIAL_BODY "<html><head><title>%d %s</title></head><body>" CRLF \
127  "<h1>%d %s</h1></body></html>" CRLF
128 #define GLOBUS_L_HTML_HREF "<a href=\"%s\">%s</a><br>"
129 #define GLOBUS_L_LOCATION_HEADER "Location: %s" CRLF
130 
131 #define GLOBUS_L_DEFAULT_FAILURE_CODE 400
132 #define GLOBUS_L_DEFAULT_FAILURE_REASON "Bad Request"
133 
134 /* The "client failure" (4xx) response codes defined in RFC 2068 end at 415 */
135 #define GLOBUS_L_PROTOCOL_FAILURE_CODE 416
136 #define GLOBUS_L_PROTOCOL_FAILURE_REASON "Protocol Error"
137 
138 #define GLOBUS_L_MALLOC_FAILURE_CODE 417
139 #define GLOBUS_L_MALLOC_FAILURE_REASON "Malloc Error"
140 
141 /******************************************************************************
142  Module specific Types
143 ******************************************************************************/
144 typedef enum
145 {
146  /* Client-only states */
147  GLOBUS_GASS_TRANSFER_HTTP_STATE_CONNECTING,
148  GLOBUS_GASS_TRANSFER_HTTP_STATE_REQUESTING,
149  GLOBUS_GASS_TRANSFER_HTTP_STATE_CLOSING,
150  GLOBUS_GASS_TRANSFER_HTTP_STATE_REFERRED,
151  GLOBUS_GASS_TRANSFER_HTTP_STATE_DENIED,
152  GLOBUS_GASS_TRANSFER_HTTP_STATE_RESPONDING,
153  /* Common states */
154  GLOBUS_GASS_TRANSFER_HTTP_STATE_IDLE,
155  GLOBUS_GASS_TRANSFER_HTTP_STATE_DONE,
156  GLOBUS_GASS_TRANSFER_HTTP_STATE_PENDING
157 } globus_gass_transfer_http_state_t;
158 
159 /* These mirror the GASS listener states exactly */
160 typedef enum
161 {
162  GLOBUS_GASS_TRANSFER_HTTP_LISTENER_STARTING,
163  GLOBUS_GASS_TRANSFER_HTTP_LISTENER_LISTENING,
164  GLOBUS_GASS_TRANSFER_HTTP_LISTENER_READY,
165  GLOBUS_GASS_TRANSFER_HTTP_LISTENER_ACCEPTING,
166  GLOBUS_GASS_TRANSFER_HTTP_LISTENER_CLOSING1,
167  GLOBUS_GASS_TRANSFER_HTTP_LISTENER_CLOSING2,
168  GLOBUS_GASS_TRANSFER_HTTP_LISTENER_CLOSED
169 } globus_gass_transfer_listener_state_t;
170 typedef enum
171 {
172  GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_CHUNK_SIZE,
173  GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_CHUNK_EXT,
174  GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_CHUNK_END_HEADER_CR,
175  GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_CHUNK_END_HEADER_LF,
176  GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_CHUNK_BODY,
177  GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_CHUNK_END_BODY_CR,
178  GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_CHUNK_END_BODY_LF,
179  GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_CHUNK_FOOTER,
180  GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_UNTIL_LENGTH,
181  GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_UNTIL_EOF,
182  GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_EOF,
183  GLOBUS_GASS_TRANSFER_HTTP_RECV_STATE_ERROR
184 } globus_l_gass_transfer_http_recv_state_t;
185 
186 typedef struct
187 {
188  /* Standard "proto" elements */
193 
194  /* Begin internal http-specific proto state */
195  globus_gass_transfer_listener_t listener;
196  globus_io_handle_t handle;
197  globus_url_scheme_t url_scheme;
198 
199  globus_gass_transfer_listener_state_t state;
200  globus_bool_t destroy_called;
201 
202  struct globus_gass_transfer_http_request_proto_s * request;
203 } globus_gass_transfer_http_listener_proto_t;
204 
205 typedef struct globus_gass_transfer_http_request_proto_s
206 {
207  /* Standard "proto" elements */
210 
212 
216 
218 
219  /* Begin internal http-specific proto state */
220  globus_io_handle_t handle;
221  /* last data for sending, and EOF on receiving */
222 
223  volatile globus_bool_t oneshot_registered;
224  volatile globus_bool_t oneshot_active;
225 
226  volatile globus_gass_transfer_http_state_t state;
227 
229 
230  globus_bool_t failure_occurred;
231  globus_bool_t destroy_called;
232 
233  /* Flags from the request attributes */
234  globus_url_t proxy_url;
235  globus_bool_t text_mode;
236  globus_size_t block_size;
237 
238  /* Type and name of the requested resource */
239  globus_url_t url;
240  char * url_string;
242 
243  /*
244  * For the "send" case, a 4 item iovec array, containing
245  * the chunk header, body, and trailing CRLF, and a 0-length
246  * chunk + crlf
247  */
248  struct iovec iov[4];
249  /* Length and transfer encoding */
250  globus_size_t length;
251  globus_size_t handled;
252  globus_bool_t chunked;
253  /* sending-side: are we handling the last data block? */
254  globus_bool_t last_data;
255 
256  globus_bool_t client_side;
257  /* Amount of data from the current chunk still needs to
258  be given to the user */
259  globus_size_t chunk_left;
260  globus_l_gass_transfer_http_recv_state_t recv_state;
261  globus_bool_t eof_read;
262 
263  /* Used to parse/store responses from the HTTP server */
264  globus_byte_t * response_buffer;
265  globus_size_t response_buflen;
266  globus_size_t response_offset;
267  globus_size_t parsed_offset;
268  int code;
269  char * reason;
270  globus_bool_t parse_error;
271 
272  /* Major/minor version of the HTTP protocol we are using */
273  int major;
274  int minor;
275  /* HTTP headers we've received */
276  globus_list_t * headers;
277 
278  /* Line mode of this particular file we are reading */
279  globus_gass_transfer_http_line_mode_t line_mode;
280  /*
281  * The buffer which was handed to the protocol module
282  * from GASS
283  */
284  globus_byte_t * user_buffer;
285  globus_size_t user_buflen;
286  globus_size_t user_offset;
287  globus_size_t user_waitlen;
288 
289  globus_gass_transfer_authorization_t authorization_mode;
290  char * authorized_subject;
291  char * connected_subject;
292 
293  /* For handling requests from client */
294  char * uri;
295  char * method;
296  globus_bool_t proxy_connect;
297  globus_bool_t got_response;
298  globus_bool_t waiting_for_response;
299 } globus_gass_transfer_http_request_proto_t;
300 
301 /******************************************************************************
302  Module specific Prototypes
303 ******************************************************************************/
304 #if !defined(GLOBUS_GASS_TRANSFER_HTTP_PARSER_TEST)
305 static
306 void
307 globus_l_gass_transfer_http_send(
310  globus_byte_t * buffer,
311  globus_size_t buffer_length,
312  globus_bool_t last_data);
313 
314 static
315 void
316 globus_l_gass_transfer_http_receive(
319  globus_byte_t * buffer,
320  globus_size_t buffer_length,
321  globus_size_t wait_for_length);
322 
323 static
324 void
325 globus_l_gass_transfer_http_writev_callback(
326  void * callback_arg,
327  globus_io_handle_t * handle,
328  globus_result_t result,
329  struct iovec * iov,
330  globus_size_t iovcnt,
331  globus_size_t nbytes);
332 
333 static
334 void
335 globus_l_gass_transfer_http_write_callback(
336  void * callback_arg,
337  globus_io_handle_t * handle,
338  globus_result_t result,
339  globus_byte_t * buf,
340  globus_size_t nbytes);
341 
342 static
343 void
344 globus_l_gass_transfer_http_write_response(
345  void * arg,
346  globus_io_handle_t * handle,
347  globus_result_t result,
348  globus_byte_t * buf,
349  globus_size_t nbytes);
350 
351 static
352 void
353 globus_l_gass_transfer_http_proto_destroy(
354  globus_gass_transfer_http_request_proto_t * proto);
355 
356 static
357 void
358 globus_l_gass_transfer_http_read_callback(
359  void * callback_arg,
360  globus_io_handle_t * handle,
361  globus_result_t result,
362  globus_byte_t * buf,
363  globus_size_t nbytes);
364 
365 static
366 void
367 globus_l_gass_transfer_http_read_buffered_callback(
368  void * callback_arg,
369  globus_io_handle_t * handle,
370  globus_result_t result,
371  globus_byte_t * buf,
372  globus_size_t nbytes);
373 
374 static
375 void
376 globus_l_gass_transfer_http_callback_read_buffered_callback(
377  void * arg);
378 
379 static
380 void
381 globus_l_gass_transfer_http_callback_ready_callback(
382  void * arg);
383 void
384 globus_l_gass_transfer_http_copy_text_buffer(
385  globus_byte_t * output,
386  globus_byte_t * input,
387  globus_gass_transfer_http_line_mode_t * line_mode,
388  globus_size_t input_max_to_copy,
389  globus_size_t output_max_to_copy,
390  globus_size_t * input_copied,
391  globus_size_t * output_copied);
392 
393 static
394 void
395 globus_l_gass_transfer_http_fail(
398 
399 static
400 void
401 globus_l_gass_transfer_http_close_callback(
402  void * callback_arg,
403  globus_io_handle_t * handle,
404  globus_result_t result);
405 
406 static
407 void
408 globus_l_gass_transfer_http_accept_callback(
409  void * callback_arg,
410  globus_io_handle_t * handle,
411  globus_result_t result);
412 
413 
414 static
415 void
416 globus_l_gass_transfer_http_destroy(
419 
420 static
421 void
422 globus_l_gass_transfer_http_new_request(
424  globus_gass_transfer_requestattr_t * attr);
425 
426 static
427 globus_object_t *
428 globus_l_gass_transfer_http_new_requestattr(
429  char * url_scheme);
430 
431 static
432 globus_object_t *
433 globus_l_gass_transfer_http_new_listenerattr(
434  char * url_scheme);
435 
436 static
437 void
438 globus_l_gass_transfer_http_close_listener(
440  globus_gass_transfer_listener_t listener);
441 
442 static
443 void
444 globus_l_gass_transfer_http_listen(
446  globus_gass_transfer_listener_t listener);
447 
448 static
449 void
450 globus_l_gass_transfer_http_accept(
452  globus_gass_transfer_listener_t listener,
454  globus_gass_transfer_requestattr_t * attr);
455 
456 static
457 globus_bool_t
458 globus_l_gass_transfer_http_authorization_callback(
459  void * arg,
460  globus_io_handle_t * handle,
461  globus_result_t result,
462  char * identity,
463  gss_ctx_id_t context_handle);
464 
465 static
466 void
467 globus_l_gass_transfer_http_listener_destroy(
469  globus_gass_transfer_listener_t listener);
470 
471 static
472 int
473 globus_l_gass_transfer_http_new_listener(
474  globus_gass_transfer_listener_t listener,
475  globus_gass_transfer_listenerattr_t * attr,
476  char * scheme,
477  char ** base_url,
479 
480 static
481 void
482 globus_l_gass_transfer_http_connect_callback(
483  void * arg,
484  globus_io_handle_t * handle,
485  globus_result_t result);
486 
487 static
488 void
489 globus_l_gass_transfer_http_command_callback(
490  void * arg,
491  globus_io_handle_t * handle,
492  globus_result_t result,
493  globus_byte_t * buf,
494  globus_size_t nbytes);
495 
496 static
497 void
498 globus_l_gass_transfer_http_response_callback(
499  void * arg,
500  globus_io_handle_t * handle,
501  globus_result_t result,
502  globus_byte_t * buf,
503  globus_size_t nbytes);
504 
505 static
506 void
507 globus_l_gass_transfer_http_listener_proto_destroy(
508  globus_gass_transfer_http_listener_proto_t *
509  proto);
510 static
511 void
512 globus_l_gass_transfer_http_callback_listen_callback(
513  void * arg);
514 
515 static
516 void
517 globus_l_gass_transfer_http_listen_callback(
518  void * callback_arg,
519  globus_io_handle_t * handle,
520  globus_result_t result);
521 #endif
522 
523 static
524 globus_bool_t
525 globus_l_gass_transfer_http_find_crlf(
526  globus_byte_t * bytes,
527  globus_size_t len,
528  globus_size_t * crlf_offset);
529 
530 static
531 globus_bool_t
532 globus_l_gass_transfer_http_parse_headers(
533  globus_gass_transfer_http_request_proto_t * proto);
534 
535 static
536 globus_bool_t
537 globus_l_gass_transfer_http_parse_one_header(
538  globus_gass_transfer_http_request_proto_t * proto,
539  globus_bool_t * last_header);
540 
541 static
542 globus_bool_t
543 globus_l_gass_transfer_http_parse_status_line(
544  globus_gass_transfer_http_request_proto_t * proto);
545 
546 static
547 globus_bool_t
548 islws(
549  char byte);
550 
551 static
552 globus_bool_t
553 ischar(
554  char byte);
555 
556 static
557 globus_bool_t
558 istspecial(
559  char byte);
560 
561 static
562 void
563 globus_l_gass_transfer_http_callback_send_callback(
564  void * arg);
565 
566 static
567 void
568 globus_l_gass_transfer_http_request_callback(
569  void * arg,
570  globus_io_handle_t * handle,
571  globus_result_t result,
572  globus_byte_t * buf,
573  globus_size_t nbytes);
574 
575 static
576 globus_result_t
577 globus_l_gass_transfer_http_register_read(
578  globus_gass_transfer_http_request_proto_t * proto);
579 
580 static
581 char *
582 globus_l_gass_transfer_http_construct_request(
583  globus_gass_transfer_http_request_proto_t * proto);
584 
585 static
586 globus_bool_t
587 globus_l_gass_transfer_http_handle_chunk(
588  globus_gass_transfer_http_request_proto_t * proto);
589 
590 static
591 globus_bool_t
592 globus_l_gass_transfer_http_parse_response(
593  globus_gass_transfer_http_request_proto_t * proto);
594 
595 static
596 globus_bool_t
597 globus_l_gass_transfer_http_parse_request(
598  globus_gass_transfer_http_request_proto_t * proto);
599 
600 static
601 globus_bool_t
602 globus_l_gass_transfer_http_parse_request_line(
603  globus_gass_transfer_http_request_proto_t * proto);
604 
605 static
606 void
607 globus_l_gass_transfer_http_extract_referral(
608  globus_gass_transfer_http_request_proto_t * proto,
609  char *** referral,
610  globus_size_t * referral_count);
611 
612 static
613 void
614 globus_l_gass_transfer_http_callback_denied(
615  void * arg);
616 
617 static
618 void
619 globus_l_gass_transfer_http_close(
620  globus_gass_transfer_http_request_proto_t * proto);
621 
622 static
623 globus_result_t
624 globus_l_gass_transfer_http_register_close(
625  globus_gass_transfer_http_request_proto_t * proto);
626 
627 static
628 void
629 globus_l_gass_transfer_http_listener_close(
630  globus_gass_transfer_http_listener_proto_t * proto);
631 
632 #ifdef __cplusplus
633 }
634 #endif
635 
636 #endif /* GLOBUS_L_GASS_TRANSFER_HTTP_H */
637 
638 #endif /* GLOBUS_DONT_DOCUMENT_INTERNAL */
globus_gass_transfer_request_type_t
Definition: globus_gass_transfer.h:129
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:342
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:147
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:274
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 send_length, globus_bool_t last_data)
Definition: globus_gass_transfer_proto.h:107
Protocol module listener handling structure.
Definition: globus_gass_transfer_proto.h:416
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:174
Protocol module request handling structure.
Definition: globus_gass_transfer_proto.h:370