Skip to content

Instantly share code, notes, and snippets.

@bilus
Created April 10, 2024 15:11
Show Gist options
  • Save bilus/cba0b051f55b539a34d2865e13456810 to your computer and use it in GitHub Desktop.
Save bilus/cba0b051f55b539a34d2865e13456810 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import logging
import sys
log = logging.getLogger(__name__)
CONTENT = b'Content-Disposition: form-data; name='
OCTET_STREAM = b'Content-Type: application/octet-stream'
MULTIPART_FORM = 'multipart/form-data'
CRLF = b'\n'
alt_name = dict(normal='url', hiRes='urlHiRes')
# Legacy delimiter for separating the multipart
LEGACY_BOUNDARY = b'--*****2019.04.10.CONRAD*****'
class DecodingError(Exception):
pass
def extract_content_type_boundary(content_type):
content_type, semicolon, params = content_type.partition(';')
if content_type.strip().lower() == 'multipart/form-data':
for param in params.split(';'):
name, equal_sign, value = param.strip().partition('=')
if not equal_sign or name.strip().lower() != 'boundary':
continue
stripped = value.strip().strip('"')
if not stripped:
raise DecodingError(
reason={'debug': {'error': 'Boundary error'}}
)
return f'--{stripped}'.encode('ascii')
# LEGACY! Previously content_type was never passed by acr_client
# in that case content_type was auto-filled as `application/octet-stream`
# or other.
return LEGACY_BOUNDARY
def decode_multipart_form_data(body, content_type):
fields = {}
files = {}
try:
boundary = extract_content_type_boundary(content_type)
print("boundary", boundary)
print("body", body)
for disp in body.split(boundary)[1:-1]:
print("disp", disp)
key, value = disp.split(CONTENT + b'"', 1)[1].split(b'"', 1)
print("value", value)
key = key.decode('ascii')
if OCTET_STREAM in value:
files[key] = value.split(OCTET_STREAM, 1)[1].split(CRLF)[2]
else:
fields[key] = value.split(CRLF)[2].decode('ascii')
return fields, files
except IndexError:
log.info('decode_multipart_form_data error')
raise DecodingError()
# Read body from stdin.
raw = sys.stdin.read().encode('utf-8')
content_type = "multipart/form-data; boundary=*****2016.05.27.acrcloud.rec.copyright.1712659928.682365*****"
boundary = extract_content_type_boundary(content_type)
print(boundary)
result = decode_multipart_form_data(raw, content_type)
print(result)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment