/* * Copyright (c) 2021-2024 joshua stein * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef __REQUEST_H__ #define __REQUEST_H__ #include #include "stdint.h" #include "detritus.h" /* TODO: don't pass browser for statusf but return specific error codes? */ #include "browser.h" #include "tcp.h" #define GOPHER_PORT 70 #define FINGER_PORT 79 #define HTTP_PORT 80 #define HTTPS_PORT 443 #define GEMINI_PORT 1965 #define URI_MAX_SCHEME_LEN 20 #define URI_MAX_HOSTNAME_LEN 255 #define URI_MAX_PORT_LEN 5 #define URI_MAX_PATH_LEN 512 #define URI_MAX_QUERY_LEN 512 #define URI_MAX_STR_LEN (URI_MAX_SCHEME_LEN + 3 + \ URI_MAX_HOSTNAME_LEN + \ 1 + URI_MAX_PORT_LEN + \ URI_MAX_PATH_LEN + \ 1 + URI_MAX_QUERY_LEN) struct URI { char *scheme; char *hostname; char *path; char *query; char *str; unsigned short port; }; struct request { unsigned char buf[(4 * 1500) + 2048]; /* 4*MTU + input */ unsigned char input[1500]; unsigned long input_len; char *output; unsigned long output_len; unsigned long output_pos; TCPiopb iopb; StreamPtr stream; wdsEntry wds[2]; TCPStatusPB status_pb; bool tcp_done_reading; char hostname[URI_MAX_HOSTNAME_LEN]; unsigned short port; ip_addr ip; char ip_s[12 + 3 + 1]; uint8_t tls_id; short tls_state; unsigned char tls_flags; struct browser *browser; }; extern uint8_t tls_req_last_id; struct tls_init_request { uint8_t flags[2]; #define BLUESCSI_TLS_INIT_REQUEST_FLAG_NO_VERIFY (1 << 0) uint8_t unix_time[4]; char hostname[256]; }; struct URI * parse_uri(char *uristr); struct URI * build_relative_uri(struct URI *uri, char *relative, size_t len); char * uri_encode(unsigned char *str); /* * queuer is called with wrote=false to set buf and len, then data is * written to socket, then queuer is called again with did_write=true and * len set to the actual bytes written */ typedef bool (*request_data_queuer)(struct request *request, void *cookie, char **buf, size_t *len, bool did_write); /* * consumer is called with did_read=false and len, and must set buf to * something that can hold len bytes, then data is read into buf, then * consumer is called again with did_read=true and len set to the actual * bytes read */ typedef bool (*request_data_consumer)(struct request *request, void *cookie, char **buf, size_t *len, bool did_read); /* * shuffle handles actual tcp/tls reading and writing, then calls back to * queuer and consumer when necessary */ bool request_data_shuffle(struct request *request, request_data_queuer queuer, void *queuer_cookie, request_data_consumer consumer, void *consumer_cookie); struct request * request_connect(struct browser *browser, char *hostname, unsigned short port, bool tls, unsigned char tls_flags); void request_xfree(struct request **requestp); /* TLS functions */ short scsi_find_tls(void); void scsi_cleanup(void); bool scsi_can_do_tls(void); uint8_t scsi_tls_init(struct tls_init_request *req); bool scsi_tls_close(uint8_t tls_id); short scsi_tls_status(uint8_t tls_id, short *cipherspace, short *plainspace, short *error); size_t scsi_tls_read(uint8_t tls_id, unsigned char **buf, size_t max_size, bool cipher); size_t scsi_tls_write(uint8_t tls_id, unsigned char *buf, size_t buf_size, bool cipher); #endif