Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Functions | Variables
res_http_post.c File Reference

HTTP POST upload support for Asterisk HTTP server. More...

#include "asterisk.h"
#include <sys/stat.h>
#include <fcntl.h>
#include <gmime/gmime.h>
#include "asterisk/linkedlists.h"
#include "asterisk/http.h"
#include "asterisk/paths.h"
#include "asterisk/tcptls.h"
#include "asterisk/manager.h"
#include "asterisk/cli.h"
#include "asterisk/module.h"
#include "asterisk/ast_version.h"
Include dependency graph for res_http_post.c:

Go to the source code of this file.

Data Structures

struct  mime_cbinfo
 

Macros

#define MAX_PREFIX   80
 

Functions

static int __ast_http_post_load (int reload)
 
static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int find_sequence (char *inbuf, int inlen, char *matchbuf, int matchlen)
 
static int http_post_callback (struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_vars, struct ast_variable *headers)
 
static int load_module (void)
 
static GMimeMessage * parse_message (FILE *f)
 
static void post_raw (GMimePart *part, const char *post_dir, const char *fn)
 
static int process_message (GMimeMessage *message, const char *post_dir)
 
static void process_message_callback (GMimeObject *part, gpointer user_data)
 
static int readmimefile (struct ast_iostream *in, FILE *fout, char *boundary, int contentlen)
 
static int reload (void)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "HTTP POST support" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload, .requires = "http", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static char prefix [MAX_PREFIX]
 

Detailed Description

HTTP POST upload support for Asterisk HTTP server.

Author
Terry Wilson <twils.nosp@m.on@d.nosp@m.igium.nosp@m..com

AMI over HTTP support - AMI over the http protocol

Definition in file res_http_post.c.

Macro Definition Documentation

◆ MAX_PREFIX

#define MAX_PREFIX   80

Definition at line 52 of file res_http_post.c.

Function Documentation

◆ __ast_http_post_load()

static int __ast_http_post_load ( int  reload)
static

Definition at line 429 of file res_http_post.c.

References ast_calloc, ast_config_destroy(), ast_config_load2(), ast_copy_string(), ast_free, ast_http_uri_link(), ast_http_uri_unlink_all_with_key(), ast_str_create, ast_str_set(), ast_strdup, ast_variable_browse(), ast_http_uri::callback, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, ast_http_uri::data, ast_http_uri::description, ast_http_uri::dmallocd, ast_http_uri::has_subtree, http_post_callback(), ast_http_uri::key, ast_http_uri::mallocd, ast_variable::name, ast_variable::next, prefix, ast_http_uri::uri, and ast_variable::value.

Referenced by load_module(), and reload().

430 {
431  struct ast_config *cfg;
432  struct ast_variable *v;
433  struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
434 
435  cfg = ast_config_load2("http.conf", "http", config_flags);
436  if (!cfg || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
437  return 0;
438  }
439 
440  if (reload) {
442  }
443 
444  for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
445  if (!strcasecmp(v->name, "prefix")) {
446  ast_copy_string(prefix, v->value, sizeof(prefix));
447  if (prefix[strlen(prefix)] == '/') {
448  prefix[strlen(prefix)] = '\0';
449  }
450  }
451  }
452 
453  for (v = ast_variable_browse(cfg, "post_mappings"); v; v = v->next) {
454  struct ast_http_uri *urih;
455  struct ast_str *ds;
456 
457  if (!(urih = ast_calloc(sizeof(*urih), 1))) {
458  ast_config_destroy(cfg);
459  return -1;
460  }
461 
462  if (!(ds = ast_str_create(32))) {
463  ast_free(urih);
464  ast_config_destroy(cfg);
465  return -1;
466  }
467 
468  urih->description = ast_strdup("HTTP POST mapping");
469  urih->uri = ast_strdup(v->name);
470  ast_str_set(&ds, 0, "%s", v->value);
471  urih->data = ds;
472  urih->has_subtree = 0;
474  urih->key = __FILE__;
475  urih->mallocd = urih->dmallocd = 1;
476 
477  ast_http_uri_link(urih);
478  }
479 
480  ast_config_destroy(cfg);
481  return 0;
482 }
struct ast_variable * next
ast_http_callback callback
Definition: http.h:105
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1216
int ast_http_uri_link(struct ast_http_uri *urihandler)
Register a URI handler.
Definition: http.c:673
#define CONFIG_STATUS_FILEINVALID
static int http_post_callback(struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_vars, struct ast_variable *headers)
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: main/config.c:3154
Structure for variables, used for configurations and for channel variables.
const char * key
Definition: http.h:116
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
unsigned int has_subtree
Definition: http.h:106
static char prefix[MAX_PREFIX]
Definition: res_http_post.c:69
unsigned int mallocd
Definition: http.h:108
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
static int reload(void)
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
#define CONFIG_STATUS_FILEUNCHANGED
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
const char * description
Definition: http.h:102
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
Structure used to handle boolean flags.
Definition: utils.h:199
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
Definition of a URI handler.
Definition: http.h:100
void ast_http_uri_unlink_all_with_key(const char *key)
Unregister all handlers with matching key.
Definition: http.c:712
unsigned int dmallocd
Definition: http.h:110
const char * uri
Definition: http.h:103
void * data
Definition: http.h:114
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 517 of file res_http_post.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 517 of file res_http_post.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 517 of file res_http_post.c.

◆ find_sequence()

static int find_sequence ( char *  inbuf,
int  inlen,
char *  matchbuf,
int  matchlen 
)
static

Definition at line 189 of file res_http_post.c.

Referenced by readmimefile().

190 {
191  int current;
192  int comp;
193  int found = 0;
194 
195  for (current = 0; current < inlen-matchlen; current++, inbuf++) {
196  if (*inbuf == *matchbuf) {
197  found=1;
198  for (comp = 1; comp < matchlen; comp++) {
199  if (inbuf[comp] != matchbuf[comp]) {
200  found = 0;
201  break;
202  }
203  }
204  if (found) {
205  break;
206  }
207  }
208  }
209  if (found) {
210  return current;
211  } else {
212  return -1;
213  }
214 }
static int inbuf(struct baseio *bio, FILE *fi)
utility used by inchar(), for base_encode()

◆ http_post_callback()

static int http_post_callback ( struct ast_tcptls_session_instance ser,
const struct ast_http_uri urih,
const char *  uri,
enum ast_http_method  method,
struct ast_variable get_vars,
struct ast_variable headers 
)
static

Definition at line 323 of file res_http_post.c.

References ast_debug, ast_http_body_read_status(), ast_http_error(), ast_http_manid_from_vars(), AST_HTTP_POST, ast_http_request_close_on_completion(), ast_log, ast_str_buffer(), astman_is_authed(), astman_verify_session_writepermissions(), ast_http_uri::data, EVENT_FLAG_CONFIG, LOG_ERROR, ast_variable::name, ast_variable::next, NULL, parse_message(), mime_cbinfo::post_dir, process_message(), readmimefile(), ast_tcptls_session_instance::stream, ast_variable::value, and var.

Referenced by __ast_http_post_load().

324 {
325  struct ast_variable *var;
326  uint32_t ident;
327  FILE *f;
328  int content_len = 0;
329  struct ast_str *post_dir;
330  GMimeMessage *message;
331  char *boundary_marker = NULL;
332 
333  if (method != AST_HTTP_POST) {
334  ast_http_error(ser, 501, "Not Implemented", "Attempt to use unimplemented / unsupported method");
335  return 0;
336  }
337 
338  if (!urih) {
339  ast_http_error(ser, 400, "Missing URI handle", "There was an error parsing the request");
340  return 0;
341  }
342 
343  ident = ast_http_manid_from_vars(headers);
344  if (!ident || !astman_is_authed(ident)) {
346  ast_http_error(ser, 403, "Access Denied", "Sorry, I cannot let you do that, Dave.");
347  return 0;
348  }
349 
352  ast_http_error(ser, 401, "Unauthorized", "You are not authorized to make this request.");
353  return 0;
354  }
355 
356  if (!(f = tmpfile())) {
357  ast_log(LOG_ERROR, "Could not create temp file.\n");
358  ast_http_error(ser, 500, "Internal server error", "Could not create temp file.");
359  return 0;
360  }
361 
362  for (var = headers; var; var = var->next) {
363  fprintf(f, "%s: %s\r\n", var->name, var->value);
364 
365  if (!strcasecmp(var->name, "Content-Length")) {
366  if ((sscanf(var->value, "%30u", &content_len)) != 1) {
367  ast_log(LOG_ERROR, "Invalid Content-Length in POST request!\n");
368  fclose(f);
370  ast_http_error(ser, 400, "Bad Request", "Invalid Content-Length in POST request!");
371  return 0;
372  }
373  ast_debug(1, "Got a Content-Length of %d\n", content_len);
374  } else if (!strcasecmp(var->name, "Content-Type")) {
375  boundary_marker = strstr(var->value, "boundary=");
376  if (boundary_marker) {
377  boundary_marker += strlen("boundary=");
378  }
379  }
380  }
381  fprintf(f, "\r\n");
382 
383  /*
384  * Always mark the body read as failed.
385  *
386  * XXX Should change readmimefile() to always be sure to read
387  * the entire body so we can update the read status and
388  * potentially keep the connection open.
389  */
391 
392  if (0 > readmimefile(ser->stream, f, boundary_marker, content_len)) {
393  ast_debug(1, "Cannot find boundary marker in POST request.\n");
394  fclose(f);
395  ast_http_error(ser, 400, "Bad Request", "Cannot find boundary marker in POST request.");
396  return 0;
397  }
398 
399  if (fseek(f, SEEK_SET, 0)) {
400  ast_log(LOG_ERROR, "Failed to seek temp file back to beginning.\n");
401  fclose(f);
402  ast_http_error(ser, 500, "Internal server error", "Failed to seek temp file back to beginning.");
403  return 0;
404  }
405 
406  post_dir = urih->data;
407 
408  message = parse_message(f); /* Takes ownership and will close f */
409  if (!message) {
410  ast_log(LOG_ERROR, "Error parsing MIME data\n");
411 
412  ast_http_error(ser, 400, "Bad Request", "There was an error parsing the request.");
413  return 0;
414  }
415 
416  if (!process_message(message, ast_str_buffer(post_dir))) {
417  ast_log(LOG_ERROR, "Invalid MIME data, found no parts!\n");
418  g_object_unref(message);
419  ast_http_error(ser, 400, "Bad Request", "There was an error parsing the request.");
420  return 0;
421  }
422  g_object_unref(message);
423 
424  /* XXX Passing 200 to the error response routine? */
425  ast_http_error(ser, 200, "OK", "File successfully uploaded.");
426  return 0;
427 }
struct ast_variable * next
void ast_http_error(struct ast_tcptls_session_instance *ser, int status, const char *title, const char *text)
Send HTTP error message and close socket.
Definition: http.c:648
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
uint32_t ast_http_manid_from_vars(struct ast_variable *headers) attribute_pure
Return manager id, if exist, from request headers.
Definition: http.c:217
#define NULL
Definition: resample.c:96
static int readmimefile(struct ast_iostream *in, FILE *fout, char *boundary, int contentlen)
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int astman_is_authed(uint32_t ident)
Determinie if a manager session ident is authenticated.
Definition: manager.c:7551
static int process_message(GMimeMessage *message, const char *post_dir)
const char * method
Definition: res_pjsip.c:4335
#define LOG_ERROR
Definition: logger.h:285
#define EVENT_FLAG_CONFIG
Definition: manager.h:78
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
void ast_http_body_read_status(struct ast_tcptls_session_instance *ser, int read_success)
Update the body read success status.
Definition: http.c:899
int astman_verify_session_writepermissions(uint32_t ident, int perm)
Verify a session&#39;s write permissions against a permission mask.
Definition: manager.c:7600
struct ast_iostream * stream
Definition: tcptls.h:160
static GMimeMessage * parse_message(FILE *f)
void ast_http_request_close_on_completion(struct ast_tcptls_session_instance *ser)
Request the HTTP connection be closed after this HTTP request.
Definition: http.c:836
void * data
Definition: http.h:114

◆ load_module()

static int load_module ( void  )
static

Definition at line 498 of file res_http_post.c.

References __ast_http_post_load(), AST_MODFLAG_DEFAULT, AST_MODULE_INFO(), AST_MODULE_LOAD_SUCCESS, AST_MODULE_SUPPORT_CORE, ASTERISK_GPL_KEY, reload(), and unload_module().

499 {
500  g_mime_init(
501 #ifndef AST_GMIME_VER_30
502  0
503 #endif
504  );
505 
507 
509 }
static int __ast_http_post_load(int reload)

◆ parse_message()

static GMimeMessage* parse_message ( FILE *  f)
static

Definition at line 104 of file res_http_post.c.

References NULL, and process_message_callback().

Referenced by http_post_callback().

105 {
106  GMimeMessage *message;
107  GMimeParser *parser;
108  GMimeStream *stream;
109 
110  stream = g_mime_stream_file_new(f);
111 
112  parser = g_mime_parser_new_with_stream(stream);
113  g_mime_parser_set_respect_content_length(parser, 1);
114 
115  g_object_unref(stream);
116 
117  message = g_mime_parser_construct_message(parser
118 #ifdef AST_GMIME_VER_30
119  , NULL
120 #endif
121  );
122 
123  g_object_unref(parser);
124 
125  return message;
126 }
#define NULL
Definition: resample.c:96

◆ post_raw()

static void post_raw ( GMimePart *  part,
const char *  post_dir,
const char *  fn 
)
static

Definition at line 71 of file res_http_post.c.

References ast_debug, ast_log, LOG_WARNING, and PATH_MAX.

Referenced by process_message_callback().

72 {
73  char filename[PATH_MAX];
74  GMimeDataWrapper *content;
75  GMimeStream *stream;
76  int fd;
77 
78  snprintf(filename, sizeof(filename), "%s/%s", post_dir, fn);
79 
80  ast_debug(1, "Posting raw data to %s\n", filename);
81 
82  if ((fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666)) == -1) {
83  ast_log(LOG_WARNING, "Unable to open %s for writing file from a POST!\n", filename);
84 
85  return;
86  }
87 
88  stream = g_mime_stream_fs_new(fd);
89 
90 #ifdef AST_GMIME_VER_30
91  content = g_mime_part_get_content(part);
92 #else
93  content = g_mime_part_get_content_object(part);
94 #endif
95  g_mime_data_wrapper_write_to_stream(content, stream);
96  g_mime_stream_flush(stream);
97 
98 #ifndef AST_GMIME_VER_24
99  g_object_unref(content);
100 #endif
101  g_object_unref(stream);
102 }
#define LOG_WARNING
Definition: logger.h:274
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define PATH_MAX
Definition: asterisk.h:40

◆ process_message()

static int process_message ( GMimeMessage *  message,
const char *  post_dir 
)
static

Definition at line 172 of file res_http_post.c.

References mime_cbinfo::count, mime_cbinfo::post_dir, and process_message_callback().

Referenced by http_post_callback().

173 {
174  struct mime_cbinfo cbinfo = {
175  .count = 0,
176  .post_dir = post_dir,
177  };
178 
179 #ifdef AST_GMIME_VER_24
180  g_mime_message_foreach(message, process_message_callback, &cbinfo);
181 #else
182  g_mime_message_foreach_part(message, process_message_callback, &cbinfo);
183 #endif
184 
185  return cbinfo.count;
186 }
static void process_message_callback(GMimeObject *part, gpointer user_data)
const char * post_dir
Definition: res_http_post.c:65

◆ process_message_callback()

static void process_message_callback ( GMimeObject *  part,
gpointer  user_data 
)
static

Definition at line 131 of file res_http_post.c.

References ast_debug, ast_log, ast_strlen_zero, mime_cbinfo::count, LOG_ERROR, LOG_WARNING, mime_cbinfo::post_dir, and post_raw().

Referenced by parse_message(), and process_message().

133 {
134  struct mime_cbinfo *cbinfo = user_data;
135 
136  cbinfo->count++;
137 
138  /* We strip off the headers before we get here, so should only see GMIME_IS_PART */
139  if (GMIME_IS_MESSAGE_PART(part)) {
140  ast_log(LOG_WARNING, "Got unexpected GMIME_IS_MESSAGE_PART\n");
141  return;
142  } else if (GMIME_IS_MESSAGE_PARTIAL(part)) {
143  ast_log(LOG_WARNING, "Got unexpected GMIME_IS_MESSAGE_PARTIAL\n");
144  return;
145  } else if (GMIME_IS_MULTIPART(part)) {
146 #ifndef AST_GMIME_VER_24
147  GList *l;
148 
149  ast_log(LOG_WARNING, "Got unexpected GMIME_IS_MULTIPART, trying to process subparts\n");
150  l = GMIME_MULTIPART(part)->subparts;
151  while (l) {
152  process_message_callback(l->data, cbinfo);
153  l = l->next;
154  }
155 #else
156  ast_log(LOG_WARNING, "Got unexpected MIME subpart.\n");
157 #endif
158  } else if (GMIME_IS_PART(part)) {
159  const char *filename;
160 
161  if (ast_strlen_zero(filename = g_mime_part_get_filename(GMIME_PART(part)))) {
162  ast_debug(1, "Skipping part with no filename\n");
163  return;
164  }
165 
166  post_raw(GMIME_PART(part), cbinfo->post_dir, filename);
167  } else {
168  ast_log(LOG_ERROR, "Encountered unknown MIME part. This should never happen!\n");
169  }
170 }
static void process_message_callback(GMimeObject *part, gpointer user_data)
#define LOG_WARNING
Definition: logger.h:274
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
const char * post_dir
Definition: res_http_post.c:65
static void post_raw(GMimePart *part, const char *post_dir, const char *fn)
Definition: res_http_post.c:71

◆ readmimefile()

static int readmimefile ( struct ast_iostream in,
FILE *  fout,
char *  boundary,
int  contentlen 
)
static

Definition at line 225 of file res_http_post.c.

References ast_iostream_read(), ast_log, buf, errno, find_sequence(), LOG_WARNING, and NULL.

Referenced by http_post_callback().

226 {
227  int find_filename = 0;
228  char buf[4096];
229  int marker;
230  int x;
231  int char_in_buf = 0;
232  int num_to_read;
233  int boundary_len;
234  char * path_end, * path_start, * filespec;
235 
236  if (NULL == in || NULL == fout || NULL == boundary || 0 >= contentlen) {
237  return -1;
238  }
239 
240  boundary_len = strlen(boundary);
241  while (0 < contentlen || 0 < char_in_buf) {
242  /* determine how much I will read into the buffer */
243  if (contentlen > sizeof(buf) - char_in_buf) {
244  num_to_read = sizeof(buf)- char_in_buf;
245  } else {
246  num_to_read = contentlen;
247  }
248 
249  if (0 < num_to_read) {
250  if (ast_iostream_read(in, &(buf[char_in_buf]), num_to_read) < num_to_read) {
251  ast_log(LOG_WARNING, "read failed: %s\n", strerror(errno));
252  num_to_read = 0;
253  }
254  contentlen -= num_to_read;
255  char_in_buf += num_to_read;
256  }
257  /* If I am looking for the filename spec */
258  if (find_filename) {
259  path_end = filespec = NULL;
260  x = strlen("filename=\"");
261  marker = find_sequence(buf, char_in_buf, "filename=\"", x );
262  if (0 <= marker) {
263  marker += x; /* Index beyond the filename marker */
264  path_start = &buf[marker];
265  for (path_end = path_start, x = 0; x < char_in_buf-marker; x++, path_end++) {
266  if ('\\' == *path_end) { /* convert backslashses to forward slashes */
267  *path_end = '/';
268  }
269  if ('\"' == *path_end) { /* If at the end of the file name spec */
270  *path_end = '\0'; /* temporarily null terminate the file spec for basename */
271  filespec = basename(path_start);
272  *path_end = '\"';
273  break;
274  }
275  }
276  }
277  if (filespec) { /* If the file name path was found in the header */
278  if (fwrite(buf, 1, marker, fout) != marker) {
279  ast_log(LOG_WARNING, "fwrite() failed: %s\n", strerror(errno));
280  }
281  x = (int)(path_end+1 - filespec);
282  if (fwrite(filespec, 1, x, fout) != x) {
283  ast_log(LOG_WARNING, "fwrite() failed: %s\n", strerror(errno));
284  }
285  x = (int)(path_end+1 - buf);
286  memmove(buf, &(buf[x]), char_in_buf-x);
287  char_in_buf -= x;
288  }
289  find_filename = 0;
290  } else { /* I am looking for the boundary marker */
291  marker = find_sequence(buf, char_in_buf, boundary, boundary_len);
292  if (0 > marker) {
293  if (char_in_buf < (boundary_len)) {
294  /*no possibility to find the boundary, write all you have */
295  if (fwrite(buf, 1, char_in_buf, fout) != char_in_buf) {
296  ast_log(LOG_WARNING, "fwrite() failed: %s\n", strerror(errno));
297  }
298  char_in_buf = 0;
299  } else {
300  /* write all except for area where the boundary marker could be */
301  if (fwrite(buf, 1, char_in_buf -(boundary_len -1), fout) != char_in_buf - (boundary_len - 1)) {
302  ast_log(LOG_WARNING, "fwrite() failed: %s\n", strerror(errno));
303  }
304  x = char_in_buf -(boundary_len -1);
305  memmove(buf, &(buf[x]), char_in_buf-x);
306  char_in_buf = (boundary_len -1);
307  }
308  } else {
309  /* write up through the boundary, then look for filename in the rest */
310  if (fwrite(buf, 1, marker + boundary_len, fout) != marker + boundary_len) {
311  ast_log(LOG_WARNING, "fwrite() failed: %s\n", strerror(errno));
312  }
313  x = marker + boundary_len;
314  memmove(buf, &(buf[x]), char_in_buf-x);
315  char_in_buf -= marker + boundary_len;
316  find_filename =1;
317  }
318  }
319  }
320  return 0;
321 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
ssize_t ast_iostream_read(struct ast_iostream *stream, void *buffer, size_t count)
Read data from an iostream.
Definition: iostream.c:273
#define ast_log
Definition: astobj2.c:42
int errno
static int find_sequence(char *inbuf, int inlen, char *matchbuf, int matchlen)

◆ reload()

static int reload ( void  )
static

Definition at line 491 of file res_http_post.c.

References __ast_http_post_load(), and AST_MODULE_LOAD_SUCCESS.

Referenced by load_module().

492 {
494 
496 }
static int __ast_http_post_load(int reload)

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 484 of file res_http_post.c.

References ast_http_uri_unlink_all_with_key().

Referenced by load_module().

485 {
487 
488  return 0;
489 }
void ast_http_uri_unlink_all_with_key(const char *key)
Unregister all handlers with matching key.
Definition: http.c:712

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "HTTP POST support" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload, .requires = "http", }
static

Definition at line 517 of file res_http_post.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 517 of file res_http_post.c.

◆ prefix

char prefix[MAX_PREFIX]
static

Definition at line 69 of file res_http_post.c.

Referenced by __ast_http_post_load().