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